Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:23287
HistoryFeb 25, 2010 - 12:00 a.m.

[TKADV2010-003] avast! 4.8 and 5.0 aavmker4.sys Kernel Memory Corruption

2010-02-2500:00:00
vulners.com
11

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Advisory: avast! 4.8 and 5.0 aavmker4.sys Kernel Memory
Corruption
Advisory ID: TKADV2010-003
Revision: 1.0
Release Date: 2010/02/22
Last Modified: 2010/02/22
Date Reported: 2010/02/01
Author: Tobias Klein (tk at trapkit.de)
Affected Software: avast! 4.8 <= 4.8.1368.0
avast! 5.0 < 5.0.418.0
Remotely Exploitable: No
Locally Exploitable: Yes
Vendor URL: http://www.avast.com
Vendor Status: Vendor has released an updated version
Patch development time: 10 days

======================
Vulnerability Details:

The kernel driver aavmker4.sys shipped with avast! 4.8 and 5.0 contains a
vulnerability in the code that handles IOCTL requests. Exploitation of this
vulnerability can result in:

1) local denial of service attacks (system crash due to a kernel panic), or

2) local execution of arbitrary code at the kernel level (complete system
compromise)

The issue can be triggered by sending a specially crafted IOCTL request.

No special user rights are required to exploit the vulnerability.

==================
Technical Details:

The IOCTL call 0xb2d60030 of the aavmker4.sys kernel driver shipped with
avast! 4.8 and 5.0 accepts user supplied input that doesn't get validated
enough. In consequence it is possible to overwrite arbitrary kernel space
and user space memory addresses with arbitrary values. This can be
exploited to control the kernel execution flow and to execute
arbitrary code at the kernel level.

Disassembly of aavmker4.sys (avast! 4.8, file version 4.8.1356.0):

[…]
.text:00010E46 [1] cmp eax, 0B2D60030h ; vulnerable IOCTL
.text:00010E4B jz loc_10EEF
[…]
.text:00010EEF loc_10EEF:
.text:00010EEF cmp byte_1262C, 0
.text:00010EF6 jz short loc_10F0C
[…]
.text:00010F0C loc_10F0C:
.text:00010F0C [2] mov edi, [ebx+0Ch]
.text:00010F0F [3] cmp esi, 878h ; InputBufferSize == 0x878?
.text:00010F15 jz short loc_10F21
[…]

[1] Vulnerable IOCTL
[2] EDI now points to user controlled IOCTL input data
[3] The size of the IOCTL input data must be equal to 0x878

[…]
.text:00010F21 loc_10F21:
.text:00010F21 and [ebp+var_4], 0
.text:00010F25 cmp dword ptr [edi], 0
.text:00010F28 jz loc_10FC5
.text:00010F2E [4] mov esi, [edi+870h]
.text:00010F34 mov [ebp+v34_uc], esi
.text:00010F37 mov eax, ds:MmUserProbeAddress
.text:00010F3C [5] cmp esi, [eax] ; user space or kernel space?
.text:00010F3E jnb short loc_10F46
[…]

[4] If the input size equals 0x878 a pointer value gets extracted from the
user supplied IOCTL input data and saved in ESI
[5] It is checked if ESI points into user space or kernel space

[…]
.text:00010F46 loc_10F46:
.text:00010F46 push esi ; VirtualAddress
.text:00010F47 [6] call ds:MmIsAddressValid
.text:00010F4D test al, al
.text:00010F4F jz short loc_10F5F
.text:00010F51 lea eax, [esi+8]
.text:00010F54 push eax ; VirtualAddress
.text:00010F55 [7] call ds:MmIsAddressValid
.text:00010F5B test al, al
.text:00010F5D jnz short loc_10F65
[…]

[6] + [7] If ESI points to an address in kernel space it is checked if ESI
and ESI+8 are pointing to valid memory addresses

