前言
最近在出题的时候,不知道为啥,做的php题目本地跑很正常,但是到平台上就跑不起来,后来我决定用python模拟了php弱比较漏洞,然后把代码分享给大家看看
代码
from flask import Flask, request
import hashlib
import os
app = Flask(__name__)
FLAG = os.environ.get('GZCTF_FLAG') //这是平台的Flag环境变量,大家可以根据自己的需求更改
st = """
<?php
$a = $_GET['a'];
$b = $_GET['b'];
if ($a !== null && $b !== null && $a != $b) {
if (md5($a) == md5($b)) {
echo $flag;
}
}
highlight_string($code);
?>
"""
def is_php_md5_collision(val):
"""检测是否符合 PHP 弱比较漏洞"""
md5_hash = hashlib.md5(val.encode()).hexdigest()
return md5_hash.startswith("0e") and md5_hash[2:].isdigit()
@app.route("/")
def challenge():
a = request.args.get("a", "")
b = request.args.get("b", "")
if a and b and a != b:
if is_php_md5_collision(a) and is_php_md5_collision(b): # 模拟 PHP 的漏洞
return f"代码在哪里?\n{st}\n{FLAG}"
return f"代码在哪里?\n{st}\nERROR"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
哈哈,这个问题很有趣。想象一下,当我期望返回的是php代码,实际上返回的是python代码,这种情况很有意思,简单的说一下PHP弱比较漏洞吧
漏洞讲解
获取两个变量a和b,然后判断他们是否是同一个值,如果是,就返回错误,否则就进行md5加密,然后就是著名的0e漏洞
因为处理hash字符串时,PHP会将每一个以 0E开头的哈希值解释为0,那么只要传入的不同字符串经过哈希以后是以 0E开头的,那么PHP会认为它们相同
参考链接:
2: PHP md5 相等绕过