返回

文章详情

窃取我的比特币 CTF 演示

Hacker News2026年10月26日 00:15

用 ❤️ 赞助的窃取我的比特币 CTF 概念验证。一个针对窃取我的比特币挑战的实时 PHP 回调,从开始到结束,在一个标准库的 Python 文件中。这份 README 解释了 stealmybitcoin_poc.py ,这是我在窃取我的比特币 CTF 运行中使用的请求序列的单文件 Python 复现。它仅使用 Python 的标准库。这个脚本自行构造请求,在继续之前检查每个泄漏,并记录新运行的 HTTP 字节。这可能可以更简单地做到,而不需要所有额外的调试垃圾,就像我关于 Steam 本地特权提升的 John Hammond 视频中发现的那样,您可能可以清理这个丑陋的演示。注意 ⚠️ 诚实地请清理它,或者制作您自己的更好的版本,而不是被 Sol 处置的。⚠️ 下面的所有内容都是针对 Docker 实验室,而不是实时挑战。实验室是一个本地的 Alpine PHP 8.4.26 CLI 服务器,位于 nginx 后面,这与校准偏移的构建和工作模型相同。只需一分钟就可以启动它,整个链条就可以在您自己的机器上端到端运行。实际上解决挑战的实时运行作为历史备注保留在底部。发送什么,返回什么 ───────────────────────────────────────────────────────────────────────────── 0 健康检查 GET /php-version.php -> PHP 8.4.26 确认 1 堆泄漏 249,042 B 生产者 + 8 x 6,672 B -> 256 B cookie (OOM 使一个工作者失效) └─ Zend chunk base 2 代码泄漏 251,557 B 生产者 + 8 x 92,388 B -> 16 B cookie (OOM 使一个工作者失效) └─ zval_ptr_dtor 3 回调 368,812 B POST -> 伪造 HashTable 运行 (假 HashTable + 命令) └─ zif_system(cmd) ───────────────────────────────────────────────────────────────────────────── 最多 20 个 HTTP 请求。没有循环,没有重试。简短版本 小的多部分上传使得 PHP 在内存使用上大幅超出传输大小所示。当它在会话上传进度解析途中耗尽内存时,PHP 会在一个工作者中留下过时状态,然后再次被重用。正确构造后续请求,字节会通过会话 cookie 泄漏。我将这些读取为堆地址和 PHP 代码地址。通过这两个地址,最终请求会放置一个伪造的 PHP 结构,在清理时可以找到它,而清理会调用 zif_system,PHP 的系统处理程序。该命令通过仍然开放的连接发送一个新的证明标记和一个打印标志结果。为什么需要两个地址?操作系统随机化 PHP 的代码和堆的位置,相互独立。堆泄漏告诉脚本将伪造结构放在哪里,而代码泄漏则告诉它想要调用的函数实际存在的位置。来自早期工作者或早期运行的地址不是安全的替代品,我每次尝试时,尝试都会失败。内容 实验室 从这里开始 每个请求的作用 1. 小生产者如何达到内存限制 2. 如何恢复堆地址 3. 如何恢复 PHP 代码地址 4. 如何最终请求达到系统 读取结果 实际上运作的频率 实际解决它的实时运行 行话,简短 感谢 实验室 此 PoC 中的偏移量是为运行内置 CLI 服务器的 Alpine PHP 8.4.26 调校,具有四个工作者。实验室完全复现了这一点,在 nginx 后面,通过回环。重要的是 构建比版本字符串更重要。一个 Debian php:8.4.26-fpm 栈报告相同的 PHP/8.4.26,但具有不同的二进制布局,因此代码指针指纹将永远不会匹配,运行在代码泄漏阶段中止。请使用下面的 Alpine 镜像。三个小文件。将它们放在空目录中: public/php-version.php(健康端点,演示所需的唯一页面)<?php header('Content-Type: text/plain'); echo 'PHP ', PHP_VERSION, ' '; echo 'PID: ', getmypid(), ' '; print-flag(作为挑战二进制文件的占位符,必须是可执行的) #! /bin/sh printf ' %s ' 'LOCAL_DUMMY_WIF_NEVER_USE' nginx.conf events {} http { server { listen 80; server_name _; location / { proxy_pass http ://ctf-cross-php: 8000; proxy_http_version 1.1; proxy_set_header Host $host; } } } 然后启动它: docker network create ctf-cross-net docker run -d --name ctf-cross-php --network ctf-cross-net --read-only --tmpfs /tmp:rw,size=32m,mode=1777 --memory 1g -v "$PWD /public:/app:ro" -v "$PWD /print-flag:/usr/local/bin/print-flag:ro" -e PHP_CLI_SERVER_WORKERS=4 php:8.4.26-fpm-alpine3.23 php -S 0.0.0.0:8000 -t /app docker run -d --name ctf-cross-nginx --network ctf-cross-net -p 127.0.0.1:18166:80 -v "$PWD /nginx.conf:/etc/nginx/nginx.conf:ro" nginx:1.27-alpine 检查它: $ curl -s http://127.0.0.1:18166/php-version.php PHP 8.4.26 PID: 1 PID 随着响应的工作者而变化,这是正常的。版本行是演示检查的部分。用以下命令拆除: docker rm -f ctf-cross-nginx ctf-cross-php && docker network rm ctf-cross-net。提示 在 Windows 上,从 PowerShell 运行这些 docker run 命令,或者将 $PWD 替换为类似 C:/lab 的完整驱动器路径。

阅读全文 →

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

☕请我喝杯咖啡