Thursday, December 1, 2011

Node.JS Security - the good, bad and ugly

At the moment, dev world is full of rave about Node and server side JavaScript (databases like MongoDB and the likes). There hasn't been a better time for front-end and JS developers. On the first look - it appears great, promising and exciting.

On the down side, as with most upcoming technologies, there isn't enough security analysis, consideration and advisory to reference and understand gotchas with server side JS. Nothing wrong with that - it's functions, coolness and innovation that brings business and not security (history/economics is a testimony).

In this post, I will share my security view point as I see it. This could be an ever growing list and the kind of things you can achieve with server side JavaScript - there is no early end to this.

Let's start with the good things. Node inherently introduces a great security benefit over
traditional server side programming paradigms and that is "secure by default" (reminds me of my NetBSD days). As highlighted in white below, your create your web server - a bare bone types and not a full blown with bells and whistles like Apache.



And then chose and pick what you want. Like define what your doc root will have - unlike anything and everything in a traditional web doc root. Like highlighted in yellow below - that is what your web server will respond to for requests. Rest needs to be caught by a 404.



Summarizing - your web server isn't configured and capable more than what you want it to be unlike Apache, Tomcat or IIS. I recall countless instances of Tomcat compromises due to default admin and manager apps that come installed and running with default passwords. And IIS getting exploited with WebDAV buffer overflow when in reality the web app never really needed it in first place. Typically web servers sent a false sense of security where developers mostly considered them to be secure. And we all know, more features, bigger the attack surface. Bigger the attack surface more chances of things going wrong. And something that can go wrong will go wrong!

On the flip side - the bad parts. Node carries over the known dangerous JavaScript APIs like the eval that can be trivially exploited to do server side injection (that were earlier only client side exploits like XSS).

Let's look at a PoC exploit where app evaluates the input and returns  an output like below


Abusing eval on client side would result an XSS but on server-side it induces a server side injection alike SQL Injection as seen below where we inject an HTTP response.


 The screenshot below highlights execution of server side injection.


To best of my knowledge, this issue was first brought to notice in context of Node by Bryan Sullivan at BlackHat. Not a brand new exploit. We know eval is evil. What is worth note here is most developers wouldn't imagine this happening at the first go. From that perspective this exploit vector server side is novel.

What do I see ugly? The ugly parts are the ones that introduce new attack vectors. There should have been default protection built-in ideally. The event driven single threaded programming model is not what web developers are used to. Node is single threaded and a simple error can create a denial of service condition as highlighted in the screenshot below.


As highlighted, hitting submit crashes the node server.


Similar DoS condition would result when messing with global variables - intentionally or unintentionally. Above scenarios are quite likely considering JS developers are usually quite used to errors. I see thousands of live sites day in and out that have a number of errors showing up in Firebug console and running absolutely ok which will not be the case as you go server side.

Another  ugly part is that web developers are not quite used to service permissioning. Web developers had it outsourced to Apache/IIS, would now end up running their node services as root, that earlier ran as nobody.

A 1000 feet high apple to apple comparison between let's say PHP and Node tells me - it took a step back in security. At least, you would come to expect a sanitization/validation library for a new programming language, if not a fancy new auto-sanitization module like PHP Filter (aah yes - Filter isn't a complete auto sanitization in PHP but you get what I mean).

An honest look and I feel node isn't meant to be used as is.  With a strong framework, is how it should be used. There are many in the fray right now - Express probably is the most widely used. I haven't tried it yet but from what I see, security in node is a work in progress.

Being a Yahoo, how can I end without not mentioning Yahoo Cocktails. Haven't played around with it yet, but this is something I have super high hopes with. The engineers I met there are fabulous. Come Q1 2012 it would be there for all of us to play around. Yahoo is a great company, the best  I have worked for - no doubt I would love to see it scoring high.

Learning more and more of Node, I keep reminding myself "Node is powerful, and with power comes responsibility".

Tuesday, September 13, 2011

Exploiting iGoogle Gadgets

Exploitation of iGoogle gadgets which uses iframes under the hood is well known. Here is an excellent paper on Frame Navigation that explores this attack vector on iGoogle gadgets.

Below is a quick demo on redirection attack on iGoogle gadgets. All the attacks that I mentioned on FB iframe tabs also apply here. It is just that iGoogle is less viral making FB a better ROI target.

Exploiting FB Iframe tabs


FBML was deprecated and Facebook iframe tabs were introduced in Feb'11. As expected it caught significant traction from the developer and security researchers alike. While developers applauded introduction of existing mechanisms like iframes that enable writing 3rd party apps without any learning curve that traditionally existed with Facebook, the security community alarmed concerns over the viral nature of Facebook that combined with iframes further exacerbated their evil nature. Below is a screenshot of Levi's iframe tab on FB.



I love iframes. Haven't they existed there would have been shouts of killing HTTP and inventing a new protocol to support client side mashups. So in a sense, iframe is a blessing that enabled an unexpected requirement by chance although with some security implications. Another assurance on my belief that these great technologies - HTTP, iframe and JS are there to stay for a very very long time, if someone still doubted. I also believe the new specifications HTML5 Sandbox and ES5 are moving in the right direction to enable secure mashups - 1 day when those (IE6) are buried!

Back to the topic. Nothing new but worth visiting what all an attacker could technically exploit on FB iframe tabs. 

1. Malicious Redirection via top.location = http://s0m3phishing.com, as seen in the video below. For demo I perform a redirect to http:///yahoo.com


2. Fake Login / Malicious UI via  and window.open()






3. Drive-by Downloads/ Install Malware via Content-Disposition: attachment




4. Denial of Service (DoS) and Noise by creating infinite alert()and while loops. This particularly is an issue not concerning many, including the security community, but for business it is, as an attacker can impact user engagement and experience which are of prime importance in this business.


