视频教程:
https://www.bilibili.com/video/BV1KT421k7ZE
主要内容:
1、目录穿越原因以及示例代码
2、任意文件下载和任意目录列出代码示例
3、解压文件时候的目录穿越问题
4、目录穿越防御方式
入群二维码(如果失效后台回复进群即可):
目录穿越
根本原因:在使用 new File(filePath)的时候,filePath可控,并且未对filePath做严格校验,攻击者可以通过 ../ 的方式进行目录条约,实现任意文件下载或 跨目录上传文件漏洞。
示例代码:
public static void main(String[] args) throws Exception {
String filename = "/aaa/../../velocityDemo.html";
String filePath = System.getProperty("user.dir") + "/logs/" + filename;
System.out.println(filePath);
File file = new File(filePath);
// 读取文件内容
InputStream inputStream = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF8"));
String line ;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
任意文件下载
public String download(String filename, HttpServletResponse response) {
// 下载的文件路径
String filePath = System.getProperty("user.dir") + "/logs/" + filename;
log.info("[vul] 任意文件下载:" + filePath);
try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(filePath)))) {
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
response.setContentLength((int) Files.size(Paths.get(filePath)));
response.setContentType("application/octet-stream");
// 使用 Apache Commons IO 库的工具方法将输入流中的数据拷贝到输出流中
IOUtils.copy(inputStream, response.getOutputStream());
log.info("文件 {} 下载成功,路径:{}", filename, filePath);
return "下载文件成功:" + filePath;
} catch (IOException e) {
log.error("下载文件失败,路径:{}", filePath, e);
return "未找到文件:" + filePath;
}
}
任意文件下载进阶利用
SpringBoot一般来说是通过jar包来启动服务,所以通过任意文件下载漏洞最有利用价值的是下载到SpringBoot对应的jar包。
这里可以组合linux文件下载中的多个文件,构造一条SpringBoot任意文件下载利用链,如下所示。
【Step1】定位启动的时候jar包的pid
通过任意文件读取/proc/sched_debug,获取服务器中的进程信息。通过关键字java定位SpringBoot对应的进程,获取进程号pid。
【Step2】获取jar包绝对路径
通过/proc/[PID]/cmdline和/proc/[PID]/environ获取进程对应的信息,一般情况下通过这种方式可以拿到SpringBoot对应的jar包的绝对路径。其中cmdline可以获取进程对应的包名,environ可以获取对应的绝对路径,组合之后可以得到jar包对应绝对路径。
任意路径遍历
"/list") (
public String fileList(String filename) {
String filePath = System.getProperty("user.dir") + "/logs/" + filename;
log.info("[vul] 任意路径遍历:" + filePath);
StringBuilder sb = new StringBuilder();
File f = new File(filePath);
File[] fs = f.listFiles();
if (fs != null) {
for (File ff : fs) {
sb.append(ff.getName()).append("<br>");
}
return sb.toString();
}
return filePath + "目录不存在!";
}
修复方式
public String safe(String filename) {
if (!checkTraversal(filename)) {
String filePath = System.getProperty("user.dir") + "/logs/" + filename;
return "安全路径:" + filePath;
} else {
return "检测到非法遍历!";
}
}
/**
* 目录遍历检测
*/
public boolean checkTraversal(String content) {
return content.contains("..") || content.contains("/");
}
Zip Slip系列漏洞
作为一名开发人员,您经常需要处理zip文件。例如,考虑上传功能或处理作为zip文件上传的一堆CSV文件。Snyk安全团队发现并负责任地披露了一个整洁的漏洞。它使用路径遍历,可以在提取文件时使用。通过路径遍历,您可以尝试覆盖目标文件夹之外的文件。例如,您可以在提取zip文件时覆盖ls命令。在每次用户在ls中键入命令时,将该命令替换为一些额外的恶意操作后,您可以在向用户显示实际命令之前将清单的结果发送到服务器。所以你最终会得到远程命令执行。
示例代码:
public static void main(String[] args) throws Exception {
String filePath = System.getProperty("user.dir") + "\zip";
ZipFile zip = new ZipFile(new File(filePath + "\out.zip"));
// 创建一个指定目录用于存储解压后的文件
File destinationDir = new File(filePath + "\zipSlid");
// 获取 ZIP 文件中的所有条目
Enumeration<? extends ZipEntry> entries = zip.entries();
// 遍历 ZIP 文件中的每个条目
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
// 构建目标文件对象,使用解压后的文件名和指定的存储目录
File f = new File(destinationDir, e.getName());
// 从 ZIP 条目中获取输入流
InputStream is = zip.getInputStream(e);
// 将输入流内容复制到目标文件
// (注意:copy 方法需要定义,可能是第三方库 IOUtils 提供的)
IOUtils.copy(is,new FileOutputStream(f));
}
}
使用python生成zip文件
import zipfile
# the name of the zip file to generate
zf = zipfile.ZipFile('out.zip', 'w')
# the name of the malicious file that will overwrite the origial file (must exist on disk)
fname = 'sec_test.txt'
#destination path of the file
zf.write(fname, '../../../../../../../../../../../../../../../../../../../../../../../../tmp/sec_test.tmp')
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...