Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Thursday, September 2, 2010

When bugs are forgotten

Last year, at HAR2009, there was a presentation about reverse engineering switch firmware. The researchers had found there is a backdoor password in some Accton-based switches (which are sold by several manufacturers, such as 3Com). It was a very nice piece of reverse engineering.

After the presentation I occasionally checked the manufacturer website to see when a patch would show up, but it never did. In fact the vulnerability was never picked up by the security community. I have a vulnerable device (a 3com 3812 gigabit switch) and started to complain. So here it is, more than a year later, a >365-day exploit.


It's hard to say which switches are vulnerable and which are not. It certainly doesn't mean that if you have a 3Com device it is vulnerable, but you can check yourself using the exploit code. Vulnerability scanners will start detecting it soon and time will tell I guess. In the meantime, you could disable all management interfaces and manage your switches using a console cable.

Monday, August 2, 2010

Why MS10-046 mentions my name

Some people have asked me why Microsoft credits me in MS10-046 (a.k.a. the patch for the lnk bug). In version 1.0 of the original advisory they only mentioned .LNK files as an attack vector. When playing around with the bug and the published exploit code, I discovered the vulnerability could also be exploited with .PIF files (MS-DOS shortcuts). This was the case even after applying the workaround (disabling the display of icons on lnk files). So I contacted the MSRC, they updated the workaround and were kind enough to credit me for the additional attack vector.

Thursday, May 13, 2010

Presenting at Hack in the Box 2010 - Amsterdam

The first part of the conference program for HITBSecConf 2010 - Amsterdam has been announced. I will be giving a presentation on the security of 2.4GHz wireless presenters. I will be talking about hardware reverse engineering and building an Arduino-based device to attack these devices. With such a device you can send random keystrokes to someone using such a presenter during a presentation.

You can read the full abstract here.

Friday, April 9, 2010

Unwrapping Oracle PL/SQL with unwrap.py

The Oracle wrap utility can be used to obfuscate PL/SQL code, to ensure it can't be easily read. Pete Finnigan described (pdf) the wrapping process for Oracle 9g, but for 10g and 11g it still remains a bit of a mystery. I decided to release my Python unwrapping utility (supports 10g and 11g).

The unwrapping steps for 10g are nicely described in the Oracle Hacker's Handbook, but the actual substitution table needed to decode the package is omitted. Nobody (as far as I know) has published it. A lot of people seem to know how to do it though, there is even an online unwrapper available (and I'm sure everyone seriously involved in Oracle security knows how to do it). A Russian-made closed source tool is also available, but tends to upset virus scanners.

So to save everyone a couple of hours of figuring it out, here it is: unwrap.py

It's easy to use (I've used the wrapped procedure from this article as an example):

$ ./unwrap.py wrapped.txt

=== Oracle 10g/11g PL/SQL unwrapper - by Niels Teusink - blog.teusink.net ===

PROCEDURE WRAP_IT (SEED_IN NUMBER)
IS
  V_RAND INTEGER;
BEGIN
  DBMS_RANDOM.INITIALIZE (SEED_IN);
  FOR I IN 1..5 LOOP
   V_RAND := MOD(ABS(DBMS_RANDOM.RANDOM),45);
   DBMS_OUTPUT.PUT_LINE(I||': '||V_RAND);
  END LOOP;
END;
$


Update: one excellent resource I forgot to mention is this blog post by Anton Scheffer from Amis. I did not use his code to create my script but he describes how to get the substitution table as well. I also noticed Oracle security expert Pete Finnigan has mentioned my script on his blog (his older blogpost Unwrapping PL/SQL is also a good source of information).

Thursday, August 27, 2009

Windows password filters

During my HAR talk, I briefly described the password filter mechanism. A password filter is a DLL that is listed in the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages.

Whenever a user changes his password, Windows passes the plaintext password to all the DLL’s listed there. The password filter can then determine whether the password meets its requirements (complexity, length etc.) and approve or disapprove the password. You can use this feature to implement your own password filter DLL and enforce your custom company password policy.

Of course, a password filter could also choose to do something else with the plaintext password. As I described in my previous blog post, Microsoft does this with RASSFM.DLL. An attacker could also create his own backdoor password filter that, for example, sends the password to a remote server.

The procedures you need to implement are quite well documented on MSDN. There is even a universal password filter available on Sourceforge. This allows you to pass the password to a custom script.

Wednesday, August 26, 2009

Passwords stored using reversible encryption: how it works (part 2)

In part one of this article, I described how the reversible encryption of Windows domain passwords works. In this part, we will look at the security of this mechanism.

To decrypt the password you need the following components:
- The encrypted password (G$RADIUSCHAP)
- The 16 byte random (G$RADIUSCHAPKEY)
- The global LSA secret (G$MSRADIUSCHAPKEY)
- A static key hardcoded in RASSFM.DLL

The hardest thing to get is that global LSA secret. This is stored in active directory and synchronized between domain controllers. To access this key, you need domain administrator privileges. An obvious risk here is that once someone gains domain administrator privileges, he won’t need to crack any passwords, but can simply decrypt them. Of course, if an attacker gains domain administrator privileges on your domain, you are already in big trouble anyway.
However, the other components are all semi-public information. The static key is hardcoded in RASSFM.DLL which comes with every Windows server, so is easy to get. The G$RADIUSCHAP and G$RADIUSCHAPKEY are stored in active directory in the userParameters structure. If you have a user account on a domain you can use AD Explorer to access the Active Directory database and read this information. Of course, to decrypt the password you will still need that LSA secret.

The encrypted version of the password can be interesting though; by looking at the encrypted password you can derive the length of the plaintext password. Two examples I used in my presentation:

Pwd1 encrypted: 0f53 8420 9418 05ce 01ad

Pwd12 encrypted: 5d69 9375 6f92 1b63 7728 439f

So, by looking at the encrypted passwords you should notice that the encrypted version of Pwd12 is two bytes longer than the encrypted version of Pwd1. So, although we cannot determine from just looking at the encrypted password that they are very similar, we can determine their length. What this means is, that as a domain user, you can determine the length of other people’s passwords, which could be quite interesting.

If you obtain the LSA secret somehow (maybe because you temporarily gain domain administrator privileges), from that point on you can decrypt passwords stored using reversible encryption. This could be used as a nice backdoor, just steal the LSA secret, enable reversible encryption (if it hasn’t been enabled yet) and you can grab the domain administrator password with just a normal user account.

Someone in the HAR 2009 audience had a very nice question: Is it possible to recreate the LSA secret if you’re afraid it has been stolen. Of course the better option is to recreate the entire domain, but this is not always an option. To recreate the LSA secret you need to write a program that sets the LSA secret to NULL. According to the documentation, Windows will delete the LSA secret. It will generate a new LSA secret when it needs to encrypt another password. Of course, Windows won’t be able to decrypt the passwords stored before that point anymore. However, it will still try to decrypt them using the new LSA secret, which will result in gibberish most of the time. If you’re really unlucky it could decrypt the first two bytes to NULL, which basically means the password is suddenly empty. So if you ever have to do this, resetting all passwords immediately is probably a good idea.

Tuesday, August 25, 2009

HAR 2009 talk references

I promised to put up some nice ‘further reading’ material for those who have seen my HAR talk. So here it is:

LM/NTLM
Disabling the LM hash
Free Rainbow Tables and download site

Passing the hash
The original post from 1997 by Paul Ashton
Core Pass-The-Hash toolkit
Tenable SMBshell

Token stealing
Luke Jennings research page
A tutorial on the tool by CG

You can see the video of my talk here or download it here or here.

Passwords stored using reversible encryption: how it works (part 1)

In case you missed my HAR2009 talk: in the second part I talked about a Windows feature called ‘Store passwords using reversible encryption’. When this is enabled (per user or for the entire domain), Windows stores the password encrypted, but in such a way that it can reverse the encryption and recover the plaintext password. This feature exists because some authentication protocols require the plaintext password to function correctly, the two most common examples are HTTP Digest Authentication and CHAP.

This feature is not enabled by default but I’ve seen it a couple of times in customer networks. As I couldn’t find any description of how this mechanism works or any tool to recover these passwords, I decided to investigate.

