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.
Serialization is used to convert data to be stored in a manner that can be easily sent across a network, transferred to a file, or added to a database. The main purpose of this process of conversion is to save the state of an object .
When untrusted user-controlled data is saved into an object and an operation is performed on it, potential vulnerabilities could arise. Such is the case with the website discussed within this report. The PHPSESSID serialization cookie, provided upon accessing the website, was passed directly into an include statement. This resulted in a local file inclusion vulnerability (LFI) which was then upgraded to remote code execution (RCE).
Attack Narrative
Other than having been provided the source code for this challenge, no other information was given except for the IP of the box and the port on which the HTTP service sits. Despite having the source code, this challenge will be treated as if that information was not given so as to replicate real-world black-box environment engagements.
Website Analysis
To begin analyzing for vulnerabilities, the website will first be accessed:
After crawling through the website, nothing out of the ordinary was discovered. There was nothing on the website that looked for user-input, so common web vulnerabilities related to XSS and SQL were unlikely to be present on the website.
Discovering Object Injection
However, after intercepting a request to the website with BurpSuite, it could be seen that the website provides a cookie to the client:
This is peculiar as there is no need for a cookie on the website because it does not have any functionality. Looking at the value for the cookie, the byte stream looks similar to base64. After base64 decoding it, the following interesting information is discovered:
From the decoded output, the cookie can be identified as a serialized PHP object.
Understanding PHP Serialized Objects
The O at the beginning of the output represents “Object”, and the number 9 represents the number of characters that comprise the name of the object (in this case it is “PageModel” which is nine characters in length). The letter “s” represents string, and it refers to the type of the data that it precedes.
LFI
Following the modification of /www/index.html to /etc/passwd, the server’s response changes:
Note that the data s:15 was modified to s:11 because /etc/passwd is 11 characters long
Request:
Reponse:
Therefore, the server is most likely performing some sort of include statement on the file parameter. To efficiently enumerate files on the server, a python script was developed to quickly perform the operation of modifying the file parameter and base64 encoding the object:
In regards to the last two lines of the file, it was found that upon inputting a nonexistent file (or a file that cannot be read due to lack of permissions), the html output contained 0 bytes of data. Now, instead of tediously base64 encoding the cookie and putting it into BurpSuite, the python script can be run instead to quickly perform this task:
From the output of the /etc/passwd file, two particular entries can be seen: the root user is running /bin/ash instead of the normal /bin/bash (this may be to prevent users from getting to root unless it is aliased to something), and there is a local user named www running /bin/sh.
Local File Enumeration
A second python script was created to quickly enumerate the local files on the system:
The script opens file called lfi.txt[1] and puts the file name into the object. When the file is present on the system, the length of the response will be greater than 0 bytes, and the name of the file will be printed out. However, after the python script finished executing, no interesting files were discovered:
RCE
Seeing as an LFI vulnerability was detected, the possibility of upgrading this to RCE is something of interest. A common methodology for converting an LFI vulnerability to RCE is log poisoning[2], a process in which a malicious GET request causes a log file to execute PHP. Before performing the malicious GET request, the location of the access log must first be identified; this can be done with the help of Nmap and Google:
Nmap detects the version running on the HTTP service to be nginx. After googling for the location of the file, it was found that the access log is located at /var/log/nginx/access.log[3]:
When a GET request with PHP is performed on the web server, code execution can be observed:
Request:
Output:
To find the flag file, the ls -R (for recursive) was used. After performing the same methodology used above, the flag file was found in the root directory of the system
Finally, the flag can be grabbed:
Post Exploitation Analysis
Due to the source code being given, the code responsible for the deserialization vulnerability can easily be analyzed.
Cause of Object Injection Vulnerability
The file associated with the serialized cookie is index.php, and the insecure way it deals with this cookie can be seen:
At the very bottom of the file, the function unserialize is performed on the argument $cookie. This would not result in a vulnerability if the cookie could not be modified by the client. However, this was not true for this challenge, and the web server could therefore be exploited.. To fix this insecurity, the json_encode() and json_decode() should be implemented instead. Furthermore, input validation must be carried out on the cookie to ensure that it does not contain unexpected data (such as a different file name).
Additionally, the serialized object should be stored in a database with a unique identifier. The unique identifier would then be the value of the cookie, and its associated data could then be safely retrieved thus removing the ability of the client to modify the object’s data.
Conclusion
The web server was vulnerable to a PHP Object Injection attack. This vulnerability can easily be avoided by practicing the secure methods outlined in the Post Exploitation Analysis section. The following remediations should be immediately observed to ensure that sensitive local files do not get read by untrusted users:
Secure the index.php file
As discussed in the previous section, the json_decode() and json_encode() functions should be used instead of the insecure unserialize() function
Insert object data into a database and use a unique identifier
The aforementioned remediations should be followed as soon as possible, as the system is currently prone to being penetrated by a malicious actor.
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 system contained an SQL injection vulnerability which could be leveraged to not only log into an application with admin privileges, but also could be used to read local files on the target. After leaking the source code of the website, an insecure usage of handling files was exploited to get RCE. With a www-data shell on the system, an insecure password of a local user located in the SQL database was cracked. Eventually the system was fully compromised through misconfigurations relating to SMTP and APT.
This box is a great introduction to the exploitation of a web server. It involves exploiting a web service through an LFI vulnerability and upgrading that to an RCE exploit via log poisoning. The method of escalating to root privileges is also instructive.