撰写本系列文章目的在於提升资讯安全之实务能力,
并透过实作体悟到资讯安全领域的重要性,
本系列所有文章之内容皆有一定技术水平,
不得从事非法行为、恶意攻击等非法活动,
「一切不合法规之行为皆受法律所约束」,
为了避免造成公司、厂商或玩家之间困扰,
所有实作不会拿已上市产品、Online Game 等等来作范例学习,
且部分具有深度、价值之内容,将会提升一定阅读门槛(不对该技术做分析、解说),
请勿透过本系列文章所学,从事任何非法活动,请不要以身试法!!!
就在昨天(铁人赛 Day 03)的时候有说到 Blackbone 的其中一个 DLL Injection 方法,
还没看的人可以先去快速看一下:【Day 03】- 打针!打针!从 R0 注入的那件事!
在昨天的文章中,最後部分有提到两个隐藏 Module 的方法,
而就在今天!就是这篇文章!将要来说说第一个隐藏技术:
PEB(Process Environment Block)断链
另外:
明天,也就是铁人赛 Day 05 将会介绍 PEB 断链的缺点与找出隐藏 Module 的方法,
後天,也就是铁人赛 Day 06 将会介绍其它更厉害、更难以侦测的隐藏 Module 方法!
最後:
这个 Module 系列就会在铁人赛 Day 06 结束,
当然,隐藏 Module 的方法百百种,这几天只简单的讲几个例子~
铁人赛 Day 07 将会进入 Process 伪装、隐藏,甚至是 Rookit 常用的技术。
(在阅读这篇文章之前,应该要确保目前脑袋是清晰的)
首先要先说一下,
小弟我目前还属於菜鸟阶段,正不断努力学习中,
若有发现错误或不妥之处还请不吝赐教。
欢迎大家多多留言,互相交流交流。
那麽进入今天主题~~
第一个问题:
什麽是 PEB(Process Environment Block)???
那这个 PEB 长什麽样子?可以怎麽看?
!process 0 0 notepad.exe
查看 notepad.exe
lkd> !process 0 0 notepad.exe
PROCESS ffff8f899b178080
SessionId: 1 Cid: 0b2c Peb: ecacd59000 ParentCid: 10b8
DirBase: 984ad000 ObjectTable: ffffa685c250d6c0 HandleCount: 262.
Image: notepad.exe
Peb: ecacd59000
!peb ecacd59000
查看 notepad.exe 的 PEB
dt _peb
查看 PEB 结构
lkd> dt _peb
ntdll!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
+0x010 ImageBaseAddress : Ptr64 Void
+0x018 Ldr : Ptr64 _PEB_LDR_DATA
+0x020 ProcessParameters : Ptr64 _RTL_USER_PROCESS_PARAMETERS
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
+0x3a0 WaitOnAddressHashTable : [128] Ptr64 Void
+0x7a0 TelemetryCoverageHeader : Ptr64 Void
+0x7a8 CloudFileFlags : Uint4B
好了,到这边基本上介绍完 PEB 是什麽了(? XD 已经快速带过
假设你/你刚才有仔细看的话,会注意到:
lkd> !peb ecacd59000
PEB at 000000ecacd59000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: No
--->ImageBaseAddress: 00007ff67a610000
NtGlobalFlag: 0
NtGlobalFlag2: 0
--->Ldr 00007ff9baa6f3a0
Ldr.Initialized: Yes
--->Ldr.InInitializationOrderModuleList: 000002de3e212440 . 000002de3e27cb90
--->Ldr.InLoadOrderModuleList: 000002de3e2125b0 . 000002de3e27c320
--->Ldr.InMemoryOrderModuleList: 000002de3e2125c0 . 000002de3e27c330
--- --- --- ---
--- --- --- ---
--- --- --- ---
lkd> dt _peb
ntdll!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
-->+0x010 ImageBaseAddress : Ptr64 Void
-->+0x018 Ldr : Ptr64 _PEB_LDR_DATA
+0x020 ProcessParameters : Ptr64 _RTL_USER_PROCESS_PARAMETERS
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
--- --- --- --- ---
+0x3a0 WaitOnAddressHashTable : [128] Ptr64 Void
+0x7a0 TelemetryCoverageHeader : Ptr64 Void
+0x7a8 CloudFileFlags : Uint4B
再次进入到 WinDbg 输入 dt _PEB_LDR_DATA
来看一下 Ldr 的数据类型:
lkd> dt _PEB_LDR_DATA
ntdll!_PEB_LDR_DATA
+0x000 Length : Uint4B
+0x004 Initialized : UChar
+0x008 SsHandle : Ptr64 Void
-->+0x010 InLoadOrderModuleList : _LIST_ENTRY
-->+0x020 InMemoryOrderModuleList : _LIST_ENTRY
-->+0x030 InInitializationOrderModuleList : _LIST_ENTRY
+0x040 EntryInProgress : Ptr64 Void
+0x048 ShutdownInProgress : UChar
+0x050 ShutdownThreadId : Ptr64 Void
看一下 MSDN 可以知道:
哦!所以 Process 中的 Module 资讯是存在这三个表里的:
然後储存着它们讯息的 structure 是 LDR_DATA_TABLE_ENTRY
所以再次进入到 WinDbg 输入 dt _LDR_DATA_TABLE_ENTRY
来看一下 LDR_DATA_TABLE_ENTRY structure 长什麽样子:
lkd> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x010 InMemoryOrderLinks : _LIST_ENTRY
+0x020 InInitializationOrderLinks : _LIST_ENTRY
+0x030 DllBase : Ptr64 Void
+0x038 EntryPoint : Ptr64 Void
+0x040 SizeOfImage : Uint4B
+0x048 FullDllName : _UNICODE_STRING
+0x058 BaseDllName : _UNICODE_STRING
+0x068 FlagGroup : [4] UChar
+0x068 Flags : Uint4B
+0x068 PackagedBinary : Pos 0, 1 Bit
+0x068 MarkedForRemoval : Pos 1, 1 Bit
+0x068 ImageDll : Pos 2, 1 Bit
+0x068 LoadNotificationsSent : Pos 3, 1 Bit
+0x068 TelemetryEntryProcessed : Pos 4, 1 Bit
+0x068 ProcessStaticImport : Pos 5, 1 Bit
--- --- --- ---
--- --- --- ---
--- --- --- ---
+0x070 HashLinks : _LIST_ENTRY
--- --- --- ---
--- --- --- ---
--- --- --- ---
所以所以,用一张图来表达以上资讯:
(如果感觉模糊看不清楚,请复制图片连结)
(在新分页打开就可以看高清图片!)
图片参考自:33c0c3 大大画的图
补充一下:
(因为这是补充的,所以就不详细写了)
(多看几次就会看懂我要写的内容是什麽 XD)
lkd> dt _PEB 0x000000ec`acd59000
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
--- --- --- ---
--- --- --- ---
--- --- --- ---
+0x003 IsLongPathAwareProcess : 0y0
+0x004 Padding0 : [4] ""
+0x008 Mutant : 0xffffffff`ffffffff Void
+0x010 ImageBaseAddress : 0x00007ff6`7a610000 Void
+0x018 Ldr : 0x00007ff9`baa6f3a0 _PEB_LDR_DATA
--- --- --- ---
--- --- --- ---
--- --- --- ---
lkd> dt 0x00007ff9`baa6f3a0 _PEB_LDR_DATA
ntdll!_PEB_LDR_DATA
+0x000 Length : 0x58
+0x004 Initialized : 0x1 ''
+0x008 SsHandle : (null)
+0x010 InLoadOrderModuleList : _LIST_ENTRY [ 0x? - 0x? ]
+0x020 InMemoryOrderModuleList : _LIST_ENTRY [ 0x?0 - 0x? ]
+0x030 InInitializationOrderModuleList : _LIST_ENTRY [ 0x? - 0x? ]
+0x040 EntryInProgress : (null)
+0x048 ShutdownInProgress : 0 ''
+0x050 ShutdownThreadId : (null)
lkd> dt 0x00007ff9`baa6f3a0+0x010 _LIST_ENTRY
ntdll!_LIST_ENTRY
[ 0x000002de`3e2125b0 - 0x000002de`3e27c320 ]
+0x000 Flink : 0x? _LIST_ENTRY [ 0x? - 0x? ]
+0x008 Blink : 0x? _LIST_ENTRY [ 0x? - 0x? ]
到了这边概念大致上已经讲完,
接下来讲一下 Module 的隐藏方式:
首先,先回到 Blackbone Project 中的 Loader.c 的 BBUnlinkFromLoader Func
PPEB pPeb = PsGetProcessPeb( pProcess );
if (!pPeb)
{
DPRINT( xxxxxxxxxx );
return STATUS_NOT_FOUND;
}
for (PLIST_ENTRY pListEntry = pPeb->Ldr->InLoadOrderModuleList.Flink;
pListEntry != &pPeb->Ldr->InLoadOrderModuleList;
pListEntry = pListEntry->Flink)
{
--- --- ---
--- --- ---
}
xxx pEntry = CONTAINING_RECORD(
pListEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks
);
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
// addr: 结构体中某个成员地址
// type: 结构体原本的样子
// field: 结构体的某个成员
//详细说明请谷哥...
// Unlink
if ((PVOID)pEntry->DllBase == pBase)
{
RemoveEntryList( &pEntry->InLoadOrderLinks );
RemoveEntryList( &pEntry->InInitializationOrderLinks );
RemoveEntryList( &pEntry->InMemoryOrderLinks );
//RemoveEntryList( &pEntry->HashLinks );
//最後这个 HashLinks 今天没时间讲了,有空再补充上来。
break;
}
FORCEINLINE
BOOLEAN
RemoveEntryList(
_In_ PLIST_ENTRY Entry
)
{
PLIST_ENTRY PrevEntry;
PLIST_ENTRY NextEntry;
NextEntry = Entry->Flink;
PrevEntry = Entry->Blink;
if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry)) {
FatalListEntryError((PVOID)PrevEntry,
(PVOID)Entry,
(PVOID)NextEntry);
}
PrevEntry->Flink = NextEntry;
NextEntry->Blink = PrevEntry;
return (BOOLEAN)(PrevEntry == NextEntry);
}
到这里,告一段落了!!!!!
不过最後我再补充一项知识,
假设想在 User mode 中做到 PEB 断链有可能吗?
答案是有的,但是必须想办法拿到 PEB 的 Address。
我们知道 EProcess 是存在於 Kernel mode,
那要怎麽在 User mode 拿到 PEB 的 Address 呢?
最一开始有说到 PEB 出现在 TEB(Thread Environment Block) 中
TEB(Thread Environment Block):
当 Windows 载入 Process 建立 Thread 时,系统会为每个 Thread 分配 TEB,
且 FS 暂存器会被设置成 FS:0 指向目前 Thread 的 TEB Address,
所以可以拿到 TEB Address。
TEB(Thread Environment Block)结构:
lkd> dt _TEB
ntdll!_TEB
+0x000 NtTib : _NT_TIB
+0x038 EnvironmentPointer : Ptr64 Void
+0x040 ClientId : _CLIENT_ID
+0x050 ActiveRpcHandle : Ptr64 Void
+0x058 ThreadLocalStoragePointer : Ptr64 Void
-->+0x060 ProcessEnvironmentBlock : Ptr64 _PEB
+0x068 LastErrorValue : Uint4B
+0x06c CountOfOwnedCriticalSections : Uint4B
+0x070 CsrClientThread : Ptr64 Void
--- --- --- ---
--- --- --- ---
--- --- --- ---
--- --- --- ---
--- --- --- ---
--- --- --- ---
看到了吧?有 Process Environment Block 耶!!!
可以再看一下,位於 0x00 的 NtTib 是 _NT_TIB 结构,
_NT_TIB 结构:
lkd> dt _NT_TIB
ntdll!_NT_TIB
+0x000 ExceptionList : Ptr64 _EXCEPTION_REGISTRATION_RECORD
+0x008 StackBase : Ptr64 Void
+0x010 StackLimit : Ptr64 Void
+0x018 SubSystemTib : Ptr64 Void
+0x020 FiberData : Ptr64 Void
+0x020 Version : Uint4B
+0x028 ArbitraryUserPointer : Ptr64 Void
->>+0x030 Self : Ptr64 _NT_TIB
所以呢~所以呢~
直接:
//mov eax,fs:[0x030] //x86 Get PEB
mov eax,gs:[0x060] //x64 Get PEB
//mov ecx,[eax + 0x00c] //x86 PEB 的 Ldr
mov ecx,[eax + 0x018] //x64 PEB 的 Ldr
mov xxx,ecx //把拿到的 Address 放进 xxx 变数
pop ecx
pop eax
好了,这篇真的结束了!
明天将介绍一些方法,来对抗这种 PEB 断链隐藏 Module 的手法!
如果你/你有发现哪里写得不好或是有地方写错,
欢迎留个言,大家一起讨论讨论鸭~~
那我们下期见 o( ̄▽ ̄)ブ
各位大大好, 第一次发文, 想请教有无推荐的mail server,公司用,约100使用者, 有看过...
前言 上次讲完了过去 Linux 的排程器,今天就来讲讲 CFS (complete fair sc...
放烟火 2 ( 爆炸效果 ) 教学原文参考:放烟火 2 ( 爆炸效果 ) 这篇文章会延续「放烟火 1...
各位在刚载好VScode都会做甚麽样的设定或安装甚麽扩充功能呢? 虽然网路上一大堆的介绍,但零零总总...
今天的内容会跟各位介绍 Google Cloud 相关的基础知识,希望不会不小心的讲成像业配文QQ,...