web安全——命令执行与代码执行
命令执行漏洞
漏洞成因
由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端执行。命令注入攻击中Web服务器没有过滤类似system(),eval(),exec()等函数是该漏洞攻击成功的最主要原因。
应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的输入的情况下,就会造成命令执行漏洞。
PHP中常见命令执行函数
- system():执行一个外部的应用程序的输入并显示输出的结果
函数原型如下:string system(string command,int&return_var)
其中,command是要执行的命令,return_var存放执行命令后的状态值。
- passthru():passthru函数可以用来执行一个UNIX系统命令并显示原始的输出,
当UNIX系统命令的输出是二进制的数据,并且需要直接返回值给浏览器时,
需要使用passthru函数来替代system与exec函数。
Passthru函数原型如下:void passthru (string command, int&return_var)
其中,command是要执行的命令,return_var存放执行命令后的状态值。
- exec(args) :exec函数可以用来执行一个外部的应用程序
string exec (string command, array&output, int &return_var)
其中,command是要执行的命令,output是获得执行命令输出的每一行字符串,
return_var存放执行命令后的状态值。
- shell_exec(args) 执行shell命令并返回输出的字符串,
函数原型如下:string shell_exec (string command)
其中,command是要执行的命令。
反引号:`` 与shell_exec函数的功能相同
popen(handle,mode)(无回显)
proc_open(‘cmd’,‘flag’,‘flag’)(无回显)
pcntl_exec():需要开启pcntl扩展
命令拼接符
windows
1. “|”:直接执行后面的语句。
2. “||”:如果前面的语句执行失败,则执行后面的语句,前面的语句只能为假才行。
3. “&”:两条命令都执行,如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。
4. “&&”:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
linux
1. “;”:执行完前面的语句再执行后面的语句。
2. “|”:显示后面语句的执行结果。
3. “||”:当前面的语句执行出错时,执行后面的语句。
4. “&”:两条命令都执行,如果前面的语句为假则执行执行后面的语句,前面的语句可真可假。
5. “&&”:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
命令执行漏洞防御
在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义
参数的值尽量使用引号包裹(单引号变量不解析),并在拼接前调用addslashes进行转义
能使用脚本解决的工作,不要调用其他程序处理。尽量少用执行命令的函数,并在disable_functions中禁用
代码执行漏洞
漏洞成因
应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval(),eval可以将字符串当作函数进行执行)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。一般很难通过黑盒查找漏洞,大部分都是根据源代码判断代码执行漏洞。
PHP中代码执行的函数
eval():将输入的字符串当做PHP代码执行
assert():判断是否为字符串,是则当成代码执行。php官方在php7中更改了assert函数。在php7.0.29之后的版本不支持动态调用。
call_user_func():把第一参数作为回调函数
call_user_func_array():调用回到函数,并把第一个数组参数作为回到函数的参数
array_map():为数组的每个元素应用回调函数
create_function():创建匿名函数
preg_replace()、str_replace()、call_user_func()这些函数跟eval、exec等函数地特性相同,都属于危险函数
preg_replace(mixed pattern,mixed replacement,mixed subject [,int limit]):此函数可以用来执行一个正则表达式的搜索和替换
$pattern:正则表达式匹配的内容
$replacement:用于替换的字符串或字符串数组
$subject:要搜索替换的目标字符串或字符串数组
当$pattern存在/e模式修正符,允许代码执行
${}:z中间的php代码将会被解析
其他语言的代码执行函数
Javascript:eval
vbscript:execute、Eval
Python:exec
代码执行漏洞的利用
1、一句话木马
<?php @eval($_POST['passwd']);?>
2、获取当前工作路径
${exit(print(getcwd()))}
使用菜刀
3、读文件
${exit(var_dump(file_get_contents($_POST[f])))}
f=/etc/passwd
使用post提交数值 f=/etc/passwd
代码执行漏洞防御
- 对于eval()函数一定要保证用户不能轻易接触eval参数或者用正则严格判断输入的数据格式。
- 对于字符串一定要使用单引号包裹可控代码,并且插入前进行addslashes
- 对于preg_replace放弃使用e修饰符.如果必须要用e修饰符,请保证第二个参数中,对于正则匹配出的对象,用单引号包裹。