Tuesday, January 27, 2009

Why you should not use ‘OR 1=1’ when testing for SQL injection (part 2)

In my previous post, I explained why testing for SQL injection using ‘OR 1=1’ can lead to data loss. In this article, I will describe an alternative and safer approach.

I like to use ‘AND 1=0’ instead of ‘OR 1=1’. This does not increase the number of items affected by a query, but (in most cases) results in the query returning 0 rows (as 1=0 is never true ?). In our previous example of a site displaying articles, no article would have been displayed. The resulting query would become:

SELECT title,text,hitcount FROM articles WHERE id=1234 AND 1=0

That query would return 0 rows. So now what? We’re looking at the site we’re testing and no article is displayed, so what? It doesn’t mean there’s SQL injection. Well, now we enter ‘AND 1=1’ after the articleID and the following query is executed:

SELECT title,text,hitcount FROM articles WHERE id=1234 AND 1=1

Now the ‘AND 1=1’ does not affect the original query, and article 1234 is displayed. At this point I am pretty sure I have SQL injection and could try a UNION SELECT to extract more information from the database.

Of course, this is not the only solution to this problem, but it’s one of the safest to use (unless the application displays SQL errors). For bypassing authentication I still sometimes use the OR approach, but in most cases you do not have to take the risk.

Monday, January 26, 2009

Why you should not use ‘OR 1=1’ when testing for SQL injection (part 1)

Everybody who has read a paper on SQL injection has seen the ‘OR 1=1’ example (or the similar ‘ OR ‘’=’). It is the classic method for bypassing authentication when an application does not sanitize user input before using it in SQL queries.

I think it is somewhat overused. Often I see pentesters throwing this kind of string into each input field, hoping to trigger an SQL injection or some kind of error. Some tools which test for SQL injection (for example Nessus) also do it.

So why do I think it’s bad? Well, because it can have a major impact on the query that’s executed and has the potential to break things. Production systems are often the target of pentests and we should try not to break those.

Unless you have the source code to the application, you can’t know exactly what happens with your input string. Most people assume they are injecting into SELECT statements, but of course, applications also use DELETE, UPDATE and INSERT, which modify the database. Let me give you a real life example, we once cam e across an application which did this ($articleID comes from user input):

‘SELECT title,text,hitcount FROM articles WHERE id=’ + $articleID

A prime target for SQL injection! But a little further in the code something else happens:

‘UPDATE articles SET hitcount=’ + $hitcount+1 ‘ WHERE id=’ + $articleID

So the application first retrieves the title,text and hitcount for a certain article from the database, all is well here, the only thing that happens if we enter ‘OR 1=1’ after the articleID is that the application will receive all articles from the database and will most likely pick the first one.

The next statement is a different story, as the application tries to change something. It has retrieved the ‘hitcount’ for the article in the previous query (the hitcount being the number of times the article has been viewed) and uses it in a different query, to update the hit counter with a new view. Our articleID is used again as well, but in this case the resulting query becomes something like:

UPDATE articles SET hitcount=1338 WHERE articleID=1234 OR 1=1

This will set the hitcount to 1338, but instead for just just article 1234, it changes it for all articles in the table, not what we intended to do! Of course this is in most cases a relatively harmless scenario (and an example of lousy software engineering), but had our articleID been used in a DELETE statement, all articles would have been deleted from the table.

In the next part of this article, I will describe an alternative approach.

Sunday, January 25, 2009

My DECT handset actually wants to encrypt!

I had the opportunity to test some more DECT phones and interception worked great on most of them. A friend’s Siemens Gigaset 4010 and a Panasonic 720 both did not encrypt conversations and were easy to eavesdrop on.

When I got to another friend’s house, it was a different story. He had two DECT handsets, a Profoon (similar to the one without encryption I own) and a Siemens C455 IP. The C455 is very similar to the C475 listed on dedected.org which uses encryption, so I expected this one to encrypt as well. It did use encryption, the only audio I got was static. I was surprised to see (or hear) however, that his Profoon used encryption as well. It turned out he did not use the base station which came with the Profoon handset, he had instead paired the handset with the C455 base station.

I had brought my own Profoon handset and base station so we decided to pair it with the C455 base station as well to see if it would encrypt. It turns out it did! So what I bought is a handset which does support encryption, but a base station which refuses to encrypt. To confirm this we paired his C455 handset with my base station and as expected, no encryption. I knew to use encryption, both the handset and base station need to support it, but I did not expect they would be selling ‘incompatible’ combinations. It does make sense though, the manufacturers probably just buy the cheapest chipset for both the handset and base station. As there is a standard, they have no problems communicating, but the manufacturer might not even realize they are unable to encrypt.

This fact could make mitigating the vulnerability a bit easier. A large organisation with a lot of DECT handsets may not need to replace their entire DECT system, but may be able to keep either the base stations or the handsets. So in my opinion, the ListOfPhones on dedected.org could use another column: whether the lack of encryption on certain sold combinations is caused by the phone, the base station or both.

Wednesday, January 14, 2009

More on DECT sniffing and attacks

The dedected blog reports the COM-ON-AIR Type II cards are practically sold out, so they are working on supporting the older (less compatible) Type III cards. I took a look on eBay and only Type III and PCI cards are available right now. Looking at the ended auctions, it seems that (in the last two weeks ) over 700 Type II cards have been sold on eBay!

Patches are now available on the dedected mailing-list which allow capturing directly to audio files. So no more converting captured calls. These should be integrated into the main SVN soon (apparently there are some licensing issues). I did not have a chance to test the patches so far. A draft of the paper detailing the attacks and the DSAA algorithm is also available on the dedected wiki: Attacks on the DECT authentication mechanisms.

Finally, the DECT forum has reacted on the possibility of DECT eavesdropping. They state this:

"It is impossible to accidentally eavesdrop on telephone conversations and therefore the risk for users is very low. Only those with a clear criminal energy and intent and a sophisticated knowledge would be capable of eavesdropping."

I can’t say I agree with them. Yes, of course eavesdropping on other people’s phone calls is illegal and it should be, but with the tools dedected has created it is certainly not hard to do so. I'm not interested in my neighbours phone calls, but a lot of people probably are. Just look at the number of cards sold on eBay, these can’t all be nice pentesters with good intentions :-).

Update: I have tested the patch for capturing directly to audio files. The dect_cli tool does store .wav files as well as .pcap files now. With my handset, the files are sometimes empty (well, their size is 44 bytes) though, while they shouldn't be. When it does work, the .wav files are quite nice, but with my handset, the volume still turns out quite low. A bit of amplification using Audacity works well though.

Tuesday, January 13, 2009

Sniffing DECT

A couple of weeks ago, at the CCC congress in Germany, a couple of guys gave a presentation about attacks on DECT cordless phones. Basically, you can buy a DECT PCMCIA card and create a rogue base station (tunnel the calls through a VOIP gateway while you record them) or intercept unencrypted phone calls.

Indeed, some of the DECT phones use no encryption at all. DECT phones are supposed to use the DECT Standard Cipher (DSC) but some just do not (maybe encryption is optional in the DECT standard?). The presenters have a website at dedected.org which describes some more technical details.

I decided to buy a COM-ON-AIR DECT PCMCIA card on eBay and it arrived today! The people at dedected.org have created Linux drivers for this card and it was pretty easy to get it working on my Ubuntu laptop.

The dedected SVN includes patches for Kismet-newcore (DECT module) and Wireshark, but also include a couple of handy standalone tools. One of these is called dect_cli. With this tool you can scan for DECT base stations, calls and even record calls. I’ve put some sample output of this tool here (the call I am sniffing is my own).

I also went to a hardware store (GAMMA) this evening and bought the cheapest DECT phone (Profoon PDX-500) so I could play around with it. The box says ‘GAP compatible DECT digital’. I do not have a working landline at the moment so I had to try it without one. This phone, as it turns out, does not use encryption. After recording the call, I could hear myself faintly saying ‘hello hello hello’ (not in a very creative mood), albeit with a lot of static. I’ll try to get my hands on some more DECT phones, I’m curious how many of the phones sold in the Netherlands do not use encryption.

I did not get a clear sound with the current tools. According to the dedected wiki this is something they are still working on. You can listen to a bit of music-over-DECT (and a lot of static) I recorded here (raw dump files here). I simply used sox without any options to convert it to .wav, but there is a 'modified decode' on the dedected wiki which should result in somewhat better quality. In my case, using this filter resulted in a lot of silence but the beeps at the end of the file were very clear :-).

Update: I got the opportunity to test this with another DECT phone. Combined with the 'modified decode' I was able to get really good sound quality.
Also, it turns out that encryption is optional in the DECT standard, as this document (pdf) from the DECT Forum describes (on page 11).

Tuesday, December 16, 2008

