[NT] Insufficient Argument Validation of Hooked SSDT Functions on Multiple Antivirus and Firewalls



The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html

- - - - - - - - -



Insufficient Argument Validation of Hooked SSDT Functions on Multiple
Antivirus and Firewalls
------------------------------------------------------------------------


SUMMARY

Insufficient argument validation of hooked SSDT functions on multiple
Antivirus and Firewalls (BitDefender Antivirus [1], Comodo Firewall [2],
Sophos Antivirus [3] and Rising Antivirus [4]) have been found that could
lead to a Denial of Service (DoS) and possibly to code execution attacks.
An attacker, utilizing these flaws, could be able to locally reboot the
whole system shutting down the firewall or anti-virus protection. However,
in some cases it may be possible to extend the impact of these bugs, and
they could lead to the execution of arbitrary code in the privileged
kernel mode.

DETAILS

Vulnerable Packages:
* BitDefender Antivirus version 2008 Build 11.0.11
* Comodo Firewall Pro version 2.4.18.184
* Sophos Antivirus version 7.0.5
* Rising Antivirus version 19.60.0.0 and version 19.66.0.0

Non-vulnerable Packages:
* BitDefender Antivirus version 2008 builds available through automatic
updates, posterior to January 18th.
* Comodo Firewall Pro version 3.0
* Rising Antivirus version 20.38.20

Vendor Information, Solutions and Workarounds:
1) BITDEFENDER ANTIVIRUS (BID 28741, CVE-2008-1735)
According to BitDefender, the flaw was not exploited by any malicious
application, and it was corrected through automatic updates. Information
on this issue can be found on BitDefender website at this location:
<http://kb.bitdefender.com/KB419-en--Security-vulnerability-in-BitDefender-2008.html.> http://kb.bitdefender.com/KB419-en--Security-vulnerability-in-BitDefender-2008.html.

2) COMODO FIREWALL PRO (BID 28742, CVE-2008-1736)
The vulnerability is fixed in Comodo Firewall Pro 3.0, available at:
<http://www.personalfirewall.comodo.com/download_firewall.html>
http://www.personalfirewall.comodo.com/download_firewall.html

3) SOPHOS ANTIVIRUS (BID 28743, CVE-2008-1737)
Vendor statement:

"Sophos Anti-Virus 7.x for Windows 2000, 2003 and XP is affected by this
vulnerability.

Non-vulnerable products from Sophos are earlier versions of Sophos
Anti-Virus for Windows, Sophos Anti-Virus for non-Windows platforms and
all other Sophos products.

The vulnerability is only exploitable if Runtime Behavioural Analysis is
switched on. Even then the exploit will only be effective if the end user
is using security settings that are lower than the defaults for most web
browsers today, or if the end user agrees to activate an ActiveX or Java
Applet from the webpage hosting the exploit.

Workarounds to avoid this vulnerability include:
a. Using the default security settings or higher on the latest version of
your chosen web browser. In line with general security best practice we
would also encourage end users not to download ActiveX or Java Applets
unless confident about their content.

b. Turning off the Runtime Behavioural Analysis functionality within
Sophos Anti-Virus (customers will still benefit from Sophos Behavioural
Genotype protection and other means of protecting endpoints against
malware).

N.B. Should an exploit be released into the wild, Sophos will deploy
protection against that exploit.

The fix for this vulnerability requires customers to reboot their
endpoints. Given the low severity of the vulnerability, to minimise
disruption to our customers Sophos will release the fix at the earliest
opportunity that coincides with a necessary reboot of the product."

4) RISING ANTIVIRUS (BID 28744, CVE-2008-1738)
A fixed version of Rising Antivirus can be downloaded from:
<http://rsdownload.rising.com.cn/for_down/rsfree/ravolusrfree.exe>
http://rsdownload.rising.com.cn/for_down/rsfree/ravolusrfree.exe

All Rising customers can also update up to a patched version through
automatic updates.

Technical Description / Proof of Concept Code:
We have found that BitDefender Antivirus, Rising Antivirus, Comodo
Firewall and Sophos Antivirus have hooks that do not properly validate the
arguments of the hooked functions before accessing them, and lead to the
program trying to reference some invalid memory, leading in some scenarios
to a BSOD (Blue Screen of Death).

In our tests we used the kernel hooks probing tool BSODhook [5] in order
to find any kind of insufficient argument validation of hooked SSDT
functions. From Matousec paper [6]:

