如果注入器由特定应用程序启动,PE 注入会失败吗?

PE injection fails if injector gets launched by specific application?

简短免责声明:由于此问题包含有关 hacking/pentesting 的主题,我想声明此问题仅作为学校项目的一部分用于教育目的。为了防止可能的滥用,我将只 post 理解问题所必需的代码。

为了演示 Windows10 的危险和漏洞,我目前正在编写一个小型 C++/WinAPI 应用程序,它使用两种常用技术:

我设法在独立文件中成功地执行了这两种技术。但是,一旦我将这两种方法结合起来(即先提升,然后注入),就会出现一个奇怪的错误。

问题描述

当注入器手动启动(通过双击)时,一切正常,但是当注入器由于 UAC 绕过而由 System32\fodhelper.exe (x64) 启动时,会发生以下情况:注入已完成,注入应用程序的控制台 window 出现,但我没有继续执行,而是收到一堆错误消息,指出“The code execution cannot proceed because [garbage characters].dll was not found”。这表明偏移量出了点问题,Windows 加载程序正试图在错误的位置读取导入。

总结:代码注入工作正常,除非注入器由 fodhelper.exe 启动。在这种情况下,注入的 PE 文件无法 运行.

到目前为止,我已尝试找出问题的根源

似乎注入行为完全相同,但指标显示由于 fodhelper.exe 传递给注入器的一些未知影响,Windows 加载程序似乎表现不同。

感谢任何解释或假设!如果您需要更多信息,请随时询问。

最小可重现示例

(调试信息和注释有限): https://0bin.net/paste/UPRIg12n#6nJvBok72UcDvIa56c-XEss7AibIh1Zrs+c3sUzvQMj

注意:如果排除 elevateProcess 函数或使用 UAC 手动提升 exe,请查看注入如何工作,以及包含所述函数时注入如何失败。

编辑

根据用户 RbMm 的回答,此错误是自动应用于 fodhelper.exe 和似乎被所有子进程继承。据此,启动目标进程时的removing/resetting这个属性应该修复错误。到目前为止,我已经尝试了以下方法,但结果没有任何改变:

DWORD resetPolicy = 0;
STARTUPINFOEXA siEx = { 0 };
SIZE_T AttributeListSize = 0;
siEx.StartupInfo.cb = sizeof(siEx);
InitializeProcThreadAttributeList(NULL, 1, 0, &AttributeListSize);
siEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, AttributeListSize);
InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &AttributeListSize);
UpdateProcThreadAttribute(siEx.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &resetPolicy, sizeof(resetPolicy), NULL, NULL);
...
CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT | CREATE_SUSPENDED, NULL, NULL, (LPSTARTUPINFOA)&siEx, &PI);

当进程通过 RunAs 创建并提升时 - appinfo.dll 调用 RAiLaunchAdminProcess函数(这是在一些svchost.exe)和这个函数,将STARTUPINFOEX(和EXTENDED_STARTUPINFO_PRESENT标志)传递给CreateProcessAsUser。这里 - lpAttributeList,特别是 PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY attribute key is used for set several exploit mitigation policy for the child process (fodhelper.exe in your case). and here EnableModuleTamperingProtection is set for child process tree. effect of this - when system resolve import descriptor, it check (inside LdrpGetImportDescriptorForSnap) for this mitigation flag, and if it enabled - call LdrpCheckPagesForTampering api, it return true, if SharedOriginal 是 0,这意味着这是 EXE/IAT 的写时复制私有副本——因此 'tampered' 与。 在调用 LdrpMapCleanModuleView 之后。此时你的尝试开始失败

可能第一个 public 关于这个的信息,来自 Alex Ionescu -

LdrpCheckPagesForTampering/LdrpMapCleanModuleView (RS3) are pretty cool antihollowing mitigations (EPROCESS.EnableModuleTamperingProtection)

如果您自行启动新进程,您当然不会为设置 PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY 调用 UpdateProcThreadAttribute,在这种情况下,您的代码 有时 可以工作。真的只是随机的,有时 - 这里存在许多其他错误和糟糕的编码