Apuntes de pwndbg
Comandos
Obtener información
info functions
Obtiene las functiones que se encuentran definidas en el binario.
info functions- Salida de ejemplo:
pwndbg> info functions
All defined functions:
Non-debugging symbols:
0x0000000000400528 _init
0x0000000000400550 puts@plt
0x0000000000400560 system@plt
0x0000000000400570 printf@plt
0x0000000000400580 memset@plt
0x0000000000400590 read@plt
0x00000000004005a0 setvbuf@plt
0x00000000004005b0 _start
0x00000000004005e0 _dl_relocate_static_pie
0x00000000004005f0 deregister_tm_clones
0x0000000000400620 register_tm_clones
0x0000000000400660 __do_global_dtors_aux
0x0000000000400690 frame_dummy
0x0000000000400697 main
0x00000000004006e8 pwnme
0x0000000000400756 ret2win
0x0000000000400780 __libc_csu_init
0x00000000004007f0 __libc_csu_fini
0x00000000004007f4 _finiinfo registers
Obtiene la información de los registros en el estado actual de la apliación tras su ejecución.
info registers- Salida de ejemplo:
pwndbg> info registers
rax 0xb 0xb
rbx 0x7fffffffdf68 0x7fffffffdf68
rcx 0x7ffff7ea5976 0x7ffff7ea5976
rdx 0x0 0x0
rsi 0x7ffff7f87643 0x7ffff7f87643
rdi 0x7ffff7f887b0 0x7ffff7f887b0
rbp 0x7fffffffde50 0x7fffffffde50
rsp 0x7fffffffde50 0x7fffffffde50
r8 0x0 0x0
r9 0x0 0x0
r10 0x0 0x0
r11 0x202 0x202
r12 0x0 0x0
r13 0x7fffffffdf78 0x7fffffffdf78
r14 0x7ffff7ffd000 0x7ffff7ffd000
r15 0x0 0x0
rip 0x4006d7 0x4006d7 <main+64>
eflags 0x206 [ PF IF ]
cs 0x33 0x33
ss 0x2b 0x2b
ds 0x0 0x0
es 0x0 0x0
fs 0x0 0x0
gs 0x0 0x0
fs_base 0x7ffff7d9e740 0x7ffff7d9e740
gs_base 0x0 0x0
pwndbg> info breakpoints
Obtiene información sobre los breakpoints que se han establecido.
info breakpoints- Salida de ejemplo:
pwndbg> info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004006d2 <main+59>
breakpoint already hit 1 time
2 breakpoint keep y 0x00000000004006d7 <main+64>Desensamblar
disas main
Desensambla la función main
disas main- Salida de ejemplo:
pwndbg> disas main
Dump of assembler code for function main:
0x0000000000001139 <+0>: push %rbp
0x000000000000113a <+1>: mov %rsp,%rbp
0x000000000000113d <+4>: sub $0x210,%rsp
0x0000000000001144 <+11>: mov %edi,-0x204(%rbp)
0x000000000000114a <+17>: mov %rsi,-0x210(%rbp)
0x0000000000001151 <+24>: mov -0x210(%rbp),%rax
0x0000000000001158 <+31>: add $0x8,%rax
0x000000000000115c <+35>: mov (%rax),%rdx
0x000000000000115f <+38>: lea -0x200(%rbp),%rax
0x0000000000001166 <+45>: mov %rdx,%rsi
0x0000000000001169 <+48>: mov %rax,%rdi
0x000000000000116c <+51>: call 0x1030 <strcpy@plt>
0x0000000000001171 <+56>: mov $0x0,%eax
0x0000000000001176 <+61>: leave
0x0000000000001177 <+62>: ret
End of assembler dump.disas <inicio>, <fin>
Desensambla un rango de instrucciones (indicando las direcciones de memoria de inicio y fin).
disas 0x1144,0x115f- Salida de ejemplo:
pwndbg> disas 0x1144,0x115f
Dump of assembler code from 0x1144 to 0x115f:
0x0000000000001144 <main+11>: mov %edi,-0x204(%rbp)
0x000000000000114a <main+17>: mov %rsi,-0x210(%rbp)
0x0000000000001151 <main+24>: mov -0x210(%rbp),%rax
0x0000000000001158 <main+31>: add $0x8,%rax
0x000000000000115c <main+35>: mov (%rax),%rdx
End of assembler dump.También se puede hacer así:
disas main+13,main+36- Salida de ejemplo:
pwndbg> disas main+13,main+36
Dump of assembler code from 0x1186 to 0x119d:
0x0000000000001186 <main+13>: call 0x1070 <malloc@plt>
0x000000000000118b <main+18>: mov %rax,-0x8(%rbp)
0x000000000000118f <main+22>: mov -0x8(%rbp),%rax
0x0000000000001193 <main+26>: mov %rax,%rsi
0x0000000000001196 <main+29>: lea 0xe6b(%rip),%rax # 0x2008
End of assembler dump.
(gdb)layout asm
Despliega una ventana que muestra el código ensamblador del binario:
layout asm
PD: Para cerrar la ventana se debe presionar Ctrl + x y a.
set disassembly-flavor intel
Cambia la sintaxis de la instrucciones en ensamblador:
set disassembly-flavor intel- Salida de ejemplo:
pwndbg> set disassembly-flavor intel
pwndbg> disas 0x1144,0x115f
Dump of assembler code from 0x1144 to 0x115f:
0x0000000000001144 <main+11>: mov DWORD PTR [rbp-0x204],edi
0x000000000000114a <main+17>: mov QWORD PTR [rbp-0x210],rsi
0x0000000000001151 <main+24>: mov rax,QWORD PTR [rbp-0x210]
0x0000000000001158 <main+31>: add rax,0x8
0x000000000000115c <main+35>: mov rdx,QWORD PTR [rax]
End of assembler dump.
pwndbg>Breakpoints
break
Pone un breakpoint en la dirección de memoria especificada.
break *0x0000000000001169- Salida de ejemplo:
pwndbg> break *0x0000000000001169
Breakpoint 1 at 0x1169: file vuln.c, line 6.delete
Elimina todos los breakpoints.
delete- Salida de ejemplo:
pwndbg> delete
Delete all breakpoints, watchpoints, tracepoints, and catchpoints? (y or n) yEjecutar el binario
run
Ejecuta el binario que está siendo depurado dentro del depurador (pwndbg). Si se ha establecido un breakpoint, la ejecución de detendrá en la instrucción previa al breakpoint.
run- Salida de ejemplo:
pwndbg> run
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
...run <<< commando
Puedes ejecutar el comando y, si espera una entrada, puedes usar <<< para indicar el el valor que se usará como entrada. Además, puedes ejecutar comandos dentro del depurador para darle al binario una entrada específica. Esto es demostrado en el siguiente post:

