记一道java文件上传目录穿梭修复
进来先ls看文件:

看看readme

要求不改原本的业务逻辑修改jar包,那就是java的漏洞修复了。
按题目要求的下载文件:

拿到jar包过后改后缀为.zip解压,然后丢到idea里面看

总共就三个类
package com.xiinnn;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Value("${my.uploadPath}")
private String uploadPath;
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(new String[]{this.uploadPath + "/**"}).addResourceLocations(new String[]{"file:" + this.uploadPath + "/"});
}
}
package com.xiinnn;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class MyController {
@PostMapping({"/doUpload"})
public String uploadJpgImage(@RequestParam("file") MultipartFile file) throws Exception {
String hint = "提示:本处仅允许上传jpg文件";
String fileName = file.getOriginalFilename();
if (!fileName.contains(".jpg")) {
return "nonono";
} else {
Path targetDirectory = Paths.get("upload/").toAbsolutePath();
Path targetPath = targetDirectory.resolve(fileName);
if (!Files.exists(targetDirectory, new LinkOption[0])) {
Files.createDirectories(targetDirectory);
}
Files.copy(file.getInputStream(), targetPath, new CopyOption[0]);
String absolutePath = targetPath.toString();
return absolutePath;
}
}
@GetMapping({"/"})
public String index() {
return "<form action="/doUpload" method="post" enctype="multipart/form-data" id="form">n <label for="file">文件: </label>n <input type="file" name="file" id="file"><br>n <input type="submit" name="submit" value="提交">n</form>";
}
}
package com.xiinnn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class, args);
}
}
然后发现在MyController类中,String fileName = file.getOriginalFilename();直接拿用户的输入来拼接上传路径,如果用户传的文件名是../../hack等会导致文件目录穿梭,写道upload/外的地方
我们用idea新建一个项目,复制之前jar包里面的application,yml和pom.xml,然后复制对应的类名和包名

然后贴一下修正后的代码
package com.xiinnn;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
@RestController
public class MyController {
@PostMapping("/doUpload")
public String uploadJpgImage(@RequestParam("file") MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();
if (originalFilename == null) {
return "nonono";
}
String fileName = Paths.get(originalFilename).getFileName().toString();
if (!fileName.toLowerCase(Locale.ROOT).endsWith(".jpg")) {
return "nonono";
}
Path targetDirectory = Paths.get("upload").toAbsolutePath().normalize();
Path targetPath = targetDirectory.resolve(fileName).normalize();
if (!targetPath.startsWith(targetDirectory)) {
return "nonono";
}
if (!Files.exists(targetDirectory)) {
Files.createDirectories(targetDirectory);
}
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, targetPath);
}
return targetPath.toString();
}
@GetMapping("/")
public String index() {
return "<form action="/doUpload" method="post" enctype="multipart/form-data" id="form">n"
+ " <label for="file">文件: </label>n"
+ " <input type="file" name="file" id="file"><br>n"
+ " <input type="submit" name="submit" value="提交">n"
+ "</form>";
}
}
package com.xiinnn;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Value("${my.uploadPath}")
private String uploadPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(uploadPath + "/**")
.addResourceLocations("file:" + uploadPath + "/");
}
}
package com.xiinnn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class, args);
}
}
然后直接在maven面板双击package生成新的jar包上传即可(在target里面)


先删除服务器里之前的jar包

然后在对应目录上传我们的jar包

然后按题目要求重启服务,等15秒读裁判机生成的flag即可
