Aggregator
CVE-2025-31794 | Web Ready Now WR Price List Manager for Woocommerce Plugin up to 1.0.8 on WordPress authorization
CVE-2025-31827 | vlad.olaru Fonto Plugin up to 1.2.2 on WordPress path traversal
CVE-2025-31800 | Publitio Plugin up to 2.1.8 on WordPress path traversal
Suspected China-Nexus Threat Actor Actively Exploiting Critical Ivanti Connect Secure Vulnerability (CVE-2025-22457)
Written by: John Wolfram, Michael Edie, Jacob Thompson, Matt Lin, Josh Murchie
On Thursday, April 3, 2025, Ivanti disclosed a critical security vulnerability, CVE-2025-22457, impacting Ivanti Connect Secure (“ICS”) VPN appliances version 22.7R2.5 and earlier. CVE-2025-22457 is a buffer overflow vulnerability, and successful exploitation would result in remote code execution. Mandiant and Ivanti have identified evidence of active exploitation in the wild against ICS 9.X (end of life) and 22.7R2.5 and earlier versions. Ivanti and Mandiant encourage all customers to upgrade as soon as possible.
The earliest evidence of observed CVE-2025-22457 exploitation occurred in mid-March 2025. Following successful exploitation, we observed the deployment of two newly identified malware families, the TRAILBLAZE in-memory only dropper and the BRUSHFIRE passive backdoor. Additionally, deployment of the previously reported SPAWN ecosystem of malware attributed to UNC5221 was also observed. UNC5221 is a suspected China-nexus espionage actor that we previously observed conducting zero-day exploitation of edge devices dating back to 2023.
A patch for CVE-2025-22457 was released in ICS 22.7R2.6 on February 11, 2025. The vulnerability is a buffer overflow with a limited character space, and therefore it was initially believed to be a low-risk denial-of-service vulnerability. We assess it is likely the threat actor studied the patch for the vulnerability in ICS 22.7R2.6 and uncovered through a complicated process, it was possible to exploit 22.7R2.5 and earlier to achieve remote code execution.
Ivanti released patches for the exploited vulnerability and Ivanti customers are urged to follow the actions in the Security Advisory to secure their systems as soon as possible.
Post-Exploitation Tactics, Techniques, and ProceduresFollowing successful exploitation, Mandiant observed the deployment of two newly identified malware families tracked as TRAILBLAZE and BRUSHFIRE through a shell script dropper. Mandiant has also observed the deployment of the SPAWN ecosystem of malware. Additionally, similar to previously observed behavior, the actor attempted to modify the Integrity Checker Tool (ICT) in an attempt to evade detection.
Shell-script DropperFollowing successful exploitation of CVE-2025-22457, Mandiant observed a shell script being leveraged that executes the TRAILBLAZE dropper. This dropper injects the BRUSHFIRE passive backdoor into a running /home/bin/web process. The first stage begins by searching for a /home/bin/web process that is a child process of another /home/bin/web process (the point of this appears to be to inject into the web process that is actually listening for connections). It then creates the the following files and associated content:
-
/tmp/.p: contains the PID of the /home/bin/web process.
-
/tmp/.m: contains a memory map of that process (human-readable).
-
/tmp/.w: contains the base address of the web binary from that process
-
/tmp/.s: contains the base address of libssl.so from that process
-
/tmp/.r: contains the BRUSHFIRE passive backdoor
-
/tmp/.i: contains the TRAILBLAZE dropper
The shell script then executes /tmp/.i, which is the second stage in-memory only dropper tracked as TRAILBLAZE. It then deletes all of the temporary files previously created (except for /tmp/.p), as well as the contents of the /data/var/cores directory. Next, all child processes of the /home/bin/web process are killed and the /tmp/.p file is deleted. All of this behavior is non-persistent, and the dropper will need to be re-executed if the system or process is rebooted.
TRAILBLAZETRAILBLAZE is an in-memory only dropper written in bare C that uses raw syscalls and is designed to be as minimal as possible, likely to ensure it can fit within the shell script as Base64. TRAILBLAZE injects a hook into the identified /home/bin/web process. It will then inject the BRUSHFIRE passive backdoor into a code cave inside that process.
BRUSHFIREBRUSHFIRE is a passive backdoor written in bare C that acts as an SSL_read hook. It first executes the original SSL_read function, and checks to see if the returned data begins with a specific string. If the data begins with the string, it will XOR decrypt then execute shellcode contained in the data. If the received shellcode returns a value, the backdoor will call SSL_write to send the value back.
SPAWNSLOTHAs detailed in our previous blog post, SPAWNSLOTH acts as a log tampering component tied to the SPAWNSNAIL backdoor. It targets the dslogserver process to disable both local logging and remote syslog forwarding.
SPAWNSNARESPAWNSNARE is a utility that is written in C and targets Linux. It can be used to extract the uncompressed linux kernel image (vmlinux) into a file and encrypt it using AES without the need for any command line tools.
SPAWNWAVESPAWNWAVE is an evolved version of SPAWNANT that combines capabilities from other members of the SPAWN* malware ecosystem. SPAWNWAVE overlaps with the publicly reported SPAWNCHIMERA and RESURGE malware families.
AttributionGoogle Threat Intelligence Group (GTIG) attributes the exploitation of CVE-2025-22457 and the subsequent deployment of the SPAWN ecosystem of malware to the suspected China-nexus espionage actor UNC5221. GTIG has previously reported UNC5221 conducting zero-day exploitation of CVE-2025-0282, as well as the exploitation CVE-2023-46805 and CVE-2024-21887.
Furthermore, GTIG has also previously observed UNC5221 conducting zero-day exploitation of CVE-2023-4966, impacting NetScaler ADC and NetScaler Gateway appliances. UNC5221 has targeted a wide range of countries and verticals during their operations, and has leveraged an extensive set of tooling, spanning passive backdoors to trojanized legitimate components on various edge appliances.
GTIG assesses that UNC5221 will continue pursuing zero-day exploitation of edge devices based on their consistent history of success and aggressive operational tempo. Additionally, as noted in our prior blog post detailing CVE-2025-0282 exploitation, GTIG has observed UNC5221 leveraging an obfuscation network of compromised Cyberoam appliances, QNAP devices, and ASUS routers to mask their true source during intrusion operations.
ConclusionThis latest activity from UNC5221 underscores the ongoing sophisticated threats targeting edge devices globally. This campaign, exploiting the n-day vulnerability CVE-2025-22457, also highlights the persistent focus of actors like UNC5221 on edge devices, leveraging deep device knowledge and adding to their history of using both zero-day and now n-day flaws. This activity aligns with the broader strategy GTIG has observed among suspected China-nexus espionage groups who invest significantly in exploits and custom malware for critical edge infrastructure.
RecommendationsMandiant recommends organizations immediately apply the available patch by upgrading Ivanti Connect Secure (ICS) appliances to version 22.7R2.6 or later to address CVE-2025-22457. Additionally organizations should use the external and internal Integrity Checker Tool (“ICT”) and contact Ivanti Support if suspicious activity is identified. To supplement this, defenders should actively monitor for core dumps related to the web process, investigate ICT statedump files, and conduct anomaly detection of client TLS certificates presented to the appliance.
AcknowledgementsWe would like to thank Daniel Spicer and the rest of the team at Ivanti for their continued partnership and support in this investigation. Additionally, this analysis would not have been possible without the assistance from analysts across Google Threat Intelligence Group and Mandiant’s FLARE, we would like to specifically thank Christopher Gardner and Dhanesh Kizhakkinan of FLARE for their support.
Indicators of CompromiseTo assist the security community in hunting and identifying activity outlined in this blog post, we have included indicators of compromise (IOCs) in a GTI Collection for registered users.
Code Family
MD5
Filename
Description
TRAILBLAZE
4628a501088c31f53b5c9ddf6788e835
/tmp/.i
In-memory dropper
BRUSHFIRE
e5192258c27e712c7acf80303e68980b
/tmp/.r
Passive backdoor
SPAWNSNARE
6e01ef1367ea81994578526b3bd331d6
/bin/dsmain
Kernel extractor & encryptor
SPAWNWAVE
ce2b6a554ae46b5eb7d79ca5e7f440da
/lib/libdsupgrade.so
Implant utility
SPAWNSLOTH
10659b392e7f5b30b375b94cae4fdca0
/tmp/.liblogblock.so
Log tampering utility
YARA Rules rule M_APT_Installer_SPAWNANT_1 { meta: author = "Mandiant" description = "Detects SPAWNANT. SPAWNANT is an Installer targeting Ivanti devices. Its purpose is to persistently install other malware from the SPAWN family (SPAWNSNAIL, SPAWNMOLE) as well as drop additional webshells on the box." strings: $s1 = "dspkginstall" ascii fullword $s2 = "vsnprintf" ascii fullword $s3 = "bom_files" ascii fullword $s4 = "do-install" ascii $s5 = "ld.so.preload" ascii $s6 = "LD_PRELOAD" ascii $s7 = "scanner.py" ascii condition: uint32(0) == 0x464c457f and 5 of ($s*) } rule M_Utility_SPAWNSNARE_1 { meta: author = "Mandiant" description = "SPAWNSNARE is a utility written in C that targets Linux systems by extracting the uncompressed Linux kernel image into a file and encrypting it with AES." strings: $s1 = "\x00extract_vmlinux\x00" $s2 = "\x00encrypt_file\x00" $s3 = "\x00decrypt_file\x00" $s4 = "\x00lbb_main\x00" $s5 = "\x00busybox\x00" $s6 = "\x00/etc/busybox.conf\x00" condition: uint32(0) == 0x464c457f and all of them } rule M_APT_Utility_SPAWNSLOTH_2 { meta: author = "Mandiant" description = "Hunting rule to identify strings found in SPAWNSLOTH" strings: $dslog = "dslogserver" ascii fullword $hook1 = "g_do_syslog_servers_exist" ascii fullword $hook2 = "ZN5DSLog4File3addEPKci" ascii fullword $hook3 = "funchook" ascii fullword condition: uint32(0) == 0x464c457f and all of them }How To Harden GitLab Permissions with Tenable
If your organization uses GitLab for managing your software development lifecycle, you must ensure you’re not misconfiguring the permissions of this open source DevSecOps platform. Doing so can expose your source code, along with sensitive data, while creating security risks. In this blog, we’ll explain how new Tenable plugins can help you keep your GitLab environment secure.
GitLab is one of the most popular source code management (SCM) and continuous integration and delivery/development (CI/CD) open-source solutions. Enterprise developers leverage GitLab to build their organizations’ web applications and automate their deployment. GitLab is available as both a SaaS application and an on-premises solution.
GitLab permissions model overviewGitLab’s structure is organized into these key components:
- Projects: This is the core unit where source code, issues, CI/CD pipelines and other development resources live. Each project contains its own repository and settings. A project can be public, private or internal.
- Groups: They contain one or more projects to help administrators define high-level organizational units designed for teams or organizations. By leveraging groups, administrators can for, example, automatically assign permissions and apply configurations to their projects. Self-managed GitLab instances and SaaS instances for organizations will automatically provide a top-level group which we will refer to as the “root” or “organization-level” group.
- User Namespaces: Every GitLab user automatically gets a personal namespace to host personal projects or code snippets to share with other users.
GitLab offers administrators the ability to define their access control policy on the different components according to their business needs. This includes:
- Setting the default visibility for newly created groups, projects or snippets. The three available options are private, internal and public. The public option makes the resource readable to anyone in the world without any authentication.
- Restricting visibility levels to limit the visibility options available to users when creating or updating resources such as projects, groups or snippets.
Use cases for the different types of visibility vary depending on the organization’s business needs. For example, if an organization is hosting an open-source project on a GitLab instance, it would make sense for administrators to set the visibility option for the project or the group to public. On the other hand, an administrator would most likely choose the private or internal options for a GitLab instance dedicated to an internal project.
Identifying permissions blindspotsWe recently developed new Tenable Web Application Scanning plugins for GitLab, designed to alert our customers about overpermissive visibility levels. While conducting our research, we identified a number of permission blindspots in GitLab that guided the development of our plugins.
Limited visibility controls over personal namespacesFirst, we realized that GitLab administrators who want to restrict visibility levels for their groups, projects and snippets can only do so in certain scenarios.
In some cases, administrators can restrict visibility levels only for organization-level groups and for inherited objects. However, they can’t restrict visibility levels for personal namespaces.
According to GitLab’s documentation, the visibility restriction setting “does not apply to groups and projects created under a personal namespace” although there is a feature request to extend this functionality to enterprise users.
GitLab’s documentation provides a workaround for administrators to disable the creation of personal namespaces. However, the workaround’s functionality is limited.
Permission blindspots via GitLab’s GraphQL API: Groups, topics, snippetsSecond, we identified that third-party tools for detecting excessive GitLab permissions rely mainly on the GitLab REST API. But GitLab also offers a GraphQL API, which provides a more flexible and efficient way to query data. Thus, we decided to see if we could use it for our detections.
GitLab instances expose a GraphQL Explorer interface on the https://GITLAB/-/graphql-explorer URL. Although this web interface slightly increases the GitLab attack surface, it doesn’t pose an immediate security risk because its role is mainly to offer a convenient way to send requests to the GitLab GraphQL API. If you’re not an authenticated user of the target GitLab instance, the requests will only allow retrieval of publicly available data.
Access to public groupsLet’s look at the type of public data you’re able to access via this method, starting with the following query to retrieve the public groups on a target instance:
Requesting public groups through the GraphQL API
Public groups fetched through the GraphQL API
The response returns all the public groups along with their webUrl, which allows an unauthenticated user to visit those URLs directly.
Access to public projects and their source codeWith the URLs that were returned, an unauthenticated user can now follow the same operation to see the public projects and access their source code:
Requesting public projects through the GraphQL API
Public projects fetched through the GraphQL API
Access to project topicsAn unauthenticated user also can retrieve information about project topics by specifying the title and description fields in the GraphQL query:
Requesting public topics through the GraphQL API
Public topics fetched through the GraphQL API
Access to public code snippetsWe also observed that the code snippets feature can be public depending on the hosting type and the license level, and administrators can’t change the visibility level to private or internal as described in this official issue. The code snippets feature allows users to store pieces of code on the GitLab instance without adding them to a project repository.
That said, we noticed a difference in behaviour between the GitLab REST and GraphQL APIs: using the GraphQL API an unauthenticated user would be able to retrieve the list of public snippets but not with the GitLab REST API.
If you try to use the GitLab REST API to request the list of all public snippets without authentication through the https://GITLAB//api/v4/snippets/public URL, you’ll get a 401 error:
{"message":"401 Unauthorized"}By trying to access the public snippets through either the https://GITLAB/explore/snippet or https://GITLAB/-/snippets URLs, the unauthenticated user will be redirected to the sign_in page. However, by using the GraphQL API, an unauthenticated user will be able to get the entire list of public snippets and browse its source code:
Requesting public snippets through the GraphQL API
Public snippets fetched through the GraphQL API
Depending on the content of the public code snippet shared by the GitLab users, this could potentially expose sensitive source code to unauthorized users.
Understand what “public” visibility means on GitLabNote that unauthenticated users would be able to access GitLab APIs most of the time even in cases where single sign-on (SSO) authentication is enforced, which can help attackers gain access to the exposed data.
Using this method, we found many instances where unauthenticated users would be able to access publicly-available data from GitLab projects. We believe the reason for this is that many GitLab users probably assume incorrectly that the public visibility option restricts viewers to users within their organization. In fact, this option gives visibility to everyone in the world.
In addition, the GitLab platform currently offers administrators a way to set the default visibility for code snippets and enforce access-control over them. However, this feature is not available to all users and depends on customers’ hosting mode and the license level.
This highlights the need for organizations to fully understand the permissions model of the third-party tools they use, and to proactively add controls when possible. To ensure proper implementation of any third-party tool or service, you should carefully review the product documentation to prevent security issues such as data exposure.
How Tenable Can HelpOur new plugins for GitLab help customers set up additional controls and monitor the potential misconfigurations discussed above:
- GitLab Public Snippets Detected will check if any public snippet has been detected during the scan when a GitLab instance is detected.
- GitLab Public Projects Detected will report any public project available when a GitLab instance is detected.
The post How To Harden GitLab Permissions with Tenable appeared first on Security Boulevard.
Social Engineering Just Got Smarter
How To Harden GitLab Permissions with Tenable
If your organization uses GitLab for managing your software development lifecycle, you must ensure you’re not misconfiguring the permissions of this open source DevSecOps platform. Doing so can expose your source code, along with sensitive data, while creating security risks. In this blog, we’ll explain how new Tenable plugins can help you keep your GitLab environment secure.
GitLab is one of the most popular source code management (SCM) and continuous integration and delivery/development (CI/CD) open-source solutions. Enterprise developers leverage GitLab to build their organizations’ web applications and automate their deployment. GitLab is available as both a SaaS application and an on-premises solution.
GitLab permissions model overviewGitLab’s structure is organized into these key components:
- Projects: This is the core unit where source code, issues, CI/CD pipelines and other development resources live. Each project contains its own repository and settings. A project can be public, private or internal.
- Groups: They contain one or more projects to help administrators define high-level organizational units designed for teams or organizations. By leveraging groups, administrators can for, example, automatically assign permissions and apply configurations to their projects. Self-managed GitLab instances and SaaS instances for organizations will automatically provide a top-level group which we will refer to as the “root” or “organization-level” group.
- User Namespaces: Every GitLab user automatically gets a personal namespace to host personal projects or code snippets to share with other users.
GitLab offers administrators the ability to define their access control policy on the different components according to their business needs. This includes:
- Setting the default visibility for newly created groups, projects or snippets. The three available options are private, internal and public. The public option makes the resource readable to anyone in the world without any authentication.
- Restricting visibility levels to limit the visibility options available to users when creating or updating resources such as projects, groups or snippets.
Use cases for the different types of visibility vary depending on the organization’s business needs. For example, if an organization is hosting an open-source project on a GitLab instance, it would make sense for administrators to set the visibility option for the project or the group to public. On the other hand, an administrator would most likely choose the private or internal options for a GitLab instance dedicated to an internal project.
Identifying permissions blindspotsWe recently developed new Tenable Web Application Scanning plugins for GitLab, designed to alert our customers about overpermissive visibility levels. While conducting our research, we identified a number of permission blindspots in GitLab that guided the development of our plugins.
Limited visibility controls over personal namespacesFirst, we realized that GitLab administrators who want to restrict visibility levels for their groups, projects and snippets can only do so in certain scenarios.
In some cases, administrators can restrict visibility levels only for organization-level groups and for inherited objects. However, they can’t restrict visibility levels for personal namespaces.
According to GitLab’s documentation, the visibility restriction setting “does not apply to groups and projects created under a personal namespace” although there is a feature request to extend this functionality to enterprise users.
GitLab’s documentation provides a workaround for administrators to disable the creation of personal namespaces. However, the workaround’s functionality is limited.
Permission blindspots via GitLab’s GraphQL API: Groups, topics, snippetsSecond, we identified that third-party tools for detecting excessive GitLab permissions rely mainly on the GitLab REST API. But GitLab also offers a GraphQL API, which provides a more flexible and efficient way to query data. Thus, we decided to see if we could use it for our detections.
GitLab instances expose a GraphQL Explorer interface on the https://GITLAB/-/graphql-explorer URL. Although this web interface slightly increases the GitLab attack surface, it doesn’t pose an immediate security risk because its role is mainly to offer a convenient way to send requests to the GitLab GraphQL API. If you’re not an authenticated user of the target GitLab instance, the requests will only allow retrieval of publicly available data.
Access to public groupsLet’s look at the type of public data you’re able to access via this method, starting with the following query to retrieve the public groups on a target instance:
Requesting public groups through the GraphQL API
Public groups fetched through the GraphQL API
The response returns all the public groups along with their webUrl, which allows an unauthenticated user to visit those URLs directly.
Access to public projects and their source codeWith the URLs that were returned, an unauthenticated user can now follow the same operation to see the public projects and access their source code:
Requesting public projects through the GraphQL API
Public projects fetched through the GraphQL API
Access to project topicsAn unauthenticated user also can retrieve information about project topics by specifying the title and description fields in the GraphQL query:
Requesting public topics through the GraphQL API
Public topics fetched through the GraphQL API
Access to public code snippetsWe also observed that the code snippets feature can be public depending on the hosting type and the license level, and administrators can’t change the visibility level to private or internal as described in this official issue. The code snippets feature allows users to store pieces of code on the GitLab instance without adding them to a project repository.
That said, we noticed a difference in behaviour between the GitLab REST and GraphQL APIs: using the GraphQL API an unauthenticated user would be able to retrieve the list of public snippets but not with the GitLab REST API.
If you try to use the GitLab REST API to request the list of all public snippets without authentication through the https://GITLAB//api/v4/snippets/public URL, you’ll get a 401 error:
{"message":"401 Unauthorized"}By trying to access the public snippets through either the https://GITLAB/explore/snippet or https://GITLAB/-/snippets URLs, the unauthenticated user will be redirected to the sign_in page. However, by using the GraphQL API, an unauthenticated user will be able to get the entire list of public snippets and browse its source code:
Requesting public snippets through the GraphQL API
Public snippets fetched through the GraphQL API
Depending on the content of the public code snippet shared by the GitLab users, this could potentially expose sensitive source code to unauthorized users.
Understand what “public” visibility means on GitLabNote that unauthenticated users would be able to access GitLab APIs most of the time even in cases where single sign-on (SSO) authentication is enforced, which can help attackers gain access to the exposed data.
Using this method, we found many instances where unauthenticated users would be able to access publicly-available data from GitLab projects. We believe the reason for this is that many GitLab users probably assume incorrectly that the public visibility option restricts viewers to users within their organization. In fact, this option gives visibility to everyone in the world.
In addition, the GitLab platform currently offers administrators a way to set the default visibility for code snippets and enforce access-control over them. However, this feature is not available to all users and depends on customers’ hosting mode and the license level.
This highlights the need for organizations to fully understand the permissions model of the third-party tools they use, and to proactively add controls when possible. To ensure proper implementation of any third-party tool or service, you should carefully review the product documentation to prevent security issues such as data exposure.
How Tenable Can HelpOur new plugins for GitLab help customers set up additional controls and monitor the potential misconfigurations discussed above:
- GitLab Public Snippets Detected will check if any public snippet has been detected during the scan when a GitLab instance is detected.
- GitLab Public Projects Detected will report any public project available when a GitLab instance is detected.