像往常一样,我的反调试相关帖子,一切都从微软没有记录的一点无害标志开始。或者至少我是这么认为的。
这次的主要攻击者是NtMapViewOfSection
,一个可以将段对象映射到给定进程的地址空间的系统调用,主要用于实现共享内存和内存映射文件(Win32 API 将是MapViewOfFile)。
NTSTATUS NtMapViewOfSection( HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
通过在ntoskrnl
's 中进行一些挖掘MiMapViewOfSection
并在 Windows 标头中搜索已知常量,我们可以恢复大多数有效标志值背后的含义。
/* Valid values for AllocationType */ MEM_RESERVE 0x00002000 SEC_PARTITION_OWNER_HANDLE 0x00040000 MEM_TOPDOWN 0x00100000 SEC_NO_CHANGE 0x00400000 SEC_FILE 0x00800000 MEM_LARGE_PAGES 0x20000000 SEC_WRITECOMBINE 0x40000000
最初我失败了ctrl+f
并且没有意识到这0x2000
是一个已知的标志,所以我开始深入挖掘。在同一个函数中,我们还可以发现标志的作用及其主要限制。
// --- MAIN FUNCTIONALITY --- if (SectionOffset + ViewSize > SectionObject->SizeOfSection && !(AllocationAttributes & 0x2000)) return STATUS_INVALID_VIEW_SIZE; // --- LIMITATIONS --- // Image sections are not allowed if ((AllocationAttributes & 0x2000) && SectionObject->u.Flags.Image) return STATUS_INVALID_PARAMETER; // Section must have been created with one of these 2 protection values if ((AllocationAttributes & 0x2000) && !(SectionObject->InitialPageProtection & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE))) return STATUS_SECTION_PROTECTION; // Physical memory sections are not allowed if ((Params->AllocationAttributes & 0x20002000) && SectionObject->u.Flags.PhysicalMemory) return STATUS_INVALID_PARAMETER;
现在,这听起来像是一个沼泽标准MEM_RESERVE
,您也可以VirtualAlloc(MEM_RESERVE)
随心所欲,但是与此内存交互的 API 会以不同的方式对待它。
你可能会问有多大不同?好吧,在错误地将标志识别为未记录后,我继续尝试创建我可能创建的最大部分。一切都很顺利,直到我打开ProcessHacker内存视图。PC 几乎无法使用至少一分钟,此后黑客也有一段时间没有响应。随后的运行似乎没有抓住了整个系统但是它仍然采取长达4分钟的NtQueryVirtualMemory
调用返回。
我想你可以像鲍勃·罗斯所说的那样把这称为快乐的小事故。
由于我很懒,所以我决定使用Windows Performance Recorder而不是潜入和倒退。这是一个使用 ETW 跟踪的漂亮工具,可以让您深入了解系统上发生的事情。然后可以在Windows 性能分析器中查看记录的跟踪。
这并没有说太多,但至少我们知道在哪里看。
在花了更多时间盯着每个人最喜欢的反编译器中的代码之后,它变得更加清楚发生了什么。我敢打赌,它会遍历给定内存范围的每个页表条目。而且因为我们一次处理数 TB 的数据,所以迭代次数超过 10 亿次。(MiQueryAddressState
是一个很大的函数,我不认为一个简短的伪代码片段可以做到公正)
从我的测试来看,视图大小和所用时间之间的关系是完全线性的,这一事实也加强了这一点。为了进一步验证这个想法,我们还可以做一些快速的餐巾纸数学计算,看看它是否全部加起来:
instructions per second (ips) = 3.8Ghz * ~8 page table entries (n) = 12TB / 4096 time taken (t) = 3.5 minutes instruction per page table entry = ips * t / n = ~2000
在我看来,这个数字看起来相当可信,所以,把所有的东西加起来,我会坚持当前的想法。
// file handle must be a handle to a non empty file void* section = nullptr; auto status = NtCreateSection(§ion, MAXIMUM_ALLOWED, nullptr, nullptr, PAGE_EXECUTE_READWRITE, SEC_COMMIT, file_handle); if (!NT_SUCCESS(status)) return status; // Personally largest I could get the section was 12TB, but I'm sure people with more // memory could get it larger. void* base = nullptr; for (size_t i = 46; i > 38; --i) { SIZE_T view_size = (1ull << i); status = NtMapViewOfSection(section, NtCurrentProcess(), &base, 0, 0x1000, nullptr, &view_size, ViewUnmap, 0x2000, // <- the flag PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(status)) break; }
请注意,理想情况下,您需要用这些部分包围代码,因为只有这些部分的保留部分会导致速度变慢。此外,事务也可以是需要非空文件的解决方案,而无需触及任何已存在的内容或创建用户可见的内容。
我认为这是一种伟大而强大的技术,可以让人们分析您的代码。资源使用是合理的,设置它只需要几个系统调用,并且不太可能被意外触发。
过去几十年,会展业信息化数字化相对落后,过度依赖于物理空间。2020年,在全球...
Hyper-V是微软的一款虚拟化产品,是微软第一个采用类似VMware和Citrix开源Xen一...
如果你在IT领域工作足够长的时间,你会发现,相同的事情似乎在反复发生,只是使...
国际数据公司(IDC)日前发布了《中国工业云市场跟踪(2020上半年)》报告。报告显示...
函数工作流采用按需付费方式,无最低费用,分别对请求次数和执行时间进行收费。 ...
本文转载自微信公众号「前端思维框架」,作者ViktorHub。转载本文请联系前端思维...
首先,大数据是互联网发展的必然结果,随着社会资源逐渐向互联网汇集,大数据本...
注册一个com的 域名 多少钱?注册一个 com域名 的价格平时大概是55元,如果是第...
目前我国经济已进入中速增长平台,在国际环境发生重大变化的背景下,要在“十四...
来源 | 阿里巴巴云原生公众号 背景 KubeVela v1.0 启用了新的官网架构和文档维护...