今天在做一道web命令执行的题目的时候,用到了FFI这个拓展:
payload如下:
$ffi = FFI::cdef("int system(char* command);");
$ffi ->system("cat /etc/passwd");
使用FFI::cdef()
函数声明我们要调用的c语言中的函数system,然后调用system执行命令。
大概了解了一下这个拓展,用来调用c语言中的函数和库。然后仿照着别人的代码做了个实验:
PHP7.4新特性FFI初体验
我们要在PHP中用ffi调用C语言的代码:
// filename cli_size.c
/**
* 通过函数 ioctl() 获得终端界面的参数
* @see https://blog.csdn.net/weixin_42205987/article/details/82080615
*/
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
struct winsize get_size()
{
struct winsize size;
ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
return size;
}
unsigned short get_cli_rows()
{
struct winsize size;
ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
return size.ws_row;
}
unsigned short get_cli_cols()
{
struct winsize size;
ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
return size.ws_col;
}
我们先把上面的c代码编译成动态链接库libcli_size.so:
gcc -O2 -fPIC -shared -g cli_size.c -o libcli_size.so
首先我们使用FFI::cdef()函数声明我们要调用的这个库中的函数以及使用到的数据类型。FFI::cdef()函数的第二个参数就是我们自己的库文件名了。然后用var_dump输出调用结果:
<?php
//test.php
$ffi = FFI::cdef(<<<CTYPE
struct winsize {
unsigned short ws_row; /* rows, in characters */
unsigned short ws_col; /* columns, in characters */
unsigned short ws_xpixel; /* horizontal size, pixels */
unsigned short ws_ypixel; /* vertical size, pixels */
};
unsigned short get_cli_rows();
unsigned short get_cli_cols();
struct winsize get_size();
CTYPE, 'libcli_size.so');
//输出调用结果
var_dump($ffi->get_cli_rows());
var_dump($ffi->get_cli_cols());
var_dump($ffi->get_size());
然后php test.php
查看结果:
成功调用了C语言的代码!