IMF
- Layout for this exercise:

1 - INTRODUCTION
- The goal of this exercise is to develop a hacking process for the vulnerable machine IMF.
- According to the author's description IMF contains a number of flags starting off easy and getting harder as the hacking process progresses, so that each flag gives a hint for the next flag.
- IMF can be downloaded from here:
https://www.vulnhub.com/entry/imf-1,162/
- Once downloaded and extracted with VirtualBox:

2 - ENUMERATION
- Using netdiscover to find the IP that corresponds to IMF:


- Scanning with Nmap:

- So there is just one service available, the web server at port 80. Let's connect directly via a browser:

2 - FLAG 1
- Examining the source of the script contact.php we find a reference to flag1:

- Storing and decoding with base64:


- So we have the 1st flag: allthefiles
3 - FLAG 2
- Also, at the same script contact.php we find 3 lines of characters ending up with ==, what gives a hint that it might be another encoded base64 string:

- Storing the characters and decoding with base64, we find a recursive reference to flag2:


- Storing and decoding with base64:


- So we have the 2nd flag: imfadministrator
4 - FLAG 3
- When trying the string achieved at the 2nd flag as a folder for the web server we get a login form:

- Viewing the source:

- Somebody called Roger gives us a message about SQL and a "hard-coded password".
- Having a look at the Contact Us tab we are offered 3 different potential usernames:

- Let's study the different responses from the server when using rmichaels, akeith or estone as usernames and any other random password:
- For rmichaels we have an answer of "invalid password":


- For akeith we have an anwser of "invalid username":


- For estone we have an anwser of "invalid username":


- We conclude that rmichaels is a valid username, although we don't know yet the password.
- However, at this point we know that the server is using the language PHP (contact.php), and Burp can help us to analyze what is happening when entering credentials at the login form.
- Let's use Burp to intercept the login process using rmichaels as username and an arbitrary password:


- First thing to do is to store the cookie value for later usage:

- Now, let's review the characteristics of the PHP strmcp() function.
- strmcp() compares two strings, returning 0 if they are equal; however, it also returns 0 if one the arguments is a string and the other one an array, like explained here:
http://danuxx.blogspot.com/2013/03/unauthorized-access-bypassing-php-strcmp.html
https://marcosvalle.github.io/ctf/php/2016/05/12/php-comparison-vlun.html
- We can take advantage of that circumstance by modifying the parameter pass to pass[] (an array):


- Forwarding, the authentication is bypassed:


- Storing and decoding we get the flag3: continueTOcms


5 - FLAG 4
- Following the advice at flag3 let's continue by clicking IMF CMS (after disabling Burp's interception):


- Enumerating the potential databases with sqlmap and option --dbs:


- Searching for tables at database admin:


- Dumping the content of admin -> pages:


- The result of the dump shows that under pages there is another hidden folder called tutorials-incomplete. Let's check it:

- At the lower left side of the picture we can find one QR code. Isolating and decoding it with xing we get the flag4:



- Storing and decoding flag4:


- The script uploadr942.php leads us to a very interesting uploading page:

6 - FLAG 5
- Let's try some uploads to learn whether there is any type of restriction of filter about the format of the uploading files.
- First, we learn that uploading a PHP file is not allowed:



- However, the same script adding the string GIF89 and renaming with the .gif extension is accepted:



- Viewing the source, there is a string that refers to the successfully loaded file:


- Trying to visit the /uploads folder we notice that it is forbidden, but it means that at least we know of its existence:

- We are able to confirm that the file has been successfully uploaded to /uploads:

- Now, let's try to execute some commands remotely from the brower.
- For instance, who is our user:

- Where we are:

- Listing the content of the folder /uploads we detect the presence of the text file flag5_abc123def.txt:

- By the way, the rest of the content corresponds to other uploaded files during previous trials, as well as the current valid test.gif script.
- Reading flag5_abc123def.txt we find the flag5:

- Storing and decoding with base64, we find that the flag 5 is agentservices:


7 - FLAG 6
7.1 - Locating the agent service
- Now, the flag 5 agentservices should be our passport to the final root access.
- Searching for some agent service, it seems that it works at port tcp/7788:

- Locating the executable agent:

- Checking permissions for agent:

- Running it, and Agent ID is required:

7.2 - Port knocing
- Looking for more interesting content at /usr/local/bin we find an access_codes file:

- Reading access_codes, it seems like a port knock sequence:

- While port 7788 is filtered by default ...

- ... after executing command knock (following the information provided by access_codes) the port 7788 is open:


7.3 - Running the agent service
-Setting a Netcat listening session on port 7788:

- Connecting with Netcat from Kali to IMF's port 7788, where agent service is running:

- Let's transfer agent to our local machine:


- The transfer is successful:

- What type of file is agent:

- Giving execution permissions and running locally agent:

- Entering an invalid Agent ID like abcde:

- Let's ltrace our program, entering an arbitrary ID:

- It is noticeable that the function strncmp compares string abcde with string 48093572.
- Shall this be the valid Agent ID? The answer is yes:

7.4 - Getting a remote limited shell with weevely
- weevely is is a stealth PHP web shell that simulate telnet-like connection. It is an essential tool for web application post exploitation, and can be used as stealth backdoor or as a web shell to manage legit web accounts, even free hosted ones.
https://tools.kali.org/maintaining-access/weevely
- Using weevely let's generate a PHP script called prueba with the password secreto:


- Reading prueba:


- Adding GIF89 to the top of the script and renaming with the extension .gif:


- Now, it is time to upload prueba.gif to IMF:


- The upload is successful, and the server sends back a code referring to the uploaded script:

- Launching weevely from Kali, we achieve a low privileged remote shell at IMF:

7.5 - Privilege Escalation
- The final step will to exploit the executable agent with the goal of getting a root shell will be done in short.