The Backdoor Foundry: A Toolchain for Building Application Specific Implants

Presented at REcon 2019, June 28, 2019, 4:30 p.m. (30 minutes).

In this presentation I show a method for "linking" in additional code to ELF files in a way which is more robust than demonstrated by "the backdoor factory". # Presentation Outline ## Speaker Introduction My name is Evan Jensen. In August, I will have studied RE for ten years. Since graduating with my BS in computer science I've been working in offense oriented roles for government and private organizations. Today I run the Boston Cybernetics Institute where I empower people to control technology and I would like to do the same for the audience. ## Topic Introduction I'll introduce, in an approachable way, the desired capability and the challenges that have prevented such a capability from emerging. I'll talk about what an executable container is and the advantages it provides using the Executable and Linkable Format(ELF) when needed for concrete examples. I'll talk about the software build lifecycle, with emphasis on linking and what the linker does to ultimately enable the loader to do its job. I'll reference prior art in the application backdoor space including the construction of an unsophisticated application "binder" and the improvements brought by "The Backdoor Factory" authored by Joshua "midnite_runr" Pitts. I'll highlight the drawbacks of existing solutions before moving on to an in depth exploration of the problem space. ## ELF File Format Deep Dive Since ELF files are the subject of this research it's important to understand their component parts and to learn what artifacts are emitted, processed, preserved and discarded during a typical build cycle, such as with `clang` or `gcc`. In this part of the presentation I'll show how symbols are stored and manipulated in an ELF, the attributes they can be described with, how static and dynamic relocation is performed, the function of "section" and "program" headers, the dynamic table, and the data structures that make everything possible. ## Linking Algorithm The closest piece of software to what I'm releasing is a static linker. In this part of the presentation I cover all of the material needed to understand the operation of a linker and how the linker sets up the operating system loader for success and ultimately program launch. The "linking" process I developed and demonstrate here diverges from the standard linking process because the objects being "linked" are an already linked program and one or more relocatable objects. When processing fully linked programs less information is available because during standard linking, data like the static relocation table is typically discarded. In the case of striped executables, as much data is deleted as possible while keeping a executable functional. ## Additional Features Here I discuss the opportunities that this new "post-linking" software environment presents. For example I can insert new shared library dependencies or insert new symbols into a given application and then manipulate the referenced data from my inserted high level code. I can also use a C++ name mangling inspired approach to manipulate the operation of the binary rewriter/relinker from source. An example of influencing rewriter behavior from source is by treating some C++ namespaces differently. If a variable is declared in a specific C++ namespace I can emit the appropriate ELF records to coerce the operating system's dynamic loader to search for functions in external libraries and write function pointers on top of the namespace variables. These can then be used as standard function pointers. ## Demo Here I demo a small application specific backdoor that I developed for Ubuntu's dynamic linker. Because almost all applications load the dynamic linker, rewriting it enables foreign code to run inside the context of almost every application on a given system. This is a good test of overall system robustness because the dynamic linker makes almost no assumptions about the environment it gets loaded into and as it copes with unpredictable programs and runtimes so must any passenger code. In general it is possible to backdoor a given dynamic loader at the source level but it may not be possible to predict the specific dynamic loader installed on a target system before compromising it. The binary rewriting approach is more powerful because it does not make assumptions about targets other that they are well formatted ELF files. ## Conclusion A summary of what I was able to accomplish and description of how the techniques presented can be generalized to write creative linkers for other executable container formats. I will also give examples of other uses for The Backdoor Foundry such as performance testing, generic application introspection, application hardening, fuzzing and more.

Presenters:

  • Evan Jensen
    Evan Jensen (@jensensec) is the co-founder and CTO of the Boston Cybernetics Institute (BCI) where he splits his time between conducting assessments for clients, performing security research and teaching cybersecurity courses. Evan has taught reverse-engineering at BU, RPI, NYU, MIT, West Point and MIT Lincoln Laboratory. He is currently an instructor at Tufts University, where he teaches the course Fundamentals of Software Reverse-Engineering. Outside of work he is a community organizer and CTF player. Evan wrote much of "The CTF Field Guide" and captained two CTF teams: Brooklynt_Overflow from 2012 to 2014 and Lab RATs from 2014 to 2016. He also runs @beansec, one of the oldest CitySec meetups in the United States, you're all invited.

Links:

Similar Presentations: