Fileless adware via web push notifications

One push too far / part 1

Push notifications are by no means anything new, and we know them well from our mobiles. However, in recent years the ability to send notifications was introduced into the web environment. After getting annoyed with yet another website asking to send me ‘notifications’, I’ve decided to explore this relatively new feature to better understand what risks (if any) are involved.  And indeed, relatively quick research led me to interesting results which I’ll cover in this 3-part article series:

  1. I’ll start by presenting a zero day I found in Firefox that allows exploiting notifications to create a cool adware.
  2. In part 2 I’ll present a new XSS attack vector I call ‘notification hijack’, that allows persistent control over users’ browsers.
  3. In Part 3 I’ll discuss a cool way for you to use Google as a CNC for your notification-based botnet.
Quick vulnerability: 90’s-style adware

Let’s start at the end: I found that if you use Firefox and give permissions for a site to send you push notifications, the site can launch infinite numbers of arbitrary tabs in your browser whenever it chooses.

Let’s see in action:

So,  what actually happened here?

Bit of technical background

I will not go into too much details about the mechanism’s technical components (many articles out there do a great job at that – I like this one), but as it’s a pretty new technology and not everyone is familiar with it, let’s cover the basics. Web notifications comprise three parts –client, website, and a service provider:

1. Client’s browser:

Only in supported browsers (I’ve tested Chrome and Firefox), when users access a website that uses push notifications they will be presented with a request to authorize the specific site to send them notifications. If you use the internet, you’ve probably seen this before:

If the user approves, a “subscription” object will be created based on the website’s public key. The subscription object contains a unique URL created for the specific endpoint and public key. In chrome an example subscription looks like this:

Something else that happens when the user accesses the website is the registration of a service worker (if you’re unfamiliar with service workers, these are locally stored JavaScript files that are responsible for handling client-side events). The registered service worker is responsible for handling incoming notifications. The service worker operates in a separate sandbox (it cannot change the DOM, for example) and must originate from the app’s domain.

2. Website server:

This is pretty straight forward, the website sending push notification has to maintain a list of endpoint URLs. The site can send notifications to these endpoints by accessing the service provider’s API, using its private key. This tutorial site can be used for sending notifications (once you have a valid endpoint)

3. Service provider:

The service provider is the ‘authority’ responsible for distributing the notifications to users (Google for Chrome, Mozilla for Firefox). When the website server sends a notification to an endpoint, it is the service provider that validates the used keys.

Firefox’s Vulnerability

So how exactly did I manage to launch arbitrary tabs? Let’s look at the JavaScript code of the service worker that was used for this vulnerability:

self.addEventListener(‘notificationclick’, function(event) {

  event.waitUntil(

    clients.openWindow(‘https://www.komodosec.com’)

  );});

 

self.addEventListener(‘notificationclose’, function(event) {

  event.waitUntil(

    clients.openWindow(‘https://www.komodosec.com’)

  );});

Our code consumes both the ‘notificationClick’ and the ‘notificationClose’ events, which are launched, respectively, when a user clicks or closes a notification. For both events, the code launches a new tab.

The service worker sandbox allows a new tab to be launched when the user actively chooses to do so (by clicking the notification), However, it should forbid launching a new tab upon ‘notificationClose’. I found that Firefox allows the launch of tabs due to ‘notificationClose’ events, an so we can force the users to open tabs no matter how they handle the notification.

But wait, it gets better – in Firefox, when you send subsequent notifications the browser will automatically close ‘old’ notifications – thus triggering the ‘notificationClose’ events without any user interaction. Put this together and the website can now launch arbitrary tabs without the user’s interaction: simply send two notifications (the purpose of the second is merely to close the first), consume the ‘notificationClose’ event and open a tab. Or, send 3 notifications and open 2 tabs (you get the picture).

Mozilla’s response

I’ve reported the issue to Mozilla in January as part of their bug-bounty program. In a true Komodo research tradition, Mozilla decided to acknowledge and remedy the issue, but not to pay a bounty.

A fix is deployed as part of Firefox 59, and a CVE was allocated to the issue (CVE-2018-5141).

Further read

Check out part 2 and part 3 for more Push fun!

Zohar Shachar, tech lead

 

Facebook Comments