PHP代码审计之代码执行漏洞

前言:

  这几天过的是相当的充分,不过终于是腾出时间来记录学习笔记了,继上次的特殊注入之后,这次准备记录一下PHP代码中几个高危函数使用不当引起的漏洞。

参考文献:水清云影的教学

正文:

  关于代码执行漏洞的解释:代码执行漏洞是指对高危函数传参时过滤不当,字符串被当作代码执行引起的代码注入漏洞。

  关于代码执行漏洞的利用条件:一般来说要满足三个基础条件,一是存在可以将字符串转换成代码执行的高危函数,二是用户可以直接或间接控制该字符串,三是对该字符串的过滤不当。

常见PHP高危函数:

  1. 代码执行函数:eval()和assert()

    1)bool eval(mixed phpcode):把字符串按照 PHP 代码来计算。该字符串必须是合法的 PHP 代码,且必须以分号结尾。如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。

    2)bool assert ( mixed $assertion [Throwable $exception] )如果 assertion :如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

  2. 回调函数:call_user_func()、call_user_func_array()和array_map()

    1)mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ):把第一个参数作为回调函数调用。

    2)mixed call_user_func_array ( callable $callback , array $param_arr ):把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。

    3)array array_map ( callable $callback , array $array1 [, array $... ] ):返回数组,是为 array1 每个元素应用 callback函数之后的数组。 callback 函数形参的数量和传给 array_map() 数组数量,两者必须一样。

  3. 动态执行函数:函数名和参数都由动态变量实现

    1)定义一个函数;

    2)将函数名(字符串)赋值给一个变量;

    3)使用变量名代替函数名调用函数。

高危函数使用实例:

eval()和assert()
1
2
3
4
5
6
7
8
9
10
eval-assert.php
<?php
$shell=$_GET['shell'];
eval($shell);
?>

<?php
$shell=$_GET['shell'];
assert($shell);
?>

两个函数使用效果类似,如下图:p1

  eval()和assert()两个函数在执行php语句的效果方面是相同的,但eval()函数的参数必须以分号结尾,assert()可以不用,毕竟这个函数原意是用来断言的。

call_user_func()、call_user_func_array()和array_map()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
callback.php
<?php
function callback(){
$shell=$_GET['shell'];
eval($shell);
}
@call_user_func('callback',$shell);
?>

<?php
function callback(){
$shell=$_GET['shell'];
eval($shell);
}
@call_user_func_array('callback',array($shell));
?>

<?php
function callback(){
$shell=$_GET['shell'];
eval($shell);
}
@array_map('callback',array($shell));
?>

三个代码的运行的效果类似,如下图:p2

  这三个函数都是将第一个参数当作一个方法名,第二个参数当作该方法的内部参数。不同的是第一个函数接受的回调内部参数是单个变量,而后两个函数接受的回调内部参数必须是数组类型。

动态执行函数
1
2
3
4
5
6
7
8
9
10
run.php
<?php
$_GET['func']($_GET['shell']);
?>

<?php
$func=$_GET['func'];
$shell=$_GET['shell'];
$func($shell);
?>

两段代码执行效果类似,如下图:p3

  关键就是能控制函数名和参数,当函数名是个可控变量的时候,该部分的输出就能被改成php中各类高危函数,造成代码执行漏洞。

代码执行漏洞的防范:

  不管是哪种代码执行漏洞,必定会牵扯到参数被利用的地方,只要对用户的传参进行各方面的过滤,或者直接将代码写死,就能有效预防代码执行漏洞的出现。

总结:

  对作为一个小白的我来说,对代码执行漏洞的理解不是太过于深入,以上就是目前的我所理解的代码执行漏洞,如果有什么不完整或不正确的地方,希望大佬们能多多批评:

QQ