漏洞原理
程序有时需要调用一些执行系统命令的函数,当用户能控制这些函数中的参数时,就可以将恶意的系统命令拼接到正常命令中,从而造成命令执行攻击。
漏洞产生原因
- 开发人员编写源码时,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句,并提交服务端执行。
- Web服务器没有过滤类似system、eval和exec等函数,是该漏洞攻击成功的主要原因。
漏洞危害
- 继承Web服务程序的权限去执行系统命令或读写文件
- 反弹shell
- 控制整个网站甚至控制服务器
- 进一步内网渗透
命令执行相关函数
- system函数
string system(string $command, int &$return_var = ?)
// 执行成功则返回命令输出的最后一行,失败则返回False
执行多条命令时,在Linux系统上可以使用:① ; - 前面的语句执行完成后执行后面的语句 ② |(管道符) - 显示后面语句的执行结果 ③ || - 前面的语句执行出错时执行后面的语句;在Windows系统上可以使用:① & - 前面的语句为假时执行后面的语句 ② && - 前面的语句为假时出错后面的语句不执行 ③ | - 显示后面语句的执行结果 ④ || - 前面的语句执行出错时执行后面的语句。
- exec函数
string exec(string $command, array &$output = ?, int &$return_var = ?)
// 返回命令执行结果的最后一行内容
- shell_exec函数
string shell_exec(string $cmd)
// 返回命令执行的输出 如果执行过程中出错或进程不产生输出 则返回NULL
- passthru函数
void passthru(string $command, int &$result_code = null)
// 执行外部程序并显示原始输出
当所需执行的Unix命令输出二进制数据,并且需要直接传送到浏览器的时候,需要用此函数来替代exec或system。常用来执行pbmplus之类的可以直接输出图像流的命令。通过设置content-type为image/gif,然后调用pbmplus程序输出gif文件,就可以从PHP脚本中直接输出图像到浏览器。
- eval函数
eval(string $code)
eval函数将输入的字符串参数当作PHP程序代码来执行。
- assert函数
bool assert(mixed $assertion, string $description = ?) // PHP5
bool assert(mixed $assertion, Throwable $exception = ?) // PHP7
assert函数会检查指定的assertion并在结果为False时采取适当的响应。如果assertion是字符串,它将会被assert函数当做PHP代码来执行。
- preg_replace
string|array|null preg_replace(
string|array $pattern,
string|array $replacement,
string|array $subject,
int $limit = -1,
int &$count = null
)
该函数搜索subject中匹配pattern的部分,之后以replacement进行替换。当使用被弃用的e修饰符时,这个函数转义一些字符,在完成替换后,引擎会将结果字符串作为PHP代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。
- call_user_func
mixed call_user_func(callable $callback, mixed ...$args)
防御
- 尽量不要执行外部命令
- 使用自定义函数或函数库来替代外部命令的功能
- 使用escapeshellarg函数来处理命令参数
- 使用safe_mode_exec_dir指定可执行文件的路径,可以把会使用的命令提前放入此路径内