命令执行漏洞概述
- 命令执行定义
- 命令执行条件
- 命令执行成因
- 命令执行漏洞带来的危害
- 远程命令执行漏洞相关函数
- assert()
- preg_replace()
- call_user_func()
- a ( a( a(b)可变函数
- 远程命令执行漏洞的利用
- 系统命令执行漏洞相关函数
- system()
- exec()
- shell_exec()
- passthru()
- popen()
命令执行定义
- 基本定义:命令执行漏洞是指攻击者可以随意执行系统命令,分为远程命令执行(远程代码执行)和系统类命令执行。
- 原理:程序应用时有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen,当用户能控制这些函数的参数时,就可以将恶意系统命令,拼接到正常的命令中,从而造成命令执行攻击。
命令执行条件
- 用户能够控制函数输入
- 存在可以执行代码或者系统命令的危险函数
命令执行成因
- 由于开发人员再编写源码的时候,没有针对代码中的可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句,并且提交服务端执行。
- 命令注入攻击时,Web服务器没有过滤类似System,eval和exec等函数,是漏洞攻击成功的主要原因。
命令执行漏洞带来的危害
- 继承Web服务程序的权限去执行系统命令(任意代码)或者读写文件
- 反弹Shell
- 控制整个网站甚至整个服务器
- 进一步内网渗透
远程命令执行漏洞相关函数
assert()
说明:检查断言是否为false
assert(mixed $assertion, Throwable $exception = ?): bool
传统断言(PHP5和7)
**如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。**如果传入了 boolean 的条件作为 assertion,这个条件将不会显示为断言函数的参数;在调用你定义的 assert_options() 处理函数时,条件会转换为字符串,而布尔值 false 会被转换成空字符串。
断言这个功能应该只被用来调试。应该用于完整性检查时测试条件是否始终应该为 true,来指示某些程序错误,或者检查具体功能的存在(类似扩展函数或特定的系统限制和功能)。
简单说就是assert后面跟着字符串,那就当作php代码进行处理了。
preg_replace()
preg_replace — 执行一个正则表达式的搜索和替换
preg_replace(
string|array $pattern,
string|array $replacement,
string|array $subject,
int $limit = -1,
int &$count = null
): string|array|null
搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [,int $limit = -1 [,int
c
o
u
n
t
]
]
)
:
m
i
x
e
d
其中
p
a
t
t
e
r
n
是要搜索的模式。可以是一个字符串或字符串数组。当
p
a
t
t
e
r
n
存在一个“
/
e
”修饰符时,
count ]] ) : mixed 其中pattern是要搜索的模式。可以是一个字符串或字符串数组。当pattern存在一个“/e”修饰符时,
count]]):mixed其中pattern是要搜索的模式。可以是一个字符串或字符串数组。当pattern存在一个“/e”修饰符时,replacement的值会被当成php代码来执行。
现在解释一下这个函数的具体使用方法:
简化一下模型:preg_replace(O,A,HELLOWORLD),就是把第三个参数的中的O替换成A。
代码中第一个参数中的“.”代表任意字符,“*”代表任意次数,两个连接起来就代表任意字符串。
就是因为加了一个/e,这个时候就会把第二参数当作php函数进行执行。
call_user_func()
call_user_func — 把第一个参数作为回调函数调用
call_user_func(callable
c
a
l
l
b
a
c
k
,
m
i
x
e
d
.
.
.
callback, mixed ...
callback,mixed...args): mixed
a ( a( a(b)可变函数
<?php
if(isset( $_GET['a' ])&isset($_GET['b'])){
@$a = $_GET['a'];
@$b = $_GET['b' ];
@$a($b);//函数,可变函数
//$a就是函数的名
//$b就是函数的值
//?a=assert&b=phpinfo()
//assert(phpinfo());
else{
echo "Please input a&b";
?>
就是前面的作为函数名,后面的参数作为函数的参数。
远程命令执行漏洞的利用
?a=@eval(KaTeX parse error: Expected group after '_' at position 28: …一句话木马 ?a=print(_̲__FILE_);获取当前绝对…_POST[1],$_POST[2])); 1=shell.php&2=<?phpphpinfo()?>写shell
*************************************************************************************************************************************************************远程命令执行我们提供的字符串是php代码,而系统命令执行提供的字符串时系统命令
系统命令执行漏洞相关函数
- system()
- exec()
- shell_exec()
- passthru()
- popen()
- 反问号
system()
exec()
(PHP 4, PHP 5, PHP 7, PHP 8)
exec — Execute an external program
Description :
exec(string KaTeX parse error: Expected 'EOF', got '&' at position 16: command, array &̲output = null, int &$result_code = null): string|false
exec() executes the given command.
shell_exec()
Description:
shell_exec(string $command): string|false|null
参数就是要执行的命令。
passthru()
passthru ( string c o m m a n d [ , i n t s command [, int s command[,intsreturn_var ] ) : void
同exec()函数类似,passthru()函数也是用来执行外部命令(command)的。当所执行的Unix命令输出二进制数据,并且需要直接传送到浏览器的时候,需要用此函数来替代 exec()或 system()函数。常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。通过设置Content-type为image/gif,然后调用pbmplus程序输出 gif 文件,就可以从 PHP脚本中直接输出图像到浏览器。
参数:
command:要执行的命令。
return_var:如果提供return_var参数,Unix命令的返回状态会被记录到此参数。
popen()
popen ( string $command , string $mode ) : resource
打开一个指向进程的管道,该进程由派生给定的command命令执行而产生。
参数
command:命令。
mode:模式。
<?php
if(isset($_GET['a'])){
popen( "whoami >>1.txt" , 'r');
}else{
echo "Please input a";
}
?>
看一下代码中的大于号:
“>:覆盖”
“>>:追加”