某cms代码审计

某cms代码审计

简介

JFinalCMS是一款小巧、灵活、简单、易用的轻量级cms。能满足各种企业站 博客 等中小型站点。极速开发,动态添加字段,自定义标签,动态创建数据库表并crud数据,数据库备份、还原,动态添加站点(多站点功能),一键生成模板代码,让您轻松打造自己的独立网站,同时也方便二次开发,让您快速搭建个性化独立网站 。

0x0 开始

首先先读一下web.xml

图片.png
找到JFinalFilter,可以看到代码是限制了访问jsp,但是没有看到对其他安全漏洞的过滤。

图片.png
可以看到是有对jsp以及jspx做了限制不允许访问。

图片.png
然后可以随便找一个Controller然后进入发现是继承了BaseController这个类

图片.png
然后BaseController又继承了Controller类。

图片.png

读一下Controller类的源码,首先是init方法,这个方法可能是初始化controller,该方法把HttpServletRequest和HttpServletResponse赋值给该类的属性。简单来说Controller就是对Servlet的封装。

图片.png
然后读到getPara函数,实际上就是获取url里面的参数。
图片.png

以及getPara的一系列封装,以及getParaToInt和getParaToLogin之类的,就是返回一个数字类型的对象,之后审计遇到这种这类函数可以放弃注入和xss等需要特殊字符的漏洞。(主要通读就是看看有没有过滤函数之类的)

图片.png

图片.png

上传文件的getFiles系列方法。因为程序有对jsp和jspx做校验就不仔细看了。

图片.png

0x1 sql注入

路由/search

图片.png
断点调试到ActionHandler的113行,跟进render函数

图片.png
然后到跟进62行的render函数

图片.png
其实data就是我们传递进去的数据

图片.png
然后是跟进57行 走到了exec函数

图片.png
然后是调用了exec参数去执行,这里跟进的是findPage函数。

图片.png

跟踪到findPage发现keyword没有经过过滤,以及转义直接就使用+的方式拼接进入sql语句种造成了sql注入的问题。

图片.png
注入结果:

图片.png

ps: 要在statArray[21]的时候跟进

图片.png
因为statArray其他的元素其实就是把模板文件读取一遍,然后在渲染出来。不执行sql操作。

图片.png

0x2 任意文件读取

路由监听/common/down/file 获取get请求的fileKey参数。

图片.png
跟进getPara函数发现其实就是封装好的getParameter函数。也没有过滤../关键字。

图片.png
然后用fileKey的值和PathKit.getWebRootPath() 函数的返回值拼接 (其实这里已经不用看getWebRootPath的返回值了,因为getWebRootPath无论是什么,都可以被../../../../去进行目录跨越)。

图片.png
http://127.0.0.1:8080/common/down/file?fileKey=/../../../../../../../../../../windows/win.ini
成功读取到win.ini文件。
(个人觉得审计这套源码学到比较重要的东西:虽然返回的是404,但是依旧是执行了下载文件功能,有时候src或者黑盒测试的时候遇到404应该尽量fuzz一下。而不是直接放弃。也许404页面有大用也说不准,听几个师傅说过404页面xss,url跳转之类的水洞出现率还是挺高的。)

图片.png

0x3 存储型XSS

留言板处的在线留言功能/guestbook可以添加留言。

图片.png
抓取数据包,然后直接打上xss测试的payload: <img src=0 onerror=alert(1)>

图片.png

这里的看到第三十行的代码

Guestbook guestbook = getModel(Guestbook.class,"",true);

图片.png

分析getModel方法,这里是调用了injectModel方法,看着参数列表像是一个通过class创建一个对象的方法。

图片.png

跟进injectModel,发现其实就是调用了request.getParameterMap获取http的全部参数,然后对照类的字段名,依次匹配,如果名称一样(比如http参数名是name, xxx这个类也有一个name字段,则将http参数name的值赋值给xxx这个类的对象的name字段)。

图片.png

最后是调用save生成数据库insert语句然后直接插入数据库,这里是没有过滤的。所以就导致了xss。

图片.png
有点意思的是,虽然开发者知道并且为之后的功能提前预留了过滤xss的发放,但实际上并没有重写方法。可以看到filter函数是一个空函数,所以并没有过滤xss的功能。

图片.png
最后前台效果如下:

图片.png

并且从后台取出sql数据的时候,也没有经过过滤,所以该xss也能够前台盲打后台。

图片.png

0x4 CSRF

后台/admin/admin/save路由,可以看到全程未有referer以及csrf-token校验。

图片.png

且观察前端代码也没有使用csrf-token进行校验

图片.png

poc:

<html>
  <body>
    <form action="http://localhost:8080/admin/admin/save" method="POST" name="form1" enctype="application/x-www-form-urlencoded" >
      <input type="hidden" name="username" value="test"/>
      <input type="hidden" name="password" value="test"/>
      <input type="hidden" name="rePassword" value="test"/>
      <input type="hidden" name="name" value="test"/>
      <input type="hidden" name="roleIds" value="1"/>
      <input type="submit" value="Submit request" />
    </form>
    <script>history.pushState('', '', '/');</script>
  </body>
</html>

登录管理员的情况下,可以看到成功附带cookie过去,并且成功的添加了test用户,并且登录成功。

图片.png
使用csrf添加的test账户成功登录后台。

图片.png

0x5 总结

在审计过程中如果时间关系不要紧的话可以采用debug大法一个一个参数跟踪,也可以采用白+黑的方式测试,这样能省一些事,但是还是得对代码漏洞的成因进行分析,因为这样其实能够找到更多漏洞,一个点有注入往往意味着整套程序都有注入。也可以学到一些开发姿势。而且以后在挖src或者其他什么情况没有思路的时候不要放弃任何一个页面(包括404)。

  • 发表于 2024-04-25 09:00:01
  • 阅读 ( 5109 )
  • 分类:代码审计

0 条评论

请先 登录 后评论
Whoisa
Whoisa

4 篇文章

站长统计