DV1460 / DV1492:

Realtime- (and) Operating-Systems

08:15-10:00 Thursday October 20th, 2016

Security Part I


Table of Contents
Exploitation by Primitives

1. Introduction

  • Last time we saw exploit and defences of increasing complexity.
    • The arms race between defenders and attackers is an evolutionary struggle.
    • Return-oriented programming and format-string attacks.
    • The attacker is building read-, write- and execute- primitives from different bugs in the code.
    • As defender plug up old holes, the attack vectors become more obscure.
    • Interesting economic perspective: have we passed "peak exploit"?
  • The final few exploits we look at dig into the Byzantine layers of software in a modern OS.
    • Dangling pointers: heap manipulation.
    • Command Injection: using shellshock to attack the process model.

2. Dangling pointers

  • Dangling pointers are a basic type of bug.
  • Program allocates some memory.
  • After using it the program frees the memory.
  • Later (for reasons) the pointer is used after the memory is free.
char *x = new char[100]; ... do lots of stuff ... delete x; ... some time later ... x[0] = ...
  • Why would the programmer do this?
    • Mismatched assumptions, harder to spot in different procedures / classes / libraries...
    • Conditional code - some paths free the memory and some do not.
  • Like buffer overflows there are many of these kinds of bugs in large programs.

3. Building a write-primitive

  • Unlike a buffer-overflow: it is unclear where the dangling pointer will write.
  • We don't know what memory it targets.
  • Ideally writing through the pointer would cause an access violation exception.
  • But, recall the interface between the program and the memory management.
  • Simple, dense, contiguous address ranges.
  • Memory frees do not propagate to the memory subsystem.
  • The memory handler inside the process libc is a performance hack (avoid syscalls).
  • New heap objects will occupy the old addresses...

4. Object Orientation

  • Interesting things happen in the runtime of OO languages.
  • When objects are stored on the heap:
    • A piece of memory is allocated for the data storage.
    • A V-table is filled in for the methods.
    • These are function pointers...
  • Overwriting a location on the heap can corrupt a V-table.
  • Calling a method on that object will now jump to an arbitrary address (execution-primitive).
  • OO language + dangling pointers = replacement for buffer overflows.

5. Browser exploits

  • Browser exploits are very valuable.
    • Vulnerable system only has to load a page.
    • Advertising is pervasive.
  • Javascript is an OO language.
    • It sits on-top of the heap-management provided by the host OS.
  • Any dangling pointers in the runtime can lead to control of the browser.
  • [I was somewhat distracted writing this as someone is trying this technique in twitter adverts...]

6. NULL pointers

  • NULL is used as a sentinel in many languages.
    • No data or code can live at address 0.
    • This is a basic assumption.
  • But some systems allow a slightly richer interaction with the memory subsystem.
  • Recall the interesting tricks that mmap allows.
    • Sharing memory with other processes.
    • Avoiding copy overhead in file I/O.
  • And until it was patched out...
    • ...mapping addressable pages onto NULL!
  • Target was a program with two bugs:
    • Jump to NULL (e.g. uninitialised function pointer), exploitable mmap().

7. Command Injection

  • We introduced system() as a dangerous vector in the standard library.
  • But many programs have legimate uses for it.
    • cron - scheduler for unix systems.
      • User can run arbitrary commands at specific times of day.
    • Lazy programmers ("rapid application development"), embedding bits of shell: we never intend for scaffolding to become permanent.
  • The system() call takes a string to execute.
    • So a vulnerable program has some string processing depending on user input.
    • If the attacker can control the contents of the string - run arbitrary code.
  • e.g. if the user supplies filenames that are sprintf'd into a string.

8. Command Injection

  • (C) Randall Munrow (xkcd)
  • Securing an OS is significantly more complex than a database.
    • All inputs to any privileged program must be sanitised.
    • Great care must be taken to avoid exposing usable primitives.

9. Security Threats

  • We've seen a lot about the mechanisms for breaking in.
  • It all boils down to finding / building / using:
    • Read-, Write- and Execute-primitves.
  • With this "hacker mindset" lets take a step back and review some features.
Convenience vs Security
Every feature is a potential read-, write- or execute-primitive. Securing this attack surface means breaking composabiity of features.
  • ActiveX - removes the inconvenience of sandboxing by giving full access to arbitrary websites.
  • HTML email - replaces a "transparent" data format with a layer of abstraction that may include unknown primitives (e.g. unique outgoing image links, cookie access).

10. Review of security threats

  • JavaScript - every point the interpreter interacts with the OS is a potential primitive for exploitation.
  • Logic bombs - running close source software is an opportunity to live in "interesting times".
  • Back door - running un-audited source is a form of execute-primitive.
  • NFS - mounting external storage is highly convenient.
    • Enables sharing of storage space and scaling beyond sizes available in a desktop.
    • Assumes the server is trusted.
    • Any compromise between client and server (LAN, router, server itself) enable read- and write-pritives to any file in the filesystem.
    • If executables are stored in NFS then it becomes too easy.
    • Normal NFS configurations keep binaries on local volumes (contrast with NX "protection").

11. Review of security threats

  • Trojan horse - running an unknown program is handing an execute-primitive to the attacker.
    • e.g. helpful "generators" (serials, credit cards etc), cracks, pirated games, "custom VPNs", wifi authentication, disk "cleaners"...
  • Spoofing logins - giving credentials to an unaudited entity...
    • ...you wouldn't just give your credit card to a waiter would you?
    • The purpose of credentials is to guard access to primitives.
  • Viruses rely on the user supplying credentials to them.
    • If I can't make a program that executes itself, perhaps the user will do it for me?
    • Start with a limited execute-primitive (e.g. a trojan horse).
    • Use that execution to rewrite and enable further execute-primitives.
      • Other programs, boot-sectors, device-drivers...

12. Review of security threats

  • Exploits in programs that read from the network are highly valuable.
    • e.g Send data to trigger buffer-overflow, ..., Profit!
  • No loner necessary to trick the user into supplying an execute-primitive.
    • Automating the infection process: worms.
  • The Morris Worm (1988), best explained by Michael Bolton in Office Space.
    • "I always do that. I always mess up some mundane detail."
    • Three expoits: rsh (guest acounts!), finger exploit, sendmail exploit.
  • Of course this led people to wonder, how could we really improve this?
    • Warhol worm - hidden propagation phase followed by mass infection.
    • Worm propagation strategies are similar to human epidemics.
    • Roughly speaking: Plague Inc strategies work well.

13. Review of security threats

  • Once root access has been achieved, keeping it means hiding from view.
    • Hijack any syscalls that would reveal the kit, rewrite output.
    • Needs an execute-primitive in the boot sequence for the OS.
  • a) Firmware b) Blue pill c) device driver / module d) standard library e) application (e.g. systemd)
Final summary: security is a cross-cutting concern.
Controlling access to primitives cannot be logically decomposed into nice clean box - it impacts every aspect of OS design and implementation.

Break (15mins)


15. Note to self

  • Delivery speed vs slide contents is off.
    • Started to wander a little during FS block.
    • Slipped about 1/2 lecture during I/O
  • Next year:
    • Security stuff is about 14.5 and 15.
    • Options
      • shrink I/O back to 2, expand either Security or 1/2 on VM.
      • expand explanations so numbering matches running order.