TIER: 2
ARCHETYPE - WINDOWS - VERY EASY
TAGS: Network, Protocols, MSSQL, SMB, Impacket, Powershell, Reconnaissance, Remote Code Execution, Clear Text Credentials, Information Disclosure, Anonymous/Guest Access
Enumeration:
NAMP:
We found that SMB ports are open and also that a Microsoft SQL Server 2017 is running on port 1433. We are going to enumerate the SMB with the tool smbclient :
SMB:
We located a couple of interesting shares. Shares ADMIN$ & C$ cannot be accessed as the Access Denied error states, however, we can try to access and enumerate the backups share by using the following command
There is a file named prod.dtsConfig which seems like a configuration file. We can download it to our local machine by using the get command for further offline inspection.
By reviewing the content of this configuration file, we spot in cleartext the password of the user sql_svc , which is M3g4c0rp123 , for the host ARCHETYPE. With the provided credentials we just need a way to connect and authenticate to the MSSQL server. Impacket tool includes a valuable python script called mssqlclient.py which offers such functionality. But first we should better understand what Impacket is and how we can install it. As the author states
MSSQL server: https://github.com/SecureAuthCorp/impacket Impacket is a collection of Python classes for working with network protocols. Impacket is focused on providing low-level programmatic access to the packets and for some protocols (e.g. SMB1-3 and MSRPC) the protocol implementation itself. Packets can be constructed from scratch, as well as parsed from raw data, and the object oriented API makes it simple to work with deep hierarchies of protocols. The library provides a set of tools as examples of what can be done within the context of this library.
Now we are ready to learn about the usage of the tool and specifically of the mssqlclient.py script.
Foothold:
IMPACKET:
As a first step we need to check what is the role we have in the server. We will use the command found in the above cheatsheet:
The output is 1 , which translates to True In previous cheatsheets, we found also how to set up the command execution through the xp_cmdshell:
First it is suggested to check if the xp_cmdshell is already activated by issuing the first command:
Indeed is not activated. For this reason we will need to proceed with the activation of xp_cmdshell as follows:
Now we are able to execute system commands:
Finally we managed to get a command execution!
Now, we will attempt to get a stable reverse shell. We will upload the nc64.exe binary to the target machine and execute an interactive cmd.exe process on our listening port.
We navigate to the folder and then start the simple HTTP server, then the netcat listener in a different tab by using the following commands:
POWERSHELL:
In order to upload the binary in the target system, we need to find the appropriate folder for that. We will be using PowerShell for the following tasks since it gives us much more features then the regular command prompt. In order to use it, we will have to specify it each time we want to execute it until we get the reverse shell. To do that, we will use the following syntax:
The -c flag instructs the powershell to execute the command. We will print the current working directory by issuing the following: We found the folder where we will place the binary. To do that, we will use the wget alias within PowerShell ( wget is actually just an alias for Invoke-WebRequest ):
As a user archetype\sql_svc , we don't have enough privileges to upload files in a system directory and only user Administrator can perform actions with higher privileges. We need to change the current working directory somewhere in the home directory of our user where it will be possible to write. After a quick enumeration we found that Downloads is working perfectly for us to place our binary. In order to do that, we are going to use the wget tool within PowerShell:
We can verify on our simple Python HTTP server that the target machine indeed performed the request:
Now, we can bind the cmd.exe through the nc to our listener:
Finally looking back at our netcat listener we can confirm our reverse shell and our foothold to the system:
Privilege Escalation:
For privilege escalation, we are going to use a tool called winPEAS , which can automate a big part of the enumeration process in the target system. You can find more information for enumerating Windows system for Privilege Escalation paths in the HTB academy module Windows Privilege Escalation.
winPEAS:
On the target machine, we will execute the wget command in order to download the program from our system. The file will be downloaded in the directory from which the wget command was run. We will use powershell for all our commands:
We successfully downloaded the binary. To execute it, we will do the following:
From the output we can observer that we have SeImpersonatePrivilege (more information can be found here), which is also vulnerable to juicy potato exploit. However, we can first check the two existing files where credentials could be possible to be found.
As this is a normal user account as well as a service account, it is worth checking for frequently access files or executed commands. To do that, we will read the PowerShell history file, which is the equivalent of .bash_history for Linux systems. The file ConsoleHost_history.txt can be located in the directory
We can navigate to the folder where the PowerShell history is stored:
To read the file, we will type:
We can now use the tool psexec.py again from the Impacket suite to get a shell as the administrator:
-------------------------------------------------------------------------------------
OOPSIE - LINUX- VERY EASY
TAGS: PHP, Web, Custom Applications, Session Handling, Apache, Reconnaissance, Web Site Structure Discovery, Cookie Manipulation, SUID Exploitation, Authentication bypass, Clear Text Credentials, Arbitrary File Upload, Insecure Direct Object Reference (IDOR), Path Hijacking
Enumeration:
PROXY THOUGH BURP Then we select the "Manual proxy configuration" enter HTTP Proxy 127.0.0.1:8080 Note: check the option of Also use this proxy for FTP and HTTPS
We need to disable the interception in Burp suite as it's enabled by default. Navigate to Proxy Tab , and under Intercept subtab select the button where Intercept in on so to disable it. Now that everything is setup correctly we refresh the page in our browser and switch in Burp Suite under the Target tab and then on the Sitemap option: It is possible to spot some directories and files that weren't visible while browsing. One that is indeed very interesting it's the directory of /cdn-cgi/login
DEFAULT CREDS After trying a couple of default username/password combinations, we didn't managed to get any access. But there is also an option to Login as Guest . Trying that and now we are presented with couple of new navigation options as we are logged in as Guest:
We need to find a way to escalate our privileges from user Guest to super admin role. One way to try this is by checking if cookies and sessions can be manipulated. Then we can navigate to Storage section where Cookies are being presented.
We can try change the id variable to something else like for example 1 to see if we can enumerate the users Indeed we got an information disclosure vulnerability, which we might be able to abuse. We now know the access ID of the admin user thus we can try to change the values in our cookie through the Developer tools so the user value to be 34322 and role value to be admin . Then we can revisit the Uploads page.
Foothold:
Now that we got access to the upload form we can attempt to upload a PHP reverse shell.
BRUTE FORCE DIR Now we might need to bruteforce directories in order to locate the folder where the uploaded files are stored but we can also guess it. uploads directory seems a logical assumption. We confirm that by running also the gobuster tool.
REVERSE SHELL But first, we will need to set up a netcat connection:
Then request our shell through the browser:
We got a reverse shell! In order to have a functional shell though we can issue the following:
Lateral Movement:
As user www-data we can't achieve many things as the role has restricted access on the system. Since the website is making use of PHP and SQL we can enumerate further the web directory for potential disclosures or misconfigurations. After some search we can find some interesting php files under /var/www/html/cdncgi/login directory. We can manually review the source code of all the pages or we can try search for interesting strings with the usage of grep tool. grep is a tool that searches for PATTERNS in each FILE and print lines that match the patterns. We can use cat * to read all files while pipeing the output to grep where we provide the pattern of a string that starts with the word passw and followed by any string such as for example words passwd or password. We can also use the switch -i to ignore case sensitive words like Password.
We found user robert . In order to login as this user, we use the su command:
Unfortunately, that wasn't the password for user robert . Let's read one by one the files now. We are going to start with db.php which seems interesting
Privilege Escalation:
Before running any privilege escalation or enumeration script, let's check the basic commands for elevating privileges like sudo and id:
We observe that user robert is part of the group bugtracker . Let's try to see if there is any binary within that group:
We found a file named bugtracker . We check what privileges and what type of file is it:
There is a suid set on that binary, which is a promising exploitation path.
Commonly noted as SUID (Set owner User ID), the special permission for the user access level has a single function: A file with SUID always executes as the user who owns the file, regardless of the user passing the command. If the file owner doesn't have execute permissions, then use an uppercase S here. In our case, the binary 'bugtracker' is owned by root & we can execute it as root since it has SUID set.
The tool is accepting user input as a name of the file that will be read using the cat command, however, it does not specifies the whole path to file cat and thus we might be able to exploit this. We will navigate to /tmp directory and create a file named cat with the following content:
We will then set the execute privileges:
In order to exploit this we can add the /tmp directory to the PATH environmental variable. PATH is an environment variable on Unix-like operating systems, DOS, OS/2, and Microsoft Windows, specifying a set of directories where executable programs are located.
Now we will check the $PATH:
Finally execute the bugtracker from /tmp directory:
Remove that cat on the /tmp directory..! Then cat the flag
-------------------------------------------------------------------------------------
VACCINE - LINUX- VERY EASY
TAGS: Web, Network, Vulnerability Assessment, Databases, Injection, Custom Applications, Protocols, Source Code Analysis, Apache, PostgreSQL, FTP, PHP, Reconnaissance, Password Cracking, SUDO Exploitation, SQL Injection, Remote Code Execution, Clear Text Credentials, Anonymous/Guest Access
1. Enumeration:
There are three ports open: 21 (FTP), 22 (SSH), 80 (HTTP). Since we don't have any credentials for the SSH service, we will start off with enumeration of the port 21, since the Nmap shows that it allows anonymous login:
FTP
We can see that there is a backup.zip file available, we will download it:
It will be located in the folder from where we established the FTP connection. We will try to unzip it with the command unzip:
The compressed archive asks us for a password. We will try a couple of basic passwords to see if it will let us in, however, no luck in it. We will have to somehow crack the password. The tool we will use for this task is named John the Ripper.
PASSWORD CRACKING
JOHN THE RIPPER
In order to successfully crack the password, we will have to convert the ZIP into the hash using the zip2john module that comes within John the Ripper:
Now, we will type the following command:
So it will load the wordlist & it will do a bruteforce attack against the hash stored in file hashes. Once the password is cracked, we will use the --show option to display the cracked password.
We can see the cracked password: 741852963 . We will extract the files now:
We will now read the index.php file first:
We can see the credentials of admin:2cb42f8734ea607eefed3b70af13bbd3 , which we might be able to use. But the password seems hashed.
HASHCAT
We will try to identify the hash type & crack it with the hashcat:
It provides a huge list of possible hashes, however, we will go with MD5 first: We will put the hash in a text file called hash & then crack it with hashcat:
We will start our web browser to enumerate the port 80, see where can we log in We can see the login page, by supplying the previously found username & cracked password, we managed to log in successfully!
2. Foothold:
So the dashboard has nothing special in it, however, it has a catalogue, which might be connected with the database. Let's create any query:
By checking the URL, we can see that there is a variable $search which is responsible for searching through catalogue. We could test it to see if it's SQL injectable, but instead of doing it manually, we will use a tool called sqlmap.
SQLMAP
We will provide the URL & the cookie to the sqlmap in order for it to find vulnerability. The reason why we have to provide a cookie is because of authentication To grab the cookie, we can intercept any request in Burp Suite & get it from there, however, you can install a great extension for your web browser called cookie-editor :
The cookies in HTTP messages of requests are usually set the following way:
Knowing that, here's how our sqlmap syntax should look:
We ran the sqlmap. Note: There will be some questions that the tool will ask you, you can respond with 'Y ' or 'N', or just by pressing ENTER for the default answer.
Out of this output, the thing that is important to us is the following: GET parameter 'search' is vulnerable. Do you want to keep testing the others (if any)? The tool confirmed that the target is vulnerable to SQL injection, which is everything we needed to know. We will run the sqlmap once more, where we are going to provide the --os-shell flag, where we will be able to perform command injection:
We got the shell, however, it is not very stable & interactive. To make it much stable, we will use the following payload:
NETCAT
We will turn on the netcat listener on port 443:
Then we will execute the payload:
We got the foothold. We will quickly make our shell fully interactive:
We got the fully interactive shell now. The user flag could be found in /var/lib/postgresql/
3. Privilege Escalation
We are user postgres , but we don't know the password for it, which means we cannot check our sudo privileges:
We will try to find the password in the /var/www/html folder, since the machine uses both PHP & SQL, meaning that there should be credentials in clear text
In the dashboard.php , we found the following:
SSH
Note that the shell might die all of a sudden, instead of re-doing the exploit all over again, we will use the SSH to log in:
We will type the sudo -l to see what privileges do we have So we have sudo privileges to edit the pg_hba.conf file using vi by running sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf . We will go to GTFOBins to see if we can abuse this privilege:
So we will execute it We are unable to execute the following command because sudo is restricted to only /bin/vi /etc/postgresql/11/main/pg_hba.conf
There's also an alternative way according to GTFOBins:
So we will perform that as well:
We managed to open the vi editor as the superuser, which has root privileges Now we will press the : button to set the instructions inside Vi:
Next, we will open up the same instruction interface & type the following:
-------------------------------------------------------------------------------------
UNIFIED - LINUX- VERY EASY
TAGS: Web, Vulnerability Assessment, Databases, Injection, Custom Applications, Outdated Software, MongoDB, Java, Reconnaissance, Clear Text Credentials, Default Credentials, Code Injection
Enumeration:
The scan reveals port 8080 open running an HTTP proxy. The proxy appears to redirect requests to port 8443 , which seems to be running an SSL web server. We take note that the HTTP title of the page on port 8443 is " UniFi Network "
Upon accessing the page using a browser we are presented with the UniFi web portal login page and the version number is 6.4.54 . If we ever come across a version number it’s always a great idea to research that particular version on Google. A quick Google search using the keywords UniFy 6.4.54 exploit reveals an article that discusses the in-depth exploitation of the CVE-2021-44228 vulnerability within this application.
To determine if this is the case, we can use FoxyProxy after making a POST request to the /api/login endpoint, to pass on the request to BurpSuite, which will intercept it as a middle-man. The request can then be edited to inject commands. We provide a great module based around intercepting web requests.
First, we attempt to login to the page with the credentials test:test as we aren’t trying to validate or gain access. The login request will be captured by BurpSuite and we will be able to modify it. Before we modify the request, let's send this HTTPS packet to the Repeater module of BurpSuite by pressing CTRL+R
Exploitation:
The Exploitation section of the previously mentioned article mentions that we have to input our payload into the remember parameter. Because the POST data is being sent as a JSON object and because the payload contains brackets {} , in order to prevent it from being parsed as another JSON object we enclose it inside brackets " so that it is parsed as a string instead.
We input the payload into the remember field as shown above so that we can identify an injection point if one exists. If the request causes the server to connect back to us, then we have verified that the application is vulnerable.
JNDI: is the acronym for the Java Naming and Directory Interface API . By making calls to this API, applications locate resources and other program objects. A resource is a program object that provides connections to systems, such as database servers and messaging systems.
LDAP: is the acronym for Lightweight Directory Access Protocol , which is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over the Internet or a Network. The default port that LDAP runs on is port 389 .
After we hit "send" the "Response" pane will display the response from the request. The output shows us an error message stating that the payload is invalid, but despite the error message the payload is actually being executed. Let's proceed to starting tcpdump on port 389 , which will monitor the network traffic for LDAP connections.
tcpdump is a data-network packet analyzer computer program that runs under a command line interface. It allows the user to display TCP/IP and other packets being transmitted or received over a network to which the computer is attached.
After tcpdump has been started, click the Send button in repeater. The tcpdump output shows a connection being received on our machine. This proves that the application is indeed vulnerable since it is trying to connect back to us on the LDAP port 389. We will have to install Open-JDK and Maven on our system in order to build a payload that we can send to the server and will give us Remote Code Execution on the vulnerable system.
Open-JDK is the Java Development kit, which is used to build Java applications. Maven on the other hand is an Integrated Development Environment (IDE) that can be used to create a structured project and compile our projects into jar files . These applications will also help us run the rogue-jndi Java application, which starts a local LDAP server and allows us to receive connections back from the vulnerable server and execute malicious code. Once we have installed Open-JDK, we can proceed to install Maven. But first, let’s switch to root user.
Once we have installed the required packages, we now need to download and build the Rogue-JNDI Java application. Let's clone the respective repository and build the package using Maven.
This will create a .jar file in rogue-jndi/target/ directory called RogueJndi-1.1.jar . Now we can construct our payload to pass into the RogueJndi-1-1.jar Java application. To use the Rogue-JNDI server we will have to construct and pass it a payload, which will be responsible for giving us a shell on the affected system. We will be Base64 encoding the payload to prevent any encoding issues.
After the payload has been created, start the Rogue-JNDI application while passing in the payload as part of the --command option and your tun0 IP address to the --hostname option.
Now that the server is listening locally on port 389 , let's open another terminal and start a Netcat listener to capture the reverse shell.
Going back to our intercepted POST request, let's change the payload to:
After sending the request, a connection to our rogue server is received and the following message is shown.
Once we receive the output from the Rogue server, a shell spawns on our Netcat listener and we can upgrade the terminal shell using the following command.
The above command will turn our shell into an interactive shell that will allow us to interact with the system more effectively. From here we can navigate to /home/Michael/ and read the user flag.
Privilege Escalation:
The article states we can get access to the administrator panel of the UniFi application and possibly extract SSH secrets used between the appliances. First let's check if MongoDB is running on the target system, which might make it possible for us to extract credentials in order to login to the administrative panel.
MongoDB is a source-available cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas.
Let's interact with the MongoDB service by making use of the mongo command line utility and attempting to extract the administrator password. A quick Google search using the keywords UniFi Default Database shows that the default database name for the UniFi application is ace .
The output reveals a user called Administrator. Their password hash is located in the x_shadow variable but in this instance it cannot be cracked with any password cracking utilities. Instead we can change the x_shadow password hash with our very own created hash in order to replace the administrators password and authenticate to the administrative panel. To do this we can use the mkpasswd command line utility.
The $6$ is the identifier for the hashing algorithm that is being used, which is SHA-512 in this case, therefore we will have to make a hash of the same type. SHA-512, or Secure Hash Algorithm 512, is a hashing algorithm used to convert text of any length into a fixed-size string. Each output produces a SHA-512 length of 512 bits (64 bytes). This algorithm is commonly used for email addresses hashing, password hashing...
Once we've generated the SHA-512 hash the output will look similar to the one above, however due to the salt the hash will change every time it is generated. A salt is added to the hashing process to force their uniqueness, increase their complexity without increasing user requirements, and to mitigate password attacks like hash tables. Let's proceed to replacing the existing hash with the one we created.
We can verify that the password has been updated in the Mongo database by running the same command as above. The SHA-512 hash appears to have been updated.
Let's now visit the website and log in as administrator . It is very important to note that the username is case sensitive. The authentication process was successful and we now have administrative access to the UniFi application.
UniFi offers a setting for SSH Authentication, which is a functionality that allows you to administer other Access Points over SSH from a console or terminal. Navigate to settings -> site and scroll down to find the SSH Authentication setting. SSH authentication with a root password has been enabled.
The page shows the root password in plaintext is NotACrackablePassword4U2022 . Let's attempt to authenticate to the system as root over SSH.
The connection is successful and the root flag can be found in /root
-------------------------------------------------------------------------------------
INCLUDED - VIP - LINUX- VERY EASY
TAGS: PHP, Web, Network, Custom Applications, Protocols, Apache, TFTP, LXD, Reconnaissance, Local File Inclusion, Clear Text Credentials, Arbitrary File Upload
Enumeration:
The scan shows only port 80 TCP open, which seems to be running Apache version 2.4.29 .
Apache: Let's navigate to port 80 using a browser like Chromium.
LFI: Local File Inclusion The webpage features the landing page for a Gear manufacturing company. It does not seem to contain anything of interest, however, if we take a look at the URL we can see that this has automatically changed to
This is a common way that developers use to dynamically load pages in a website and if not programmed correctly it can often lead to the webpage being vulnerable to Local File Inclusion, but more about that in a bit.
In the above example, the code is located inside index.php , which is used to dynamically load other pages of the website by using the file variable as the control point. If this variable has not been specified in the GET request, the page automatically re-writes the URL and loads home.php . If the value has been specified, the code attempts to load a page from the value of the variable. For instance, if the variable was file=register.php , the PHP code would attempt to load register.php from the same folder. This is a good way to seamlessly load different web pages, however if the include command is not restricted to just the web directory (e.g. /var/www/html ), it might be possible to abuse it in order to read any file that is available on the system and the user who is running the web server has privileges to read.
This is what is called a Local File Inclusion vulnerability and is defined as follows:
Local file inclusion (also known as LFI) is the process of including files, that are already locally present on the server, through the exploitation of vulnerable inclusion procedures implemented in an application.
We can easily determine if this is the case by attempting to load a file that we know definitely exists on the system and is readable by all users. One of those files is /etc/passwd and to load it, change the file parameter from home.php to /etc/passwd . For consistency reasons we will show this process with the cURL command line utility instead of a browser. This is successful and a list of users is returned.
It is worth noting that inputting /etc/passwd might not always work if the inclusion already specifies working directory.
In this example the DIR parameter is used to acquire the current working directory that the script is located in (e.g. /var/www/html ) and then the value of the file variable is concatenated at the end. If we were to input /etc/passwd the full path would become
which would result in a blank page as there is no such file or folder on the system.
To bypass this restriction we would have to instruct the code to search in previous directories. This would work similarly to how navigating to a previous folder is done with the cd command
In such a case, /etc/passwd would become
TFTP: Trivial File Transfer Protocol
Back to the task at hand, while a Local File Inclusion is a great way to gather information and read system files the goal of every Penetration Tester is to achieve Remote Code Execution on a system. There is a plethora of ways that an LFI can turn into RCE, from log poisoning to plaintext passwords in configuration files and forgotten backups, however in this case the passwd file gave us a big hint as to how to proceed. The last user that is listed is called tftp
A quick Google search reveals that Trivial File Transfer Protocol (TFTP) is a simple protocol that provides basic file transfer function with no user authentication. TFTP is intended for applications that do not need the sophisticated interactions that File Transfer Protocol (FTP) provides.
It is also revealed that TFTP uses the User Datagram Protocol (UDP) to communicate. This is defined as a lightweight data transport protocol that works on top of IP
UDP: UDP provides a mechanism to detect corrupt data in packets, but it does not attempt to solve other problems that arise with packets, such as lost or out of order packets. It is implemented in the transport layer of the OSI Model, known as a fast but not reliable protocol, unlike TCP, which is reliable, but slower then UDP. Just like how TCP contains open ports for protocols such as HTTP, FTP, SSH and etcetera, the same way UDP has ports for protocols that work for UDP.
To this end let's use Nmap to scan for open UDP ports. It is worth noting that a UDP scan takes considerably longer time to complete compared to a TCP scan and it also requires superuser privileges
The scan reveals that port 69 UDP is open and an instance of the TFTP server is running on it. In order to communicate with TFTP, we need to install it on our Linux machine.
LinPEAS:
When it comes to privilege escalations, we can manually check one by one or we can simply run any automation script to do the searching for us. Since this box is the Linux box we can use LinPEAS
Once the tool is installed its manual page can assist with its usage.
Foothold:
TFTP works by default without the need for authentication. That means that anyone can connect to the TFTP server and upload or download files from the remote system. We can chain this with the LFI vulnerability that we have already identified, in order to upload malicious PHP code to the target system that will be responsible for returning a reverse shell to us. We will then access this PHP file through the LFI and the web server will execute the PHP code. We can either create our own PHP code or use one of the many available PHP reverse shells that can be found online through a Google search. One of them can be found here.
Copy the code and place it inside a file called shell.php . Then open it using a text editor such as nano or vim and edit the following lines.
The $port variable specifies the local port that we will use to catch the reverse shell. This can be anything we want as long as it is not already being used by a local process. Let's leave it to 1234 . The $ip variable specifies the local IP address that the shell will be returned to. We can acquire this IP by running the ifconfig command and looking under tun0 . The IP will be in the form of 10.10.14.X .
After acquiring the local IP, change it in the PHP shell and save it. Then we will upload the file to the remote TFTP server.
Now that the file has been uploaded, we need to start a local Netcat listener on the port that we specified in the reverse shell, in order to catch the connection once it initiates
Finally we must find a way to access the uploaded PHP file through the LFI but we do not know where the file is uploaded on the target system. Thinking back to the passwd file that we read earlier, the TFTP user's home folder is specified as /var/lib/tftpboot
This information can also be found with a quick Google search: The default configuration file for tftpd-hpa is /etc/default/tftpd-hpa. The default root directory where files will be stored is /var/lib/tftpboot
With this information let's try to load /var/lib/tftpboot/shell.php
Once this command is run our terminal will appear stuck, however our Netcat listener has caught a connection
The received shell is not fully interactive, however we can make it a bit better by using Python3.
With access to the system as the www-data user we do not have enough privileges to read the user flag, therefore we need to find a way to move laterally to user mike who was also found on the passwd file. A good place to start our enumeration would be the web server directory as it often contains configuration files that might include passwords.The web-related files are usually stored in the /var/www/html folder, so that's where we are going start
The folder contains two interesting hidden files, .htaccess and .htpasswd . The htpasswd file is used to store usernames and passwords for basic authentication of HTTP users. Let's read both files.
The second file contains credentials for user Mike. Often times users re-use the same passwords for multiple services and accounts and compromising one of them might mean that all of them are compromised. If user Mike has used the same password for their system account, we might be able to use the su utility to acquire a shell with their privileges.
This is successful and the user flag is located in /home/mike .
Privilege escalation: The next step is escalating to the root user in order to gain the highest privileges on the system. Looking at the groups that user Mike is a member of, the lxd group is listed
A quick Google search on what LXD is reveals the following information LXD is a management API for dealing with LXC containers on Linux systems. It will perform tasks for any members of the local lxd group. It does not make an effort to match the permissions of the calling user to the function it is asked to perform
Digging a little deeper into LXD and searching for the keywords LXD Exploit on Google reveals the following information
A member of the local “lxd” group can instantly escalate the privileges to root on the host operating system. This is irrespective of whether that user has been granted sudo rights and does not require them to enter their password. The vulnerability exists even with the LXD snap package
This is exactly what we need and this HackTricks page describes the whole exploitation process step by step. The exploit works by making use of the Alpine image, which is a lightweight Linux distribution based on busy box. After this distribution is downloaded and built locally, an HTTP server is used to upload it to the remote system. The image is then imported into LXD and it is used to mount the Host file system with root privileges.
Let's begin by installing the Go programming language as well as some other required packages.
Then we must clone the LXC Distribution Builder and build it:
After the build is complete let's download the Alpine YAML file and build it:
-------------------------------------------------------------------------------------
MARKUP - VIP - WINDOWS - VERY EASY
TAGS: Web, Injection, Apache, SSH, PHP, Reconnaissance, Scheduled Job Abuse, Weak Credentials, Arbitrary File Upload, XXE Injection, Weak Permissions
Enumeration:
Once completed, the scan reports three open ports, 22, 80 and 443. Since we have no credentials at hand, we can start by exploring the webserver running on port 80.
We are met with a simple login page. Attempting a number of default credentials lands us on a successful login
We successfully logged in with admin:password .
Moving past the login screen, we are met with a number of resources. After a quick exploratory dive into each of them, we notice that the Order page could be of interest to us, since it presents us with a number of user input fields
In order to better understand how this input functions, we will need to fire up BurpSuite, set up our FoxyProxy plug-in to intercept requests from port 8080, and interact with the input fields by filling in some random information and pressing the Submit button.
Searching for a XML exploitation cheatsheet we are met with several examples such as the following. From the above cheatsheet an excerpt can be taken that is of relevance to us.
Lets try to read /etc/passwd in different ways. For Windows you could try to read:
In this first case notice that SYSTEM "file:///etc/passwd" will also work.
Considering that the target is running a version of Windows, we will be using c:/windows/win.ini file in order to test out the exploit's validity. In BurpSuite, send the request to the Repeater module by rightclicking on the request and clicking Send to Repeater or by pressing the CTRL + R combination on your keyboard. Then, switch to the Repeater tab at the top of the BurpSuite window and change the XML data section of the request to the following:
The output of the win.ini file on the target itself is dispalyed in our response message, which proves that the XML External Entity vulnerability is present
Foothold:
We can try guessing where all the important files are located, however, it might turn out to be an endless road. Let's try to find something of importance on the HTML code of the web page.
Modified by Daniel . This could be a hint towards a username present on the target system, since they would have access to the web page's source code for configuration purposes. Since we can already navigate the files present on the target system using the XXE vulnerability, let's attempt to navigate to the daniel user's .ssh folder in order to attempt to retrieve their private key
The RSA key is printed out in the output, from where it can be placed in a local file on your machine named id_rsa , which you can later use to connect to the target at any point in time. Pick a folder to create the file in and run the commands below
Next, copy the RSA key present in the Response in BurpSuite and paste it into the id_rsa file using the text editor of your choice. It's also important to set the right privileges for the id_rsa file so as to be accepted by your SSH client. The commands below will achieve and verify this
Following this, we can attempt to log in as the daniel user through our SSH client, using his private key.
We are successful, and the user flag can be retrieved from C:\Users\daniel\Desktop .
Privilege Escalation:
In order to retrieve the Administrator flag, we will need to escalate our privileges. Let's check our current ones by typing the command below
Seeing as the privileges listed for the daniel user are not of very unique importance, we can move on to exploring the file system in hopes of discovering any uncommon files or folders that we could use to leverage our attack.
In the C: directory, there is a Recovery.txt file which seems uncommon, but is empty, as seen from the 0 bytes displayed next to the name of the file in our output above. However, the Log-Management folder might be of some use to us, as it's also uncommon. Inside it, we find a job.bat file, which upon further inspection offers us some insight into its' purpose.
The purpose of job.bat seems to be related to clearing logfiles, and it can only be run with an Administrator account. There is also mention of an executable named wevtutil , which upon further investigation is determined to be a Windows command that has the ability to retrieve information about event logs and publishers. It can also install and uninstall event manifests, run queries and export, archive and clear logs. We now understand the use of it in this case, alongside the el and cl parameters found in the job.bat file
Since the file itself can only be run by an Administrator, we could try our luck and see if our usergroup could at least edit the file, instead of running it, or if there are any mismatched permissions between the script and the usergroup or file configuration. We can achieve this by using the icacls command
Looking at the permissions of job.bat using icacls reveals that the group BUILTIN\Users has full control (F) over the file. The BUILTIN\Users group represents all local users, which includes Daniel as well. We might be able to get a shell by transferring netcat to the system and modifying the script to execute a reverse shell.
Before then, we need to check if the wevtutil process mentioned in the job.bat file is running. We can see the currently scheduled tasks by typing the schtasks command. If our permission level doesn't allow us to view this list through Windows' command line, we can quickly use powershell's ps command instead, which represents another security misconfiguration that works against the server.
We can see that the process wevtutil is running, which is the same process listed in the job.bat file. This indicates that the .bat script might be executing. Because the target host does not have access to the Internet, we will need to deliver the nc64.exe executable through our own connection with the target. In order to do so, we will first need to download nc64.exe on our system, start up a Python HTTP server on one of our ports, then switch to the shell we have on the host to issue a wget command with our address and the nc64.exe file residing on our server.
This will initialize a download from the host to our Python server for the executable. Make sure you don't switch folders after downloading the executable. The Python HTTP server needs to be running in the same directory as the location of the downloaded nc64.exe file we want to deliver to the target. In order to download the executable on our system, we can use this link:
Switching to the shell we have on the host, we can issue the download command targetting our own IP address on the VPN. Replace the {your_IP} parameter in the command pictured below with the IP address assigned on your own machine to the tun0 interface. You can check this by running ip a or ifconfig on one of your own terminals.
Since we have full control over the job.bat script, we will modify its' contents by running the following command. Make sure to run it from the Windows Command Line, where the daniel@MARKUP user is displayed before every command, and not from Windows PowerShell, where PS is displayed before every command. As before, make sure to change the {your_IP} parameter with the IP address assigned to your tun0 interface and the {port} parameter with a port of your choice, which you will listen for connections on
We will turn on the netcat listener and wait for the script to execute.
Once the script executes, we receive a shell on the terminal tab the listener was active on.
The reverse shell might be slow, in that case, either be patient or quickly read the root flag directly without navigating around the target directories using the following command:
The exploit might not work on the first attempt. Due to the sensitivity of the exploit, many attempts might lead to failure, in which case the exploit should be run multiple times until it becomes successful. There is no workaround for an unstable exploit. Make sure you are not running the echo command from PowerShell
-------------------------------------------------------------------------------------
BASE- VIP - LINUX- VERY EASY
TAGS: Web, Vulnerability Assessment, Custom Applications, Source Code Analysis, Authentication, Apache, PHP, Reconnaissance, Web Site Structure Discovery, SUDO Exploitation, Authentication bypass, Clear Text Credentials, Arbitrary File Upload, Information Disclosure, PHP type juggling
Enumeration:
The scan shows two ports open - Port 80 (HTTP) and Port 22 (SSH). We start off with enumerating port 80 using our web browser.
We can see a very simple webpage with the provided links in the navigation bar. By clicking the Login button, we are presented with the login page:
We can see that there is a login directory, where the login.php is stored. Let's try accessing that directory by removing login.php from the end of the URL.
The /login folder seems to be configured as listable, and we can see the php files that are responsible for the login task. There's also a .swp file, which is a swap file
Swap files store the changes that are made to the buffer. If Vim or your computer crashes, the swap files allow you to recover those changes. Swap files also provide a way to avoid multiple instances of an editor like Vim from editing the same file
The swap file was probably created due to a crash of the Vim application while the developer was editing the file. The file ended up being unnoticed and left in the web application files where anyone can download it by clicking on the login.php.swp in the listable directory. The web server is set up to handle requests to .php files by running the PHP code in the file, but because the extension of the swap file isn't .php , the web server returns the raw code as text.
Let us click on this file and download it for further analysis. Navigate to the folder where the file is downloaded and read it to see if any parts of the code from login.php were saved. Typically the most straight forward way to recover a Vim swap file is with the vim -r [swap file] . But sometimes these files can be particular and won't recover.
As .swp is a temporary file, it contains a lot of non-human-readable content, thus we will use the strings utility to read this swap file because strings will only display the human-readable text.
The Linux "strings" command makes it possible to view the human-readable characters within any file. The main purpose of using the "strings" command is to work out what type of file you're looking at, but you can also use it to extract text. The output from the strings command is as follows
After checking the code, we can see HTML/PHP code, but it's out of order and a bit jumbled. Still, there's enough there that we can figure out what the code is trying to do. Specifically, the block of PHP code that handles login appears to be upside down. To make it look normal we can place the output of the strings command inside a new file and read it with the tac utility, which reads files similar to cat but instead does so in a backwards manner
Now the output is much better for reading. After analyzing the file, here's the part that is interesting
The developer is using the strcmp function to check the username and password combination. This function is used for string comparison and returns 0 when the two inputted values are identical, however, it is insecure and the authentication process can potentially be bypassed without having a valid username and password.
This is due to the fact that if strcmp is given an empty array to compare against the stored password, it will return NULL . In PHP the == operator only checks the value of a variable for equality, and the value of NULL is equal to 0 . The correct way to write this would be with the === operator which checks both value and type. These are prominently known as "Type Juggling bugs" and a detailed video explanation on this can be found here.
In PHP, variables can be easily converted into arrays if we add [] in front of them. For example:
Adding [] changes the variable $username to an array, which means that strcmp() will compare the array instead of a string
In the above code we see that if the comparison succeeds and returns 0 , the login is successful. If we convert those variables into empty arrays ( $username[] & $password[] ), the comparison will return NULL , and NULL == 0 will return true, causing the login to be successful.
In order to exploit this vulnerability, we will need to intercept the login request in BurpSuite. To do so fire up BurpSuite and configure the browser to use it as a proxy, either with the FoxyProxy plugin or the Browser configuration page. Then send a login request with a random set of credentials and catch the request in Burp.
Change the POST data as follows to bypass the login.
This converts the variables to arrays and after forwarding the request, strcmp() returns true and the login is successful. Once logged in, we see a file upload functionality.
Foothold:
Since the webpage can execute PHP code, we can try uploading a PHP file to check if PHP file uploads are allowed or not, and also check for PHP code execution. Let us create a PHP file with the phpinfo() function, which outputs the configurational information of the PHP installation.
After test.php has been created, choose the file after clicking the Upload button, and we will be presented with the following notification, which shows that the file was successfully uploaded.
Next, we need to figure out where uploaded files are stored. To do that, we will use Gobuster to do a directory brute force.
The scan shows that a folder called _uploaded exists. We will navigate to it to see if our file is there. It appears that this folder has also been set as listable and we can see all the files that are uploaded
Upon clicking on test.php , we can see the output of the phpinfo() command, thus confirming code execution
Let us now create a PHP web shell which uses the system() function and a cmd URL parameter to execute system commands. Place the following code into a file called webshell.php
We are making use of the $_REQUEST method to fetch the cmd parameter because it works for fetching both URL parameters in GET requests and HTTP request body parameters in case of POST requests. Furthermore, we also use a POST request later in the walkthrough, thus using the $_REQUEST method is the most effective way to fetch the cmd parameter in this context
After the web shell has been created, upload it as shown previously.
The above URL returns with the output of the id command, letting us know that Apache is running in the context of the user www-data . Let's intercept this request in BurpSuite and send it to the repeater tab by pressing the CTRL+R shortcut, or by right-clicking inside the request and selecting Send to Repeater
Now that we know we can execute code on the remote system, let's attempt to get a reverse shell. The current request is an HTTP GET request and we can attempt to use it to send a command that will grant us a reverse shell on the system, however, it is likely that one might encounter errors due to the presence of special characters in the URL (even after URL encoding them). Instead, let us convert this GET request to a POST request and send the reverse shell command as an HTTP POST parameter. Right-click inside the Request body box, and click on the "Change request method" in order to convert this HTTP GET request to an HTTP POST request
In the repeater tab, we can alter the request and set the following reverse shell payload as a value for the cmd parameter
This reverse shell payload will make the remote host connect back to us with an interactive bash shell on the specified port that we are listening on.
In order to execute our payload, we will have to first URL encode it. For URL encoding the payload, select the payload text in the request body and press CTRL+U
It's important to URL encode the payload, or else the server will not interpret the command correctly. For example, in the POST body, the & character is used to signal the start of a new parameter. But we have two & characters in our string that are both a part of the cmd parameter. By encoding them, this tells the server to treat this entire string as part of cmd .
Let's now start a Netcat listener on port 443 and then send the request in Burp for the payload to execute.
A reverse shell on the system is successfully received.
Lateral Movement:
As we already know, the Apache server is running as the www-data use and the shell we received is also running in the context of this user. www-data is a default user on systems where web servers are installed and usually has minimal privileges. Let's enumerate the system to see if we can find any interesting information that might allow us to escalate our privileges. We will first check the configuration file in the login folder that we found earlier. These configuration files often include credentials that are used to communicate with SQL or other types of data storage servers. Let's read it.
The config.php file reveals a set of credentials. System administrators often re-use passwords between web and system accounts so that they do not forget them. Let us enumerate further to see if this password is valid for any system user. To do that, we will first list the files in the /home directory to quickly identify the users on the system
A folder called John is found, which gives us a valid username.
The su command can usually be used to switch to a different user in Linux, however, as our shell is not fully interactive, this command will fail. There are methods for upgrading this shell to an interactive one, but luckily, the Nmap scan showed that port 22 is open, which means we can attempt to log in as the user John over SSH with the password that we identified.
This is successful and the flag can be found in the users home directory, i.e. /home/john/user.txt .
Privilege Escalation:
We now need to escalate our privileges to that of the root user, who has the highest privileges in the system. Instead of running a system enumeration tool like linPEAS , let us first perform some basic manual enumeration. Upon checking the sudo -l command output, which lists the sudo privileges that our user is assigned, we see that user john can run the find command as a root
It is rarely a good idea to allow a system user to run a binary with elevated privileges, as the default binaries on Linux often contain parameters that can be used to run system commands. A good list of these binaries can be found in the GTFOBins website
GTFOBins is a curated list of Unix binaries that can be used to bypass local security restrictions in misconfigured systems.
For windows systems, the equivalent of this is the LOLBAS.
Once we navigate to the GTFObins website, we can search for find .
Under the Sudo section we see the following. According to GTFOBins , we need to run the following command in order to escalate our privileges:
The -exec flag is used with find to run some command on each matching file that is found. We'll abuse this to just run a shell, and since the process is running as root (from sudo ), that shell will also be running as root. Instead of sh , we will use bash as it offers better syntax and it is actually an improvement over sh . Once we run this command, we successfully obtain a root shell.
The root flag can be found in the root folder, /root/root.txt .
Last updated