As we resolved the attack on our network (read about my investigation into malware posing as a Chrome Extension), I thought about how sloppy the attack was and how easily we'd discovered the intrusion. The attack was initiated from a direct IP connection over a nonstandard port with no TLS encryption. In particular, TLS encryption would have slowed our investigation by obscuring the connection between the traffic and the Chrome extension.
While the attacker hid their malicious code, it was a half-hearted effort. Their control server was unable to handle the influx of traffic from 25K users, which resulted in frequent retransmission timeouts and widely varying response times. And why go to this effort at all to only steal URLs?
How much damage could a sophisticated attacker with cybersecurity knowledge do? Well, I set off to write my own Chrome malware.
I designed my malware with the following components:
- An always-running background page that handles the following tasks:
- Batching and exfiltrating data through a TLS websocket
- Injecting a malicious script into every tab
- Event handlers for web requests and responses (such as headers, bodies)
- Event handlers for IPC messages sent by injected scripts
- A script injected into each tab that performs the following tasks:
- Capture all submitted forms
- Capture all keystrokes
- Batch captured data and transmit it to the background page through IPC
- A control server which receives collected data
In roughly 200 lines of code, and with fewer permissions than the malicious Postman extension, I created an extension that was capable of exfiltrating all of the following data to an external websocket endpoint in real time:
- All keystrokes
- All form data (including passwords, emails, etc.)
- All request headers (including cookies, API keys, session IDs, etc.)
- All request bodies (including API keys, passwords, etc.)
- All response headers
I also coded a quick web interface for my control server that could display the data in real-time as it was captured by my extension.
First, I tried logging into Reddit.
Then I tried logging into Facebook:
All my credentials were captured by the keystroke logger and the form grabber. Even Google services (such as Gmail) were vulnerable:
Based on these findings, it's clear that Chrome extensions pose a genuinely high security risk. Part of my job requires that I spend time learning about these risks to continue to strengthen our detection service as new threats emerge. Our detections are able to catch a large number of these types of attacks.
Exfiltration attacks through extensions are particularly compelling for attackers because they create the following risks:
- Extensions are capable of targeting and exfiltrating highly-sensitive information (such as credit card numbers, SSNs, session cookies, API keys, usernames, passwords, emails, etc.) through a variety of APIs:
- DOM Capture - capturing the HTML content of any tab through DOM APIs.
- Input Capture - capturing keystrokes on any tab through Event APIs.
- Form Capture - capturing the final contents of any form before it is submitted to the server through Event and DOM APIs.
- HTTP Capture - capturing all requests and responses made by any tab or extension, including headers and bodies, regardless of whether or not the request is TLS encrypted through Chrome APIs.
- Backdoors can be embedded within an extension that solves a legitimate problem for a targeted high-value audience, such as corporate developers. In fact, the container extension might even have a legitimate need for the permissions that enable malicious behavior.
- Popular extensions such as uBlock request at least all of the permissions that enabled the malicious behavior in my research extension.
- In some cases, a permission might seem benign, but allows an attacker to open a gaping security hole. A surprising amount of damage can be done with just a few common permissions such as 'tabs'.
- My research extension demonstrated what was possible with the permissions accessed by the malicious Postman extension, and over 27,000 users willingly granted the extension these same permissions.
- Smart extensions can actively evade detection by taking the following steps:
- Avoiding malicious activity when extensions are enabled or disabled
- Avoiding malicious activity when developer tools are open
- Hiding the origin header in exfiltration requests
- Timing data transmission with user interactions
- Exfiltrating only small amounts of targeted high-value data
- By default, extensions update automatically (without user approval) and are synchronized across devices.
- A container extension can be uploaded without the malicious code for the initial approval process. Backdoors can be silently added later through updates, provided they do not require additional permissions.
- Google is taking steps to solve the problem, but the Postman attack demonstrates the need for additional investment in this area.
- Writing and publishing extensions have very low barriers to entry; they cost only a few dollars and require only basic JS/HTML/CSS knowledge.
For obvious legal reasons, I didn't upload my extension to the Chrome store for testing.