Sidestepping inline URL content filters
Picture the scene – you have a small office network with a single gateway device hooking you up to the Internet. The gateway device performs your basic firewall and NAT tasks, and also hooks into some kind of URL filter server like Websense or McAfee SmartFilter. The URL filter will categorise all websites that people ask for, and will permit or deny access to them according to some defined policy. The trigger for this categorisation is the border device – it must look out for HTTP requests passing through it and act on them like this:
- The border device sees an HTTP request passing through it, heading outbound from the office network.
- The border device allows the request to carry on to its destination.
- When the response arrives, the border device will hold onto it and not release it back to the requester.
- Whilst the request is heading off to its destination, the border device parses out the URL and passes it off to the URL filter server (Websense/McAfee/whatever).
- The URL filter server will categorise the requested URL, apply a policy to it, and send a yes-or-no response back to the border device.
- If the response is a ‘yes’, the border device releases the response held in step 3 and the user will see their webpage.
- If the response is a ‘no’, the border device throws away the held response and instead returns an HTTP redirect to the user which will take them to some kind of blockpage telling them why their request was denied.
Organisations usually use this technology for applying some kind of HR-sanctioned policy (no porn, no warez, etc.), but there’s a strong security angle to its use, too.
McAfee SmartFilter has the option to ‘block’ certain categories you choose. It can also ‘warn’ instead of block – the difference is that the user can bypass a warn page, whereas a blockpage is a total dead end. Consider a security-only policy that looks like this and is designed to defend against common web threats like injected hidden iframes etc:
- The policy will ‘block’ on anything that is categorised as being in any way malicious. Hopefully, if the URL filter vendor is doing their job properly, commonly injected URLs will fall into this category pretty quickly.
- The policy will ‘warn’ on anything that is uncategorised. New websites turn up every nanosecond, so clearly the URL filter vendors are always playing catchup. In the case of something like conficker, frequent new URLs are part of its C&C strategy, so we have to exercise caution when allowing users to see uncategorised websites.
Why is this an effective strategy? Well, if an injected hidden iframe is categorised as Malicious, the hidden iframe will contain our URL filter’s blockpage instead of the malicious content and the user is saved. Likewise, if the iframe’s content is uncategorised, it will contain the warn page instead of the mischief – again, the user is saved.
Warning on uncategorised as opposed to outright blocking has the happy side effect that the user can proceed to view uncategorised sites that they have explicitly asked for. There’s no way a user can bypass a warn page that’s in a hidden iframe!
Clearly, this strategy isn’t 100% effective – it’s a preventative measure, after all, and prevention eventually fails. You’re primarily at the mercy of the URL filter vendor’s accuracy and timeliness of their categorisations, which can of course let you down. Having said that, from personal experience this is an extremely effective technique of keeping out the majority of today’s web-based attacks on desktop machines.
At this point, let’s think back to step four above:
“Whilst the request is heading off to its destination, the border device parses out the URL and passes it off to the URL filter server”
The key phrase here is “parses out the URL” – the border device actually needs to inspect the traffic passing through it and decide that something is or is not an HTTP request. Clearly, each vendor will have their own ways of doing this, and I can only really speak for Cisco kit here because that’s where my experience lies.
I’ve been finding that certain classes of web-based attacks seem to take measures that sidestep URL content filtering that may otherwise prevent delivery of the attack code to the browser. Whether they do this sidestepping deliberately isn’t something that I can tell you, but it does happen even if it’s just by accident.
The first sidestepping technique is to use a nonstandard port. There have been lots of .cn-targetted iframes injected recently, and their latest trick is to use port 8080 instead of 80. Why is this effective? It’s effective because (for Cisco at least) in order to parse out a URL the border device must recognise the traffic as HTTP, a step typically taken by looking at destination port numbers. A Cisco will, by default, only inspect traffic on port 80, so our iframes targetted at 8080 will not be vetted by the URL filter at all and will get delivered to the user’s browser:
router#show ip port-map http Default mapping: http tcp port 80 system defined
Ooops. To fix this, you can either:
- Apply some kind of egress filtering so that users can only see a subset of destination ports, or
- Explicitly tell your Cisco to inspect more ports for HTTP:
router#show ip port-map http Default mapping: http tcp port 80 system defined Default mapping: http tcp port 8080 user defined Default mapping: http tcp port 8000 user defined Default mapping: http tcp port 8001 user defined Default mapping: http tcp port 8801 user defined
Clearly the problem here is that there are over 65000 ports for the baddies to choose from…
I have no idea if other inline URL filter devices are susceptible to the same sidesteps, but Cisco ones definitely are. Whether they intended to or not, the bad guys are bypassing yet another layer of preventative defensive measures – it’s yet another thing for us all to look out for!
There is an update to this post here.
Alec Waters is responsible for all things security at Dataline Software, and can be emailed at alec.waters(at)dataline.co.uk