PHP shell_exec 的安全风波


在PHP里有个很牛逼轰轰的函数 那就是 shell_exec.这个函数需要一个字符串,也就是命令.然后就可以在PHP脚本中执行 外部命令了.所以说 非常 强大但同时你需要非常注意因为稍有不谨慎就能导致安全隐患.

我之前就 基于这个函数 搞了两个简单的页面运行 LINUX 小工具: FIGLETCURL

原理如下:

1
2
3
$value = $_GET['value'];
$cmd = 'figlet $value';
shell_exec($cmd);
$value = $_GET['value'];
$cmd = 'figlet $value';
shell_exec($cmd);

三行代码很简单; 变量从URL地址栏里用户 通过 GET方式设置.然后就执行,如果用户给这样的输入:

hello | ls -l

最后执行的命令就会很不幸的变成这样:

figlet hello | ls -l

这命令组合后是合法的 ;这样的话用户 就可以执行任何命令;如果他 敲入 rm -rf / 那么后果不敢相像.

所以 我们必须把这些字符给排除(特殊字符)

1
2
3
4
$value = str_replace('|', '', $value);
$value = str_replace(';', '', $value);
...
...
$value = str_replace('|', '', $value);
$value = str_replace(';', '', $value);
...
...

很多符号都得考虑,比如逗号分号$(/等,一一排除并不是很完美的解决方法 因为这样一来有可能漏掉 二来用户就无法真正使用这些字符.

最简单的方法是 先把字符串中的单引号给删掉 然后 在字符串前后加一个单引号,这样 在LINUX命令行下 单引号内的字符就是不转义的.

1
$value = '\'' . str_replace('\'', '', $value) . '\'';
$value = '\'' . str_replace('\'', '', $value) . '\'';

比如 ‘a | ls -l’ 就会变成

figlet 'a | ls -l' 

这样 就会被认为是单一命令,相当安全.

英文:https://helloacm.com/escape-linux-command-to-prevent-security-holes-from-php-shell_exec-function/

GD Star Rating
loading...
本文一共 357 个汉字, 你数一下对不对.
PHP shell_exec 的安全风波. (AMP 移动加速版本)
上一篇: 怎么样查看主机的 CPU 核数?
下一篇: PHP 中 Rate Limit 的简单实现

扫描二维码,分享本文到微信朋友圈
1e88a65cb9fe2d880891a1cb5965a600 PHP shell_exec 的安全风波 I.T. PHP是最好的语言 折腾 有意思的 程序设计

评论