NSSCTF | [SWPUCTF 2021 新生赛]easy_md5

打开题目,是一个高亮显示的php脚本

php 复制代码
<?php 
 highlight_file(__FILE__);
 include 'flag2.php';
 
if (isset($_GET['name']) && isset($_POST['password'])){
    $name = $_GET['name'];
    $password = $_POST['password'];
    if ($name != $password && md5($name) == md5($password)){
        echo $flag;
    }
    else {
        echo "wrong!";
    }
 
}
else {
    echo 'wrong!';
}
?>

这段PHP代码用于演示一个典型的安全挑战,特别是关于PHP中md5哈希函数的特性和弱类型比较的问题。以下是逐行分析:

第1行:展示当前文件源代码

通过highlight_file(__FILE__);展示当前文件的源代码。__FILE__是一个特殊的预定义常量,表示当前文件的完整路径和文件名。

第2行:包含外部文件

include 'flag2.php';引入外部文件flag2.php。我们可以假设这个文件定义了一个名为$flag的变量,其中包含了需要在满足特定条件下显示的敏感信息(即"flag")。

第3-17行:校验GET和POST参数

代码首先检查是否同时通过GET方法提交了name参数和通过POST方法提交了password参数。如果没有,输出"wrong!"。

如果两个参数都存在,分别将它们赋值给变量$name$password

条件判断和漏洞点

核心逻辑在于这个条件判断:

复制代码
if ($name != $password && md5($name) == md5($password)){
    echo $flag;
}
  • 条件要求$name$password不相等,但它们的MD5哈希值必须相等,才会输出$flag变量的值(即满足挑战条件)。
  • 这里利用的是PHP中md5哈希函数的特性和弱类型比较(==)。在某些特殊情况下,不同的输入可以产生相同的MD5哈希值长文本输出(尽管这是极为罕见的),或者在使用==进行比较时利用PHP弱类型的特性来绕过检查。

实际上,满足这个条件的一个通常方法是利用PHP中的"魔术哈希"(Magic Hash)问题。"魔术哈希"是指一些特殊值,它们的MD5哈希值以"0e"开头,接下来是纯数字,这在PHP中会被解释为科学记数法表示的0,导致弱类型比较时等于另一个具有相同特性的哈希值。

总结

这个脚本的挑战点在于找到使得$name$password的MD5哈希值在弱类型比较下相等,但这两个值本身并不相等的输入。正确的解决方式通常涉及寻找或利用已知的"魔术哈希"值。

这道题有两种解法,一种是寻找两变量值不相等,但md5后的散列值相等的一组数据,分别使用GET和POST两种请求方法传入即可得到flag。

另一种是通过数组绕过的方式。

第一种解法:md5绕过

介绍几个符合两变量值不相等,但md5后的散列值相等的数据

php 复制代码
//md5加密后以0E开头,且后面均为纯数字
QNKCDZO
240610708
s878926199a
s155964671a

然后利用Hackbar传参即可得到flag。

payload:?name=QNKCDZO

POST:password=240610708

第二种方法:数组绕过

payload:?name\[\]=1

POST:password\[\]=2

PHP 中的 md5 函数在处理字符串时运行正常,但如果传入的是一个数组,md5 函数返回 NULL。在 PHP 中,当你尝试对一个数组使用 md5() 函数时,会发生类型错误,因为 md5 预期的是一个字符串。如果请求的参数是一个数组(例如通过 name[]=1),则 $_GET['name']$_POST['password'] 将会是数组而不是字符串。

那么,在提及的代码逻辑中,当同时使用GET传参 ?name[]=1 和POST传参 password[]=2 时,$name$password 都会成为数组。这将导致条件:

复制代码
if ($name != $password && md5($name) == md5($password)){
    echo $flag;
}

结果如下:

  • $name != $password 返回 true,因为两个数组不相等。
  • 由于 PHP 会对名称后带 [] 的参数自动创建数组,因此 md5($name)md5($password) 都会尝试对数组进行哈希处理,导致它们都返回 NULL 或者产生一个警告并返回一个布尔值 false
  • 在 PHP 中,(NULL == NULL) 为 true,(false == false) 也为 true。因此使得 md5($name) == md5($password) 返回 true,而忽略了实际哈希值因为它们都是 NULL 或者 false。

因此尽管 $name$password 都没有被哈希处理,但由于它们都返回了 NULL 或者 false,相等性比较因类型转换返回了 true,从而导致它们按照代码的逻辑满足了输出 $flag 的条件。这是一个类型弱检查的问题,说明==在 PHP 中可能会导致一些非预期的行为,尤其是当比较的值中包含非字符串类型,像是数组时。

本题完。

相关推荐
Lorin 洛林21 小时前
一文读懂 Agent Skills
前端·网络
风中芦苇啊1 天前
从直接生成到受控配置:新一代图表Agent的SQL安全生成范式
数据库·sql·安全
泛普软件1 天前
企业项目管理软件如何选型?统筹多项目资源把控交付与盈利水平
大数据·安全
andxe1 天前
安科士AndXe 400G QSFP-DD LR8光模块芯片架构与品控体系解析
网络·光模块·光通信
去码头整点薯条981 天前
网络实验报告10
网络
坚定的共产主义生产设备永不宕机1 天前
路由协议OSPF进阶一篇讲全
网络
碎碎念_4921 天前
以太网技术、VLAN、STP详解
网络·stp·vlan
云水一下1 天前
DVWA从入门到精通(四):CSRF(跨站请求伪造)
安全·csrf·dvwa
tuddy7894641 天前
Codex++ 安全边界探秘:从模型能力到风险防御
人工智能·python·安全
hbugs0011 天前
【案例分享】全网首个华三数据中心流量可视化实验,基于EVE-NG V7平台
网络·网络协议·安全·devops·eve-ng