一.命令执行漏洞原理
1.形成原因
应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数的参数,并且开发人员对这个参数没有严格的过滤时就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。
2.漏洞的利用前提条件:
1.开发人员调用了能够执行系统命令的函数
2.这个函数的参数可控
3.开发人员没有对该函数的参数进行过滤或过滤不严
二:php可能存在命令执行漏洞的函数
1.利用系统函数来实现命令执行的函数
eval()、assert()、preg_replace()、call_user_func()
ob_start()、unserialize()、creat_function() 、usort()、uasort()、uksort()、 array_filter()、 array_reduce()、 array_map()
这些函数过滤不严谨,可能会造成远程命令执行漏洞 。
各个函数的使用
eval()函数
2.直接执行系统命令的代码函数
system(),exec(),shell_exec(),passthru(), pcntl_exec(), popen(), proc_open(),反引号
PHP命令执行函数常配合代码执行漏洞使用, 利用命令执行函数执行操作系统命令, 下列时部分函数用法
system();
system()函数可以执行系统命令, 并将命令执行的结果直接输出到界面中, 使用时直接在参数中传入需要执行的命令即可
system('ls');
exec();exec()函数可以执行系统命令, 但它不会直接输出结果, 而是将执行的结果保存到数组中
exec( 'ls' , $result );
参数1: 字符串类型,需要执行的系统命令
参数2: 数组类型,保存系统命令的执行结果
print_r($result); //输出执行结果
shell_exec();shell_exec()函数可以执行系统命令, 但它不会直接输出执行的结果, 而是返回一个字符串类型的变量来存储系统命令的执行结果, 在参数中传递需要执行的系统命令即可
echo shell_exec('ls');
passthru();passthru()函数可以执行系统命令, 并将执行结果输出到页面中, 与system()函数不同的是, 它支持二进制的数据, 更多的用于文件, 图片等操作, 使用时直接在参数中传递字符串类型的系统命令即可
passthru('ls');
popen();
popen()函数可以执行系统命令, 但不会输出执行的结果, 而是返回一个资源类型的变量用来存储系统命令的执行结果, 需要配合fread()函数来读取命令的执行结果
$result = popen( 'ls' , 'r' );
参数1:字符串类型,需要执行的命令
参数2:字符串类型,模式
返回值:资源类型,命令执行的结果
echo fread( $result , 100 );
参数1:资源类型,需要读取的文件指针
参数2:int类型,读取n个字节
返回值:字符串类型,读取的文件内容echo fread(popen('ls','r'),100);
反引号``反引号可以执行系统命令, 但它不会输出结果, 而是返回一个字符串类型的变量, 用来存储系统命令的执行结果, 可单独使用, 也可配合其他命令执行函数使用来绕过参数中的过滤条件
echo `ls`;
三:正则绕过
首先我们要清楚啥是正则表达式。http://t.csdnimg.cn/7yULz这篇博客介绍了常见的正则表达式类型,熟悉正则表达式有助于我们理解php语言中preg_match所过滤的内容。
绕过方式;
1.换行符绕过%0a可以替换(;)
2.数组绕过
因为preg_match只能处理字符串,当传入的subject是数组时会返回false
补充:在遇到php语言的题时,会看下列的字符,如果不知道其含义会比较棘手。
/i不区分大小写
/s匹配任何不可见字符,包括空格、制表符、换页符等等,等价于[fnrtv]
/D如果使用$限制结尾字符,则不允许结尾有换行;
3.%5c绕过
通过脚本的fuzz我们可以用%5c绕过
最后通过命令执行获取信息
4.preg_match("/^$/e") (注:php版本需要小于5.5.0),使用前需要获得php的版本号
preg_replace 使用了 /e 模式,导致可以代码执行
5.PHP利用PCRE回溯次数限制绕过某些安全限制
/<?.*[(`;?>].*/is //这个正则会验证我们上传文件的内容是否有php代码
<?.*匹配php的开头和文件内容 而[(`;?>]匹配php代码的末尾,
但是正则末尾还有.* ——一个贪婪匹配他会继续匹配代码末尾是否还有代码
之后根据ph牛的文章
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
我们可以让正则一直回溯知道超出他回溯的上限