117
injectso Modifying and Spying on running processes under Linux and Solaris Shaun Clowes – [email protected]

bh-europe-01-clowes

Embed Size (px)

Citation preview

Page 1: bh-europe-01-clowes

injectso

Modifying and Spying on running processes under

Linux and SolarisShaun Clowes – [email protected]

Page 2: bh-europe-01-clowes

Overview – Part 1A study of InjLibIntroduction to injectsoAll about ELFProgram/process modification techniques under Unix

Page 3: bh-europe-01-clowes

Overview – Part 2injectso vs InjLibHow injectso worksIntercepting dynamic function callsDefending against injectsoFuture

Page 4: bh-europe-01-clowes

Introduction to InjLibWindows System Journal 1994Jeffrey RichterInject a DLL into another processInjection has no effect on processDLL can be passed information about the target process

Page 5: bh-europe-01-clowes

InjLibInjLib process is trivial

Entire process complete < 50 lines of codeStill impressive

Technique very widely used:Pwdump (2 and 3)GetAdminFport Virtually every ‘Spy’ application

Page 6: bh-europe-01-clowes

InjLib – Basic Process 1. Find address of system function used

to open libraries2. Attach to process3. Allocate memory in process4. Copy DLL loading function into process5. Create thread in process at injected

function6. Function loads DLL

Page 7: bh-europe-01-clowes

InjLib – Step 1Copied function needs to know how to get a DLL loadedDLLs dynamically loaded with “LoadLibraryA”Copied function needs to know address of this LoadLibraryA Copied function cannot rely on normal IAT processing since it is in different process

Page 8: bh-europe-01-clowes

InjLib – Step 1‘LoadLibraryA’ is in kernel32.dllAll Windows applications have kernel32.dll mappedSafe to assume DLL mapped at same address in all processes on a machine

Page 9: bh-europe-01-clowes

InjLib – Step 1Load reference to kernel32.dllhDll = LoadLibrary ("Kernel32");

Get address of LoadLibraryApLoadLib = GetProcAddress(hDll, “LoadLibraryA”);

Page 10: bh-europe-01-clowes

InjLib – Step 2Attach to process (as a debugger)In code:hProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE,

dwPid)

Need SE_DEBUG privilege to open processes owned by other users

Page 11: bh-europe-01-clowes

InjLib – Step 3Allocate memory in remote process to store

Copied functionArguments to copied function

In code:pMem = VirtualAllocEx (hProc, NULL, dwBytesToAlloc,

MEM_COMMIT, PAGE_EXECUTE_READWRITE);

Page 12: bh-europe-01-clowes

InjLib – Step 4Copy function and arguments into process.In code:WriteProcessMemory (hProc, pAddr, pToCopy,

dwAmtToCopy, &dwWritten);

To copy function just copy everything from function address to immediately following function address

Page 13: bh-europe-01-clowes

InjLib – Step 5Create a new thread in remote process, Start it at address of injected functionPass address of structure in process containing information about location of ‘LoadLibraryA’ and DLL nameIn Code:hThread = CreateRemoteThread(hProc, NULL, 0,

pInjectedFunction, pArgs, 0, NULL);

Page 14: bh-europe-01-clowes

InjLib – Step 6Injected function now runsCall ‘LoadLibraryA’ using function pointer and DLL name arguments

Page 15: bh-europe-01-clowes

InjLib – ResultInjLib process for injecting a DLL is

EasyShortSafe

Page 16: bh-europe-01-clowes

InjLib – What next?Up to application

Tinker with internal memory structuresChange window appearance/layoutCall API routines from inside processUse IPC channels in processPatch program functionsEndless possibilities

Page 17: bh-europe-01-clowes

Introduction to injectsoinjectso is like InjLib for Linux and SolarisInject shared libraries into remote processesProvides some support code to help in dynamic function patching/interceptionMuch more detail later

Page 18: bh-europe-01-clowes

Modifying Programs/Processes

The ability to modify behavior of programs/processes has obvious security ramifications

Patching vulnerabilitiesRun timeStatically

Subverting applicationsBackdoorsViruses

Page 19: bh-europe-01-clowes

Modifying Programs/Processes under

UnixA few techniques:

Binary PatchingDynamic Loader EnvironmentIn Core Patching

Page 20: bh-europe-01-clowes

Breakdown of ELFNeed understanding of internal structure of executablesELF = Executable and Linkable FormatOriginally by Unix System Labs (USL)Adopted by Tool Interface Standards committee (TIS)Used in virtually every recent Unix

Page 21: bh-europe-01-clowes

Breakdown of ELFThree main types of ELF files

Relocatable file – object file ready to be linked with othersExecutable Shared Object (Library)

Only last two relevantConcentrate on Executables

Page 22: bh-europe-01-clowes

ELF ‘Views’ELF describes two separate ‘views’ of an executable, a linking view and a loading viewLinking view is used at static link time to combine relocatable filesLoading view is used at run time to load and execute program

Page 23: bh-europe-01-clowes

ELF ‘Views’ – Split

Page 24: bh-europe-01-clowes

ELF Linking ViewDivides executable into many meaningful ‘Sections’Sections have:

A name and type Requested memory location at run timePermissions (writeable/executable)

.interp

.text

.rel.plt

.dynstr

.dynsym

.dynamic

Page 25: bh-europe-01-clowes

ELF Linking View – Important Sections

.interp Requested Dynamic linker

.dynamic Dynamic linking information

.symtab, .dynsym

Symbols (static/dynamic)

.strtab, .dynstr String tables

.plt Procedure linkage table

.rel.<x> Relocations for section x

.text Code

Page 26: bh-europe-01-clowes

ELF Linking ViewNot all sections loaded at run time

Information used for linkingDebugging information

Difference between link time and run time

Page 27: bh-europe-01-clowes

ELF Loading ViewMuch simpler view, divides executable into ‘Segments’Only includes data to be loaded into memory at runtimeSegments have:

A simple typeRequested memory location at run timePermissions (readable/writeable/executable)

Page 28: bh-europe-01-clowes

ELF Loading View – Segment Types

INTERP Dynamic linker for this executable

DYNAMIC

Dynamic linking information

LOAD Segment loaded into memory

Page 29: bh-europe-01-clowes

ELF ‘Views’ - Linking to Loading

Page 30: bh-europe-01-clowes

ELF Loading ViewSemantics of section table (Linking View) are irrelevant in Loading ViewSection information can be removed from executable

Page 31: bh-europe-01-clowes

Loading and Executing an ELF Executable

1. File opened2. File descriptor passed to dynamic

linker specified in INTERP segment3. Linker reads file segments and loads

them at requested addresses4. Linker finds and processes the

dynamic segment

Page 32: bh-europe-01-clowes

The Dynamic Section/Segment

A table with records containing data critical to dynamic loading/linkingAllows dynamic linker to quickly find out information about the executable

No need for section table etc

Each record consists of:A type (tag)Value (or pointer)

Page 33: bh-europe-01-clowes

Dynamic Segment Record Tags

DT_NEEDED

Name of a required shared library

DT_JMPREL Address of relocation entries associated with the PLT

DT_DEBUG Pointer to debugging information from dynamic linker

Page 34: bh-europe-01-clowes

Loading and Executing an ELF Executable

5. Map in shared libraries corresponding to DT_NEEDED entries

6. Add libraries to link map stored in debug struct referenced by DT_DEBUG entry

7. Perform Global Offset Table (GOT) relocations

8. Perform Procedure Linkage Table (PLT) relocations (usually lazily)

Page 35: bh-europe-01-clowes

The Procedure Linkage Table

Stored in the .plt sectionAllows executables to call functions that aren’t present at compile time

Shared library functionsprintf() etc.

Set of function stubs

Page 36: bh-europe-01-clowes

The Procedure Linkage Table

Page 37: bh-europe-01-clowes

The Procedure Linkage Table

Redirection through PLT to real printf() determined by Dynamic LinkerUsually done ‘Lazily’

Page 38: bh-europe-01-clowes

Dynamic Symbols/Relocations

In .rel.plt and .dynsym sectionsTell Dynamic Linker what it needs to resolve where (PLT)More on PLT/Dynamic relocations later

Page 39: bh-europe-01-clowes

The Global Offset TableLike PLT but for non function symbols

‘stderr’, ‘errno’ etc

Referenced by PLT on IA32But NOT Sparc

Both PLT and GOT targeted for attack in format string vulnerabilities

Page 40: bh-europe-01-clowes

DT_DEBUG RecordPointer to a structure provided by the Dynamic Linker (at run time)Normally examined by DebuggersShows memory layout of process

Which object files are loadedBase address at which they are loaded

Page 41: bh-europe-01-clowes

Binary PatchingStatically modify code in fileNeed to:

Insert additional codeLink existing code to added code

Page 42: bh-europe-01-clowes

Binary Patching – Inserting Code

Code in assembler (sometimes C)Where to put additional code?

Overwrite existing unused codeHard to identify

Section paddingNot much spaceNeed section in executable segment (on non IA32 targets)

Page 43: bh-europe-01-clowes

Binary Patching – Inserting Code

Add a segmentHave as much space as needed

Other methodsUnix viruses

Our example will add a new segment

Can reuse existing but unneeded segment entry (e.g PT_PHDR)Create our own program headers

Page 44: bh-europe-01-clowes

Binary Patching – Adding a Segment

Page 45: bh-europe-01-clowes

Binary Patching – Patch what?

What to modify?Anything!Function prologues

Redirect internal function calls

General codeInsert new/remove old code

How to modify old codeJump to new code, then jump back

Page 46: bh-europe-01-clowes

Binary Patching - Demo

Demo

Page 47: bh-europe-01-clowes

Binary Patching - Advantages

Very flexibleCan modify almost everything

PermanentLittle performance impact

Page 48: bh-europe-01-clowes

Binary Patching - Disadvantages

Complex, error prone, time consuming work

Particularly any asm code/disassembly

Hard to intercept dynamic functions (can’t simply overwrite PLT entries statically)Program must be restarted

Bad if it’s a critical service

Page 49: bh-europe-01-clowes

Binary Patching - Disadvantages

Program executable must be modifiedEntire code must usually be relocatable

Can’t easily import functionsDirect syscalls

Page 50: bh-europe-01-clowes

In Core PatchingModify the in core image of the process while it runsCan modify the remote process memory using ptrace() or procfs

Page 51: bh-europe-01-clowes

In Core PatchingAs with static patching need to:

Insert additional codeLink existing code to new code

Page 52: bh-europe-01-clowes

In Core PatchingWhere to put additional code?

Need executable memory spaceOverwrite existing unused code

Hard to identify

Use segment paddingMuch more significant at run timePage padded

Overwrite Program HeadersNot needed at execution time

Page 53: bh-europe-01-clowes

In Core PatchingLinking in additional code:

Exactly as with file patching

Page 54: bh-europe-01-clowes

In Core Patching - Demo

Demo

Page 55: bh-europe-01-clowes

In Core Patching - Advantages

Very flexibleCan modify almost everything Non permanentCan be performed on running process

Page 56: bh-europe-01-clowes

In Core Patching - Disadvantages

Complex, error prone, time consuming work

Particularly any asm code/disassembly

Can easily kill running programParticularly if not stopped at patch time

Page 57: bh-europe-01-clowes

Dynamic Loader Environment

Dynamic loader resolves at run time all external symbols (dynamic relocations)

GOT – Data relocationsPLT – Function relocations

How?

Page 58: bh-europe-01-clowes

Dynamic Loader TricksReads DT_NEEDED entries in PT_DYNAMIC segmentLoads files and adds them to link mapThen goes on to process relocations

Page 59: bh-europe-01-clowes

Dynamic Loader Tricks – Process View

Page 60: bh-europe-01-clowes

Dynamic Linker Tricks - Resolution

When processing relocations dynamic linker looks through map and

Searches each libraries exported symbolsTries to find matching symbol nameLooks for non ‘weak’ function

First match is the winner

Page 61: bh-europe-01-clowes

Dynamic Linker – Function Call Interception

Trick is to get your library loaded firstIt will be the match (winner) for all its exported symbols

Can intercept any dynamic function call (libc etc)

Page 62: bh-europe-01-clowes

Dynamic Linker – Getting in First

Modify DT_NEEDED recordsOverwrite other library entry

Open it in your library with linker routinesSubstitute library depends on old libraryRequires lazy binding!

Move DYNAMIC segment and recreate

Page 63: bh-europe-01-clowes

Dynamic Linker – Getting in First

Use Linker environmentLD_PRELOAD specifies libraries to be loaded immediatelyVery common technique

Page 64: bh-europe-01-clowes

Dynamic Linker – Calling Real Function

Intercepting function usually needs to call old functionDynamic linker provides interface (through libdl.so):

dlopen – Open a librarydlsym – Get address of symbol, RTLD_NEXT flag specifies libraries after current one

Page 65: bh-europe-01-clowes

Dynamic Linker Tricks - Demo

Demo

Page 66: bh-europe-01-clowes

Dynamic Linker Tricks - Advantages

EasyAll interception code can be done in C

SimpleSafe

Provided interception routines are sound

LD_PRELOAD non permanent

Page 67: bh-europe-01-clowes

Dynamic Linker Tricks - Disadvantages

LD_PRELOAD not permanentDT_NEEDED approach requires executable modification

And library in place at all times

Program must be restartedAgain, bad for a critical service

Page 68: bh-europe-01-clowes

injectso - End Part 1

Questions?

Page 69: bh-europe-01-clowes

injectso - Part 2

Page 70: bh-europe-01-clowes

Re-Overview – Part 2injectso vs InjLibHow injectso worksIntercepting dynamic function callsDefending against injectsoFuture

Page 71: bh-europe-01-clowes

injectso TeaserSince we’re doing all these demosQuick demo of library injection using injectsoReal demos to follow internal details

Page 72: bh-europe-01-clowes

injectso – Simple Demo

Demo

Page 73: bh-europe-01-clowes

injectso Vs InjLibinjectso is basically the same as Injlib, but for Unix (Linux/Solaris)Much harder on Unix than on windows

Operating system provides minimal support

Page 74: bh-europe-01-clowes

injectso Vs InjlibLoadLibraryA

Close equivalent under Unix

OpenProcessClose equivalent under Unix

VirtualAllocExNo Unix equivalentNo way to modify remote processes’ page protection

Page 75: bh-europe-01-clowes

injectso Vs InjlibWriteProcessMemory

Close equivalent under Unix

CreateRemoteThreadNo Unix EquivalentUnix and Threads not best of friends

In summary, the two most important functions for InjLib have no Unix equivalent

Page 76: bh-europe-01-clowes

injectso – Conceptual Steps

Break down library injection into conceptual steps

Then find ways to implement them under Unix

Page 77: bh-europe-01-clowes

injectso – Conceptual Steps

Steps:1.Open process2.Find function in process to load a

library3.Get process to call that function to

load specified library4.(Bonus Points) Help injected library do

something useful

Page 78: bh-europe-01-clowes

Step 1. Attaching to Process

No problemInjLib uses OpenProcess to get debugger connectionAlmost equivalent functions:

ptrace() – Linuxprocfs - Solaris

Page 79: bh-europe-01-clowes

Step 1. Attaching to Process

Abilities gained:Read and write to arbitrary process memory

Page permissions do not apply

Modify process registersOther funky stuff under Solaris (but ptrace() support is nice)

Page 80: bh-europe-01-clowes

Step 2. Library Open Functions

The function dlopen() can be used to open a dynamic library

And have it mapped in as normal

In Windows LoadLibraryA is in Kernel32.dll

Therefore in all programs

Page 81: bh-europe-01-clowes

Step 2. Library Open Functions

Under Unix dlopen() exists in libdl.so

Dynamic linker related routines

How to use functions that aren’t loaded?

Page 82: bh-europe-01-clowes

Step 2. Library Open Functions

Functions in libdl.so are stubsPerform error processing (under Linux)Real functions are located in

glibc (Linux)ld.so.1 (Solaris)

Makes senseDynamic linker must have access to the functionality to work

Page 83: bh-europe-01-clowes

Step 2. Library Open Functions

Thus all (dynamically linked) processes have access to dlopen() functionality at all times

Page 84: bh-europe-01-clowes

Step 2. Locating Library Functions

InjLib:Open kernel32.dllFind function addressAssume same in remote process

injectso can do the same using dlopen() and dlsym()

Does the address assumption hold?

Page 85: bh-europe-01-clowes

Step 2. Locating Library Functions

No!Patches such as PaX, OpenWall etc deliberately randomly map shared librariesLocation of library in one process not the same in another

Page 86: bh-europe-01-clowes

Step 2. Locating Library Functions

Duplicate actions of dynamic linker (by reading process memory):

Loop through link mapLoop through each objects dynamic symbolsFind matching symbolDetermine symbols absolute address (we have the base address)

Page 87: bh-europe-01-clowes

Step 2. Locating Library Functions

Page 88: bh-europe-01-clowes

Step 3. Calling the Loader Routine

Much harder under UnixNeed to force main process to jump to other code

Can’t just create a thread and copy function

Page 89: bh-europe-01-clowes

Step 3. Calling the Loader Routine

Issues:Restoring process after

Syscall interruption

Constructing arguments to routineActually forcing call to routine

Page 90: bh-europe-01-clowes

Step 3a. Syscall Interruption

A lot of code spends majority of time in syscalls

select(), read(), connect(), write() etc.

Redirecting process to other code will break the syscall

Breaking syscalls is not fun

Page 91: bh-europe-01-clowes

Step 3a. Syscall Interruption

Syscall arguments stored in registersIA32 Linux - %eax, %ebx, %ecx, %edx …Sparc Linux - %o1, %o2, %o3, …Sparc Solaris - %g1, %o0, %o1, …

When syscall is interrupted the syscall returns an error into:

IA32 Linux - %eaxSparc Linux - %o1Sparc Solaris - %g1

Page 92: bh-europe-01-clowes

Step 3a. Syscall Interruption

Value isn’t errno, I.e EINTREven if it were most code can’t handle it and dies

Need to prevent adverse affectsRestart syscall But the first argument is gone?!

Page 93: bh-europe-01-clowes

Step 3a. Syscall Interruption

Finding old parameter:IA32 Linux – Stored in debugger structureSparc Solaris – Debugger connection doesn’t break syscall, take it before breakSparc Linux – Hell!

Page 94: bh-europe-01-clowes

Step 3a. Syscall Interruption

Save old registers before modifying processRestore old syscall (and set instruction pointer) in saved registersWhen complete restore and start

Page 95: bh-europe-01-clowes

Step 3b. Calling FunctionNeed to construct arguments and call functionInjLib copies in a function (and sets it executable)Doesn’t work on Unix:

Can’t malloc remote memoryCan’t set remote memory executable

Page 96: bh-europe-01-clowes

Step 3b. Calling FunctionObvious solution – Trampolines

As used in gdbCopy code onto process stack to call function

Well and truly broken by PaX, OpenWall etc

Page 97: bh-europe-01-clowes

Step 3b. Calling Functioninjectso steps:

1. Copy string arguments onto remote process stack (removed on register restore)

2. Set arguments in registers as required

3. Set saved PC/EIP to be an invalid page (0x41414140)

4. Set PC/EIP to function

Page 98: bh-europe-01-clowes

Step 3b. Calling Function5. Allow process to execute6. Catch SegFault on return (invalid

page)7. Continue processing

No executable code injected at allNo permissions issues

Page 99: bh-europe-01-clowes

injectso - SuccessIf done right library is loaded into remote process, care of dynamic linker

_init() is called as normal

Process continues on as normal

Page 100: bh-europe-01-clowes

injectso - Demo

Demo

Page 101: bh-europe-01-clowes

injectso – IssuesSignals

Signals generated during injection (e.g SIGALRM, SIGCHLD, SIGURG etc)Need to be replayed

Dangerous by definitionEspecially with unsafe syscall restartBut generally reliable with injectso

Page 102: bh-europe-01-clowes

injectso – What next?Library can do whatever it wishesHowever useful to be able to override dynamic function calls

Most holes can be fixed this wayMost processes can be subverted this way

Page 103: bh-europe-01-clowes

injectso – User Function Call

injectso can call a user specified function after injection

Provides address of program PT_DYNAMIC segment

Utility object called Intercept.o makes use of this

Compile it into libraryEasily intercept dynamic functions

Page 104: bh-europe-01-clowes

Intercept.o – Intercepting Function Calls

User code provides list of functions to overrideIntercept.o function intercept_begin() called by injectsoFinds functions in PLT and patches them to refer to replacement versionsProvides pointer to old function to library

Page 105: bh-europe-01-clowes

Intercept.o – Intercepting Function Calls

Page 106: bh-europe-01-clowes

Intercept.o – Intercepting Function Calls

Needs to reapply after every call to original

Lazy Binding

A little harder on Sparc

Page 107: bh-europe-01-clowes

injectso – Demo - Interception

Demo

Page 108: bh-europe-01-clowes

injectso – Protecting Applications

Protect running servicesKill bad input data as it comes inIntercept input functions and purify

Page 109: bh-europe-01-clowes

injectso – Demo - Protection

Demo

Page 110: bh-europe-01-clowes

injectso – Subverting Applications

Backdoor running programsPop magic shell on certain inputLog input and output to critical service

Page 111: bh-europe-01-clowes

injectso – Demo - Subversion

Demo

Page 112: bh-europe-01-clowes

injectso - AdvantagesSimpleFlexible

Library can do anything it wishes

No modifications to binaryNo disk files

Library may be deleted after injection

Page 113: bh-europe-01-clowes

injectso – AdvantagesService does not need to be restartedCode normally in CCode gets relocations freeMostly safe

Page 114: bh-europe-01-clowes

injectso - DisadvantagesNot permanentComplex to use for non dynamic function interception

Page 115: bh-europe-01-clowes

Protecting against injectsoinjectso is not a new attack

As demonstrated via three other methods

Modifying processes/binaries only possible after intrusionProtect machine

Page 116: bh-europe-01-clowes

injectso – The FutureModify relocations

Prevents PLT patching problems for unbound functionsNeed executable space (on Sparc)

Hard to find with PaX aroundOverwrite library code segment?

Other PlatformsAdditional helpers (Prologue interception etc)

Page 117: bh-europe-01-clowes

Thank you for listening!Questions?SecureReality Web Site:http://www.securereality.com.au

Email:[email protected]