Code Reuse Ten Years Later: A Study on Gadget Finding

The Dynamics of Innocent Flesh on the Bone:
Code Reuse Ten Years Later
Victor van der Veen
, Dennis Andriesse, Manolis Stamatogiannakis,
Xi Chen
, Herbert Bos, and Cristiano Giuffrida
Vrije Universiteit Amsterdam
Microsoft
Takeaway
 
1)
Gadget finding:                 analysis
2)
Compare 
four
 classes of defenses
3)
Break
 the state-of-the-art
 
static
 
dynamic
 
Control-Flow Integrity | Information Hiding | Re-Randomization | Pointer Integrity
Static Flesh on the Bone
 
Shacham at CCS 2007
ret2libc
 without any function call
Combine short instruction sequences to build gadgets
The first systematic formulation of code reuse
 
 
Highly influential (900 citations)
CCS 2017 Test of Time Award
 
 
Return-Oriented Programming
Static Flesh on the Bone
 
Impact
Shaped how we think about code reuse:
1.
Analyze the 
geometry
 of victim binary code
2.
Locate gadgets
3.
Chain gadgets to craft an exploit
Initiated much research, almost an arms race
 
Discover gadgets by means of 
static
 analysis
Model never changed
Threat Model
 
Baseline
ASLR + DEP + Coarse-Grained CFI + Shadow stack 
(no classic ROP)
Attackers
Arbitrary memory read/write
Access to the binary
Goal is to divert control flow 
(no data-only attacks)
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
 
