浅析代码执行漏洞

发布于 2021-08-06  66 次阅读


什么是代码执行

在开发中,开发人员经常需要能灵活的插入一些代码,并且是这些代码生效,例如:

  • 系统主题模板调用
  • 灵活的逻辑判断<?php
    $string = "beautiful";
    $time = "winter";

    $str = 'This is a $string $time morning!';
    echo $str. "<br />";

    eval("\$str = \"$str\";");
    echo $str;
    ?>
    //输入:
    This is a $string $time morning!
    This is a beautiful winter morning!

漏洞产生的原因

当这些代码中的参数可控的时候,恶意用户就可以插入自己想要的执行的代码(或命令),这行代码呗执行之后就造成了漏洞。

例如:

<?php
$a = $_GET[8];
eval($a);

?>
image-20210321211635945
<?php
$a = $_GET[8];
system($a);
?>
image-20210321212127585

常见的命令/代码执行函数

eval() 和 assert()

  1. mixed eval( string $code)把字符串code作为PHP代码执行
    • 代码不能包含打开/关闭 PHP tags。比如不能传入: '<?php echo "Hi!"; ?>'。但仍然可以用合适的 PHP tag 来离开、重新进入 PHP 模式。比如 'echo "In PHP mode!"; ?>In HTML mode!<?php echo "Back in PHP mode!";’。
    • 传入的必须是有效的 PHP 代码。所有的语句必须以分号结尾。比如 'echo "Hi!"' 会导致一个 parse error,而 'echo "Hi!";' 则会 正常运行。
  2. bool assert ( mixed $assertion [, string $description ] )PHP语言中是用来判断一个表达式是否成立,返回true or false。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

调用参数过滤不当

call_user_func()、call_user_func_array ()、 array_map ()等几十个函数都可以调用其他函数的 功能。其中一个参数为调用的函数名,如果这个传入的函数名可控,那就可以调用意外的函数来执行我们想 执行的代码。

  1. mixed call_user_func( callable $callback[, mixed $parameter[, mixed $…]] )第一个参数 callback是被调用的毁掉函数,其余参数是回调函数的参数,该类函数的功能是调用函数,多用在框架中动态调用函数,其余参数都是回调函数的参数
  2. array array_map( callable $callback, array $array1[, array $…] )返回数组,是为 array1 每个元素应用 callback函数之后的数组。 callback 函数形参的数量和传给array_map() 数组数量,两者必须一样。

动态函数执行

由于PHP特性,PHP的函数名称可以由字符串进行拼接。

//例子1
$a = 'e'.'v'.'a'.'l';
$a('phpinfo()');

//例子2
$_GET['a']($_POST[_]);

基于该类写法变形出来的,经常被当做WEB后门使用

漏洞的危害

  1. 继承Web服务程序的权限去执行系统命令或读写文件。
  2. 反弹shell
  3. 控制整个网站甚至控制服务器。
  4. 进一步内网渗透

漏洞如何防护

  1. 尽量不要执行外部命令。
  2. 使用自定义函数或者函数库来代替外部命令的功能。
  3. 使用escapeshe||arg函数来处理命令参数。
  4. 使用safe_mode_exec_dir指定可执行文件的路径。(safe_mode_exec_dir指定路径时可以把会使用的命令提前放入此路径内。)
  5. 使用disable_funcation()禁用危险命令