- Security needs to be a first-class design concern.
- You don’t need to fix all the bugs, you just need to be better than the other guy.
- Code is growing in complexity (11 million+ lines in the kernel) and more people using tools (750,000+ Android devices activate per day).
- Security is an arms race, where good guys and bad guys compete.
Why do Hackers Attack?
- Build botnets. Botnets can do things you can’t do otherwise; bitcoin generation, spam, etc.
- Gain control ofuseful private information (creditcards)
- Punish/embarrassing people, e.g. Sony, Church of Scientology, etc
- To educate and advocate, e.g. Firesheep.
- Earn a reputation.
Win the Bear Race!
The attackers are the bear. Don’t be something the bear wants to eat.
- Buffer Overflows: the daddy of attacks. The classic stack-smasher.
- The cure is to refuse to allow execution on the stack; e.g. the NX bit.
- The countermeasure to that is the “heap spray” attack; the buffer overwrite gets initial access, but instead of stack-smashing, you inject huge amounts of data into the heap, which is also valid code. Then you jump to a random address in the heap space, which will give you a decent chance of hitting executable code in the heap, and away you go.
- People have tried having ROM-only execution, refusing to execute out of memory.
- The counter to this is “return oriented programming”. You overrun, inspect the ROM, and then use the functions and function fragments in the ROM, chaining them together to build what you want. e.g. one team were able to implement a Turing-complete VM for themselves.
- Hardware attacks. e.g. Adding 1400 gates as a rogue designer to make a hardware Linux backdoor; bug in Intel processor to make an OS-independent attack.
- No-execute stacks. Can be thwarted by heap-spray in a naive implementation; that is countered by heap address randomisation. Implemented in recent Linux, Windows, and MacOS. This means you need to jump to the right address for the heap overflow on the first time, greatly reducing the likelihood.
- “Stack Canaries” are embedded in the stack frame, as a random value embedded in each function. If the canary is wrong, the execution simply halts.
- Only fully available in OpenBSD.
- Encrypted pointers with StackGuard. Every pointer is encypted with a different, simple XOR on every execution.
- All of these techniques have a cost in memory or CPU.
- Sandboxing. Classic technique from virtual machines (in the Smalltalk/Java sense). For example, Chrome, Firefox, and IE 9 all implement this. All tabs talk to a policy manager, rather than to the underlying operating system.
- The “Browser in the Middle” attack - an attack where visiting a car forum would trigger JS that would check for an open tab to an HSBC internet banking session, and would do a $1 funds transfer.
- What can you do about buffer overflows? Safe languages. Eliminates Spacial and Temporal buffer overflows.
- But in May 2011 the two top attack vectors were Flash and Oracle Java, both of which are managed code. Ooops.
- Languages can be safe. But implementations can be unforgivably broken.
Developers Need to Adopt Better Development Strategys
- “For every piece of software there is a trail of abused users.”
- So employ tools to find vulnerabilities.
- We fix earlier before we release, and we release cleaner code.
- Constrain inputs. If you can’t put garbage into the program, you’ve reatly reduced the possibility of an attack.
- The tools that can check and produce reommendations on vulnerabilities can be used by the bad guys.
- Dynamic taint checking can be used to uncover paths of external inputs that need to be sanity-checked.
Dataflow Analaysis 101
- We build a graph on how the data flows through the program, propogating the taint information.
- This will only work on buffer overflows.
Side-Channel Attacks and Protections
- Depressing because your system qua system is secure, well-thought out, and well-implemented. but someone creates e.g. an environmental condition that violates your assumptions.
- For example, a power fluctuation can indication whether you are mostly doing 1s or 0s.
- The classic RSA attack was based on how long it reuquire to encrypt information.
- Keyboard noise detection. Tempest devices can read your screen.
- Punishing a system.
- Cash. Blackmail.
- Other human engineering, e.g. the Red-Headed League.
- An old attack on DES relied on the fact that DES would flush the cache when it was processing data. Because the placement of the code and data in the cache is consistent, forcing invalidation of the cache can reveal enough timing infomation to let you work out the 1s and 0s.
- Differential Power Analysis. You know XOR takes less power than ADDs, while MUL requires more. So based on the operations you can derive the key; for example, AES is almost all XOR, so watching the power fluctuations will tell you if it’s XOR 0,0 XOR 1,1 XOR 0,1.
- Timing-based attacks. Daniel Bernstein demonstrated a timing attack against AES based on cache timings.
- Fault-based attacks: this is Valeria’s attack from the morning.
Tools for More Secure Software
- Valgrind is a platform that runs as a VM on Linux, with a suite of plugins that find memory leaks, dangling pointers, races, and so on.
- Programs run slooooooooooooooower while running under Valgrind.
- Apparently it’s pronounced Val-grin-d not Val-grind.
- OpenBSD ProPolice. Also becoming available in GCC.
- Fuzz testing will find all sorts of crap, albeit shallow crap.
- Google’s browser fuzz tester found hundreds of defects when it was first released.
- Klee is a more thorough fuzz tester, checking the code coverage as it fuzzes, rather than operating purely randomly. It tries to execute every path that exists, allowing it to come up with deep bugs.
- Metasploit will package up attacks and go after your machine(s).
- The embedded space is incredibly immature. Headed a panel with teams who have remote-owned cars, UAVs, and Pacemakers. He described it as the most terrifying panel he’s run.
- There are even PHP static alanalysers now.