Diary of a reverse-engineer

Because we like to play with weird things.

Token Capture via an Llvm-based Analysis Pass

Introduction

About three years ago, the LLVM framework started to pique my interest for a lot of different reasons. This collection of industrial strength compiler technology, as Latner said in 2008, was designed in a very modular way. It also looked like it had a lot of interesting features that could be used in a lot of (different) domains: code-optimization (think deobfuscation), (architecture independent) code obfuscation, static code instrumentation (think sanitizers), static analysis, for runtime software exploitation mitigations (think cfi, safestack), power a fuzzing framework (think libFuzzer), ..you name it.

A lot of the power that came with this giant library was partly because it would operate in mainly three stages, and you were free to hook your code in any of those: front-end, mid-end, back-end. Other strengths included: the high number of back-ends, the documentation, the C/C++ APIs, the community, ease of use compared to than gcc (see below from kcc’s presentation), etc.

The front-end part takes as input source code and generates LLVM IL code, the middle part operates on LLVM IL and finally the last one receives LLVM IL in order to output assembly code and or an executable file.

In this post we will walk through a simple LLVM pass that does neither optimization, nor obfuscation; but acts more as a token finder for fuzzing purposes.

Keygenning With KLEE

Introduction

In the past weeks I enjoyed working on reversing a piece of software (don’t ask me the name), to study how serial numbers are validated. The story the user has to follow is pretty common: download the trial, pay, get the serial number, use it in the annoying nag screen to get the fully functional version of the software.

Since my purpose is to not damage the company developing the software, I will not mention the name of the software, nor I will publish the final key generator in binary form, nor its source code. My goal is instead to study a real case of serial number validation, and to highlight its weaknesses.

In this post we are going to take a look at the steps I followed to reverse the serial validation process and to make a key generator using KLEE symbolic virtual machine. We are not going to follow all the details on the reversing part, since you cannot reproduce them on your own. We will concentrate our thoughts on the key-generator itself: that is the most interesting part.

Spotlight on an Unprotected AES128 White-box Implementation

Introduction

I think it all began when I’ve worked on the NSC2013 crackme made by @elvanderb, long story short you had an AES128 heavily obfuscated white-box implementation to break. The thing was you could actually solve the challenge in different ways:

  1. the first one was the easiest one: you didn’t need to know anything about white-box, crypto or even AES ; you could just see the function as a black-box & try to find “design flaws” in its inner-workings
  2. the elite way: this one involved to understand & recover the entire design of the white-box, then to identify design weaknesses that allows the challenger to directly attack & recover the encryption key. A really nice write-up has been recently written by @doegox, check it out, really :): Oppida/NoSuchCon challenge.

The annoying thing is that you don’t have a lot of understandable available C code on the web that implement such things, nevertheless you do have quite some nice academic references ; they are a really good resource to build your own.

This post aims to present briefly, in a simple way what an AES white-box looks like, and to show how its design is important if you want to not have your encryption key extracted :). The implementation I’m going to talk about today is not my creation at all, I just followed the first part (might do another post talking about the second part? Who knows) of a really nice paper (even for non-mathematical / crypto guys like me!) written by James A. Muir.

The idea is simple: we will start from a clean AES128 encryption function in plain C, we will modify it & transform it into a white-box implementation in several steps. As usual, all the code are available on my github account; you are encourage to break & hack them!

Of course, we will use this post to briefly present what is the white-box cryptography, what are the goals & why it’s kind of cool.

Before diving deep, here is the table of contents:

Taming a Wild Nanomite-protected MIPS Binary With Symbolic Execution: No Such Crackme

As last year, the French conference No Such Con returns for its second edition in Paris from the 19th of November until the 21th of November. And again, the brilliant Eloi Vanderbeken & his mates at Synacktiv put together a series of three security challenges especially for this occasion. Apparently, the three tasks have already been solved by awesome @0xfab which won the competition, hats off :).

To be honest I couldn’t resist to try at least the first step, as I know that Eloi always builds really twisted and nice binaries ; so I figured I should just give it a go!

But this time we are trying something different though: this post has been co-authored by both Emilien Girault (@emiliengirault) and I. As we have slightly different solutions, we figured it would be a good idea to write those up inside a single post. This article starts with an introduction to the challenge and will then fork, presenting my solution and his.

As the article is quite long, here is the complete table of contents:

Dissection of Quarkslab’s 2014 Security Challenge

Introduction

As the blog was a bit silent for quite some time, I figured it would be cool to put together a post ; so here it is folks, dig in!

The French company Quarkslab recently released a security challenge to win a free entrance to attend the upcoming HITBSecConf conference in Kuala Lumpur from the 13th of October until the 16th.

The challenge has been written by Serge Guelton, a R&D engineer specialized in compilers/parallel computations. At the time of writing, already eight different people manage to solve the challenge, and one of the ticket seems to have been won by hackedd, so congrats to him!

According to the description of the challenge Python is heavily involved, which is a good thing for at least two reasons:

In this post I will describe how I tackled this problem, how I managed to solve it. And to make up for me being slow at solving it I tried to make it fairly detailed.

At first it was supposed to be quite short though, but well..I decided to analyze fully the challenge even if it wasn’t needed to find the key unfortunately, so it is a bit longer than expected :–).

Anyway, sit down, make yourself at home and let me pour you a cup of tea before we begin :–).

Corrupting the ARM Exception Vector Table

Introduction

A few months ago, I was writing a Linux kernel exploitation challenge on ARM in an attempt to learn about kernel exploitation and I thought I’d explore things a little. I chose the ARM architecture mainly because I thought it would be fun to look at. This article is going to describe how the ARM Exception Vector Table (EVT) can aid in kernel exploitation in case an attacker has a write what-where primitive. It will be covering a local exploit scenario as well as a remote exploit scenario. Please note that corrupting the EVT has been mentioned in the paper “Vector Rewrite Attack”[1], which briefly talks about how it can be used in NULL pointer dereference vulnerabilities on an ARM RTOS.

