Java代码审计之hello博客系统

一. 第三方组件漏洞:

1.1 H2 Database (数据库)

H2 Database 是一个用 Java 编写的开源嵌入式关系数据库管理系统(RDBMS)。它被设计成轻量级、快速和可靠的数据库解决方案,适用于各种应用程序和平台。

1
2
3
4
5
6
<!-- H2Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

curl + 左键 点击h2 进入pom文件,版本号为1.4.197 版本存在 CVE-2021-42392 漏洞(远程代码执行漏洞/JNDI 注入漏洞)

利用前提:配置文件需要满足三点(src/main/resources/application.yaml)

  1. web-allow-others: true,这个设置允许其他网络上的计算机访问H2数据库的控制台。通常情况下,H2数据库的控制台只允许本地访问,但设置为 true 后,其他计算机也可以通过网络访问该控制台。
  2. enabled: true,这个设置启用了H2数据库的控制台。将其设置为 true 后,你就可以通过下述配置的路径访问H2数据库的控制台。
  3. path: /h2-console,这是H2数据库控制台的路径配置。它指定了通过Web浏览器访问控制台的URL路径。在这个例子中,控制台可以通过 http://yourdomain/h2-consol

访问 http://localhost:8090/h2-console/login.jsp ,可以看到 H2 控制台

二. 单点漏洞审计

2.1.1 任意文件删除漏洞代码审计

先进行添加备份的操作:

正向梳理功能时,发现后台设置下博客备份功能存在一个删除功能,通过抓包发现是根据文件名进行的删除操作,可能存在任意文件删除漏洞,如下图所示:

通过抓包获取到接口名为 /admin/backup/delBackup,通过关键字逐一尝试,最终使用关键字delBackup 定位到该接口的 Controller 层代码为 BackupController

代码审计:

  1. 双击第 213 行的 fileName 参数,通过高亮显示 fileName 以及 type 参数在第 215 行处被使用
  2. 分析第 215 行,简单来说就是拼接了用户的主目录路径加上 /halo/backup/ 加上传递来的type 参数加上传递来的 fileName 参数,最终拼接成一个完整的路径赋值给 srcPath 参数。其中 type参数应该是其中一个路径。(getProperties() 和 getProperty() 是Java中 System 类的方法,用于获取系统属性。)
    1. getProperties() 方法返回一个 Properties 对象,该对象包含了当前Java虚拟机的系统属性。系统属性是一组由操作系统或Java虚拟机定义的全局变量,用于描述系统的各种配置和状态。
    2. getProperty(String key) 方法用于获取指定键(key)对应的系统属性值。它接受一个字符串参数key ,表示要获取的系统属性的键。
    3. 使用 getProperty(“user.home”) 即获取了系统属性中名为 user.home 的属性值,即当前用户的主目录路径。
  3. 单击 srcPath 的高亮显示,可以看到在第 217 行使用了 FileUtil.del 方法对srcPath 进行了操作,通过名字可以猜出这就是文件删除方法了。将鼠标悬停在该方法处,可以看到是hutool 组件下的方法
  4. 进入 FileUtil.del 方法,就是单纯的删除操作。(一般来说组件本身不会做任意文件操作防护的,因此需要自行编写防护代码,从上述两步操作中可以看到,该接口并没有任何防止跨目录的操作,从功能点思考可能会造成任意文件删除漏洞。)

2.1.2 漏洞验证

通过上面的分析可以看见路径是C:\Users\HW/halo/backup/posts/posts_backup_20250617153812.zip,在C:\Users\HW/halo/backup/路径下添加一个文件,以便测试

验证步骤:

​ 在后端页面的备份管理处点击删除按钮,并进行抓包,将fileName参数后面的文件写成想要删除的文件名demo.txt(注意需要目录穿越一下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /admin/backup/delBackup?type=posts&fileName=../demo.txt HTTP/1.1
Host: localhost:8090
Cookie: JSESSIONID=06gI4Fomcb1KJ0qNhp-ooVhbPFPz2W5ZxmIRA9Nj
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://localhost:8090/admin/backup?type=posts
Accept-Encoding: gzip, deflate, br, zstd
Sec-Fetch-Dest: empty
sec-ch-ua-platform: "Windows"
Sec-Fetch-Mode: cors
Accept-Language: zh-CN,zh;q=0.9
sec-ch-ua: "Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0

删除成功:

2.1.3 SSRF 漏洞代码审计

正向梳理功能时,发现系统内安装主题处,可通过远程拉去的方式下载主题,可能会存在 SSRF 漏洞。

通过抓包获取到接口名是 /admin/themes/clone ,关键字搜索/clone 定位到该接口的 Controller 层代码为 ThemeController

  1. 单击 remoteAddr 查看传递调用关系,在第 186 行处进行了 isBlank 判空操作,没什么其他值得注意的。然后就直接到第 190 行,进行了 git clone 拼接传入的 remoteAddr 参数操作,使用的是 RuntimeUtil.execForStr 方法执行命令
  2. 分析 RuntimeUtil.execForStr 方法。Ctrl加鼠标左键点击 execForStr,进入该方法,发现该方法是 Hutool 组件下的工具类,其中底层就是使用的 ProcessBuilder 执行的命令,没什么其他额外需要注意的代码
  3. 总结来说,底层使用 ProcessBuilder 执行了 git clone 拼接 remoteAddr 的命令,其中remoteAddr 我们可控,进而通过 git clone 可以进行了网络请求操作,导致触发 SSRF 漏洞。简单说就是 ProcessBuilder 命令执行加上 git clone 触发的 SSRF 漏洞

2.1.3 漏洞验证:

也可以探测内网端口开放情况,通过响应时长判断出端口开放情况

2.1.4 任意文件写入

正向梳理功能时发现系统内存在一处主题编辑功能,通过文件名进行内容写入,可能存在任意文件写入漏洞

过抓包获取到接口名为 /admin/themes/editor/save ,通过关键字逐一尝试,最终使用关键字 /editor/save 定位到该接口的 Controller 层代码为 ThemeController

代码审计分析:

  1. 第一步,可以看到接口接收两个参数分别为 tplName 和 tplContent,通过抓取接口数据包时,我们可以知道 tplName 为模板名字,tplContent 为写入内容
  2. 分析上图第 304 到 307 行代码,通过注释了解这部分代码为 获取主题路径 ,具体操作为该部分代码使用了一个名为 StrBuilder 的类来构建字符串 templates/themes/ 并赋值给 themePath,然后进行了三次追加操作,也就说在 templates/themes/ 的路径上追加了BaseController.THEME , / 以及我们传入的 tplName 参数,其中 BaseController.THEME 点击跟踪,发现值为 anatole 。
  3. 分析第 308 行代码,创建了一个 File 对象,传入的两个参数为basePath.getAbsolutePath() 和 themePath.toString() ,themePath 就不说了,就是上面获取主题路径操作,只不过进行了 toString() 操作。而 basePath.getAbsolutePath() 来自第 302 行,根据注释该段代码操作为 获取项目根路径 ,使用了ResourceUtils.getURL(“classpath:”).getPath() 方法。最后,使用 basePath.getAbsolutePath() 来获取文件的绝对路径, getAbsolutePath() 是 File 类中的一个方法。
  4. 分析最后两行,这就很简单了,就是创建一个 FileWriter 对象,用于将内容写入到模板文件中,其中 tplPath 就是上面分析的路径,tplContent 就是从前端传来的参数,也就是写入的内容。其中要注意的是,使用 FileWriter 对象写入内容,如果指定的文件路径不存在的话, FileWriter 会自动创建一个新的文件

2.1.5 漏洞复现


Java代码审计之hello博客系统
http://example.com/2025/06/17/Java代码审计之hello博客系统/
作者
XCDH
发布于
2025年6月17日
许可协议