5. Browser History Sniffing/Mining via getComputedStyle()as highlighted in the screenshot below




6. Referrer Leak like Referrer: http:///r.html?a=secret&b=private



7. LAN Scanning via JavaScript. A good write up on this is available here




Wednesday, September 2, 2009

Another SQL Injection Variant

Here is another variation of conducting successful SQL Injection attack, Truncation-Based SQL Injection, by Varun Sharma of Microsoft ACE team.

http://msdn.microsoft.com/hi-in/security/ee216344%28en-us%29.aspx

It is not a new vulnerability or something that defies existing security best practices against SQL Injection - use SQL Parameters, input validation, least privilege principle, but just highlights another way to break weak code.

Thursday, August 20, 2009

Linux NULL Pointer Dereference CVE-2009-2692

Refer here for a quick read on what a NULL Pointer Dereference vulnerability is.

Over the past week, the latest Linux NULL Pointer Dereference exploit has rendered millions of servers world-wide vulnerable to root compromise. Here's the CVE reference CVE-2009-2692.

Several local exploits have been released so far, the ones I tried and worked like magic are at:
- The shorter one http://www.securityfocus.com/data/vulnerabilities/exploits/36038-4.tgz
- The longer one http://www.securityfocus.com/data/vulnerabilities/exploits/wunderbar_emporium.tgz

Here's how simply I get root on my box using the former exploit

To understand the exploit in detail a good explanation can be found here.

In summary - the exploit does a NULL pointer dereference that lands on page zero that is filled with bytes in your control. The exploit leverages pulseaudio, a setuid binary, to load your code.

Thursday, August 13, 2009

Statefull/Authenticated/Deep Protocol Fuzzing with Sulley

Okay so Sulley works, but creating a basic HTTP fuzzer was nothing so cool. It just scratched the protocol surface. How about statefull or in-state protocol with authentication? How but fuzzing the methods/functions and it's arguments deep within?

Here is a proof-of-concept dig at leveraging Sulley to do just that for FTP. Same would be possible to achieve for various other protocols like SMTP, POP3.

from sulley import *

import socket
import ftplib


s_initialize("ftp-cmds")

if s_block_start("site"):
s_string("status")
s_static("\r\n")
s_block_end()


def ftpcon(target):

ftp = ftplib.FTP('localhost','cloner','cloner')

def do_fuzz():
sess = sessions.session(session_filename="ftptest.log")
target = sessions.target('localhost', 21)
sess.add_target(target)
sess.pre_send=ftpcon
sess.connect(s_get("ftp-cmds"))
sess.fuzz()

if 1:
do_fuzz()

Firing this generates 1076 test cases for fuzzing (ofcourse you could add to the existing Sulley attack library to generate more test cases) one ftp command post authentication.


This code can be extended to fuzz all the ftp commands/methods and its arguments that are available post authentication in a statefull manner.

Let's see what it really took to get this done. It was FTPLIB that made it possible for us to take establish an authenticated session with the target Pure-FTPd server. The default python installation comes with libraries for several other protocols like SMTP, HTTP and POP3 as well.

For encrypted protocols SSL python library is available in case you do not wish to use proto=ssl option from Sulley.

How difficult is it to write something like FTPLIB or the authentication/statefull piece for your target protocol? The short answer is - it depends - on protocol specifications (if at all you have) and your mileage. Good skill set at Python socket programming can boost your mileage considerably!

Let's look at a snippet of FTPLIB and see what does it take.

def connect(self, host='', port=0, timeout=-999):
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
return self.welcome

No wonder why hackers love Python!

Monday, August 10, 2009

Network Protocol Fuzzing

Arguably fuzzing is one leading technique hackers have leveraged over a decade to discover scores of software security issues.

For a detailed look into techniques, tools, pros & cons a look at Charlie Miller paper is worth a read.

There are two well-known fuzzing frameworks Sulley & Peach - that could be leveraged to create your own fuzzers. I haven't had had a dig at Peach as I haven't yet exhausted Sulley yet or run into major road blocks. The author of Sulley - Pedram has been quite considerate to answer my queries and the tool looks promising so far.

It is fairly straight forward to crank up your first fuzzer if your protocol is as simple as HTTP.

Following code is what I needed to write to get a basic fuzzer ready to torture an HTTP server. The intention was just to have a feel of Sulley. The real goal otherwise is to do some really complex things. But yeah - the things below had to respond to get my confidence & investment.

from sulley import *

s_initialize("HTTP VERBS BASIC")
s_group("verbs", values=["GET", "HEAD"])
if s_block_start("body", group="verbs"):
s_delim(" ")
s_delim("/")
s_string("index.html")
s_delim(" ")
s_string("HTTP")
s_delim("/")
s_string("1")
s_delim(".")
s_string("1")
s_static("\r\n\r\n")
s_block_end()

def do_http_fuzz() :
sess = sessions.session(session_filename="audits/http_session_test.txt")
target = sessions.target("127.0.0.1", 80)
sess.add_target(target)
sess.connect(s_get("HTTP VERBS BASIC"))

sess.fuzz()

print "test completed"

do_http_fuzz()

Firing this script on a latest Apache web server results in 9062 test cases and the wireshark screenshot shows some of the attack patterns that are sent to Apache.



This was simple. But then this is HTTP. How about session oriented or stateful protocols like FTP or even better with encryption SSH? And how about fuzzing deep within a protocol? Fuzzing FTP methods or the protocol methods that are reachable only after a valid secure authenticated session is created? The answer is yes, a framework that can facilitate all this would be a great asset for many security testers.

In my next post we will look at fuzzing a stateful protocol. Precisely we will look at fuzzing deep within a stateful protocol post authentication.