IMF
IMF is a boot2root mcahine that contains many flags. After each flag, the difficulty is increased. This machine starts with web and ends with a buffer overflow.
Enumeration
Nmap port scan
Nmap scan shows that on port 80 an Apache webserver is running.
|
Visiting the page shows the following
Flag 1
On the Contact Us
page the first flag shows in the inspect element section.
flag1{YWxsdGhlZmlsZXM=}
This is base64 and decodes to allthefiles
Flag 2
With the hint from the first flag, I inspect the javascript files. There are 3 suspicious files. Especially one of them looks like base64 because of the ending ==
in the filename, since base64 strings often end with this for padding. Read this
if you want an explanation why.
Combining these three strings togeher gives me the following string:
ZmxhZzJ7YVcxbVlXUnRhVzVwYzNSeVlYUnZjZz09fQ==
|
Decoding the flag gives the following:
imfadministrator
Flag 3
The hint from the last flag is an hidden endpoint to login.
Inspecting the page reveals the following comment
This leeds me to this
article from Hacktricks about bypassing PHP comparisons.
What this tells us to do is change the name="pass"
field in the form to name="pass[]
.
Remember that on the service page /contant.php
on the main website there were some names shown.
The tool CeWL
can be used to generate a wordlist.
|
Then any tool can be used to try all the combinations, which are only 78.
|
After trying rmichaels
seemed to working and we are redirected to the page containing the flag.
The flag flag3{Y29udGludWVUT2Ntcw==}
decodes to continueTOcms
.
Flag 4
The dashboard we are redirected to when we click IMF CMS
contains a strange URL structure pagename=home
.
Putting a single quote '
there gives the following output
High chance that this contains a sql vulnerability. I spin up sqlmap
, but don’t forget to get the php cookie uljlgrmgg3ut9jmfoikejsvrc0
from the devtools, since we need to be authenticated to see this page.
|
Sqlmap found a vulnerability and retrieves all the information. After looking around the database a bit I found the interesting part, which reveals another endpoint /tutorials-incomplete
(scroll to the right).
|
This page shows a QR code
Scanning the QR code gives the fourth flag flag4{dXBsb2Fkcjk0Mi5waHA=}
which decodes to uploadr942.php
Flag 5
At the /uploadr942.php
endpoint there is a upload form.
Trying to upload the default pentestmonkey PHP reverse shell
gives an error invalid file type
.
After trying a couple different files, I found out that i can upload GIF images without any error. Now the next point is finding out where my uploaded GIF is stored. After a file is uploaded succesfully, the html on the page changes as can be seen in the two pictures below.
Before uploading:
After uploading a comment appears that seems to be the filename.
The file appears to be uploaded at /imfadministrator/uploads/8e1064d0df99.gif
.
Changing the php reverse shell to a gif extension phpshell.gif
, shows that a the WAF detects it and blocks the upload.
In order to restrict this I look for file signatures
extensions that I can use to bypass this filter. I end up with the following script that is just a simple php web shell. \x73\x79\x73\x74\x65\x6d
is system
is hexadecimal, so it isn’t detected by the WAF.
|
After uploading this file I successfully execute commands.
Now instead of the cmd commands I start a nc
listener on my host machine
|
And on the webpage I pass my reverse shell URL encoded.
|
Passing this in the URL gives the following final URL
|
This successfully gives me a reverse shell, from where I also print flag 5.
|
Flag 5 decoded: agentservices
Flag 6
Before continuing I upgrade this awful shell to an interactive one using a python3 trick I will write another post about. With this interactive shell i can use CTR+C
, arrow keys and more.
|
Running netstat -antp
shows a local port at 7788
.
|
Running cURL on the page gives the following output with Invalid Agent ID
|
Running whereis agent
, also from the hint, gives the following binary path.
|
Running the binary, I can give input and it returns invalid agent ID
|
Going to the location of the binary, there is another file called access_codes
.
|
this contains the following information
SYN 7482,8279,9467
. SYN is for a SYN request, probably a portknock.
|
After port knocking it, port
7788
is opened!
|
Now I can remotely connect with the binary
|
To transfer the binary I use python uploadserver
on my Kali machine.
|
From the machine with the agent
binary I make the following curl request to transfer the binary to my Kali machine.
|
Now I have the binary locally, so I can inspect it better using my favorite tools; checksec, Ghidra and GEF .
Checksec is used to check the binary security settings.
|
Ghidra detects it as a x86 file.
Ghidra automatically loads us into the main function.
Changing the names of the important variables easily shows the logic. All we have to do is to get a 0
from the bool_strncmp
, that means the strings that are being compared are the same. In the strncmp
function, the first 8 characters of our_input
and local_28
are being compared against each other. our_input
contains our input from the fgets
functions. On line 16 asprintf
dynamically allocates memory for local_28
and format the ‘string’ 48093572
into that memory. So if we input 48093572
we should get into the main menu.
And yes, we validate successfully.
|
Trying some options shows a zsh: segmentation fault
in menu option 3. Submit Report
.
|
In Ghidra we can also see the dangerous gets
function.
I start gef
to dynamically analyze the binary.
I first generate a pattern to be able to identify the exact offset.
|
Running the binary and giving that as input to menu option 3, shows our eip
value.
Passing this back to gef
to calculate the offset
|
Using python3 to generate a string to verify this offset of 168
|
Passing that in menu option 3 shows exactly what we expect to see, namely our B
’s
Now it is time to add the shellcode. We can also see in the picture above that all our A
’s are in the eax
register. This means we just need to find a jmp eax
instruction which address we place instead of the B
’s to execute our shellcode. There is a call eax
at 0x8048563
Now I need to generate a reverse shell using mfsvenom
. Note the /x86
for the correct architecture. Also note the -b "\x00"
to make sure there are no null bytes in the shellcode.
|
I then wrote the following script to automate the exploit using pwntools .
|
|
Running the script successfully gives root and the final flag can be printed.
|
And final flag, flag6 can be decoded to Gh0stProt0c0ls
.