Thursday, July 15, 2010

Zone Crasher

I released a new security advisory for Oracle Solaris and OpenSolaris. See TKADV2010-005 for a detailed description of the vulnerability and the OpenSolaris source browser for the source code fixes.

Tuesday, May 04, 2010 now with kernel support

New release.

What's new with version 1.3:

* Additional checks for a number of kernel hardening features.
  Thanks to Jon Oberheide (
Example of the new "--kernel" option:

You can download the new version 1.3 of here.

Sunday, April 18, 2010

Split-process model FTW

As I already mentioned in my last posting Google Chrome supports a split-process model that allows each browser tab to exist in its own process. The benefits to such a configuration include security and stability, as a bug in the renderer will only cause problems with a single tab that can be closed while others remain active.

► Want an example?

If you open this testcase in Apple's Safari the browser will crash. If you open the testcase in Google Chrome only the current tab will be affected. It's a simple stack overflow (stack exhaustion) bug. This is a stability issue that by itself cannot lead to remote code execution. See this blog entry for more information about stack overflows.

If you want some more information about the particular bug see the Chromium bugtracker or Webkit's Bugzilla.

Apple also finally recognized the benefits of such a split-process model: see WebKit2.

Friday, April 02, 2010

"Kernel Bug" in Google Chrome

I have to admit that I'm deeply impressed by the security architecture of Chromium, the open-source browser upon which Google Chrome is built. Google provides a lot of interesting background information on the security architecture of Chromium here and here. The most important security feature of Chromium is that the browser has two modules in separate protection domains: a »browser kernel«, which interacts with the operating system, and a »rendering engine«, which runs with restricted privileges in a sandbox.

If there's a bug in the rendering engine (JavaScript V8, Webkit, FFmpeg etc.) it will only affect a sandboxed renderer process. As long as you can't escape the sandbox you're quite limited in what you can do. But if you find a bug in the browser kernel the game changes.

Lately (see TKADV2010-004) I found an out-of-bounds array indexing bug in the FTP handling code of Google Chrome. As all the networking code, including the handling of FTP, is implemented in the browser kernel, the bug not only affects a sandboxed browser tab but the whole browser.

If you want to crash your Google Chrome browser (Windows version <= see my advisory for a proof of concept.

Tuesday, March 30, 2010

My new book just got released!

It's available in German only at the moment, but I'm currently working on an English version of the book.

► German Version

»Aus dem Tagebuch eines Bughunters.
 Wie man Softwareschwachstellen aufspürt und behebt«

Das Buch beschreibt den Lebenszyklus ausgewählter Softwareschwachstellen, die ich im Laufe der letzten Jahre gefunden habe. Jedes Kapitel erläutert dabei im Detail, wie ich die jeweilige Schwachstelle gefunden und anschließend ausgenutzt habe, sowie die durchgeführten Schritte zur Behebung der Schwachstelle seitens des Herstellers.

Mehr Informationen zum Buch gibt es auf meiner Webseite oder beim dpunkt.verlag.

► English Version

Working Title: »From A Bug Hunter's Diary«

The book describes the lifetime of some interesting real-life software vulnerabilities I found over the last years. Each chapter goes into great detail on how I found a bug, the steps I took to exploit it and how it was rectified by the vendor.

The English version will be released when it is finished ;)

Monday, February 22, 2010

The Fix That Never Was

Approximately two years ago I found a memory corruption bug in one of the kernel drivers shipped with avast! 4.7. After I reported the bug to ALWIL Software they only took about two weeks to provide a fixed version. That's quite fast for a commercial software vendor. To be honest, I never checked if and how the bug was fixed with that new version. Anyway, a few weeks ago I decided to have a look at the avast! drivers again. While reversing the drivers I quickly realized that the measures taken by ALWIL Software to fix my 2 year old bug weren't sufficient.

►  A Short Recap of the "old" Bug

Disassembly of the vulnerable aavmker4.sys driver (avast! 4.7, file version 4.7.1098.0):
.text:00010E06    loc_10E06: 
.text:00010E06      xor     edx, edx
.text:00010E08      mov     eax, [ebp+v38_uc]
.text:00010E0B      mov     [eax], edx
.text:00010E0D      mov     [eax+4], edx
.text:00010E10      add     esi, 4         ; src
.text:00010E13      mov     ecx, 21Ah      ; len
.text:00010E18      mov     edi, [eax+18h] ; dst
.text:00010E1B      rep movsd              ; memcpy
The memcpy() function at .text:00010E1B gets called with the following parameters:
memcpy (EDI, ESI, ECX); 
EDI (dst): the value is extracted from user controlled IOCTL input data
ESI (src): points to user controlled IOCTL input data
ECX (len): 0x21A
As both the destination address as well as the source data of that memcpy() call could be controlled by the requesting user it was possible to overwrite arbitrary memory addresses with arbitrary values. This could be exploited to control the kernel execution flow and to execute arbitrary code at the kernel level. For more details see TKADV2008-002.

► The Fix

The "new" version of the kernel driver (avast! 4.8 <= 4.8.1368.0) implements the following check to remediate the described bug.

Disassembly of the vulnerable aavmker4.sys driver (avast! 4.8, file version 4.8.1356.0):
.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 [1]  mov    esi, [edi+870h] 
.text:00010F34      mov    [ebp+v34_uc], esi 
.text:00010F37      mov    eax, ds:MmUserProbeAddress 
.text:00010F3C [2]  cmp    esi, [eax]      ; user space or kernel space?
.text:00010F3E      jnb    short loc_10F46 
Before the described memcpy() function is called a pointer value gets extracted from the user supplied IOCTL input data. That value is then stored in ESI (see [1]). Then it is checked if ESI points into user space or kernel space (see [2]). This is done by comparing the pointer with MmUserProbeAddress. If ESI points into kernel space, the memcpy() function gets called as before. If it points into user space memcpy() won't be called.

If ESI points into kernel space 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      rep movsd              ; memcpy 
The memcpy() function at .text:00010FAE gets called with the following parameters:
memcpy (EDI, ESI, ECX); 
EDI (dst): the value is extracted from a user defined kernel space address
ESI (src): points to user controlled IOCTL input data
ECX (len): 0x21A
Assumption of the "new" check: As the destination address of memcpy() is now extracted from kernel space memory it isn't possible to directly control that value from user space anymore.

This only holds true if we weren't able to (temporarily) store user controlled data at a user defined address in kernel space. 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.

Well, the fix that never was ;)

