Jrecms代码审计小计
Jrecms代码审计小计
项目简介
JreCms是开源免费的JAVA企业网站开发建设管理系统
软件架构
- MVC:JFinal
- 页面:enjoy
- 缓存:ehcache
- 数据库:Mysql
项目地址:https://gitee.com/heyewei/JFinalcms
环境搭建
下载源码后,创建数据表cms,导入相应sql文件
IDA打开源码可自动加载包
源码分析
XSS-反射
在com/cms/controller/admin/LoginController.java#index()里,用JFinal的getPara获取的数据被交给render渲染前端页面。

而前端用的是用来接收页面传来的参数


xss-存储型
前台留言功能

找到留言功能的控制器com/cms/controller/front/GuestbookController.java#save(),这里使用了JFinal框架的getModel将接收的表单传递给Guestbook对象,且没有做任何过滤。

可以看到传入参数没有过滤

继续跟进
可以看到这里执行了sql语句插入到了数据库中
相关管理员审核的时候可触发xss

任意文件删除
翻阅后台的时候发现数据库备份功能

备份后有删除功能

点击删除抓包

尝试更改其他文件名
先找到相关文件

在其上一层路径建一个1.txt测试


发现成功被删除
回到源码查看src/main/java/com/cms/controller/admin/DatabaseController.java

这里发现仅仅接受那么参数就触发delete()函数

发现只是进行路径传递进行delete,未做任何过滤
任意文件读取
在src/main/java/com/cms/controller/admin/DatabaseController.java中发现restore()函数也有几分问题

审计发现,没有返回文件内容

尝试无果继续寻找

点击编辑后发现有filename参数

尝试更换文件名
已经在上层目录新建1.txt


成功!相似的,读取数据库文件

回到源码里

获取filename和directory参数然后拼接,唯一的判断是把,替换为/,然后如果directory存在就拼接上directory,不存在就拼接/
SSTI
还是在模版管理处
模版框架是enjoy,

1 | #set((java.beans.Beans::instantiate(null,"javax.script.ScriptEngineManager")).getEngineByExtension("js").eval("function test(){ return java.lang.Runtime};r=test();r.getRuntime().exec(\"calc.exe\")")) |

定位原文com/cms/controller/admin/TemplateController.java#update(),content参数没做任何处理就传递给了com/cms/util/TemplateUtils.java#write()。跟进到该方法,可以看到没有对content进行任何处理就写入到文件了,那么模板管理功能是存在SSTI的。

更新处和上面如出一辙,没有任何过滤直接到write

前台任意文件下载
这个我没找到功能点在哪,这个漏洞是看别的师傅挖到的
搜素FileInputStream找到src/main/java/com/cms/controller/common/DownController.java
发现相关路径/common/down接收参数fileKey可渲染文件


尝试一下
1 | /common/down/file?fileKey=/../../../src/main/resources/config.properties |

下载成功
文件上传配合任意文件渲染RCE
在com/cms/controller/front/AjaxController.java#html()里,既没有鉴权也没有过滤,就直接将传入的文件路径拼接之后,使用JFinal框架的render渲染了。

在后台找一个能回显上传文件路径的文件上传点,文件的内容为SSTI的Payload即可。

1 | POST /jrecms/admin/file/upload HTTP/1.1 |
/static/upload/ce54b595-aa62-4231-afef-5220ec1a47a3.jpg


这里也可以上传html文件xss,没在写了
SQL注入
com/cms/entity/Admin.java#findPage()里,传入的name、username参数被拼接到filterSql变量,然后传递给了JFinal框架的paginate,在JFinal框架li这种写法是存在SQL注入的。使用IDEA找到使用findPage()的地方。

找到了在com/cms/controller/admin/AdminController.java#index()里,传入的name、username参数未做任何处理就被传递给findPage(),那么这里是存在SQL注入的。