The article is broken down into two main sections. First a brief description of the ARM EVT and its implications from an exploitation point of view (please note that a number of things about the EVT will be omitted to keep this article relatively short). We will go over two examples showing how we can abuse the EVT.

I am assuming the reader is familiar with Linux kernel exploitation and knows some ARM assembly (seriously).

Deep Dive Into Python’s VM: Story of LOAD_CONST Bug

Introduction

A year ago, I’ve written a Python script to leverage a bug in Python’s virtual machine: the idea was to fully control the Python virtual processor and after that to instrument the VM to execute native codes. The python27_abuse_vm_to_execute_x86_code.py script wasn’t really self-explanatory, so I believe only a few people actually took some time to understood what happened under the hood. The purpose of this post is to give you an explanation of the bug, how you can control the VM and how you can turn the bug into something that can be more useful. It’s also a cool occasion to see how works the Python virtual machine from a low-level perspective: what we love so much right?

But before going further, I just would like to clarify a couple of things:

  • I haven’t found this bug, this is quite old and known by the Python developers (trading safety for performance), so don’t panic this is not a 0day or a new bug ; can be a cool CTF trick though
  • Obviously, YES I know we can also “escape” the virtual machine with the ctypes module ; but this is a feature not a bug. In addition, ctypes is always “removed” from sandbox implementation in Python

Also, keep in mind I will focus Python 2.7.5 x86 on Windows ; but obviously this is adaptable for other systems and architectures, so this is left as an exercise to the interested readers. All right, let’s move on to the first part: this one will focus the essentials about the VM, and Python objects.

First Dip Into the Kernel Pool : MS10-058

Introduction

I am currently playing with pool-based memory corruption vulnerabilities. That’s why I wanted to program a PoC exploit for the vulnerability presented by Tarjei Mandt during his first talk “Kernel Pool Exploitation on Windows 7” [3]. I think it’s a good exercise to start learning about pool overflows.

Forewords

If you want to experiment with this vulnerability, you should read [1] and be sure to have a vulnerable system. I tested my exploit on a VM with Windows 7 32 bits with tcpip.sys 6.1.7600.16385. The Microsoft bulletin dealing with this vulnerability is MS10-058. It has been found by Matthieu Suiche [2] and was used as an example on Tarjei Mandt’s paper [3].

Triggering the flaw

An integer overflow in tcpip!IppSortDestinationAddresses allows to allocate a wrong-sized non-paged pool memory chunk. Below you can see the diff between the vulnerable version and the patched version.

Having a Look at the Windows’ User/Kernel Exceptions Dispatcher

Introduction

The purpose of this little post is to create a piece of code able to monitor exceptions raised in a process (a bit like gynvael’s ExcpHook but in userland), and to generate a report with information related to the exception. The other purpose is to have a look at the internals of course.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--Exception detected--
ExceptionRecord: 0x0028fa2c Context: 0x0028fa7c
Image Path: D:\Codes\The Sentinel\tests\divzero.exe
Command Line: ..\tests\divzero.exe divzero.exe
PID: 0x00000aac
Exception Code: 0xc0000094 (EXCEPTION_INT_DIVIDE_BY_ZERO)
Exception Address: 0x00401359
EAX: 0x0000000a EDX: 0x00000000 ECX: 0x00000001 EBX: 0x7ffde000
ESI: 0x00000000 EDI: 0x00000000 ESP: 0x0028fee0 EBP: 0x0028ff18
EIP: 0x00401359
EFLAGS: 0x00010246

Stack:
0x767bc265 0x54f3620f 0xfffffffe 0x767a0f5a
0x767ffc59 0x004018b0 0x0028ff90 0x00000000

Disassembly:
00401359 (04) f77c241c                 IDIV DWORD [ESP+0x1c]
0040135d (04) 89442404                 MOV [ESP+0x4], EAX
00401361 (07) c7042424304000           MOV DWORD [ESP], 0x403024
00401368 (05) e833080000               CALL 0x401ba0
0040136d (05) b800000000               MOV EAX, 0x0

That’s why I divided this post in two big parts:

  • the first one will talk about Windows internals background required to understand how things work under the hood,
  • the last one will talk about Detours and how to hook ntdll!KiUserExceptionDispatcher toward our purpose. Basically, the library gives programmers a set of APIs to easily hook procedures. It also has a clean and readable documentation, so you should use it! It is usually used for that kind of things:
    • Hot-patching bugs (no need to reboot),
    • Tracing API calls (API Monitor like),
    • Monitoring (a bit like our example),
    • Pseudo-sandboxing (prevent API calls),
    • etc.

Breaking Kryptonite’s Obfuscation: A Static Analysis Approach Relying on Symbolic Execution

Introduction

Kryptonite was a proof-of-concept I built to obfuscate codes at the LLVM intermediate representation level. The idea was to use semantic-preserving transformations in order to not break the original program. One of the main idea was for example to build a home-made 32 bits adder to replace the add LLVM instruction. Instead of having a single asm instruction generated at the end of the pipeline, you will end up with a ton of assembly codes doing only an addition. If you never read my article, and you are interested in it here it is: Obfuscation of steel: meet my Kryptonite.

In this post I wanted to show you how we can manage to break that obfuscation with symbolic execution. We are going to write a really tiny symbolic execution engine with IDAPy, and we will use Z3Py to simplify all our equations. Note that a friend of mine @elvanderb used a similar approach (more generic though) to simplify some parts of the crackme ; but he didn’t wanted to publish it, so here is my blog post about it!