18 lines
1.6 KiB
Plaintext
18 lines
1.6 KiB
Plaintext
# Level4
|
|
|
|
Using ghidra, we can decompile the code and see that it fills a buffer of 520 bytes using `fgets()`.
|
|
This buffer will then be passed directly as a parameter to `printf`. This allows us to print whatever we want (e.g dump the stack, change variables).
|
|
We can see in the decompiled code that a global variable `m` exists. The program will execute a `system("/bin/cat /home/user/level5/.pass")` if `m == 16930116`.
|
|
Our goal here will be to change the value of this variable in order to get the password.
|
|
|
|
To do so, we will first dump the stack to know where the buffer is located.
|
|
Let's print something basic like `print("AAAA" + "%x"*20)`. We can see that 0x41414141 (= "AAAA") is printed at the 12th position in the stack.
|
|
Now that we know where our buffer is located on the stack, let's exploit printf.
|
|
|
|
By using the `%n` flag, we can change the value of a variable to the length of what's been printed before (here, `m == 16930116`).
|
|
Since we cannot pass arguments to printf directly, we need to specify the position in the stack of the variable we want `%n` to print to. This is achieved by writing `m`'s address (obtained through gdb, static address since ASLR is disabled) at the beginning of the buffer.
|
|
Finally, we print the 16930112 bytes (+ 4 bytes for the address have already been printed) so that `m == 16930116`.
|
|
Unfortunately, unlike the previous level, we cannot print all the bytes directly in the buffer. For this, we will use printf's padding feature to print the right number of bytes.
|
|
Here is the command:
|
|
`(python -c 'print "\x10\x98\x04\x08" + "%16930112p" + "%12$n"') | ./level4`
|