The security implications of jQuery are not terribly exciting, but they are commonly misunderstood and can have a large impact. In many situations, we see this costing significant time and money for larger organizations; jQuery vulnerabilities are often raised with risk blown out of proportion and are a common source of disagreement between penetration testers and developers.
It’s worth noting that almost all of jQuery security issues surround functions which were so commonly misused that the jQuery team modified behavior to protect developers. Although the changes have been widely interpreted as bug fixes, it can be easily argued that vulnerabilities introduced by jQuery are nothing more than developer error. It is our hope that this article can be used for organization to better assess the risk of common jQuery security issues.
$() is identical to, and the most common written form of the jQuery() function, it returns a jQuery object: essentially chunk of content to be written to DOM.
In most use cases, a jQuery function will take a selector, element, or object as a parameter. The selector, denoted by a hash (#), is an identifier for existing html content in the current DOM. In the following example we will use the jQuery html() function to modify an element with the #myDivTag selector:
<script src="https://code.jquery.com/jquery-1.10.2.js"></script> <div id="myDivTag">My old div tag text!</div> <script> $( "#myDivTag" ).html("<b>My new div tag text!</b>"); </script>
Notice the "My old div tag text!" does not show. The jQuery modifies the DOM at runtime to replace the text of our div element:
This capability is not new. In the old world, the above code would be written similar to the example below:
<div id="myDivTag">My div tag text!</div> <script> document.getElementById("myDivTag").innerHTML = "My new div tag text!"; </script>
As you can see, the jQuery function is similar to the getElementById() function. But there is an important difference: jQuery accepts more than just a selector ID, including HTML and script content. Below shows an example of this:
Our ‘Hello world!’ is now bound to browser DOM and visible on screen.
Application pentesters may already see the attack vectors in the examples above, however there’s a point we cannot stress enough: jQuery() and some element specific sub-functions are execution sinks. Penetration testers must evaluate the sources of data consumed by jQuery functions and determine if and how they are bound to DOM. For many applications this can be an extremely time consuming manual process. Fortunately, there is some help from tools like Burpsuite Professional’s passive scanner which will recognize simple occurrences of certain DOM properties placed within a jQuery function (Example: $(location.hash)). The unfortunate part is that more complex instances DOM XSS in cannot be reliably detected with automated methods.
If you arrived at this page today because a vulnerability titled “jQuery XSS Vulnerability” was raised on a pentest report, you’re not alone. At the time of this writing there are no known direct XSS vulnerabilities in the jQuery framework (not including jQuery plugins). Unfortunately, it is extremely common for the behavior changes to be interpreted as bug fixes.
Let’s take a closer look at the behavior change that has caused so many headaches. Below is an example of the most common vulnerable code:
<html><body> <script src="https://code.jquery.com/jquery-1.6.1.js"></script> <script> $(window.location.hash).appendTo("body"); </script> </body></html>
On the page below we can introduce arbitrary script directly into the browser DOM, this even bypasses Chrome’s XSS Auditor:
This XSS vector is so common that jQuery eventually changed the selector handling characteristics to prevent such attacks. A change was soon put in place to block HTML strings starting with a ‘#’. This requirement defeats XSS vectors from the window.location.hash property as content will always start with a hash.
In the following example using jQuery 1.6.1, an XSS bug is simulated. This passes script beginning with a # character as it would when being consumed from the location.hash property:
The code successfully executes.
In the example below we upgrade jQuery to 1.6.3 and run the same code:
The code no longer runs because the string starts with a # character. Not long after this change an additional behavior change was made to further fine tune the html detection of jQuery. In version 1.9.0b1 it became mandatory for html content to start with a < character. The discussion can be found here.
The jQuery ajax $.get() function (not to be confused with the .get() function) is used to make, as you might have guessed, ajax GET requests. It was found that in versions prior to 1.12.0 would automatically evaluate response content, potentially executing script if it were contained in a response.
Unlike the selector handling issue described above, we believe this behavior to be considered dangerous and potentially unexpected to even savvy developers. The important follow up to that statement is the scenarios in which this issue may manifest are far more unlikely than that of the previous issue.
This behavior may facilitate two potential vulnerabilities in an application.
Like almost all modern software, jQuery aims to be powerful and versatile. There are countless safe and legitimate functions which can contribute to security vulnerabilities when misused. The jQuery issues described here were all a result of software which functioned as designed but was implemented improperly.
Regardless if you work in Security, Compliance, IT, or management, it is a near 100% chance that you have encountered wireless networks in the enterprise before. Wireless networking has been around for quite some time and -in my experience- are given less consideration when it comes to configuration, deployment, and most importantly security. This is a problem, as a compromise of a company’s wireless network usually means access directly to the backbone of an organizations internal network and resources, among other things. This guide will take you through the how’s and why’s of wireless, in addition to teaching all of the most common (and some lesser known) attack vectors. We will also be covering Bluetooth, NFC, and some hash cracking in order to obtain a broader understanding and more effectively attacks against wireless systems.
Firstly, let’s start off strong with a brief overview of the fundamentals of wireless network communications. Now I can understand that this part might be a bit dry, but it is definitely necessary to a full understanding of “the big picture”. In addition, I know that some of our readers might already know what is in this section, but a brief refresher never hurt anyone.
In general, there are 2 components to a basic wireless network; the Access Point (Referred to as the AP), and the client. The client and the access point create a connection between each other, and send each other wireless signals (Most commonly over 2.4 and 5Ghz) that are then interpreted on each end. These signals encapsulate packets and have a fixed structure that is dependent on the protocols that are used for that specific sort of communications. The AP then interprets these signals and (in most cases) converts them to regular network traffic, that is then either routed to other wireless clients, or back into the network that the AP is connected to.
Now, with all of this data going over the air, anyone in range would be able to view and modify this traffic. That’s why different encryption methods have been devised to protect this traffic that is otherwise viewable by anyone with a good antenna and a bit of luck. A few of the most common encryption types are WPA, WPA2 (And variants), and WEP.
As you can see in the above graphic, over time there has been a shift in what protocols are used. In the infancy of wireless, there were only open (unencrypted) wireless networks, and WEP encrypted wireless networks, but as time went on, WPA and WPA2x gained popularity for reasons of security. In an open wireless network, any client can connect (also known as “associate”) with the wireless network as long as they are in range. In addition, even if a client is not associated with an open AP, they would still be able to see all traffic going over the air in essentially plain-text (when using special hardware detailed in pt. 2).
In an encrypted wireless network, the connection between the client and the AP is secure in the sense that an outside onlooker, who does not have access to the wireless network (usually through password based authentication) would not be able to view and/or modify the traffic of the clients of that specific network. The first standard form of this type of encryption was called “WEP” (Wired Equivalent Privacy). For some time, WEP was known was the de-facto method for wireless security, until tools, attacks, and methods where developed essentially making this sort of authentication useless. In modern wireless networks, much more sophisticated WPA and WPA2x security is used to better protect these networks. Although these encryption protocols are strong, they all have weaknesses that can be exploited in order to gain access to the AP, Client, or underlining network.
Now, it is not just the security of the wireless protocol itself that is important, but what those wireless clients have access to. For example, in a typical home network, the entire wireless and wired network are on the same subnet, and thus a client on the AP can have access to a smart TV hooked up by Ethernet. In addition, home networks usually have WPA/WPA2-PSK encryption that only involves a password for authentication.
Conversely, in the enterprise, it is best practice to isolate the wireless networks from the rest of the company’s internal network, and only allow wireless clients to access parts of the network on a case-by-case basis. This is called “wireless isolation” and is commonplace in the modern enterprise system. Although it is the better option, a lot of company networks fall victim to negligence during wireless configuration, thus a wireless client will have access to the internal network. This is fantastic from a would-be attacker standpoint, as the wireless network now becomes a more lucrative point of entry. Additionally, in an enterprise, it is possible that the wireless networking system has added layers of security. An example of this would be “Mac address whitelisting”. This is when only a predetermined set of clients are allowed to connect to the AP. The MAC address is data that is unique to the specific wireless adapter installed on a device (i.e. a laptop wireless card, a USB wireless card, a cell phones internal wireless adapter.). Another example would be username/password authentication that could authenticate the user with a Radius, MS Active Directory, or other server.
Now that we have a solid understanding of the basics of these types of networks, we can move on to learning about their vulnerabilities and how to exploit that, and the first thing we need to cover is hardware. What exactly you are going to need to get going with wireless penetration testing, from a basic USB card to a 2 mile+ packet cannon, this will all be covered in part 2 coming shortly.
Stay tuned at https://www.linkedin.com/company/virtue-security
Mark Shasha is a penetration tester at Virtue Security in New York City – @bignosesecurity
Many vulnerability scanners will raise false positives regarding outdated installations of OpenSSH on Ubuntu; notably issues similar to:
A thorough penetration test should weed out false positives of these issues, however they are a common occurrence in assessments relying on automated tools. In this example we will look at a fully patched Ubuntu 14.04 server with OpenSSH installed and show how to properly validate this issue. To start let’s grab the banner of the host in question:
$ nc 10.0.1.35 22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3
This banner reveals a number of configuration details about the server, but we’re only concerned right now with the very last flag on this example. The ‘2.3’ on the right is the internal Ubuntu patch level, which we can use to verify what vulnerabilities have been patched. First we should find out what the latest patch level is; to do this we can reference the following URL:
This will lead us to the following URL where we can look at the changelog: http://packages.ubuntu.com/trusty-updates/openssh-server
Which then brings us to the changelog for the latest Ubuntu openssh-server patch:
openssh (1:6.6p1-2ubuntu2.3) trusty-security; urgency=medium * SECURITY REGRESSION: random auth failures because of uninitialized struct field (LP: #1485719) - debian/patches/CVE-2015-5600-2.patch: -- Marc Deslauriers
Mon, 17 Aug 2015 21:52:52 -0400 openssh (1:6.6p1-2ubuntu2.2) trusty-security; urgency=medium [..] * SECURITY UPDATE: X connections access restriction bypass - debian/patches/CVE-2015-5352.patch: refuse ForwardX11Trusted=no connections attempted after ForwardX11Timeout expires in channels.c, channels.h, clientloop.c. - CVE-2015-5352
Here we have verification that the 2.3 patch includes an improved fix for vulnerability CVE-2015-5600 and that the 2.2 patch included updates for CVE-2015-5352 as well. This is a critical comparison that should be made to vulnerabilities raised by automated scanners. If no verification can be obtained from this method, the comparison should default to the OpenSSH version (6.6 in this case) and CVE details.
If the OpenSSH server is found to be out of date it can be easily upgraded with Ubuntu’s package management system.
$ sudo apt-get update $ sudo apt-get upgrade
We see a lot of confusion regarding the X-XSS-Protection header and thought it might be worthwhile to go over exactly what this header is and what it isn’t.
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=http://example.com/your_report_URI
XSS Auditor isn’t a solution to XSS attacks. As Justin Schuh of Google mentions, “XSS auditor is a defense-in-depth mechanism to protect our users against some common XSS vulnerabilities in web sites. We know for a fact it can’t catch all possible XSS variants, and those it does catch still need to be fixed on the affected site. So, the auditor is really an additional safety-net for our users, but not intended as a strong security mechanism.” Because of this, XSS Auditor bypasses are rated as ‘SecSeverity-None’ and, if you we’re wondering, are not eligible for bug bounty payments.
XSS Auditor takes a black list approach to identify dangerous characters and tags supplied in request parameters. It also attempts to match query parameters with content to identify injection points. If the query parameter can’t be matched to content in the response, the auditor will not be triggered. Because the browser will never have insight to server-side code, an application that mangles an XSS payload will always render the XSS auditor useless in preventing attacks.
To take a quick look at the code behind Chrome’s XSS auditor, we can get an idea of the inner workings of the detection mechanisms:
Just by looking through the function names we can see that the auditor searches for script tags, valid HTML attributes, and other XSS injection vectors. Before rendering the response in the Document Object Model presented to the user, XSS auditor searches for instances of (malicious) parameters sent in the original request. If a detection is positive, the auditor is triggered and the response is “rewritten” to a non-executable state in the browser DOM. Chrome’s ‘view-source’ has a builtin component to highlight sections on code in red that caused the XSS auditor to fire.
A bypass of XSS auditor should not be considered a vulnerability. While the Chromium team does actively improve the auditor, there are likely to always be number of bypasses for the auditor. We will not go in depth about specific bypasses as they do change with time and are likely to be outdated fast. At the time of this writing two examples that are functional in the latest version of chrome can be found here and here.
Chances are you may have arrived here after a vulnerability scan returns a finding called “Terminal Services Doesn’t Use Network Level Authentication (NLA)”. The default configuration of Windows 7, 2008, and 2012 allows remote users to connect over the network and initiate a full RDP session without providing any credentials. This allows an untrusted user to land on the system login page as shown below:
Several risks are associated with this functionality; an attacker is now able to:
The default configuration of RDP is similar to letting anyone into the lobby of your building; while they may not have keys to apartments, we generally don’t want strangers milling around the lobby to gather information if it can be avoided.
To enable network level access on Windows 2008 R2 we can do the following:
Changes are immediate, no reboot is required. Network Level Access should now be enabled.
One of the quickest and easiest ways to verify if NLA is to use the ‘rdesktop’ tool packaged with Kali Linux. When NLA is properly enabled, you will get the following error:
root@kali:~# rdesktop 10.0.1.73 Autoselected keyboard map en-us ERROR: CredSSP: Initialize failed, do you have correct kerberos tgt initialized ? Failed to connect, CredSSP required by server.
For long term solutions to this issue, organizations may wish to make this change part of a hardened standard image used to provision new servers.