Classic bug: phpBB 2.0.12 authentication bypass

December is always a very busy month at work, so it has been a while since my last post. Here's another classic bug: the phpBB 2.0.12 authentication bypass. I am not sure who discovered this bug, but the first references to it seem to be from February 2005.

As the title says, this is an authentication bypass bug, which means an attacker can access any account on a vulnerable phpBB version without knowing the password. This is not your typical web application bug though, it has to do with serialization and you could patch it by adding only one byte to the vulnerable code.

So how does it work? A phpBB forum has a ‘remember me’ function, which basically gives you a cookie which automatically logs you in. The cookie looks something like this:

a:2:{s:11:"autologinid";s:32:"96948aad3fcae80c08a35c9b5958cd89";s:6:"userid";s:4:"3207";}

This format is created by the PHP serialize function. Basically, it is a technique to store a complex structure into a string. If we unserialize the above example, we get this (print_r output):

Array
(
[autologinid] => 96948aad3fcae80c08a35c9b5958cd89
[userid] => 3207
)

So our cookie is used to store an array containing two strings: our userid and something called an ‘autologinid’. As it turns out, the autologinid is just an MD5 hash of the phpBB password. Not such a good idea, as this makes phpBB vulnerable to passing-the-hash attacks. phpBB 3 doesn’t use this type of cookie anymore though.

The bug is in this part of the phpBB source code (simplified):

$sessiondata = unserialize(stripslashes($HTTP_COOKIE_VARS[$cookiename]));
if( $sessiondata['autologinid'] == $userdata['user_password'] ){
// autologinid matches password
$login = 1;
}

Doesn’t look that bad does it? After unserializing the data, It simply compared the autologinid in our session with the MD5 of the user’s password. They use the == operator to compare two strings, nothing wrong with that. But what if one of the operands in the comparison is not a string? Take for example the following PHP code:

if(true == ‘96948aad3fcae80c08a35c9b5958cd89’){
echo ‘true!’;
}

You may not expect it, but this piece of code outputs ‘true!’. PHP simply converts the string to a boolean and unless the string is empty or ‘0’ PHP will convert it to ‘true’. So what does this have to do with our vulnerability? Let’s take another look at a part of our serialized cookie:

s:32:"96948aad3fcae80c08a35c9b5958cd89"

Our MD5 hash is prefixed with s:32:, which means this variable is a string with a length of 32. So instead of just specifying the string itself, we also specify its type! The trick is to simply change this part of our cookie to:

b:1

Which makes our cookie:

