5.【BUUCTF】[BJDCTF2020]Easy MD5及知识点

news/2025/2/9 2:41:18 标签: 网络, web安全, 安全, 网络安全, php, 代码复审

进入题目页面如下

尝试提交XSS攻击以及sql注入

并没有回显,尝试无果,用burp suite抓取响应包查看一下,右键→拦截→拦截响应

在响应中找到了响应头

Hint:select * from ‘admin’ where password =md5($pass,ture)

给出提示MD5

SQL 查询语句的提示,原始的查询语句 select * from ‘admin’ where password =md5($pass,true) (注意:MD5 函数第二个参数在不同数据库意义不同,在 MySQL 里 MD5() 函数只接受一个参数)
这个 SQL 语句的目的是从名为 admin 的表中查询出 password 字段值等于对变量 $pass 进行 MD5 哈希处理后结果的所有记录。
SQL 注入风险
原理:如果在实际应用中,$pass 是用户输入的内容,且没有经过严格的过滤和转义,可以通过构造特殊的输入来改变 SQL 语句的原意,从而实现 SQL 注入攻击。

php"><?php
$pass = $_GET['pass'];
$sql = "SELECT * FROM admin WHERE password = MD5('$pass')";
// 执行 SQL 查询
?>

可以构造如下的 pass 参数:

' OR '1'='1

最终的 SQL 语句会变成:

SELECT * FROM admin WHERE password = MD5('' or '1'='1')

由于 '1'='1' 永远为真,这个查询会返回 admin 表中的所有记录,可能借此绕过登录验证或者获取敏感信息。

当'or'后的值为True时,可实现SQL注入

md5函数

md5 函数通常用于计算输入字符串的 MD5 哈希值。md5(string, raw) 这种形式的函数调用中,string 是需要进行哈希计算的输入字符串,而 raw 是一个布尔类型的参数,用于指定返回的哈希值的格式。

string:这是必需的参数,代表要进行 MD5 哈希计算的原始字符串数据。可以是任意长度的文本信息,例如用户密码、文件内容等。
raw:这是一个可选参数,不同编程语言对该参数的处理和含义可能有所不同,但一般来说:
当 raw 为 true 或者类似表示真的值时,函数会返回原始的 128 位(16 字节)二进制格式的哈希值。
当 raw 为 false 或者类似表示假的值时,函数会返回以 32 位十六进制字符串形式表示的哈希值。

在 PHP 里,md5() 函数的第二个参数用于指定是否返回原始二进制数据
php"><?php
// 待哈希的字符串
$string = "Hello, World!";

// 返回 32 位十六进制字符串形式的哈希值
$hexHash = md5($string, false);
echo "十六进制哈希值: ". $hexHash. "\n";

// 返回原始二进制形式的哈希值
$binaryHash = md5($string, true);
echo "二进制哈希值长度: ". strlen($binaryHash). " 字节\n";
?>

在上述代码中,当第二个参数为 false 时,得到的是常见的 32 位十六进制字符串;当为 true 时,得到的是 16 字节的二进制数据。

看了大佬的博客才继续下去,附上链接

[BUUOJ记录] [BJDCTF2020]Easy MD5 - Ye'sBlog - 博客园

大佬说

