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, lpszPrivilege, &luid) ) { 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;
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>
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() {
LoadLibraryA("user32.dll");
_asm { sub esp,0x60 xor ebx,ebx push ebx push 0x20202072 push 0x6F6D616D
mov eax, esp push ebx
push 0x20202072 push 0x6F6D616D
mov ecx, esp push ebx push eax push eax push ebx mov eax, 0x757f1300 call eax
}
}
|
然后可以使用od x32dbg等获取机器码 然后在使用内联汇编去调用即可
正则表达式 shellcode转换
1
| ([0-9a-fA-F]{2})` 替换为 `0x\1
|
img