PHP代码审计之危险函数

前言: 前几天总结了一下命令执行漏洞和代码执行漏洞,在其中发现了一些危险函数,其实危险函数还有很多,今天就来总结一下,之前总结过的就一笔带过,着重写之前没总结过的。

0x01 命令执行函数

1
2
3
4
5
6
7
8
9
system() — 执行外部命令,并且输出执行结果

passthru() — 执行外部命令并且显示原始输出

exec() — 执行一个外部命令,不输出

shell_exec() — 执行一个外部命令,不输出

反引号(``) — 与shell_exec()函数一样

popen() — 通过 popen() 的参数传递一条命令,并对 popen() 所打开的文件进行执行

proc_open() — 执行一个命令,并且打开用来输入/输出的文件指针。

0x02 代码执行函数

1.1 eval 函数

eval函数可以把字符串当作php代码来执行,最常见的操作就是一句话木马:

1
<?php @eval($_POST['ps']);?>

1.2 assert函数

assert函数的作用与eval的差不多,也可以把字符串当作 php 代码来执行。

1.3 preg_replace函数

如果有/e模式修正符,也可以执行代码

1.4 creat_function匿名函数

根据传递的参数创建匿名函数,并为其返回唯一名称。

1
2
3
4
5
string create_function ( string $args , string $code )

string $args 要向我们创建的函数中传入的变量

string $code 要创建函数的代码部分

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//用普通函数实现执行命令
function func($cmd)
{
return system($cmd);
}
func('whoami');
echo "<br />";

//以上函数可以用匿名函数表示
$func = create_function('$cmd','return system($cmd);');
$func ('whoami');
?>

在这里插入图片描述

1.5 $func=’sys’.’tem’

将字符串拼接,然后赋值给函数,直接调用即可执行命令

例:

1
2
3
4
<?php
$func = 'sys'.'tem';
$func('whoami');
?>

以上代码也会执行whoami

1.6 回调函数

call_user_func()、call_user_func_array()、array_map() 都可以调用其他函数。

例:

1
2
3
4
5
<?php
call_user_func('system', "whoami");
echo "<br />";
call_user_func_array('system', array("whoami"));
?>

这样也可以执行whoami命令
在这里插入图片描述

0x03 文件包含函数

文件包含是比较危险的,可以导致被getshell

3.1 include和require语句

1
2
语法:	include 'filename';
require 'filename';

include 和 require 语句是相同的,通过 include 或 require 语句,可以把指定的文件复制一份,然后使用到includerequire语句的文本中。

3.2 require_once和include_once语句

require_once语句(或include_once)和require语句(或include)完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

0x04 文件操作函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
copy 拷贝文件

file_get_contents 将整个文件读入为字符串

file_put_contents 将整个字符串写入文件

file 将文件读入数组中

fopen 打开文件或者url

move_upload_file将上传文件移动到新的位置

readfile 输出文件

rename 重命名

rmdir 删除目录

unlink delete 删除文件

0x05 特殊函数

5.1 phpinfo

1
bool phpinfo ([ int $what = INFO_ALL ] )

输出关于 PHP 配置的信息

5.2 获取变量信息的函数

1、get_defined_vars函数

1
array get_defined_vars ( void )

此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
2、get_defined_constants函数

1
array get_defined_constants ([ bool $categorize = false ] )

返回当前所有已定义的常量名和值。 这包含 define() 函数所创建的,也包含了所有扩展所创建的。

3、get_defined_functions

1
array get_defined_functions ( void )

返回一个包含所有已定义函数列表的多维数组

4、get_included_files

1
array get_included_files ( void )

返回所有被 include、 include_once、 require 和 require_once 的文件名。

5.3 使用软连接读取文件内容

1、symlink

1
2
3
4
5
bool symlink ( string $target , string $link )

target 连接的目标

link 连接的名称

对于已有的 target 建立一个名为 link 的符号连接。

2、readlink

1
2
3
string readlink ( string $path )

path 链接符号的路径

readlink() 和同名的 C 函数做同样的事,返回符号连接的内容。

5.4 配置函数

1、ini_get

1
string ini_get ( string $varname )

成功时返回配置选项的值。

2、ini_set

1
string ini_set ( string $varname , string $newvalue )

设置指定配置选项的值。这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。

3、ini_alter

此函数是in_set函数的别名。

5.5 数字判断

1、is_numeric

1
bool is_numeric ( mixed $var )

如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。
如果仅用is_numeric判断而不用intval函数转换,就有可能插入16进制的字符串到数据库,进而可能导致sql二次注入。

2、in_array

1
2
3
4
5
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

needle 待搜索的值

haystack 待搜索的数组

检查数组中是否存在某个值

该函数有一个特性,在搜索之前会进行自动类型转换。

1
2
3
$a = '1abc'; 

in_array($a,array(1,2,3))的返回值会是真

5.6、glob——列出匹配文件路径

1
array glob ( string $pattern [, int $flags = 0 ] )

寻找与$pattern模式匹配的文件路径

5.7、dl——载入扩展

1
bool putenv ( string $setting )

载入指定参数 library 的 PHP 扩展。

5.8 环境变量

1、getenv

1
string getenv ( string $varname )

获取一个环境变量的值。

2、putenv

1
bool putenv ( string $setting )

添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态。

5.9 变量覆盖

1、parse_str

1
void parse_str ( string $encoded_string [, array &$result ] )

如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )。

2、extract

1
int extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] )

本函数用来将变量从数组中导入到当前的符号表中。检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突。

3、mb_parse_str

1
bool mb_parse_str ( string $encoded_string [, array &$result ] )

解析 GET/POST/COOKIE 数据并设置全局变量。 由于 PHP 不提供原始 POST/COOKIE 数据,目前它仅能够用于 GET 数据。 它解析了 URL 编码过的数据,检测其编码,并转换编码为内部编码,然后设置其值为 array 的 result 或者全局变量。

4、import_request_variables

1
bool import_request_variables ( string $types [, string $prefix ] )

GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。

参考文献:
https://www.jianshu.com/p/b9db30cb4c54
https://www.bilibili.com/video/av56030160/

文章目录
  1. 1. 0x01 命令执行函数
  2. 2. 0x02 代码执行函数
    1. 2.0.1. 1.1 eval 函数
    2. 2.0.2. 1.2 assert函数
    3. 2.0.3. 1.3 preg_replace函数
    4. 2.0.4. 1.4 creat_function匿名函数
    5. 2.0.5. 1.5 $func=’sys’.’tem’
    6. 2.0.6. 1.6 回调函数
  • 3. 0x03 文件包含函数
    1. 3.0.1. 3.1 include和require语句
    2. 3.0.2. 3.2 require_once和include_once语句
  • 4. 0x04 文件操作函数
  • 5. 0x05 特殊函数
    1. 5.0.1. 5.1 phpinfo
    2. 5.0.2. 5.2 获取变量信息的函数
    3. 5.0.3. 5.3 使用软连接读取文件内容
    4. 5.0.4. 5.4 配置函数
    5. 5.0.5. 5.5 数字判断
    6. 5.0.6. 5.6、glob——列出匹配文件路径
    7. 5.0.7. 5.7、dl——载入扩展
    8. 5.0.8. 5.8 环境变量
    9. 5.0.9. 5.9 变量覆盖
  • |