Java代码审计之hello博客系统
一. 第三方组件漏洞:
1.1 H2 Database (数据库)
H2 Database 是一个用 Java 编写的开源嵌入式关系数据库管理系统(RDBMS)。它被设计成轻量级、快速和可靠的数据库解决方案,适用于各种应用程序和平台。
1 | |
curl + 左键 点击h2 进入pom文件,版本号为1.4.197 版本存在 CVE-2021-42392 漏洞(远程代码执行漏洞/JNDI 注入漏洞)

利用前提:配置文件需要满足三点(src/main/resources/application.yaml)
- web-allow-others: true,这个设置允许其他网络上的计算机访问H2数据库的控制台。通常情况下,H2数据库的控制台只允许本地访问,但设置为 true 后,其他计算机也可以通过网络访问该控制台。
- enabled: true,这个设置启用了H2数据库的控制台。将其设置为 true 后,你就可以通过下述配置的路径访问H2数据库的控制台。
- 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

代码审计:
- 双击第 213 行的 fileName 参数,通过高亮显示 fileName 以及 type 参数在第 215 行处被使用
- 分析第 215 行,简单来说就是拼接了用户的主目录路径加上 /halo/backup/ 加上传递来的type 参数加上传递来的 fileName 参数,最终拼接成一个完整的路径赋值给 srcPath 参数。其中 type参数应该是其中一个路径。(getProperties() 和 getProperty() 是Java中 System 类的方法,用于获取系统属性。)
- getProperties() 方法返回一个 Properties 对象,该对象包含了当前Java虚拟机的系统属性。系统属性是一组由操作系统或Java虚拟机定义的全局变量,用于描述系统的各种配置和状态。
- getProperty(String key) 方法用于获取指定键(key)对应的系统属性值。它接受一个字符串参数key ,表示要获取的系统属性的键。
- 使用 getProperty(“user.home”) 即获取了系统属性中名为 user.home 的属性值,即当前用户的主目录路径。
- 单击 srcPath 的高亮显示,可以看到在第 217 行使用了 FileUtil.del 方法对srcPath 进行了操作,通过名字可以猜出这就是文件删除方法了。将鼠标悬停在该方法处,可以看到是hutool 组件下的方法
- 进入 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.1.3 SSRF 漏洞代码审计
正向梳理功能时,发现系统内安装主题处,可通过远程拉去的方式下载主题,可能会存在 SSRF 漏洞。

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

- 单击 remoteAddr 查看传递调用关系,在第 186 行处进行了 isBlank 判空操作,没什么其他值得注意的。然后就直接到第 190 行,进行了 git clone 拼接传入的 remoteAddr 参数操作,使用的是 RuntimeUtil.execForStr 方法执行命令
- 分析 RuntimeUtil.execForStr 方法。Ctrl加鼠标左键点击 execForStr,进入该方法,发现该方法是 Hutool 组件下的工具类,其中底层就是使用的 ProcessBuilder 执行的命令,没什么其他额外需要注意的代码
- 总结来说,底层使用 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

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

2.1.5 漏洞复现
