【攻防世界】easyphp(PHP代码审计)

简介: 【攻防世界】easyphp(PHP代码审计)

进入题目环境,检查页面内容,页面附有源代码:

<?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;
}
?>

进行代码审计,将整体代码分开分别分析。

使用 $_GET 方法上传参数 $a 与 $b、$c,并进行判断来进行回显:

找到可以获取 flag 的关键代码进行审计:

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

审计得知,若要输出 $flag 的值,则需要 $key1 和 $ket2 均为True,即均大于零。

首先查看 $key1 大于零的条件:

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...");
}

代码首先对参数 a 进行判断,要求参数a的值大于 6000000 且 a的位数不超过3位,故可以使用科学计数法来给 参数a 赋值。 ?a= 1e9

接着对参数 b 进行判断,若b存在 且 参数b的后六位 等于 字符串'8b184b' 的话,即赋值 $key1=1。

故编写 MD5破解脚本:

import hashlib
for i in range(100000):
    x = str(i).encode()  #将字符串转换为字节串,因为hashlib.md5()函数的参数必须为字节串
    y = hashlib.md5(x)  #进行md5加密编码
    m = y.hexdigest()  #以十六进制的格式返回编码数据
    if(m[-6:] == "8b184b"):  #若编码后六位等于字符串"8b184b",则代表爆破成功
        print("爆破结果为:" + m)
        break
    print(i)

爆破结果如下:

成功获得 符合条件的b的值---53724。

查看 $key2 大于零的条件:

$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");
}

进行代码审计,引入了新的参数 $c:

第一个 if 判断语句:要求 $c 是一个数组,且 $c['m'] 的值不为数字 (is_numeric()函数判断),在 $c['m'] 的数据类型不为数字的同时还要求 $c['m'] 的键值大于 2022,需要用到 PHP 的弱语言特性。

PHP是一类典型的弱语言,在PHP代码中:

2023abc 与 2022 作比较时,会自动将 字符串类型的 '2022abc' 转换为 数字类型2023 来和 2022 进行比较。

故可以将 $c['m'] 赋值为 字符串 '2023abc'。

被嵌套的第二个 if 语句:$c['n'] 也为一个数组,所以 $c 是典型的 数组嵌套数组,在要求 $c['n'] 为一个数组的同时要求 $c['n'][0] 也为一个数组,所以 $c['n'] 中也嵌套一个数组。

最后利用 array_search()函数要求 $c['n'] 中可以匹配 字符串 'DGGJ',同时利用 foreach 要求 c['n'] 不存在字符串 'DGGJ',看似要求矛盾,实则依然利用PHP的弱语言特性。

若 $c['n'] 的键值包含数字0,当 数字0 和字符串'DGGJ'进行比较时,字符串'DGGJ'会自动被转换为数字零,以此可以达到目的。

所以 payload: c={"m":"2023abc","n":[[0,1],0]}。

所以最终的payload:http://61.147.171.105:53569/?a=1e9&b=53724&c={"m":"2023abc","n":[[0,1],0]}

成功获得 flag。

相关文章
|
6月前
|
安全 小程序 PHP
PHP代码审计(七)Rips源代码审计系统使用教程
上一篇中提到的Seay源代码审计系统是由C#编写的winform程序,现在已经停止更新了,但是,还是比较好用的。 PHP代码审计还有另一个工具,也是一个神器Rips
221 0
|
6月前
|
安全 小程序 PHP
PHP代码审计(五)PHP代码审计方法与步骤
(1):获取到网站源码(这就是废话……) (2):将网站部署到你自己的环境中,能运行。 这里特殊说明一下我的习惯,我本地的环境与线上的环境基本上保持一致,这样在本地审计及线上部署的时候能发现更多的问题。不建议说是随便搭个环境能跑起来就行,这样不是很严谨。 (3):拿到源码之后,浏览大概的项目结构。
79 0
|
6月前
|
Shell PHP Windows
PHP代码审计(四)PHP文件操作函数(2)
改变文件所有者。如果成功则返回 TRUE,如果失败则返回 FALSE。 语法:chown(file,owner)
46 0
|
6月前
|
安全 Unix Shell
PHP代码审计(四)PHP文件操作函数(1)
改变文件所有者。如果成功则返回 TRUE,如果失败则返回 FALSE。 语法:chown(file,owner)
47 0
|
6月前
|
安全 小程序 PHP
PHP代码审计(六)Seay源代码审计系统使用教程
www.cnseay.com/ 当然,这个已经不能访问了。 软件的版本比较早,需要.NET framework3.5框架,我这里是软件启动的时候自动提醒安装,如果没有自动提醒,那么你需要手动安装.NET frameWork3.5框架,否则,程序应该是没有办法运行。
586 0
|
1月前
|
数据安全/隐私保护
攻防世界13-simple_php
攻防世界13-simple_php
|
29天前
|
PHP
攻防世界---Web_php_include
攻防世界---Web_php_include
|
1月前
|
PHP
02-攻防世界PHP2
02-攻防世界PHP2
|
1月前
|
安全 Linux PHP
【攻防世界】php_rce (ThinkPHP5)
【攻防世界】php_rce (ThinkPHP5)
|
1月前
|
安全 PHP
【攻防世界】file_include (PHP伪协议+过滤器)
【攻防世界】file_include (PHP伪协议+过滤器)