Phishing for Shellshock

Written on:October 10, 2014
Comments are closed


I thought I was done writing about Shellshock, but a recent discussion with some colleagues got me back on the topic. We were commenting about how organizations tend to react very quickly to patching external assets for a bug like Shellshock but many probably wait to patch internal assets due to a false sense of security. It got me thinking about how an external actor could exploit a bug like Shellshock on internal systems and one of the first things that came to mind was a JavaScript-based phishing attack.

The PoC Exploit

I figured one of the easiest methods of probing an internal network for vulnerable assets is to get the organization’s employees to do it for you.The idea is simple…host a malicious page with JavaScript that when visited, will initiate a series of web requests on the user’s internal network that include a crafted HTTP header to trigger the Shellshock vuln. I wrote a very basic proof of concept below:

All the script does is force the client to make multiple GET requests to a pre-defined range of non-routable/internal IP addresses. These GET requests are sent via AJAX with modified Accept and Accept-Language headers to create a simple reverse shell back to a waiting external IP address. The use of these particular headers over other, more-commonly used headers such as User-Agent and Cookie was necessary due to the restrictions of XMLHTTPRequest. However, in my testing it was still successful, depending of course on the configuration of the target web application (e.g. CGI script that sets env variables for multiple headers). Don’t forget, non-CGI PHP scripts can also be vulnerable so this simple scan would would not target those.

The JavaScript parses the URL for some configuration parameters — namely the IP addresses to scan and the external callback IP address. Here’s an example URL:


The first parameter (s) is the internal IP at which to start scanning. Params e3 and e4 are the ending values for the third and fourth octet of the starting IP. With the above example URL, the script will make an HTTP request to Then it will make a request to, etc until it reaches I could have been more granular and chose to modify all octets but this was only intended as a simple PoC. The last parameter (d) is the callback IP and port to which the remote shell will connect. Obviously the example is an invalid value but you get the idea.

Within the content of the JavaScript I also included a urlArray that contains various paths to try on each target internal IP. This could be useful if you wanted to attempt several common cgi script names, or if you knew of vulnerable technologies deployed by the organization on its internal network (but didn’t know the specific internal IP address).

The beauty of this attack method is that (other than the available headers from which to choose) CORS is not a factor here. Below you can see that the scan does trigger a warning.


However, this makes no difference to us as the “attacker”  because we don’t need to see the response from the request made by the client. We simply need to force the client to make the request and sit back and wait for a vulnerable internal server to initiate the call back to us. In fact, CORS browser settings did not have an effect on my testing:


Here’s another view of the phished client making the requests, first to the “malicious”, external page (184.X.X.X) and then to the internal assets (172.X.X.X):


Since it’s the internal server that will be initiating the subsequent call out (with the remote shell), it is less likely that it would be blocked by an IPS or Firewall. This demo only illustrates a simple piped shell, though there are better options for a more robust exploit method. Also, in this demo version, neither the url nor the JavaScript is obfuscated.

Just like the external mass scans, the success of an attack like this will vary, even on an unpatched network. Obviously, likelihood goes up if you can be sure about the internal IP address space. There are several ways you could do this via passive and active reconnaissance. I won’t go into all of those here (I cover some passive recon techniques in this post), but I will cover one interesting method I saw the other day in a DerbyCon video by Nate Power in which he shows how to obtain the IP address of the internal interface of an organizations OWA server by a crafted request using openssl s_client. I validated this works very well:


Once you have your target internal IP range, you just have to get one or more organizational users to visit your malicious page. That’s where the phishing component comes in. It usually doesn’t take much…a crafted email with the link is pretty much all you need. Maybe throw in an insecure Google redirector for good measure 🙂

Here’s a very short demo video. The cmd window on the left is the waiting listener sitting on an external IP address. The window on the right is the session of the internal organizational “victim” that receives the phishing email and clicks the link. You’ll notice the shell is almost instantaneous because I limited the scan to only a single IP address for this demo. A larger scan will take some more time so so if you’re going to test this, you’ll want to choose a longer video!

I tested this with a considerably larger group of IP addresses with the same success. I also successfully tested on both Windows and Mac clients using IE, FF, Chrome, and Safari. Btw, the listener code is available here if you’re interested.

So what mitigating protections are there for an attack like this? Well, for starters, patch all vulnerable assets, both internal and external. Phishing awareness is also a factor, though it’s a moving target. Again, there’s limitations on the types of AJAX-based HTTP requests so it’s not as flexible as scanning external IPs directly. Also, your network IPS or even client-based HIPS solutions may catch these type of web requests. Surprisingly, Symantec was able to detect and stop these requests on several of the machines I tested with (both Mac and Windows).



Oh yeah, did I mention…patch those internal systems?

The above PoC script is really basic and could be greatly improved and in the end, there’s nothing groundbreaking or novel about this approach, though it does illustrate why patching all vulnerable assets as soon as possible is a sound security practice.

Until next time,

– Mike

6 Comments add one

  1. Hey there Mike. Just want to say that I love reading your security blog and I respect the organization which you’ve put into all of your articles. Even while Shellshock has become a bit played out (to me) I found this approach of abusing shellshock to be very interesting. Thanks for all the great material.


    • Mike Czumak says:

      Thanks Alec, that’s great to hear. I was reluctant to post a second article about something that had gotten so much hype but I did think it illustrated the dangers of becoming complacent with patching internal systems. Thanks again for the feedback. – Mike

  2. sadi zane says:

    Hi Mike.

    I just one say thanks so much for all your impressive informative articles .

    Honestly great job easy read .. Simply fantastic .

    Sadi zane

  3. Andy says:

    I found this article after trying out this same attack earlier this week. This is such a clear & well-written post!

    My results differed from yours in that I couldn’t get IE to send the GET request to the vulnerable server and I could only get FF to send the GET request under certain conditions. Chrome would consistently send it. I’ll try your PoC to see if I see anything different, but we did essentially the same thing.

    I initially started thinking about it because of the MS15-034 vulnerability, which requires the “range” header to be set. I couldn’t get it to work (I think) because the range header is not considered a “simple header” in the spec, which causes the GET request to be considered a “Cross-Origin Request with Preflight” ( This causes the browser to initially send out an OPTIONS request, however if you only set some combination of “simple headers” in your AJAX request, the browser will consider the GET a “Simple Cross-Origin Request”.

    After a while a friend was looking at the list of simple headers and we got to thinking maybe shellshock could be exploited with just the Accept-Language header.

    With China’s “Great Cannon” being able to inject code like this into people’s web requests just as easily as code to DDOS GitHub, it’s a pretty bad vulnerability. (

    Just curious, did you contact Google/Firefox/etc? It’s not really clear to me why you wouldn’t ALWAYS follow the “Cross-Origin Request with Preflight” path and ALWAYS initially send an OPTIONS request. (I may just be missing something…)

    With shellshock completely exploitable this way and MS15-034 so close to being exploitable, it seems pretty likely that there will be more to come too…


    • Mike Czumak says:

      Thanks Andy. Funny you should mention ms15-034…I just posted on it a few minutes ago ( and in it I mention the possibility of a phishing-style attack similar to the one I devised for Shellshock. You’re absolutely correct in that the likelihood is lower because the Range header is protected by CORS restrictions and requires the typical preflight OPTIONS request. Although browsers do tend to vary in their handling of CORS, much of it (including the way simple headers are to be treated) is outlined in the spec as you pointed out, so in many cases the browser developers are simply honoring that. In terms of reliability for my Shellshock exploit I used the Accept and Accept-Language headers and don’t recall having any issues (though it’s been several months and I don’t remember if I tested every browser).

      – Mike