Writeup (Table of content)
KMACTF 2022
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
Duet | c (64 bit) | Buffer Overflow |
Ret2Shellcode |
Shellcode (32 bit) can be executed on 64 bit binary and argument when execute int 0x80 will be eax, ebx, ecx, edx... |
Two Shot | c (64 bit) | Buffer Overflow Format String |
Ret2libc |
HCMUS CTF 2022
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
PrintMe | ||||
Timehash - rev | c (64 bit) | Patch file | ||
WWW | c (64 bit) | Format String |
Overwrite GOT |
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
calert | c (64 bit) | Integer Overflow Buffer Overflow |
Ret2libc |
We can change original canary if we know its address which is not in range of libc nor ld |
KCSC CTF 2022
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
readOnly | c (64 bit) | Buffer Overflow |
Ret2dlresolve |
|
start | c (64 bit) | Buffer Overflow |
SROP |
|
feedback | c (64 bit) | Integer Overflow Buffer Overflow |
SROP |
|
guess2pwn | c++ (64 bit) | First byte from urandom may be null |
||
pwnMe | c (64 bit) | Format String |
Ret2libc |
|
babyheap | c (64 bit) | Use After Free Heap Overflow |
||
5ecretN0te | c (64 bit) | Heap Overflow |
House of Force |
Wolverine Security Conference/CTF
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
Us3_th3_F0rc3 | c (64 bit) | Heap Overflow |
House of Force |
zer0pts CTF 2022
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
Modern Rome | c++ (64 bit) | Integer Overflow |
||
accountant | c (64 bit) | Integer Overflow |
ret2libc |
If register (rax, rbx, rcx...) contain 0x10000000000000000 (9 bytes in total), the most significant byte will be remove (the 0x1 will be remove) and make register to null again |
FooBar CTF 2022
Name | Type | File Type | Bug | Technique | Note |
---|---|---|---|---|---|
Death-note | pwn | c (64 bit) | Use After Free |
Tcache Attack House of Botcake |
Tcache forward pointer changed in libc 2.32 (source) |
Pragyan CTF 2022
Name | Type | File Type | Bug | Technique | Note |
---|---|---|---|---|---|
Poly-Flow | pwn | c (32 bit) | Buffer Overflow |
||
Portal | pwn | c (64 bit) | Format String |
||
Database | pwn | c (64 bit) | Heap Overflow |
Tcache Attack |
|
Comeback | pwn | c (32 bit) | Buffer Overflow |
||
TBBT | pwn | c (32 bit) | Format String |
Overwrite GOT |
TSJ CTF 2022
Name | Type | File Type | Bug | Technique | Note |
---|---|---|---|---|---|
bacteria | pwn | c (64 bit) | Buffer Overflow |
Ret2dlresolve |
r_offset can be any writable and controllable place, don't need to be @got |
MOCSCTF 2022
Name | Type | File Type | Bug | Technique | Note |
---|---|---|---|---|---|
C@ge | pwn | c++ (64 bit) | Heap Overflow |
Tcache Attack Ret2libc |
Use libc environ() to leak stack address |
calc | pwn | c (64 bit) | Buffer Overflow Unchecked Index |
ret2win |
|
orange | pwn | c (64 bit) | Heap Overflow |
House of Orange Tcache Attack Unsorted Bin Attack |
Overwrite malloc hook with realloc and realloc hook with one gadget |
pwnable.tw
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
Start | c (32 bit) | Buffer Overflow |
ROPchain Shellcode |
|
orw | c (32 bit) | Shellcode |
||
calc | c (32 bit) | ROPchain |
||
3x17 | c (64 bit) | ROPchain |
Attack by overwriting .fini_array |
Wanna Game 2022
Name | Type | File Type | Technique |
---|---|---|---|
Letwarnup | pwn | c (64 bit) | Format String Overwrite GOT |
Feedback | pwn | c (64 bit) | Least Significant Byte |
note | pwn | c (64 bit) | Heap Attack Unsorted Bin Attack |
pwn.tn
Name | Type | File Type | Technique |
---|---|---|---|
f_one | pwn | c (64 bit) | Format String Overwrite GOT |
f_two | pwn | c (32 bit) | Buffer Overflow Integer Overflow Format String |
KCSC - Entrance exam
Name | Type | File Type | Technique |
---|---|---|---|
ArrayUnderFl0w | pwn | c | Unchecked Index |
guessMe | pwn | c | Specific Seed Rand |
Make Me Crash | pwn | c | Buffer Overflow |
Chall | pwn | c | Format String |
ret2win | pwn | c | Buffer Overflow |
get OVER InT | pwn | c | Integer Overflow |
bof1 | pwn | c | Buffer Overflow |
ISITDTU 2019
Name | Type | File Type | Technique |
---|---|---|---|
tokenizer | pwn | cpp (64 bit) | Least Significant Byte |
iz_heap_lv1 | pwn | c (64 bit) | Heap Attack Tcache attack |
DiceCTF 2022
Name | Type | File Type | Technique |
---|---|---|---|
baby-rop | pwn | c (64 bit) | Heap Attack ROP chaining |
dataeater | pwn | c (64 bit) | ret2dlresolve Fake link_map |
DefCamp CTF 21-22 Online
Name | Type | File Type | Technique |
---|---|---|---|
cache | pwn | c (64 bit) | Use After Free Double Free Tcache Attack Overwrite GOT |
blindsight | pwn | c (64 bit) | Blind ROP Buffer Overflow |
SVATTT 2019
Name | File Type | Bug | Technique | Note |
---|---|---|---|---|
three_o_three | c (64 bit) | Unlimited malloc size |
FILE structure attack |
Malloc with size larger than heap size make the chunk near libc ; Scanf flow: __uflow -> _IO_file_underflow -> read 1 byte until meet \n |
Technique (Table of content)
Name | Note |
---|---|
Ret2dlresolve (64 bit) | Just input, no output and no output function |
Heap Exploit | Just notes. For a full technique, please visit this page |
Note (Table of content)
- 32 bit:
payload = b'A'*<x> # Padding
payload += p32(<@plt> / libc.sym['<function name>'])
payload += p32(<return address>)
payload += p32(<arg1>)
payload += p32(<arg2>)
...
- 64 bit:
payload = b'A'*<x> # Padding
payload += p64(pop_rdi)
payload += p64(<arg1>)
payload += p64(pop_rsi_r15)
payload += p64(<arg2>)
payload += p64(<any byte>)
payload += p64(@plt / libc.sym['<function name>'])
payload += p32(<return address>)
Install docker on parrot:
sudo apt install docker.io
Install docker-compose for convinient command
To debug a process from docker, add this YAML code to docker-compose.yml, the same wilth expose
(source):
cap_add:
- SYS_PTRACE
Because my computer doesn't show pid when running container so I use the following way to debug:
import subprocess
from pwn import *
def GDB():
proc = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
ps = proc.stdout.read().split(b'\n')
pid = ''
for i in ps:
# Change the recognization here
if b'/home/bacteria/bacteria' in i and b'timeout' not in i:
pid = i.split(b' ')[1].decode()
# Change command here
command = '''
'''
with open('/tmp/command.gdb', 'wt') as f:
f.write(command)
# Need sudo permission
subprocess.Popen(['sudo', '/usr/bin/x-terminal-emulator', '--geometry', '960x1080+960+0', '-e', 'gdb', '-p', pid, '-x', '/tmp/command.gdb'])
input() # input() to make program wait with gdb
p = connect('127.0.0.1', 9487)
GDB()
Using x-terminal-emulator to create popup shell and pass command in a file:
# Intel debug
import subprocess
def GDB():
command = '''
'''
with open('/tmp/command.gdb', 'wt') as f:
f.write(command)
subprocess.Popen(['/usr/bin/x-terminal-emulator', '--geometry', '960x1080+960+0', '-e', 'gdb', '-p', str(p.pid), '-x', '/tmp/command.gdb'])
input() # input() to make program wait with gdb
# Arm debug
def GDB(filename, port):
q = process(f"/usr/bin/x-terminal-emulator --geometry 960x1080+960+0 -x gdb-multiarch -q --nh -ex 'source ~/.gef-283690ae9bfcecbb3deb80cd275d327c46b276b5.py' -ex 'set architecture arm64' -ex 'file {filename}' -ex 'target remote localhost:{port}'", shell=True)
port = 1234
filename = ''
p = process(f'qemu-aarch64 -L /usr/aarch64-linux-gnu -g {port} {filename}}'.split())
GDB('cli', port)
from ctypes import*
# Load glibc chạy chung với chương trình
glibc = cdll.LoadLibrary('./libc6_2.27-3ubuntu1.4_amd64.so')
# Tạo seed rand với seed bằng time(null)
glibc.srand(glibc.time(None))
# Lấy giá trị random
val = glibc.rand()
print(hex(val))
- Get child pid (way 1):
import os
from pwn import *
p = process(<Some Program>)
child_pid = pwnlib.util.proc.children(os.getpid())[0]
print(child_pid)
- Get child pid (way 2):
from pwn import *
p = process(<Some Program>)
print(pidof(p))
- Get child pid (way 3):
from pwn import *
p = process(<Some Program>)
print(p.pid)
- ARGS:
from pwn import *
# print(args.<ANY NAME IN CAPITAL>)
print(args.MYNAME)
print(args.MYAGE)
--> python run.py MYNAME=Johnathan MYAGE=20
- Core file:
from pwn import *
p = process('<File>')
p.sendline(b'A'*500)
p.wait() # Wait until it crash. Core file will be made after crash.
# If it doesn't crash, check manually to make sure it crash
core = Coredump('./core')
# Read number of data from the specified address
print(core.read(<some address>, <number of byte read>)) # Return byte
# Read until null byte
print(core.string(<some address>))
Get opcode from binary
objdump -d <Name of program>|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/\ $//g'|sed 's/\ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
-
r < <()
can pass null byte,r <<<$()
cannot. -
flag +/-ZERO
to set or remove flag.
- rsp (esp) address must end with byte 0x00, 0x10, 0x20, 0x30... or it will cause error.
Ex: if rsp address end with 0xe8 --> segfault.
%p%p%p%n
will write and access easily.%4$n
will write but cannot access.- Payload should have
%c
instead%x
to make sure it write a byte, not a random byte on stack. - Enter
.
toscanf()
with number format (%d
,%u
,%ld
...) won't enter new value to var.