A PoC C2 implementation that uses Native Messaging API to execute direct commands in the Windows OS.
Report Bug
Table of Contents
This is a new C2 implementation named Covert C2 or C3 (Covert+Command+Control=C3) that uses the Native Messaging API to establish a post-exploitation communication against a host. Native Messaging API is a browser API that is used from extension to communicate with desktop applications. For more details, here is a link to the relevant paper: https://www.mdpi.com/1999-5903/17/4/172
In this case, the Native Messaging API was weaponized to be used for post-exploitation attacks. This serves as a Proof-of-Concept (PoC) as it can take multiple directions and configurations. This means that it might need some additional implementations before being used in a real-case scenario.
Another reason that this serves as a PoC and not as a complete post-exploitation framework is that this is an open-source project and most EDRs will signature it. So, providing the methodology and simple way of communication could assist future and authorized red-team engagements to success.
All previous works focused on exploiting the browser itself, e.g., stealing cookies, injecting different domains, or causing redirects. Only EarthKitsune APT group used a similar technique in 2023 to load a shellcode in the memory of the host by using the Native Messaging API in their attack flow.
However, this work communicates directly with the OS, i.e., executes direct commands and uses minimal evasion tactics to achieve this post-exploitation attack. As a result, no tested EDR (4 were tested on free trial) was able to flag this communication as malicious.
This means that such an attack is mostly undocumented by EDR vendors and could cause serious issues when exploited.
The differences and advantages with other C2 frameworks are the following:
- Decentralized approach: Each host can communicate separately with any number of C2 servers, say by using subdomains or domains or implementing a cookie functionality.
- Expandability: The implementation right now supports only Windows, but it can be easily extended to be used against MacOS or Linux since it is mainly focused on using the Native Messaging API which is supported by both MacOS and Linux major browsers.
- Adaptability: It can adapt to different environments. For example, it can load the shellcode of another C2 framework to continue the post-exploitation attack or construct different type of commands for direct execution.
- Out-of-the-box Persistence: Persistence is quite crucial in a red team engagement. As a result, C3 offers out-of-the-box persistence to the post-exploitation attack by utilizing browser plugins.
- Direct Code Execution: It offers direct code execution. Although, in some cases, this will limit the attack's execution. In the latter case, using any adapt feature could assist, like using the shellcode of another C2 framework.
- Enhanced Stealth: EDRs had zero detections against the post-exploitation attacks of this implementation. Considering this implementation had minimal usage of evasion techniques, the evasion capabilities can be further enhanced, if needed. Also, it uses secure traffic with the C2 webserver with the assistance of HTTP/3 and QUIC.
- Lightweight: The extension, native app, and webserver executions are lightweight. This means that low resources are being consumed either from the victim's host or the webserver.
The following section describes the installation procedure for the C2 webserver, the extension, and the native application. For testing purposes, only Chromium browsers were tested, i.e., Chrome and MSEdge. Regarding the development of the native app or the reflective DLL, a common environment was used, i.e., Visual Studio 2022 with all of the relevant Windows SDKs installed.
Relevant testbed and versions:
- MS Windows 10 Enterprise (build 19045.5371)
- MSEdge v132.0.2957.140
- Chrome v132.0.6834.160
- Ubuntu Server 22.04 LTS
- Caddy v2.9.1
- PHP v8.4
- Python v3.11.6
For testing purposes, an Azure VM was used, along with a free azurewebsites domain name. Consider using whatever is suitable.
- Install an Ubuntu OS, e.g., 22.04.
sudo apt update && sudo apt upgrade -ysudo apt install -y debian-keyring debian-archive-keyring apt-transport-httpscurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpgcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.listsudo apt updatesudo apt install php php-fpmsudo systemctl enable php8.4-fpm.servicesudo apt install caddy=2.9.1sudo mkdir /var/www/domainsudo mkdir /var/www/domain/uploadssudo chown -R www-data:www-data /var/www/domain- Allow in firewall the 443/tcp and 443/udp ports
sudo nano /etc/caddy/Caddyfile-
domain { root * /var/www/domain # Enable HTTP/3 @http3 { protocol h3 } header { Strict-Transport-Security max-age=31536000; alt-svc "h3=\":443\"; ma=2592000" } @cors { method OPTIONS header Origin * } handle @cors { header Access-Control-Allow-Origin * header Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD" header Access-Control-Allow-Headers "Content-Type" respond 204 } header { Access-Control-Allow-Origin * Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD" Access-Control-Allow-Headers "Content-Type" } # Enable the static file server. file_server bind 0.0.0.0 tls { protocols tls1.3 } # Another common task is to set up a reverse proxy: # reverse_proxy localhost:8080 # Or serve a PHP site through php-fpm: # php_fastcgi localhost:9000 php_fastcgi unix//run/php/php-fpm.sock # Use php-fpm to process PHP files } sudo systemctl restart caddy
Regarding the extension installation, we will need the background.js and manifest.json files. Before proceeding with the installation, it should be mentioned there is a different behavior in Chrome and MSEdge. MSEdge can load extensions from anywhere without any issues. However, when the malicious extension is installed and the user opens the browser, the browser popups a message named "Turn off extensions in developer mode." with a highlighted blue button that when the user clicks it, the button disables the malicious extension. This can be bypassed with the usage of "headless" mode which will be explained later on. The following screenshot demonstrates this popup message.
On the other hand, Chrome is restricted when trying to install extensions outside of the Chrome store. For instance, when using the "--load-extension" flag to load the malicious extension, when the user or the process terminates, Chrome deletes the complete folder of the loaded extension. To achieve installation and bypass this issue, a legitimate pre-installed extension must be replaced with the malicious one, e.g., nmmhkkegccagdldgiimedpiccmgmieda, with the files of the malicious extension (background.js and manifest.json). The latter step and the "--load-extension" flag are needed to be used to ensure that Chrome will not delete the malicious extension.
Native app can be installed by simply storing the native_app.exe, the native_app.json, and the libcurl.dll files in a directory with user access, say AppData. The Dll libcurl.dll is needed from the native app to communicate with HTTP/3. Of course, this communication can be done with say, HTTP/1. So, by altering the code, the libcurl.dll usage is not necessary. However, libcurl.dll is available here for download https://curl.se/download.html.
Then, a new registry entry is required for the extension to be able to communicate with the native app. So, a new entry in HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\NEW ENTRY NAME and add as a path the directory that native_app.json resides.
The native_app.json needs the extension ID of the malicious extension to allow the communication with the native app. So, obtain the extension ID from the Secure Preferences file of either MSEdge or Chrome and add it to native_app.json either manually or automatically.
For development purposes, the test.py in dev folder can be used for assistance.
This section is dedicated to the usage of C3 separated in the following parts: Persistence, and Direct Command Execution.
Persistence is by default enabled in the C3 since in most cases a user will open their infected browser and as a result, the malicious extension will communicate directly with the webserver.
To further enhance persistence, an attacker can use either shortcuts or the headless mode. First, by simply replacing the legitimate shortcuts and adding the "--load-extension" flag could allow the attacker to achieve persistence and communication with the webserver. The following screenshot demonstrates the execution of this flag.
However, to avoid having user interaction, an attacker can use the "--headless" mode. MSEdge can use headless mode by adding the "--user-data-dir" flag during execution. This could create a directory with all user's preferences in the desired location, allowing the execution of the malicious extension in headless mode and altering the relevant .lnk file, e.g., "C:\path\to\exe" --load-extension="C:\path\to\extension" --user-data-dir="C:\path\to\create\new-user-data-folder" --headless. This means that an attacker can use MSEdge with a malicious extension without having issues with the relevant popup message of disabling the development (malicious) extension.
The same case can be applied to Chrome. However, Chrome for some reason requires to be executed twice with the same flags, i.e., headless and user-data-dir to establish a stable communication with the webserver. As a result, both browsers can be used with headless mode and say a Task Scheduler, without requiring users' interaction for persistence.
C3 operates with direct command execution, having the following flow between the attacker and the victim:
- The attacker's C2 server waits for the browser extension on the victim's machine to initiate a connection.
- Upon connection, the C2 server sends a URL to the extension.
- The extension forwards the URL to the native application.
- The native application downloads the DLL from the URL via HTTP/3 (QUIC), loads it into memory, and executes it.
- The native application sends the execution result to the extension.
- The extension relays the result back to the C2 server.
- The attacker views the execution result.
The following figure demonstrates this communication.
Webserver handles different endpoints, namely, /show-response, /query, /get-dll, /plugin-request, /get-plugin-request, /send-plugin-response, and /download/{filename}. The following screenshot demonstrates the homepage of the webserver.
1. /show-response: View the latest response, command output, and file information (used by the attacker).
2. /query: Interactive interface to respond to plugin requests and view files (used by the attacker). When a connection is received by the extension, the placeholder is enabled and the attacker can enter the URL with the relevant DLL they want to execute. The response is shown under the "Last Execution" field.
In this step, the attacker can send the relevant URL to the native app to download the DLL and execute it.
- /get-dll: Download the command execution DLL (used by the native app).
- /plugin-request: POST endpoint for plugin requests (used by the extension).
- /get-plugin-request: GET endpoint to check for active plugin requests (used by the extension).
- /send-plugin-response: POST endpoint to submit responses and handle file uploads (used by the extension).
- /download/{filename}: Download retrieved files from the server (used by the attacker).
For testing purposes, the following six scenarios were implemented and tested to verify the EDR's detection capabilities and the C3 functionality. The relevant commands are comment-out in the Dll code.
- Basic command execution: The
whoamicommand was executed via CMD. - Network connectivity test: The
ping 8.8.8.8command was executed via CMD. - Data Exfiltration: A file in the Downloads folder was converted to base64 and uploaded to the C2 server.
- Scheduled task execution as another user: The
schtaskscommand was used to schedule and execute a task as a different user. Due to the limitations of direct command execution without an interactive shell, the output of the task was redirected to a file, which was then retrieved. While this file-based approach impacts OpSec, it was necessary given the constraints of Covert C2's direct command execution and lack of shellcode support. Alternative solutions for avoiding file system interaction include blind command execution or using a C2 framework with shellcode capabilities. - Lateral movement: The
net usecommand was employed to establish a connection to another host via SMB. Similar to theschtasksscenario, file redirection was used to capture the output. It is noted that enabling WinRM on target hosts would simplify lateral movement and remote command execution with output capture. - Random: The last scenario was employed to illustrate the effectiveness of the evasion with random command execution. This means that this scenario used all the previous scenarios in random order.
To evaluate the detectability of Covert C2 by each EDR, we first installed the necessary components: the Covert C2 framework (including the web server and workstation components in the victim's host) and then the EDR software on the target workstation (victim's host). The evaluation involved initiating a connection from the Chrome browser to the C2 server every 10 sec. If a command was available, the communication proceeded as described in the relevant figure. Otherwise, the C2 server responded with "No".
Each of the six test scenarios was executed for five minutes with randomized command selection, i.e., either a specific scenario URL or a "No" response from the C2 server, for a total of 15 min per EDR. A final 10-min mixed scenario was then conducted, where commands were randomly selected from any of the five test cases (command execution or file upload).
Remarkably, the proposed scheme evaded detection by all tested EDR solutions across all six scenarios. This finding suggests a significant vulnerability in a range of EDR products to this post-exploitation technique. The fact that zero detections were recorded, despite the absence of code obfuscation (excluding the necessary Base64 encoding for file uploads), further underscores the potential impact of this approach.
Here is a short demonstration of the C3 command execution. The webserver is on the left side of the screen, while the victim's host on the right. The webserver is waiting for a connection to be established with an extension. Only then, the webapp enables the two buttons with green color. The first command is a whoami, while the second command is a ping 8.8.8.8. Both commands return their output to the webserver that are be noted in the "Last Execution" field. Note that the OneDrive popup is irrelevant to the C3. The installation procedure is that the attacker used the "--load-extension" flag in the .lnk of the Chrome browser.
c2-demo-light.mp4
Several potential detection points emerge from the usage of C3. In detail, the following list illustrates different protection mechanisms that can be used to mitigate the usage of C3.
- Using Group Policy Objects (GPO) to disable the installation of browser extensions, apart from the ones that are whitelisted.
- Using AppLocker and/or Windows Defender Application Control (WDAC).
- Registry entries, Task Scheduler, portable execution of browsers, shortcuts, and browsers executing CMD can be potentially monitored with different YARA rules. While not foulproof, examples of three (3) YARA rules are provided in the YARA directory.
From the above mitigations, only the GPO is the most effective one if configured correctly since it blocks the installation of any extension ID that this ID is not in the whitelist of the relevant policy. Options two (2) and three (3) in the above list can be potentially bypassed with different implementations and/or misconfigurations.
For example, AppLocker can be bypassed if a portable browser is used or a filetype that is not in the restricted list, say .vbs or with a DLL sideloading attack. Additionally, monitoring different functionalities is a more signature way of flagging these operations. As a result, an attacker can use a different functionality to potentially bypass this detection method.
To visualize the analysis, the following screenshot demonstrates the child processes of Chrome browser when communicates with the native app and when the native app executes a ping command. The third screenshot demonstrates what a user will view when a GPO blocks the installation of not-whitelisted extensions and an attacker tries to load a malicious extension with the "load-extension" flag.
Distributed under the MIT license. See LICENSE.txt for more information. C3 repository is provided for educational and/or legitimate purposes with no warranty.
Efstratios Chatzoglou - efchatzoglou@gmail.com