When you change your password on a domain that has reversible encryption enabled, a password filter called RASSFM.DLL is used to store the password using reversible encryption. The key that is used to do this is G$MSRADIUSCHAPKEY, which is stored as a global LSA secret. This key is decrypted using a static key (hardcoded in the DLL). The result of this operation is combined with a 16-byte random value (generated every time someone changes their password) and that key is used to encrypt a Unicode version of the password using the RC4 algorithm.

I found out these passwords are stored in Active Directory in a per-user structure called userParameters. If you use a tool such as AD Explorer you can look at this structure in an AD that has enabled this feature. When you look at this structure, it looks like a binary blob, with some human-readable parts in there. When you enable reversible encryption you will notice two readable strings: G$RADIUSCHAP and G$RADIUSCHAPKEY. The userParameters can also be used to store settings unrelated to reversible encryption, such as per-user Terminal Server settings.

Following the G$RADIUSCHAP part is the ascii-hex encoded encrypted password. The part following the G$RADIUSCHAPKEY name is the 16-byte random value.

So to decrypt this password we use the following steps:
- Take the G$MSRADIUSCHAPKEY Global LSA secret
- Decrypt it using the static key
- Parse the userParameters structure and extract the G$RADIUSCHAP and G$RADIUSCHAPKEY values
- Combine the value of G$RADIUSCHAPKEY (the 16-byte random) with the decrypted LSA secret to create an RC4 key
- Decrypt the value of G$RADIUSCHAP using that RC4 key

The result is a plaintext Unicode password. My tool 'Revdump' automates this procedure.

In part two of this article, I will look at the security of this mechanism.

Monday, July 6, 2009

Speaking at HAR 2009

The program for HAR 2009 was publicly announced a couple of days ago and I’m on the speakers list. My talk is called 'How we break into domains' and I will go over the steps I usually take when breaking into Windows domains. I have an hour for my talk, so I should be able to cover the technical details as well. Of course, I will also be presenting some new stuff I’ve been working on.

I had a lot of fun at the two previous events (HAL 2001 and WTH 2005) and am glad I can contribute a talk this year. See you all at HAR!

Thursday, June 25, 2009

Zen Cart authentication bypass

Zen Cart is a popular open source e-commerce application, written in PHP. Yesterday, two exploits for Zen Cart showed up on milw0rm. The first one is a remote code execution, the second one an SQL injection exploit. The root cause of the two bugs however, is the same: an authentication bypass on the administrative interface of Zen Cart discoverd by Ghyslain/BlackH. Zen Cart has released a patch for this issue here.

Zen Cart does a pretty decent job verifying administrators are actually authenticated, however it has some exceptions to the rule:

This code is present in /admin/includes/init_includes/init_admin_auth.php (slightly simplified code):

