Introduction to the Witchcraft Compiler Collection

Jonathan Brossard

5th of August

DEFCON 24, Las Vegas,

2016

USA

TL ; DR

The Witchcraft Compiler Collection is free software (MIT/BSD License).

I would love you to extend it and contribute to WCC on https://github.com/endrazine/wcc

You can write in Lua, Punk-C or C.

No assembly skills required.

Who am I ?

Image courtesy of Pixabay (https://pixabay.com/en/museum-mask-africa- african-cult-953595/)

https://www.defcon.org/images/defcon-20/dc-20-presentations/Brossard/ DEFCON-20-Brossard-Hardware-Backdooring-is-Practical.pdf

https://

media.blackhat.com/bh-us-11/Brossard/BH_US_11_Brossard_Post_Memory_ WP.pdf

+ Nullcon Goa, which is awesome :)

+add your own preferred conferences around the globe here :) #NonExhaustiveList

DISCLAIMER S

DISCLAIMER

My employers are not associated with this talk in any way.

This is my personal research.

LEGAL HELP

This talk received help from the EFF.

Warmest thank you to Nate Cardozo, Andrew Crocker and Mitch Stoltz

Free legal advising to security researchers :

https://www.ef.org/ https://www.ef.org/issues/coders/reverse- engineering-faq

WE’RE RECRUITING

Fcrnx gb bhe fravbe frphevgl UE:

Wnzrf Fnyr

[email protected]

uggc://jjj.yvaxrqva.pbz/va/wnzrftfnyr

Tbbq yhpx !

AGENDA

Motivation

WCC components

“Libifying” a binary

Unlinking binaries

Crossing a Fish and a Rabbit

Introduction to Witchcraft

Binary “refection” without a VM

Towards binary self awareness

Future work

MOTIVATION

Prerequisites: A binary you have the right to reverse engineer. No source code.

Case studies:

1)You would like to verify the results of a static analysis

2)You know a way to crash an application but don’t want to work on the entire binary (eg: remote fuzzing).

Let’s work on the ELF 64b version of smbserver-1.5.32.

CASE STUDY : STATIC

ANALYSIS

STATIC ANALYSIS

STATIC ANALYSIS

STATIC ANALYSIS

STATIC ANALYSIS

STATIC ANALYSIS

We have only a partial symbolic stack trace. How to verify if this vulnerability exists ?

Wouldn’t it be nice if we could call reply_close() with arbitrary arguments directly ?

CASE STUDY : FUZZING

You are fuzzing a complex server (smbd) over the network.

CASE STUDY : FUZZING

We have only a partial symbolic stack trace.

This could be a worker thread (note: smbd is linked with libpthread).

I don’t want to resend new packets or restart threads when analyzing !

Bonus points if you triggered it via instrumentation/concolic execution and don’t actually have a trigger either.

Can we verify if this vulnerability is exploitable ?

Wouldn’t it be nice to call

rpc_clnt_record_build_header() or any function in client.so with arbitrary arguments directly ?

PROBLEM STATEMENT

You can do the later with some work (exported functions from shared libraries) but in theory, not the former ever ever (function directly within a binary).

Let’s make both possible with 0 code nor reverse

engineering.

WCC COMPONENTS

Binaries (C):

wld : witchcraft linker

wcc : witchcraft core compiler

wsh : witchcraft shell : dynamic interpreter + scripting engine

Scripts (lua, …):

wcch : witchcraft header generator

wldd : witchcraft compiler fags generator

...

Host machine : GNU/Linux x86_64 (mostly portable to POSIX systems).

WLD : “LIBIFICATION”

Transforming an ELF executable binary into an ELF shared library.

DEMOS

A word on decompiling

LIBIFICATION

typedef struct

{

unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */

Elf64_Half e_type;

/* Object fle type */

Elf64_Half e_machine;

/* Architecture */

Elf64_Word e_version;

/* Object fle version */

Elf64_Addr e_entry;

/* Entry point virtual address */

Elf64_Of e_phof;

/* Program header table fle ofset */

Elf64_Of e_shof;

/* Section header table fle ofset */

Elf64_Word e_fags;

/* Processor-specifc fags */

Elf64_Half e_ehsize;

/* ELF header size in bytes */

Elf64_Half e_phentsize;

/* Program header table entry size */

Elf64_Half e_phnum;

/* Program header table entry count */

Elf64_Half e_shentsize;

/* Section header table entry size */

Elf64_Half e_shnum;

/* Section header table entry count */

Elf64_Half e_shstrndx;

/* Section header string table index */

} Elf64_Ehdr;

 

DEMOS

Libifcation of proftpd

LIBIFICATION OF PROFTPD

WE REALLY PATCHED 1 BYTE

ONLY

USING OUR NEW SHARED

LIBRARY

HOW COMES THIS WORKS ?

We’re really creating a “non relocatable” shared library.

ET_DYN and ET_EXEC ELF fles are both executable (ASLR support in the kernel)

This is equivalent to creating a shared library with a non NULL base address (equivalent to prelinking)

Note: Amazingly, this shared library is still a valid executable too.

DEMOS

Linking against apache2

APACHE2 AS A SHARED

LIBRARY

