Blog | Talks | Docs | Tools | Advisories | About | RSS
Fermín J. Serna - Blog...
<<<<< September - 2014 >>>>>

17-Sep-2014 [18:11] -- XNU Kernel stack and heap information leaks

Today Apple released IOS8 and then credited a lot of vulnerability researchers for fixed bugs. Find more information at

Here I am going to present details of 4 of them where I was credited: CVE-2014-4371, CVE-2014-4419, CVE-2014-4420 and CVE-2014-4421. As weird as it sounds, I found them on a plane reading the XNU kernel code :S

One of those is a "kernel stack content information leak" and was confirmed on latest version of MacOSX and IOS at the time I reported to Apple (May 8th 2014). PoC here: ntstat-x.c

$ ./ntstat_x
Leaked 4 bytes at the kernel stack: 0xd5d38dfd

The problem resides at the very end of the file
When going back to user mode you do not clear the field leaving it with the original stack contents.

if (result != 0)
struct nstat_msg_error err;

err.hdr.type = NSTAT_MSG_TYPE_ERROR;
err.hdr.context = hdr->context;
err.error = result;

result = ctl_enqueuedata(kctl, unit, &err, sizeof(err), CTL_DATA_EOR);

Fix should be to zero out the entire structure before setting fields and returning from kernel mode.

The other three instances of this info leak lead to another two kernel stack info leak and a more interesting heap info leak. I am pretty sure the last one can be used to leak pointers to the kernel and bypass K-ASLR.

Stack content leak: nstat_control_send_counts
Heap content leak: nstat_control_send_description
Stack content leak: nstat_control_send_removed

Fermin J. Serna - @fjserna

Comments (0)

21-Aug-2013 [13:26] -- CVE-2013-3186 - The case of a one click sandbox escape on IE

MSFT security updates for August 2013 contained a fix for a vulnerability I reported to MSRC some time ago. Behind a some kind cryptic title of "Internet Explorer Process Integrity Level Assignment Vulnerability " hides a 1 click sandbox escape (CVE-2013-3186).

Some context before the vulnerability. IE sandbox, called protected mode, is based on integrity levels where the renderer (where JS runs among other things) runs as Low Integrity level and the main frame runs as Medium Integrity level. They talk to each other through a broker RPC/pipe interface. A process running under Low IL can read almost anything in the system (ACL allowing) but can write to very few locations (TempLow for example). Basically protected mode is tackling the persistance problem of malware exploiting a security vulnerability at the Low IL process.

Find more about integrity levels and IE protected mode here.

Then we have the concept of ElevationPolicy which basically is a list of pairs (program & elevation policy) at the registry (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Low Rights\ElevationPolicy). These are the supported values:

3 - Protected Mode silently launches the broker as a medium integrity process.
2 - Protected Mode prompts the user for permission to launch the process. If permission is granted, the process is launched as a medium integrity process.
1 - Protected Mode silently launches the broker as a low integrity process.
0 - Protected Mode prevents the process from launching.

Basically, if there is an item there with ElevationPolicy 3 the broker will execute that program as Medium IL if requested.

And this is the case for msdt.exe. Funny thing is that CreateProcess() has a hook inside the LowIL IE process and if you try to CreateProcess("msdt.exe") it will get brokered to the IE Medium IL one and applied the Elevation policy there. Some sanitization happens to most of the parameters for security reasons (do not create a Medium IL process where the process token is too unrestricted, ...)

The vulnerability here is that msdt.exe (that due to its elevation policy will run as medium IL outside of any sandbox) has some interesting command line options. Concretely this one:

/path directory | .diagpkg file | .diagcfg file ----
Specifies the full path to a diagnostic package. If you specify a directory, the directory must contain a diagnostic package. You cannot use the /path parameter in conjunction with the /id, /dci, or /cab parameter.

This diagpkg is basically a troubleshooting cab/zip file composed of powershell scripts. msdt.exe initially will show an initial dialog with attacker controlled strings from the cab file (hello social engineering) and once the user clicks the continue button one of the attacker controlled powershell scripts will get executed (again as medium). Voila, sandbox escaped...

Couple of things worth mentioning:

Fermin J. Serna - @fjserna

Comments (0)

