Permhash — No Curls Necessary

Jared Wilson
May 15, 2023
15 min read
|   Last updated: May 16, 2023

permhash logoAdversaries take numerous directions to gain authorization for actions on targeted endpoints: privilege escalation, DLL side-loading, credential theft, and more. Browser extensions, Android Packages (APKs), and other permission declaring files take a different approachthey declare the permissions they require, sensitive or not. These file types are external code sources that are given authorization to run with varying degrees of permissions. Due to their unique file type, not being a standard executable, there is a lack of automated analysis that is performed on these files. Security researchers, threat hunters, and cyber analysts need a method to cluster, hunt for, and pivot between browser extensions, APKs, and other files that declare a set of permissions in a repeatable and scalable way.

Permhash is an extensible framework to hash the declared permissions applied to Chromium-based browser extensions and APKs allowing for clustering, hunting, and pivoting similar to import hashing and rich header hashing.

This research will include a deep dive into permhash showing its theory and demonstrating real-world successes and shortcomings, all the while showing its potential for wide use across the security industry.

Chromium Extensions, APKs, and Their Permissions

Chromium Extensions

A CRX file is a collection of files archived together into a single package that can be used as an extension in Chromium-based browsers. Extensions enhance the browsing experience by adding features and functionality to the browser.

Extensions use a set of permissions to clarify how they can operate and interact with other data sources. Especially malicious extensions, as their permissions frequently exceed what is required, in order to collect additional user-data. An extension declares its intent in the permissions field of the manifest file. Every extension requires a JSON-formatted file, named manifest.json, that provides important extension-specific information. See the example manifest file contents in Figure 1.

Figure 1: Example Manifest File Contents


  "manifest_version": 3,

  "name": "My Extension",

  "version": "1.0.1",

  "default_locale": "en",

  "description": "A plain text description",

  "permissions": [






This manifest is specifying that the extension associated with it requires the permissions: tabs, bookmarks, and unlimitedStorage. Each permission keyword is associated with a browser API that allows some type of action to be performed or data to be collected.

Figure 2: List of Permission Descriptions




Gives access to privileged fields of the Tab objects.


Gives access to the chrome.bookmarks API.


Provides an unlimited quota for storing client-side data, such as databases and local storage files.

As shown in Figure 2, at its most pure intentions, the permissions themselves aren’t malicious but are the means that malicious extensions abuse to gain levels of access.

Android Packages

APKs include a set of declared permissions. These permissions exist in the AndroidManifest.xml file. Every functioning Android app must have an Android manifest file at the root of the project source. The manifest file describes essential information about the app to the Android build tools, the Android operating system, and Google Play, including the app’s permissions. Unlike extension manifest files, Android manifest files are in AXML format but are still easily identifiable. See Figure 3 for an example of the permissions within an APK.

Figure 3: APK Example Permissions

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>

Similar to all file types with declared permissions, the APKs permissions specify the level of access required to function within the Android environment.

Adversaries Abusing Extensions and APKs

While these file types may not get the dedicated focus that executables do, Mandiant has observed adversaries using malicious extensions and APKs in their cyber operations.

UNC3873 was identified distributing VIPERSOFT via torrents of cracked software. In at least some instances, UNC3873 leveraged VIPERSOFT to subsequently download VENOMSOFT payloads. VENOMSOFT is a cryptocurrency dataminer that disguises itself as a browser extension.

Three malware families, BRAINSTORM, BRAINFOG, and BRAINLINK, were identified installing the malicious extension, RILIDE. RILIDE is a Chromium-based extension that monitors the URLs visited by victims, screenshots their browser tab views, and injects remote Javascript into select websites. RILIDE targets the theft of email and cryptocurrency details.

Even Nation State Actors have been observed using malicious extensions. Google TAG released a report about the threat group ARCHIPELAGO (a subset of APT43) using malicious Chrome extensions in combination with phishing and malware. The earliest versions of these extensions, reported as STOLEN PENCIL in 2018, included functionality to steal usernames, passwords, and browser cookies. They were delivered via phishing emails with a link that directed recipients to a lure document that prompted users to install the malicious Chrome extension.

Nation State Actors use malicious APKs as well.  A subset of APT42’s infrastructure served as command and control (C2) servers for Android mobile malware designed to track locations, monitor communications, and generally surveil the activities of individuals of interest to the Iranian government, including activists and dissidents inside Iran.

These threats exist and will continue to exist to certain degrees, as countermeasures are implemented. Regardless of the state of the threat, the need to hunt for and identify these clusters of malware is paramount for the defender and cyber security community.

Permhash Hypothesis and Execution

The hypothesis behind the research into permhash is the following:

Calculating a hash of a joined string of the permissions from an extension or APK will be a data-point that can be used to hunt, cluster, and pivot between like file types.

The theory of identifying a data set to help cluster files requires a certain set of qualities. The data would need to be extractable, adversary defined, meaningful to functionality, and have ties to code reuse.

  • Extractable – The data needs to be collectable, at scale, from the samples it is related to.
  • Adversary Defined – The data needs to be sourced or created by the adversary and a consequence of the adversary’s actions.
  • Meaningful to Functionality – The data needs to have a relationship to the functionality of the extension. For example: the history permission implies that the extension intends to manipulate or read the browser history.
  • Code Reuse Identifier – It is beneficial if the data is in a format that it can be reused. This encourages actors to reuse their code, further establishing a cluster.

However, why use a hash is an important question. Hashing allows for a user to condense an unwieldy data-point into a concise figure that is easily searchable and pivotable. Some permission sets can be incredibly large, spanning multiple thousands of characters. Condensing this complex string into a single unique 64 character value makes the handling of this data more feasible.

To create a permission string Mandiant performs the following actions:

  1. Identify extension or APK manifest files with a permissions field
  2. Extract the permissions
  3. Join all permissions together into one string (i.e. “tabsbookmarksunlimitedStorage”)
    1. Ensure order of the permissions is maintained in the string
    2. Ensure the casing is maintained
    3. For dictionary values in the list of permissions (observed in extensions), use a key.value format. For example, the usbDevices permission is a dictionary with a list value that is a dictionary, see Figure 4 for an example:
      Figure 4: usbDevices permissions example

      "permissions": [
          "usbDevices": [
              "vendorId": 123,
              "productId": 456

      This permhash string would look like usbDevices.vendorId.123usbDevices.productId.456”.

    4. Compute a sha256 hash of the permission string.

This process is standardized across both extension permissions and APK permissions.

Permhash at Scale

Extension Manifest Files

While performing this research Mandiant was able to collect 11,575 extension manifest samples with permissions. To better understand the data, a frequency scatter plot was created (Figure 5). The frequency scatter plot tells us how many times a certain permhash occurs. For example, in Figure 5, the dot in the top left is showing that in our 11,575 samples there are 1,280 permhashes that are unique and not shared, whereas the dot on the bottom right shows there is a single permhash that is shared 5,166 times across our samples. These extremes tell us two interesting hypotheses about the data:

  1. The 1,280 samples with unshared permhashes are very unique across the dataset.
    • Potentially good samples to hunt for new families.
  2. The 5,166 samples with the shared permhash (bb9f069898e465a64e584a5770313597f7c8a12c4947438786374d861557a536) potentially have a common nexus. 
Frequency Scatter Plot
Figure 5: Frequency Scatter Plot

Both extremes are interesting for hunting and research, however, the smaller groupings of data are excellent opportunities for clustering and finding related samples.

APK Files

While performing this research a goal was to show the same graphing for both Extension Manifests and APKs. This would further solidify this clustering and analysis method. To achieve this goal, Mandiant identified 13,372 APKs to use when calculating permhash and creating the associated frequency scatter plot. APKs demonstrated many of the same features as extension manifestsachieving the goal.

Similar to extension manifests, APKs have extremes where one permhash is shared once and 2,625 times the permhash is only shared with one other sample. This can be observed in Figure 6.

Frequency Scatter Plot with Extremes
Figure 6: Frequency Scatter Plot with Extremes

While there is value in the extremes, the initial wins are identified within the curve of the graph. Working in the curve of the graph allows a researcher to work with a batch of related samples between 20 and 100 sharing a permhash rather than in the thousands.

Permhash in the Wild


VENOMSOFT is a cryptocurrency dataminer that disguises itself as a browser extension. The extension will load malicious JS files depending on the visited website and drain victim cryptocurrency wallets by hooking API calls related to money withdrawals and swapping their wallets.

Mandiant had six unique VENOMSOFT manifest.json files with a shared permhash of 9126f12ce5d0e610bb74da304b6bd0cd648428e59e74326fbd5affaa70d2257e. Pivoting on this permhash within the dataset surfaced seven files, six were the previously known VENOMSOFT files and 6affa6fc3d3f0f5269737a560971f060 was unknown at the time of writing. Careful analysis of the manifest file and its relationships show that the related extension is a previously unattributed VENOMSOFT sample.


UNC3559 is a financially motivated threat cluster that has distributed the CHROMELOADER dropper since at least early 2022. CHROMELOADER is a dropper that subsequently downloads a malicious Chrome extension, which can display advertisements in the browser and capture browser search data.

While hunting through manifest files associated to known threat clusters, Mandiant identified 1ba7a6eff1e897e0f77f1d7b0dfd3ff7 and its associated permhash, d4d1b61f726a5b50365c8c18b2c5ac7ab34b3844e0d50112f386dfd875b6afac. Pivoting on this permhash within the collected 11,575 samples led to the identification of six new previously unattributed samples. Further analysis then showed a relationship between the new files and UNC3559 using CHROMELOADER leading to enhanced clustering and understanding of the threat actor.

CERBERUS Android Trojan

CERBERUS is an Android Trojan with a broad range of capabilities typical of banking Trojans, RATs, and ransomware. These capabilities include the ability to perform overlay attacks, log keystrokes, send and read SMS messages, location collection, contact listing, call forwarding, lock user device, install/remove applications and interact with the OS and file system remotely, among others.

Utilizing permhash to pivot within the 13,372 collected APK samples, Mandiant identified a cluster of CERBERUS samples with a shared permhash. There were 12 samples within this cluster. Of those 12, Mandiant was aware that 10 of them were confirmed CERBERUS, the two remaining samples were unknown. Further analysis showed that these two unknown samples were indeed CERBERUS and one of the samples included a previously unreported C2 IP address. This shows the benefit of being able to pivot between samples in large datasets and identify new threat data.

LEMONJUICE Android Backdoor

LEMONJUICE is an Android backdoor with a wide range of functionality designed to enable remote control of and access to a compromised device. The malware is capable of tracking device location, recording the microphone, retrieving contact lists, accessing call, SMS, clipboard, and notification logs, viewing installed applications, downloading and uploading files, viewing connectivity status, and executing additional commands from the C2 server.

Identifying malicious APKs and pivoting on the permhash to identify related samples is an excellent use of permhash. While hunting through the samples collected in this research Mandiant identified 93 samples with a shared permhash. Of the 93 samples, 91 were previously known LEMONJUICE samples. This shows a very high threat density. The other two samples were then confirmed to be newly identified LEMONJUICE.

Cautionary Tale

APT43 is a prolific cyber operator that supports the interests of the North Korean regime and has used extensions in previous cyber operations.

The manifest files from these extensions pose as a cautionary tale. Much of the manifest details between the APT43 samples overlap, including the extension name, script names, description, dev tools, and icon. However, as the version of the extension changes so do the permissions, as shown in Figure 7.

Figure 7: APT43 Manifest Permissions

Sample 1: "permissions": ["tabs","webNavigation","cookies","https://*/*","http://*/*"]

Sample 2: "permissions": ["tabs","webNavigation","cookies","https://*/*","http://*/*"]

Sample 3: "permissions": ["tabs","webNavigation","webRequest","webRequestBlocking","https://*/*"]

Sample 4: "permissions": ["tabs","webNavigation","webRequest","webRequestBlocking","cookies","https://*/*","http://*/*"]

This is an instance of the requirements of the extension changing over time and therefore modifying the permhash. This is expected behavior given that, as stated in the Hypothesis and Execution section, permhash is adversary defined.

Using Permhash

In an attempt to broaden the use of permhash across the security industry, Mandiant, in collaboration with VirusTotal, has made permhash available within the VirusTotal Platform. When analyzing a CRX or APK the permhash value is viewable in the file details and available to pivot on.

Permhash Pivoting in VT
Figure 8: Permhash Pivoting in VT

Furthermore, Mandiant has released a permhash python library, a tool that can be used to calculate the permhash of a CRX, APK, CRX manifest, or APK manifest. 

Detection Opportunities

The four detections listed are to help identify files of interest when calculating permhash, CRX extensions, extension manifests, APKs, and Android manifests.

rule M_Hunting_Extension_Manifest_Permissions_1 {


        author = "Mandiant"

        description = "Hunting for extension manifests with permissions."       

        md5 = "b4a020208821c7e5bf99f8e3367897ba"


        $a1 = /"manifest_version"\s*:\s*/ ascii

        $a2 = /"name"\s*:\s*/ ascii

        $a3 = /"version"\s*:\s*/ ascii

        $anchor = /"permissions"\s*:\s*/ ascii

        $s1 = /"author"\s*:\s*/ ascii

        $s2 = /"automation"\s*:\s*/ ascii

        $s3 = /"background"\s*:\s*/ ascii

        $s4 = /"chrome_settings_overrides"\s*:\s*/ ascii

        $s5 = /"chrome_url_overrides"\s*:\s*/ ascii

        $s6 = /"commands"\s*:\s*/ ascii

        $s7 = /"content_scripts"\s*:\s*/ ascii

        $s8 = /"content_security_policy"\s*:\s*/ ascii

        $s9 = /"cross_origin_embedder_policy"\s*:\s*/ ascii

        $s10 = /"cross_origin_opener_policy"\s*:\s*/ ascii

        $s11 = /"declarative_net_request"\s*:\s*/ ascii

        $s12 = /"devtools_page"\s*:\s*/ ascii

        $s13 = /"event_rules"\s*:\s*/ ascii

        $s14 = /"export"\s*:\s*/ ascii

        $s15 = /"externally_connectable"\s*:\s*/ ascii

        $s16 = /"file_browser_handlers"\s*:\s*/ ascii

        $s17 = /"file_system_provider_capabilities"\s*:\s*/ ascii

        $s18 = /"homepage_url"\s*:\s*/ ascii

        $s19 = /"host_permissions"\s*:\s*/ ascii

        $s20 = /"import"\s*:\s*/ ascii

        $s21 = /"incognito"\s*:\s*/ ascii

        $s22 = /"input_components"\s*:\s*/ ascii

        $s23 = /"key"\s*:\s*/ ascii

        $s24 = /"minimum_chrome_version"\s*:\s*/ ascii

        $s25 = /"oauth2"\s*:\s*/ ascii

        $s26 = /"omnibox"\s*:\s*/ ascii

        $s27 = /"optional_host_permissions"\s*:\s*/ ascii

        $s28 = /"optional_permissions"\s*:\s*/ ascii

        $s29 = /"options_page"\s*:\s*/ ascii

        $s30 = /"options_ui"\s*:\s*/ ascii

        $s32 = /"requirements"\s*:\s*/ ascii

        $s33 = /"sandbox"\s*:\s*/ ascii

        $s34 = /"short_name"\s*:\s*/ ascii

        $s35 = /"storage"\s*:\s*/ ascii

        $s36 = /"tts_engine"\s*:\s*/ ascii

        $s37 = /"update_url"\s*:\s*/ ascii

        $s38 = /"version_name"\s*:\s*/ ascii

        $s39 = /"web_accessible_resources"\s*:\s*/ ascii

        $s40 = /"action"\s*:\s*"/ ascii

        $s41 = /"default_locale"\s*:\s*"/ ascii

        $s42 = /"description"\s*:\s*"/ ascii

        $s43 = /"icons"\s*:\s*"/ ascii


        filesize < 10KB and $anchor and (all of ($a*)) and (1 of ($s*))


rule M_Hunting_BrowserExtension_CRX_1



        author = "Mandiant"

        description = "Hunting for CRX extension files."

        md5 = "b07c560ac6ef98dd1d9fbce144bc62f6"


        $a = "manifest.json" ascii

        $crx = {43 72 32 34}

        $pk = {50 4B 03 04}


        ($crx at 0) and $a and (#pk >1) and

        (for any i in (1..#pk) : ($a at @pk[i]+30))


rule M_Hunting_ArchiveEngine_APK_1



        author = "Mandiant"

        description = "Hunting for suspected APK files"

        md5 = "a04c2c3388da643ef67504ef8c6907fb"


        $f1 = {41 6e 64 72 6f 69 64 4d 61 6e 69 66 65 73 74 2e 78 6d 6c 50 4b}

        $f2 = {63 6c 61 73 73 65 73 2e 64 65 78 50 4b}

        $type = {50 4b}


        $type at 0 and all of them


rule M_Hunting_ArchiveEngine_APK_Manifest_1



        author = "Mandiant"

        description = "Hunting for suspected APK manifest files."

        md5 = "32f1ff7244ff5041f0db8613b97e24c4"


        $type = {03 00 08 00}

        $s1 = "manifest" ascii fullword

        $f1 = "activity" ascii fullword

        $f2 = "service" ascii fullword

        $f3 = "receiver" ascii fullword

        $f4 = "provider" ascii fullword


        $type at 0 and $s1 and (2 of ($f*))


Protection and Mitigation

This research has touched on multiple malware families that exist within the Android and CRX realm (LEMONJUICE, CERBERUS, CHROMELOADER, and VENOMSOFT). It is important to state that Mandiant and other security teams across Google, are committed to the mission of understanding and countering advanced threats. We apply our research to ensure Google’s products are secure and our users are safe. For individuals at high risk of this activity and other serious threats, Google provides advanced security resources, including Enhanced Safe Browsing and the Advanced Protection Program. When these tools are used in combination with Google’s Security Checkup, they provide the fastest and strongest level of protection against serious threats.


Researchers, analysts, and threat hunters need every advantage when identifying connections between large datasets. While the research documented in this post is specific to Chromium-based extensions and APKs, the theory of permhash is extensible and applicable to all filetypes that declare their permissions, increasing the potential for impact. The use of permhash, as demonstrated in this research, can be adopted to illuminate previously unknown related samples through pivoting and clustering.


This research  would not have been possible without the assistance of Connor McLaughlin, Nick Simonian, Matthew Dunwoody, Anders Vejlby, Paco López, Todd Plantenga, Daniel Garcia, Emiliano Martinez, Francisco Santos, Aseel Kayal, and countless others.