APACHE2 AS A SHARED

LIBRARY

WCC : “UNLINKING”

The typical approach to reverse engineering is to transform binaries or shared libraries back to source code.

Instead, we aim at transforming fnal binaries or shared libraries back to ELF relocatable objects, that can later be relinked normally (using gcc/ld) into executables or shared objects.

This binary refactoring is enough to “reuse” (steal) binary functions without any disassembly. This is no longuer true : some relocations require some disassembly. We used the capstone disassembly library to perform this.

WCC : “UNLINKING”

Source code

Compiler

Relocatable

objects

(*.o)

L i n k e r

Binaries

(executables, shared libs…)

WCC : “UNLINKING”

Source code

Compiler

Decompiler

Relocatable

objects

(*.o)

L i n k e r

Binaries

(executables, shared libs…)

WCC : “UNLINKING”

Source code

Compiler

Decompiler

Relocatable

objects

(*.o)

L i n k e r

Binaries

(executables, shared libs…)

UNLINKING

Source code

Compiler

Decompiler

Relocatable

objects

 

(*.o)

 

L

w

i

n

c

k

e

c

r

Binaries

(executables, shared libs…)

WCC : COMMAND LINE

The command line is made to resemble the syntax of gcc :

WCC : INTERNALS

The front end is build around libbfd. The backend is trivial C to copy each mapped section of the binary, handle symbols and relocations.

Beneft of using libbfd : the input binary doesn’t need to be an ELF !

=> We can for instance transform a Win64 executable into ELF 64b relocatable objects…

DEMO

(Binary to object fle to relocatable

to unstripped library)

WCC : DEMO

DEMO

(Crossing a Fish and a Rabbit)

PE + ELF = PELF

WCC : PE32 TO ELF64

DEMO

Native OpenBSD on linux

WITCHCRAFT

(Punk-C/Punxie)

PUNK-C LANGUAGE (WSH)

Lua Interpreter

+

“Refected” C

API

=

INTRODUCTION TO

WITCHCRAFT

BINARY “REFLECTION”

WITHOUT A VM

Now that we know how to transform arbitrary binaries into shared libraries, we can load them into our address space via dlopen().

Let’s implement the same features as traditional virtual machines, but for raw binaries !

Whish list :

-Load arbitrary applications into memory

-Execute arbitrary functions with any arguments (and get results)

-Monitor/Trace execution

-Automated functions prototyping/annotation

-Learn new behavior

-Examine/Modify arbitrary memory

WSH : ARCHITECTURE

Loading is done via dlopen().

The core engine/shell is built around lua.

Can be compiled with luajit to get JIT compilation.

Tracing/Memory analysis doesn’t rely on ptrace() : we share the address space.

Lightweight : ~5k lines of C.

No disassembler (as of writing. Subject to change). No need for /proc support !

Function names mapped in each library is dumped from the link_map cache.

WSH : THE WICHCRAFT

INTERPRETER

Distinctive features:

-We fully share the address space with analyzed applications (no ptrace() nor context switches).

-Requires no privileges/capabilities (no root, no ptrace(), no CAP_PTRACE, no /proc…)

-No disassembly : fully portable (POSIX)

-Implements “refection” for binaries

-Full featured programming language

-Interactive and/or fully scriptable, autonomous programs

-Has no types

-Has no fxed API : any function you load in memory becomes available in WSH

-Functions have no prototypes

=> Can call arbitrary functions without knowing their prototypes => Allows for extended function annotations (to be fully automated) => Steal/Reuse any code. Add scripting to any application.

NONE OF THIS IS SUPPOSED TO WORK

WSH : THE WICHCRAFT

INTERPRETER

Advanced features:

-Loads any code via dlopen() : this solves relocations, symbols resolution, dependencies for us.

-Secondary loader bfd based (could load invalid binaries, anything in memory).

-Dumping of dynamic linker cash internals (undocumented) : linkmap

-Breakpoints without int 0x03 (use SIGINVALID + invalid opcode)

-Bruteforcing of mapped memory pages via msync() (0day, no /proc needed)

-Wsh can be compiled to do JIT compilation on the fy at runtime.

-Automated fuzzing/extended prototyping/functional testing

NONE OF THIS IS SUPPOSED TO WORK

WITCHCRAFT

DEMO

TOWARDS BINARY SELF

AWARENESS

Consciousness 1.0

SELF AWARENESS

“Self-awareness is the capacity for introspection and the ability to recognize oneself as an individual separate from the environment and other individuals.”

https://en.wikipedia.org/wiki/Self-awareness

“Consciousness is the state or quality of awareness, or, of being aware of an external object or something within oneself. It has been defned as: sentience, awareness, subjectivity, the ability to experience or to feel, wakefulness, having a sense of selfhood, and the executive control system of the mind.”

https://en.wikipedia.org/wiki/Consciousness

WITCHCRAFT

Numerical solutions

WITCHCRAFT

FUTURE WORK

FUTURE WORK

-Hyde our own presence better in memory (second heap)

-Remote debugging, running process injection

-Shadow mapping, internal libraries tracing (recursive ltrace)

-ltrace/strace to valid scripts

-system call tracing

TO BE CONTINUED

Questions ?