Thursday, December 3, 2020

Hack The Box - Swagshop - CTF writeup



So in preparation for the OSCP and to get better at understanding security vulnerabilities I have been doing what are commonly referred to as capture the flag challenges. Here I will go over a unique vulnerability that allows remote access to a "user.txt" file and a "root.txt" file. The root.txt file can only be acquired remotely if I can gain remote command execution as the root or system user. Since this is a Linux based system I will be trying to escalate my privileges up to root so I can control the system and do the file retrieval. 

The biggest and initial step is enumeration. So far I just know there is a box with an IPv4 address of 10.10.10.140. From the name I can assume perhaps that this is a shop of some kind but that is all the initial information given. In essence this CTF is mirroring what you would refer to as black box testing in a security or penetration testing job. Here perhaps a shop owner is concerned about their security and would like to see what if anything bad could happen if an attacker targeted their site so they can know what to patch or fix ASAP. Let's proceed with initial enumeration. I'll start with Nmap.


The initial Nmap scan reveals a common setup. There are two ports open. The service known as ssh or secure shell is open on port 22 which is operating with the tcp or transmission control protocol and is using OpenSSH 7.2p2. This allows an admin to remotely control the machine but without a password I would have to check the version to see if it is a vulnerable or patched version. Next I see that port 80 is open running from an Apache/2.4.18 Ubuntu server. 




Well that is rather strange. Our initial scan revealed what appears to be a common web server but we are unable to connect on port 80. Perhaps let me try some DNS rebinding by adding this IPv4 address to my etc/hosts files so my local machine will resolve to the proper address.

 
It is still not loading. To double check to see if there is data and that it's not an issue from how I am browsing I like to get manual and use the command line. I used a simple cURL request to see the page.


Nice, now we are getting somewhere. This looks more like what I was expecting to be hosted on port 80. There is a webpage and I can see the store is running Magento and we are indeed looking at an e-commerce site. 

It was a proxy issue I needed to configure this since in the background I am also using burpsuite to intercept and analyze requests. This just basically means I am routing all the traffic from the site through this tool that allows for more manual analysis and testing.



Sometimes, trial and error is the best teacher. So in fact the site was actually not resolving because I was going to https://10.10.10.140 and not http://10.10.10.140. Since this is for practice the site does not have proper security certificates and therefore when trying to access via https the web browser by default tries to access port 443 which is unavailable. A request in a browser to http goes to port 80 which is open and now here we are at the store. 





Now when I go to see the login page I see an interesting behavior in how the server is handling the request. It is common to see a login just served from a web root directory but here I see that there are path parameters in the URL which for a Magento site makes sense since these links are interacting with a database on the backend. So the URL I get sent to when I attempt to login is: 
http://10.10.10.140/index.php/customer/account/login/. The index.php before the /customer/account/login is of particular interest. Let's keep that in our notes and move forward. 

I now want to see what else is on this server so I will use "gobuster" as follows: 


Ok, /app with a 301 is interesting to me so I went and explored that folder. Within it I found /etc/local.xml. This config file has an install date and a key so I'll add that to my notes because keys are usually important if you find them lying around.


Also, the site is using Mage with a copyright date of 2008. Let's check the site to see what version of Magento they are running. Wow, just as I suspected they are running a very old version of Magento. This store is being setup with a 2014 version of Magento. It is always important to use the latest versions of software to have the latest patches against dangerous vulnerabilities. This got me thinking I should perhaps see if I don't have to reinvent the wheel here. Ok, this is good, there appear to be quite a few exploits within Metasploit for Magento. Perhaps what we are looking for already exists which will make this engagement a lot easier than having to code some exploits from scratch. The one that first stands out in the list of potential exploits is the authenticated remote code execution. However we will have to create an admin user to use that one. Upon doing some quick googling I come to find that there is also an exploit that allows me to create an admin user. Perfect. So this will be two steps to get the initial shell. I will have to create an admin account I can use and then run the following exploit with authenticated credentials to have the remote machine connect back to my testing(attacker) box. Here below I am looking at the exploit to create a new admin user. A few points to note are that the default username:password combination will now be forme:forme. In a real penetration test or red team engagement from a public IP you would want to change this to be secure so an attacker from the outside doesn't inadvertently use the backdoor you have just created. Here I am just on a VPN and this is a practice box so this is fine. Also, upon trying to navigate to the /admin/Cms_Wysiwyg/directive/index/ directory I see that this is not allowed. 





