sqlmap跑post注入:别只盯着URL
很多人测注入,习惯性把sqlmap往URL上一甩,跑得欢。可真正的业务逻辑,大多藏在POST请求的body里——登录框、搜索栏、JSON数据。你光扫GET参数,等于只查了门锁,没翻窗户。
上个月帮朋友看一个后台管理系统,登录接口就是标准的POST。用户名密码框在前端,数据包长这样:username=admin&password=123456。拿sqlmap直接跑URL?屁用没有,服务器压根不搭理GET请求。得把整个POST请求体喂给它。
最笨但最稳的办法,是抓包存文件。Burp截下登录请求,右键copy to file,存成login.txt。然后一行命令:
sqlmap -r login.txt -p username --dbs
-r读取请求文件,-p指定测试参数。这里有个坑——别让sqlmap把password也一起测,有时候密码字段会触发WAF的疯狂拦截,反而把username的注入点给带崩了。
如果手头没有Burp,纯命令行也能凑合。用--data参数直接写body:
sqlmap -u "http://target.com/login" --data="username=admin&password=123" --level=2
注意--level必须调到2以上,默认level 1只测GET参数,POST参数会被无视。这细节坑过无数新手——命令看着没问题,结果跑半小时全是“无注入”,最后发现是level没调。
还有种更隐蔽的场景:前端用AJAX发JSON。比如{ "user":"tom","pass":"123"},这时候--data得写成--data='{ "user":"tom","pass":"123"}',还要加个--headers="Content-Type: application/json"。否则sqlmap按表单格式发请求,服务器直接返回415,你还在那傻等。
跑POST注入时,响应时间明显比GET慢。因为每个payload都要经过服务器解析body、拼接SQL、再回显。我习惯先加--batch跳过交互,再用--current-db快速验证是否真注入。如果返回了库名,再上--tables慢慢拖。别一上来就--dump-all,那会把目标服务器拖死,也容易暴露自己。
最后说个反直觉的事:POST注入的payload有时得URL编码,有时不用。取决于服务器怎么解析Content-Type。遇到奇葩情况,直接加--charset=UTF-8强制指定编码,能省不少折腾。sqlmap跑POST注入,本质是模拟一个真实的浏览器提交动作——你构造的请求越像正常用户,WAF就越难分辨。
工具是死的,请求是活的。下次拿到一个POST接口,先看数据格式,再决定怎么喂给sqlmap。别让工具思维限制了你对漏洞的想象力。