Injection
Injection is the art of inserting code/data to manipulate the program. Particularly we will focus on code injection.
LD_PRELOAD is an environment variable that will tell the linker to loader symbols in a shared library before executing a program
This has the side effect of potentially overwriting functions that the program depends on (e.g. other shared libraries).
Example: LD_PRELOAD=./sharedobj.so ./my_prog
R--
R--
R-E
RW-
R--
RW-
R-E
ELF Header
Header Table
Code
Data
R--
R--
R-E
RW-
R--
RW-
R-E
ELF Header
Header Table
Code
Data
Injected Code
Process 1
Process 2
Process 1
Process 2
Write(fd, shellcode, size)
New Code
/* What this would look like if it was a C program */
int main()
{
//This would be actual shellcode
char *shellcode = {0x1, 0x2, 0x3, ...};
size_t shellcodeSize = 0x20;
//Note O_WRONLY and SEEK_SET are #defines to integer values
fd = open(fd, /proc/<insert_pid_num_here>/mem, O_WRONLY);
lseek(fd, offset, SEEK_SET);
write(fd, shellcode, shellcodeSize);
return 0;
}
Note: you may need to convert this to shellcode too
We can manipulate the program's memory, registers, and file-descriptors. In a sense, we can patch the program dynamically using the ptrace system call.
long ptrace (enum __ptrace_request request, pid_t pid, void *addr, void *data);
More in man ptrace
Lets see an example of this
Note: there are multiple ways, but this is just one way.
Tracer:
libc.so
./target
Stack
Tracer:
libc.so
./target
Stack
0x0F 0x05 0xCC
Tracer:
libc.so
./target
Stack
0x0F 0x05 0xCC
Tracer:
libc.so
./target
Stack
0x0F 0x05 0xCC
New Allocated Memory
Tracer:
libc.so
./target
Stack
0xFF 0xDO 0xCC
New Allocated Memory
Tracer:
libc.so
./target
Stack
0xFF 0xDO 0xCC
New Allocated Memory
Tracer:
libc.so
./target
Stack
0xFF 0xDO 0xCC
New Allocated Memory
./inject.so
Tracer:
libc.so
./target
Stack
0xFF 0xDO 0xCC
New Allocated Memory
./inject.so
Tracer:
libc.so
./target
Stack
0xFF 0xDO 0xCC
New Allocated Memory
./inject.so
Tracer:
libc.so
./target
Stack
We have an updated version of limited resources. Instead of having the write system call, we now have ptrace available. Figure out how to use ptrace and /proc/pid/mem injection in order to get the flag.