Exploitation of binary vulnerabilities or learning to “pump” (Part 1)

Hello everyone! In this series of writeups we will analyze known tasks on exploitation of binary vulnerabilities from Exploit Exercises (they are no longer there, so I recompiled them for Win). About what Buffer Overflow is is written perfectly and with examples HERE (great article by @Mogen). By the way, there are a lot of cool problems on the topic of PWN on Codeby Gamesso I recommend it 🙂

So… we will solve our problems using static (Ghidra) and dynamic analysis (x64dbg). And most importantly, we will do it without the source code of the vulnerable program, unlike how it is done HERE And HERE.

Stack0

To solve this problem I will use my “sand-reverse-laboratory”, where I already have everything “installed” 🙂

First, we'll do “statics”. We launch Hydra and throw in the program that we'll “pump”.

Let's start the analysis:

We get the disasm listing and decompiled code:

Rename the variables (there is little code here – not really necessary, but it's a good habit):

So, we see that we have a 64-character buf array and a “bad” gets() function. We also have a condition: if the var1 variable = 0, we will get “Try again”. Accordingly, to get to the else branch, we need to somehow modify the var1 variable. Select the code and remember the “test eax, eax” instruction, we will need it a little later.

Let's move on to “dynamics”. Open the program in x64dbg, look at strings and find that same “Try again”, fall through the instructions, see “test eax, eax” and “test al, al”. Put a breakpoint on any of these instructions.

“Submit to the entrance” 10 characters.

We see that the EAX register has not changed at all (equal to 0). PS The “test eax, eax” instruction in x86/x64 assembly language performs a bitwise logical AND operator between the eax register and itself. The “test” instruction does not change the value in the eax register, but affects the processor flags, in particular, the zero flag (ZF), which is set if the result of the AND operation is zero. This means that if eax contains zero, then ZF will be set, and if eax is not zero, then ZF will be cleared. This allows using the je (jump if equal) or jne (jump if not equal) instructions to jump to certain labels depending on the EAX value.

We make a conditional jump (je) and get “Try again”.

Great! What if we send 65 characters instead of 64?

We see that there is a one in EAX. Thus, 64 bytes “led” us to the beginning of the changed variable (var1), and the next byte will be placed in the changed variable. In other words, 65 bytes of data will change 0x00000000 to 0x00000041 (the 65th character “A”). Thus, the unsafe gets() function allowed us to overflow buf and change the var1 variable, which led us to the following result:

Thank you all for your attention 🙂

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *