![Elastic_Banner_11_(2).jpg](https://i0.wp.com/static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6df834d6b3085b00/67a438914bee0bea57186ac9/Elastic_Banner_11_%282%29.jpg?ssl=1)
When your CISO asks if a specific browser extension has ever been installed on any of your workstations, how quickly can you get the correct answer? Malicious browser extensions are a significant threat that many organizations have no way of managing or detecting. This blog post explores how the Elastic Infosec team uses osquery and the Elastic Stack to create a real-time inventory of all browser extensions and detection rules as well as how to notify the team if a workstation has a known compromised browser extension. This solution is built entirely using osquery, the Elastic Defend integration, and SIEM capabilities within the Elastic Stack.
Table of Contents
Threat actors targeting browser extensions
There has been an increased focus from threat actors in targeting browser extensions as a way to steal information or compromise users — and even some threat actors directly target the developers of legitimate extensions with the goal of adding malicious code.
With enough permissions, a browser extension has the ability to view or change any information on any website you visit with your browser and collect sensitive information passed to the websites, such as the usernames, passwords, or bank account information. Extensions could access and steal any website’s stored authentication tokens. They can even change the content of a website to socially engineer a user into downloading malware onto their workstation like changing the destination of a link, for example.
Enterprise challenges
Managing browser extensions in an enterprise poses some complex challenges.
-
Extensions are installed per profile within the browser.
-
Each user account on a workstation can have multiple different profiles within each of their browsers, such as a personal profile and a work profile.
-
It is common to see workstations with five or more different user profiles — each with their own set of installed extensions.
There are some options, such as managed browsers that can control the installed extensions for the corporate profiles by creating allow or block lists for extensions, but these solutions don’t manage noncorporate profiles on those workstations. The personal browser extensions on corporate workstations still represent a risk to your company if the user logs into work systems from their personal profile. Another risk scenario is that the personal extension could dynamically change the destination of a clicked link, causing a user to download a malicious file to their work system.
Deploy and manage osquery within Kibana
osquery is an open source agent that works on almost all modern operating systems (OS). It treats each OS like a relational database with tables that you can query to gather information about the current state of the system. You can query the 200+ tables in the schema for information, such as running processes; installed browser extensions; Python libraries; loaded docker containers; loaded kernel modules; open network connections; connected USB devices; and many more.
At Elastic, we protect all of our workstations with our own XDR capabilities, which includes deploying Elastic Agent to all of our workstations for distributed protection and response. One of the great features of Elastic Security is the ability to easily deploy and manage osquery to your endpoints using the Osquery Manager integration within Kibana. The osquery integration is included in the Basic license — there are no additional licensing costs to deploy it within your fleet of agents.
Advantages of using osquery with Elastic
Elastic Defend and other endpoint detection and response (EDR) agents can stream real-time process, network, and file logs from a workstation. But these audit logs can’t tell you all of the information about the state of the OS,such as installed browser extensions. This is where osquery comes in. It lets us capture a snapshot of the current state of a workstation so that we know which Chrome extensions users have.
With a few clicks in Kibana, you can deploy osquery to all of your workstations and manage and view your queries directly within the Elastic Stack — no extra infrastructure is required when you manage osquery with Kibana. Another advantage of using osquery with Elastic is that the results of all queries are immediately ingested into an Elasticsearch index and available for all of the various use cases. Ingesting the results into your Elastic Stack also provides you with a historic timeline of your queries, which you can use to see when hardware and software changes were made to a system over time.
For more information about using osquery in Elastic, check out the osquery documentation guide.
Using osquery in Elastic
Within osquery, there are two ways to run a query — immediately as a live query or as part of a regularly scheduled group of queries that osquery refers to as a query pack.
Live query
A live query will run a single query against one or more hosts. Live queries are a good way to build and refine your queries during testing or to hunt for specific indicators during an investigation. When selecting the hosts to run a live query in Elastic, you can select hosts individually, all hosts in a fleet policy, or by operating system. If an agent is offline when you run the live query, it will stay queued if the agent comes online within the next 60 minutes; otherwise, it will be cleared. A feature in the Elastic version of osquery are saved queries. This feature makes it easy to preconfigure commonly used complex queries that can then be used by other team members.
Query pack
A query pack is a collection of preconfigured queries that are scheduled to run at different intervals. Each query in the pack can specify which OS platform it will run on, so a single pack can be used safely on a policy with multiple OS. A query pack can be exported and imported as a .json file to allow you to quickly add a pack in Kibana. osqery provides some sample packs to get started, or you can try out the browser_monitoring pack we use to inventory our browser extensions.
Creating an inventory of all extensions with osquery
The Elastic Infosec team has configured the browser_monitoring pack to run every six hours on all of our workstations to create an inventory of all browser extensions. We run the queries every six hours because Elastic is a globally distributed company, and we can’t predict the working hours of our users.
![browser_monitoring query pack](https://i0.wp.com/static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt246e4e2e025155b6/67a4353b4405de67c64b213b/image1.png?ssl=1)
Because of the complexity that comes with multiple user profiles, the queries to collect browser extension information require a JOIN operator to join the users table to the extension table. The JOIN operator will combine two tables together using a common field that exists in both tables. In this case, it is the user ID uid field.
SELECT * FROM users JOIN chrome_extensions USING (uid)
The results from the pack queries can also be seen directly in the osquery UI with links to open the results of each query in Kibana Discover or Lens.
![browser_monitoring results view](https://i0.wp.com/static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc86339f0b6ec6495/67a435498de79c12eab8f8d9/image4.png?ssl=1)
The results from all queries are stored directly into the logs-osquery_manager.result* index pattern. The results from a scheduled pack query can be found using the action.id field. For pack results, this field follows the naming convention of pack_{pack_name}_{query_name}. We are using a pack named browser-monitoring with a query named chrome_extensions. To view the results of this query, you can query for action_id: “pack_browser-monitoring_chrome_extensions”.
When viewing the results of the osquery in Discover you will see that each of the fields from the osquery schema table are indexed with the osquery.* field name. When viewing information about Chrome extensions, the fields we use most often are the osquery.identifier, osquery.name, osquery.permissions, osquery.profile, and osquery.version.
![Example query results](https://i0.wp.com/static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted71ebe6a4477742/67a435548de79c69c2b8f8dd/image2.png?ssl=1)
Here is a full list of the fields available in the chrome_extension query response:
-
osquery.identifier is the unique identifier of each extension. With this identifier, you can find the extension on the Google Chrome Web Store, or look up the reputation score of the extension using a service, such as Secure Annex or crxaminer.tech.
-
osquery.name is the name of the extension as displayed in the Chrome Web Store and in your browser.
-
osquery.profile is the Google Chrome profile that the extension is installed in. It is very common for a user to have multiple different Chrome profiles in a single-user account.
-
osquery.permissions are the permissions granted to the extension. This field can be used to filter for extensions that are granted dangerous permissions, such as permissions to view or modify requests to every website. Pay close attention to any extensions that have permissions, such as https://*/* , which grants the extension access to every https website that you access.
-
osquery.version is the installed version of the extension. In some cases, an extension could have one compromised version, which you want to remove.
- osquery.update_url is the url that the extension uses to check for any updates. If this value is anything other than the standard update path of https://clients2.google.com/service/update2/crx, then the extension has been ‘sideloaded’ or installed in some way other than the standard web store and should be investigated.
Another very important osquery table is the chrome_extension_content_scripts. This table contains information about each of the javascript files being used by the extensions. If you find that there is a compromised extension on a host, you can use the osquery.path, osquery.match, and osquery.script fields from this table to find the full path of each script run by the extension. With this information you can use Elastic Defend’s response action capabilities to download those files for offline analysis.
Creating detection rules for bad extensions
Now that you have a live inventory of all browser extensions you can build detections. The most straightforward detection to build is one for known bad extensions. The known bad extension list will likely come from a threat intelligence report containing known identifiers and versions. For this example, we are going to use the threat intel from the recently reported Cyberhaven extension compromise campaign. At the bottom of the report is a link to a collection of IOCs that contain the name, ID, and version of known malicious extensions.
Name | ID | Version |
VPNCity | nnpnnpemnckcfdebeekibpiijlicmpom | 2.0.1 |
Parrot Talks | kkodiihpgodmdankclfibbiphjkfdenh | 1.16.2 |
Uvoice | oaikpkmjciadfpddlpjjdapglcihgdle | 1.0.12 |
Internxt VPN | dpggmcodlahmljkhlmpgpdcffdaoccni | 1.1.1 |
Bookmark Favicon Changer | acmfnomgphggonodopogfbmkneepfgnh | 4.00 |
Castorus | mnhffkhmpnefgklngfmlndmkimimbphc | 4.40 |
Wayin AI | cedgndijpacnfbdggppddacngjfdkaca | 0.0.11 |
Search Copilot AI Assistant for Chrome | bbdnohkpnbkdkmnkddobeafboooinpla | 1.0.1 |
VidHelper – Video Downloader | egmennebgadmncfjafcemlecimkepcle | 2.2.7 |
AI Assistant – ChatGPT and Gemini for Chrome | bibjgkidgpfbblifamdlkdlhgihmfohh | 0.1.3 |
TinaMind – The GPT-4o-powered AI Assistant! | befflofjcniongenjmbkgkoljhgliihe | 2.13.0 |
Bard AI chat | pkgciiiancapdlpcbppfkmeaieppikkk | 1.3.7 |
Reader Mode | llimhhconnjiflfimocjggfjdlmlhblm | 1.5.7 |
Primus (prev. PADO) | oeiomhmbaapihbilkfkhmlajkeegnjhe | 3.18.0 |
Tackker – online keylogger tool | ekpkdmohpdnebfedjjfklhpefgpgaaji | 1.3 |
AI Shop Buddy | epikoohpebngmakjinphfiagogjcnddm | 2.7.3 |
Sort by Oldest | miglaibdlgminlepgeifekifakochlka | 1.4.5 |
Rewards Search Automator | eanofdhdfbcalhflpbdipkjjkoimeeod | 1.4.9 |
Earny – Up to 20% Cash Back | ogbhbgkiojdollpjbhbamafmedkeockb | 1.8.1 |
ChatGPT Assistant – Smart Search | bgejafhieobnfpjlpcjjggoboebonfcg | 1.1.1 |
Keyboard History Recorder | igbodamhgjohafcenbcljfegbipdfjpk | 2.3 |
Email Hunter | mbindhfolmpijhodmgkloeeppmkhpmhc | 1.44 |
Visual Effects for Google Meet | hodiladlefdpcbemnbbcpclbmknkiaem | 3.1.3 |
Cyberhaven security extension V3 | pajkjnmeojmbapicmbpliphjmcekeaac | 24.10.4 |
GraphQL Network Inspector | ndlbedplllcgconngcnfmkadhokfaaln | 2.22.6 |
GPT 4 Summary with OpenAI | epdjhgbipjpbbhoccdeipghoihibnfja | 1.4 |
Vidnoz Flex – Video recorder & Video share | cplhlgabfijoiabgkigdafklbhhdkahj | 1.0.161 |
YesCaptcha assistant | jiofmdifioeejeilfkpegipdjiopiekl | 1.1.61 |
Proxy SwitchyOmega (V3) | hihblcmlaaademjlakdpicchbjnnnkbo | 3.0.2 |
ChatGPT App | lbneaaedflankmgmfbmaplggbmjjmbae | 1.3.8 |
Web Mirror | eaijffijbobmnonfhilihbejadplhddo | 2.4 |
Hi AI | hmiaoahjllhfgebflooeeefeiafpkfde | 1.0.0 |
Using this list of IOCs, there are two different ways to build a detection. The simplest way is to use these ID and version values to build a single, large Elasticsearch query looking at osquery data for any of these extension identifiers and versions chained together with an OR operator. For example:
action_id: pack_browser-monitoring_chrome_extensions AND (
(osquery.identifier: "nnpnnpemnckcfdebeekibpiijlicmpom" AND osquery.version: "2.0.1")
OR
(osquery.identifier: "kkodiihpgodmdankclfibbiphjkfdenh" AND osquery.version: "1.16.2")
OR
(osquery.identifier: "oaikpkmjciadfpddlpjjdapglcihgdle" AND osquery.version: "1.0.12")
)
If you are ingesting threat intel feeds to your Elastic Stack using one of our threat intelligence integrations, you can create a more dynamic version of this rule using an indicator match rule type. An indicator match rule compares fields in two different index patterns and will trigger an alert when those fields match. If your threat feed supports Google Chrome extension IDs and versions, you can create an indicator match rule that will alert you when an installed chrome extension ID and version matches a known bad extension.
Here is an example configuration of an indicator match rule. The indicator index field names will change depending on the threat intel platform being used.
![Example indicator match rule configuration](https://i0.wp.com/static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltce37b5fcc1e0fbae/67a43563ecc9d749ce415095/image3.png?ssl=1)
The advantage with this method is that there is no need to manually update the detection rule each time a new list of known bad extensions is released or updated. You will immediately be alerted as soon as a new indicator is added to your threat intel index.
Try it out
Threat actors are going to continue to use Chrome extensions as a way to steal valuable information and target systems. If you don’t have visibility of the extensions installed on your workstations, you won’t be able to protect your users from this attack vector. With osquery and Elastic, you can manage and reduce the overall risk to your enterprise with visibility and alerting of browser extensions at no additional licensing costs.
Try it out for yourself with a 14 day free trial of Elastic Cloud.
The release and timing of any features or functionality described in this post remain at Elastic’s sole discretion. Any features or functionality not currently available may not be delivered on time or at all.
Leave a Reply