Transcript
Page 1: Hotlinking is Too Hot for Comfort

Hotlinking is Too Hot for Comfort

@johnwilander, GeekMeet Stockholm 2013

Page 2: Hotlinking is Too Hot for Comfort

@johnwilander

Hotlinking ==

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>

Page 4: Hotlinking is Too Hot for Comfort

@johnwilander

Crawled

• Alexa Top 10,000

• Up to 500 pages per domain

• 3,000,000+ pages in total

Page 5: Hotlinking is Too Hot for Comfort

@johnwilander

Page 6: Hotlinking is Too Hot for Comfort

@johnwilander

Sites typically hotlink JavaScriptfrom 5-15 remote hosts

Page 7: Hotlinking is Too Hot for Comfort

@johnwilander

If I can run a script on your site or app, what

can I do?

Page 8: Hotlinking is Too Hot for Comfort

@johnwilander

Browser Exploitation Frameworkhttp://beefproject.com/

Page 9: Hotlinking is Too Hot for Comfort

@johnwilander

So, who is able to run scripts on your site?

Page 10: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper Functions www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

Page 11: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

Page 12: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

ga.js and urchin.js are two different versions of Google Analytics => probably not on the same site.

68.37+17.32 ≈ 85% of Alexa Top 10,000

Please don't be evil, Google.

Page 13: Hotlinking is Too Hot for Comfort

@johnwilander

Page 14: Hotlinking is Too Hot for Comfort

@johnwilander

https://github.com/Craga89/qTip2/issues/286

2011-12-08 there was an issue reported

Page 15: Hotlinking is Too Hot for Comfort

@johnwilander

"sends your browser agent and another piece of info"

Page 16: Hotlinking is Too Hot for Comfort

@johnwilander

"old Wordpress install … security vulnerability"

"infected nearly all JS files on my site"

Page 17: Hotlinking is Too Hot for Comfort

@johnwilander

"The offending scripts have been removedas well as the Wordpress blog"

"cronjob setup that checks for changes"

"Closed"

Page 18: Hotlinking is Too Hot for Comfort

@johnwilander

"it downloads some other exploits"

Comment

Page 19: Hotlinking is Too Hot for Comfort

@johnwilander

https://github.com/Craga89/qTip2/issues/286

One month later …

Page 20: Hotlinking is Too Hot for Comfort

@johnwilander

"issue is still present"

Page 21: Hotlinking is Too Hot for Comfort

@johnwilander

"Looks like the security hole wasn't plugged after all"

"Please … do not hotlink"

"Reopened"

Page 22: Hotlinking is Too Hot for Comfort

@johnwilander

"I've disabled the Wordpress blog on my site"

"Closed"

Page 23: Hotlinking is Too Hot for Comfort

@johnwilander

Questions on qtip Hack

• How many end user PCs were trojanized?

• How many passwords stolen?

• How many credit card numbers stolen?

• How many internet bank logins remote controlled?

Page 24: Hotlinking is Too Hot for Comfort

@johnwilander

Stale Hotlink Domains

Page 25: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

…Hotlinks

Page 26: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

Other domains

Hotlinks

Page 27: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

Other domains

Stale domains,open for purchase

Page 28: Hotlinking is Too Hot for Comfort

@johnwilander

The Stale Numbers

• +3,000,000 pages crawled

• 4,225 hotlinked domains outsideAlexa Top 1,000,000

• 50 domains stale, i.e. no longer registered

Page 29: Hotlinking is Too Hot for Comfort

@johnwilander

Nick et al purchased two of those stale

domains

Page 30: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

Page 31: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

23 less popular sites

blogtools.us

Page 32: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

blogtools.us

hbotapadmin.com

80,466 4,615Visits (15 days)

23 less popular sites

Page 33: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

Including domains

Including pages

blogtools.us

hbotapadmin.com

80,466

24

84

4,615

4

41

Visits (15 days)

23 less popular sites

Page 34: Hotlinking is Too Hot for Comfort

@johnwilander

The Case of the Unauthorized Image

Page 35: Hotlinking is Too Hot for Comfort

@johnwilander

”Hotlinked images,can they bite me too?”

Page 36: Hotlinking is Too Hot for Comfort

@johnwilander

<script src="http://3rdparty.net"></script>

<img src="http://3rdparty.net">

OK, this might be bad

But this?

Page 37: Hotlinking is Too Hot for Comfort

@johnwilander

Page 38: Hotlinking is Too Hot for Comfort

@johnwilander

What if Meetup allowedprofile images to be hotlinked?

Page 39: Hotlinking is Too Hot for Comfort

@johnwilander

Meanwhile, at the Attacker’s Server …

Page 40: Hotlinking is Too Hot for Comfort

@johnwilander

src/main/webapp/ css/… img/thumb_john.jpg js/… html/…

Including images typically looks like thisin a web app project:

But an attacker could instead resolve that image URL in code, like this …

Page 41: Hotlinking is Too Hot for Comfort

@johnwilander

private static final String IMG_PATH = "/img/thumb_john.jpg";private boolean returnUnauthorized = false;@GET@Path("/thumb_john.jpg")@Produces("image/jpg")public Response getEvilImage(@Context ServletContext context) { if (returnUnauthorized) { return Response.status(Response.Status.UNAUTHORIZED) .header("WWW-Authenticate", "Basic").build(); } else { try { BufferedImage image = ImageIO.read(context.getResourceAsStream(IMG_PATH)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", outputStream); byte[] imageData = outputStream.toByteArray(); return Response.ok(imageData).build(); } catch (IOException e) { e.printStackTrace(); return Response.serverError().build(); } }}

Page 42: Hotlinking is Too Hot for Comfort

@johnwilander

private static final String IMG_PATH = "/images/thumb_john.jpg";private boolean returnUnauthorized = false;@GET@Path("/thumb_john.jpg")@Produces("image/jpg")public Response getEvilImage(@Context ServletContext context) { if (returnUnauthorized) { return Response.status(Response.Status.UNAUTHORIZED) .header("WWW-Authenticate", "Basic").build(); } else { try { BufferedImage image = ImageIO.read(context.getResourceAsStream(IMG_PATH)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", outputStream); byte[] imageData = outputStream.toByteArray(); return Response.ok(imageData).build(); } catch (IOException e) { e.printStackTrace(); return Response.serverError().build(); } }}

… adding some nasty, alternate behavior.

Page 43: Hotlinking is Too Hot for Comfort

@johnwilander

Page 44: Hotlinking is Too Hot for Comfort

@johnwilander

Now what will John Doe enter?

Page 45: Hotlinking is Too Hot for Comfort

@johnwilander

Some more nails for the coffin …

• CSS files can execute JavaScript (expressions in IE6-7 and XBL in Firefox)

• SVGs can execute JavaScript

• Gif files can be edited to become executable JavaScript and HTML


Recommended