PHP审计(一)
程序员文章站
2022-07-09 20:32:56
一、php中常见的危险函数和审计要点 危险函数(功能过于强大) 参数是否外部可控,有没有正确的过滤。 PHP获取外界传入参数是通过下面几个全局函数的形式,所以审计参数传入经常要和下面几个变量打交道 PHP中危险函数有五大特性: 参数是否可控 执行任意代码函数 1)把传入的字符串直接当成php代码直接 ......
一、php中常见的危险函数和审计要点
危险函数(功能过于强大)
参数是否外部可控,有没有正确的过滤。
php获取外界传入参数是通过下面几个全局函数的形式,所以审计参数传入经常要和下面几个变量打交道
php中危险函数有五大特性:
变量 | 说明 |
$_get | 数组,存放着所有通过url参数传递的数据 |
$_post | 数组,当http post请求的content-type是application/x-www-form-urlencoded或multipart/form-data的部分解析成关联数组 |
$_files | 数据,存放着http post上传的文件信息 |
$_cookie | 数组,存放着http头里面cookie段内容 |
$_request | 数组,默认情况下包含了$_get, $_post, $_cookie的数据 |
$_server | 数组,包含了http头,服务器环境等信息 |
$_session | 数组,存放当前会话可用的session变量 |
参数是否可控
执行任意代码函数
1)把传入的字符串直接当成php代码直接执行,如:
a | b | c | d | |
1 | 函数 | 函数说明 | 例子 | 运行结果 |
2 | assert | 判断一个断言是否为false | assert('print(123)') | 输出123 |
3 | eval | 把一个字符串当做php代码执行 | eval('echo 123') | 输出123 |
4 | create_function | 用给的一个字符串创建匿名函数 | create_function('$a','print($a);')(123) | 输出123 |
2)通过引入文件的形式执行php代码,如:(利用:查看这些引入文件参数是否外部可控)
a | b | c | d | |
1 | 函数 | 函数说明 | 例子 | 结果 |
2 | include | 包含并运行指定文件 | include '1.php' | 包含文件1.php,并执行里面的代码 |
3 | include_once | 包含并运行指定文件 | include_once '1.php' | 包含文件1.php,并执行里面的打码 |
4 | require | 包含并运行指定文件 | require '1.php' | 包含文件1.php,并执行里面的代码 |
5 | require_once | 包含并运行指定文件 | require_once '1.php' | 包含文件1.php,并执行里面的代码 |
3)数据处理函数
函数 | 函数说明 | 例子 | 结果 | |
1 | preg_replace | 使用正则替换内容,php7之前的正则表达式参数可以开启\e的模式,执行任意代码 | preg_replce("/(.)/e",'print(\1),'123'); |
php5下输出123 |
2 | array_map | 为数组的每个元素应用回调函数 | $b=array_map('assert',['print(123)']); | php5下输出123 |
3 | array_filter | 用回调函数过滤数组中的单元 | array_filter(['print(123)'],'assert'); | php5下输出123 |
4 | array_walk | 使用用户自定义函数对数组中的每个元素做回调处理 |
$a=['print(123)'];array_walk($a,'assert') |
php5下输出123 |
5 | call_user_func | 把第一个参数作为回调函数调用 | call_user_func('assert','print(123)'); | 输出123 |
4)能够读取网络资源的函数(配置 allow_url_include=1 才可以使用)
函数 | 函数说明 | 例子 | 结果 | |
1 | curl系列 | 发起网络请求 | ||
2 | file_get_contents | 原本功能是读取文件,但是支持封装协议,所以可以读取网络上的资源 | file_get_contents('https://url.com') | 请求url.com |
3 | file | 原本功能是读取文件,但是支持封装协议,所以可以读取网络上的资源 | file('https://url.com') | 请求url.com |
4 | fopen | 原本功能是读取文件,但是支持封装协议,所以可以读取网络上的资源 | fopen('https://url.com') | 请求url.com |
5 |
copy |
原本功能是复制文件,但是支持封装协议,所以可以读取网络上的资源 | copy('https://url.com') | 请求url.com,并保存txt文档 |
5)能够执行系统命令或者调用外部程序的函数
函数 | 函数说明 | 例子 | 结果 |
exec | 执行一个外部程序 | exec('touch 1.txt') | 在当前目录下生成1.txt |
shell_exec |
通过shell执行命令,并且将完整的输出以字符串的方式返回 | shell_exec('touch 1.txt') | 在当前目录下生成1.txt |
system | 执行外部程序,并显示输出 | system('touch 1.txt') | 在当前目录下生成1.txt |
passthru | 执行外部程序,并显示输出 | passthru('touch 1.txt') | 在当前目录下生成1.txt |
popen | 打开进程文件指针 | popen('touch 1.txt','r') | 在当前目录下生成1.txt |
proc_open | 执行一个命令,并打开用来输入/输出的文件指针 | proc_open('touch 1.txt',[],$a) | 在当前目录下生成1.txt |
`` | 反引号包含的内容会当成系统命令执行 | `touch 1.txt` | 在当前目录下生成1.txt |
6)能够修改运行时候的上下文环境
函数 | 函数说明 | 例子 | 结果 |
extract | 从数组中将变量导入到当前的符号表,审计时候需要判别传输数组是否外部可控 | $a='1';extract(['a'=>'2']);echo $a | 输出2 |
parse_str |
将字符串解析成多个变量 | $a='1';parse_str('a=2');echo $a | 输出2 |
ini_set | 修改运行时php配置 | ini_set('memory_limit','2048m') | 设置运行时最大占用额内存为2048m |
上一篇: SSH框架之Spring第三篇
下一篇: 又被偷了