idiotc4t's blog
搜索文档…
伪装命令行规避检测

简介

在蓝队排查恶意进程过程中,经常会使用processexplorer等进程检查工具进行详细的检测,而通常的恶意进程往往特征会比较明显,这种技术通过伪造PEB进程环境块来伪装自己,让自己的特征不那么明显,从而增加一点存活率。

手工操作

在windbg中我们可以比较方便的获取当前附加进程的PEB,由于PEB存储在用户空间,所以不需要进行内核级的操作我们就能对其修改,在ring3用户层x86系统下PEB通常存储在fs:[30]的位置,而x64系统则有细微差异,存储在gs:[0x60]的位置,在x86系统中我们通常使用内联汇编的方式获取peb的地址,而在x64中这种方式在编写上不那么方便,所以使用另一种利用操作系统函数NtQueryInformationProcess函数获取。
查看当前进程PEB。
1
0:001> dt _peb @$peb
2
ntdll!_PEB
3
+0x000 InheritedAddressSpace : 0 ''
4
+0x001 ReadImageFileExecOptions : 0 ''
5
+0x002 BeingDebugged : 0x1 ''
6
+0x003 BitField : 0x4 ''
7
+0x003 ImageUsesLargePages : 0y0
8
+0x003 IsProtectedProcess : 0y0
9
+0x003 IsImageDynamicallyRelocated : 0y1
10
+0x003 SkipPatchingUser32Forwarders : 0y0
11
+0x003 IsPackagedProcess : 0y0
12
+0x003 IsAppContainer : 0y0
13
+0x003 IsProtectedProcessLight : 0y0
14
+0x003 IsLongPathAwareProcess : 0y0
15
+0x004 Padding0 : [4] ""
16
+0x008 Mutant : 0xffffffff`ffffffff Void
17
+0x010 ImageBaseAddress : 0x00007ff6`90600000 Void
18
+0x018 Ldr : 0x00007ffc`46fa53c0 _PEB_LDR_DATA
19
+0x020 ProcessParameters : 0x00000240`e4b220e0 _RTL_USER_PROCESS_PARAMETERS
20
+0x028 SubSystemData : (null)
21
+0x030 ProcessHeap : 0x00000240`e4b20000 Void
22
+0x038 FastPebLock : 0x00007ffc`46fa4fe0 _RTL_CRITICAL_SECTION
23
+0x040 AtlThunkSListPtr : (null)
24
+0x048 IFEOKey : (null)
25
+0x050 CrossProcessFlags : 0
26
+0x050 ProcessInJob : 0y0
27
+0x050 ProcessInitializing : 0y0
28
+0x050 ProcessUsingVEH : 0y0
29
+0x050 ProcessUsingVCH : 0y0
30
+0x050 ProcessUsingFTH : 0y0
31
+0x050 ProcessPreviouslyThrottled : 0y0
32
+0x050 ProcessCurrentlyThrottled : 0y0
33
+0x050 ProcessImagesHotPatched : 0y0
34
+0x050 ReservedBits0 : 0y000000000000000000000000 (0)
35
+0x054 Padding1 : [4] ""
36
+0x058 KernelCallbackTable : (null)
37
+0x058 UserSharedInfoPtr : (null)
38
+0x060 SystemReserved : 0
39
+0x064 AtlThunkSListPtr32 : 0
40
+0x068 ApiSetMap : 0x00000240`e49a0000 Void
41
+0x070 TlsExpansionCounter : 0
42
+0x074 Padding2 : [4] ""
43
+0x078 TlsBitmap : 0x00007ffc`46fa5340 Void
44
+0x080 TlsBitmapBits : [2] 0x10011
45
+0x088 ReadOnlySharedMemoryBase : 0x00007df4`bc970000 Void
46
+0x090 SharedData : (null)
47
+0x098 ReadOnlyStaticServerData : 0x00007df4`bc970750 -> (null)
48
+0x0a0 AnsiCodePageData : 0x00007df5`beab0000 Void
49
+0x0a8 OemCodePageData : 0x00007df5`beab0000 Void
50
+0x0b0 UnicodeCaseTableData : 0x00007df5`beae0028 Void
51
+0x0b8 NumberOfProcessors : 0xc
52
+0x0bc NtGlobalFlag : 0
53
+0x0c0 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
54
+0x0c8 HeapSegmentReserve : 0x100000
55
+0x0d0 HeapSegmentCommit : 0x2000
56
+0x0d8 HeapDeCommitTotalFreeThreshold : 0x10000
57
+0x0e0 HeapDeCommitFreeBlockThreshold : 0x1000
58
+0x0e8 NumberOfHeaps : 3
59
+0x0ec MaximumNumberOfHeaps : 0x10
60
+0x0f0 ProcessHeaps : 0x00007ffc`46fa3c40 -> 0x00000240`e4b20000 Void
61
+0x0f8 GdiSharedHandleTable : (null)
62
+0x100 ProcessStarterHelper : (null)
63
+0x108 GdiDCAttributeList : 0
64
+0x10c Padding3 : [4] ""
65
+0x110 LoaderLock : 0x00007ffc`46f9f4f8 _RTL_CRITICAL_SECTION
66
+0x118 OSMajorVersion : 0xa
67
+0x11c OSMinorVersion : 0
68
+0x120 OSBuildNumber : 0x47bb
69
+0x122 OSCSDVersion : 0
70
+0x124 OSPlatformId : 2
71
+0x128 ImageSubsystem : 3
72
+0x12c ImageSubsystemMajorVersion : 0xa
73
+0x130 ImageSubsystemMinorVersion : 0
74
+0x134 Padding4 : [4] ""
75
+0x138 ActiveProcessAffinityMask : 0xfff
76
+0x140 GdiHandleBuffer : [60] 0
77
+0x230 PostProcessInitRoutine : (null)
78
+0x238 TlsExpansionBitmap : 0x00007ffc`46fa5320 Void
79
+0x240 TlsExpansionBitmapBits : [32] 1
80
+0x2c0 SessionId : 3
81
+0x2c4 Padding5 : [4] ""
82
+0x2c8 AppCompatFlags : _ULARGE_INTEGER 0x0
83
+0x2d0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
84
+0x2d8 pShimData : 0x00000240`e49e0000 Void
85
+0x2e0 AppCompatInfo : (null)
86
+0x2e8 CSDVersion : _UNICODE_STRING ""
87
+0x2f8 ActivationContextData : 0x00000240`e49d0000 _ACTIVATION_CONTEXT_DATA
88
+0x300 ProcessAssemblyStorageMap : (null)
89
+0x308 SystemDefaultActivationContextData : 0x00000240`e49c0000 _ACTIVATION_CONTEXT_DATA
90
+0x310 SystemAssemblyStorageMap : (null)
91
+0x318 MinimumStackCommit : 0
92
+0x320 SparePointers : [4] (null)
93
+0x340 SpareUlongs : [5] 0
94
+0x358 WerRegistrationData : (null)
95
+0x360 WerShipAssertPtr : (null)
96
+0x368 pUnused : (null)
97
+0x370 pImageHeaderHash : (null)
98
+0x378 TracingFlags : 0
99
+0x378 HeapTracingEnabled : 0y0
100
+0x378 CritSecTracingEnabled : 0y0
101
+0x378 LibLoaderTracingEnabled : 0y0
102
+0x378 SpareTracingBits : 0y00000000000000000000000000000 (0)
103
+0x37c Padding6 : [4] ""
104
+0x380 CsrServerReadOnlySharedMemoryBase : 0x00007df4`28530000
105
+0x388 TppWorkerpListLock : 0
106
+0x390 TppWorkerpList : _LIST_ENTRY [ 0x0000009c`16855390 - 0x0000009c`16855390 ]
107
+0x3a0 WaitOnAddressHashTable : [128] (null)
108
+0x7a0 TelemetryCoverageHeader : (null)
109
+0x7a8 CloudFileFlags : 0xe0
110
+0x7ac CloudFileDiagFlags : 0
111
+0x7b0 PlaceholderCompatibilityMode : 2 ''
112
+0x7b1 PlaceholderCompatibilityModeReserved : [7] ""
113
+0x7b8 LeapSecondData : 0x00007df5`beaa0000 _LEAP_SECOND_DATA
114
+0x7c0 LeapSecondFlags : 0
115
+0x7c0 SixtySecondEnabled : 0y0
116
+0x7c0 Reserved : 0y0000000000000000000000000000000 (0)
117
+0x7c4 NtGlobalFlag2 : 0
Copied!
通过前人的逆向分析,我们知道在ProcessExplorer等工具会从PEB+0x20的位置的_RTL_USER_PROCESS_PARAMETERS结构体内读取path,commandline等相关数据。
1
ntdll!_RTL_USER_PROCESS_PARAMETERS
2
+0x000 MaximumLength : 0x718
3
+0x004 Length : 0x718
4
+0x008 Flags : 0x6001
5
+0x00c DebugFlags : 0
6
+0x010 ConsoleHandle : 0x00000000`00000050 Void
7
+0x018 ConsoleFlags : 0
8
+0x020 StandardInput : 0x00000000`00000054 Void
9
+0x028 StandardOutput : 0x00000000`00000058 Void
10
+0x030 StandardError : 0x00000000`0000005c Void
11
+0x038 CurrentDirectory : _CURDIR
12
+0x050 DllPath : _UNICODE_STRING ""
13
+0x060 ImagePathName : _UNICODE_STRING "C:\Windows\system32\cmd.exe"
14
+0x070 CommandLine : _UNICODE_STRING ""C:\Windows\system32\cmd.exe" "
15
+0x080 Environment : 0x00000240`e4b36440 Void
16
+0x088 StartingX : 0
17
+0x08c StartingY : 0
18
+0x090 CountX : 0
19
+0x094 CountY : 0
20
+0x098 CountCharsX : 0
21
+0x09c CountCharsY : 0
22
+0x0a0 FillAttribute : 0
23
+0x0a4 WindowFlags : 1
24
+0x0a8 ShowWindowFlags : 1
25
+0x0b0 WindowTitle : _UNICODE_STRING "C:\Windows\system32\cmd.exe"
26
+0x0c0 DesktopInfo : _UNICODE_STRING "Winsta0\Default"
27
+0x0d0 ShellInfo : _UNICODE_STRING ""
28
+0x0e0 RuntimeData : _UNICODE_STRING ""
29
+0x0f0 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR
30
+0x3f0 EnvironmentSize : 0x1136
31
+0x3f8 EnvironmentVersion : 7
32
+0x400 PackageDependencyData : (null)
33
+0x408 ProcessGroupId : 0x41f0
34
+0x40c LoaderThreads : 0
35
+0x410 RedirectionDllName : _UNICODE_STRING ""
36
+0x420 HeapPartitionName : _UNICODE_STRING ""
37
+0x430 DefaultThreadpoolCpuSetMasks : (null)
38
+0x438 DefaultThreadpoolCpuSetMaskCount : 0
39
Copied!
可以看到在_RTL_USER_PROCESS_PARAMETERS+0x60和+0x70的位置存储这我们感兴趣的两个—UNICODE_STRING结构体,通过查看这两个结构体我们可以知道其指向的字符串存放位置。
1
0:001> dt _UNICODE_STRING 0x00000240`e4b220e0+0x60
2
ntdll!_UNICODE_STRING
3
"C:\Windows\system32\cmd.exe"
4
+0x000 Length : 0x36
5
+0x002 MaximumLength : 0x38
6
+0x008 Buffer : 0x00000240`e4b22728 "C:\Windows\system32\cmd.exe"
7
0:001> dt _UNICODE_STRING 0x00000240`e4b220e0+0x70
8
ntdll!_UNICODE_STRING
9
""C:\Windows\system32\cmd.exe" "
10
+0x000 Length : 0x3c
11
+0x002 MaximumLength : 0x3e
12
+0x008 Buffer : 0x00000240`e4b22760 ""C:\Windows\system32\cmd.exe" "
Copied!
将其指向的字符串进行修改,需要注意的是修改字符串的同时最好也要修改该结构体的Lenght的成员,可以看到在修改指针指向内容后,显示会按照我们预期的方式进行。
1
0:001> eu 0x00000240`e4b22728 "C:\\Windows\\System32\\notepad.exe"
2
0:001> eu 0x00000240`e4b22760 "C:\\Windows\\System32\\pad.exe"
3
0:001> dt _UNICODE_STRING 0x00000240`e4b220e0+0x60
4
ntdll!_UNICODE_STRING
5
"C:\Windows\System32\notepad"
6
+0x000 Length : 0x36
7
+0x002 MaximumLength : 0x38
8
+0x008 Buffer : 0x00000240`e4b22728 "C:\Windows\System32\notepad"
9
0:001> dt _UNICODE_STRING 0x00000240`e4b220e0+0x70
10
ntdll!_UNICODE_STRING
11
"C:\Windows\System32\pad.exee" "
12
+0x000 Length : 0x3c
13
+0x002 MaximumLength : 0x3e
14
+0x008 Buffer : 0x00000240`e4b22760 "C:\Windows\System32\pad.exee" "
15
Copied!

代码实现

由于修改指向内存内容的方式比较沙雕,给出的代码会使用修改指针的方式实现。
1
#include <stdio.h>
2
#include <Windows.h>
3
#include <winternl.h>
4
5
6
typedef DWORD(*pNtQueryInformationProcess) (HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
7
8
int main()
9
{
10
HANDLE hProcess =0;
11
ULONG lenght = 0;
12
HANDLE hModule;
13
PROCESS_BASIC_INFORMATION ProcessInformation;
14
pNtQueryInformationProcess NtQueryInformationProcess;
15
wchar_t CommandLine[] = L"C:\\Windows\\system32\\notepad.exe";
16
wchar_t CurrentDirectory[] = L"C:\\Windows\\system32\\";
17
18
hModule = GetModuleHandleA("Ntdll.dll");
19
hProcess = GetCurrentProcess();
20
NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hModule, "NtQueryInformationProcess");
21
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), &lenght);
22
23
//WriteProcessMemory(hProcess, ProcessInformation.PebBaseAddress->ProcessParameters->CommandLine.Length, &CommandLine, sizeof(CommandLine), NULL);
24
//WriteProcessMemory(hProcess, ProcessInformation.PebBaseAddress->ProcessParameters->ImagePathName.Length, &CurrentDirectory, sizeof(CurrentDirectory), NULL);
25
ProcessInformation.PebBaseAddress->ProcessParameters->CommandLine.Length = sizeof(CommandLine);
26
ProcessInformation.PebBaseAddress->ProcessParameters->ImagePathName.Length = sizeof(CurrentDirectory);
27
ProcessInformation.PebBaseAddress->ProcessParameters->CommandLine.Buffer = &CommandLine;
28
ProcessInformation.PebBaseAddress->ProcessParameters->ImagePathName.Buffer = &CurrentDirectory;
29
30
getchar();
31
return 0;
32
}
Copied!

LINKS

PEB (winternl.h) - Win32 apps
docsmsft
NtQueryInformationProcess function (winternl.h) - Win32 apps
docsmsft
最近更新 1yr ago