Static instrumentation based on executable file formats About - - PowerPoint PPT Presentation

static instrumentation based on executable file formats
SMART_READER_LITE
LIVE PREVIEW

Static instrumentation based on executable file formats About - - PowerPoint PPT Presentation

Romain Thomas - rthomas@quarkslab.com Static instrumentation based on executable file formats About Romain Thomas - Security engineer at Quarkslab Working on various topics: Android, (de)obfuscation, software protection and reverse


slide-1
SLIDE 1

Romain Thomas - rthomas@quarkslab.com

Static instrumentation based on executable file formats

slide-2
SLIDE 2

About

Romain Thomas - Security engineer at Quarkslab Working on various topics: Android, (de)obfuscation, software

protection and reverse engineering

Author of LIEF

slide-3
SLIDE 3

Executable Formats

Executable Formats: Overview

slide-4
SLIDE 4

Executable Formats

First layer of information when analysing a binary

1entrypoint, libraries, ...

slide-5
SLIDE 5

Executable Formats

First layer of information when analysing a binary Provide metadata1 used by the operating system to load the binary.

1entrypoint, libraries, ...

slide-6
SLIDE 6

Executable Formats

OSX / iOS: Mach-O Linux: ELF Windows: PE Android: ELF, OAT

slide-7
SLIDE 7

Executable Formats

Why modify formats ?

slide-8
SLIDE 8

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-9
SLIDE 9

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-10
SLIDE 10

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-11
SLIDE 11

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-12
SLIDE 12

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-13
SLIDE 13

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-14
SLIDE 14

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-15
SLIDE 15

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-16
SLIDE 16

Executable Formats

More privileged area Userland

Format Loader Kernel

Perform relocations Load shared libraries Create Process Map content Set permissions Change segments / sections permissions Add shared libraries Disable ASLR

slide-17
SLIDE 17

Executable Formats

LIEF: Library to Instrument Executable Formats

slide-18
SLIDE 18

LIEF

One library to deal with ELF, PE, Mach-O Core in C++ Bindings for different languages: Python, C 2, . . . Enable modification on these formats User friendly API

2C binding is not as mature as Python and C++

slide-19
SLIDE 19

Executable Formats

Parser ELF Binary Object PE Binary Object Mach-O Fat Binary Object OAT Binary Object DEX File Object VDEX File Object ART File Object Abstract Binary Builder

Information extraction Information adding . . .

slide-20
SLIDE 20

Executable Formats

import lief target = lief.parse("ELF/PE/Mach-O/OAT") print(target.entrypoint)

slide-21
SLIDE 21

Executable Formats

import lief target = lief.parse("ELF/PE/Mach-O/OAT") for section in target.sections: print(section.virtual_address) process(section.content)

slide-22
SLIDE 22

Executable Formats

import lief target = lief.parse("some.exe") target.tls.callbacks.append(0x....) target.write("new.exe")

slide-23
SLIDE 23

Executable Formats

import lief target = lief.parse(...) section = lief.ELF.Section(".text2") section.content = [0x90] * 0x1000 target += section target.write("new.elf")

slide-24
SLIDE 24

Executable Formats

Next parts introduce interesting modifications on formats:

Hooking Exporting hidden functions Code injection through shared libraries

slide-25
SLIDE 25

PE Hooking

PE Hooking

slide-26
SLIDE 26

PE Hooking

Regarding to PE files, LIEF enables to rebuild the import table elsewhere in the binary so that one can add new functions, new libraries

  • r patch the Import Address Table.
slide-27
SLIDE 27

Example

Figure – Original IAT

slide-28
SLIDE 28

Example

The following code patch the IAT entry of __acrt_iob_func with a trampoline to the function 0x140008000 pe = lief.parse("some.exe") pe.hook_function("__acrt_iob_func", 0x140008000) builder = lief.PE.Builder(pe) builder.build_imports(True).patch_imports(True) builder.build() builder.write("hooked.exe")

slide-29
SLIDE 29

Example

slide-30
SLIDE 30

Example

Figure – Original IAT patched with trampoline functions

slide-31
SLIDE 31

Example

Figure – Trampoline for non-hooked function Figure – Trampoline for hooked function

slide-32
SLIDE 32

Example

This method only works if accesses to the IAT are performed with call

  • instructions. Especially it doesn’t if there is lea on the original IAT

Limitations

slide-33
SLIDE 33

ELF Hooking

Regarding to ELF files, hooking can be done with a patch of the plt/got.

slide-34
SLIDE 34

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: 0x400486 ...

slide-35
SLIDE 35

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: 0x400486 ...

slide-36
SLIDE 36

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: 0x400486 ...

slide-37
SLIDE 37

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: 0x400486 ...

slide-38
SLIDE 38

ELF plt/got

Figure – Relocations associated with plt/got

slide-39
SLIDE 39

ELF plt/got

import lief elf = lief.parse("some_elf") elf.patch_pltgot("memcmp", 0xAAAAAAAA) elf.write("elf_modified")

slide-40
SLIDE 40

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: XXXXXX <memcmp@hook> ...

.hook

... XXXXXX: memcmp hooked ...

https://lief.quarkslab.com/recon18/demo1

slide-41
SLIDE 41

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: XXXXXX <memcmp@hook> ...

.hook

... XXXXXX: memcmp hooked ...

https://lief.quarkslab.com/recon18/demo1

slide-42
SLIDE 42

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: XXXXXX <memcmp@hook> ...

.hook

... XXXXXX: memcmp hooked ...

https://lief.quarkslab.com/recon18/demo1

