Outline Vulnerabilities in OS interaction Low-level view of memory CSci 5271 Introduction to Computer Security Intermission: gdb demo Day 3: Low-level vulnerabilities Basic memory-safety problems Stephen McCamant Where overflows come from University of Minnesota, Computer Science & Engineering More problems Shell code injection Shell code injection example Don’t pass untrusted strings to a Benign: s②st❡♠✭✧❝♣ ✩❛r❣✶ ✩❛r❣✷✧✮ , command shell arg1 = ✧❢✐❧❡✶✳t①t✧ In C: s②st❡♠ , ♣♦♣❡♥ Attack: arg1 = ✧❛ ❜❀ ❡❝❤♦ ●♦t❝❤❛✧ s②st❡♠✭✧❝♠❞ ✩❛r❣✶ ✩❛r❣✷✧✮ Command: Fix 1: avoid shell ✧❝♣ ❛ ❜❀ ❡❝❤♦ ●♦t❝❤❛ ❢✐❧❡✷✳t①t✧ Not a complete solution: blacklist ‘ ❀ ’ Fix 2: sanitize data (preferably whitelist) Bad/missing error handling Race conditions Under what circumstances could each Two actions in parallel; result depends system call fail? on which happens first Careful about rolling back after an error Usually attacker racing with you in the middle of a complex operation 1. Write secret data to file Fail to drop privileges ✮ run untrusted 2. Restrict read permissions on file code anyway Many other examples Update file when disk full ✮ truncate
Classic races: files in ✴t♠♣ TOCTTOU gaps Time-of-check (to) time-of-use races Temp filenames must already be unique 1. Check it’s OK to write to file But “unguessable” is a stronger 2. Write to file requirement Attacker changes the file between Unsafe design ( ♠❦t❡♠♣✭✸✮ ): function to steps 1 and 2 return unused name Just get lucky, or use tricks to slow Must use ❖ ❊❳❈▲ for real atomicity you down TOCTTOU example TOCTTOU example ✐♥t s❛❢❡❴♦♣❡♥❴❢✐❧❡✭❝❤❛r ✯♣❛t❤✮ ❢ ✐♥t s❛❢❡❴♦♣❡♥❴❢✐❧❡✭❝❤❛r ✯♣❛t❤✮ ❢ ✐♥t ❢❞ ❂ ✲✶❀ ✐♥t ❢❞ ❂ ✲✶✱ r❡s❀ str✉❝t st❛t s❀ str✉❝t st❛t s❀ st❛t✭♣❛t❤✱ ✫s✮ r❡s ❂ st❛t✭♣❛t❤✱ ✫s✮ ✐❢ ✭✦❙ ■❙❘❊●✭s✳st ♠♦❞❡✮✮ ✐❢ ✭r❡s ⑤⑤ ✦❙ ■❙❘❊●✭s✳st ♠♦❞❡✮✮ ❡rr♦r✭✧♦♥❧② r❡❣✉❧❛r ❢✐❧❡s ❛❧❧♦✇❡❞✧✮❀ ❡rr♦r✭✧♦♥❧② r❡❣✉❧❛r ❢✐❧❡s ❛❧❧♦✇❡❞✧✮❀ ❡❧s❡ ❢❞ ❂ ♦♣❡♥✭♣❛t❤✱ ❖ ❘❉❖◆▲❨✮❀ ❡❧s❡ ❢❞ ❂ ♦♣❡♥✭♣❛t❤✱ ❖ ❘❉❖◆▲❨✮❀ r❡t✉r♥ ❢❞❀ r❡t✉r♥ ❢❞❀ ❣ ❣ TOCTTOU example Changing file references ✐♥t s❛❢❡❴♦♣❡♥❴❢✐❧❡✭❝❤❛r ✯♣❛t❤✮ ❢ With symbolic links ✐♥t ❢❞ ❂ ✲✶✱ r❡s❀ With hard links str✉❝t st❛t s❀ r❡s ❂ st❛t✭♣❛t❤✱ ✫s✮ With changing parent directories ✐❢ ✭r❡s ⑤⑤ ✦❙ ■❙❘❊●✭s✳st ♠♦❞❡✮✮ Avoid by instead using: ❡rr♦r✭✧♦♥❧② r❡❣✉❧❛r ❢✐❧❡s ❛❧❧♦✇❡❞✧✮❀ ❢✯ functions that operate on fds ❡❧s❡ ❢❞ ❂ ♦♣❡♥✭♣❛t❤✱ ❖ ❘❉❖◆▲❨✮❀ ✯❛t functions that use an fd in place of r❡t✉r♥ ❢❞❀ the CWD ❣
Directory traversal with ✳✳ Environment variables Can influence behavior in unexpected ways Program argument specifies file with P❆❚❍ directory ❢✐❧❡s ▲❉ ▲■❇❘❆❘❨ P❆❚❍ ■❋❙ What about . . . ❢✐❧❡s✴✳✳✴✳✳✴✳✳✴✳✳✴❡t❝✴♣❛ss✇❞ ? Also umask, resource limits, current directory IFS and why it’s a problem Outline Vulnerabilities in OS interaction In Unix, splitting a command line into Low-level view of memory words is the shell’s job String ✦ argv array Intermission: gdb demo ❣r❡♣ ❛ ❜ ❝ vs. ❣r❡♣ ✬❛ ❜✬ ❝ Basic memory-safety problems Choice of separator characters (default space, tab, newline) is configurable Where overflows come from Exploit s②st❡♠✭✧✴❜✐♥✴✉♥❛♠❡✧✮ More problems Overall layout (Linux 32-bit) Detail: static code and data
Detail: heap Detail: initial stack Example stack frame Outline Vulnerabilities in OS interaction Low-level view of memory Intermission: gdb demo Basic memory-safety problems Where overflows come from More problems Outline Stack frame overflow Vulnerabilities in OS interaction Low-level view of memory Intermission: gdb demo Basic memory-safety problems Where overflows come from More problems
Overwriting adjacent objects Overwriting metadata Forward or backward on stack On stack: Other local variables, arguments Return address Fields within a structure Saved registers, incl. frame pointer On heap: Global variables Size and location of adjacent blocks Other heap objects Double free Use after free Passing the same pointer value to AKA use of a dangling pointer ❢r❡❡ more than once Could overwrite heap metadata More dangerous the more other heap Or, access data with confused type operations occur in between Outline Library funcs: unusable Vulnerabilities in OS interaction ❣❡ts writes unlimited data into supplied Low-level view of memory buffer Intermission: gdb demo No way to use safely (unless stdin Basic memory-safety problems trusted) Finally removed in C11 standard Where overflows come from More problems
Library funcs: dangerous Library funcs: bounded Big three unchecked string functions Just add “n”: str❝♣②✭❞❡st✱ sr❝✮ str♥❝♣②✭❞❡st✱ sr❝✱ ♥✮ str❝❛t✭❞❡st✱ sr❝✮ str♥❝❛t✭❞❡st✱ sr❝✱ ♥✮ s♣r✐♥t❢✭❜✉❢✱ ❢♠t✱ ✳✳✳✮ s♥♣r✐♥t❢✭❜✉❢✱ s✐③❡✱ ❢♠t✱ ✳✳✳✮ Must know lengths in advance to use Tricky points: safely (complicated for s♣r✐♥t❢ ) Buffer size vs. max characters to write Failing to terminate Similar pattern in other funcs returning str♥❝♣② zero-fill a string More library attempts Still a problem: truncation OpenBSD str❧❝♣② , str❧❝❛t Unexpectedly dropping characters from Easier to use safely than “n” versions the end of strings may still be a Non-standard, but widely copied vulnerability Microsoft-pushed str❝♣② s , etc. E.g., if attacker pads paths with Now standardized in C11, but not in glibc Runtime checks that ❛❜♦rt ✴✴✴✴✴✴✴ or ✴✳✴✳✴✳✴✳ Compute size and use ♠❡♠❝♣② Avoiding length limits is best, if implemented correctly C++ st❞✿✿str✐♥❣ , glib, etc. Off-by-one bugs Even more buffer/size mistakes Inconsistent code changes (use str❧❡♥ does not include the terminator s✐③❡♦❢ ) Comparison with ❁ vs. ❁❂ Misuse of s✐③❡♦❢ (e.g., on pointer) Length vs. last index Bytes vs. wide chars (UCS-2) vs. ①✰✰ vs. ✰✰① multibyte chars (UTF-8) OS length limits (or lack thereof)
Other array problems Outline Vulnerabilities in OS interaction Low-level view of memory Missing/wrong bounds check One unsigned comparison suffices Intermission: gdb demo Two signed comparisons needed Beware of clever loops Basic memory-safety problems Premature optimization Where overflows come from More problems Integer overflow Integer overflow example Fixed size result ✻ ❂ math result Sum of two positive ✐♥t s negative or ✐♥t ♥ ❂ r❡❛❞❴✐♥t✭✮❀ less than addend ♦❜❥ ✯♣ ❂ ♠❛❧❧♦❝✭♥ ✯ s✐③❡♦❢✭♦❜❥✮✮❀ ❢♦r ✭✐ ❂ ✵❀ ✐ ❁ ♥❀ ✐✰✰✮ Also multiplication, left shift, etc. ♣❬✐❪ ❂ r❡❛❞❴♦❜❥✭✮❀ Negation of most-negative value ✭❧♦✇ ✰ ❤✐❣❤✮✴✷ Signed and unsigned Mixing integer sizes Unsigned gives more range for, e.g., Complicated rules for implicit s✐③❡ t conversions Also includes signed vs. unsigned At machine level, many but not all Generally, convert before operation: operations are the same E.g., ✶❯▲▲ ❁❁ ✻✸ Most important difference: ordering Sign-extend vs. zero-extend In C, signed overflow is undefined ❝❤❛r ❝ ❂ ✵①❢❢❀ ✭✐♥t✮❝ behavior
Null pointers Undefined behavior C standard “undefined behavior”: Vanilla null dereference is usually anything could happen non-exploitable (just a DoS) Can be unexpectedly bad for security But not if there could be an offset (e.g., field of struct) Most common problem: compiler optimizes assuming undefined behavior And not in the kernel if an untrusted cannot happen user has allocated the zero page Linux kernel example Format strings ♣r✐♥t❢ format strings are a little interpreter str✉❝t s♦❝❦ ✯s❦ ❂ t✉♥✲❃s❦❀ ♣r✐♥t❢✭♠s❣✮ with untrusted ♠s❣ lets ✴✴ ✳✳✳ the attacker program it ✐❢ ✭✦t✉♥✮ Allows: r❡t✉r♥ P❖▲▲❊❘❘❀ Dumping stack contents ✴✴ ♠♦r❡ ✉s❡s ♦❢ t✉♥ ❛♥❞ s❦ Denial of service Arbitrary memory modifications! Next time Exploitation techniques for these vulnerabilities
Recommend
More recommend