Attachment blocking – harder then it sounds

Disclaimer

My intention with this post is not to grade or evaluate the solution described here. My only point is to be sure you are aware of the potential side effects of using this particular configuration. Also, as not being a subject-matter expert, this post only reflects what I learnt and understood after few hours of testing.

Background story

When you have a spam filter/mail gateway (of any kind), you want to use it to block “dangerous” attachments, right? You don’t want your users to receive executables for instance. I know, a simple Word file with a macro is as dangerous as an EXE, but unfortunately you can’t block Word files. So you just try doing your best.

Approach

We set up two types of blocking rules. One was blocking files based on their extension. Simple file name matching rules (e.g. *.jar, *.exe, *.bin). Yes, it can be bypassed by a 7-year old, I know that. However, a) it doesn’t hurt to turn this on (oh yeah.. it can hurt as we learnt) and b) if the bad guys need to rename their hack.exe to hack.ex_, we already gained some advantage. Nothing happens if the user double-click on the “hack.ex_” file, so it’s something 🙂

The other thing we did was MIME-Type blocking. We were blocking MIME-Types that may indicate dangerous files – among others we had “application/octet-stream” in the list.

Lessons learnt

We learnt three important lessons within 2 hours :). Needless to say we blocked hundreds of e-mails in the first hour which was more than suspicious.

You can’t fully trust in mime-types. No, I’m not talking about maliciously changing it, but valid e-mails with valid attachment stating incorrect mime-types.

When we checked the console we saw lots of e-mails being blocked by our mime-type rule: application/octet-stream. Checking the e-mails showed that they contained PDFs, GIF images, that sort of things. As you know a PDF should be application/pdf while GIF is image/gif. Well.. in theory. In reality sometimes they’re sent as application/octet-stream.

As you can see the attachment was a PDF, however it was sent with the mime-type of application/octet-stream. Ergo, it was blocked.

pdf_magic

So you can’t really block application/octet-stream because of the huge number of the false positive hits. Sad… really sad.

If you turn on the inspection of the archive containers, it’ll extract EVERYTHING it can. As it’s well known, the new Office file formats (xslx, docx, pptx etc.) are archives. So the mail gateway can and will extract those files. It’s a good question whether it’s the expected behavior or not, but it’s a fact. The only problem you may face (if you want to filter the *.bin extension) is that these Office files may contain *.bin files. For instance, most of them has a “printerSettings1.bin”.

pptx_magic

This means, you can’t really block the *.bin files without blocking most of the MS Office files as well.

Of course you could set up exceptions. Yes, you could, if you’re lucky enough to have a mail gateway supporting such nice features 🙂

The last lesson – never trust the “Delivery status” column of your mail log. So here is the thing, let’s say you blocked couple of  hundreds of e-mails by accident, so you have to release them manually. This is not a problem, every mail filter has this functionality.

The following two pictures show the status of a blocked e-mail before and after it was delivered.

delivery

delivery

If you can’t find the difference, you’re right… there is no difference!! So you can’t be sure whether the e-mail was really delivered to the recipient or not after you clicked on the “Deliver” button. And believe me, when you’re in the middle of fixing the mess you’ve created, you really want to know the delivery status. Actually, this is the only thing you care about!

I think the take away here is what we already know. It’s easy to write security recommendations and guidelines, but the road of implementation is full of bumps and roadblocks. And sometimes even the simplest things are impossible to do.

Advertisements

Custom Web SSO

Suppose you have two web applications (AppA and AppB) and you want to have an SSO solution between these two. Namely, the user logs in to AppA and when he clicks on a link, he can start using AppB without providing any credentials. SSO as I said. Suppose AppA and AppB are deployed to different servers and are available on different domains.
I guess all of you know or at least heard about different authentication protocols or SSO implementations offering such a functionality. Easy as a pie.

I’ve seen a different implementation though. There were mulitple steps (request/response messages) in the background, so let me highlight only the interesting one:

GET /AppB/init.do?userid=[userid]&authToken=[token]&authServer=[host:port]

In the response (if the “authentication” was successful), there was a login form pre-filled with a username and a password. Then this form was instantly submitted by a tiny Javascript code. So basically there was a hidden login. Let’s see what was the magic here.

The first thing you may spot here is that sending back a form pre-filled with credentials puts some questions on the table. For one, it’s definitely not the best practice. For second, how do they know the password?? The passwords – I mean ALL of them – are stored as hash values, right? Not in this case. They stored the password in clear-text (or used a reversible encryption) – not good. Also, if you saw the passwords of 2 users, you could easily figure out the passwords of the others. But let’s put this whole “form sending thing” aside.

Take another look at the GET query instead. There are three parameters:

  • userid – OK, this is a userID
  • authToken – This is like a One Time Password. It is random, generated by AppA and you can use it only once
  • authServer – This is the interesting part. The value is a hostname and a port. Guess what happens if you change that hostname to your IP… from that point, you are the authentication server \o/
    Hey, don’t forget… great power comes with great responsibility… 😉

As you set up yourself as the authentication server, you receive a HTTP GET request from AppB – most probably from its application server. The request includes the userid and the token. That’s cool. The question is – how shall I reply to the request? What’s the correct response according to the “authentication protocol”? The problem is that you don’t know the protocol, you are a fake authentication server. Let me guide you through the protocol reverse exercise I’ve done here. Brace yourself, hardcore stuff is coming… Ready?

So you receive a GET request with the userid and the token, right? It’s like a question:
“Hey, dude here is a token and a userid. Could you please check if I can let him in? Appreciate that.”

What could be the answer? Most probably “Yes” or “No”. Considering that these are machines, I would go with “Y” or “N”.

So here is my advanced 1337 authentication server:

echo -n "Y" | nc -v -l 80

Guess what.. I could log in to AppB with any user without providing a valid token.

So the takeaways:

  • @Developers – Please never invent a new SSO architecture, use something from the shelf. But if you invent a new one, never ever let the users the replace one component of your SSO architecture.
  • @Pentesters – Always try the most simple option first (“Y”), if it doesn’t work, you can start doing complicated stuff, but always KISS first!

Happy Hacking!

Crazy sniffing

The story is simple – you fire up your Wireshark and start sniffing (you may have your IP set or not – doesn’t matter). What happens? Usually you see a bunch of broadcast or mulitcast messages etc. You may see unicast packets as well. However in case of unicast, your IP must be the source or destination IP, right? Let’s assume you haven’t been a bad boy yet (no MitM tricks here).

Here comes the interesting part. In the past couple weeks, we had the same issue at two different places. We connected our laptops and started sniffing. We saw all the usual stuff, but we also captured unicast packets coming from and going to DIFFERENT hosts. I know what you’re thinking – we got a span port or we were connected to a hub – easy. Well, there are two problems with this theory:
1) It wasn’t the case – we checked it together with the network guys 😉
2) If that would have been the case, we could saw ALL traffic. But we saw only fragments.

Sometimes we got just FIN, RST or SYN packets. In other cases we could capture partial SMB file transfers from which we could (partially) recover the file. Also, we captured complete PCL streams – from a print server to a network printer.

It was 100% unpredictable.

We did some research together with the local network guys.

The good news is it’s a well known issue called “unicast flooding” – credit goes to Rolando 🙂
Under certain circumstances (e.g. asymmetric routing), such things may happen.

Here is a good illustrated write-up: http://www.ciscozine.com/unicast-flooding-due-to-asymmetric-routing/

Of course, Cisco has its own note on the topic: http://www.cisco.com/c/en/us/support/docs/switches/catalyst-6000-series-switches/23563-143.html

Happy Hacking!