Well this is rather strange. The directory in the exploit doesn't seem to be accessible in this version of Magento on this particular Apache server. This is going to create a big problem because without that working we won't be able to create the new admin account. But then I remembered something critical. 



Do you remember the path parameters from the initial reconnaissance? I tried including index.php before the directory in the url being requested in the exploit and am now granted access to an admin panel. This is great because now that we have a path to access the admin panel we can attempt to run the exploit without it just getting 403 errors from the server. 

Ok, so here is a quick overview of the python exploit code I will run against this Magento server. Like I said before you would want to modify the password for security on a real red team engagement. However, here for the purpose of this exercise I am going to just set the target URL and include the path parameter of /index.php. 



Now it's time for the rubber to meet the road. Let's see if this exploit works.


Excellent! The exploit worked and the first piece of this puzzle is finally falling into place. Let's test it out. We are now successfully logged in as user "forme". There used to be another exploit that could be run within this panel but it has been patched on this version of Magento. So for now let's log out and return to the authenticated RCE code we had seen above now that we have a way for the program to authenticate with our newly created admin credentials. 




Now I will move onto the other python exploit and see what needs to be modified for this particular scenario. Interestingly enough it looks like there is a php function with an argument of 'system' which will allow for the code execution. I configured it with the newly created credentials. And this highlights the importance of reconnaissance in addition to good note taking. I need the exact install date but I have that from the xml file I had found at the beginning in that /app folder. Perfect, this is the missing piece that this exploit needs to work against this particular version of Magento. The exact date and time of install are needed to proceed. Here below you can see how I modified the code:


Well, that is not what was expected. It doesn't run and python is giving some error about no control matching. I see that the module being used in mechanize so I assume there are some issues with the automated requests being sent by this headless browser of sorts. 


Unfortunately, that wasn't it. I tried a few variations of the url, included the /index.php and /admin which seems to have solved that problem. Very cool. I don't want to get into all the debugging details but suffice it to say there were a few more variations to get this code running with the newer version of mechanize than when this box was first created. However, moving forward, when I tested with the system command of 'whoami' I see that I am getting remote code execution on this system as 'www-data'. This is good because now I can see if I can establish a foothold with a shell even if it is a low level shell like the one assigned to www-data. For good measure I want to make sure the script is executing on the server correctly so I try to retrieve the /etc/passwd file. 



This is great because at this point I am able to do remote code execution on the remote machine. Now to have more control and possibly escalate my privileges I will need an initial shell which is an interactive prompt that allows me to control the machine remotely. I setup a simple netcat listener but had trouble. The issue was that it seems that a firewall was blocking all my attempts except on port 443. There was also something particular with the bash nesting for this to work. However, as you can see in the screenshots below I got the first shell and was able to upgrade it to a proper shell using "python3 -c 'import pty;pty.spawn("/bin/bash")'. Then you pause the session, modify it and return to an interactive prompt that now allows more editing without freezing or hanging.




At this point this solves the first challenge and from here it's a matter of just navigating to the user's desktop. In this case the user is named 'haris' and the 'user.txt' file is on their desktop. 



Now from the output above when checking for sudo privileges I see that this user has access to run /usr/bin/vi and appears to have wildcard editing access on /var/www/html/*.  I go ahead and open index.php in vi which is a process that I am now running as root. I then, instead of doing :wq! to exit do :!/bin/bash and I am dropped right into the root user's command prompt with full system control and privileges.


From here it is a matter of just navigating to the correct folder to retrieve the 'root.txt' flag. This was a fun box with some tricky little challenges in regards to path parameters in the url, python module debugging and finally an interesting privilege escalation at the end there. I have been learning a lot doing these challenges and I find that there are few things as exciting as getting to be "root".












Automated Exploitation of a Bluetooth vulnerability that leads to 0-click code execution

This blog post covers an interesting vulnerability that was just discovered earlier this year and an open source free tool that was created ...