简介
版本:6.1.1
漏洞类型:SQL 注入(高危)
核心工具:棋士 AI 代码审计平台(aireview.dx-src.com)
铭飞CMS ,gitee获取到GVP的明星开源项目,众多企业使用其作为网站管理系统使用,随着版本迭代历史漏洞修复,漏洞利用不再单一化,新漏洞利用隐藏在更深的角落,本次记录一次配合AI代码审计工具--棋士完成的复杂的sql注入漏洞链查找。
使用过程
直接压缩包上传
上传后等待扫描完成后,查看结果,发现一处sql注入。
棋士辅助深入分析
根据缺陷详情介绍可发现,典型的java orm框架mybatis xml的sql注入,这么简单吗?代码层排查一下。
参数走向分析
数据层:
继续查找漏洞链。
业务层:
访问层:
由此可推断出contentModel必须不为空才能满足注入前提条件,并且注入点的实体为diyList。
往上寻找到控制层,寻找到注入点fieldValueList。
注入参数构造解析
fieldValueList的唯一赋值方式已找到,接下来看似只需要关注如何控制其key(entry.value的值)就能完成注入。
寻找entry的赋值方式,发现追踪到此,找棋士问下具体代码含义。
棋士解释为解析请求参数,事情似乎变得简单了,请求参数直接注入?
再次查看注入key的前置条件,value不能为空、filedStr元素列表必须包含key,value就是请求参数具体值,filedStr是啥?查看一下。
通过注释可以发现filedStr为自定义模型,并且这个自定义模型的,并且需要很多以下前提条件才能赋值,代码丢给寻找棋士解释
通过棋士分析,结合代码可得出以下结论
从代码角度分析
1、categoryIds 不能为空,并且不能包含 , ,才能保证typeId不为空
2、typeId必须能获取到值不能为空并且mdiyModelId也不能为空
3、mdiyModelId必须能获取到值,且fieldMap有值
从业务角度分析
业务逻辑是要从通过栏目获取到自定义模型,所以接下来的步骤就是构建具备可注入性质的自定义模型,并且栏目引用这个模型,整理下当前漏洞链关系图
可以看到由modelField字段json反序列化获取,也就是说在定义模型时通过定义可注入的modelFiled,key为注入点,并且请求时要有参数key名称相同。
自定义模型环节
接下来进入自定义模型环节,进入页面后。
通过页面功能结合代码查看,注入点为json的field字段。
根据官方提供的原始数据改造下:
1、表名不重复
2、增加field字段,并在key内设置注入点
直接根据以上导入会提示自定义表名重复
根据代码分析需要提供title字段,并且不重复
json增加title字段
接下来配置栏目绑定我们恶意的自定义模型
通过页面访问获取到栏目id,直接访问sql注入接口search,构造恶意参数
url:http://localhost:8080/mcms/search?categoryIds=1666653706550321152&id%20%3D1%20or%201%3D1%20%23=1111
将注入点写入参数key,并将key url编码
注入前置条件不足补充
抛出文件找不到,检查原因
通过日志排查,会通过tmpl参数寻找在template\1\default\ 下的文件
通过模板文件上传解决此问题,经测试需要创建双层default目录,上传至模板文件才会创建default目录
上传后增加参数tmpl=1.txt
url:http://localhost:8080/mcms/search?categoryIds=1666653706550321152&id%20%3D1%20or%201%3D1%20%23=1111&tmpl=1.txt
后台抛出错误,并没有注入成功,使用“棋士”辅助解决问题
通过“棋士”解释可以看到参数是因为,第三个参数被注释掉所以出现问题,可以直接在注入点写入参数占位符尝试
更新模型注入点
url更新: http://localhost:8080/mcms/search?categoryIds=1666653706550321152&id%3D1%20or%201%3D1%20or%201%3D%3F%23=1111&tmpl=1.txt
后台日志查看恶意sql语句已注入成功
进一步利用
直接使用id = 1 OR 1 = 1 or extractvalue(1,concat(0x7e,(/11/SELECT user/**/()),0x7e)) # 作为参数传入的话会触发防御机制
查看防御代码
通过代码可以看出触发防御机制的情况有以下内容
1、有sql注释符号
2、检测到sql关键字并存在sql符号
extractvalue`( 就会触发第二条情况,但是只是单个检查参数,前面看filed是数组形式,可以通过组合形式绕过防御。
Filed利用链
因field注入前是通过前端参数并且后端为map结构,要特殊设置参数名称(也要同时设置key)才能保证其在sql注入时的顺序。
再次利用“棋士”提供的预编译符?直接注入的方式防止mybatis框架报错无法执行sql。
此field调用链更新到模型内部,或者重新建立模型即可。
访问search接口并拼接参数:http://localhost:8080/mcms/search?categoryIds=1666653706550321152&tmpl=1.txt&id+%3D+1+OR+extractvalue+%2F*1111111111=1&i1*%2F+%281%2C+concat%280x7e%2C+%28+%2F*=1&i2*%2F+SELECT+user+%2F*=1&i3*%2F+%28%29%29%2C+0x7e%29%29+or++1%3D%3F+and+1%3D%3F+and+1%3D%3F+and+1%3D%3F+%23111111111111=1
漏洞利用手法总结
1、上传双层目录为default压缩包文件
2、导入自定义模型并在添加field、title字段,并且field结构体的key字段为注入点,title不可重复、tablename 字段不可重复,并且创建数据库名称要对应
3、栏目要绑定自定义的危害模型
4、访问危害接口search 时传入三个参数,分别为tmpl 步骤一上传的文件名称、categoryIds 步骤三绑定的栏目id、以及对应field结构体的key值的参数名称对应的参数值随便
5、进一步绕过安全防护机制,要依靠field利用链
6、利用 “棋士” 提供的 ? 占位符注入,解决mybatis预编译环节出现的报错问题
修复方案
“棋士”针对该漏洞提供了多维度的解决方案 :
立即方案: 使用预编译参数、白名单校验、部署Web过滤器拦截明显注入特征、修改数据库账号为最小权限。
长期方案: 实施全站代码审计、部署SQL防火墙、建立安全编码规范。
总结
此漏洞利用手法复杂,各个环节每一个节点知识储备量不足,就会导致此漏洞的遗漏,“棋士”是一款集代码审计、AI 知识问答、PoC 构造辅助及修复建议于一体的综合性安全工具 。能显著提升从漏洞发现到闭环修复的整体效率,是安全从业者和开发者的得力助手 。