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 中可能会导致一些非预期的行为,尤其是当比较的值中包含非字符串类型,像是数组时。

本题完。

相关推荐
WTT001125 分钟前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
杨德杰1 小时前
QT网络(一):主机信息查询
网络·qt
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
yang_shengy2 小时前
【JavaEE】网络(6)
服务器·网络·http·https
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
Aimin20223 小时前
路由器做WPAD、VPN、透明代理中之间一个
网络
群联云防护小杜3 小时前
如何给负载均衡平台做好安全防御
运维·服务器·网络·网络协议·安全·负载均衡
ihengshuai3 小时前
HTTP协议及安全防范
网络协议·安全·http
爱码小白4 小时前
网络编程(王铭东老师)笔记
服务器·网络·笔记
蜜獾云4 小时前
linux firewalld 命令详解
linux·运维·服务器·网络·windows·网络安全·firewalld