if (if (!isset($_SESSION['admin_id']) &&
!(basename($SERVER['PHP_SELF']) == 'password_forgotten.php')) {
zen_redirect('login.php');
}

So basically, if you are not logged in, Zen Cart will redirect you to the login page, unless you are accessing the password_forgotten.php page.

The problem here is trusting the PHP_SELF variable to determine which script is being accessed. Here a bit of strange PHP behaviour comes in. If I request http://server.com/index.php, the PHP_SELF variable will be /index.php. However if I request http://server.com/index.php/foobar , the PHP_SELF variable will be /index.php/foobar, but the script being executed will still be index.php!

So in this case we can trick Zen Cart into thinking we are accessing password_forgotten.php, while we are actually accessing a different file by requesting:

http://target/admin/customers.php/password_forgotten.php

The file we are executing is customers.php, but basename(PHP_SELF) will return password_forgotten.php! Zen Cart thinks we are accessing the ‘I forgot my password’ page, which does not require authentication and allows us to continue without logging in. We can now view a list of customers on our target site, without logging in!

The code execution exploit uses this to access an admin script that allows an administrator to create new files. The exploit uses this functionality to create a new php file on the server, this php file contains a simple backdoor and voila: remote code execution.

Luckily Zen Cart has released a fix for this (although I expect most installations are still vulnerable). I took a look at the patch and noticed it attempts to fix the bug by checking if the string '.php' appears more than once in PHP_SELF. At first this seems to be an (ugly but) effective fix and I think it is in most cases. However, Zen Cart supports multiple platforms, including Windows. As you may know, filenames on Windows are not case sensitive (foo.txt is the same as foo.TXT). The new check however only checks for lowercase instances of '.php'… So if our target is a Windows system, we can circumvent the patch by requesting:

http://target/admin/customers.PHP/password_forgotten.php

So by changing the extension of customers.php to .PHP, we modify the PHP_SELF variable so '.php' is only present once and bypass the new check! I modified the code execution exploit on milw0rm to reflect this and was able to succesfully exploit my installation of Zen Cart on a Windows platform.

Of course I notified the Zen Cart developers of the shortcoming in their patch and they have released an updated version which does a case insensitive check.

Tuesday, May 12, 2009

Time to update SquirrelMail

Today Squirrelmail released version 1.4.18. This version fixes a couple of vulnerabilities, some of which I spotted while browsing through SquirrelMail source code while installing it:
  1. A reflected XSS caused by unsafe handling of the $PHP_SELF variable
  2. A reflected XSS caused by unsafe handling of user supplied encrypted data
  3. A remote command execution vulnerability (only in very specific configurations)
The first XSS is caused by the fact that SquirrelMail only used the strip_tags function to filter this variable. As the variable is often used within tags, you can still inject additional HTML attributes (think onmouseover). This was exploitable in multiple scripts. SquirrelMail now uses htmlspecialchars instead.

The second XSS is rather interresting. SquirrelMail comes with a test script which (given ciphertext and a key) decrypts user supplied data. The decrypted data was then displayed unfiltered (resulting in an obvious XSS). Pretty stealthy and should circumvent any IDS or WAF. Having this kind of script in your webroot is obviously a bad idea anyway.

The last bug occurs only in very specific configurations. If you have more than one imap server, there is a way to configure that in SquirrelMail. If you configure this and use the example map_yp_alias function for this, unauthenticated attackers could execute shell commands on your server. If you built your own function for this, you should probably check if it handles input correctly. It is unlikely that you're running this kind of configuration, but there are probably a couple of installations out there using this.

Thursday, May 7, 2009

Grabit exploits are available (but not working)

I have seen two exploits so far for the NZB overflow, both on milw0rm (here and here). I took a look at the code and they do not look very reliable, in fact both of them suffer from the same problem I initially had when exploiting the bug.

The exploits on milw0rm are tuned for very specific environments, this is caused by the fact that Grabit prepends the current directory to the string copied in the buffer. The authors created the NZB exploits in a specific directory and the exploits will not work if they place it in another one with a different path length (this is why the second exploit has two 'targets').

When I was creating an exploit, this seemed like a serious problem for exploit reliability to me. But when tracing through the code, you will notice that the directory is not always prepended. If the DTD reference is to an absolute path (instead of a relative one), it will not prepend the directory and exploitation is a lot more reliable. After I fixed this in the two exploits, they work just fine on my system.

Wednesday, April 8, 2009

Tonight on Dutch television, NOVA: Het afluisteren van DECT-telefoons

In other words, some Dutch media attention on DECT eavesdropping. There has been very little coverage of DECT security issues in the Dutch media, so I’m hoping this broadcast will change that.

DECT sniffing has become easier since my last post. COM-ON-AIR prices seem to be going down again on eBay and people are selling pre-made boot CD’s for DECT sniffing. So no Linux installation necessary anymore, someone can simply buy a COM-ON-AIR card and a CD, pop both of them in a laptop and start sniffing. Needless to say, eavesdropping on your neighbours conversations is illegal, so only use this if you have permission.

I purchased a couple of cards for Fox-IT shortly after the issue became public. As a part of penetration tests, I have already tested DECT security at some of our customers. The results are pretty much as you would expect.

Update: Some shocking details from the broadcast: phone conversations of the Dutch IRS (Belastingdienst), the police, a hospital and a Dutch government minister all can be easily intercepted. First viewer reactions on the NOVA site are of course 'Where can I get one of those eavesdropping things, it sounds like fun'.

Update2: It looks like the media coverage has arrived!

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!

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).