跟安全有关的敏感函数
在代码安全审计中,快速定位敏感函数,有助于帮助我们更快发现漏洞。这里就通过实例方式说明一下敏感函数是如何运行的。
1.eval()
该函数把字符串当做php代码来计算,并且字符串必须是合法的php代码,要以分号结尾。
语法eval(phpcode)
实例:
<?php
eval('phpinfo();');
?>
2.assert()
该函数会检查一个指定断言。断言是一个逻辑学词汇,主要用于程序员来进行假设判断。断言只有两种类型,字符串型或者布尔型,当断言为false时返回字符串表达式。如果断言是字符串那么会当做php代码执行。
语法assert(phpcode)
实例:
<?php
assert('phpinfo();');
?>
3.call_user_func()
把第一个参数作为回调函数调用,后面的参数作为回调函数的参数。
call_user_func('callback()',$callback)
实例:
<?php
$a = phpinfo();
call_user_func('eval',$a);
?>
还有call_user_func_array()与之类似,只是传入参数为数组。
4.create_function()
创建匿名函数,此函数返回唯一的函数名称一个字符串,否则出错返回false。
语法creat_funciton($args,$code)$args:一个字符串类型的函数参数$code,字符串类型的函数代码
实例:
<?php
$func = create_function('$a,$b', 'return ($a+$b);');
echo $func(10,20);
?>
这就相当于:
<?php
function func($a,$b){
return ($a+$b);}
echo func(10,20);
?>
最终输出都是30。
<?php
$a = $_GET['a'];
$func = create_function('$a','eval($a);');
$func($a);
?>
5.exec()
命令执行函数,执行一个外部程序,不显示输出。
<?php
echoexec('whoami');
?>
exec 执行系统外部命令时不会输出结果,而是返回结果的最后一行。
6.system ()
命令执行函数,执行一个外部程序,显示输出。
<?
phpsystem('whoami');
?>
7.passthru ()
命令执行函数,执行一个外部程序,显示原始输出。常用来执行诸如pbmplus 之类的可以直接输出图像流的命令。通过设置Content-type 为image/gif,然后调用pbmplus 程序输出gif 文件,就可以从PHP 脚本中直接输出图像到浏览器。
<?php
passthru('whoami');
?>
8.shell_exec ()
通过shell 环境执行命令,并且将完整的输出以字符串的方式返回。值得一提的是,这个函数跟执行操作符(反引号``)具有等同效力。
<?php
echo shell_exec('whoami');
echo "<br>";
echo `whoami`;
?>
9.fopen(),fclose(),fread(),fwrite()
fopen()函数打开文件或者url。
语法:
fopen(filename,mode,include_path,context)
参数:
filename:必需。规定要打开的文件或url;
mode:必需。规定请求到该文件的访问类型;
其余两个参数可忽略。
这里补充下mode参数的类型总结。
"r" (只读方式打开,将文件指针指向文件头)
"r+" (读写方式打开,将文件指针指向文件头)
"w" (写入方式打开,清除文件内容,如果文件不存在则尝试创建之)
"w+" (读写方式打开,清除文件内容,如果文件不存在则尝试创建之)
"a" (写入方式打开,将文件指针指向文件末尾进行写入,如果文件不存在则尝试创建之)
"a+" (读写方式打开,通过将文件指针指向文件末尾进行写入来保存文件内容)
"x" (创建一个新的文件并以写入方式打开,如果文件已存在则返回FALSE 和一个错误)
"x+" (创建一个新的文件并以读写方式打开,如果文件已存在则返回FALSE 和一个错误
fclose()函数用于关闭被打开的文件,与fopen配合使用。
语法fclose(file)
fread()函数读取打开的文件。函数会在到达指定长度或读到文件末尾(EOF)时(以先到者为准),停止运行。该函数返回读取的字符串,如果失败则返回FALSE。
语法
fread ( resource $handle , int $length )
参数:
handle:必需。文件系统指针,由fopen打开创建的资源;
length:必需。规定要读取的最大字节数。
fwrite()将内容写入一个打开的文件中。跟fputs()具有同等效力。
语法:
fwrite(file,string,length)
参数:
file:必需。规定要写入的打开文件;
string:必需。规定要写入打开文件的字符串;
length:可选。规定要写入打开文件最大字节数。
综合实例:
<?php
$file1= fopen("123.txt", "w");
fwrite($file1,"Hello World. Testing!");
fclose($file1);
$file2 = fopen("123.txt", "r");
echo fread($file2,filesize("123.txt"));
fclose($file2);
?>
10.file_put_contents和file_get_contents
file_put_contents() 函数把一个字符串写入文件中。
该函数访问文件时,遵循以下规则:
1.如果设置了FILE_USE_INCLUDE_PATH,那么将检查filename 副本的内置路径;
2.如果文件不存在,将创建一个文件;
3.打开文件;
4.如果设置了LOCK_EX,那么将锁定文件;
5.如果设置了FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容;
6.向文件中写入数据;
7.关闭文件并对所有文件解锁。
实际上整个过程与依次调用fopen(),fwrite() 以及fclose() 功能一样。如果成功,该函数将返回写入文件中的字符数。如果失败,则返回False。
语法:
file_put_contents(file,data,mode,context)
参数:
file:必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。
data:必需。规定要写入文件的数据。可以是字符串、数组或数据流。
其他可选可省略。
file_get_contents() 把整个文件读入一个字符串中。该函数是用于把文件的内容读入到一个字符串中的首选方法。
语法:
file_get_contents(path,include_path,context,start,max_length
参数:
path:必需。规定要读取的文件。
其他可选可省略。
综合实例:
<?php
file_put_contents("test.txt","Hello World. Testing!");
echo file_get_contents("test.txt");
?>
11.str_replace()
str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写)。
该函数必须遵循下列规则:
1.如果搜索的字符串是数组,那么它将返回数组。
2.如果搜索的字符串是数组,那么它将对数组中的每个元素进行查找和替换。
3.如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换。
4.如果查找的是数组,而替换的是字符串,那么替代字符串将对所有查找到的值起作用。
注释:该函数区分大小写。请使用str_ireplace()函数执行不区分大小写的搜索。
注释:该函数是二进制安全的。
语法
str_replace(find,replace,string,count)
参数:
find:必需。规定查找要查找的值;
replace:必需。规定替换find中查找的值;
string:必需。规定被搜索的字符串;
实例:
<?php
echo str_replace("world","chengdu","Hello world!");
?>
12.preg_replace()
preg_replace 函数执行一个正则表达式的搜索和替换。
语法:
preg_replace(pattern , replacement ,subject ,limit,count)
参数:
pattern:必需。要搜索的模式,可以是字符串或一个字符串数组;
replacement:必需。用于替换的字符串或字符串数组;
subject: 必需。要搜索替换的目标字符串或字符串数组.
其余可选可省略。
用法就是:搜索subject 中匹配pattern 的部分,以replacement 进行替换。
这个函数本身没什么特别,关键在于pattern中,如果使用了/e修饰符,那么被替换后的字符串将直接以PHP代码形式执行。
实例运用:
<?php
preg_replace("/(.*)/e",$_GET['a'],"123");
?>
13.小结
跟安全有关的敏感函数还有很多比如include(),require(),popen(),proc_open(),highlight_file(),escapeshellcmd()等等,可以自行在官方手册上查询资料。