概述
漏洞原理
代码执行漏洞是指应用程序本身过滤不严,用户可以通过请求将代码注入到应用中执行。当应用在调用一些能将字符串转化成代码的函数(如php中的eval)时,没有考虑到用户是否能控制这个字符串,将造成代码注入漏洞。
狭义的代码注入通常指将可执行代码注入到当前页面中,如php的eval函数,可以将字符串代表的代码作为php代码执行,当前用户能够控制这段字符串时,将产生代码注入漏洞。
漏洞展示
eval和assert函数
<?php
if(isset($_GET['cmd'])){
$cmd = $_GET['cmd'];
eval("$cmd = $cmd");
echo "success";
}else{
echo "fail";
}
?>
这里解释一下isset函数和empty函数的区别:empty是判断一个变量是否为“空”,而isset 则是判断一个变量是否已经设置。但是这里有一点绝对要注意起来:当一个变量值为0,empty 认为这个变量同等于空,即相当于没有设置。
其实assert函数和eval函数的功能是一样的。
当我们在cmd参数中执行php的内部函数phpinfo()
时,eval函数都正确地执行
调用php内部的系统命令函数system(ipconfig);
查看主机网络信息
查看当前用户system(whoami);
回调函数
- 先说说回调函数是咋回事!PHP的回调函数其实和C、Java等语言的回调函数的作用是一模一样的,都是在主线程执行的过程中,突然跳去执行设置的回调函数。回调函数执行完毕之后,再回到主线程处理接下来的流程
有两种方式
callBack.php
<?php
function callBack(){
$b = $_GET['cmd'];
eval($b);
}
call_user_func('callBack',$b);
<?php
// function callBack(){
// $b = $_GET['cmd'];
// eval($b);
// }
//
// call_user_func('callBack',$b);
$b = 'phpinfo()';
call_user_func($_GET['a'],$b);
第一个和第二个的区别主要是,第一个是将危险代码封装在一个函数中,然后使用回调函数进行调用,第二个则是通过传入a参数然后赋值一个危险变量在调用。
常见的回调函数还有:call_user_func
、call_user_func_array
、array_map
等
动态执行函数
<?php
$_GET['a']($_GET['b']); //接受GET请求a的参数作为一个函数,b作为a函数里面的参数
//$_GET['c']($_POST['d']); //换成POST方法类似
-
GET方式
-
POST方式
解析:把GET传过来的a作为一个函数去调用GET传过来的b作为参数去执行。 -
正则表达式/e修正符注入
<?php
//1.第一个参数
//echo $cmd = $_GET['cmd'];
//$str = "<php>phpinfo()</php>";
//preg_replace("/<php>(.*?)$cmd","\1",$str);
//2.第二个参数
//preg_replace("/php/e",$_GET['cmd'],'php');
//3.第三个参数
$str = $_GET['cmd'];
preg_replace("/[php](.*?)[/php]/e","\1",$str);
第一个参数cmd=</php>/e
使用/e修饰符,preg_replace会将 replacement 参数当作 PHP 代码执行,这个正则被正确的匹配到,在进行替换的过程中,cmd传入的String当作函数来运行,因此phpinfo()被成功执行。\1
是指第一个缓冲区。
第二个参数cmd=phpinfo()
只要在subject上匹配到pattern的内容,就会执行$_GET['cmd']
的代码。一定要让字符串匹配到正则它才会执行我们的恶意代码。
第三个参数cmd=[php]phpinfo()[/php]
修复方案
- 尽量不要执行外部的应用程序或命令
- 使用自定义函数或函数库来替代外部应用程序或命令的功能
- 使用escappeshellarg函数来处理命令的参数
- 使用safe_mode_exec_dir来指定可执行的文件路径
- 将执行函数的参数做白名单限制,在代码或配置文件中限制某些参数
最后
以上就是耍酷火为你收集整理的代码执行漏洞的全部内容,希望文章能够帮你解决代码执行漏洞所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复