| Advisory NTIADV0814 | |
| ArcaVir (ps_drv.sys) Multiple Privilege Escalation Vulnerabilities | |
| Vendor | ArcaBit Sp. z o.o. |
| Affected Software | ArcaVir 2009 Antivirus Protection < 9.4.3201.9 ArcaVir 2009 Internet Security < 9.4.3202.9 ArcaVir 2009 System Protection < 9.4.3203.9 ArcaVir 2009 Home Protection < 9.4.3204.9 |
| Affected Driver | ps_drv.sys |
| Date Reported | 2008-12-23 |
| Release Date | 2009-05-23 |
| Status | Partially Fixed ArcaVir 2009 Antivirus Protection 9.4.3201.9 ArcaVir 2009 Internet Security 9.4.3202.9 ArcaVir 2009 System Protection 9.4.3203.9 ArcaVir 2009 Home Protection 9.4.3204.9 |
| Exploit | PsDrv_Exp.zip - Local Privilege Escalation Exploit |
| Disclosure Timeline |
2008-12-23 - Vulnerability reported to vendor 2009-01-02 - Vendor response 2009-01-13 - First incomplete update released 2009-01-24 - Status update request 2009-01-25 - Vendor response 2009-01-27 - Vulnerability description sent to vendor 2009-01-27 - Vendor response 2009-04-10 - Status update request 2009-04-11 - Vendor response 2009-04-15 - Second update released by vendor 2009-04-16 - Vulnerability description sent to vendor 2009-04-16 - Vendor response 2009-04-22 - Third update released by vendor 2009-05-19 - Status update request (no response) 2009-05-23 - Full technical details released to general public |
| Description | |
| ArcaVir is prone to a local privilege escalation vulnerabilities that occurs in the ps_drv.sys driver. This driver allows any user to open the device "\\Device\\ps_drv" and issue IOCTLs with a buffering mode of METHOD_NEITHER. | |
| Details | |
|
The problem specifically exists because the driver allows untrusted user mode code to pass kernel addresses as arguments to the driver. This can be exploited to overwrite an arbitrary address and execute arbitrary code in kernel space via a specially crafted IOCTL. This is only one example (IOCTL 0x2A7B802B) of many vulnerable IOCTLs.
seg000:00023F3C RootkitMemoryBlock proc near
seg000:00023F3C
seg000:00023F3C ArcaStruct = dword ptr -14h
seg000:00023F3C Buffer = dword ptr -10h
seg000:00023F3C InputBuffer = dword ptr -0Ch
seg000:00023F3C BufferLength = dword ptr -8
seg000:00023F3C Address = dword ptr -4
seg000:00023F3C
seg000:00023F3C push ebp
seg000:00023F3D mov ebp, esp
seg000:00023F3F sub esp, 14h
seg000:00023F42 mov [ebp+ArcaStruct], ecx
seg000:00023F45 push offset StrRootkitMemBlock ; "ROOTKIT_MEMBLOCK\n"
seg000:00023F4A call DbgPrint
seg000:00023F4F add esp, 4
seg000:00023F52 mov eax, [ebp+ArcaStruct]
seg000:00023F55 cmp [eax+_ARCA_STRUCT.InputBufferLength], 8
seg000:00023F5C jnz short @@invalid_input_buffer_size
seg000:00023F5E mov ecx, [ebp+ArcaStruct]
seg000:00023F61 cmp [ecx+_ARCA_STRUCT.Type3InputBuffer], 0
seg000:00023F68 jnz short @@check_passed_parameters
seg000:00023F6A
seg000:00023F6A @@invalid_input_buffer_size:
seg000:00023F6A push offset StrInvalidInputBufferSize ; "Zły rozmiar input bufora\n"
seg000:00023F6F call DbgPrint
seg000:00023F74 add esp, 4
seg000:00023F77 mov eax, STATUS_INVALID_BUFFER_SIZE
seg000:00023F7C jmp @@exit
seg000:00023F81
seg000:00023F81 @@check_passed_parameters:
seg000:00023F81 mov edx, [ebp+ArcaStruct]
seg000:00023F84 mov eax, [edx+_ARCA_STRUCT.Type3InputBuffer]
seg000:00023F8A mov ecx, [eax]
seg000:00023F8C mov edx, [eax+4]
seg000:00023F8F mov [ebp+InputBuffer], ecx
seg000:00023F92 mov [ebp+BufferLength], edx
seg000:00023F95 cmp [ebp+BufferLength], 0
seg000:00023F99 jnz short @@check_output_buffer
seg000:00023F9B push offset StrInvalidInputAddress ; "Zerowy rozmiar bufora do odczytu\n"
seg000:00023FA0 call DbgPrint
seg000:00023FA5 add esp, 4
seg000:00023FA8 mov eax, STATUS_INVALID_PARAMETER
seg000:00023FAD jmp @@exit
seg000:00023FB2
seg000:00023FB2 @@check_output_buffer:
seg000:00023FB2 mov eax, [ebp+ArcaStruct]
seg000:00023FB5 mov ecx, [eax+_ARCA_STRUCT.OutputBufferLength]
seg000:00023FBB cmp ecx, [ebp+BufferLength]
seg000:00023FBE jnz short @@invalid_output_buffer_size
seg000:00023FC0 mov edx, [ebp+ArcaStruct]
seg000:00023FC3 cmp [edx+_ARCA_STRUCT.UserBuffer], 0
seg000:00023FCA jnz short @@check_address
seg000:00023FCC
seg000:00023FCC @@invalid_output_buffer_size:
seg000:00023FCC push offset StrInvalidOutputBufferSize ; "Zły rozmiar output bufora\n"
seg000:00023FD1 call DbgPrint
seg000:00023FD6 add esp, 4
seg000:00023FD9 mov eax, STATUS_INVALID_BUFFER_SIZE
seg000:00023FDE jmp short @@exit
seg000:00023FE0
seg000:00023FE0 @@check_address:
seg000:00023FE0 mov eax, [ebp+InputBuffer]
seg000:00023FE3 mov [ebp+Buffer], eax
seg000:00023FE6 mov ecx, [ebp+BufferLength]
seg000:00023FE9 mov edx, [ebp+InputBuffer]
seg000:00023FEC lea eax, [edx+ecx-1]
seg000:00023FF0 mov [ebp+Address], eax
seg000:00023FF3 mov ecx, [ebp+Address]
seg000:00023FF6 push ecx
seg000:00023FF7 mov edx, [ebp+Buffer]
seg000:00023FFA push edx
seg000:00023FFB call CheckAddress
seg000:00024000 movsx eax, ax
seg000:00024003 test eax, eax
seg000:00024005 jnz short @@copy_memory
seg000:00024007 push offset StrInvalidMemoryRange ; "Niedostepny zakres pamięci\n"
seg000:0002400C call DbgPrint
seg000:00024011 add esp, 4
seg000:00024014 mov eax, STATUS_RANGE_NOT_FOUND
seg000:00024019 jmp short @@exit
seg000:0002401B
seg000:0002401B @@copy_memory:
seg000:0002401B mov ecx, [ebp+BufferLength]
seg000:0002401E push ecx
seg000:0002401F mov edx, [ebp+InputBuffer]
seg000:00024022 push edx
seg000:00024023 mov eax, [ebp+ArcaStruct]
seg000:00024026 mov ecx, [eax+_ARCA_STRUCT.UserBuffer]
seg000:0002402C push ecx
seg000:0002402D call memcpy
seg000:00024032 add esp, 0Ch
seg000:00024035 mov edx, [ebp+ArcaStruct]
seg000:00024038 mov eax, [edx+_ARCA_STRUCT.IoStatus]
seg000:0002403E mov ecx, [ebp+BufferLength]
seg000:00024041 mov [eax+_IO_STATUS_BLOCK.Information], ecx
seg000:00024044 mov edx, [ebp+ArcaStruct]
seg000:00024047 mov eax, [edx+_ARCA_STRUCT.IoStatus]
seg000:0002404D mov [eax+_IO_STATUS_BLOCK.Status], 0
seg000:00024053 xor eax, eax
seg000:00024055
seg000:00024055 @@exit:
seg000:00024055 mov esp, ebp
seg000:00024057 pop ebp
seg000:00024058 retn
seg000:00024058 RootkitMemoryBlock endp
|
|