代码执行漏洞

代码审计-代码执行

代码执行漏洞

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

挖掘思路

  • 用户能够控制函数输入
  • 存在可执行代码的危险函数

常见危险函数

eval()和assert()、回调函数、动态函数执行、preg_replace函数

eval()和assert()

eval() 、assert()将输入的字符串参数作为PHP程序代码来执行

实例

eval()

<?php
if(isset($_GET['cmd'])){
    $cmd = $_GET['cmd'];
    eval($cmd);
}else{
    echo "fail";
}

assert()

<?php
if(isset($_GET['cmd'])){
    $cmd = $_GET['cmd'];
    assert($cmd);
}else{
    echo "fail";
}

回调函数

原型:mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )

$callback 是要调用的自定义函数名称

$parameter 是自定义函数的参数

常见的回调函数:

call_user_func()、call_user_func_array()、array_map()等

实例

<?php
error_reporting(E_ALL ^ E_NOTICE);
function callback()
{
    $cmd = $_GET['cmd'];
    eval($cmd);
}


call_user_func('callback',$cmd);
?>

<?php
error_reporting(E_ALL ^ E_NOTICE);

$a =  'phpinfo();';
call_user_func($_GET['a'],$a);

?>

动态函数执行

  1. 定义一个函数
  2. 将函数名(字符串)赋值给一个变量
  3. 使用变量名代替函数名动态调用函数

实例

GET

<?php
// 接受GET请求a的参数作为一个函数,b是作为a函数里的参数
$_GET["a"]($_GET["b"]);
?>

POST

<?php
// 接受GET请求a的参数作为一个函数,b是作为a函数里的参数
$_GET["a"]($_POST["b"]);

?>

正则表达式

正则表达式语法规则 普通字符作为原子

限定符 特殊符号作为原子

边界限制符 通用字符类型作为原子

后向引用  自定义原子表作为原子

1 $pattern = '/\d/'; //匹配任何一个数字

2 $pattern = '/\D/'; //匹配任何一个非数字

3 $pattern = '/\w/'; //匹配任何一个 数字、字母(大小写)、下划线

4 $pattern = '/\W/'; //匹配任何一个 非 数字、字母(大小写)、下划线

5 $pattern = '/\s/'; //匹配任何一个空白字符 空格 \n \r 回车 换行

6 $pattern = '/\S/'; //匹配任何一个非空白字符

实例

<?php
//1.普通字符作为原子
$pattern = '/abc/';
$str = 'abcdefghijklmnopqrstuvwxyzabc';
preg_match_all($pattern,$str,$res);
var_dump($res);

//2.特殊符号的字符作为原子
$pattern = '/\[php\]/';
$str = '[php]123456';
preg_match_all($pattern,$str,$res);
var_dump($res);

//3.通用字符作为原子
$pattern1 = '/\d/';  //0-9
$pattern2 = '/\D/'; //a-zA-Z
$str = '123411aassfafdas22';
preg_match_all($pattern1,$str,$res);
var_dump($res);
?>

<?php
//4.自定义原子
$pattern = '/[aj]sp/'; //匹配[aj]中任意一个字符作为原子的asp jsp
$str = 'aaaspjjjjjspspsp';
preg_match_all($pattern,$str,$res);
var_dump($res);

//5.限定符
$pattern1 = '/go*gle/'; //* 匹配前面出现的原子次数0次 1次 或多次 g go goo
$pattern2 = '/go+gle/'; //+ 匹配前面出现的原子次数1次 或多次 go goo
$pattern3 = '/go?gle/'; //? 匹配前面出现的原子次数0次 1次 g go
$str = 'go';
preg_match_all($pattern1,$str,$res);
var_dump($res);

//6.边界限定
$pattern1 = '/^abc/'; //匹配输入字符开始的位置 必须要以abc的形式开头
$pattern2 = '/abc$/'; //匹配输入字符结尾的位置 必须要以abc的形式结尾
$pattern3 = '/^abc$/'; //只匹配abc
$str ='abc';
preg_match_all($pattern3,$str,$res);
var_dump($res);

//7.反向引用
$pattern = '/\d{4}(-)\d{2}\\1\d{2}/';
$str = '2021-08-30';
preg_match_all($pattern,$str,$res);
var_dump($res);

?>

preg_replace函数

原型:

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

$pattern 正则匹配的内容$replacement 用于替换的字符串或字符串数组

$subject 要进行搜索和替换的字符串或字符串数组

$pattern 存在/e模式修正符修饰 允许代码执行

实例

第一个参数

<?php
echo $cmd = $_GET['cmd'];
$str = '<php>phpinfo()</php>';
preg_replace("/<php>(.*?)$cmd","\\1","$str");

?>

第二个参数

<?php
preg_replace("/php/e",$_GET['cmd'],'php');
?>

第三个参数

<?php
$str = $_GET['cmd'];
preg_replace("/\[php\](.*?)\[\/php\]/e","\\1",$str);
?>

修复方案

  • 尽量不要执行外部的应用程序或命令 使用自定义函数或函数库来替代外部应用程序或命令的功能
  • 使用escappeshellarg函数来处理命令的参数
  • 使用safe_mode_exec_dir来指定可执行的文件路径
  • 将执行函数的参数做白名单限制,在代码或配置文件中限制某些参数
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C9ccc00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值