Knock knock.. who’s there? Time for a new exploit challenge! This time the challenge is a VM created by zer0w1re on VulnHub. I got a tip from a friend who actually build the vulnerable binary in the VM so I gave it a go 😀 .
After mounting the VM and doing an initial nmap scan to locate the VM I fired up a second nmap scan to get an indication what is running on the box. Nmap returned one port: 1337!
After connecting to the service on port 1337 we get three seemingly random numbers. Let’s start knocking!
I actually spent quit some time trying to knock the ports and opening the hidden ports. I tried all the combinations of these three ports but no luck.. I then started playing with socket timeouts and sleeps and noticed the port knocking process is actually quite time sensitive. Sleeping for one second between each knock solved all my problems and I could reliable open the ports on the VM. I eventually ended up with this little neat python script:
And after executing the script you can see two new ports popping up in the nmap scan:
When visiting the website we are presented with a very bare-bone page with an image and the message “Gotta look harder”. There was nothing interesting in the html code of the page and dirbuster didn’t list anything interesting. I ended up downloading the image and on further inspection it contained some additional data appended:
These are hopefully SSH login credentials.. but no luck. A friend pointed out that the credentials *may be* ROT13 encrypted. After decrypting the two strings I was presented with the two strings: “nosaJ” and “fnk2Pj9Bj”. Still no luck.. When reversing the first string the outcome resembles somewhat a normal name: “Jason”. After reversing both strings and trying those as credentials I was presented with a shell! A restricted shell though.. We can escape this easily by running bash from our restricted shell… Now, let’s do some real work!
Exploiting Tiny File Crypter
Looking around I found a binary called tfc, Tiny File Crypter..
Interesting! After encrypting some files and decrypting them again I noticed the program uses some symmetric encryption algorithm meaning the encrypted data can be decrypted again with the same algorithm. I started fuzzing the input: long filenames and big files and soon we ran into this:
This is interesting! Let’s investigate the crash! I pulled the binary to my own VM and opened it in IDA and began analyzing the logic. It appeared that the program had an encryption function called “CryptFile” which reads x number of bytes from the input file to a buffer on the stack, encrypts them (xcrypt function) and then writes them to the output file. This code loops until the read function returns 0 indicating end of file. Here is the IDA graph of the read/crypt/write part:
The funny thing is that it is reading the data from the input file in a buffer on the stack with a fixed size (4096 bytes) and the function does not do any length checking.. The vulnerability is triggered after the input file has been “encrypted” so we need to trigger the vulnerability with an already encrypted file. So we now have a good understanding what goes wrong and where the exploitable part is. How to proceed? We need to create an input file which is already encrypted and big enough to trigger the vulnerability, preferably with some MSF pattern to see which offsets in the file overwrite what on the stack. We need to create an application that does the same as tfc but doesn’t have… ‘extra features’. The nice thing about IDA is that we can create pseudocode which we can use to create our own crypter application. We copied the xcrypt function and build a very small c program to encrypt files bigger than 4096:
We create a pattern of 4500 character with metasploit and encrypt it with our own crypter application. We fire up GDB (in combination with Peda) and run tfc with the newly crafted pattern file. We can clearly see our msf pattern in certain registers and on the stack! With pattern_offset we identify the following:
- EBP register is overwritten with our pattern, offset 4120
- EIP register is overwritten with our pattern, offset 4124
- ESP points to our pattern, offset 4128
So we need to create a payload (exec /bin/sh or something else), place that in the encrypted file and overwrite EIP with the adress of that payload. But how do we get that adress? Luckily ESP points to our input data, offset 4128 so if we can find a “jmp esp” ROP gadget in the binary we are golden! We are going to put our payload at offset 4128 and the address of the “jmp esp” instruction at offset 4124. Let’s see if there is such a ROP gadget:
Yes, there it is! We now simply create a payload with msfpayload and create a handy python script to generate the malicous tfc file:
Yeah! we got the flag!! zer0w1re and c0ne: thanks for the nice challenge!