Cranelift, Part 3: Correctness in Register Allocation
In this post, I will cover how we worked to ensure correctness in our register allocator, regalloc.rs, by developing a symbolic checker that uses abstract interpretation to prove correctness for a specific register allocation result. By using this checker as a fuzzing oracle, and driving just the register allocator with a focused fuzzing target, we have been able to uncover some very interesting and subtle bugs, and achieve a fairly high confidence in the allocator’s robustness.
IJON: Exploring Deep State Spaces via Fuzzing
In this paper, we propose IJON, an annotation mechanism that a human analyst can use to guide the fuzzer. In contrast to the two aforementioned techniques, this approach allows a more systematic exploration of the program’s behavior based on the data representing the internal state of the program. As a consequence, using only a small (usually one line) annotation, a user can help the fuzzer to solve previously unsolvable challenges. We extended various AFL-based fuzzers with the ability to annotate the source code of the target application with guidance hints. Our evaluation demonstrates that such simple annotations are able to solve problems that—to the best of our knowledge—no other current fuzzer or symbolic execution based tool can overcome. For example, with our extension, a fuzzer is able to play and solve games such as Super Mario Bros. or resolve more complex patterns such as hash map lookups. To further demonstrate the capabilities of our annotations, we use AFL combined with IJON to uncover both novel security issues and issues that previously required a custom and comprehensive grammar to be uncovered. Lastly, we show that using IJON and AFL, one can solve many challenges from the CGC data set that resisted all fully automated and human guided attempts so far.
Hypervisor Necromancy; Reanimating Kernel Protectors
In this (rather long) article we will be investigating methods to emulate proprietary hypervisors under QEMU, which will allow researchers to interact with them in a controlled manner and debug them. Specifically, we will be presenting a minimal framework developed to bootstrap Samsung S8+ proprietary hypervisor as a demonstration, providing details and insights on key concepts on ARM low level development and virtualization extensions for interested readers to create their own frameworks and Actually Compile And Boot them ;). Finally, we will be investigating fuzzing implementations under this setup.
Helping Generative Fuzzers Avoid Looking Only Where the Light is Good
Using a generative fuzzer — which creates test cases from scratch, rather than mutating a collection of seed inputs — feels to me a lot like being the drunk guy in the joke: we’re looking for bugs that can be triggered by inputs that the generator is likely to generate, because we don’t have an obviously better option, besides doing some hard work in improving the generator. This problem has bothered me for a long time.
Binary symbolic execution with KLEE-Native
KLEE is a symbolic execution tool that intelligently produces high-coverage test cases by emulating LLVM bitcode in a custom runtime environment. Yet, unlike simpler fuzzers, it’s not a go-to tool for automated bug discovery. Despite constant improvements by the academic community, KLEE remains difficult for bug hunters to adopt. We’re working to bridge this gap!
My internship produced KLEE-Native; a version of KLEE that can concretely and symbolically execute binaries, model heap memory, reproduce CVEs, and accurately classify different heap bugs. The project is now positioned to explore applications made possible by KLEE-Native’s unique approaches to symbolic execution. We will also be looking into potential execution time speed-ups from different lifting strategies. As with all articles on symbolic execution, KLEE is both the problem and the solution.
Write Fuzzable Code
Fuzzing is sort of a superpower for locating vulnerabilities and other software defects, but it is often used to find problems baked deeply into already-deployed code. Fuzzing should be done earlier, and moreover developers should spend some effort making their code more amenable to being fuzzed.
This post is a non-comprehensive, non-orthogonal list of ways that you can write code that fuzzes better. Throughout, I’ll use “fuzzer” to refer to basically any kind of randomized test-case generator, whether mutation-based (afl, libFuzzer, etc.) or generative (jsfunfuzz, Csmith, etc.). Not all advice will apply to every situation, but a lot of it is sound software engineering advice in general. I’ve bold-faced a few points that I think are particularly important.
Down the Rabbit-Hole...
I often find it valuable to write simple test cases confirming things work the way I think they do. Sometimes I can’t explain the results, and getting to the bottom of those discrepancies can reveal new research opportunities. This is the story of one of those discrepancies; and the security rabbit-hole it led me down.
Any application, any user - even sandboxed processes - can connect to any CTF session. Clients are expected to report their thread id, process id and HWND, but there is no authentication involved and you can simply lie. Secondly, there is nothing stopping you pretending to be a CTF service and getting other applications - even privileged applications - to connect to you.
Even without bugs, the CTF protocol allows applications to exchange input and read each other’s content. However, there are a lot of protocol bugs that allow taking complete control of almost any other application.
Regarding disclosure: https://bugs.chromium.org/p/project-zero/issues/detail?id=1859#c10
Bzip2 And The Cve That Wasn’t
Compiling with the GCC sanitizers and then fuzzing the resulting binaries might find real bugs. But not all such bugs are security issues. When a CVE is filed there is some pressure to treat such an issue with urgency and push out a fix as soon as possible. But taking your time and making sure an issue can be replicated/exploited without the binary being instrumented by the sanitizer is often better.
I don’t think anything went wrong here, but some interesting details.
Design and Evolution of C-Reduce
Since 2008, my colleagues and I have developed and maintained C-Reduce, a tool for programmatically reducing the size of C and C++ files that trigger compiler bugs. C-Reduce also usually does a credible job reducing test cases in languages other than C and C++; we’ll return to that later.
Part 2: https://blog.regehr.org/archives/1679
KPMG Audit Professionals Manipulated the Scoring of Training Exams
In today’s edition of edit a URL and go to jail...
KPMG sent participants in training programs a hyperlink that directed them to the applicable exams. Embedded in the hyperlink was an instruction to the server that specified the score necessary to pass the exam. Thus, the characters “MasteryScore=70” meant participants were required to answer at least 70 percent of the answers accurately to pass the exam. By changing the number in the hyperlink, audit professionals could change the score required to pass.
58. For a period of time up to November 2015, certain audit professionals, including one partner, altered the URLs for their exams to lower the scores required to pass. Twenty-eight of these auditors did so on four or more occasions. Certain audit professionals lowered the required score to the point of passing exams while answering less than 25 percent of the questions correctly.
Also: 25%??? Come on guys, that’s worse than random chance!
Provoking browser quirks with behavioural fuzzing
The first bug I want to talk about is how to close a HTML comment in a different way. If you read the HTML specification you’ll know that you can close a comment with --> or --!> but what about another way? This is a great question to start off fuzzing with. You just then need to generate some code that answers that question.
Reverse-engineering Broadcom wireless chipsets
In this blogpost I provided an account of various activities during my 6 months as an intern at Quarkslab, my project involved understanding the Linux kernel drivers, analyzing Broadcom firmware, reproducing publicly known vulnerabilities, working on an emulator to run portions of firmware, fuzzing and finding 5 vulnerabilities (CVE-2019-8564, CVE-2019-9500, CVE-2019-9501, CVE-2019-9502, CVE-2019-9503). Two of those vulnerabilities are present both in the Linux kernel and firmware of affected Broadcom chips. The most common exploitation scenario leads to a remote denial of service. Although it is technically challenging to achieve, exploitation for remote code execution should not be discarded as the worst case scenario.
Don’t miss the disclosure timeline at the end.
The Fuzzing Hype-Train: How Random Testing Triggers Thousands of Crashes
Despite massive efforts, finding and reproducing bugs is incredibly hard. Fuzzing is an efficient way of discovering security critical bugs by triggering exceptions such as crashes, memory corruption, or assertion failures automatically (or with a little help) and comes with a witness (proof of the vulnerability) that allows developers to reproduce the bug and fix it.
Notes on fuzzing ImageMagick and GraphicsMagick
Given the gaping chasm between what was expected and the massive success of OSS-Fuzz on ImageMagick and GraphicsMagick I thought it would be helpful to review what factors I thought were contributing to OSS-Fuzz finding so many vulnerabilities and other bugs:
Remotely compromise devices by using bugs in Marvell Avastar Wi-Fi: from zero knowledge to zero-click RCE
With this research, I’m going to answer the question that has had to be answered for quite a time: to what extent is Marvell WiFi FullMAC SoC (not) secure. Since the wireless devices with the analyzed chip aren’t fully researched by the community yet, they may contain a tremendous volume of unaudited code, which may result in severe security issues swarming devices equipped with WLAN cards.
How to write a rootkit without really trying
We open-sourced a fault injection tool, KRF, that uses kernel-space syscall interception. You can use it today to find faulty assumptions (and resultant bugs) in your programs. Check it out!
This post covers intercepting system calls from within the Linux kernel, via a plain old kernel module. We’ll go through a quick refresher on syscalls and why we might want to intercept them and then demonstrate a bare-bones module that intercepts the read(2) syscall.
MicroWalk: A Framework for Finding Side Channels in Binaries
In this work, we propose a novel technique based on Dynamic Binary Instrumentation and Mutual Information Analysis to efficiently locate and quantify memory based and control-flow based microarchitectural leakages. We develop a software framework named MicroWalk for side-channel analysis of binaries which can be extended to support new classes of leakage. For the first time, by utilizing MicroWalk, we perform rigorous leakage analysis of two widely-used closed-source cryptographic libraries: Intel IPP and Microsoft CNG. We analyze 15 different cryptographic implementations consisting of 112 million instructions in about 105 minutes of CPU time. By locating previously unknown leakages in hardened implementations, our results suggest that MicroWalk can efficiently find microarchitectural leakages in software binaries.
Vectorized Emulation: Hardware accelerated taint tracking at 2 trillion instructions per second
In this blog I’m going to introduce you to a concept I’ve been working on for almost 2 years now. Vectorized emulation. The goal is to take standard applications and JIT them to their AVX-512 equivalent such that we can fuzz 16 VMs at a time per thread. The net result of this work allows for high performance fuzzing (approx 40 billion to 120 billion instructions per second [the 2 trillion clickbait number is theoretical maximum]) depending on the target, while gathering differential coverage on code, register, and memory state.
Further since we’re running emulated code we are able to run a soft MMU implementation which has byte-level permissions. This gives us stronger-than-ASAN memory protections, making bugs fail faster and cleaner.
How I’ve found vulnerability in a popular Rust crate (and you can too)
I have recently discovered a zero-day vulnerability in a fairly popular and well-designed Rust crate. In this article I’m going to discuss how I did it and why it wasn’t discovered earlier, and introduce a new tool, libdiffuzz, that I’ve created for the job. A recently discovered vulnerability in Rust standard library makes a cameo appearance.
Fuzzing the OpenBSD Kernel
Fuzzing the OpenBSD kernel using the syzkaller kernel fuzzer.
A driver for tracking kernel code coverage.
Enabled on a per thread basis.
The kernel program counter is tracked during syscalls made by the same thread.
Not a strict requirement for syzkaller but improves its ability to generate interesting programs.