Preview question What two methods are mentioned in the StackGuard paper to prevent canary forgery? CSci 5271 A. “terminator canary” and “random canary” Introduction to Computer Security Low-level attacks and defenses B. “StackGhost” and “random XOR canary” Stephen McCamant C. “stack layout randomization” and “entropy canary” University of Minnesota, Computer Science & Engineering D. “StackGhost” and “PointGuard” E. “Keccak” and “Rijndael” Outline Code reuse Shellcode techniques, cont’d Exploiting other vulnerabilities If can’t get your own shellcode, use existing code Return address protections Classic example: s②st❡♠ implementation in C library “Return to libc” attack Announcements intermission More variations on this later ASLR and counterattacks W ✟ X (DEP) Outline Non-control data overwrite Shellcode techniques, cont’d Exploiting other vulnerabilities Overwrite other security-sensitive data Return address protections No change to program control flow Announcements intermission Set user ID to 0, set permissions to all, etc. ASLR and counterattacks W ✟ X (DEP) Heap meta-data Heap meta-data Boundary tags similar to doubly-linked list Overwritten on heap overflow Arbitrary write triggered on ❢r❡❡ Simple version stopped by sanity checks
Use after free Integer overflows Easiest to use: overflow in small (8-, 16-bit) value, or Write to new object overwrites old, or vice-versa only overflowed value used 2GB write in 100 byte buffer Key issue is what heap object is reused for Find some other way to make it stop Influence by controlling other heap operations Arbitrary single overwrite Use math to figure out overflowing value Null pointer dereference Format string attack Add offset to make a predictable pointer Attacker-controlled format: little interpreter On Windows, interesting address start low Allocate data on the zero page Step one: add extra integer specifiers, dump stack Most common in user-space to kernel attacks Already useful for information disclosure Read more dangerous than a write Format string attack layout Format string attack layout Format string attack: overwrite Outline Shellcode techniques, cont’d ✪♥ specifier: store number of chars written so far to Exploiting other vulnerabilities pointer arg Return address protections Advance format arg pointer to other attacker-controlled data Announcements intermission Control number of chars written with padding ASLR and counterattacks On x86, use unaligned stores to create pointer 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 Shellcode techniques, cont’d Exploiting other vulnerabilities Suppose you have a safe place to store the canary Why not just store the return address there? Return address protections Needs to be a separate stack Announcements intermission Ultimate return address protection ASLR and counterattacks W ✟ X (DEP) Integer overflow question Pre-proposals due tonight Which of the following is not always true, when the variables are interpreted as 32-bit unsigned ✐♥t s in C? Most groups formed? A. ①✯② is odd, if both ① and ② are odd One PDF per group, include schedule choices B. ①✯② ❂❂ ②✯① Submit via Canvas by 11:59pm C. ① ✰ ① ✰ ① ✰ ① ❂❂ ✹✯① D. ✶✻✯① ❃❂① E. ① ✰ ✭✲①✮ ❂❂ ✵ HA1 VMs now available BCECHO Request from Travis if you have not already An even simpler buffer overflow example First exploit is due Friday evening Can compile like BCMTA, install setuid root Shouldn’t be too hard to find, but allow time for Will use for attack demo purposes next week trying out the VM and testing
Outline Basic idea Shellcode techniques, cont’d “Address Space Layout Randomization” Exploiting other vulnerabilities Move memory areas around randomly so attackers Return address protections can’t predict addresses Announcements intermission Keep internal structure unchanged ASLR and counterattacks E.g., whole stack moves together W ✟ X (DEP) Code and data locations Relocation (Windows) Extension of technique already used in compilation Execution of code depends on memory location Keep table of absolute addresses, instructions on E.g., on 32-bit x86: how to update Direct jumps are relative Function pointers are absolute Disadvantage: code modifications take time on load, Data must be absolute prevent sharing PIC/PIE (GNU/Linux) What’s not covered “Position-Independent Code / Executable” Main executable (Linux 32-bit PIC) Keep code unchanged, use register to point to data Incompatible DLLs (Windows) area Relative locations within a module/area Disadvantage: code complexity, register pressure hurt performance Entropy limitations Leakage limitations Intuitively, entropy measures amount of randomness, in bits If an attacker learns the randomized base address, Random 32-bit int: 32 bits of entropy can reconstruct other locations ASLR page aligned, so at most ✸✷ ✲ ✶✷ ❂ ✷✵ bits of Any stack address ✦ stack unprotected, etc. entropy Other constraints further reduce possibilities
GOT hijack (M¨ uller) GOT hijack (M¨ uller) ♣r✐♥t❢❅♣❧t✿ ❥♠♣ ✯✵①✽✵✹✾✻✼✽ Main program fixed, libc randomized ✳✳✳ PLT in main program used to call libc s②st❡♠❅♣❧t✿ ❥♠♣ ✯✵①✽✵✹✾✻✼❝ Rewire PLT to call attacker’s favorite libc functions ✳✳✳ E.g., turn ♣r✐♥t❢ into s②st❡♠ ✵①✽✵✹✾✻✼✽✿ ❁❛❞❞r ♦❢ ♣r✐♥t❢ ✐♥ ❧✐❜❝❃ ✵①✽✵✹✾✻✼❝✿ ❁❛❞❞r ♦❢ s②st❡♠ ✐♥ ❧✐❜❝❃ ret2pop (M¨ uller) ret2pop (M¨ uller) Take advantage of shellcode pointer already present on stack Rewrite intervening stack to treat the shellcode pointer like a return address A long sequence of chained returns, one pop Outline Basic idea Shellcode techniques, cont’d Traditional shellcode must go in a memory area that Exploiting other vulnerabilities is writable, so the shellcode can be inserted Return address protections executable, so the shellcode can be executed Announcements intermission But benign code usually does not need this combination ASLR and counterattacks W xor X, really ✿ ✭ ❲ ❫ ❳ ✮ W ✟ X (DEP) Non-writable code, ❳ ✦ ✿ ❲ Non-executable data, ❲ ✦ ✿ ❳ Prohibit execution of static data, stack, heap E.g., read-only .text section Not a problem for most programs Has been standard for a while, especially on Unix Incompatible with some GCC features no one uses Lets OS efficiently share code with multiple program Non-executable stack opt-in on Linux, but now instances near-universal
Implementing ❲ ✟ ❳ One important exception Page protection implemented by CPU Remaining important use of self-modifying code: Some architectures (e.g. SPARC) long supported ❲ ✟ ❳ just-in-time (JIT) compilers x86 historically did not E.g., all modern JavaScript engines One bit controls both read and execute Allow code to re-enable execution per-block Partial stop-gap “code segment limit” ♠♣r♦t❡❝t , ❱✐rt✉❛❧Pr♦t❡❝t Eventual obvious solution: add new bit Now a favorite target of attackers NX (AMD), XD (Intel), XN (ARM) Counterattack: code reuse Classic return-to-libc (1997) Overwrite stack with copies of: Attacker can’t execute new code Pointer to libc’s s②st❡♠ function So, take advantage of instructions already in binary Pointer to ✧✴❜✐♥✴s❤✧ string (also in libc) There are usually a lot of them The s②st❡♠ function is especially convenient And no need to obey original structure Distinctive feature: return to entry point Chained return-to-libc Beyond return-to-libc Shellcode often wants a sequence of actions, e.g. Can we do more? Oh, yes. Restore privileges Classic academic approach: what’s the most we Allow execution of memory area could ask for? Overwrite system file, etc. Can put multiple fake frames on the stack Here: “Turing completeness” Basic idea present in 1997, further refinements How to do it: reading for Monday Next slides Return-oriented programming (ROP) And counter-defenses Control-flow integrity (CFI)
Recommend
More recommend