ffifdyop字符串md5加密后若raw参数为True时会返回 'or'6<trash> (<trash>

只要第一位是非零数字会被判定为True

<trash>会在MySQL将其转换成整型比较时丢掉

后端的SQL语句

select * from `admin` where password=''or'6<trash>'

直接输入ffifdyop,点击提交

进入下一个界面

ctrl+u查看源代码

看到注释中的关键信息

这里使用了==弱比较

比较操作符分为强比较和弱比较,以 PHP 为例来详细讲解弱比较 == 的情况。当在代码里使用 md5(string, raw) 配合 == 弱比较

PHP 中 == 弱比较规则

在 PHP 里,== 是弱比较操作符,它在比较时会进行类型转换,然后再比较值是否相等。

var_dump(0 == "abc"); // 输出: bool(true)

这是因为在使用 == 比较时,PHP 会尝试将字符串 "abc" 转换为数字,转换结果为 0,所以与整数 0 比较时结果为 true

md5() 和 == 可能出现的问题

在某些情况下,当使用 md5() 函数计算哈希值并使用 == 进行比较时,可能会因为弱比较的特性产生意外结果。

哈希值以 0e 开头的情况

部分字符串经过 MD5 哈希后的结果会以 0e 开头,在科学计数法中,0e 后面跟着的数字表示 0 乘以 10 的多少次方,结果始终为 0。当使用 == 比较两个以 0e 开头的 MD5 哈希值时,PHP 会将它们当作科学计数法表示的数字进行比较,从而认为它们相等。

php">$str1 = "240610708";
$str2 = "QNKCDZO";
$md5_1 = md5($str1);
$md5_2 = md5($str2);

var_dump($md5_1 == $md5_2); // 输出: bool(true)

echo "MD5 of str1: ". $md5_1. "\n"; // 输出: 0e462097431906509019562988736854
echo "MD5 of str2: ". $md5_2. "\n"; // 输出: 0e830400451993494058024219903391

在上述代码中,$str1 和 $str2 是不同的字符串,但它们的 MD5 哈希值以 0e 开头,使用 == 比较时结果为 true

重要代码解释

php"><?php
// 从 GET 请求中获取参数 a 的值并赋值给变量 $a
$a = $_GET['a'];
// 从 GET 请求中获取参数 b 的值并赋值给变量 $b
$b = $_GET['b'];

// 检查 $a 不等于 $b 并且它们的 MD5 哈希值相等
if ($a != $b && md5($a) == md5($b)) {
    // 若条件满足,执行这里的代码
    echo "找到了满足条件的 a 和 b!";
} else {
    // 若条件不满足,执行这里的代码
    echo "未找到满足条件的 a 和 b。";
}
?>

以下是可以绕过该条件判断的示例输入:

php">?a=240610708&b=QNKCDZO

这两个字符串不同,但它们的 MD5 哈希值分别是:

md5(240610708) 的结果是 0e462097431906509019562988736854

md5(QNKCDZO) 的结果是 0e830400451993494058024219903391

在 PHP 的弱比较下,这两个哈希值会被判定为相等。

得到这个页面

进行代码审计

php"><?php
// 关闭所有 PHP 错误报告,避免将错误信息暴露给用户,增强安全性,但也可能掩盖一些潜在问题
error_reporting(0);

// 引入 flag.php 文件,该文件中通常定义了敏感信息,如 flag 值
include "flag.php";

// 高亮显示当前 PHP 文件(即包含此代码的文件)的源代码,方便开发者调试或展示代码结构
highlight_file(__FILE__);

// 检查 POST 请求中 param1 和 param2 两个参数的值是否不相等,并且它们的 MD5 哈希值是否严格相等(值和类型都相等)
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    // 如果上述条件满足,则输出 flag.php 文件中定义的 $flag 变量的值
    echo $flag;
}

由于 MD5 算法存在哈希碰撞的问题,也就是可以找到两个不同的输入,它们经过 MD5 计算后得到相同的哈希值。不过代码中使用了 === 进行严格比较,这要求不仅哈希值的内容相同,类型也要相同,所以利用以 0e 开头的 MD5 值在弱比较下相等这种方法在这里行不通。

但实际上可以利用 MD5 对数组不做处理的特性来绕过这个判断。当 md5() 函数的参数为数组时,它会返回 NULL

md5数组绕过

1. 原理概述

在许多编程语言里,当使用 MD5 函数对数组进行处理时,其行为可能并非如预期对数组元素进行哈希计算,而是会产生一些特殊结果,利用这些特殊结果可以绕过基于 MD5 哈希值比较的验证机制,这就是 MD5 数组绕过。以 PHP 语言为例,下面详细介绍其原理、示例及防范措施。

2. PHP 中 MD5 对数组的处理

在 PHP 里,md5() 函数是用于计算字符串的 MD5 哈希值的。当传入的参数是数组时,md5() 函数不会对数组元素进行哈希计算,而是直接返回 NULL

php"><?php
$array1 = [1, 2, 3];
$array2 = [4, 5, 6];