► Exploitation

Exploiting this bug is quite easy:

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).

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.

STEP 3: Manipulate a function pointer.

STEP 4: Fun and profit.

Working out the rest of the attack is left as an exercise for the reader ;)

Affected are avast! 4.8 <= 4.8.1368.0 and avast! 5.0 < 5.0.418.0. See also my security advisory (TKADV2010-003) for further information.

► EIP Control

I wrote a proof of concept (poc) that gains control of the kernel execution flow (EIP control). Output of the kernel debugger when executing the poc (avast! 5.0 under Windows XP SP3):
#################### AAVMKER: WRONG RQ ######################!
Access violation - code c0000005 (!!! second chance !!!)
41414141 ??              ???

kd> kb
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for Aavmker4.SYS - 
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
edc99bdc f7955cae 8621ada8 e21f0030 00000001 0x41414141
edc99c34 804ee129 861f8030 866c0d98 806d22d0 Aavmker4+0xcae
edc99c44 80574dde 866c0e08 865833c0 866c0d98 nt!IopfCallDriver+0x31
edc99c58 80575c7f 861f8030 866c0d98 865833c0 nt!IopSynchronousServiceTail+0x70
edc99d00 8056e4ec 000002f8 00000000 00000000 nt!IopXxxControlFile+0x5e7
edc99d34 8053d648 000002f8 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
edc99d34 7c91e514 000002f8 00000000 00000000 nt!KiFastCallEntry+0xf8
039cb1b0 65006e90 000002f8 b2d60034 039cb1fc 0x7c91e514
039cb24c 00000000 00000000 00000000 00000000 0x65006e90

kd> r
eax=8621ada8 ebx=866c0d98 ecx=00000000 edx=00000000 esi=867d2bc0 edi=80527660
eip=41414141 esp=edc99be0 ebp=edc99c34 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010202
41414141 ??              ???
If no kernel debugger is attached the poc gives the following BSoD:

Tuesday, February 02, 2010

iPhone OS and Mac OS X Stack Buffer Overflow

My second security advisory in 2010 (TKADV2010-002) describes the details of a stack buffer overflow I found in CoreAudio of Apple's iPhone OS and Mac OS X. The bug can be triggered by playing a maliciously crafted mp4 audio file. Example attack vectors on the iPhone are MobileSafari and malicious ringtones.

Crashdump details:

Process:         mediaserverd [17]
Path:            /usr/sbin/mediaserverd


Exception Codes: KERN_INVALID_ADDRESS at 0x41414140


Unknown thread crashed with ARM Thread State:
    r0: 0x6474613f    r1: 0x01380c40      r2: 0x380c561c      r3: 0x0000010d
    r4: 0x41414141    r5: 0x41414141      r6: 0x41414141      r7: 0x41414141
    r8: 0x41414141    r9: 0x00181494     r10: 0x41414141     r11: 0x41414141
    ip: 0x00818000    sp: 0x01380c00      lr: 0x3072d454      pc: 0x41414140
  cpsr: 0x60000030

Sunday, January 31, 2010

Kernel NULL Pointer Dereference in (Open)Solaris

Today I released a security advisory (TKADV2010-001) describing a NULL pointer dereference in the kernel of Oracle Solaris 10 and OpenSolaris (x86). The bug happens in processor microcode code when retrieving the microcode revision.

Debugging information (SunOS 5.10 Generic_139556-08 i86pc i386 i86pc):

> ::msgbuf
BAD TRAP: type=e (#pf Page fault) rp=fffffe80012dcbf0 addr=0 occurred in module "unix" due to a NULL pointer dereference

#pf Page fault
Bad kernel fault at addr=0x0
pid=1471, pc=0xfffffffffb81e8f3, sp=0xfffffe80012dcce0, eflags=0x10286
cr0: 8005003b cr4: 6b0
cr2: 0 cr3: 9f84000 cr8: c
        rdi:                0 rsi:                1 rdx:               b6
        rcx:                0  r8: ffffffff88050b20  r9: ffffffff87df87c0
        rax:                0 rbx:                0 rbp: fffffe80012dccf0
        r10:               f5 r11:                0 r12:                0
        r13:                1 r14:                3 r15:           100001
        fsb: ffffffff80000000 gsb: fffffffffbc278a0  ds:               43
         es:               43  fs:                0  gs:              1c3
        trp:                e err:                2 rip: fffffffffb81e8f3
         cs:               28 rfl:            10286 rsp: fffffe80012dcce0
         ss:               30

fffffe80012dcb00 unix:die+da ()
fffffe80012dcbe0 unix:trap+5e6 ()
fffffe80012dcbf0 unix:_cmntrap+140 ()
fffffe80012dccf0 unix:ucode_get_rev+53 ()
fffffe80012dcd80 ucode:ucode_ioctl+22e ()
fffffe80012dcd90 genunix:cdev_ioctl+1d ()
fffffe80012dcdb0 specfs:spec_ioctl+50 ()
fffffe80012dcde0 genunix:fop_ioctl+25 ()
fffffe80012dcec0 genunix:ioctl+ac ()
fffffe80012dcf10 unix:brand_sys_sysenter+1f2 ()

syncing file systems...
dumping to /dev/dsk/c0d0s1, offset 110231552, content: kernel

Now that Oracle has completed its acquisition of Sun the Sun Alert for this vulnerability will be published in April as part of Oracle's next Critical Patch Update (CPU). The exact date would be 13 April 2010 as documented here.

Since the patch for Solaris 10 is already available and the diffs will be visible in the Mercurial repository and in the OpenSolaris source browser I chose not to wait until 13 April but published my advisory today.

Saturday, January 02, 2010 with PaX support

New release.

What's new with version 1.2:

* Additional PaX ( checks
  Thanks to Brad Spengler ( for the PaX support.

* Some minor fixes (coloring adjusted, 'pidof' replacement)
You can download the new version 1.2 of here.