A page to show up #1 on Google when searching for "Jeremiah" (Currently #4). Only the prophet and TV show left! I have the edge, TV show is cancelled and the prophet isn't generating any new content.

The prophet, TV show, and that pesky Owyang guy going down!A page to show up #1 on Google when searching for "Jeremiah Grossman", and it FINALLY has!

Tuesday, November 28, 2006

Browser Port Scanning without JavaScript

Update 2: Ilia Alshanetsky has already found a way to improve upon the technique using the obscure content-type "multipart/x-mixed-replace". There's a great write up and some PHP PoC code to go with it. Good stuff! RSnake has been coveringthe topic as well.Update: A sla.ckers.org project thread has been created to exchange results. Already the first post has some interesting bits.

Since my Intranet Hacking Black Hat (Vegas 2006) presentation, I've spent a lot of time researching HTML-only browser malware since many experts now disable JavaScript. Imagine that! Using some timing tricks, I "think" I've discovered a way to perform Intranet Port Scanning with a web browser using only HTML. Unfortunately time constraints are preventing me from finishing the proof-of-concept code anytime soon. Instead of waiting I decided to describe the idea so maybe others could try it out. Here's how its supposed to work... there are the two important lines of HTML:

HTML is hosted on an "attacker" control website.

The LINK tag has the unique behavior of causing the browser (Firefox) to stop parsing the rest of the web page until its HTTP request (for 192.168.1.100) has finished. The purpose of the IMG tag is as a timer and data transport mechanism back to the attacker. One the web page is loaded, at some point in the future a request is received by check_time.pl. By comparing the current epoch to the initial “epoch_timer” value (when the web page was dynamically generated) its possible to tell if the host is up. If the time difference is less than say 5 seconds then likely the host is up, if more, then the host is probably down (browser waited for timeout). Simple.

Example (attacker web server logs)

/check_time.pl?ip=192.168.1.100&start=1164762276Current epoch: 1164762279 (3 second delay) - Host is up

/check_time.pl?ip=192.168.1.100&start=1164762276Current epoch: 1164762286(10 second delay) - Host is down

A few browser/network nuances have caused stability and accuracy headaches, plus the technique is somewhat slow to scan with. To fork the connections I used multiple IFRAMES HTML connections, which seemed to work.

I'm pretty sure most of the issues can be worked around, but like I said, I lack the time. If anyone out there takes this up as a cause, let me know, I have some Perl scraps if you want them.

> Aside from the time-consuming aspect of it, refused connections fail quickly, so it's difficult to distinguish them from successful connections.

Yes, thats right. Refused connections (host is up) and web servers responding (host is and port is open) has been difficult to distinguish between. But if this only turns into a ping sweep, hey, that might not be such a bad thing either. :)

Great post. I've decided to see if there can be an easy way to implement timeouts in Firefox and it looks like with Content-Type: multipart/x-mixed-replace; it is quite possible. Since the full text is too long for a reply in a blog, I've made a separate blog entry which can be found here that describes the process.

In about 2-3 minutes entire 192.168.1. could be scanned using this process via a single link in my tests.

If you wouldn't mind, drop me an email and I'd be happy to share some source code. jeremiah __at__ whitehatsec.com. However, I think Ilia (below) has just trumped me.

Ilia,

All I gotta say is WOW. I knew people would push the envelope if I only explained the concept, but I never thought this fast and that well. I'm going to have to spend some quality time with your examples. Great stuff.