$hash1 = md5($array1);
$hash2 = md5($array2);

var_dump($hash1);  // 输出: NULL
var_dump($hash2);  // 输出: NULL

if ($hash1 === $hash2) {
    echo "两个数组的 MD5 哈希值相等";
} else {
    echo "两个数组的 MD5 哈希值不相等";
}
?>

在上述代码中,$array1 和 $array2 是不同的数组,但对它们使用 md5() 函数计算哈希值时,结果都为 NULL,所以在进行严格比较 $hash1 === $hash2 时,结果为 true

构造 POST 请求

可以通过构造一个包含两个不同数组的 POST 请求来绕过判断条件。

payload

param1[]=1&param2[]=2

用hackbar工具POST传参 

最终得到flag


http://www.niftyadmin.cn/n/5845461.html

相关文章

文件上传到腾讯云存储、签名及设置过期时间

将文件上传到腾讯云对象存储&#xff08;COS&#xff0c;Cloud Object Storage&#xff09;可以通过腾讯云提供的 SDK 实现。以下是详细的步骤和示例代码&#xff0c;帮助您完成文件上传操作。 步骤 注册腾讯云账号并创建存储桶&#xff1a; &#xff08;1&#xff09;登录腾讯…

MAC OS安装Homebrew

文章目录 1.下载Homebrew2.完成安装3.验证安装4.更新 Homebrew作为一个包管理器&#xff0c;提供了一种简便的方式来安装、更新和卸载各种命令行工具和应用程序。相比于手动下载和编译源代码&#xff0c;或者从不同的网站下载安装包&#xff0c;使用Homebrew可以显著减少这些操…

采用idea中的HTTP Client插件测试

1.安装插件 采用idea中的HTTP Client插件进行接口测试,好处是不用打开post/swagger等多个软件,并且可以保存测试时的参数,方便后续继续使用. 高版本(2020版本以上)的idea一般都自带这个插件,如果没有也可以单独安装. 2.使用 插件安装完成(或者如果idea自带插件),会在每个Con…

使用PyCharm创建项目以及如何注释代码

创建好项目后会出现如下图所示的画面&#xff0c;我们可以通过在项目文件夹上点击鼠标右键&#xff0c;选择“New”菜单下的“Python File”来创建一个 Python 文件&#xff0c;在给文件命名时建议使用英文字母和下划线的组合&#xff0c;创建好的 Python 文件会自动打开&#…

ctf网络安全题库 ctf网络安全大赛答案

此题解仅为部分题解&#xff0c;包括&#xff1a; 【RE】&#xff1a;①Reverse_Checkin ②SimplePE ③EzGame 【Web】①f12 ②ezrunner 【Crypto】①MD5 ②password ③看我回旋踢 ④摩丝 【Misc】①爆爆爆爆 ②凯撒大帝的三个秘密 ③你才是职业选手 一、 Re ① Reverse Chec…

蓝桥杯备赛——进制转化相关问题

目录 一、基础概念 二、问题研究&#xff08;1&#xff09; 代码解读&#xff1a; 1. transfer 函数 代码功能概述 详细步骤 2. main 函数 代码功能概述 详细步骤 三、运用递归解决 &#xff08;一&#xff09; 代码如下&#xff1a; 代码解读&#xff1a; &#…

大模型deepseek-r1 本地Open WebUI部署详解

一、Open WebUI简介 Open WebUI是一个用户友好的Web界面&#xff0c;专为本地大语言模型&#xff08;LLMs&#xff09;设计。它支持多种模型&#xff0c;包括Ollama和OpenAI兼容的API&#xff0c;并允许用户通过图形界面轻松调试和调用模型。Open WebUI的功能丰富&#xff0c;…

.NET Framework和.NET Core的区别

.NET Framework和.NET Core的区别&#xff0c;这需要我来详细解释一下。首先&#xff0c;我得回忆一下两者的基本信息&#xff0c;它们的发布时间、设计目的&#xff0c;还有各自的特点。 首先&#xff0c;.NET Framework是微软早期推出的&#xff0c;主要用于Windows平台的应用…