[…]
.text:00010F65 loc_10F65:
.text:00010F65 [8] mov eax, [esi]
.text:00010F67 mov [ebp+v32_uc], eax
.text:00010F6A [9] mov esi, [esi+4]
.text:00010F6D mov [ebp+var_4C], esi
.text:00010F70 [10] xor [ebp+v32_uc], 55667788h
.text:00010F77 [11] xor esi, 11223344h
.text:00010F7D mov [ebp+var_4C], esi
.text:00010F80 mov eax, dword_125E8
.text:00010F85 [12] cmp eax, [ebp+v32_uc] ; check pattern1
.text:00010F88 jnz short loc_10F93
.text:00010F8A mov eax, dword_125EC
.text:00010F8F [13] cmp eax, esi ; check pattern2
.text:00010F91 jz short loc_10F99
[…]

[8] + [9] If the addresses are valid, EAX and ESI are filled with data
from the user defined kernel space address (pointed to by ESI)

The first value (EAX) is xor'ed with 0x55667788 (see [10]) and then
compared with the value 0x85B8DA8F found at dword_125E8 (see [12]).

.data:000125E8 dword_125E8 dd 85B8DA8Fh

The second value (ESI) is xor'ed with 0x11223344 (see [11]) and then
compared with the value 0x198E3FE found at dword_125EC (see [13]).

.data:000125EC dword_125EC dd 198E3FEh

If both patterns match, the following code gets executed:

[…]
.text:00010F99 loc_10F99:
.text:00010F99 xor edx, edx
.text:00010F9B mov eax, [ebp+v34_uc]
.text:00010F9E mov [eax], edx
.text:00010FA0 mov [eax+4], edx
.text:00010FA3 lea esi, [edi+4] ; src
.text:00010FA6 mov ecx, 21Ah ; len
.text:00010FAB mov edi, [eax+18h] ; dst
.text:00010FAE [14] rep movsd ; memcpy
[…]

The memcpy function at [14] gets called with the following parameters:

memcpy (EDI, ESI, ECX);

EDI (dst): this value is extracted from a user defined kernel space address
ESI (src): points to user controlled IOCTL input data
ECX (len): 0x21A

Vulnerability:

If an attacker were able to (temporarily) store user controlled data at a
user defined address in kernel space, the check at [5] could be passed and
the memcpy() call would lead to an exploitable memory corruption condition.

Unfortunately, the aavmker4.sys driver supports at least one IOCTL that
allows an unprivileged user to temporarily store arbitrary data at a known
kernel space address.

Exploitation:

STEP 1: Use one of the IOCTLs supported by aavmker4.sys to temporarily
store arbitrary data at a known kernel space address (e.g. the IOCTL
0xb2d6001c). This data has to start with the two patterns that are checked
at [12] and [13].

STEP 2: Send a request to the vulnerable IOCTL. Store a pointer at offset
0x870 of the IOCTL data that points to the kernel space address of STEP 1.

=========
Solution:

Update to avast! 5.0 >= 5.0.418.

====================
Disclosure Timeline:

Format: year/month/day

2010/01/24 - Vendor notified using [email protected]
2010/01/29 - Vendor response with PGP key
2010/02/01 - Detailed vulnerability information sent to the vendor
2010/02/01 - Vendor confirms the vulnerability
2010/02/09 - Status update by ALWIL Software
2010/02/11 - Vendor releases updated version
2010/02/22 - Release date of this security advisory

========
Credits:

Vulnerability found and advisory written by Tobias Klein.

===========
References:

[REF1] http://forum.avast.com/index.php?topic=55484.0
[REF2] http://www.trapkit.de/advisories/TKADV2010-003.txt

========
Changes:

Revision 0.1 - Initial draft release to the vendor
Revision 1.0 - Public release

===========
Disclaimer:

The information within this advisory may change without notice. Use
of this information constitutes acceptance for use in an AS IS
condition. There are no warranties, implied or express, with regard
to this information. In no event shall the author be liable for any
direct or indirect damages whatsoever arising out of or in connection
with the use or spread of this information. Any use of this
information is at the user's own risk.

==================
PGP Signature Key:

http://www.trapkit.de/advisories/tk-advisories-signature-key.asc

Copyright 2010 Tobias Klein. All rights reserved.

-----BEGIN PGP SIGNATURE-----
Version: PGP
Charset: utf-8

wj8DBQFLgn5okXxgcAIbhEERAj8GAJ9pYDOH4TrvUzvyeOALoWLENLM7xwCg0W1g
WaQ8IbevEtzmE2njc/RRcWI=
=Egms
-----END PGP SIGNATURE-----