-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Core Security Technologies - CoreLabs Advisory
http://www.coresecurity.com/corelabs/
Insufficient argument validation of hooked SSDT functions
on multiple Antivirus and Firewalls
*Advisory Information*
Title: Insufficient argument validation of hooked SSDT functions on
multiple Antivirus and Firewalls
Advisory ID: CORE-2008-0320
Advisory URL: http://www.coresecurity.com/?action=item&id=2249
Date published: 2008-04-28
Date of last update: 2008-04-28
Vendors contacted: BitDefender, Comodo, Sophos and Rising
Release mode: Coordinated release (BitDefender, Comodo, Rising), User
release (Sophos)
*Vulnerability Information*
Class: Invalid memory reference
Remotely Exploitable: No
Locally Exploitable: Yes
Bugtraq ID: 28741 28742 28743 28744
CVE Name: CVE-2008-1735 CVE-2008-1736 CVE-2008-1737 CVE-2008-1738
*Vulnerability Description*
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.
*Vulnerable Packages*
. BitDefender Antivirus 2008 Build 11.0.11
. Comodo Firewall Pro 2.4.18.184
. Sophos Antivirus 7.0.5
. Rising Antivirus 19.60.0.0 and 19.66.0.0
. Older versions may be affected, but were not checked.
*Non-vulnerable Packages*
. BitDefender Antivirus 2008 builds available through automatic updates,
posterior to January 18th.
. Comodo Firewall Pro 3.0
. Rising Antivirus 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-BitDefende
r-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
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
All Rising customers can also update up to a patched version through
automatic updates.
*Credits*
These vulnerabilities (except the Rising one) were discovered by Damian
Saura, Anibal Sacco, Dario Menichelli, Norberto Kueffner, Andres Blanco
y Rodrigo Carvalho from Core Security Technologies, during Bugweek 2007.
The Rising vulnerability was discovered by Anibal Sacco from Core
Security Technologies exploit writers team.
These vulnerabilities were researched by Anibal Sacco and Damian Saura
from Core Security Technologies.
*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 even
more 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. Or
by 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
[2] http://www.comodo.com
[3] http://www.sophos.com
[4] http://www.rising-global.com
[5] http://www.matousec.com/downloads
[6]
http://www.matousec.com/info/articles/plague-in-security-software-driver
s.php
*About CoreLabs*
CoreLabs, the research center of Core Security Technologies, is charged
with anticipating the future needs and requirements for information
security technologies. We conduct our research in several important
areas of computer security including system vulnerabilities, cyber
attack planning and simulation, source code auditing, and cryptography.
Our results include problem formalization, identification of
vulnerabilities, novel solutions and prototypes for new technologies.
CoreLabs regularly publishes security advisories, technical papers,
project information and shared software tools for public use at:
http://www.coresecurity.com/corelabs/.
*About Core Security Technologies*
Core Security Technologies develops strategic solutions that help
security-conscious organizations worldwide develop and maintain a
proactive process for securing their networks. The company's flagship
product, CORE IMPACT, is the most comprehensive product for performing
enterprise security assurance testing. CORE IMPACT evaluates network,
endpoint and end-user vulnerabilities and identifies what resources are
exposed. It enables organizations to determine if current security
investments are detecting and preventing attacks. Core Security
Technologies augments its leading technology solution with world-class
security consulting services, including penetration testing and software
security auditing. Based in Boston, MA and Buenos Aires, Argentina, Core
Security Technologies can be reached at 617-399-6980 or on the Web at
http://www.coresecurity.com.
*Disclaimer*
The contents of this advisory are copyright (c) 2008 Core Security
Technologies and (c) 2008 CoreLabs, and may be distributed freely
provided that no fee is charged for this distribution and proper credit
is given.
*GPG/PGP Keys*
This advisory has been signed with the GPG key of Core Security
Technologies advisories team, which is available for download at
http://www.coresecurity.com/files/attachments/core_security_advisories.a
sc.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFIFl26yNibggitWa0RAnDqAJ0b0FZeUC5U4OiG8ErOuEF0dzUVgACggHC2
OHDF+apsYohQyMN3ZjAfzbk=
=c4NZ
-----END PGP SIGNATURE-----