Bootstrap

85.[1] 攻防世界 WEB easyphp

进入靶场

属于代码审计

<?php
// 高亮显示当前 PHP 文件的源代码,常用于调试或展示代码
highlight_file(__FILE__);

// 初始化两个标志变量,用于后续条件判断
$key1 = 0;
$key2 = 0;

// 从 GET 请求中获取参数 'a' 和 'b'
$a = $_GET['a'];
$b = $_GET['b'];

// 检查参数 'a' 是否存在,并且将其转换为整数后大于 6000000,同时其字符串长度小于等于 3
if (isset($a) && intval($a) > 6000000 && strlen($a) <= 3) {
    // 检查参数 'b' 是否存在,并且其 MD5 哈希值的最后 6 位等于 '8b184b'
    if (isset($b) && '8b184b' === substr(md5($b), -6, 6)) {
        // 如果上述条件都满足,将 $key1 标志设置为 1,表示通过了这部分验证
        $key1 = 1;
    } else {
        // 如果参数 'b' 不满足条件,输出提示信息并终止脚本执行
        die("Emmm...再想想");
    }
} else {
    // 如果参数 'a' 不满足条件,输出提示信息并终止脚本执行
    die("Emmm...");
}

// 从 GET 请求中获取参数 'c',并尝试将其作为 JSON 字符串解码为数组
$c = (array)json_decode(@$_GET['c']);

// 检查 $c 是否为数组,并且其键 'm' 对应的值不是数字类型,但在比较时大于 2022
if (is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022) {
    // 检查 $c 数组中键 'n' 对应的值是否为数组,并且该数组的元素数量为 2,同时第一个元素也是数组
    if (is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])) {
        // 在 $c["n"] 数组中搜索值为 'DGGJ' 的元素,并返回其键名
        $d = array_search("DGGJ", $c["n"]);
        // 如果未找到 'DGGJ',输出提示信息并终止脚本执行
        $d === false? die("no...") : NULL;
        // 遍历 $c["n"] 数组
        foreach ($c["n"] as $key => $val) {
            // 如果数组中的某个元素等于 'DGGJ',输出提示信息并终止脚本执行
            $val === "DGGJ"? die("no......") : NULL;
        }
        // 如果上述条件都满足,将 $key2 标志设置为 1,表示通过了这部分验证
        $key2 = 1;
    } else {
        // 如果 $c["n"] 不满足条件,输出提示信息并终止脚本执行
        die("no hack");
    }
} else {
    // 如果 $c 不满足条件,输出提示信息并终止脚本执行
    die("no");
}

// 检查 $key1 和 $key2 标志是否都为 1,如果是,则表示所有验证都通过
if ($key1 && $key2) {
    // 包含名为 'Hgfks.php' 的文件,通常该文件中定义了 $flag 变量
    include "Hgfks.php";
    // 输出验证成功的提示信息
    echo "You're right" . "\n";
    // 输出 $flag 变量的值,可能是一个关键信息,如密钥、标志等
    echo $flag;
}

?>

具体条件包括:

  1. GET 参数 a 转换为整数后大于 6000000 且字符串长度不超过 3。
  2. GET 参数 b 的 MD5 哈希值最后 6 位为 8b184b
  3. GET 参数 c 解码为数组后,其键 m 对应的值不是数字但大于 2022,键 n 对应的值是一个包含两个元素且第一个元素为数组的数组,并且 n 数组中存在但又不能直接等于 DGGJ

 在 PHP 中,对于科学计数法表示的字符串,intval 函数会正确转换其值,所以可以使用科学计数法来构造 a

a=1e9

可以通过编写一个简单的 Python 脚本来暴力破解满足条件的 b

import hashlib

# 初始化计数器 i,用于从 0 开始逐个尝试不同的数值
i = 0

# 开始一个无限循环,不断尝试不同的数值,直到找到满足条件的 b 值
while True:
    # 将当前的计数器值 i 转换为字符串,并使用 encode() 方法将其编码为字节串
    # 因为 hashlib.md5() 函数要求输入为字节串
    s = str(i).encode()

    # 计算 s 的 MD5 哈希值,并将结果以十六进制字符串的形式存储在 md5_hash 变量中
    md5_hash = hashlib.md5(s).hexdigest()

    # 检查计算得到的 MD5 哈希值的最后 6 位是否等于 '8b184b'
    if md5_hash[-6:] == '8b184b':
        # 如果满足条件,打印出找到的满足条件的 b 值
        print(f"找到满足条件的 b: {i}")
        # 跳出无限循环,结束程序
        break

    # 如果当前的 i 值不满足条件,将计数器 i 的值加 1,继续尝试下一个数值
    i += 1

运行

得到

b=53724

自行构造c

因为两个函数相互矛盾,需要绕过一个

c={"m":"2023a","n":[[1,2,3],0]}

最终payload

a=1e9&b=53724&​c={"m":"2023a","n":[[1,2,3],0]}

 

注意最后的传参方式

按理说/?即可以get方式传参

但我传的时候不那么顺利

大家也可以试试postman或者BP

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;