Post Memory Corruption

Memory Analysis

Jonathan Brossard

CEO – Toucan System

[email protected]

Who am I ?

-Security Research Engineer at Toucan System

-Speaker at Blackhat, Defcon, HITB, H2HC, Kiwicon... and Ruxcon :)

-Organiser of the Hackito Ergo Sum conference (Paris).

-I'm the guy who comes to Ruxcon with 90+ slides...

I don't reverse plain text

Regarding webapps...

For webdev, XSS, CSS, Javacript ... ask Jeremiah Grossman during Ruxcon ;)


A few basics

Being environment aware

PMCMA Design

Extending Pmcma

Stack desynchronization

Tool available at

We got 10k downloads+ in

2 less than months...

(Note : Andrewg, thanks for your help, you can stop your bot now...)

What's pmcma ?

It's a debugger, for Linux (maybe one day *NIX) ptrace() based.

Pmcma allows to find and test exploitation scenarios.

Pmcma's output is a roadmap to exploitation, not exploit code.

Tells you if a given bug triggering an invalid memory access is a vulnerability, if it is exploitable with the state of the art, and how to exploit it.

What's pmcma ?


Coz you asked for it...

Remote stack overflow automated exploitation

NX/SSP (stack cookies)/ASLR/PIE/STATIC

GOT/Ascii Armoring...

=> No problem, easy cheesy : can be done with static analysis (of the libc/binary) only.


Now, let's move to the real



Seriously, can we skip this section ?

How do applications

crash ?

*Stack corruptions -> stack overflows, usually now detected because of SSP | studied a LOT

*Signal 6 -> assert(),abort(): unexpected execution paths (assert() in particular), heap corruptions

*Segfault (Signal 11) -> Invalid memory access

How do applications

crash ?

*Stack corruptions -> stack overflows, usually now detected because of SSP | studied a LOT

*Signal 6 -> assert(),abort(): unexpected execution paths (assert() in particular), heap corruptions

*Segfault (Signal 11) -> Invalid memory access

Invalid memory access

-trying to read a page not readable. often not mapped at all.

-trying to write to a page not writable. often not mapped at all.

-trying to execute a page not executable. often not mapped at all.

Why do they happen ?

Because of any kind of miscomputation, really :

-integer overflows in loop counters or destination registers when copying/initializing data, casting errors when extending registers or

-uninitialised memory, dangling pointers

-variable misuse

-heap overflows (when inadvertently overwriting a function ptr)

-missing format strings

-overflows in heap, .data, .bss, or any other writable section (including shared libraries).

-stack overflows when no stack cookies are present...

Exploiting invalid exec

Trivial, really. Eg :

call eax

with eax fully user controled

Invalid memory reads (1/2)

Eg :

CVE-2011-0761 (Perl)

cmp BYTE PTR [ebx+0x8],0x9

Invalid memory reads (2/2)

Eg :

CVE-2011-0764 (t1lib)

fld QWORD PTR [eax+0x8]

Exploiting invalid memory

reads ?

-usually plain not exploitable

-won't allow us to modify the memory of the mapping directly

-in theory : we could perform a user controled read, to trigger a second (better) bug.

Invalid memory writes

Eg :

CVE-2011-1824 (Opera)

mov DWORD PTR [ebx+edx*1],eax

How to...

To exploit invalid writes, we need to find ways to transform an arbitray write into an arbitrary exec.

The most obvious targets are function


Exploiting invalid memory

writes : scenario

-Target a known function pointer (typically : .dtors, GOT entry...).

Can be prevented at compile time :

no .dtors, static GOT...

-Target function pointers in the whole binary ?

-Overwrite a given location to trigger an other bug (eg : stack overflow)

Being environment aware

Problems to take into


-Kernel : ASLR ? NX ?

-Compilation/linking : RELRO (partial/full) ? no .dtors section ? SSP ?


=> Pmcma needs to mesure/detect those features


Major problem when chosing an exploitation strategy.

ASLR : not perfect

-Prelinking (default on Fedora) breaks ASLR

-All kernels don't have the same randomization strength.

-Non PIE binaries

=> Truth is : we need better tools to test it !

Testing ASLR

-Run a binary X times (say X=100) -Stop execution after loading

-Record mappings.

=> Compare mappings, deduce randomization

DEMO : being environment aware



-We want to test overwriting different memory locations inside a process and see if they have an influence over the flow of execution

-We want to scale to big applications (web browsers, network deamons...)

-We want a decent execution time


The idea :

-We start analysing after a SEGFAULT -We make the process fork() (many

many times)

-Inside each offspring, we overwrite a different memory location

mk_fork() : benefits

Mapping looks « just like » it will when actually exploiting a binary

No ASLR/mapping replication problem

Exhaustive and hopefully fast

How to force a process to

fork ?

1)Find a +X location mapped in memory.

2)Save registers

3)Use ptrace() to inject fork() shellcode.

4)Modify registers so eip points to shellcode.

5)Execute shellcode.

6)Wait() for both original process and offspring.

7)Restore bytes in both processes.

8)Restore registers in both processes.

Forking shellcode

;forking shellcode:

xor eax,eax





mov al,0x2



int 0x80