Part1 前言
在最近的一次渗透测试项目中,遇到了一个奇葩的SQL延时注入漏洞,sqlmap无法识别出来。但是客户非让在测试环境跑出数据进行验证,否则不认可这个漏洞的危害性。编写一个多线程的延时注入脚本是很麻烦的,于是ABC_123经过了一系列操作,最终成功让sqlmap识别这个注入点并成功枚举出数据,相信也能给大家很多的启示。
注:在读研那会儿,我曾经把sqlmap手册打印出来,从头到尾看了好多遍,多读读sqlmap手册,可以加深对sqlmap的理解。
Part2 技术研究过程
-
注入漏洞判断过程
经过测试,发现这个注入点只能用uid=sleep(5)这种形式的payload才能发生延时,由于web应用对用户提交的数据进行了严格判断,所以sleep(5)函数左右不能有任何的单引号、双引号、and、or等等。尝试用sqlmap注入,结果发现sqlmap无论怎么配置参数,都是识别不出来这个注入点的。
-
Sqlmap无法注入的原因分析
1 有waf或者Web应用程序本身对用户提交的数据进行了严格的过滤。这个可以结合sqlmap的tamper脚本来绕过。
2 函数sleep(5)左右无法接逻辑连接字符and or || 等,导致sqlmap无法在合适的地方插入自己的注入语句。
3 只要sleep(1)函数设置了延时时间,哪怕只设置了1秒,那么它也会一直延迟下去,直至超时,这种情况也是造成sqlmap无法识别的重要原因。
-
Sqlmap设置第1步,构造if函数
接下来在if语句中插入*,构造以下数据包,导出txt文本,用sqlmap -r c:zhuru111.txt这样载入sqlmap中。
-
Sqlmap设置第2步,绕过waf过滤
经过一系列手工判断,发现程序过滤了空格、< > ,还过滤了其它的字符,但是幸亏没干掉select,使得这个注入点跑出数据问题不大。解决这个过滤问题,可以使用sqlmap的绕waf脚本space2comment.py,between.py。
space2comment.py脚本代码如下,可以将空格替换为/**/注释符:
between.py脚本代码如下,将< >替换为between 0 and 98形式的注入语句:
-
Sqlmap设置第3步,优化延时参数
经过上面两个步骤设置,sqlmap还是识别不出这个注入点的。接下来怎么办呢?经过一系列尝试,将sleep(5)值设置大一些,设置为延迟33秒,变成if(1=1*,sleep(33),1),然后添加延时参数–time-sec=5,最后加上–risk=3、–level=3,终于可以注入跑出数据了,最终的sqlmap的语句如下:
sqlmap.py -r c:sql111.txt –force-ssl –proxy=”http://127.0.0.1:8080/” –tamper=space2comment.py,between.py –batch –dbms=Mysql –technique BT –risk 3 –level 3 –time-sec 5 –current-db –threads 10
-
Sqlmap设置第4步,快速枚举表及字段
使用sqlmap猜解出了数据库名,但是猜解表名是一个麻烦事,因为延时注入是一个字符一个字符的猜解,速度太慢了。但是我们可以挂一个字典让sqlmap来枚举表及字段,而不用一个字符一个字符地猜解,这样对于延时注入来说,速度更快。
命令如下–common-table –common-columns
很快猜解出了user表,然后很快猜解出了email,name,pwd等字段,接下来就是猜解数据了,最终我们构造出一个很复杂的sqlmap语句。
sqlmap.py -r c:sql111.txt –force-ssl –proxy=”http://127.0.0.1:8080/” –tamper=space2comment.py,between.py –batch –dbms=Mysql –technique BT –risk 3 –level 3 –time-sec 5 -T 数据库名 -C 表名 -C user,email,pwd –dump –threads 10
Part3 总结
1. 把sqlmap的手册多看看,多了解一下sqlmap的各种参数的使用说明,在日常渗透测试工作中会事半功倍。
2. 提前构造一个if(1=1,1,2)或者case when语句,可以使sqlmap可以识别一些奇葩的sql注入点。
专注于网络安全技术分享,包括红队攻防、蓝队分析、渗透测试、代码审计等
每周一篇,99%原创,敬请关注
原文始发于微信公众号(网络安全abc123):第31篇:一系列操作使sqlmap识别一个奇葩的延时注入点并绕waf的艰难过程