Outline Return address protections CSci 5271 Introduction to Computer Security Announcements intermission Day 5: Low-level defenses and counterattacks ASLR and counterattacks Stephen McCamant University of Minnesota, Computer Science & Engineering W ✟ X (DEP) Canary in the coal mine Adjacent canary idea Terminator canary Random canary Value hard to reproduce because it would tell the copy to stop Can’t reproduce because attacker can’t guess StackGuard: 0x00 0D 0A FF For efficiency, usually one per execution 0: String functions newline: ❢❣❡ts (), etc. Ineffective if disclosed -1: ❣❡t❝ () carriage return: similar to newline? Doesn’t stop: ♠❡♠❝♣② , custom loops XOR canary Further refinements More flexible to do earlier in compiler Want to protect against non-sequential overwrites Rearrange buffers after other variables XOR return address with value ❝ at entry Reduce chance of non-control overwrite XOR again with ❝ before return Skip canaries for functions with only small variables Standard choice for ❝ : see random canary Who has an overflow bug in an 8-byte array?
What’s usually not protected? Where to keep canary value Backwards overflows Fast to access Function pointers Buggy code/attacker can’t read or write Adjacent structure fields Linux/x86: ✪❣s✿✵①✶✹ Adjacent static data objects Complex anti-canary attack Complex anti-canary attack Canary not updated on ❢♦r❦ in server Canary not updated on ❢♦r❦ in server Attacker controls number of bytes overwritten Attacker controls number of bytes overwritten ANRY BNRY CNRY DNRY ENRY FNRY search ✷ ✸✷ ✦ search ✹ ✁ ✷ ✽ Shadow return stack Outline Return address protections Suppose you have a safe place to store the canary Announcements intermission Why not just store the return address there? Needs to be a separate stack ASLR and counterattacks Ultimate return address protection W ✟ X (DEP) Note to early readers Outline Return address protections This is the section of the slides most likely to change Announcements intermission in the final version If class has already happened, make sure you have ASLR and counterattacks the latest slides for announcements W ✟ X (DEP)
Basic idea Code and data locations “Address Space Layout Randomization” Execution of code depends on memory location Move memory areas around randomly so attackers E.g., on 32-bit x86: can’t predict addresses Direct jumps are relative Keep internal structure unchanged Function pointers are absolute Data must be absolute E.g., whole stack moves together Relocation (Windows) PIC/PIE (GNU/Linux) Extension of technique already used in compilation “Position-Independent Code / Executable” Keep table of absolute addresses, instructions on Keep code unchanged, use register to point to data how to update area Disadvantage: code modifications take time on load, Disadvantage: code complexity, register pressure prevent sharing hurt performance What’s not covered Entropy limitations Intuitively, entropy measures amount of randomness, in bits Main executable (Linux 32-bit PIC) Random 32-bit int: 32 bits of entropy Incompatible DLLs (Windows) ASLR page aligned, so at most ✸✷ ✲ ✶✷ ❂ ✷✵ bits of Relative locations within a module/area entropy Other constraints further reduce possibilities Leakage limitations GOT hijack (M¨ uller) Main program fixed, libc randomized If an attacker learns the randomized base address, PLT in main program used to call libc can reconstruct other locations Rewire PLT to call attacker’s favorite libc functions Any stack address ✦ stack unprotected, etc. E.g., turn ♣r✐♥t❢ into s②st❡♠
GOT hijack (M¨ uller) ret2pop (M¨ uller) ♣r✐♥t❢❅♣❧t✿ ❥♠♣ ✯✵①✽✵✹✾✻✼✽ Take advantage of shellcode pointer already present ✳✳✳ on stack s②st❡♠❅♣❧t✿ ❥♠♣ ✯✵①✽✵✹✾✻✼❝ Rewrite intervening stack to treat the shellcode ✳✳✳ pointer like a return address ✵①✽✵✹✾✻✼✽✿ ❁❛❞❞r ♦❢ ♣r✐♥t❢ ✐♥ ❧✐❜❝❃ A long sequence of chained returns, one pop ✵①✽✵✹✾✻✼❝✿ ❁❛❞❞r ♦❢ s②st❡♠ ✐♥ ❧✐❜❝❃ ret2pop (M¨ uller) Outline Return address protections Announcements intermission ASLR and counterattacks W ✟ X (DEP) Basic idea Non-writable code, ❳ ✦ ✿ ❲ Traditional shellcode must go in a memory area that is E.g., read-only .text section writable, so the shellcode can be inserted Has been standard for a while, especially on Unix executable, so the shellcode can be executed Lets OS efficiently share code with multiple program But benign code usually does not need this combination instances W xor X, really ✿ ✭ ❲ ❫ ❳ ✮ Non-executable data, ❲ ✦ ✿ ❳ Implementing ❲ ✟ ❳ Page protection implemented by CPU Prohibit execution of static data, stack, heap Some architectures (e.g. SPARC) long supported ❲ ✟ ❳ x86 historically did not Not a problem for most programs One bit controls both read and execute Incompatible with some GCC features no one uses Partial stop-gap “code segment limit” Non-executable stack opt-in on Linux, but now near-universal Eventual obvious solution: add new bit NX (AMD), XD (Intel), XN (ARM)
One important exception Counterattack: code reuse Remaining important use of self-modifying code: Attacker can’t execute new code just-in-time (JIT) compilers So, take advantage of instructions already in binary E.g., all modern JavaScript engines There are usually a lot of them Allow code to re-enable execution per-block ♠♣r♦t❡❝t , ❱✐rt✉❛❧Pr♦t❡❝t And no need to obey original structure Now a favorite target of attackers Classic return-to-libc (1997) Chained return-to-libc Shellcode often wants a sequence of actions, e.g. Overwrite stack with copies of: Restore privileges Pointer to libc’s s②st❡♠ function Allow execution of memory area Pointer to ✧✴❜✐♥✴s❤✧ string (also in libc) Overwrite system file, etc. The s②st❡♠ function is especially convenient Can put multiple fake frames on the stack Distinctive feature: return to entry point Basic idea present in 1997, further refinements Beyond return-to-libc Next slides Can we do more? Oh, yes. Return-oriented programming (ROP) Classic academic approach: what’s the most we And counter-defenses could ask for? Control-flow integrity (CFI) Here: “Turing completeness” How to do it: reading for Thursday
Recommend
More recommend