Victim binary code (
gadgets
)
Code-Reuse Research Loop
Attacker
1.
Analyze the program
Victim binary code (
gadgets
)
Code-Reuse Research Loop
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
Attacker
1.
Analyze the program
2.
Identify gadgets not covered by defenses
3.
Publish!
Victim binary code (
gadgets
)
Code-Reuse Research Loop
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
Defender
1.
Examine identified gadgets
Attacker
1.
Analyze the program
2.
Identify gadgets not covered by defenses
3.
Publish!
Defender
1.
Examine identified gadgets
2.
Invent a way to restrict those
3.
Publish!
Attacker
1.
Analyze the program
2.
Identify gadgets not covered by defenses
3.
Publish!
Victim binary code (
gadgets
)
Code-Reuse Research Loop
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
Victim binary code (
gadgets
)
Code-Reuse Research Loop
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
Defender
1.
Examine identified gadgets
2.
Invent a way to restrict those
3.
Publish!
Attacker
1.
Analyze the program
2.
Identify gadgets not covered by defenses
3.
Publish!
Victim binary code (
gadgets
)
Code-Reuse Research Loop
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbp
push   %rbx
mov    %edi,%ebx
mov    %rsi,%rbp
sub    $0x388,%rsp
mov    (%rsi),%rdi
mov    %fs:0x28,%rax
mov    %rax,0x378(%rsp)
xor    %eax,%eax
callq  40db00
mov    $0x419ac1,%esi
mov    $0x6,%edi
callq  402840
mov    $0x4165f1,%esi
mov    $0x4165da,%edi
callq  4024b0
mov    $0x4165da,%edi
callq  402470
mov    $0x40a320,%edi
movl   $0x2,0x21bb18(%rip)
callq  413c30
movabs $0x8000000000000000,%rax
movl   $0x0,0x21c5af(%rip)
movb   $0x1,0x21c650(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
mov    %rax,0x21c701(%rip)
mov    0x21bad7(%rip),%eax
movq   $0x0,0x21c700(%rip)
movq   $0xffffffffffffffff,0x21c6ed(%rip)
movb   $0x0,0x21c646(%rip)
cmp    $0x2,%eax
je     403328
cmp    $0x3,%eax
je     402aef
sub    $0x1,%eax
je     402aca
callq  402370
mov    $0x1,%edi
callq  4023e0
test   %eax,%eax
je     4035a6
movl   $0x2,0x21c672(%rip)
movb   $0x1,0x21c60b(%rip)
jmp    402b05
mov    $0x7,%esi
xor    %edi,%edi
movl   $0x0,0x21c658(%rip)
callq  40eca0
mov    $0x416603,%edi
movl   $0x0,0x21c640(%rip)
movl   $0x0,0x21c632(%rip)
movb   $0x0,0x21c62a(%rip)
movb   $0x0,0x21c621(%rip)
movb   $0x0,0x21c619(%rip)
movl   $0x0,0x21c5f7(%rip)
movb   $0x0,0x21c5d8(%rip)
movl   $0x1,0x21c5ca(%rip)
movb   $0x0,0x21c5c1(%rip)
movb   $0x0,0x21c5b9(%rip)
movl   $0x0,0x21c5aa(%rip)
movq   $0x0,0x21c597(%rip)
movq   $0x0,0x21c584(%rip)
movb   $0x0,0x21c602(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402bbf
mov    $0x4,%ecx
mov    $0x419200,%edx
mov    $0x419240,%esi
mov    %rax,%rdi
callq  409f70
test   %eax,%eax
js     403343
cltq
xor    %edi,%edi
mov    0x419200(,%rax,4),%esi
callq  40eca0
mov    $0x416611,%edi
movq   $0x50,0x21c501(%rip)
callq  402310
test   %rax,%rax
mov    %rax,%r12
je     402be5
cmpb   $0x0,(%rax)
jne    403564
lea    0x30(%rsp),%rdx
xor    %eax,%eax
mov    $0x5413,%esi
mov    $0x1,%edi
Defender
1.
Examine identified gadgets
2.
Invent a way to restrict those
3.
Publish!
Attacker
1.
Analyze the program
2.
Identify gadgets not covered by defenses
3.
Publish!
Mindset of Defenders (Academics)
 
Assume static analysis for gadget retrieval, we
Constrained control-flow transfers (CFI)
(re)Randomize code + data
Enforce pointer integrity
 
State of the Art of War
Not many gadgets left (millions > thousands > dozens)
Remaining gadgets are hard to find
Code-reuse attacks are hard
Mindset of Attackers (real world)
 
Attackers
Do not care
 about gadgets or ROP chains 
or Turing completeness
Only need to call 
execve
 or 
mprotect
 with controllable args
Have 
no reason
 to limit themselves to static analysis
 
What memory values should I modify to gain control?
 
Model this with Dynamic Taint Analysis
 
 
Change the Model
Dynamic Analysis
 
What memory values should I modify to gain control?
1.
Get the destination binary into a 
quiescent
 state​
2.
Taint
 attacker-controlled bytes (all of rw memory)
3.
Monitor branches – 
taint sinks 
– that depend on tainted memory
      
Callsite target + arguments
4.
Dump 
taint source 
for each sink
Modeling Code-Reuse Defenses
 
What memory values can I modify?
Arbitrary memory write: 
anything in data memory
Code pointers
Data pointers
Other values (integers, characters, …)
 
A defense may limit what we can corrupt
With Code Pointer Integrity, I cannot modify 
any
 pointer
Write constraints
Modeling Code-Reuse Defenses
 
What can I target?
Arbitrary memory read: 
any function in code memory
All functions of the target binary
All functions of libc
+ any other library
 
A defense may limit what we can target
With Control-Flow Integrity, I can only target a subset of all functions
Target constraints
Automated gadget finding with Dynamic Analysis
Newton Gadget
Callsite 
cs
 is tainted by 
addresses
 
and may call 
function
Newton
Dynamic analysis
Binary
+
libraries
Static analysis
Target constraints
Write constraints
Newton
Gadgets
Newton in Practice (on nginx)
 
Scenario 1/4
Baseline
 
Target constraints
None – we can target anything
 
Write constraints
None – we can corrupt everything
Baseline
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
Memory map
Baseline
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_conf_t 
*conf; 
GET / HTTP/1.0
Memory map
*conf
Baseline
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_conf_t 
*conf;
conf->
handler
 
=
 
ngx_proxy_handler
;
GET / HTTP/1.0
Memory map
*conf
Baseline
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_conf_t 
*conf;
conf->
handler
 
=
 
ngx_proxy_handler
;
GET / HTTP/1.0
Memory map
*conf
Quiescent State
Minimal set of interaction
Server is stable
Only long-lived data in memory
Baseline
Memory map
*conf
 
Quiescent State
[newton] $>
 taint-all-memory
 
Baseline
Memory map
*conf
 
Quiescent State
[newton] $>
 taint-all-memory
[newton] $> 
monitor-indirect-calls
GET / HTTP/1.0
 
Quiescent State
[newton] $>
 taint-all-memory
[newton] $> 
monitor-indirect-calls
GET / HTTP/1.0
 
ngx_http_request_r 
*r;
r->
content_handler 
=
 
conf->
handler
;
Baseline
Memory map
*conf
*r
 
Quiescent State
[newton] $>
 taint-all-memory
[newton] $> 
monitor-indirect-calls
GET / HTTP/1.0
 
ngx_http_request_r 
*r;
r->
content_handler 
=
 
conf->
handler
;
r->
content_handler
(r)
Baseline
Memory map
*conf
*r
Baseline
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_conf_t 
*conf;
conf->
handler
 
=
 
ngx_proxy_handler
;
GET / HTTP/1.0
Memory map
*conf
Quiescent State
Arbitrary memory read/write
Baseline
Baseline
Memory map
*conf
 
Quiescent State
Let 
conf->
handler
 
point to 
system
()
Baseline
Memory map
*conf
 
Quiescent State
Let 
conf->
handler
 
point to 
system
()
Send 
GET
 request
Baseline
Memory map
*conf
*r
 
Quiescent State
Let 
conf->
handler
 
point to 
system
()
Send 
GET
 request
 
ngx_http_request_r 
*r;
r->
content_handler
 
=
 
conf->
handler
;
Baseline
Memory map
*conf
*r
 
Quiescent State
Let 
conf->
handler
 
point to 
system
()
Send 
GET
 request
 
ngx_http_request_r 
*r;
r->
content_handler
 
=
 
conf->
handler
;
r->
content_handler
(r);
Newton in Practice (on nginx)
Scenario 1/4
Baseline
Target constraints
None – we can target anything
Write constraints
None – we can corrupt everything
Newton in Practice (on nginx)
 
Scenario 2/4
Baseline + eXecute-not-Read (XnR)
 
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
None – we can corrupt everything
Memory map
*conf
Minimal set of interaction
Server is stable
Only long-lived data in
memory
eXecute-not-Read
Quiescent State
Quiescent State
Memory map
*conf
Minimal set of interaction
Server is stable
Only long-lived data in
memory
eXecute-not-Read
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
[newton] $> 
monitor-indirect-calls
Memory map
*conf
Minimal set of interaction
Server is stable
Only long-lived data in
memory
eXecute-not-Read
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $> taint-all-memory
[newton] $> monitor-indirect-calls
Scan data memory for code pointers
Memory map
*conf
conf->handler
eXecute-not-Read
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $> taint-all-memory
[newton] $> monitor-indirect-calls
Scan data memory for code pointers
.data 
| heap | stack | 
.GOT 
| …
Typical nginx run: 
767
 live code pointers
Memory map
*conf
conf->handler
eXecute-not-Read
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $> taint-all-memory
[newton] $> monitor-indirect-calls
Scan data memory for code pointers
.data 
| heap | stack | 
.GOT 
| …
Typical nginx run: 
767
 live code pointers
Including 
mprotect()
Memory map
*conf
Minimal set of interaction
Server is stable
Only long-lived data in
memory
eXecute-not-Read
Quiescent State
Quiescent State
Arbitrary memory read/write
Baseline + XnR
Memory map
*conf
 
Quiescent State
Let 
conf
->
handler
 
point to 
mprotect
()
Send 
GET
 request
eXecute-not-Read
Memory map
*conf
eXecute-not-Read
*r
Quiescent State
Let 
conf
->
handler
 
point to 
mprotect
()
Send 
GET
 request
ngx_http_request_r 
*r;
 
Quiescent State
Let 
conf
->
handler
 
point to 
mprotect
()
Send 
GET
 request
 
ngx_http_request_r 
*r;
r->
content_handler 
=
 
conf->
handler
;
r->
content_handler
(r);
Memory map
*conf
eXecute-not-Read
*r
Newton in Practice (on nginx)
Scenario 2/4
Baseline + eXecute-not-Read (XnR)
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
None – we can corrupt everything
Newton in Practice (on nginx)
 
Scenario 3/4
Baseline + XnR + Cryptographic CFI (CCFI)
 
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
We can corrupt everything, 
except
 
code
 pointers
Cryptographic CFI
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
Memory map
Cryptographic CFI
Memory map
*ls
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_listening_t 
*ls;
ls->
handler
 
=
 
http_init_connection
;
Cryptographic CFI
Memory map
*ls
*lc
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_listening_t 
*ls;
ls->
handler
 
=
 
http_init_connection
;
ngx_connection_t
 *lc;
lc->
listening
 = ls
Cryptographic CFI
Memory map
*ls
*lc
Quiescent State
Quiescent State
Cryptographic CFI
Memory map
*ls
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
*lc
Cryptographic CFI
Memory map
*ls
*lc
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
[newton] $> 
taint-wash-code-pointers
 
Cryptographic CFI
Memory map
*ls
*lc
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
[newton] $> 
taint-wash-code-pointers
[newton] $> 
monitor-indirect-calls
GET / HTTP/1.0
 
lc->
listening-
>
handler
(c);
Cryptographic CFI
Memory map
*ls
Quiescent State
*lc
Quiescent State
Arbitrary memory read/write
Baseline + XnR + CCFI
Cryptographic CFI
Memory map
*ls
*lc
 
Quiescent State
Construct counterfeit 
ls
 object
Cryptographic CFI
Memory map
*ls
*lc
 
Quiescent State
Construct counterfeit 
ls
 object
Corrupt 
lc->
listening
 
data
 pointer
(make it point to our 
ls
)
Cryptographic CFI
Memory map
*ls
*lc
 
Quiescent State
Construct counterfeit 
ls
 object
Corrupt 
lc->
listening
 
data
 pointer
(make it point to our 
ls
)
Send 
GET
 request
 
lc->
listening
->
handler
(lc);
Newton in Practice (on nginx)
Scenario 3/4
Baseline + XnR + CCFI
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
We can corrupt everything, 
except
 
code
 pointers
Newton in Practice (on nginx)
 
Scenario 4/4
Baseline + XnR + CPI
 
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
We can corrupt everything, 
except
 
code
 and 
data
 pointers
Code-Pointer Integrity
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
Memory map
Code-Pointer Integrity
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_http_log_op_s 
*ops;
Memory map
*ops
Code-Pointer Integrity
Memory map
 
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
 
ngx_http_log_op_s 
*ops;
ngx_http_variable_t 
*v; // array
ops->
data
 
=
 
0
;
*ops
*v
Code-Pointer Integrity
Memory map
 
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
 
ngx_http_log_op_s 
*ops;
ngx_http_variable_t 
*v; // array
ops->
data
 
=
 
0
;
v[
i
].
get_handler 
= 
ngx_...
 
*ops
*v
Code-Pointer Integrity
Memory map
$>
 
./nginx localhost
$>
 
nc -v localhost 80
Connection to localhost 80 port [tcp/http] succeeded!
ngx_http_log_op_s 
*ops;
ngx_http_variable_t 
*v; // array
ops->
data
 
=
 
0
;
v[
i
].
get_handler 
= 
ngx_...
*ops
*v
Code-Pointer Integrity
Memory map
Quiescent State
*ops
*v
Quiescent State
Code-Pointer Integrity
Memory map
 
Quiescent State
[newton] $> 
get-live-code-pointers
*ops
*v
Code-Pointer Integrity
Memory map
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
*ops
*v
Code-Pointer Integrity
Memory map
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
[newton] $> 
taint-wash-code-pointers
*ops
*v
Code-Pointer Integrity
Memory map
 
Quiescent State
[newton] $> 
get-live-code-pointers
[newton] $>
 taint-all-memory
[newton] $> 
taint-wash-code-pointers
[newton] $> 
taint-wash-data-pointers
[newton] $> 
monitor-indirect-calls
GET / HTTP/1.0
v[
index
].
get_handler
(r, ...);
*ops
*v
Code-Pointer Integrity
Memory map
Quiescent State
*ops
*v
Quiescent State
Arbitrary memory read/write
Baseline + XnR + CPI
Code-Pointer Integrity
Memory map
 
Quiescent State
Overwrite 
data
 field in 
ops
*ops
*v
Code-Pointer Integrity
Quiescent State
Overwrite 
data
 field in 
ops
data = 3;
Memory map
*ops
*v
Code-Pointer Integrity
Quiescent State
Overwrite 
data
 field in 
ops
data = 4;
Memory map
*ops
*v
Code-Pointer Integrity
 
Quiescent State
Overwrite 
data
 field in 
ops
data = 5;
Send
 GET 
request
 
v[
5
].
get_handler
(r, ...);
Memory map
*ops
*v
Newton in Practice (on nginx)
Scenario 4/4
Baseline + XnR + CPI
Target constraints
No access to code pages
Only target 
live
 code pointers
Write constraints
We can corrupt everything, 
except
 
code
 and 
data
 pointers
Newton in Practice
Controlling arguments
Examples only show how to divert control-flow
Use the same mechanics for 
arguments
Modeling Defenses
30 defenses
 
IFCC, MCFI, TypeArmor, PerInput, PathArmor, GRIFFIN, FlowGuard, kBouncer, ROPecker Oxymoron,
Readactor
, 
XnR
, 
HideM
, 
LR
2
, 
Khide
, 
kR^X
, 
Heisenbyte
, 
NEAR, Readactor++,
CodeArmor, Shuffler, ReRanz, TASR, ASR3, RuntimeASLR, ASLR-Guard, Cryptographic CFI, CPS, CPI
8 target constraints
3 write constraints
Equivalence classes!
Write constraints
Target constraints
Controllable Callsites for nginx
Controllable Callsites for nginx
Controllable Callsites for nginx
Controllable Callsites for nginx
 
 
 
 
 
 
 
 
Minimal coverage with 
GET / HTTP/1.0
One callsite can be enough
Context-Sensitive CFI
#Allowed Targets for nginx
#Allowed Targets for nginx
ASLR + Shadow Stack + Coarse-grained CFI
#Allowed Targets for nginx
Readactor, XnR, HideM, LR
2
, Khide, kR^X, Heisenbyte, NEAR, Shuffler, CodeArmor, ReRanz, TASR, ASR3, RuntimeASLR, ASLR-Guard, Cryptographic CFI, CPS, CPI
#Allowed Targets for nginx
Enforced statically: results are for the 
median
 callsite
Similar Results for Other Servers
Conclusion
 
10 years of code-reuse
Crafting code-reuse attacks is hard
Attacks and defenses assume 
static
 analysis
Newton
Consider the 
dynamics
 and find that there is still leeway
Use reported gadgets to compare defenses
The next 10 years of code-reuse
Combine state-of-the-art defenses to reduce exploitability
Reduce overhead of more heavyweight defenses
https://vusec.net/newton
BACKUP SLIDES
Our Policy
Open source everything
Segregated State
 
Context-Sensitive CFI (CsCFI)
Target constraints are impractical:
How does the context-sensitive analysis works?
What is the branch history size?
When is validation performed?
Perfect 
CsCFI: arbitrarily large history, but 
not unlimited
Write constraint
Limit writes to a segregated state
Segregated State
 
Bypassing Context-Sensitive CFI (CsCFI)
1.
Corrupt an independent and stable application state
2.
Send idempotent inputs that do not interfere with the state
3.
Send final input to trigger exploit setup in 1)
 
Bypassing CsCFI in practice
Multiple connections handled by a single process
Connection-specific data of connection 1 as segregated state
Perform requests over connection 2 to flush history
Segregated
History flushing
Evaluating nginx – Target Constraints
Modeling Defenses
 
Control-Flow Integrity
Limits the valid targets for a callsite
4 types of target constraints
Bypass context-Sensitive CFI with history flushing: write constraint
 
Information Hiding
Prevent code-reuse by hiding gadgets: no write constraint
3 types of target constraints around 
live
 
IFCC, MCFI, TypeArmor, PerInput, PathArmor, GRIFFIN, FlowGuard, kBouncer, ROPecker
 
Oxymoron, Readactor
, 
XnR
, 
HideM
, 
LR
2
, 
Khide
, 
kR^X
, 
Heisenbyte
, 
NEAR, Readactor++, CodeArmor
Modeling Defenses
 
Re-Randomization
Hide code-layout: only 
live
 targets
3 classes of write constraints: 
none
, 
¬CPtr
, 
¬Ptr
 
Pointer Integrity
Cannot craft new pointers: only 
live
 targets
3 classes of write constraints: 
none
, 
¬CPtr
, 
¬Ptr
 
Shuffler, CodeArmor, ReRanz, TASR, ASR3, RuntimeASLR
 
ASLR-Guard, Cryptographic CFI, CPS, CPI
Bounds checking in CPI
(Oct. 30)
 “CPI does (SoftBounds-style) bounds checking”
CPI paper is not explicit on this topic
Attacks work for simple toy programs compiled with 
–fcpi
Currently investigating, will update paper if necessary
Implementation bug: only protected writes, but not reads?
https://vusec.net/newton
Slide Note
Embed
Share

This study by Victor van der Veen and team from Vrije Universiteit Amsterdam, along with Xi Chen from Microsoft, delves into the dynamics of innocent flesh on the bone in the context of code reuse. The researchers focus on gadget finding and provide valuable insights through their analysis.


Uploaded on Aug 08, 2024 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. The Dynamics of Innocent Flesh on the Bone: Code Reuse Ten Years Later Victor van der Veen, Dennis Andriesse, Manolis Stamatogiannakis, Xi Chen , Herbert Bos, and Cristiano Giuffrida Vrije Universiteit Amsterdam Microsoft

  2. Takeaway 1) Gadget finding: analysis 2) Compare four classes of defenses Control-Flow Integrity | Information Hiding | Re-Randomization | Pointer Integrity static dynamic 3) Break the state-of-the-art

  3. Static Flesh on the Bone Shacham at CCS 2007 ret2libc without any function call Combine short instruction sequences to build gadgets The first systematic formulation of code reuse Return-Oriented Programming Highly influential (900 citations) CCS 2017 Test of Time Award

  4. Static Flesh on the Bone Impact Shaped how we think about code reuse: 1. Analyze the geometry of victim binary code 2. Locate gadgets 3. Chain gadgets to craft an exploit Initiated much research, almost an arms race Model never changed Discover gadgets by means of static analysis

  5. Threat Model Baseline ASLR + DEP + Coarse-Grained CFI + Shadow stack (no classic ROP) Attackers Arbitrary memory read/write Access to the binary Goal is to divert control flow (no data-only attacks)

  6. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program

  7. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program 2. Identify gadgets not covered by defenses 3. Publish!

  8. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program 2. Identify gadgets not covered by defenses 3. Publish! Defender 1. Examine identified gadgets

  9. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program 2. Identify gadgets not covered by defenses 3. Publish! Defender 1. Examine identified gadgets 2. Invent a way to restrict those 3. Publish!

  10. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program 2. Identify gadgets not covered by defenses 3. Publish! Defender 1. Examine identified gadgets 2. Invent a way to restrict those 3. Publish!

  11. push %r15 push %r14 push %r13 push %r12 push %rbp push %rbx mov %edi,%ebx mov %rsi,%rbp sub $0x388,%rsp mov (%rsi),%rdi mov %fs:0x28,%rax mov %rax,0x378(%rsp) xor %eax,%eax callq 40db00 mov $0x419ac1,%esi mov $0x6,%edi callq 402840 mov $0x4165f1,%esi mov $0x4165da,%edi callq 4024b0 mov $0x4165da,%edi callq 402470 mov $0x40a320,%edi movl $0x2,0x21bb18(%rip) callq 413c30 movabs $0x8000000000000000,%rax movl $0x0,0x21c5af(%rip) movb $0x1,0x21c650(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) mov %rax,0x21c701(%rip) mov 0x21bad7(%rip),%eax movq $0x0,0x21c700(%rip) movq $0xffffffffffffffff,0x21c6ed(%rip) movb $0x0,0x21c646(%rip) cmp $0x2,%eax je 403328 cmp $0x3,%eax je 402aef sub $0x1,%eax je 402aca callq 402370 mov $0x1,%edi callq 4023e0 test %eax,%eax je 4035a6 movl $0x2,0x21c672(%rip) movb $0x1,0x21c60b(%rip) jmp 402b05 mov $0x7,%esi xor %edi,%edi movl $0x0,0x21c658(%rip) callq 40eca0 mov $0x416603,%edi movl $0x0,0x21c640(%rip) movl $0x0,0x21c632(%rip) movb $0x0,0x21c62a(%rip) movb $0x0,0x21c621(%rip) movb $0x0,0x21c619(%rip) movl $0x0,0x21c5f7(%rip) movb $0x0,0x21c5d8(%rip) movl $0x1,0x21c5ca(%rip) movb $0x0,0x21c5c1(%rip) movb $0x0,0x21c5b9(%rip) movl $0x0,0x21c5aa(%rip) movq $0x0,0x21c597(%rip) movq $0x0,0x21c584(%rip) movb $0x0,0x21c602(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402bbf mov $0x4,%ecx mov $0x419200,%edx mov $0x419240,%esi mov %rax,%rdi callq 409f70 test %eax,%eax js 403343 cltq xor %edi,%edi mov 0x419200(,%rax,4),%esi callq 40eca0 mov $0x416611,%edi movq $0x50,0x21c501(%rip) callq 402310 test %rax,%rax mov %rax,%r12 je 402be5 cmpb $0x0,(%rax) jne 403564 lea 0x30(%rsp),%rdx xor %eax,%eax mov $0x5413,%esi mov $0x1,%edi Victim binary code (gadgets) Code-Reuse Research Loop Attacker 1. Analyze the program 2. Identify gadgets not covered by defenses 3. Publish! Defender 1. Examine identified gadgets 2. Invent a way to restrict those 3. Publish!

  12. Mindset of Defenders (Academics) Assume static analysis for gadget retrieval, we Constrained control-flow transfers (CFI) (re)Randomize code + data Enforce pointer integrity State of the Art of War Not many gadgets left (millions > thousands > dozens) Remaining gadgets are hard to find Code-reuse attacks are hard

  13. Mindset of Attackers (real world) Attackers Do not care about gadgets or ROP chains or Turing completeness Only need to call execve or mprotect with controllable args Have no reason to limit themselves to static analysis What memory values should I modify to gain control? Change the Model Model this with Dynamic Taint Analysis

  14. Dynamic Analysis What memory values should I modify to gain control? 1. Get the destination binary into a quiescentstate 2. Taint attacker-controlled bytes (all of rw memory) 3. Monitor branches taint sinks that depend on tainted memory Callsite target + arguments 4. Dump taint source for each sink

  15. Modeling Code-Reuse Defenses Write constraints What memory values can I modify? Arbitrary memory write: anything in data memory Code pointers Data pointers Other values (integers, characters, ) A defense may limit what we can corrupt With Code Pointer Integrity, I cannot modify any pointer

  16. Modeling Code-Reuse Defenses Target constraints What can I target? Arbitrary memory read: any function in code memory All functions of the target binary All functions of libc + any other library A defense may limit what we can target With Control-Flow Integrity, I can only target a subset of all functions

  17. Newton Automated gadget finding with Dynamic Analysis Target constraints Write constraints Binary + libraries Newton Gadgets Dynamic analysis Static analysis Newton Gadget Callsite cs is tainted by addresses and may call function

  18. Newton in Practice (on nginx) Scenario 1/4 Baseline Target constraints None we can target anything Write constraints None we can corrupt everything

  19. Memory map nginx.text Baseline nginx.data $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] [unmapped] libc.text libc.ro libc.data

  20. Memory map nginx.text Baseline nginx.data *conf $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] [unmapped] ngx_conf_t *conf; GET / HTTP/1.0 libc.text libc.ro libc.data

  21. Memory map nginx.text Baseline nginx.data *conf $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] [unmapped] ngx_conf_t *conf; conf->handler = ngx_proxy_handler; libc.text libc.ro GET / HTTP/1.0 libc.data

  22. Memory map nginx.text Baseline nginx.data *conf Quiescent State $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! Minimal set of interaction Server is stable Only long-lived data in memory [heap] [unmapped] ngx_conf_t *conf; conf->handler = ngx_proxy_handler; libc.text libc.ro GET / HTTP/1.0 libc.data

  23. Memory map nginx.text Baseline nginx.data *conf Quiescent State [newton] $> taint-all-memory [heap] [unmapped] libc.text libc.ro libc.data

  24. Memory map nginx.text Baseline nginx.data *conf Quiescent State [newton] $> taint-all-memory [newton] $> monitor-indirect-calls GET / HTTP/1.0 [heap] [unmapped] libc.text libc.ro libc.data

  25. Memory map nginx.text Baseline nginx.data *conf Quiescent State [newton] $> taint-all-memory [newton] $> monitor-indirect-calls GET / HTTP/1.0 [heap] *r [unmapped] libc.text ngx_http_request_r *r; r->content_handler = conf->handler; libc.ro libc.data

  26. Memory map nginx.text Baseline nginx.data *conf Quiescent State [newton] $> taint-all-memory [newton] $> monitor-indirect-calls GET / HTTP/1.0 [heap] *r [unmapped] libc.text ngx_http_request_r *r; r->content_handler = conf->handler; r->content_handler(r) libc.ro libc.data

  27. Memory map nginx.text Baseline nginx.data *conf Quiescent State $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! Arbitrary memory read/write Baseline [heap] [unmapped] ngx_conf_t *conf; conf->handler = ngx_proxy_handler; libc.text libc.ro GET / HTTP/1.0 libc.data

  28. Memory map nginx.text Baseline nginx.data *conf Quiescent State Let conf->handlerpoint to system() [heap] [unmapped] libc.text libc.ro libc.data

  29. Memory map nginx.text Baseline nginx.data *conf Quiescent State Let conf->handlerpoint to system() Send GET request [heap] [unmapped] libc.text system() libc.ro libc.data

  30. Memory map nginx.text Baseline nginx.data *conf Quiescent State Let conf->handlerpoint to system() Send GET request [heap] *r [unmapped] ngx_http_request_r *r; r->content_handler = conf->handler; libc.text system() libc.ro libc.data

  31. Memory map nginx.text Baseline nginx.data *conf Quiescent State Let conf->handlerpoint to system() Send GET request [heap] *r [unmapped] ngx_http_request_r *r; r->content_handler = conf->handler; r->content_handler(r); libc.text system() libc.ro libc.data

  32. Newton in Practice (on nginx) Scenario 1/4 Baseline Target constraints None we can target anything Write constraints None we can corrupt everything

  33. Newton in Practice (on nginx) Scenario 2/4 Baseline + eXecute-not-Read (XnR) Target constraints No access to code pages Only target live code pointers Write constraints None we can corrupt everything

  34. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State [heap] Quiescent State [unmapped] libc.text Minimal set of interaction Server is stable Only long-lived data in memory libc.ro libc.data

  35. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [newton] $> monitor-indirect-calls [heap] [unmapped] libc.text Minimal set of interaction Server is stable Only long-lived data in memory libc.ro libc.data

  36. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [newton] $> monitor-indirect-calls Scan data memory for code pointers [heap] [unmapped] libc.text Minimal set of interaction Server is stable Only long-lived data in memory libc.ro libc.data

  37. Memory map nginx.text eXecute-not-Read nginx.data *conf conf->handler Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [newton] $> monitor-indirect-calls Scan data memory for code pointers .data | heap | stack | .GOT | Typical nginx run: 767 live code pointers [heap] [unmapped] libc.text libc.ro libc.data

  38. Memory map nginx.text eXecute-not-Read nginx.data *conf conf->handler Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [newton] $> monitor-indirect-calls Scan data memory for code pointers .data | heap | stack | .GOT | Typical nginx run: 767 live code pointers Including mprotect() [heap] [unmapped] mprotect() libc.text libc.ro libc.data

  39. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent StateQuiescent State Arbitrary memory read/write Baseline + XnR [heap] [unmapped] libc.text Minimal set of interaction Server is stable Only long-lived data in memory libc.ro libc.data

  40. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State Let conf->handlerpoint to mprotect() Send GET request [heap] [unmapped] mprotect() libc.text libc.ro libc.data

  41. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State Let conf->handlerpoint to mprotect() Send GET request [heap] *r [unmapped] mprotect() ngx_http_request_r *r; libc.text libc.ro libc.data

  42. Memory map nginx.text eXecute-not-Read nginx.data *conf Quiescent State Let conf->handlerpoint to mprotect() Send GET request [heap] *r [unmapped] mprotect() ngx_http_request_r *r; r->content_handler = conf->handler; r->content_handler(r); libc.text libc.ro libc.data

  43. Newton in Practice (on nginx) Scenario 2/4 Baseline + eXecute-not-Read (XnR) Target constraints No access to code pages Only target live code pointers Write constraints None we can corrupt everything

  44. Newton in Practice (on nginx) Scenario 3/4 Baseline + XnR + Cryptographic CFI (CCFI) Target constraints No access to code pages Only target live code pointers Write constraints We can corrupt everything, except code pointers

  45. Memory map nginx.text Cryptographic CFI nginx.data $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] [unmapped] libc.text libc.ro libc.data

  46. Memory map nginx.text Cryptographic CFI nginx.data *ls $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] [unmapped] ngx_listening_t *ls; ls->handler = http_init_connection; libc.text libc.ro libc.data

  47. Memory map nginx.text Cryptographic CFI nginx.data *ls $> ./nginx localhost $> nc -v localhost 80 Connection to localhost 80 port [tcp/http] succeeded! [heap] *lc [unmapped] ngx_listening_t *ls; ls->handler = http_init_connection; libc.text libc.ro ngx_connection_t *lc; lc->listening = ls libc.data

  48. Memory map nginx.text Cryptographic CFI nginx.data *ls Quiescent State [heap] *lc Quiescent State [unmapped] libc.text libc.ro libc.data

  49. Memory map nginx.text Cryptographic CFI nginx.data *ls Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [heap] *lc [unmapped] mprotect() libc.text libc.ro libc.data

  50. Memory map nginx.text Cryptographic CFI nginx.data *ls Quiescent State [newton] $> get-live-code-pointers [newton] $> taint-all-memory [newton] $> taint-wash-code-pointers [heap] *lc [unmapped] mprotect() libc.text libc.ro libc.data

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#