Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Software exploitation : ROP

Software exploitation : ROP

Introduction course on ROP techniques given to 3rd year Bachelor level students.
Corresponding code can be found at:

Julien Bachmann

June 04, 2015

More Decks by Julien Bachmann

Other Decks in Technology


  1. Software exploitation : ROP Julien Bachmann .text .global _start _start:

    push $5 pop %eax cltd pushl %edx push $0x79 push $0x656b2f2e movl %esp,%ebx pushl %ex pushl %ebx pushl %edx int $0x80 mov $100,%dl sub %edx,%esp mov %esp,%ecx xchg %eax,%ebx push %edx push %ecx push %ebx xorl %eax,%eax pushl %eax push $3 pop %eax int $0x80 movb $0xff,0x4(%esp) movl %eax,0xc(%esp)
  2. intro | me Julien Bachmann / @milkmix_ Currently Cyber Security

    Architect, Kudelski Security Guest lecturer at HEIG-VD & Uni-Biel on software exploitation techniques Guest lecturer at UNIMAIL on malware and incident response Past 6 years : SCRT & ilion Security Penetration tester Incident responder
  3. intro | about Pre-requisites Knowledges on operating systems internals C

    and x86 assembly Previous course on software exploitation basics Environment Linux with 32bits binaries No Windows, iOS or Android exploitation today :( Examples https://github.com/milkmix-/training/tree/master/rop
  4. intro | objectives Attack Understanding flaws impacting software Exploitation of

    those Defence Solutions to prevent trivial exploitation
  5. pwn | recaps Buffer overflow basics out-of-bound writes rewrite saved

    instructions pointer redirect process control flow execute shellcode
  6. pwn | recaps Testing $ ./bof_01 foobar ? $ ./bof_01

    AAAAAAAAAAAAAAA ? $ ./bof_01 `python -c ‘print “A”` ?
  7. pwn | recaps Stack state after call to strcpy() ...

    &input %eip %ebp AAAA AAAA AAAA %ebp ...
  8. pwn | recaps If input is more than 128 bytes

    ... AAAA AAAA AAAA AAAA AAAA AAAA %ebp ... return address argument
  9. pwn | recaps Calling convention previous example was using stdcall

    convention arguments pushed in reverse order on the stack callee clean the stack at the end spot it: ret imm16
  10. pwn | recaps Calling convention libc uses cdelc convention arguments

    pushed in reverse order on the stack caller clean the stack at the end spot it: ret
  11. pwn | tips Buffer size calculation In this example: get

    it by reversing the function IDA Pro tips Toolbox MSF pattern_{create, offset}.rb PEDA
  12. pwn | tips In order to learn exploitation concepts disable

    the protections Compilation -fno-stack-protector -z execstack OS echo 0 > /proc/sys/kernel/randomize_va_space
  13. pwn | tips To get a coredump once the process

    crash echo "core" > /proc/sys/kernel/core_pattern ulimit -c unlimited
  14. pwn | details In the previous example shellcode address more

    or less known possible to use nop-sled to secure the exploitation
  15. pwn | details 0xBFFFFFFF 0x00000000 argv[0] “/bin/sh” env[1] “PATH=...” env[0]

    “USER=...” argv[1] “--version” argv[0] “/bin/sh” 0x00000000 *envp *envp 0x00000000 *argp *argp local var **envp **argp argc @ret ebp ... $ /bin/sh --version
  16. pwn | details What if the address could not be

    calculated? ex: user controlled input stored on the heap Check for references at the moment you take control registers stack
  17. pwn | details RET 2 reg return to register find

    instruction redirecting control flow to stored value jmp eax call ecx
  18. pwn | details POP 2 RET context: address to user-controlled

    buffer is stored in the stack find pop instruction(s) followed by a ret instruction pop useless values ret
  19. pwn | details value @pop/ ret %ebp buffer ... ebp

    return address argument &input After the overflow
  20. pwn | details POP value @pop/ ret eip &input eip

    .section .text ... pop eax ret
  21. pwn | details RET value @pop/ ret eip &input eip

    .section .text ... pop eax ret
  22. protections | intro First example only works with all protections

    disabled less likely to happen nowadays maybe if you are lucky or exploiting an old system, … Protections on multiple layers compilation os
  23. protections | unsafe ops Unsafe memory copy operation ! leading

    to out-of-bound memory accesses strcpy, strcat, memcpy, gets, scanf, sprintf, realpath, …
  24. protections | unsafe ops Microsoft Safe String API generate compiler

    warnings while using those functions GCC #pragma GCC poison allows to generate error when identifier found in code https://github.com/leafsr/gcc-poison
  25. protections | unsafe ops GCC FORTIFY_SOURCE if that macro is

    enabled it checks for basic vulnerabilities compile time : static array copied using libc functions execution time : ___strcpy_chk -D_FORTIFY_SOURCE=1 -O2
  26. protections | unsafe ops Warning beware of home made memory

    operation functions my_memcopy using a loop …
  27. protections | intro What do you need to be able

    to modify the control flow in this example ?
  28. protections | canary Smash the stack ! need to be

    able to overwrite saved EIP other possibilities, but that will be for another course
  29. protections | canary Detect overflows use canaries, like in the

    mines pro-police in GCC -fstack-protector[strong/-all]
  30. protections | canary Canary generate random value at process start

    value written in the stack before local variables (simplest use-case) compiler inserts check before ret instruction
  31. protections | canary | bypass How to bypass this ?

    1. on Unix requires to know the value 2. could try a brute-force if entropy is too small 3. use a memory leak vulnerability to retrieve the value
  32. protections | nx Execution rights ! memory pages have access

    rights defined in the Page Table Entries check Intel Developer Manuals
  33. protections | nx History first implementations in August 2004 were

    software only ExecShield W^X PAX introduced by Intel in Pentium 4 serie NX bit
  34. protections | nx Concept memory pages should either contain data

    or code rare cases where both can mix ex: JIT compilers still, stack and heap can be marked as non-executable most of the time
  35. protections | nx Bypass we cannot add data in the

    process and then execute it so let’s use what is already present ! ret2libc rop
  36. protections | nx | ret2libc ret2libc context : stack is

    non-executable libc code is obviously executable instead of having a shellcode using syscalls, directly call libc functions
  37. protections | nx | ret2libc Concept forge a stack as

    the standard execution would stdcall convention rewrite execution pointer with function address
  38. protections | nx | ret2libc ret2libc!system @“/bin/sh” @system AAAA AAAA

    AAAA AAAA AAAA ... %ebp return address argument &input align
  39. protections | nx | rop ret2libc next level calling a

    function is fun but can’t we also directly use instructions or call multiples ? Return Oriented Programming (ROP)
  40. protections | nx | rop Dino Dai Zovi “preventing the

    introduction of malicious code is not enough to prevent the execution of malicious computations”
  41. protections | nx | rop Concept chain the execution of

    simple instructions already in the memory to execute code simple instructions are called gadgets and are ended by RET pop eax ; ret mov [ebx], ecx ; ret
  42. protections | nx | rop Beware specificity of CISC architecture

    (used by Intel processors) a list of opcodes doesn’t have only one representation possible to process them at various offsets concept not applicable on RISC architectures (ARM, MIPS, …)
  43. protections | nx | rop B8 89 41 08 C3

    mov eax, 0xc3084189 mov dword ptr [ecx+8], ecx ret
  44. protections | nx | rop usage examples write 4 (controlled)

    bytes at a controlled address call function chain functions calls
  45. protections | nx | rop pop eax ret pop ecx

    ret mov [ecx], eax ret + + = write 4 bytes
  46. protections | nx | rop In practice find the gadgets

    you need forge a stack containing their addresses : ROP chain redirect execution flow to your ROP chain
  47. protections | nx | rop Finding gadgets Write your own

    tools elfesteem / pefile / capstone idapython Existing tools ropeme, ropgagdet, rp++
  48. Taking our previous example protections | nx | rop mov

    dword ptr [ecx], eax 0x08049668 0xffffdee8
  49. protections | nx | rop Taking our previous example gadget1

    : pop eax ; ret gadget2 : pop ecx ; ret gadget3 : mov dword ptr [ecx], eax ; ret @gadget1 AAAA AAAA AAAA ... %ebp return address 0xffffdee8 @gadget2 0x08049668 @gadget3 …
  50. protections | nx | rop When vulnerable function returns eax

    = ?? ecx = ?? @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... mov eax, 42 ret
  51. protections | nx | rop After ret instruction eax =

    ?? ecx = ?? @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... pop eax ret
  52. protections | nx | rop After pop instruction eax =

    0xffffdee8 ecx = ?? @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... pop eax ret
  53. protections | nx | rop After ret instruction eax =

    0xffffdee8 ecx = ?? @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... pop ecx ret
  54. protections | nx | rop After pop instruction eax =

    0xffffdee8 ecx = 0x08049668 @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... pop ecx ret
  55. protections | nx | rop After ret instruction eax =

    0xffffdee8 ecx = 0x08049668 @gadget1 AAAA AAAA AAAA ... esp 0xffffdee8 @gadget2 0x08049668 @gadget3 … eip .section .text ... mov dword ptr [ecx], eax ret
  56. protections | nx | rop What are useful gadgets ?

    redirect execution to register stack-pivot set registers values read at a memory address write-what-where init syscall number syscall
  57. protections | nx | rop Stack pivoting we only spoke

    about stack based buffer overflow as such your controlled data is in the stack other types of exploits might not be as convenient ex: heap overflow
  58. protections | nx | rop Stack pivoting ROP chain should

    be in the stack need to change esp value to point to user controlled data
  59. protections | nx | rop Examples mov esp, eax ;

    ret xchg esp, eax ; ret add esp, #value ; ret
  60. protections | nx | rop Demonstration lets use variation of

    previous sample bof_01_static goal : exit with chosen value take your VM and follow along
  61. protections | nx | rop Step 4 : write functionality

    in assembly language .section .text mov eax, 1 mov ebx, 0x42424242 int 0x80
  62. protections | nx | rop Step 6 : define needed

    instructions int 0x80 xor eax, eax inc eax pop ebx
  63. protections | nx | rop Useful when debugging break at

    the end of the vulnerable function set gadget address to 0x41414141 and check the stack layout use si (step into) to go through every instruction
  64. protections | nx | rop Calling multiple functions remember that

    they are multiple calling conventions libc is mostly using cdecl which means that the caller has to clean the stack
  65. protections | nx | rop Calling multiple functions like we

    saw in ret2libc part read system @read AAAA AAAA AAAA ... %ebp return address 0x1 @buffer 1024 @buffer read args system args @system
  66. protections | nx | rop End of read @read AAAA

    AAAA AAAA ... %esp 0x1 @buffer 1024 @buffer .section .text read: ... ret eip @system
  67. protections | nx | rop Problem we don’t have the

    correct arguments what would help ? hint: think gadgets…
  68. protections | nx | rop Yes, something to clean the

    3 entries we have in the stack ! add esp, 0xc ; ret pop reg1 ; pop reg2 ; pop reg3 ; ret
  69. protections | nx | rop Calling multiple functions using a

    pop3ret read system @read AAAA … ... %ebp return address 0x1 @buffer 1024 @system @buffer read args system args @pop3ret align
  70. protections | nx | rop End of read @read AAAA

    … ... %esp 0x1 @buffer 1024 @system read args system args @pop3ret .section .text read: ... ret eip @buffer align
  71. protections | nx | rop Execution of pop3ret @read AAAA

    … ... %esp 0x1 @buffer 1024 @system system args @pop3ret .section .text …: pop eax pop ebx pop ecx ret eip @buffer align
  72. protections | nx | rop Execution of pop3ret @read AAAA

    … ... %esp 0x1 @buffer 1024 @system system args @pop3ret .section .text …: pop eax pop ebx pop ecx ret eip @buffer align
  73. protections | nx | rop Execution of pop3ret @read AAAA

    … ... %esp 0x1 @buffer 1024 @system system args @pop3ret .section .text …: pop eax pop ebx pop ecx ret eip @buffer align
  74. protections | nx | rop Execution of pop3ret @read AAAA

    … ... %esp 0x1 @buffer 1024 @system system args @pop3ret .section .text …: pop eax pop ebx pop ecx ret eip @buffer align
  75. protections | nx | rop Detection ROP can be prevented

    by ASLR as we will see in a moment detection techniques are based on CFI violations Control Flow Integrity
  76. protections | nx | rop CFI concepts uses various heuristics

    to detect rop chains high ratio of ret instructions per instructions blocks shadow stack that validate that ret is returning to instruction following the right call instruction
  77. protections | nx | rop CFI limitations implementing a shadow

    stack degrade performance by at least 30% as such most implementations are coarse grained leaving holes that can be exploited fine grained implementations in some academic r&d projects
  78. protections | aslr Function address ! before, code and sections

    were loaded at the same address every time cat /proc/self/maps
  79. protections | aslr Wait, what ? concept seems ineffective if

    binary loading address does not change still possible to extract gadgets from it well, some gadgets but not a panacea… what went wrong?
  80. protections | aslr Requirements not all binaries (including libraries) are

    affected by ASLR need to be compiled as Position Independant {Executable, Code} -pie -fPIE -fPIC
  81. protections | aslr ASLR compatible list binary headers using readelf

    EXEC : not compatible DYN : compatible when in peda use checksec command
  82. protections | aslr Other subtleties 1 : Conservative randomization stack,

    heap, libraries, pie, vdso, mmap() 2 : full randomization 1 + memory managed by brk
  83. protections | aslr | brute-force When lazy or no other

    possibilities set the libc base address to common base brute-force the remaining 16 bits only effective on 32 bits systems or if rebasing is built-into the binary 64bits Linux has 28 bits of entropy
  84. protections | aslr | disclosure When the binary is not

    compiled as position independent as said, limited number of gadgets in it libraries loading address are randomized but… not the content of the library
  85. protections | aslr | disclosure Ok, but how to I

    find it my function ? generate pattern that appears only once in the library not present in other ones obviously need a second vulnerability in the code memory disclosure
  86. protections | aslr | disclosure Usage extract information using the

    disclosure match it against known value calculate offset to interesting functions you want to call
  87. protections | aslr | disclosure Variant highly dependant on the

    vulnerability you are exploiting if able to read /proc/self/maps, extract addresses
  88. protections | aslr | npie When the main binary is

    not compiled as position independent all text section is loaded at fixed address this also includes the GOT address
  89. protections | aslr | npie GOT Global Offset Table used

    as a mapper to call functions for which loading address is unknown pretty useful since PIC is mandatory on modern Linux distro
  90. protections | aslr | npie GOT for each offset there

    is the address of the corresponding function filed by the loader when executing the binary unless lazy binding is used, in this case only once function already called
  91. protections | aslr | npie GOT table is specific for

    each binary but : entries can be retrieved using objdump or radare2 objdump -D ./binary | grep \@plt\>:
  92. protections | aslr | npie Idea base address of the

    GOT is known in this case read at selected offset to retrieve current address of a function open the libc binary and retrieve offset from this function also extract offsets from the desired functions
  93. protections | aslr | npie Details leaked_address = <value> libc_base

    = leaked_address - offset_leaked_from_base needed_address = libc_base + offset_needed_from_base
  94. protections | aslr | npie Wait, how do I read

    the value ? as said only a limited number of gadgets in the main binary still possible to find memory read ones
  95. protections | aslr | npie Example of such gadgets mov

    eax, [ebx] ; ret add eax, [ecx + 0x8042de4c] ; ret … don’t forget to adjust value in ecx
  96. protections | aslr | npie If we have enough time

    demo on bof_04 demo using PlaidCTF ropasaurusrex
  97. protections | ro Rights to write at that location !

    prevent modifications of the GOT and the like used when vulnerability allows to write anywhere in the memory
  98. protections | ro Partial RELRO -z relro reorder sections to

    prevent overwrite through overflow GOT still writable
  99. protections | ro Full RELRO -z relro -z now like

    the previous one one loader’s job is done GOT/PLT are changed to read-only
  100. conclusion What next ? labs this afternoon, yeah! after that

    play with the concepts by yourself create/join CTF team read books or conferences papers do not hesitate to ask for help
  101. conclusion | books Modern operating systems {Linux, Windows, OSX, Android}

    Internals The Shellcoder’s handbook The art of software security assessment Fuzzing : brute force vulnerability discovery Practical reverse engineering
  102. conclusion | con Insomni’hack AppSec Forum / Cyber Security Conference

    Area41 Infiltrate Defcon BlackHat SSTiC NoSuchCon Usenix
  103. conclusion | ctf Check on ctftime.org Insomni’hack CSAW : dedicated

    to students Nuit du Hack Hack.lu CodeGate RuCTFe …