Cybersecurity Q&A
Browse concise answers derived from our published, source-linked cybersecurity coverage.
What are the steps to delete a single log entry from an EVT file?
The deletion process involves: (1) Locating the target event record using the ELF_LOG_SIGNATURE and record number; (2) Deleting the raw bytes of that record; (3) Decrementing the record numbers of all subsequent event records by 1; (4) Updating the file header’s end-of-file offset, newest record number, and maximum file size; (5) Updating the same fields in the end-of-file record. The [Part 2 article](/news/windows-event-viewer-log-evt-single-log-deletion-part-2-program-implementation-for-deleting-log-records-within-a-specified-time-range-from-evt-files) provides a programmatic implementation of this approach.
How is an EVT file structured and what key fields must be updated when deleting a log entry?
An EVT file consists of a file header, event records, an end-of-file record, and trailing empty values. When deleting a single log entry, you must update five items in the file header (first record offset, end-of-file record offset, last record number, first record number, maximum file size) and four items in the end-of-file record (same four offsets/numbers). The original [Windows Event Viewer Log (EVT) Single Log Deletion (Part 1) – Deletion Approach and Examples](/news/windows-event-viewer-log-evt-single-log-deletion-part-1-deletion-approach-and-examples) details the exact byte offsets for each field.
What is an EVT file and which Windows systems use it?
An EVT (Windows Event Viewer Log) file is the legacy format used to store system log information before Windows Vista, commonly found on Windows NT 4, 2000, XP, and 2003. It differs from the newer [Windows XML Event Log (EVTX)](/news/windows-xml-event-log-evtx-single-log-deletion-part-3-deleting-a-single-log-record-from-the-current-system-by-releasing-file-handles) format introduced in Windows 7 and later. Common EVT logs include AppEvent.Evt, SecEvent.Evt, and SysEvent.Evt stored in `%systemroot%\system32\config`.
What are the main advantages of Covenant over other C2 frameworks?
Covenant offers multi-platform support for the C2 server (Linux, macOS, Windows, Docker), high scalability through customizable communication protocols, launchers, and functionalities, and the ability to execute extended capabilities entirely in memory using dynamic compilation and Assembly.Load(). This makes it both flexible and stealthy. The article's advantages section highlights these points in [Covenant Utilization Analysis](/news/covenant-utilization-analysis).
What are some notable capabilities available through Covenant's Grunt tasks?
Covenant integrates several open-source tools as built-in tasks, including Rubeus (Kerberos abuse), Seatbelt (security enumeration), SharpDPAPI, SharpDump (LSASS dumping), SharpSploit, SharpUp, and SharpWMI. These can be executed on the target via the Task interface, and operators can also add custom task templates. This extensibility is a key advantage of Covenant, as described in the [article](/news/covenant-utilization-analysis).
What are the two communication templates for Grunt and how do they differ?
Grunt supports two templates: GruntHTTP and GruntSMB. GruntHTTP communicates with the C2 server using HTTP, establishing a reverse connection. GruntSMB uses named pipes for peer-to-peer communication between Grunts without directly contacting the C2 server, making it useful for internal network propagation. Operators can activate a GruntSMB by using the 'Connect' task from another Grunt. For more, see the [Covenant Utilization Analysis](/news/covenant-utilization-analysis).
How does Covenant launch its Grunt payload and what are some of the launcher methods?
Covenant provides 9 launcher methods for deploying Grunt, including Binary (exe), PowerShell, MSBuild, InstallUtil, Wmic, Regsvr32, Mshta, Cscript, and Wscript. Most of these store the .NET assembly in an array and load it in memory via Assembly.Load() or DotNetToJScript, avoiding disk writes. For example, the PowerShell launcher uses `[Reflection.Assembly]::Load(Data).EntryPoint.Invoke(0,$a.ToArray())`. Details can be found in the [Covenant article](/news/covenant-utilization-analysis).
What is Covenant and what makes it stand out among C2 frameworks?
Covenant is a .NET-developed C2 framework that runs on Linux, macOS, Windows, and Docker. Its most distinctive feature is support for dynamic compilation, allowing operators to upload C# code to the C2 server, which compiles it and loads the resulting assembly into memory via Assembly.Load(). This enables highly customizable in-memory payloads for defense evasion. Read more about its specifics in [Covenant Utilization Analysis](/news/covenant-utilization-analysis).
What are the different dump methods supported by Lsassy for remotely extracting the lsass process?
Lsassy supports a variety of dump methods to handle different environments and protections. These include: `comsvcs` (using `MiniDump()` from `comsvcs.dll`), `comsvcs_stealth` (copies the dll to temp before use), `dllinject` (DLL injection via APC), `dumpert` and `dumpertdll` (using Outflank's Dumpert tool via API `MiniDumpWriteDump()`), `edrsandblast` (signed driver technique), `mirrordump` and `mirrordump_embedded` (via LSA SSP plugin), `nanodump` (multiple handle leak methods), `ppldump` (bypasses PPL protection on Windows 10/Server 2019), `procdump`, `rdrleakdiag`, and `wer`. Each method may require specific parameters like paths to executables or DLLs, and some leave traces that need manual cleanup.
What are the steps to package Lsassy into a standalone exe using PyInstaller, and what common errors occur?
To package Lsassy's console interface into a standalone exe, use PyInstaller with the main script from `lsassy/console.py`. A basic command like `pyinstaller -F console.py` will fail due to missing hidden imports. You must add `--hidden-import` for all required modules: `unicrypto` backends (e.g., `unicrypto.backends.pure.DES`, `unicrypto.backends.pure.AES`) and all `lsassy` submodules for dump methods (`lsassy.dumpmethod.*`) and exec methods (`lsassy.exec.*`) and outputs (`lsassy.output.*`). The article provides a complete command. Even after packaging, the export function may fail; debugging with `-vv` reveals missing `lsassy.dumpmethod.comsvcs`, requiring the inclusion of all dependency packages.
How do you install Lsassy and fix formatting issues on Windows?
Lsassy can be installed using pip: `pip install lsassy`. However, on Windows, the default output may contain garbled characters due to `termcolor` coloring not displaying properly in cmd. To fix this, modify the `logger.py` file located at `lib\site-packages\lsassy\logger.py` to check the OS and set color codes to empty strings on Windows (nt). The provided code in the article adjusts the formatter accordingly. After this modification, the tool can be tested with a command like `lsassy -u Administrator -p Password1 192.168.1.1`.
What is Lsassy and why is it useful for remote credential extraction from lsass.exe?
Lsassy is an open-source tool designed to automate the remote extraction of password hashes from the [lsass.exe](/news/penetration-basics-remotely-extracting-credentials-from-the-lsass-exe-process) process. It addresses key challenges such as requiring remote command execution, handling different dump methods based on protective measures, efficiently transferring large dump files, and automating repetitive tasks across multiple systems. Lsassy supports multiple export methods, directly parses password hashes, and automates operations to improve efficiency compared to manual local extraction methods like those covered in [Penetration Basics - Extracting Credentials from lsass.exe Process](/news/penetration-basics-extracting-credentials-from-lsass-exe-process).
What debugging steps are recommended for analyzing CVE-2021-34473, and why is the environment setup important?
The article recommends setting up a debugging environment by first disabling JIT optimization in Visual Studio via the `COMPLUS_ZapDisable=1` environment variable and restarting the system. Then, use `appcmd list wp` to identify Exchange worker process IDs, and attach dnSpy to the relevant `w3wp.exe` processes. Debugging is essential for understanding the SSRF trigger conditions and the flow from the `/autodiscover` endpoint to the internal `/mapi/nspi` call. The analysis also helps in confirming that the vulnerability runs with SYSTEM privileges, as shown in the [original ProxyShell research](/news/proxyshell-exploitation-analysis-1-cve-2021-34473).
How can an attacker enumerate all mailbox users in an Exchange organization using this vulnerability?
Once the attacker has impersonated a valid mailbox user via the SSRF and SID technique, they can use the FindPeople operation in EWS to enumerate the GlobalAddressList. This list contains the email addresses of all mailbox users in the Exchange organization. The attacker simply needs to traverse and deduplicate results. The article references open-sourced scripts for implementation, and notes that default system mailboxes (e.g., `SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}`) can be used as the impersonated user since they exist in every Exchange environment.
How can attackers use the SSRF vulnerability to access mailbox data of other users?
After triggering the SSRF, the attacker can call the Exchange Web Service (EWS) to read email content. However, because EWS requires authentication, the attacker leverages a technique from CVE-2018-8581 (privilege escalation) by embedding a `SerializedSecurityContext` in the SOAP header with a target user's SID. This allows the attacker to impersonate any mailbox user. To obtain the SID, the attacker first fetches the user's legacyDn via `/autodiscover/autodiscover.xml`, then queries `/mapi/emsmdb` with that legacyDn to retrieve the SID, as detailed in the [ProxyShell exploitation analysis](/news/proxyshell-exploitation-analysis-1-cve-2021-34473).
What is the core vulnerability in CVE-2021-34473 and how does it function?
CVE-2021-34473 is a Server-Side Request Forgery (SSRF) vulnerability in Microsoft Exchange that serves as the foundation of the [ProxyShell attack chain](/news/proxyshell-exploitation-analysis-1-cve-2021-34473). It allows an unauthenticated attacker to make the Exchange server send requests to internal resources, such as the Exchange Web Service (EWS) or the /mapi/nspi endpoint, by crafting a specially formatted URL to the /autodiscover/autodiscover.json endpoint with a parameter like `Email=autodiscover/autodiscover.json%[email protected]`. The SSRF runs with SYSTEM privileges, enabling further exploitation.
What are the key differences between the C# and Python implementations for connecting to the Exchange one-liner backdoor?
The C# implementation is more verbose, requiring explicit handling of HTTP requests, boundaries for file uploads, and URL encoding for the memory loading case. Python is more concise, using the `requests` library to handle POST data and file uploads with minimal code. Both versions disable SSL verification for testing. The Python example for memory loading uses `urllib.parse.urlencode` to encode the base64 data, while the C# code calls `HttpUtility.UrlEncode`. For a deeper dive into related client implementations, see [Penetration Basics — Extension of Exchange One-Liner Backdoor](/news/penetration-basics-extension-of-exchange-one-liner-backdoor).
Why must the base64-encoded payload be URL-encoded when sending to the memory loading backdoor via C#?
The base64 string often contains the `=` character, which in POST data with `Content-Type: application/x-www-form-urlencoded` is interpreted as a key-value separator. Therefore, the `=` must be URL-encoded to `%3d` to avoid breaking the parameter structure. The C# code uses `HttpUtility.UrlEncode` to handle this encoding automatically. Proper encoding is critical for successful payload delivery, as highlighted in the original [Penetration Basics - Implementation of Exchange One-Liner Backdoor](/news/penetration-basics-implementation-of-exchange-one-liner-backdoor).
What does the file write backdoor (test2.aspx) do, and how is it triggered?
`test2.aspx` checks if a file upload request exists (`Request.Files.Count != 0`). If so, it saves the first uploaded file to `uploadDemo.aspx` in the same directory using `SaveAs`. Attackers can upload a malicious ASPX webshell to gain persistent access. This method is simpler than memory loading but leaves a file on disk, increasing detection risk. For further tradecraft development, refer to the [Penetration Basics — Extension of Exchange One-Liner Backdoor](/news/penetration-basics-extension-of-exchange-one-liner-backdoor) for variations.
How does the memory loading backdoor (test1.aspx) execute a payload?
`test1.aspx` reads the `demodata` parameter from a POST request, base64-decodes it, and uses `System.Reflection.Assembly.Load` to load the resulting .NET assembly into memory. It then calls `CreateInstance("Payload").Equals("");` to execute the payload's code. This technique allows running arbitrary compiled .NET code without writing files, similar to the approach used in the HyperShell tool. For defense considerations, understanding [Exchange Version Detection and Vulnerability Scanning](/news/penetration-basics-exchange-version-detection-and-vulnerability-scanning) can help identify vulnerable Exchange servers before such backdoors are deployed.