CS 519419 Cyber Attacks Defense Advanced ROP 110818
CS 519/419 Cyber Attacks & Defense Advanced ROP 11/08/18
32 bit • Arguments on the stack • [func][pop-N-ret][arg 1][arg 2][arg 3][…]
64 bit • Set argument first • • [pop rdi ret][arg 1] [pop rsi r 15 ret][arg 2][xxx] [pop rdx ret][arg 3] [pop rcx … ret][arg 4][xxx]… [pop r 8 … ret][arg 5][xxx]… [pop r 9 … ret][arg 6][xxx]… … • Then call func • [func]
Pop %rdx
Usual case
EXECVE() • 64 bit: execve(rdi = “xxxx”, rsi, rdx) • Requirements for rsi and rdx • argv and envp • 0 • There is no argument and environment variable at all • A pointer to • Array of string values • Ends with 0
EXECVE() • 64 bit: execve(rdi = “xxxx”, rsi, rdx) • Requirements for rsi and rdx • argv and envp • A pointer to • Array of string values • Ends with 0 • char **argv = {“arg 1”, “arg 2”, “arg 3”, 0} • char ** envp = {“PATH=. ”, “SHELL=/bin/bash”, 0}
EXECVE - TEST
EXECVE - TEST
EXECVE - TEST
EXECVE - TEST
EXECVE() • 64 bit: execve(rdi = “xxxx”, rsi, rdx) • Requirements for rsi and rdx • 0 • A pointer to 0 • A pointer that contains several pointers and ends with 0
How can we control rdx without pop rdx? • __libc_csu_init • Initializer for constructors in C program
ELF Execution Flow • __libc_start_main • Will call __libc_init_first -> __libc_init -> __libc_csu_init • __libc_csu_init • Call constructors in the program • Usually do not have constructors at all but this function resides in the program’s address space • Then call main()
Controlling RDX Set rdx, rsi, rdi and call execve!
Controlling RDX Set r 13 = 0 -> this will make rdx = 0 Set r 14 = 0 -> this will make rsi = 0 Set r 15 = string -> this will make rdi = r 15 (lower 4 bytes) Callq *(%r 12, %rbx, 8) r 15 d -> edi; we first can set rdi as some string address, and then set r 15 as the same value; In this case, mov %r 15 d, %rdi will have no meaning…
Controlling RDX What is the meaning of callq *(%r 12, %rbx, 8)? ? ? SYNTAX: (a, b, c) = a[b*c] func_ptr = r 12[rbx * 8] func_ptr()
Controlling RDX callq *(%r 12, %rbx, 8) func_ptr = r 12[rbx * 8] func_ptr() Example: Set rbx = 0 -> r 12[0] Meaning: Getting the value from the address pointed by r 12.
Controlling RDX callq *(%r 12, %rbx, 8) func_ptr = r 12[rbx * 8] func_ptr() Example: Set rbx = 0 -> r 12[0] Meaning: Getting the value from the address pointed by r 12. Action: Set r 12 = execve?
Controlling RDX callq *(%r 12, %rbx, 8) func_ptr = r 12[rbx * 8] func_ptr() Example: Set rbx = 0 -> r 12[0] r 12 = 0 x 4004 d 0 (execve) Action: r 12[0] = *(0 x 4004 d 0) = 0 x 0 b 5 a 25 ff Jump to 0 xb 5 a 25 ff -> SIGSEGV
Callq *(%r 12, %rbx, 8) • We need to set %r 12 as • An address that contains the address of execve() • WHAT? Is there any memory block for this? ? • YES
Procedure Linkage Table (PLT) • A program calls printf • Before running the program • Shows printf@plt, at the code section (0 x 400 XXX) • After running the program • Shows printf at the libc section (0 x 7 fa 174 b 06 XXX)
What is PLT? • To call a function, a program need to know the address • The program does not know the address of libc functions (e. g. , printf) • The ELF format let the program use a fixed address to call library function • That’s PLT! • Then, how does it work?
Reverse Engineering PLT • Disassemble • Jump to the address stored at 0 x 601030 • *0 x 601030 indicates the value in that address (because of *) • Maybe you wish to set %r 12 to 0 x 601030 to call printf…
Reverse Engineering PLT • What is in 0 x 601030? • 0 x 7 fa 174 b 06800
PLT and Global Offset Table (GOT) • 0 x 4005 a 0 (printf@plt) serve as a link to the printf in the libc • Calling 0 x 4005 a 0 -> jump to *0 x 601030 -> jump to printf() • -> calling printf() • 0 x 601030 is called as Global Offset Table (GOT) of printf • Program calls PLT • PLT jumps to the address stored in GOT • GOT stores the address in libc
ELF, PLT, GOT The program Calls a function In PLT printf() strcpy() read() Program printf() Libc printf() … strcpy() … read() … GOT libc_printf libc_strcpy GOT stores libc addr libc_read PLT jumps to GOT
ELF, PLT, GOT The program Calls a function In PLT printf() strcpy() read() Program printf() Libc printf() … strcpy() … read() … _dl_dynamic_resolve GOT 7 fa 174 b 06800 _resolve GOT stores addr of _dl_dynamic_resolve PLT jumps to GOT
Global Offset Table • Stored in the data section (i. e. , 0 x 8049 XXX or 0 x 6010 XX) • Fixed even if under ASLR if program is not PIE • Stores the address of _dl_dynamic_resolve at first • Once calling the function, it will store the function address in the libc area
Finding GOT • Readelf -a
Controlling RDX Set rdx, rsi, rdi and call execve!
Controlling RDX Set r 13 = 0 -> this will make rdx = 0 Set r 14 = 0 -> this will make rsi = 0 Set r 15 = string -> this will make rdi = r 15 (lower 4 bytes) Callq *(%r 12, %rbx, 8) Set r 12 = GOT of execve r 15 d -> edi; we first can set rdi as some string address, and then set r 15 as the same value; In this case, mov %r 15 d, %rdi will have no meaning…
Controlling RDX callq *(%r 12, %rbx, 8) func_ptr = r 12[rbx * 8] func_ptr() Example: Set rbx = 0 -> r 12[0] r 12 = 0 x 601030 (GOT of execve) Action: r 12[0] = *(0 x 601030) = addr of execve
Assignment: Week-5 • ASLR: connect to vm-ctf 2. eecs. oregonstate. edu • Use the same credentials (id, private key, etc. ) • Challenges are in /home/labs/week 5 • Use setup 5 • Due: 11/27 2: 00 pm
- Slides: 34