介绍sysmon
系统监视器(sysmon) 是一种 Windows 系统服务和设备 驱动程序,该驱动程序一旦安装在系统上,就会在整个系统中保持驻留 重新启动以监视系统活动并将其记录到 Windows 事件日志中。它 提供有关进程创建、网络的详细信息 连接,以及文件创建时间的更改。通过收集事件 它使用Windows 事件收集或SIEM代理生成并随后对其进行分析,您可以识别恶意或 异常活动,并了解入侵者和恶意软件的操作方式 您的网络。该服务作为受保护的进程运行, 因此不允许各种用户模式交互。
请注意,sysmon不提供对它生成的事件的分析, 它也不会试图躲避攻击者。
sysmon的功能
- 使用完整的命令行记录当前和 父进程。
- 使用 SHA1(默认值)记录进程映像文件的哈希值, MD5、SHA256 或 IMPHASH。
- 可以同时使用多个哈希值。
- 在进程创建事件中包含进程 GUID 以允许 即使 Windows 重用进程 ID 时,也会关联事件。
- 在每个事件中包括一个会话 GUID,以允许事件关联 在同一登录会话中。
- 记录驱动程序或 DLL 的加载及其签名和哈希。
- 日志将打开,以便对磁盘和卷进行原始读取访问。
- (可选)记录网络连接,包括每个连接的 源进程、IP 地址、端口号、主机名和端口 名字。
- 检测文件创建时间的变化,以了解文件何时 真的创造了。修改文件创建时间戳是一种 恶意软件常用来掩盖其踪迹的技术。
- 如果在注册表中更改了配置,则自动重新加载配置。
- 规则筛选,用于动态包含或排除某些事件。
- 在启动过程的早期生成事件以捕获活动 甚至由复杂的内核模式恶意软件制造
第一种:删除配置项
sysmon有个机制,sysmon默认在发现注册表被修改的时候,就会自动重新加载配置,那么在“重新加载配置”的过程中,由于此时不存在安全检测规则、因此相当于他暂时失去了检测的能力。但是这段加载时间的长度,取决于配置的维护方式,如果是由一些管理系统进行管理sysmon,则可能更新的时间会比较快
相关代码 (仅凭个人思路)
#include<stdio.h>
#define REGISTRY_PATH "SOFTWARE\TestKey"
#define VALUE_NAME "TestValue"
// 修改注册表的函数
void ModifyRegistry() {
HKEY hKey;
LONG result;
// 打开或创建注册表键
result = RegCreateKeyExA(HKEY_CURRENT_USER, REGISTRY_PATH, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL);
if (result != ERROR_SUCCESS) {
printf("Error creating/opening registry key: %ldn", result);
return;
}
// 不断修改注册表的值
for (int i = 0; i < 10; i++) { // 限制循环次数为了安全
DWORD data = i; // 你可以根据需要更改这个值
result = RegSetValueExA(hKey, VALUE_NAME, 0, REG_DWORD, (const BYTE*)&data, sizeof(data));
if (result != ERROR_SUCCESS) {
printf("Error setting registry value: %ldn", result);
} else {
printf("Set %s to %dn", VALUE_NAME, data);
}
Sleep(1000); // 每秒修改一次
}
RegCloseKey(hKey);
}
// 线程入口函数
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
ModifyRegistry();
return 0;
}
int main() {
// 创建一个新线程
HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
if (hThread == NULL) {
printf("Error creating thread: %ldn", GetLastError());
return 1;
}
//执行自己的代码逻辑
.............................................
// 等待线程完成
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0;
}
第二种:关闭sysmon
通过卸载sysmon驱动的方式
执行: fltMC.exe 查看现在系统加载的驱动
执行:fltMC.exe unload sysmonDrv
然后很明显直接关闭sysmon是需要管理员权限的
这两个方法是几年之前就公开的了
第三种 干扰事件上报
sysmon通过ReportEventW这个用户模式的 API调用来报告事件 然后最终调用的内核API是NtTraceEvent 如图(借的图)
那么我们就可以自己编写驱动(能力有限,不再扩展),然后hook住NtTraceEvent 来干扰事件的上报,以绕过sysmon
相关项目:https://github.com/bats3c/Ghost-In-The-Logs
相关文章:https://www.freebuf.com/articles/system/233015.html
第四种 针对FileBlockExecutable 事件
如图
翻译过来就是:当 sysmon 检测并阻止创建可执行文件 (PE 格式) 时,将生成此事件。
也就是说,当sysmon检测到与规则匹配的文件创建后,sysmon 会记录事件 27 并删除该文件
sysmon的操作步骤如下:
- 拦截句柄关闭操作:
-
- sysmon监控文件句柄关闭事件,这通常意味着文件的写入或创建已完成。
- 验证文件的创建操作:
-
- sysmon检查文件是否是由于创建操作而生成的。如果文件是通过打开操作而创建,sysmon会忽略该事件,以避免对合法的修改行为造成干扰。
- 检查文件内容是否为可执行文件:
-
- sysmon会读取文件的一些字节,以检查其是否为可执行文件,通过检查文件的PE头(Portable Executable Header)确认文件的格式。如果文件没有MZ/PE签名(可执行文件的标识),sysmon会忽略该文件。
- 获取文件的完整路径:
-
- sysmon会检索到被操作文件的完整路径,以便后续的日志记录和规则匹配。
- 评估文件与用户提供的规则:
-
- sysmon会根据用户设置的规则检查文件。如果文件满足删除条件(如哈希值或其他属性),那么它将进行处理。如果文件不符合这些条件,则会忽略。
- 记录FileBlockExecutable事件:
-
- 一旦判定文件需要被删除,sysmon将记录一个FileBlockExecutable事件,这为后续分析提供了必要的信息。
- 标记文件以供删除,并返回:
-
- sysmon在完成检查后,将该文件标记为待删除状态,并在完成后返回调用。这表示sysmon已成功拦截并准备安全地删除该文件。
了解了sysmon的步骤之后,就衍生出了4种针对FileBlockExecutable绕过sysmon监测的方案:
第一种 create+open
sysmon的逻辑只关注创建文件的操作,这使得攻击者可以通过分离创建和写入操作来避开监控:
- 攻击者首先创建一个空文件并立即关闭,这个文件在没有内容的情况下没有触发PE头检查,因此sysmon不会进行任何记录或删除。
- 然后,攻击者以写模式打开这个文件,将恶意内容写入,最后关闭。这一步因为是打开文件,不属于创建操作,自然也不会被sysmon监控。
第二种 supersede
依靠的是FILE_SUPERSEDE:FILE_SUPERSEDE模式在创建文件时具有覆盖的行为。如果文件已存在,该模式会删除已有的文件,然后创建一个新的文件。因此,从操作系统的角度来看,这个操作相当于先删除后创建一个新文件。
因此:sysmon并没有针对FILE_SUPERSEDE模式进行相应的监控和逻辑处理,导致使用此模式的文件操作没有被sysmon记录或删除。结果是,攻击者通过该模式创建的新文件不会触发FileBlockExecutable的检测机制。
第三种 hardlink
这种方法是使用硬链接,所谓硬链接:是一种允许文件共享内容的机制。换句话说,它允许相同的内容以多个名称(在 NTFS 上最多 1024 个)显示,可能出现在不同的目录中。通过其中一个名称修改数据会自动将其更改为其他名称。删除文件会删除一个名称,但不一定会删除数据,只要可以从其他位置访问数据,数据就会保持不变。
所以可以通过硬链接绕过sysmon:
当用户创建一个硬链接时,这并不涉及打开或修改文件句柄,而只是为已存在的文件创建一个新的名称。在这种情况下,sysmon并不知道这个操作发生了,因为它通常只监控文件的打开、创建和修改。
攻击者可以利用sysmon对文件的监控保护,首先通过sysmon的规则将某个文件删除。虽然sysmon将记录删除操作,但实际上,文件内容并没有丢失,因为它仍然可以通过硬链接访问。
由于硬链接并不会影响原始文件的数据,只是提供了不同的名称,因此,即使sysmon删除了原始文件名,内容仍可以通过新创建的硬链接保持完整。
一旦sysmon删除了原始文件,攻击者可以选择将硬链接重命名为原始文件名,从而实现绕过安全防护。在这种情况下,用户看起来像是仍然拥有该文件,而实际上,所有的数据都通过硬链接得以保留。
第四种 locking
sysmon会去检测是否为PE文件,如果检测失败就可以绕过sysmon。那么可以通过文件内容锁定机制来绕过sysmon对可执行文件的检测。这个机制可以对文件的特定字节范围进行独占锁定。通过这种机制,我们可以临时获得对文件某些字节的独占访问权限,防止其他进程(包括sysmon)读取这些字节。
在sysmon检查文件的过程中,我们可以使用另一个句柄锁定与MZ头对应的字节。这意味着在sysmon尝试读取这些字节时,会遇到一个错误(例如,访问被拒绝),迫使sysmon中止对该文件的处理并完全忽略它。由于sysmon无法读取锁定的字节,它将无法验证文件是否为可执行文件,从而绕过了其检测机制。这样,攻击者可以成功地将恶意文件隐藏在sysmon的监控之下。
第五种 mapping
原理:sysmon在其防止机制中假设有能力删除特定的可执行文件。因此,在第7步中如果文件满足删除条件,sysmon会标记该文件进行删除。但是,如果试图删除正在运行的可执行文件,系统会阻止这一操作。这是由于Windows的内存管理器,尤其是其对内存映射文件的处理逻辑。当前运行的可执行文件在系统中保持活动状态,从而无法直接删除。
因此:为了干扰sysmon的删除操作,我们可以创建一个内存映射。这是通过在文件句柄存在的同时,创建一个指向该文件内容的内存映射,使得内存管理器认为该文件仍在使用中。
当sysmon尝试删除这个文件时,由于存在对该文件的内存映射,操作系统会阻止删除。系统会报错,表明文件正在被使用,导致删除操作失败。
这种方法绕过的是预防机制而非检测机制。sysmon仍会记录删除事件的发生,但实际上无法完成删除操作。因此,虽然该事件在日志中记录了,但实际删除并未成功。
创建内存映射其实可以直接创建相应的区段对象(section object),这就足以让sysmon的删除操作失败,而不需要实际将文件内容映射到内存中。
第六种 undelete
利用windows的文件删除机制:在Windows中,当文件被打开时,系统不会立即删除它。相反,程序可以请求I/O子系统设置一个待删除标志(pending deletion flag),但实际删除操作发生在最后一个引用或句柄关闭时。这意味着,即使文件被标记为待删除,只要仍有句柄存在,文件的内容仍然可以被访问。这些被标记为待删除的文件在系统中仍然可见,但对其他进程来说,它们不可访问。只有在持有句柄的程序中,仍然可以读取或写入这些文件。然后,我们可以使用之前的句柄来清除待删除标志,从而有效地“撤销”删除操作。这打破了sysmon的假设,即待删除标志等同于未来某个时间点的实际删除。欺骗了sysmon。
相关已实现以上功能的项目:https://github.com/huntandhackett/sysmon-indepth
原文始发于微信公众号(Ting丶的安全笔记):免杀—Sysmon Bypass
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论