a:2:{s:11:"autologinid";b:1;s:6:"userid";s:4:"3207";

For the unserialize function, this simply means: the value of autologinid is a boolean with the value ‘true’. The next step is to change our cookie on the forum to this one. The forum will compare the password hash of the user with userid 3207 to ‘true’, tricking phpBB into thinking we have the actual password hash! A logical next step would be to change the userid to '1', which is the userid of the forum administrator user, giving us full control over the forum.

The patch for this vulnerability whas a simple one. The phpBB team simply changed the line:
if( $sessiondata['autologinid'] == $userdata['user_password'] ){
to
if( $sessiondata['autologinid'] === $userdata['user_password'] ){

In other words, they switched from the == to the === operator. The PHP manual has the following description for the === operator: “TRUE if $a is equal to $b, and they are of the same type.”. The fix was this simple, by changing the operator, the two compared types have to be equal, so an attacker can no longer supply a boolean instead of a string and bypass authentication.

The moral of this story? Every piece of input is important, don’t allow users to supply serialized data, unless absolutely necessary!

Tuesday, November 25, 2008

Classic bug: Modem AT command injection

This is the first article in a new series: classic bugs. These are bugs that may not always be recent, but surely are interesting, or just still relevant. I think this first bug is both.

I am talking about a bug which could be read about on the Bugtraq mailing list in 1998. The poster, Max Schau started his e-mail with ‘this is an old exploit’, even then. With this bug, you can tell modems (the old analog 56k kind) to hang up. The problem is that with a modem, the data and the modem commands all go through the same communications channel. Sometimes, modems have hard time distinguishing between the two. So, if you can trick someone into sending a modem command, you can influence their modem.

The classic example is the hang up command (ATH0). If I can trick someone into sending that string (preceded by three plus signs) through their modem, a vulnerable modem will hang up. This is easier than it may sound, many systems respond to ICMP echo (ping) packets, and reply to the packet with the same data. So all I have to do is send a modem user an ICMP echo packet containing an AT command and it will reply to the packet, sending the command through the modem.

This denial of service used to be very popular and the beautiful thing is: it still works! At Fox-IT we still have an analog line we use for war dialing. Today, I hooked up a modem and dialed into one of the free dialup ISPs. Using a simple ping command from the original advisory, I was able trick the modem into hanging up! A couple of sources report some modems will hang up when merely visiting a site with an AT command in it, I was not able to reproduce that behavior with my modem.

I spend about half an hour trying to inject other commands (for example to trick the modem into dialing a given number), but was unsuccessful. With other modems this might work better. In the original advisory, someone mentions it may be possible to get modems to dial 911, which would be a big deal. In today’s world, criminals would most likely use it to get modems to dial their premium-rate telephone numbers.

Fortunately, not all analog modems are vulnerable to this attack. Some modems require a pause before sending commands, which makes this attack impossible (or at least very hard). A way of ‘patching’ your modem is in the original advisory, this involves changing the default escape character (+) in your modem using an ATS2 command. It seems the escape character can only be a single byte, so it would be easy to brute force if you know someone has changed it.

Thursday, November 20, 2008

Something strange is going on at wpad.be

After writing my last WPAD post, I decided to check if any WPAD TLDs are serving malicious wpad.dat files. So, I took a TLD list I found on the MozillaWiki and tried to retrieve wpad.dat on all of the wpad.tld domains, using cURL with a spoofed user-agent.

I was able to connect to 50 of the nearly 700 TLDs and 24 of them are serving a wpad.dat file. Of those, five seem to be non-malicious (at least, for now): they are either serving a legitimate wpad.dat file or are telling clients not to use a proxy.

The remaining 19 however, all contain the same wpad.dat file (at the same IP address). Among these are some serious domains, such as wpad.at, wpad.be, wpad.in and wpad.es. The wpad.dat tries to match the URL against these shell expressions and tells the browser to use a proxy only if the URL matches:

http://*ad*nd*c*m*sh*ds*js
http*//*s*s*mp*tn*s*p*

Clearly, these people are trying to obfuscate the URLs they are proxying. I had some trouble figuring out what the targets are, but a couple of my colleagues at Fox-IT were able to find a match: http://pagead2.googlesyndication.com/pagead/show_ads.js. Looks like they are intercepting requests for Google ads. At the moment, the proxy seems to return an empty .js file for this request.

According to the HTTP headers, the wpad.dat file has been there since 13 October 2008. It does contain the text ‘testin testin’ so perhaps they are just preparing for something.

Sunday, November 16, 2008

Hacking random clients using WPAD

About two weeks ago, I registered the wpad.nu and wpad.fm domains. WPAD stands for Web Proxy Autodiscovery Protocol and is used by browsers to automatically find the correct proxy server for a URL. The protocol is quite simple: basically if your hostname is host-27.us.company.local, the browser will try to download a wpad.dat configuration file from wpad.us.company.local and if that doesn’t exist wpad.company.local and in some cases finally wpad.local. This doesn’t sound too bad, unless your hostname is wpad.us.company.com (notice the .com tld instead of .local). In this case your browser may be trying to download a proxy configuration file from wpad.com, which could be owned by anyone!

Fortunately wpad.com, wpad.net and wpad.org are owned by Duane Wessels, one of the good guys. He provides some statistics on his site, which show his domain serves about 25 404’s each second (he returns a 404 for the wpad.dat configuration file)!

I registered wpad.nu and wpad.fm thinking I would get a couple of requests every day, however in the last two weeks, nearly 600 unique IP addresses have been asking for the wpad.dat file! About 2/3 seem to access the file through wpad.fm, the rest through wpad.nu. The .nu TLD belongs to some small island in the South Pacific Ocean, but is quite popular as ‘nu’ is the word for 'now' in several languages, including Dutch.

As I am one of the good guys as well, I also do not serve a wpad.dat file. If I did, I could tell the victims browsers to use my server as a proxy, which would allow me to eavesdrop on or modify their web traffic (replacing all downloaded .exe files would be an easy attack). Also, as Chris Paget points out, Internet Explorer will happily NTLM authenticate against any proxy, so stealing domain credentials is also a possibility (which then could potentially be abused for VPN or Outlook Web Access).

Finally blogging

Welcome to my shiny new blog! This is just a place for me to put up my ideas and the results of small experiments. I work for an IT security company in The Netherlands as a technical auditor/penetration tester, so I will keep things mostly technical and security related.