欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[CISCN2020]-easyphp

程序员文章站 2022-05-12 14:05:29
...

源码:

<?php
    //题目环境:php:7.4.8-apache
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('could not fork');
    }else if ($pid){
        $r=pcntl_wait($status);
        if(!pcntl_wifexited($status)){
            phpinfo();
        }
    }else{
        highlight_file(__FILE__);
        if(isset($_GET['a'])&&is_string($_GET['a'])&&!preg_match("/[:\\\\]|exec|pcntl/i",$_GET['a'])){
            call_user_func_array($_GET['a'],[$_GET['b'],false,true]);
        }
        posix_kill(posix_getpid(), SIGUSR1);
    }

这里首先使用了pantl_fork(),用于创建子进程。成功时,在父进程执行线程内返回产生的子进程的PID$pid,在子进程执行线程内返回0。失败时,在父进程上下文返回-1,不会创建子进程,并且会引发一个PHP错误。进程从 pcntl_fock 开始,会产生分叉,主进程和子进程都会执行 pcntl_fock 所有的代码,可以通过 $pid 进行条件判断代码是执行在哪个进程;

而主进程使用了pcntl_wait(),这个主要用于阻塞父进程,为了等待子进程中断,防止子进程成为僵尸进程。

也就是说代码执行顺序是先从子进程开始执行。处理完子进程再执行父进程。

子进程代码中使用了call_user_func_array,这里函数中被强行添加了几个参数值,这里好像没找到什么办法进行利用。

又看到父进程代码段中的判断条件if(!pcntl_wifexited($status)是判断子进程是不是正常结束,如果不是就返回phpinfo(),而我们可以通过构造代码使子进程错误退出,从而执行父进程时,条件成立,返回phpinfo的内容。

所以我们需要构造使子进程不正常退出,通过测试,随便找个回调函数回调下即可,参数随意;

?a=call_user_func&b=pcntl_wait()

[CISCN2020]-easyphp
搜flag:
[CISCN2020]-easyphp

相关标签: CTF_Writeup_[web]