Offensive Thinking
Internet Thoughtcrime
2010-02-28 xsrfify: XSRF Helper Script
Cross Site Request Forgery ([X|C]SRF) is one of those vulnerabilities many web applications suffer from. If you already know how XSRF works, I suggest you skip the next part and directly go to the explanation of xsrfify.rb, a script to automatically convert a POST request to an HTML page ready for XSRF.
XSRF explained
The idea of XSRF is as simple as it is ingenious. Let me explain by example: Let’s say you have a web application which requires a login. A logged on user can also change his or her password, which is done by sending a simple POST (or even a GET) request to the application. The password change request could e.g. be done with this simple form:
Please enter your new password:<br />
<form method="POST" action="changepw.php">
<input id="pass" type="password" />
<input type="submit" value="Submit" />
</form>
Now, here’s the deal: as an attacker, you don’t have the login credentials, so you can’t just go and change the password. Instead, you do the following: You create an HTML page like the above, but instead of showing the form you hide the input fields. And instead of adding a submit button, you add a little bit of JavaScript to automatically submit the form whenever someone visits your HTML page. This may look like the next snippet:
<html>
<head>
<script type="text/javascript">
function send() {
if (document.forms[0]) {
var el = document.getElementById("submitform");
el.submit();
}
else {
setTimeout("send()", 1000);
}
}
</script>
</head>
<body onload="send()">
<form method="POST" id="submitform" action="http://www.example.com/changepw.php">
<input id="pass" type="hidden" value="desired_password" />
</form>
</body>
</html>
Notice how the action parameter of the form now contains the full path to the PHP page, because we are hosting this web page on our own server and the victim’s server is on http://www.example.com (that’s where the cross site in XSRF comes from). Notice also how the little JavaScript snippet gets called immediately by the onload() handler in the body tag and submits the form (or waits a second if the element is not yet loaded).
The result is, whenever an unsuspecting user opens your website, a POST request to the password-changing PHP page is sent. But that’s not the important part. The important part is that your browser, whenever it sends a request to the site while you are still logged in to the application (e.g. in another tab in your browser), the login credentials will automatically be sent with the request. Because, hey, it’s just another POST request to the website we’re logged into, right?
This means that if you are logged into the application and I can convince you to open my (malicious) website, I can make you send a request to change your password. Without knowing any login details. Because it’s your browser sending the request, and you are already authenticated. The password example above is only one possible attack vector, of course. Just look for anything in the web application which changes something using only one request. There’s plenty of XSRF opportunities for doing something malicious.
xsrfify.rb
Ok, so I got a bit carried away explaining XSRF, because my original intent was to announce a little tool I made for facilitating the exploitation of XSRF. You see, writing HTML pages like the above, to automatically send a POST request, is kinda boring. It’s always the same. A little bit of JavaScript code, a form with all the parameters, the full path to the web site. This can easily be done with a script. So I wrote xsrfify.rb. It’s little Ruby script which you can throw a raw POST request at on STDIN, and it will turn it into an HTML site with a form automatically submitted via JavaScript, ready for XSRF. Simple as that. The options are:
./xsrfify -h
Usage: ./xsrfify [options]
-n, --newlines Use \n as line delimiter when parsing the POST request instead of \r\n
-f, --full-page Print a full HTML page ready for XSRF instead of just the form
-d, --delete-submit Automatically delete parameters with the name "submit"
-h, --help Show this help
Beats writing the same old boring stuff over and over again. By the way: it works great for Cross Site Scripting only exploitable via POST, too. Just make sure that you encode your payload properly, as the script will not care about it. Just change stuff in the resulting HTML page accordingly, otherwise things may break (e.g., if you have double quotes in your payload).
It is available on github as of now:
http://www.github.com/courts/snippets/tree/master/xsrfify/
2010-01-04 Fuzzing and Enumerating with Wfuzz
Wfuzz. What a neat tool. It’s an HTTP fuzzer designed for fuzzing web applications. Although the term “fuzzing” implies too narrow a scope for this tool in my opinion. I always think of finding application bugs when I hear the term “fuzzing”, but wfuzz is also a great program to enumerate files or the like. I guess the line between “fuzzing” and “enumerating” can be kind of blurry at times.
One usage possibility besides the obvious enumeration of e.g. often found applications is to quickly build your own wordlist for the web application you’re currently (pen)testing and using wfuzz to check for these files. Most of the times you do not have a file listing of the remote installation directory. But people tend to forget to remove many of the standard files of today’s web applications which may give you useful hints, for example a Changelog file with the exact version of the application. There’s also the chance of example scripts or extensions (think frameworks like Joomla!) still available, which are surprisingly often vulnerable. Search OSVDB for “example” and you’ll see what I mean.
So what you can do is the following: First, download and unpack (and possibly even install) the webapp locally. Change into the resulting (installation) directory and get a list of all files and directories, e.g. by running:
ruby -e 'puts Dir["**/**"]' > dict.txt
Now, run wfuzz with the newly created wordlist against the remote website. The following command line is a basic wfuzz invocation with coloured output, the wordlist dict.txt, 5 threads, the suppression of HTTP 404 return values and printing HTML output to stderr, which is redirected to a file to be viewed later:
./wfuzz.py -c
-z file
-f dict.txt
-t 5
--hc 404
--html
http://www.example.com/FUZZ
2> `date '+%Y-%m-%d_%H%I'`-example.html
It’ll replace FUZZ with the words from your wordlist and give you a nice and clean output to stdout showing its findings. The saved HTML file even gives you clickable links to all the generated URLs. I tend to view it in elinks because it’s not very pretty, but it gets the job done.
Have also a look at the wordlists already included, I find many of them very useful. Wfuzz has many other options like fuzzing POST data, setting a cookie, doing authentication etc. Just have a look at “wfuzz.py -h”, it’s easy to understand.
2009-12-21 Remoting with PyAMF - the easy way
Aahh, Remote Procedure Calls. Gotta love ‘em. They make programmers forget all we have taught them about being careful with user input, sanitising everything and double checking that there’s nothing malicious in it, treating all user input as a potential threat against their system. Ok, frankly, most of the times developers tend to forget about this in all other scenarios too, or we wouldn’t still be plagued with XSS and the like.
But RPC, in whatever shape it comes, makes it a lot easier to forget about user input because it is more or less transparent to the developer. I mean, that’s the whole point of RPC, isn’t it? Letting you work with remote functions/methods/objects like they’re local. No worries about network protocols etc. And this is exactly what makes it so dangerous, because developers forget that all the pretty function calls and objects they send over the wire are not necessarily what they receive on the other end. Attackers can, if the data is not encrypted and signed, read and manipulate the data. Or send their own. The receiving end has to make sure that whatever it gets is checked first.
Where was I going with this again? Ah, yes, AMF. Adobe’s Action Message Format. It’s a binary format primarily used to serialise ActionScript objects (think RPC for Flash). I had to test a remote installation of an AMF gateway and searched for a decent way of pentesting that stuff. First thing I found was Jon Rose’s Deblaze, a command line tool to interact with Flash remoting end points. It’s a nice tool, but it only allows you to send Ints, Floats or Strings as method parameters. That wasn’t enough for me, as I needed to send more complicated objects to the remote server.
I continued searching and found a blog post about pentesting Adobe Flex Applications with a custom AMF client. They use pyAMF, a Python implementation of AMF. Perfect. The only thing that bothered me was that the way they build their client in the blog post seemed overly complicated. Do I really need to build my AMF object by hand and use an HTTP library to send the POST request to the server? That’s inconvenient for just a little testing.
I looked at the pyAMF homepage myself and found that you don’t have to do all this stuff manually. pyAMF provides a perfectly capable client library, with HTTPS support and authentication. It’s really easy to use. First, import the RemotingService:
from pyamf.remoting.client import RemotingService
Then, all you have to do is create a new RemotingService with the AMF gateway’s URL, get the service you want to use and invoke the method with whatever parameters it takes. Taken straight from pyAMF’s website for a service called “service” with the method “getLanguages()”:
client = RemotingService('http://demo.pyamf.org/gateway/recordset')
service = client.getService('service')
print service.getLanguages()
And that’s it. Much easier, isn’t it? You can also set custom headers etc. Of course, the approach taken in the abovementioned blog post might be better if you really want to dig more into the AMF internals when testing. But if you primarily want to check if you can invoke methods you shouldn’t be able to access, or call the methods with parameters they might choke on, then the pyAMF client is the way to go.
2009-12-17 Organizing your papers with Mendeley
Some days ago, someone (I can’t remember who, sorry) tweeted about Mendeley. It is a software to “Organize, share and discover research papers”. Okay, the next sentence on the website is “Like iTunes for research papers”, which almost made me stop looking at it…
It’s a GUI application and you can download it for free from their site. It is, however, closed source. But hey, can’t have everything. So don’t come complaining to me if it sends your private pictures to Flickr or whatever, I never said I’ve reviewed the code ;). Please be also aware of their EULA and their privacy policy, they’re well worth reading carefully and thinking about the implications before you start using this software. Consider yourself warned. I’ll give some final thoughts on this at the end of this post.
Mendeley works surprisingly well. There’s this huge directory on my laptop with all the security whitepapers I downloaded over time and never come around reading (sounds familiar? Yeah, I bet). BlackHat, Defcon, papers announced on Bugtraq, Full Disclosure or recently more and more over Twitter, you name it. And lets be honest: Either you read them immediately or you forget about them.
One problem is that after dumping them in my “Security Papers” directory, when I have a second look at it later, I already forgot what the papers in there are about. And if they do not have at least a filename telling me what the paper might be about, I don’t bother to open them all in my PDF reader again.
Mendeley did a very good job on organizing this directory and extracting meaningful meta information from that pile of whitepapers and slides. It wasn’t perfect and I had to correct a lot of stuff, but the initial guessing it did was better than I hoped for. Now I have all my papers neatly organized in the Mendeley database, with full text search, the ability to find papers by author or subject, information about papers referenced, BibTeX export, the possibility to annotate the PDFs and much more. It’s a really nice way to organize your stuff. Ok, I still have to read the papers myself. But at least now I can just mark them as read or unread and find them again in the pile of papers I hoard on my disk. Mendeley even allows you to conveniently rename the papers.
Their ultimate goal seems to be to start a kind of social network for researchers, you can synchronize all your stuff with their website and you are of course encouraged to do this. But it’s also possible to just use their client offline. Be always aware that they will collect data about the papers you organize with their software. I don’t think they send any stuff to their website if you don’t have an account and without you explicitly agreeing to it, but you never know. All the papers I have collected are freely available on the Internet and I have no problem with people knowing about me reading these papers, so I consider the potential public knowledge about what security papers I read not an issue. YMMV. Also, I’d be careful with my own papers that aren’t published yet, for example. I wouldn’t add these to Mendeley simply because I don’t know where that data might end. Their privacy policy openly addresses these issues and sounds reasonable, but: it’s the Internet, and what is uploaded to the Internet stays on the Internet. Always have that in mind.
Ok, I finally gave in. After resisting the hype for quite a long time, I created microblogging accounts in the end. You can follow me on
My Identi.ca account automatically pushes everything to Twitter.
Why I gave in to the “giant public asynchronous chat system”, as Lutz put it so nicely? Well, besides the things I already wrote in this blog post, microblogging can be quite fun, I have to admit. There are many things not worth a whole blog post I still would like to share sometimes.
I’m using Twidge on the command line for posting notes, which is a decent program written in Haskell for using Identi.ca and Twitter.
That said, feel free to follow me if you think my ramblings may be interesting to you ;).
« previous