19-Jul-2013 [17:56] -- Flash JIT - Spraying ROP info leak gadgets

Long time no see... again!

Back in Fall/2012 I did some research on Flash JIT code generation. This research and lack of constant blinding resulted on the following paper (including Win7/IE9 exploit code for CVE-2012-4787) where Flash could be used for ASLR bypass on IE by spraying ROP info leak gadgets.

Exploit code:

I just found today (without notification from Adobe) that Flash 11.8 implements JIT constant blinding. So consider this technique gone but older versions may still be used for info leak purposes. :)

Fermin J. Serna - @fjserna

Comments (0)

11-Mar-2013 [21:17] -- LLVM patch: VTXor

Long time no posts...

In this one I want to introduce something I developed for LLVM some months ago: VTXor. Digging on a compiler is always fun, challenging but time consuming.

I could never finish it since still requires a lot of code digging at LLVM. I guess I did the most challenging part (understanding and modifying the code emission) but I left all the other boring ones (annotations, command line options, ...). So here it is in case anyone wants to finish the boring part and make the internet a safer place. Ha!

VTxor is a security mitigation (not perfect as I will explain later) making harder to exploit vulnerabilities that take advantage of attacker controlled virtual function table pointers.

It is cool because:
- It supports 32 bit and 64 bit architectures
- It should support (although not tested) anything LLVM is able to generate code for... so ARM and other friends too.
- Supports -fPIC an non -fPIC compilations
- Makes exploitation more challenging and that is always fun

Some limitations I am aware of:
- In 32 bits compilations it is not effective due to heap spraying. Long story... I will let the reader figure it out :) But still... 64 bit with proper dispersion of virtual pages should make exploitation harder
- You need to compile the entire program and libraries with this in order to prevent virtual function calls using the encoded pointer.

Disassembly is better than words. So here it is how VTXor works.

The following code is generated when an object gets allocated and the virtual function table pointer is set. Please note because of -fPIC it will be tough to see wehre the VTxor cookie comes from.

(gdb) disass _ZN4baseC2Ev
Dump of assembler code for function _ZN4baseC2Ev:
0x08048a60 <+0>: push eax
0x08048a61 <+1>: call 0x8048a66 <_ZN4baseC2Ev+6>
0x08048a66 <+6>: pop eax
0x08048a67 <+7>: add eax,0x158e
0x08048a6d <+13>: mov ecx,DWORD PTR [esp+0x8]
0x08048a71 <+17>: mov edx,DWORD PTR [eax-0xc]
0x08048a77 <+23>: add edx,0x8
0x08048a7d <+29>: mov eax,DWORD PTR [eax-0x4]
0x08048a83 <+35>: mov DWORD PTR [esp],ecx
0x08048a86 <+38>: mov ecx,DWORD PTR [esp]
0x08048a89 <+41>: xor edx,DWORD PTR [eax] <---- xor the vftable_ptr with a random vtxor cookie
0x08048a8b <+43>: mov DWORD PTR [ecx],edx <---- store it at the first dword of the object chunk
0x08048a8d <+45>: pop eax
0x08048a8e <+46>: ret
End of assembler dump.

And when calling into a virtual function something like this happens:

0x0804893b <+299>: mov esi,DWORD PTR [edx]
0x0804893d <+301>: mov edi,DWORD PTR [ecx] <--- get the encoded vftable_ptr
0x0804893f <+303>: xor esi,edi <---- xor the vftable_ptr with the VTXor cookie
0x08048941 <+305>: mov DWORD PTR [esp],edx
0x08048944 <+308>: mov ebx,eax
0x08048946 <+310>: mov DWORD PTR [ebp-0x44],ecx
0x08048949 <+313>: call DWORD PTR [esi]

The VTXor cookie comes from libvtxor. Concretely this function:

intptr_t __vtxor_cookie;

void __attribute__ ((constructor)) __vtxor_cookie_setup(void) {

// Default value... if the read fails...

int fd=open("/dev/urandom",O_RDONLY);
if (fd>=0) {


LLVM ptatch, libvtxor code and test examples can be found here: /my-stuff/security/vtxor

Feel free to hack it and potentially try to include it in llvm trunk :)

Fermin J. Serna - @fjserna

Comments (0)