slide-43
SLIDE 43

ELF plt/got

1 2 3 .text

... 400637: jmp 400480 <memcmp@plt> ...

.plt

... 400480: jmp 201028 <memcmp@got> 400486: push 0x2 40048b: jmp 400450 <.plt> ...

.got

... 201028: XXXXXX <memcmp@hook> ...

.hook

... XXXXXX: memcmp hooked ...

https://lief.quarkslab.com/recon18/demo1

slide-44
SLIDE 44

Exporting Functions

Exporting Functions

slide-45
SLIDE 45

Idea

slide-46
SLIDE 46

Idea

slide-47
SLIDE 47

Example

int main(int argc, char argv[]) { if (COMPLICATED CONDITION) { fuzz_me(argv[1]); } return 0; }

slide-48
SLIDE 48

Example

slide-49
SLIDE 49

Example

Figure – Original Symbol Table

slide-50
SLIDE 50

Example

import lief target = lief.parse("target") target.add_exported_function(0x63A, "to_fuzz") target.write("target_modified")

slide-51
SLIDE 51

Example

slide-52
SLIDE 52

Example

Figure – New Symbol Table

slide-53
SLIDE 53

Example

typedef void(*fnc_t)(const char*); // Access with dlopen / dlsym void* hdl = dlopen("./target_modified", RTLD_LAZY); fnc_t to_fuzz = (fnc_t)dlsym(hdl, "to_fuzz"); to_fuzz(TO FEED);

https://lief.quarkslab.com/recon18/demo2

slide-54
SLIDE 54

Code injection

Code injection through shared libraries

slide-55
SLIDE 55

Context

Different techniques exist to inject code:

Using environment variables: LD_PRELOAD,

DYLD_INSERT_LIBRARIES, . . .

Using operating system API: WriteProcessMemory, ptrace, . . . Using custom kernel drivers Using executable formats

slide-56
SLIDE 56

Context

Depending on the scenario, methods can be suitable or not. Next part shows a method based on shared libraries and executable formats to leverage code injection.

slide-57
SLIDE 57

Linked Libraries - Loading

More privileged area Userland

Format Loader Kernel

Execute: my_constructor() New library: libexample.so

slide-58
SLIDE 58

Injection process

  • 1. Declare a constructor

__attribute__((constructor)) void my_constructor(void) { printf("Run payload\n"); } gcc -fPIC -shared libexample.c -o libexample.so gcc -fPIC -shared libexample.c -o libexample.dylib

slide-59
SLIDE 59

Injection process

  • 2. Add a dependency

import lief # ELF elf = lief.parse("/usr/bin/ssh") elf.add_library("libexample.so") elf.write("ssh_modified") # Mach-O macho = lief.parse("/bin/ls") macho.add_library("/Users/romain/libexample.dylib") macho.write("ls_modified") # PE: Not implemented yet

slide-60
SLIDE 60

Injection process

https://lief.quarkslab.com/recon18/demo3

slide-61
SLIDE 61

Injection process

https://lief.quarkslab.com/recon18/demo3

slide-62
SLIDE 62

Frida & LIEF

Frida & LIEF: Frida injection in an Android application

slide-63
SLIDE 63

Frida & LIEF

Using the techniques previously described, we can use Frida on an APK having at least one native library without root privileges.

slide-64
SLIDE 64

Frida & LIEF

Figure – Original APK

slide-65
SLIDE 65

Frida & LIEF

Figure – Original APK Figure – APK embedding Frida

slide-66
SLIDE 66

Frida & LIEF

Figure – Original native library

slide-67
SLIDE 67

Frida & LIEF

Figure – Modified native library

slide-68
SLIDE 68

Frida & LIEF

libgadget.config.so

"interaction": { "type": "script", "path": "/data/local/tmp/myscript.js", "on_change": "reload" }

/data/local/tmp/myscript.js

Java.perform(function () { var Log = Java.use("android.util.Log"); var tag = "frida-lief"; Log.v(tag, "I'm in the process!"); Process.enumerateModules({

  • nMatch: function (module) {

Log.v(tag, "Module: " + module.name); },

  • nComplete: function () {}

});});

slide-69
SLIDE 69

Frida & LIEF

Demo

https://lief.quarkslab.com/recon18/demo4

slide-70
SLIDE 70

Format modification

Such modifications on formats are not new34. However, it’s implemented in LIEF with a new approach that doesn’t rely

  • n replacing existing entries, using padding, removing entries, . . .

3Mayem Phrack #61 4https://github.com/Tyilo/insert_dylib

slide-71
SLIDE 71

Format modification

Instead, it keeps a consistent state of the format:

Export trie Symbol hash tables Relocations Symbol versions Rebase opcodes . . .

slide-72
SLIDE 72

What’s next

LIEF 0.9 comes with new formats related to Android:

OAT VDEX DEX ART

Modification of these formats is not available yet but further version will support it.

slide-73
SLIDE 73

What’s next

How Samsung Secures Your Wallet & How To Break It - Black Hat 2017 Tencent’s Xuanwu Lab

slide-74
SLIDE 74

What’s next

Inside Android’s SafetyNet Attestation: Attack and Defense - Ekoparty 2017 Collin Mulliner

slide-75
SLIDE 75

What’s next

Next version will also include support for Mach-O modifications:

Add unlimited number of Load commands Add libraries Change signature . . .

slide-76
SLIDE 76

Thank You

https://lief.quarkslab.com https://github.com/lief-project/LIEF @LIEF_Project - @rh0main

slide-77
SLIDE 77