"Hooking kernel functions by modifying the System Service Descriptor Table
(SSDT) is a very popular method of implementation of additional security
features and is used frequently by personal firewalls and other security
and low-level software. Although undocumented and despised by Microsoft,
this technique can be implemented in a correct and stable way. However,
many software vendors do not follow the rules and recommendations for
kernel-mode code writing and many drivers that implement SSDT hooking do
not properly validate the parameters of the hooking functions."

"Hooking SSDT functions requires extra caution. SSDT function handlers are
executed in the kernel mode but their callers are executed in the user
mode. Hence all function arguments come from the user mode. This is why it
is necessary to validate these arguments properly. Otherwise a simple user
call can easily crash the whole system. This bug usually results in a
system crash. However, it may happen that this bug is evenmore dangerous
and may lead to the execution of an arbitrary code in the privileged
kernel mode."

A local DoS attack, despite not being a very sophisticated intrusion
attack, could be used as an accessory under several scenarios. It is
commonly used by viruses as added feature, when the specific AV is
detected on the infected machine, crashing the system just to annoy. Orby
a human attacker, after a succesful remote intrusion with unprivileged
credentials to make a computer resource unavailable to its intended users.
Besides, this could be a very valuable resource when trying to fake some
service that answers broadcasts request like a DHCP, allowing to start the
service in another location replacing the original one.

1) BITDEFENDER ANTIVIRUS (BID 28741, CVE-2008-1735)
BitDefender fails to validate the pointer to the 'CLIENT_ID' structure
provided to 'NtOpenProcess'. So, if we pass an invalid pointer, we will
crash the whole system.
/-----------
NtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK AccessMask,
POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId )

text:00010ADE push 0Ch
text:00010AE0 push offset stru_114E8
text:00010AE5 call __SEH_prolog
text:00010AEA call KeGetCurrentThread
text:00010AEF xor ebx, ebx
text:00010AF1 cmp [eax+140h], bl
text:00010AF7 jz short loc_10B0D
text:00010AF9 call PsGetCurrentProcessId
text:00010AFE call PsGetCurrentProcessId
text:00010B03 push eax
text:00010B04 call sub_10724
text:00010B09 test eax, eax
text:00010B0B jnz short loc_10B12
text:00010B0D
text:00010B0D loc_10B0D: ; CODE XREF: sub_10ADE+19_j
text:00010B0D push [ebp+ClientId]
text:00010B10 jmp short loc_10B73

text:00010B12
text:00010B12 loc_10B12: ; CODE XREF: sub_10ADE+2D_j
text:00010B12 mov edi, [ebp+ClientId]
text:00010B15 cmp edi, ebx ; Little check to avoid a Null
Pointer

-----------/

Here it gets the pointer to the 'ClientId' value, and if it is non zero
('!= 0') it does not care where it is pointing to.

/-----------

text:00010B17 jnz short loc_10B1C
text:00010B19 push ebx
text:00010B1A jmp short loc_10B73

text:00010B1C
text:00010B1C loc_10B1C: ; CODE XREF: sub_10ADE+39_j
text:00010B1C mov [ebp+ms_exc.disabled], ebx
text:00010B1F mov esi, [edi] ; Here it crashes

-----------/

It access to that memory, and if that is invalid memory the system will
crash.

/-----------

text:00010B21 mov [ebp+var_1C], esi
text:00010B24 or [ebp+ms_exc.disabled], 0FFFFFFFFh
text:00010B28 jmp short loc_10B3B
text:00010B28 sub_10ADE endp

-----------/


2) COMODO FIREWALL PRO (BID 28742, CVE-2008-1736)
In Comodo there are problems in the arguments validation of
'NtDeleteFile', 'NtCreateFile' and 'NtSetThreadContext' functions.
'NtDeleteFile' receives just one parameter, a pointer to an
'OBJECT_ATTRIBUTES' structure. These attributes would include the
'ObjectName' and the 'SECURITY_DESCRIPTOR', for example. This is the hook
placed by Comodo at 'NtDeleteFile'.

/-----------

NTDeleteFile (POBJECT_ATTRIBUTES ObjectAttributes)

text:0001ACB0 push 1Ch
text:0001ACB2 push offset stru_1E3F0
text:0001ACB7 call __SEH_prolog
text:0001ACBC xor ebx, ebx
text:0001ACBE inc ebx
text:0001ACBF mov [ebp+var_1C], ebx
text:0001ACC2 xor esi, esi
text:0001ACC4 mov [ebp+var_24], esi
text:0001ACC7 mov [ebp+var_20], ebx
text:0001ACCA mov [ebp+var_28], esi
text:0001ACCD mov [ebp+ms_exc.disabled], esi
text:0001ACD0 call ds:ExGetPreviousMode
text:0001ACD6 mov edi, [ebp+ObjectAttributes]

-----------/

Here it does a lot of 'ProbeForRead' checks to see if the pointers of the
structure are valid. Nice! ('EDI' still has a pointer to the
'OBJECT_ATTRIBUTES' structure)

/-----------

...
text:0001AD25 push edi ; ObjectAttributes
text:0001AD26 call sub_1A692 ; Here it passes the
OBJECT_ATTRIBUTES structure pointer to the next function.

sub_1A692
text:0001A692 push 28h
text:0001A694 push offset stru_1E3C0
text:0001A699 call __SEH_prolog
text:0001A69E xor edi, edi
...
text:0001A6B3 mov [ebp+ms_exc.disabled], edi
text:0001A6B6 push 72747052h ; Tag
text:0001A6BB mov ebx, 400h
text:0001A6C0 push ebx ; NumberOfBytes
text:0001A6C1 push 1 ; PoolType
text:0001A6C3 call ds:ExAllocatePoolWithTag ; Allocates memory to
hold the data retrieved by ZwQueryObject
text:0001A6C9 mov esi, eax
text:0001A6CB mov [ebp+var_28], esi
text:0001A6CE cmp esi, edi
text:0001A6D0 jz short loc_1A74F

text:0001A6D2 mov edi, [ebp+ObjectAttributes]
text:0001A6D5 mov eax, [edi+OBJECT_ATTRIBUTES.RootDirectory] ; Here,
the code retrieves the RootDirectory's field value from the structure,
controled by us.
text:0001A6D8 test eax, eax
text:0001A6DA jz short loc_1A71B

text:0001A6DC push 0 ; ReturnLength
text:0001A6DE push ebx ; ObjectInformationLength
text:0001A6DF push esi ; ObjectInformation
; buffer where ZwQueryObject will put the object information

text:0001A6E0 push 1 ; ObjectInformationClass
; Specifies an OBJECT_INFORMATION_CLASS value that determines the type
; of information returned in the ObjectInformation buffer. It's using
; an undocumented type (OBJECT_NAME_INFORMATION) which returns an
UNICODE_STRING structure
text:0001A6E2 push eax ; ObjectHandle
; Now, the user-controlled handle 'll be used here to identify the object
by ZwQueryObject,
text:0001A6E3 call ds:ZwQueryObject
text:0001A6E9 mov [ebp+var_20], eax
text:0001A6EC test eax, eax
text:0001A6EE jl short loc_1A746

-----------/

Here is where the problem shows up. The code does not properly validates
the data retrieved by 'ZwQueryObject', expecting an 'UNICODE_STRING'
structure. But it is possible to make multiple calls to the function using
different handlers to obtain a null structure crashing the system when the
code tries to dereference its 'Buffer' field.

/-----------

text:0001A6F0 movzx eax, [esi+UNICODE_STRING.Length]
text:0001A6F3 shr eax, 1
text:0001A6F5 mov ecx, [esi+UNICODE_STRING.Buffer]
text:0001A6F8 movzx eax, word ptr [ecx+eax*2-2] ; Here is the problem
text:0001A6FD mov [ebp+var_30], eax
text:0001A700 cmp ax, 5Ch
text:0001A704 jz short loc_1A725

-----------/


3) SOPHOS ANTIVIRUS (BID 28743, CVE-2008-1737)
Insufficient argument validation of hooked SSDT functions on Sophos lead
to a DoS. An attacker, utilizing this flaw, would be able to locally
reboot the whole system shutting down the Firewall or AV protection.
Although neither the vendor nor Core Security has found a means of
exploiting the flaw to execute arbitrary code, it has not been possible to
rule this out.

In Sophos AV there is a problem in the arguments validation of
'NtCreateKey' function.

/-----------

