0%

AppInit_DLLS及其他

AppInit_DLLs(本地复现未成功)

https://learn.microsoft.com/zh-cn/windows/win32/win7appqual/appinit-dlls-in-windows-7-and-windows-server-2008-r2?redirectedfrom=MSDN

https://bbs.pediy.com/thread-266985.htm#msg_header_h1_3

https://blog.csdn.net/qq_36374896/article/details/107005590

https://blog.csdn.net/u013565525/article/details/28416279

使用注册表 AppInit_DLLs写入要注入的DLL路径字符串然后把LoadAppInit_DLLs值设置为1,重启后,DLL会注入所有运行进程(user32.dll被加载到进程时,会读取AppInit_DLLs注册表项,若有值则调用loadLibrary加载用户dll,即但凡是导入了user32.dll的程序都会加载该模块)

在自己的win7虚拟机试了几次 使用该方法总是会蓝屏。。。(win7sp1版)

64位系统: AppInit_Dlls(64位程序读取) HKEY_LOCAL_MACHINENT

AppInit_Dlls(32位程序读取) HKEY_LOCAL_MACHINE6432NodeNT

32位系统: HKEY_LOCAL_MACHINENT

img
排查方法
  • 监测加载User32.dll的进程的dll的加载,特别是查找不是通常的dll,或者不是正常加载的dll。
  • 监视AppInit_DLLs注册表值。
  • 监视和分析注册表编辑的API调用,如RegCreateKeyEx和RegSetValueEx

扫描进程内存——用户层dll注入简单判断

可以关注下是否有执行权限

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
83
#include <iostream>
#include <windows.h>
#include <Psapi.h>
#pragma comment(lib,"psapi.lib")

VOID ScanProcessMemory(HANDLE hProc)
{
SIZE_T stSize = 0;
PBYTE pAddress = (PBYTE)0;
SYSTEM_INFO sysinfo;
MEMORY_BASIC_INFORMATION mbi = { 0 };

//获取页的大小
ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinfo);

// 得到的镜像基地址
pAddress = (PBYTE)sysinfo.lpMinimumApplicationAddress;

printf("------------------------------------------------------------------------ \n");
printf("开始地址 \t 结束地址 \t\t 大小 \t 状态 \t 内存类型 \n");
printf("------------------------------------------------------------------------ \n");
// 判断只要当前地址小于最大地址就循环
while (pAddress < (PBYTE)sysinfo.lpMaximumApplicationAddress)
{
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
stSize = VirtualQueryEx(hProc, pAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));

if (stSize == 0)
{
pAddress += sysinfo.dwPageSize;
continue;
}
printf("0x%08X \t 0x%08X \t %8d K \t ", mbi.BaseAddress,
((DWORD)mbi.BaseAddress + (DWORD)mbi.RegionSize),mbi.RegionSize>>10);
switch (mbi.State)
{
case MEM_FREE: printf("空闲 \t"); break;
case MEM_RESERVE: printf("保留 \t"); break;
case MEM_COMMIT: printf("提交 \t"); break;
default: printf("未知 \t"); break;
}

switch (mbi.Type)
{
case MEM_PRIVATE: printf("私有 \t"); break;
case MEM_MAPPED: printf("映射 \t"); break;
case MEM_IMAGE: printf("镜像 \t"); break;
default: printf("未知 \t"); break;
}

if (mbi.Protect == 0)
printf("---");
else if (mbi.Protect & PAGE_EXECUTE)
printf("E--");
else if (mbi.Protect & PAGE_EXECUTE_READ)
printf("ER-");
else if (mbi.Protect & PAGE_EXECUTE_READWRITE)
printf("ERW");
else if (mbi.Protect & PAGE_READONLY)
printf("-R-");
else if (mbi.Protect & PAGE_READWRITE)
printf("-RW");
else if (mbi.Protect & PAGE_WRITECOPY)
printf("WCOPY");
else if (mbi.Protect & PAGE_EXECUTE_WRITECOPY)
printf("EWCOPY");
printf("\n");

// 每次循环累加内存块的位置
pAddress = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}
}

int main(int argc, char* argv[])
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
ScanProcessMemory(hProc);
CloseHandle(hProc);

system("pause");
return 0;
}
img

提权函数

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
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) 
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;

if( !OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken) )
{
printf("OpenProcessToken error: %u\n", GetLastError());
return FALSE;
}

if( !LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if( bEnablePrivilege )
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.
if( !AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}

if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}

查找函数地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Windows.h>
#include <stdio.h>

//Messagebox
typedef void (*MYPROC)(_In_ HMODULE hModule,
_In_ LPCSTR lpProcName);
void main() {
HINSTANCE libaddr = LoadLibraryA("user32.dll");
printf("动态库基地址: 0x%x\n", libaddr);
GetProcAddress(libaddr, "MessageBoxA");

HINSTANCE proc = (MYPROC)GetProcAddress(libaddr, "MessageBoxA");
printf("函数地址:0x%x\n", proc);
}
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
#include <Windows.h>
#include <stdio.h>

typedef void (*MYPROC)(_In_ HMODULE hModule,
_In_ LPCSTR lpProcName);

void main() {
/*HINSTANCE libaddr = LoadLibraryA("user32.dll");
printf("动态库基地址: 0x%x\n", libaddr);
GetProcAddress(libaddr, "MessageBoxA");

HINSTANCE proc = (MYPROC)GetProcAddress(libaddr, "MessageBoxA");
printf("函数地址:0x%x\n", proc);*/

// mamor
//6D 61 6D 6F 72 00 00 00
//user32.ll动态库基地址: 0x75770000
//MessageBoxA函数地址:0x757f1300
//char* str = "FLAG";

LoadLibraryA("user32.dll");

_asm {
sub esp,0x60 //抬高栈
xor ebx,ebx
push ebx
push 0x20202072
push 0x6F6D616D //字符串mamor

mov eax, esp
push ebx //0表示字符串结束

push 0x20202072
push 0x6F6D616D

mov ecx, esp //获取第二个字符串的地址
//MessageBoxA(0,"","",0)
push ebx
push eax
push eax
push ebx
mov eax, 0x757f1300 //MessageBoxA地址
call eax


}


}

然后可以使用od x32dbg等获取机器码 然后在使用内联汇编去调用即可

正则表达式 shellcode转换

1
([0-9a-fA-F]{2})`  替换为 `0x\1
img

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------