php代码审计【5】代码执行漏洞

代码执行漏洞是指应用程序本身过滤不严,用户可以通过请求将代码注入到应用中执行,当应用在调用一些能将字符串转化成代码的函数(如php中的eval)时,没有考虑到用户是否能控制这个字符串,造成代码注入。

1、常见危险函数(eval和assert)


eval(),assret()将输入的字符串参数作为PHP程序代码来执行
代码1:

<?php
if(isset($_GET['cmd'])){
   $cmd = $_GET['cmd'];
   print_r($cmd);
   eval("\$cmd = $cmd");//assret()函数也是一样的,这里没对用户输入做过滤
   echo "ok";
}else{
   echo "not";
}
?>

浏览器返回:

2、常见回调函数:call_user_func()  call_user_func_array()  array_map()等

mixed call_user_func(callable $callback[,mixed $parameter[,mixed $....]])
$callback是要调用的自定义函数名称
$parameter是自定义函数的参数

<?php 
function barber($type){
    echo "$type\n";
	eval("$type");
}
$cmd = $_GET['cmd'];
call_user_func('barber',$cmd);
?>

浏览器返回:

 3、动态执行函数

定义一个函数,将函数名(字符串)赋值给一个变量,使用变量名代替函数名动态调用函数。
代码3:

<?php
$cmd =($_GET['a']);
var_dump($_GET['a']);
$ming = ($_GET['b']);
var_dump($ming);
echo "<br>";
echo $_GET['a']($_GET['b']);//接受get请求a的参数作为一个函数,b是作为a函数里的参数'($_GET['a']
echo $cmd($ming);    //自己太菜,开始以为要字符串拼接,直接写就好了
?>
<?php
    call_user_func($_GET['id'],$_GET['data']);
?> 


// 我们构造我们的payload为:id=assert&data=phpinfo()时,页面就能成功返回phpinfo页面

执行结果:

4、 正则表达式(做代码审计时,会遇到正则表达式,了解正则会更容易)

<?php
echo "-------------基础-----------------------<br>";
$userinfo = "Name: <b>PHP</b> <br> Title: <b>Programming Language</b>";
preg_match_all ("/<b>(.*)<\/b>/U", $userinfo, $pat_array);
print_r($pat_array[0]);
echo "<br>";
print_r($pat_array[1]);
echo "<br>";echo "<br>";
echo "-------------普通字符作为原子-----------------------<br>";
//普通字符作为原子
$pattern = '/abc/U';
$str = 'abcdefghijklmn';
preg_match_all($pattern,$str,$res);
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------特殊符号的字符作为原子-----------------------<br>";
//特殊符号的字符作为原子
$pattern = '/\[php\]/';
$str = '0123456[php]12345[php]';
preg_match_all($pattern,$str,$res);
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------通用字符作为原子-----------------------<br>";
//通用字符作为原子
$pattern1 = '/\d/'; //0-9
$pattern2 = '/\D/'; //a-zA-Z
$str = '123132asaaaaa222';
preg_match_all($pattern2,$str,$res);
var_dump($res);
echo "<br>";
preg_match_all($pattern1,$str,$res);
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------自定义原子-----------------------<br>";
//自定义原子
$pattern1 = '/[aj]sp/'; //匹配[aj]中任意一个字符作为原子的asp jsp
$str = 'jjjjspspspasp';
preg_match_all($pattern1,$str,$res);
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------限定符-----------------------<br>";
//限定符
$pattern1 = '/go*gle/'; // *匹配掐面出现原子次数0次 1次或多次 
$pattern2 = '/go+gle/'; // +匹配前面出现的原子1次或多次
$pattern3 = '/g+gle/'; // +匹配前面出现的原子1次或多次
$pattern4 = '/go?gle/'; // ?匹配前面出现的原子0次或1次,前面出现一次或没有出现,则返回全部,否则为空
$str = 'goooogle';
$str1 ='gogle';
preg_match_all($pattern1,$str,$res);  //goooogle
var_dump($res);
echo "<br>";
preg_match_all($pattern2,$str,$res); //goooogle
var_dump($res);
echo "<br>";
preg_match_all($pattern3,$str,$res); //没有结果
var_dump($res);
echo "<br>";
preg_match_all($pattern4,$str1,$res); //gogle
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------边界限定-----------------------<br>";
//边界限定
$pattern1 = '/^abc/'; // ^匹配输入字符开始的位置,必须是abc形式的开头
$pattern2 = '/abc^/'; // ^匹配输入字符结尾的位置,必须是abc形式的结尾
$pattern3 = '/^abc$/'; // ^$只匹配某字符
$str = 'abc2342dfads';
preg_match_all($pattern1,$str,$res);
var_dump($res);
echo "<br>";
preg_match_all($pattern2,$str,$res);
var_dump($res);
echo "<br>";
preg_match_all($pattern3,$str,$res);
var_dump($res);
echo "<br>";echo "<br>";
echo "-------------反向引用-----------------------<br>";
//反向引用
$pattern = '/\d{4}(-)\d{2}\\1\d{2}/'; // \\1代表第一个()缓冲区,这里等同于(-)
$str = '2019-01-28';
preg_match_all($pattern,$str,$res);
var_dump($res);
?>

浏览器页面:

 

5、preg_replace函数:

mixed preg_replace(mixde $pattern,mixed $replacement,mixed $subject[,int $limit = -1[,int &$count]])
$pattern 正则匹配的内容 $pattern存在/e模式修正符修饰,允许代码执行
$replacement 用于替换的字符串或字符串数组
$subject 要进行搜索和替换的字符串或字符串数组

preg_replace() 函数中用到的修饰符 /e 在 PHP5.5.x 中已经被弃用了。

  如果你的PHP版本恰好是PHP5.5.X,那你肯定就会报类似下面这样的错误:

  Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in......

修复方案:
尽量不要执行外部的应用程序或命令
使用自定义函数或函数库来替代外部应用程序或命令的功能
使用escappeshellarg函数来处理命令的参数
使用sare_mode_exec_dir来指定可执行的文件路径
将执行的参数做白名单限制,在代码或配置文件中限制某些参数

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值