Annexes¶
GOT Poisoning¶
This idea has firstly been described by Ryan O’Neill in its article “Modern Day ELF Runtime infection via GOT poisoning”.
Netzob has the following needs :
- inject between an application and its libraries;
- runtime injection,
- dump any value of the variables which are transfered from an application to a libs and “vice et versa”,
- modify the value of any variables which are transfered from an application to a libs and “vice et versa”,
- hidden approach,
Those needs are generated by the following functionalities :
- detection of all the running processes ;
- filter for dynamically linked processes ;
- display the available libs of a process ;
- display all the entry functions of a chosen lib ;
- inject a proxy between multiple functions of a lib and the application ;
- the injected proxy must be controllable (dump and modify variables).
As an example, Netzob must be able to :
- fetch all the sent and received message in an HTTPS connection ;
- modify for fuzzing experiments in an HTTPS connection.
Glossary¶
First a bit of vocabulary :
Term | Description |
---|---|
GOT | Global Offset Table |
PLT | Procedure linking table |
How it works¶
This approach is composed of two object :
- an injector which has the responsibility to inject the parasite into a running process;
- a parasite which aims are to dump and or to modify the values of the variable transfered between a process and its libs.
And the scenario of the hijacking algorithm is :
- Locate binary of targeted process by parsing /proc/<pid>/maps
- Parse PLT to get desired GOT address
- Attach to the process
- Find a place to inject the parasite loader shellcode
- Inject new code and save original code we are overwriting
- Modify EIP (save old EIP) to point to our code
- Resume traced process so that it executes our parasite loader shellcode and load our parasite
- Reset register, replace original code and allow process to resume
- get base address of our parasite from %eax
- find address of parasite function within shared lib by scanning for its code sequence
- Retrieve and save value stored in desired GOT address
- Modify the return address of the parasite function with the original function address
- Overwrite desired GOT address with new value
- Detach from process and enjoy
Step1 : Locate binary of targeted process by parsing /proc/<pid>/maps¶
INPUT :
- PID of the process
OUTPUT :
- the base address of the application
- the full path of the binary
OPERATIONS :
- Parse the file /proc/<pid>/maps.
Step2 : Parse PLT to get desired GOT address¶
INPUT :
- the full path of the binary
- name of the function to hijack
OUTPUT :
- the GOT address / offset of the function to hijack
OPERATIONS :
- Parse the binary (like readelf -r does)
Step3 : Attach to the process¶
INPUT :
- PID of the process
OUTPUT :
OPERATIONS :
- Attach to the process using PTRACE_ATTACH
Step4 : Find a place to inject the parasite loader shellcode¶
INPUT :
- base address of the text segment of the process
- parasite loader shellcode
OUTPUT :
- the [start-end] offset in the text segment for the injection of shellcode
OPERATIONS :
- Computes the offset in the segment of the injected
Step5 : Inject new code and save original code we are overwriting¶
INPUT :
- start offset of the injection in the text
- parasite loader shellcode
OUTPUT :
- the [start-end] offset in the text segment for the injection of shellcode
OPERATIONS :
- backup the original code into memory using ptrace(PTRACE_PEEKTEXT ;
- load shellcode into text starting at offset using ptrace(PTRACE_POKETEXT ;
Step6 : Modify EIP (save old EIP) to point to our code¶
INPUT :
- start offset of the injection in the text
OUTPUT :
OPERATIONS :
- save the registre using ptrace(PTRACE_GETREGS ;
- modify reg.eip using ptrace(PTRACE_GETREGS to the start offset
Step7 : Resume traced process so that it executes our parasite loader shellcode and load our parasite¶
INPUT :
OUTPUT :
OPERATIONS :
- resume execution using trace(PTRACE_CONT
Step8 : Reset register, replace original code and allow process to resume¶
INPUT :
OUTPUT :
OPERATIONS :
- wait for the end of application using * wait(NULL);* ;
- retrieves the values of the registers and reset them to default ones
- detach from process using ptrace(PTRACE_DETACH
What is a workspace ?¶
A workspace contains all the resources files associated with the current analysis which includes : * the repository of automaton, * the logging configuration, * the list of available prototypes of functions which can be hijacked, * the repository of imported traces, * the global configuration file.