run <<< $(command)- Salida de ejemplo:
pwndbg> run <<< $(whoami)
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win <<< $(whoami)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Exiting
[Inferior 1 (process 656030) exited normally]step
Hace avanzar el programa a la siguiente instrucción de memoria.
step- Salida de ejemplo:
pwndbg> run
Starting program: /home/usuario/daemon/labs/ropemporium/callme/callme <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
callme by ROP Emporium
x86_64
Breakpoint 1, 0x0000000000400882 in main ()
pwndbg> step
Hope you read the instructions...
> Detectar offsets
cyclic
Con cyclic es posible crear una cadena de texto que usa la secuencia Bruijn para realizar ROP o buffer overflows.
cyclic- Salida de ejemplo:
pwndbg> cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
pwndbg> También puede usarse como entrada en el binario para realizar stack/buffer overflow.
$(python3 -c 'from pwn import *; print(cyclic(100).decode())')- Salida de ejemplo:
pwndbg> run <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400755 in pwnme ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
─────────────────────────────────────────────────────────────────────────────[ LAST SIGNAL ]──────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address: 0x0).cyclic_find / cyclic -l
Puede ser usado para encontrar el offset después de recibir un SIGSEGV (crasheo) del programa usando el valor hexadecimal que ha quedado en el RIP tras el crasheo.
cyclic -l <hex_value_inside_rip>- Salida de ejemplo:
pwndbg> cyclic -l 0x6161616c6161616b
Finding cyclic pattern of 4 bytes: b'kaaa' (hex: 0x6b616161)
Found at offset 40
pwndbg> Examinar la memoria
x/o
Muestra la memoria dentro de una dirección/registro en formato octal.
x/o <memory_address/register>- Salida de ejemplo:
pwndbg> x/o 0x0000555555555141
0x555555555141 <main+8>: 077042707x/x
Muestra la memoria dentro de una dirección/registro en formato hexadecimal.
x/x <memory_address/register>- Salida de ejemplo:
pwndbg> x/x $rip
0x555555555141 <main+8>: 0x00fc45c7x/u
Muestra la memoria dentro de una dirección/registro en formato unsigned estándar de base 10.
x/u <memory_address/register>- Salida de ejemplo:
pwndbg> x/u $rip
0x555555555141 <main+8>: 16532935x/t
Muestra la memoria dentro de una dirección/registro en formato binario
x/t <memory_address/register>- Salida de ejemplo:
pwndbg> x/t $rip
0x555555555141 <main+8>: 00000000111111000100010111000111x/b
Muestra la memoria dentro de una dirección/registro en formato single byte.
x/b <memory_address/register>- Salida de ejemplo:
pwndbg> x/b $rip
0x555555555141 <main+8>: 0xc7x/h
Muestra la memoria dentro de una dirección/registro en formato halfword (dos bytes)
x/h <memory_address/register>- Salida de ejemplo:
pwndbg> x/h $rip
0x555555555141 <main+8>: 0x45c7x/w
Muestra la memoria dentro de una dirección/registro en formato word (cuatro bytes)
x/w <memory_address/register>- Salida de ejemplo:
pwndbg> x/w $rip
0x555555555141 <main+8>: 0x00fc45c7x/g
Muestra la memoria dentro de una dirección/registro en formato giant (ocho bytes)
x/g <memory_address/register>- Salida de ejemplo:
pwndbg> x/w $rip
0x555555555141 <main+8>: 0xeb00000000fc45c7Información adicional
No solo es posible examinar lo que contiene una dirección, sino también las direcciones que la acompañan. Por ejemplo, es posible examinar el rango de direcciones desde 0x0000555555555141 hasta el 0x0000555555555160 de direcciones (32 bytes en memoria) usando el siguiente comando:
x/32<o/h/u/t/b/h/w/g> <memory address>- Salida de ejemplo:
pwndbg> x/32b $rip
0x555555555141 <main+8>: 0307 0105 0374 0 0 0 0 0353
0x555555555149 <main+16>: 023 0110 0215 05 0263 016 0 0
0x555555555151 <main+24>: 0110 0211 0307 0350 0327 0376 0377 0377
0x555555555159 <main+32>: 0203 0105 0374 01 0203 0175 0374 011También es posible mezclar los formatos. Por ejemplo, para mostrar 32 bytes formateados en hexadecimal, haría esto:
x/32xb <address/register>- Salida de ejemplo:
pwndbg> x/32xb $rip
0x555555555141 <main+8>: 0xc7 0x45 0xfc 0x00 0x00 0x00 0x00 0xeb
0x555555555149 <main+16>: 0x13 0x48 0x8d 0x05 0xb3 0x0e 0x00 0x00
0x555555555151 <main+24>: 0x48 0x89 0xc7 0xe8 0xd7 0xfe 0xff 0xff
0x555555555159 <main+32>: 0x83 0x45 0xfc 0x01 0x83 0x7d 0xfc 0x09
