[CISCN2020]-easyphp

Source code:

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

It is used first here pantl_fork()to create a child process. On success, the PID of the child process generated in the parent process execution thread is returned $pid, and 0 is returned in the child process execution thread. On failure, -1 is returned in the context of the parent process, the child process will not be created, and a PHP error will be raised. The process starts from pcntl_fock, it will fork, the main process and the child process will execute all the code of pcntl_fock, you can use $pid to conditionally determine which process the code is executing in;

The main process is used pcntl_wait(), this is mainly used to block the parent process, in order to wait for the child process to interrupt and return, to prevent the child process from becoming a zombie process.
Definition of pcntl_wait:

The wait function suspends the execution of the current process until a child process exits or receives a signal to interrupt the current process or call a signal processing function. If a child process has exited when calling this function (commonly known as a zombie process), this function returns immediately. All system resources used by the child process will be released. When pcntl_wait() is called, if there is no child process, -1 will be returned.

That is to say, the order of code execution is to execute from the child process first. After processing the child process, execute the parent process.

It is used in the subprocess code. call_user_func_arraySeveral parameter values ​​are forcibly added to the function. It seems that there is no way to use it.

I also saw that the judgment condition in the code segment of the parent process if(!pcntl_wifexited($status)is to judge whether the child process ended normally, if not, return phpinfo(), and we can make the child process exit by mistake by constructing the code, so that when the parent process is executed, the condition is established and returns The content of phpinfo.

So we need to construct to make the child process exit abnormally, pass the test, just find a callback function to call back, and the parameters are arbitrary;

?a=call_user_func&b=pcntl_wait()

Insert picture description here
Search flag:
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_36618918/article/details/108157924