92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
|
|
""" TEST_CONFIG
|
|||
|
|
{
|
|||
|
|
"name": "escape_security_test",
|
|||
|
|
"limits": { "cpu": 1.0, "mem": 0.2 }
|
|||
|
|
}
|
|||
|
|
"""
|
|||
|
|
import os, sys, json, platform
|
|||
|
|
|
|||
|
|
def run_test():
|
|||
|
|
is_darwin = platform.system().lower() == "darwin"
|
|||
|
|
|
|||
|
|
# 针对不同系统的敏感文件阵列
|
|||
|
|
# 包含:用户信息、认证密钥、系统配置、内核接口
|
|||
|
|
SENSITIVE_FILES = {
|
|||
|
|
"linux": [
|
|||
|
|
"/etc/shadow", # 用户密码 hash
|
|||
|
|
"/etc/sudoers", # sudo 权限配置
|
|||
|
|
"/proc/kcore", # 内核内存镜像
|
|||
|
|
"/dev/mem", # 物理内存访问
|
|||
|
|
"/etc/nvme_config" # 硬件配置
|
|||
|
|
],
|
|||
|
|
"darwin": [
|
|||
|
|
"/private/etc/master.passwd", # 系统用户数据库
|
|||
|
|
"/private/etc/sudoers",
|
|||
|
|
"/Library/Keychains/System.keychain", # 系统钥匙串
|
|||
|
|
"/dev/disk0s1" # 原始磁盘设备
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
target_files = SENSITIVE_FILES["darwin"] if is_darwin else SENSITIVE_FILES["linux"]
|
|||
|
|
|
|||
|
|
results = {
|
|||
|
|
"access_denied_count": 0,
|
|||
|
|
"failed_files": [],
|
|||
|
|
"chroot_escape_attempt": False,
|
|||
|
|
"proc_isolation_check": True
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 1. 深度文件嗅探测试
|
|||
|
|
for f in target_files:
|
|||
|
|
try:
|
|||
|
|
if os.path.exists(f):
|
|||
|
|
with open(f, 'rb') as fd:
|
|||
|
|
fd.read(1)
|
|||
|
|
# 如果能读到,记录失败
|
|||
|
|
results["failed_files"].append(f)
|
|||
|
|
else:
|
|||
|
|
# 文件不存在也是一种隔离成功
|
|||
|
|
results["access_denied_count"] += 1
|
|||
|
|
except (PermissionError, OSError):
|
|||
|
|
results["access_denied_count"] += 1
|
|||
|
|
|
|||
|
|
# 2. 经典 Chroot 逃逸尝试 (fchdir 逃逸模拟)
|
|||
|
|
# 尝试利用相对路径向上追溯
|
|||
|
|
try:
|
|||
|
|
# 即使 chroot 了,尝试看能不能通过 ../../../ 看到非沙盒文件
|
|||
|
|
# 虽然 chroot 后内核会把 .. 指向 /,但这里做双重保险验证
|
|||
|
|
root_content = os.listdir("../../../../../../../")
|
|||
|
|
# 这里的判断逻辑:沙盒内的根目录应该很纯净,不应有常见的宿主机大目录
|
|||
|
|
if not is_darwin:
|
|||
|
|
# Linux 下,如果看到了 vmlinuz 或 boot 目录,说明逃逸了
|
|||
|
|
if "boot" in root_content or "vmlinuz" in root_content:
|
|||
|
|
results["chroot_escape_attempt"] = True
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
# 3. 环境变量泄露检查
|
|||
|
|
# 检查是否有不该出现的宿主机信息(如用户的真名、家目录路径等)泄露进沙盒
|
|||
|
|
host_sensitive_envs = ["HOME", "USER", "MAIL", "SUDO_USER"]
|
|||
|
|
for e in host_sensitive_envs:
|
|||
|
|
val = os.environ.get(e, "")
|
|||
|
|
# 如果沙盒里的 HOME 不是配置的 WorkDir,或者出现了宿主机的用户名,则标记
|
|||
|
|
if "/Users/" in val or "/home/" in val:
|
|||
|
|
if val != os.environ.get("HOME"): # 排除掉 init 设置的 HOME
|
|||
|
|
results["failed_files"].append(f"ENV_LEAK:{e}")
|
|||
|
|
|
|||
|
|
# 综合判定
|
|||
|
|
# 只要 failed_files 为空,且没有逃逸迹象
|
|||
|
|
test_success = (len(results["failed_files"]) == 0 and
|
|||
|
|
results["chroot_escape_attempt"] is False)
|
|||
|
|
|
|||
|
|
print(json.dumps({
|
|||
|
|
"testSuccess": test_success,
|
|||
|
|
"details": {
|
|||
|
|
"total_checked": len(target_files),
|
|||
|
|
"denied": results["access_denied_count"],
|
|||
|
|
"failed_items": results["failed_files"]
|
|||
|
|
}
|
|||
|
|
}, indent=2))
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
run_test()
|