CS 519419 Cyber Attacks Defense Yeongjin Jang 011818
CS 519/419 Cyber Attacks & Defense Yeongjin Jang 01/18/18
Prerequisites • Registers • Little endian • 2’s complement
X 86/amd 64 registers 8 bit 16 bit 32 bit 64 bit A %al %ax %eax %rax B %bl %bx %ebx %rbx C %cl %cx %ecx %rcx 4 th D %dl %dx %edx %rdx 3 rd Destination %dil %di %edi %rdi 1 st Source %sil %si %esi %rsi 2 nd Stack %spl %sp %esp %rsp Base %bpl %bp %ebp %rbp Instruction $pc in GDB %rip Others %r 8 -%r 15 Amd 64 arg 5 -6 th for 8/9
Endianness • Order of bit representation of integer values • Big endian • Most significant bit (highest bit, e. g. , 31 th bit of 32 bit integer) comes first • 67305985 = 0 x 04030201 -> 0 x 04 0 x 03 0 x 02 0 x 01 • Little endian • Least significant bit (lowest bit, e. g. , 0 th bit of an integer) comes first • 67305985 = 0 x 04030201 -> 0 x 01 0 x 02 0 x 03 0 x 04
Intel Architecture • Both x 86 and amd 64 uses Little Endian • Why? • • • Suppose 0 x 000000001 is at the address of %rsp Value is 1; How to do the following assignments? long i = 1; int j = (int)i; short k = (short)i; char l = (char)i; mov (%esp), %al mov (%esp), %ax mov (%esp), %eax mov (%esp), %rax
Intel Architecture • Both x 86 and amd 64 uses Little Endian • • Reading a byte from an integer Access the value from 0(%rsp) Access the value from 0(%esp) Access the value from 0(%sp) 0 x 01 0 x 00 0(%rsp) 1(%rsp) 2(%rsp) %al 0 x 00 0 x 00 3(%rsp) 4(%rsp) 5(%rsp) 6(%rsp) 7(%rsp) %ah %ax %eax %rax
Intel Architecture • What if Big Endian? • • Reading a byte from an integer Access the value from 7(%rsp) Access the value from 3(%esp) Access the value from 1(%sp) 0 x 00 0(%rsp) 1(%rsp) 2(%rsp) 0 x 00 0 x 01 3(%rsp) 4(%rsp) 5(%rsp) 6(%rsp) 7(%rsp) %ah %al %ax %eax %rax
2’s complement • A way of representing signed numbers in binary format • For n-bit signed integer, its represented range is • 0 ~ 2^(n-1) - 1 for positive numbers • -1 ~ -2^(n-1) for negative numbers • Representation • Positive number X: as-is • E. g. , 1 -> 0 x 1 • Negative number X: 2^N + (X) • E. g. , -1 -> 2^32 + (-1) = 2^32 – 1 = 0 xffff = 1111 • E. g. , -2^31 = 2^32 + (-2^31) = 2^31 = 0 x 80000000 = 1000 0000 • The most significant bit indicates sign (1 for negative) • https: //en. wikipedia. org/wiki/Two%27 s_complement
Stack Buffer Overflow Local • Local variables reside on the stack • Overflowing local stack could affect on ebp/eip • Suppose 0 x 10(%ebp) is a string, char *s; %ebp FFFF 0 x 80484 e 8 Ret addr Saved EEEEebp DDDD CCCC • strcpy(s, “AAAABBBBCCCCDDDDEEEEFFFF”) %esp BBBB AAAA Not used. .
%ebp 0 x 4545 (EEEE) Function return • Leave • mov %ebp, %esp • pop %ebp Local %esp %ebp %esp • ret • Pop %eip • Now code executes at 0 x 4646 (FFFF) • Segmentation Fault (invalid address) FFFF 0 x 80484 e 8 Return addr Saved EEEEebp DDDD CCCC BBBB %esp AAAA Not used. .
Changing Return Address • What if we change the ‘saved return address’ to some function address? • Previously it was a “Segmentation Fault” • The processor will execute the function….
Changing Return Address Local • Program contains “execute_me()” function FFFF 0 x 80484 e 8 %ebp Ret addr Saved EEEEebp DDDD CCCC BBBB • Overwrite • “AAAABBBBCCCCDDDDEEEE” and then • The address of execute_me()! %esp AAAA Not used. .
Changing Return Address Local • Address: 0 x 804854 b FFFF 0 x 80484 e 8 • Binary string • 0 x 04030201 -> “x 01x 02x 03x 04” • Little endian! %ebp • Overwrite • “AAAABBBBCCCCDDDDEEEEx 4 bx 85x 04x 08” Ret addr Saved EEEEebp DDDD CCCC BBBB AAAA Not used. .
How to Write and Insert bin-string • Use python • python –c “print ‘x 41x 42x 43x 44’, ” • (The last comma will remove unnecessary newline) • Use shell command • Pipe • python –c “print ‘x 41x 42x 43x 44’, ” |. /stack-ovfl-32 • Or use redirection • python –c “print ‘x 41x 42x 43x 44’, ” > a. txt • . /stack-ovfl-32 < a. txt
Pwntools • A easy-to-use python toolkit that helps writing exploits • Just do • from pwn import * • Do dirty job like pipe and redirections (even for socket connections) • p = process(". /stack-ovfl-32") • p. sendline("asdfasdfx 01x 02x 03x 04") • Easily get symbols (function address) • JUMP_ADDR = p. elf. symbols['execute_me'] • p. sendline("A"*42 + p 32(JUMP_ADDR))
Useful commands • p = process(“. /stack-ovfl-32”) • Creates process for the program argument • p. elf. symbols[‘function_name’] • Get the address of function_name • p. sendline(string) • Send a string to the program • p. recv(timeout=s) • Read string from the program (with timeout s) • p. recvrepeat(s) • Read string for s seconds
Useful commands • p 64(integer) • Changes an integer value to 32 bit little endian bytes string • p 32(integer) • Changes an integer value to 32 bit little endian bytes string • hex(integer) • Changes an integer value to a hexadecimal string
Useful commands • cyclic(20) • Return a lexicographically increasing string • 'aaaabaaacaaadaaaeaaa’ • You will know where you need to change to overwrite return address…
A simple exploit for stack-ovfl-32
Debugging with Core • If program crashes, you can get a “Core dump” • Core dump is a memory and register dump at the point of crash • ulimit –c unlimited • This will set system to generate core dump on each crash • Work in a writable directory (challenge program runs as a different user) • mkdir tmp; chmod 777 tmp; cd tmp then run. . • Use gdb to read the core • gdb –-core=core
Attacking Frame Pointer Local • What if you can overwrite “saved %ebp” • But not the return address? 0 x 80484 e 8 %ebp Ret addr Saved EEEEebp DDDD CCCC BBBB AAAA Not used. .
%ebp 0 x 4545 (EEEE) Attacking Frame Pointer • On leave • Mov %ebp, %esp • Pop %ebp • EBP will be an invalid value • Return to the correct address (0 x 80484 e 8) Local %esp %ebp 0 x 80484 e 8 Ret addr Saved EEEEebp DDDD CCCC BBBB AAAA Not used. .
%esp %ebp 0 x 4545 (EEEE) Attacking Frame Pointer Local • When the caller returns (yellow local stack) • Leave again %esp • Mov %ebp, %esp (esp will be EEEE) • Pop %ebp (Segmentation fault!) • What happens if we change %ebp to a valid address? 0 x 80484 e 8 Ret addr Saved EEEEebp DDDD CCCC BBBB AAAA Not used. .
Attacking Frame Pointer Local • Changing %ebp to a valid address 0 x 80484 e 8 %ebp Ret addr The addr of Saved ebp AAAA DDDD CCCC BBBB AAAA Not used. .
Attacking Frame Pointer • On leave • Mov %ebp, %esp • Pop %ebp • EBP will point the address of “AAAA…” Local %esp %ebp • Then return to the correct address 0 x 80484 e 8 Ret addr The addr of Saved ebp AAAA DDDD CCCC BBBB %ebp AAAA Not used. .
%ebp 0 x 4141 (AAAA) Attacking Frame Pointer Local • When the caller returns (yellow local stack) • Leave again %esp • mov %ebp, %esp (%esp will be the address of AAAA) • pop %ebp (%ebp will be AAAA) Ret addr The addr of Saved ebp AAAA DDDD • Then, return • pop %eip • %eip will be BBBB! 0 x 80484 e 8 %esp %ebp CCCC BBBB AAAA Not used. .
Attacking Frame Pointer Local • Overwrite the stack as follows: • Write a controllable address to “saved ebp” • E. g. , address of AAAA • On the address + 4 of that saved ebp, • Write a return address 0 x 80484 e 8 Ret addr The addr of Saved ebp AAAA DDDD CCCC execute_me() AAAA Not used. .
%ebp 0 x 4141 (AAAA) Attacking Frame Pointer Local • When the caller returns (yellow local stack) • Leave again %esp • mov %ebp, %esp (%esp will be the address of AAAA) • pop %ebp (%ebp will be AAAA) 0 x 80484 e 8 Ret addr The addr of Saved ebp AAAA DDDD • Then, return %esp • pop %eip • %eip will be the addr of execute_me()! %esp %ebp CCCC execute_me() AAAA Not used. .
Assignment: Week-2 • Please solve challenges in the /home/labs/week 2 directory • Debug programs in the samples directory • These programs will not give you the flag • Get flags from programs in the challeges directory • Due: 1/30 4: 00 pm
- Slides: 29