Defense at Scale
> Last year, my colleague Chris Rohlf gave a keynote at BSidesNOLA entitled “Offense at Scale”. Offense sounds fun. Pwn all the things. And you’re always going to win! And normally I’m a big fan of being massively offensive. Unfortunately, I find myself on the defense when it comes to information security.
> Here’s how you defend at scale. Can’t be done. The end. Everything’s fucked. You’re pwned.
Plenty of good points here. Also a fun read.
APRR - Access Protection ReRouting
> Almost a year ago I did a write-up on KTRR, first introduced in Apple’s A10 chip series. Now over the course of the last year, there has been a good bit of talk as well as confusion about the new mitigations shipped with Apple’s A12. One big change, PAC, has already been torn down in detail by Brandon Azad, so I’m gonna leave that out here. What’s left to cover is more than just APRR, but APRR is certainly the biggest chunk, hence the title of this post.
> APRR is a pretty cool feature, even if parts of it are kinda broke. What I really like about it (besides the fact that it is an efficient and elegant solution to switching privileges) is that it untangles EL1 and EL0 memory permissions, giving you more flexibility than a standard ARMv8 implementation. What I don’t like though is that it has clearly been designed as a lockdown feature, allowing you only to take permissions away rather than freely remap them.
> It’s also evident that Apple is really fond of post-exploit mitigations, or just mitigations in general. And on one hand, getting control over the physical address space is a good bit harder now. But on the other hand, Apple’s stacking of mitigations is taking a problematic turn when adding new mitigations actively creates vulnerabilities now.
Adopting the Arm Memory Tagging Extension in Android
> As part of our continuous commitment to improve the security of the Android ecosystem, we are partnering with Arm to design the memory tagging extension (MTE). Memory safety bugs, common in C and C++, remain one of the largest vulnerabilities in the Android platform and although there have been previous hardening efforts, memory safety bugs comprised more than half of the high priority security bugs in Android 9.
> We believe that memory tagging will detect the most common classes of memory safety bugs in the wild, helping vendors identify and fix them, discouraging malicious actors from exploiting them. During the past year, our team has been working to ensure readiness of the Android platform and application software for MTE. We have deployed HWASAN, a software implementation of the memory tagging concept, to test our entire platform and a few select apps. This deployment has uncovered close to 100 memory safety bugs. The majority of these bugs were detected on HWASAN enabled phones in everyday use. MTE will greatly improve upon this in terms of overhead, ease of deployment, and scale. In parallel, we have been working on supporting MTE in the LLVM compiler toolchain and in the Linux kernel. The Android platform support for MTE will be complete by the time of silicon availability.
Map Guard and Intel MPK
> Earlier this year I pushed a small library to Github called Map Guard. The goal of Map Guard is to enforce non-invasive security policies with regards to how pages of memory may be allocated, or modified, with the mmap syscall. For example, we may want to deny any page allocations marked Read, Write, and Execute as it introduces an easy mechanism for an exploit developer to take advantage of. In the rest of this post I will break down the approach I took to implement each of these security policies, and finally how Map Guard uses Intel’s Memory Protection Keys to allow transparently enabling Execute Only memory for all regions of mapped code.
security things in Linux v5.2
> page allocator freelist randomization
And some other things as well.
security things in Linux v5.1
> Linux kernel v5.1 has been released! Here are some security-related things that stood out to me:
Assessing Unikernel Security
> Unikernels are small, specialized, single-address-space machine images constructed by treating component applications and drivers like libraries and compiling them, along with a kernel and a thin OS layer, into a single binary blob. Proponents of unikernels claim that their smaller codebase and lack of excess services make them more efficient and secure than full-OS virtual machines and containers. We surveyed two major unikernels, Rumprun and IncludeOS, and found that this was decidedly not the case: unikernels, which in many ways resemble embedded systems, appear to have a similarly minimal level of security. Features like ASLR, W^X, stack canaries, heap integrity checks and more are either completely absent or seriously flawed. If an application running on such a system contains a memory corruption vulnerability, it is often possible for attackers to gain code execution, even in cases where the application’s source and binary are unknown. Furthermore, because the application and the kernel run together as a single process, an attacker who compromises a unikernel can immediately exploit functionality that would require privilege escalation on a regular OS, e.g. arbitrary packet I/O. We demonstrate such attacks on both Rumprun and IncludeOS unikernels, and recommend measures to mitigate them.
A year with Spectre: a V8 perspective
> In theory, it would be sufficient to defeat either of the two components of an attack. Since we do not know of any way to defeat any of the parts perfectly, we designed and deployed mitigations that greatly reduce the amount of information that is leaked into CPU caches and mitigations that make it hard to recover the hidden state.
> Fortunately or unfortunately, our offensive research advanced much faster than our defensive research, and we quickly discovered that software mitigation of all possible leaks due to Spectre was infeasible. This was due to a variety of reasons. First, the engineering effort diverted to combating Spectre was disproportionate to its threat level. In V8 we face many other security threats that are much worse, from direct out-of-bound reads due to regular bugs (faster and more direct than Spectre), out-of-bound writes (impossible with Spectre, and worse) and potential remote code execution (impossible with Spectre and much, much worse). Second, the increasingly complicated mitigations that we designed and implemented carried significant complexity, which is technical debt and might actually increase the attack surface, and performance overheads. Third, testing and maintaining mitigations for microarchitectural leaks is even trickier than designing gadgets themselves, since it’s hard to be sure the mitigations continue working as designed. At least once, important mitigations were effectively undone by later compiler optimizations. Fourth, we found that effective mitigation of some variants of Spectre, particularly variant 4, to be simply infeasible in software, even after a heroic effort by our partners at Apple to combat the problem in their JIT compiler.
Local privilege escalation via the Windows I/O Manager: a variant finding collaboration
> In Windows, when a system call is made from a user mode thread, the system call handler records this in the thread object by setting its PreviousMode field to UserMode. If instead the system call is made from kernel mode using a Zw-prefixed function, or from a system thread, the PreviousMode of the thread will be set to KernelMode. This method of distinguishing between user mode and kernel mode callers is used to help determine if the arguments of the call are from a trusted or untrusted source, and therefore to what extent they need to be validated by the kernel.
> In his research, James found that there were various kernel mode drivers shipped with Windows that, when handling IRP_MJ_CREATE requests, check the IRP’s RequestorMode, but do not check for SL_FORCE_ACCESS_CHECK. Furthermore, these are potentially exploitable via kernel mode code that, on the face of it, appears to be doing the correct thing in setting IO_FORCE_ACCESS_CHECK when creating or opening a file. An attacker obtaining sufficient control of the arguments of a file create/open call, via some request originating from user mode, could use this to send an IRP_MJ_CREATE request where the RequestorMode is KernelMode. If the RequestorMode check is used in a security decision, this may lead to a local privilege escalation vulnerability.
Chrome + Windows Exploit: Security Beyond Bugfixes
> There’s a publicly visible patch for the Chrome bug, however there aren’t a lot of details on the Windows kernel bug. The Google team states that they think it may be only possible to exploit this bug against Windows 7, and not newer Windows versions -- even if the bug does exist there. I want to use the remainder of this post to explain reasons that is -- based on the information we have.
> It’s very common to think about computer security primarily in terms of fixing vulnerabilities. In reality, security teams spend a lot of their time on a different goal: making bugs hard to exploit. This often takes the form of lowering privileges and introducing exploit mitigations. Windows 10 has a lot of investment in those areas, whereas Windows 7 doesn’t contain any of the improvements made in the last several years. That’s why even though Windows 7 continues to receive security bug fixes from Microsoft, it is considerably less safe to use.
Introducing Adiantum: Encryption for the Next Billion Users
> Where AES is used, the conventional solution for disk encryption is to use the XTS or CBC-ESSIV modes of operation, which are length-preserving. Currently Android supports AES-128-CBC-ESSIV for full-disk encryption and AES-256-XTS for file-based encryption. However, when AES performance is insufficient there is no widely accepted alternative that has sufficient performance on lower-end ARM processors.
> To solve this problem, we have designed a new encryption mode called Adiantum. Adiantum allows us to use the ChaCha stream cipher in a length-preserving mode, by adapting ideas from AES-based proposals for length-preserving encryption such as HCTR and HCH. On ARM Cortex-A7, Adiantum encryption and decryption on 4096-byte sectors is about 10.6 cycles per byte, around 5x faster than AES-256-XTS.
Paper link: https://tosc.iacr.org/index.php/ToSC/article/view/7360
Protecting your data, no matter where you go on the web
> We help keep your Google Account safe by proactively detecting and responding to security threats. For example, we already automatically reset the password on your Google Account if it may have been exposed in a third party data breach—a security measure that reduces the risk of your account getting hacked by a factor of ten.
> But we want to provide you with the same data breach protections for your accounts, beyond just Google apps and sites. This is where the new Password Checkup Chrome extension can help. If we detect that a username and password on a site you use is one of over 4 billion credentials that we know have been compromised, the extension will trigger an automatic warning and suggest that you change your password.
Examining Pointer Authentication on the iPhone XS
> Among the most exciting security features introduced with ARMv8.3-A is Pointer Authentication, a feature where the upper bits of a pointer are used to store a Pointer Authentication Code (PAC), which is essentially a cryptographic signature on the pointer value and some additional context. Special instructions have been introduced to add an authentication code to a pointer and to verify an authenticated pointer’s PAC and restore the original pointer value. This gives the system a way to make cryptographically strong guarantees about the likelihood that certain pointers have been tampered with by attackers, which offers the possibility of greatly improving application security.
> Despite these flaws, PAC remains a solid and worthwhile mitigation. Apple’s hardening of PAC in the A12 SoC, which was clearly designed to protect against kernel attackers with read/write, meant that I did not find a systematic break in the design and had to rely on signing gadgets, which are easy to patch via software. As with any complex new mitigation, loopholes are not uncommon in the first few iterations. However, given the fragility of the current bypass technique (relying on, among other things, the single IOUserClient class that allows us to overwrite its IOExternalTrap, one of a very small number of usable PACIZA gadgets, and a handful of non-PAC’d JOP gadgets introduced by obfuscation), I believe it’s possible for Apple to harden their implementation to the point that strong forgery bypasses become rare.
The State Of Software Security In 2019
> My goal in this post is to skim my observations on the state of software design and development over the past year, and to try to find a meaningful way forward for myself for 2019. My perspective is limited by the fact that I have worked exclusively in client-side software security for the past 7.5 years. Still, I think there are broad trends visible even to me, and some clear signs about where we need to go as an industry.
Cross DSO CFI - LLVM and Android
> Control Flow Integrity is an exploit mitigation that helps raise the cost of writing reliable exploits for memory safety vulnerabilities. There are various CFI schemes available today, and most are quite well documented and understood. One of the important areas where CFI can be improved is protecting indirect calls across DSO (Dynamic Shared Object) boundaries. This is a difficult problem to solve as only the library itself can validate call targets and consumers of the library may be compiled and linked against the library long after it was built. This requires a low level ABI compatability between the caller and the callee. The LLVM project has documented their design for this here. The remainder of this post looks at that design, it’s drawbacks, and then briefly explores how the Android PIE Bionic linker implements it.
A journey on evaluating Control-Flow Integrity (CFI): LLVM-CFI versus RAP
> This post started out of the need to provide a little more clarification after a long and heated discussions on Twitter (initial discussion and follow up) about the origins of Control-Flow Integrity (CFI), the contributions of academia, and the precision, performance, and compatibility of different existing implementations.
> CFI is a stop the exploit defense that protects the control-flow of processes in the presence of memory corruption. The threat model assumes that an attacker can modify (read, write, update) all of the address space according to the read/write permissions of the corresponding pages. The mitigation restricts execution to valid control flows by checking the targets of indirect control flow transfers (indirect calls and indirect jumps on the forward edge or function returns on the backward edge).
The Super Capsicumizer 9000
> capsicumizer is a sandbox launcher that imposes Capsicum capability mode onto an unsuspecting program, allowing “sysadmin style” or “oblivious” sandboxing (i.e. no source code modifications, all restrictions added externally).
> How many times have you downloaded an executable file, but were afraid to run it? Have you ever been in a situation which required a clean installation of Windows, but didn’t want to set up a virtual machine?
> At Microsoft we regularly encounter these situations, so we developed Windows Sandbox: an isolated, temporary, desktop environment where you can run untrusted software without the fear of lasting impact to your PC. Any software installed in Windows Sandbox stays only in the sandbox and cannot affect your host. Once Windows Sandbox is closed, all the software with all its files and state are permanently deleted.
Securely running processes that require the entire syscall interface
> While evidence has shown that “a container with a well-crafted seccomp (secure computing mode) profile (which blocks unexpected system calls) provides roughly equivalent security to a hypervisor” (https://blog.hansenpartnership.com/measuring-the-horizontal-attack-profile-of-nabla-containers/), methods are still needed for securely running those processes that require the entire syscall interface. Solving this problem has led to some interesting research.
> Let’s take a look at some of the research being done in these areas.
Searching statically-linked vulnerable library functions in executable code
> Software supply chains are increasingly complicated, and it can be hard to detect statically-linked copies of vulnerable third-party libraries in executables. This blog post discusses the technical details of an Apache-licensed open-source library to detect code from other open-source libraries in executables, along with some real-world findings of forked open-source libraries in real-world software.