flag.txt (You need this in same directory as fiap for local exploit. fiap will read flag once you exploit it)
Enumeration
checksec
Running thecode
Static Analysis
flag function
say_hi function
It takes two inputs from the user. First input is printed.
Since PIE is enabled, we would need to leak the stack for canary and leak the code section to override the changed canary with correct canary and override the ret with flag.
Exploit
First we will use the first BoF and string format vulnerability to leak the address of say_hi+13 and stack_canary. Here we have to use “%#$p” where # is the offset in the stack instead of using many “%p” to reveal the stack. Because offset we want to look into will be overwritten by %p. offset 3 is say_hi+13 address and offset 11 is canary address.
Then we would need to figure out where canary and ret reside when you are doing second BoF. Once you figure that out, we can make exploit that has PADDING + Canary Address + Padding2 + RET Address(Here we want to return to flag function).
In encrypt(), it takes even index from string and performs algorithem. And for odd index, it does xoring.
Even Index
For each character, it will check if character is in between “a” and “z”. Pretty much checking if it is an alphabet. Then it will add 14 to it. Then check if it is alphabet still. If it isn’t it will make it into alphabet by subtracting 26 which is length of alphabet. This makes it so that result will always be an alphabet.
Odd Index
For odd index, they just xor first 15 character. then make it into hex.
Return
They then retun result from even index + odd index
Reversing
How I really feel
I feel like I should really learn to use z3 (Thoerom Solver). But This was easy enough to do it by hand. https://github.com/Z3Prover/z3
Even Index
Check if the text is in between “a” and “z”. If it is, subtract randnum(14). Then check if character is less then “a”. If it is, you add 26 to it.
Odd Index
First you want to undo the hex() and turn it into bytes. Then you want to undo the “utf-8” decoding. Then you can just use the same xor function since inverse of xor is xor.
Section of String to Read for Even and Odd Index
If you play around with encryption, you will realize that if you give string of 10 character, it will give you string that is 15. Which makes sense since for even index result, you will have 5. As for odd index it will be (len(input_string)/2) * 2 = len(input_string).
So if you give string that is 16 character, you will get 8 + 16 = 26 character string.
Putting even index and odd index list into correct string
You just have to loop through and ping pong between even index and odd index list to make a string.
Code
def decrypt(msg):
even_text = msg[0:15]
randnum = 14
text_length = len(even_text)
endtext = ""
for i in range(0, text_length):
weirdtext = even_text[i]
if weirdtext >= "a" and weirdtext <= "z":
weirdtext = chr(ord(weirdtext) - randnum)
if weirdtext < "a":
weirdtext = chr(ord(weirdtext) + 26)
endtext += weirdtext
# Decrypt xor string
oddMsg = msg[15:]
oddMsg= bytes.fromhex(oddMsg)
oddMsg = oddMsg.decode("utf-8")
xored = xor("aaaaaaaaaaaaaaa", oddMsg)
endtext_list = list(endtext)
xored_list = list(xored)
result = []
for i in range(0,15):
result.append(endtext_list[i])
result.append(xored_list[i])
return ''.join(result)
This challenge wasn’t suppose to be solved like this when I was discussing it with the author. To check out the intentional way, check out Finches in PIE. It is similar to this one except, PIE is enabled.
flag.txt (You need this in same directory as fiap for local exploit. fiap will read flag once you exploit it)
Enumuration
When you run the program, it will ask you for two inputs. And it talks about canary. I am guessing that you have to leak the canary and over ride the ret with the first input. Then fix the overwritten canary with the leaked canary.
Static Analysis
There is handy function called flag that prints out the flag
In say_hi(), we can see that the first_input can be used for format string vuln.
Second input also uses gets() so we can use it for BoF.
Solution
Looking at this problem, you can just use format string exploit to write to puts.got since after printf(&first_input) it will run puts and since we don’t return, we can go to flag function.
At first, you might think that this was simple BoF where you write shell on a stack and return to the shell. Since in description they say they have zero security features enabled. Well ASLR is enabled so it won’t work. We know that it wont work because if you give invalid tree, you get pointer and you can see that it changes every time.
Since PIE is disabled, we can just do ROP to libc. This technique is explained in this post so I won’t be writing about it. https://elnath.io/2020/05/30/stop/