int __cdecl NtCreateKeyHook(PHANDLE pKeyHandle, ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex,PUNICODE_STRING
Class, ULONG CreateOptions, PULONG Disposition)

[...]
text:0001C01C push 4 ; Alignment
text:0001C01E push 18h ; Length
text:0001C020 mov esi, [ebp+ObjectAttributes]
text:0001C023 push esi ; Address
text:0001C024 call ds:ProbeForRead

-----------/

Here it checks for 'ObjectAttributes' to be pointing to a valid address.

/-----------

text:0001C02A mov eax, [esi+OBJECT_ATTRIBUTES.RootDirectory]
text:0001C02D mov [ebp+Handle], eax
text:0001C030 mov esi, [esi+OBJECT_ATTRIBUTES.ObjectName]
text:0001C033 mov [ebp+pUnicodeString], esi

-----------/

Now, it gets from 'OBJECT_ATTRIBUTES' a handle and a pointer to an
'UNICODE_STRING' structure.

/-----------

text:0001C095 push 4
text:0001C097 push 8
text:0001C099 push esi
text:0001C09A mov ebx, ds:ProbeForRead
text:0001C0A0 call ebx ; ProbeForRead, it checks the
pointer before the dereference.

text:0001C0A2 mov eax, dword ptr [esi+UNICODE_STRING.Length]
text:0001C0A4 mov dword ptr [ebp+stUnicodeString.Length], eax
text:0001C0A7 mov esi, [esi+UNICODE_STRING.Buffer] ; And gets from
the UNICODE_STRING structure
; a pointer to the unicode buffer.
text:0001C0AA mov [ebp+stUnicodeString.Buffer], esi
text:0001C0AD push 2 ; Alignment
text:0001C0AF shr eax, 10h
text:0001C0B2 push eax ; Length
text:0001C0B3 push esi ; Address
text:0001C0B4 call ebx ; ProbeForRead

-----------/

It does the check, but here is the problem

/-----------

text:0001C0B6 push gdwValue
text:0001C0BC lea eax, [ebp+stUnicodeString]
text:0001C0BF push eax
text:0001C0C0 push [ebp+Object]
text:0001C0C3 call sub_1cb40

-----------/

The problem relies in the function not properly checking the 'Length'
field of the 'UNICODE_STRING' structure. When doing the check,
'ProbeForRead' receives the length field of the structure as a parameter
without any kind of validation.

So, if we set this field to 0, 'ProbeForRead' will not raise any exception
even though we were passing it an invalid address. And it will crash when
trying to access to the desired invalid memory.

/-----------

sub_1cb40

[...]
text:0001CB5E xor esi, esi
text:0001CB60 mov [ebp+ms_exc.disabled], esi
text:0001CB63 mov edi, [ebp+pUnicodeString]
text:0001CB66 mov eax, [edi+UNICODE_STRING.Buffer]

-----------/

And here is where it will crash:

/-----------

text:0001CB69 cmp word ptr [eax], '\' ; Reference the first pointed
byte

-----------/


4) RISING ANTIVIRUS (BID 28744, CVE-2008-1738)
In Rising antivirus the code of the 'NtOpenProcess' hook does not
validates if the pointer to the structure

/-----------

typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread;}

-----------/

is really pointing to mapped memory. So, when the code tries to
dereference the pointer to check the 'CLIENT_ID->UniqueProcess' value, if
it is pointing to invalid memory, will crash.

/-----------

NtOpenProcess( OUT PHANDLE ProcessHandle, IN ACCESS_MASK AccessMask, IN
POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId )

text:00010EAA push ebp
text:00010EAB mov ebp, esp
text:00010EAD push esi
text:00010EAE mov esi, offset Addend
text:00010EB3 push edi
text:00010EB4 mov ecx, esi ; Addend
text:00010EB6 call ds:InterlockedIncrement
text:00010EBC call PsGetCurrentProcessId
text:00010EC1 cmp eax, dword_11C8C
text:00010EC7 jnz short loc_10ECE
text:00010EC9
text:00010EC9 loc_10EC9: ; CODE XREF: sub_10EAA+37_j
text:00010EC9 push [ebp+ClientId]
text:00010ECC jmp short loc_10EF0

text:00010ECE
text:00010ECE loc_10ECE: ; CODE XREF: sub_10EAA+1D_j
text:00010ECE call PsGetCurrentProcessId
text:00010ED3 mov ecx, dword_11C80
text:00010ED9 push eax
text:00010EDA call sub_11070
text:00010EDF test al, al
text:00010EE1 jnz short loc_10EC9
text:00010EE3 call PsGetCurrentProcessId
text:00010EE8 mov edi, [ebp+ClientId] ; Here is the bug, if ClientId
is pointing to an invalid address
text:00010EEB cmp eax, [edi] ; it will crash.
text:00010EED jnz short loc_10F0D

-----------/


Report Timeline:
2008-01-11: Core Security Technologies found a security vulnerability in
BitDefender antivirus.
2008-01-14: BitDefender team is contacted by Core.
2008-01-15: BitDefender team asks Core for technical description of the
vulnerability.
2008-01-15: Technical details are sent to BitDefender team by Core.
2008-01-22: BitDefender notifies Core that a fix has been produced and the
flaw was corrected through automatic updates.
2008-02-04: According to the original schedule, the CORE-2008-0320
advisory would be released at this date, but similar flaws in other
antivirus products were discovered by Core exploit writers team.
Considering all BitDefender users are patched, Core Security Technologies
does not release the advisory and continues the research of this issue in
other products.
2008-03-20: Core analyzes similar vulnerabilities in Comodo Firewall,
Sophos Antivirus and Rising Antivirus.
2008-03-25: Core notifies the Comodo, Sophos and Rising teams of the
vulnerabilities.
2008-03-27: Comodo team asks Core for technical description of the
vulnerability.
2008-03-27: Technical details are sent to Comodo team by Core.
2008-03-31: Rising team asks Core for technical description of the
vulnerability.
2008-04-01: Technical details are sent to Rising team by Core.
2008-04-02: Rising team inform Core that the flaw has been fixed in the
Rising AV 2008 version.
2008-04-02: Sophos team asks Core for technical description of the
vulnerability.
2008-04-07: Technical details are sent to Sophos team by Core.
2008-04-11: Sophos team informs that the flaw is found in one of the
antivirus drivers, and fixing it will require a reboot for all of Sophos
Windows customers. Sophos would like to fix the bug in the next major
version (second quarter 2009), in particular considering the fact that
they were unable to come up with any practical use of this vulnerability.
2008-04-14: Comodo notifies Core that a fix has been produced.
2008-04-14: Sophos informs Core that they will be able to release a fix to
the vulnerability at the end of October 2008.
2008-04-21: Core responds that they will reschedule the publication to
April 24th, 2008. Since the vulnerability is not critical, and has been
found using publicly available tools, like the other vulnerabilities
included in the advisory, Core doesn't see a reason to postpone the
publication of the Sophos bug until October 2008.
2008-04-21: Sophos asks Core not to release details of the vulnerability
until a fix is available, and not to publish Proof of Concept code. Sophos
informs that they do not believe that arbitrary code execution is
possible.
2008-04-24: Core responds that the advisory does not contain Proof of
Concept code. Core confirms its intention of publishing the advisory,
including the technical description, but decides to postpone it to April
28th, to give the participants more time to coordinate the release of
public information.
2008-04-25: Sophos provides additional information, included in the
"vendor information" section of the advisory.
2008-04-28: CORE-2008-0320 advisory is published.

References
[1] <http://www.bitdefender.com> http://www.bitdefender.com
[2] <http://www.comodo.com> http://www.comodo.com
[3] <http://www.sophos.com> http://www.sophos.com
[4] <http://www.rising-global.com> http://www.rising-global.com
[5] <http://www.matousec.com/downloads> http://www.matousec.com/downloads
[6]
<http://www.matousec.com/info/articles/plague-in-security-software-drivers.php> http://www.matousec.com/info/articles/plague-in-security-software-drivers.php

CVE Information:
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1735>
CVE-2008-1735,
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1736>
CVE-2008-1736,
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1737>
CVE-2008-1737 and
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1738>
CVE-2008-1738


ADDITIONAL INFORMATION

The information has been provided by <mailto:advisories@xxxxxxxxxxxxxxxx>
CORE Security Technologies Advisories.
The original article can be found at:
<http://www.coresecurity.com/?action=item&id=2249>
http://www.coresecurity.com/?action=item&id=2249



========================================


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: list-unsubscribe@xxxxxxxxxxxxxx
In order to subscribe to the mailing list, simply forward this email to: 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.



Relevant Pages