Skip to main content

The CISA advisory AA25‑239A details a sophisticated espionage campaign attributed to Chinese state-sponsored actors, collectively referred to as Salt Typhoon.

 

Why Does Salt Typhoon Matter?

These actors are targeting vulnerable network infrastructure — including routers and switches — to gain initial access, persist in the environment, move laterally, and exfiltrate sensitive data. In an earlier post we described how to counter initial access from Salt Typhoon actors. In this post we will look closer at one of  key tactics in this campaign, which involves abuse of the GuestShell feature available on certain Cisco platforms.

 

What is GuestShell?

GuestShell is a containerized Linux environment embedded within certain Cisco devices (e.g., IOS XE). It allows administrators — or, in the wrong hands, attackers — to run Linux commands and applications directly on the device.  Since the activity within a virtual container is monitored less closely than native operations on switches and routers, custom malicious code executed within the container can remain undetected longer and allow threat actors to persist and exfiltrate data, to establish and maintain a foothold. One such malicious utility is “JumbledPath”.

“The use of this utility would help to obfuscate the original source, and ultimate destination, of the request and would also allow its operator to move through potentially otherwise non-publicly-reachable (or routable) devices or infrastructure.”, describe Cisco Talos analysts. 

 

What Should You Do?

If you're running Cisco devices — particularly IOS XE and NX-OS — you must immediately review your GuestShell exposure. Where not operationally required, disable it. If it must remain enabled, apply strict hardening controls. This should be treated as a high-priority mitigation step.

How Can Forward Networks Help?

It is a challenge to continuously verify the state of GuestShell across all devices. It does not show up in the running config (or even in show running config all!), and to constantly run commands against your environment is error prone and time consuming. This is where Forward Networks brings real value.

Using custom command collections, we can programmatically check the status of GuestShell on NX-OS and IOS XE devices. The results from these commands can then be used in an NQE query to trigger alerts or generate ServiceNow incidents when GuestShell is detected.

Let's get it set up!

Step 1: Create a Custom Command Group

Navigate to:
Collection > Collection Settings > Custom Commands
Click "Add Command Group".

 

Step 2: Name the Command Group

In this example, we'll name it NXOS-GuestShell-Verify.
Click Next.

 

 

Step 3: Define OS Type and Command

  • OS Connection Type: NXOS
  • Command to execute: show guestshell

 

Step 4: Select Target Devices

You can select devices in several ways:

  • Manually select specific devices
  • Use a glob pattern

Or (recommended) choose "Select All Devices of OS Connection Type" to dynamically include new devices as they are discovered.

 

 

Repeat this process for IOS XE devices, using the following command:
show app-hosting detail

Step 5: Create the NQE Query

Next, let’s create an NQE query that parses the outputs of our custom commands and identifies if GuestShell is enabled.  To create a NQE Query, navigate to NQE and click create new query

 

 

We are going to call this Query GuestShell-Verify

 

 

/**
* @intent Check to see if GuestShell is enabled
* @description Ensure that guestshell is not enabled on any device.
*/

nxos = ```
Virtual service guestshell+ detail
State : {state: string}
Package information
Name : {packageName: string}
Path : {packagePath: string}
Application
Installed version : {packageAppInstalledVer: string}
```;

iosxe = ```
State : {state: string}
Application
Name : {packageName: string}
Version : {packageAppInstalledVer: string}
Path : {packagePath: string}
```;

generic = ```
GuestShell-State : {state: string}
Application
App-Name : {packageName: string}
App-Version : {packageAppInstalledVer: string}
App-Path : {packagePath: string}
```;


foreach device in network.devices
let show_command = if device.platform.os == OS.NXOS then "show guestshell"
else if device.platform.os == OS.IOS_XE then "show app-hosting detail"
else "show app-hosting"
foreach command in device.outputs.commands
where command.commandText == show_command
let parsed_response = parseConfigBlocks(device.platform.os, command.response)
let guest_shellpattern = if device.platform.os == OS.NXOS then nxos
else if device.platform.os == OS.IOS_XE then iosxe
else generic
let my_data = blockMatches(parsed_response, guest_shellpattern)
foreach entry in my_data

select {
violation: entry.data.state == "Activated" || entry.data.state =="RUNNING",
GuestShellState: entry.data.state,
device: device.name,
deviceType: device.platform.model,
deviceOS: device.platform.os,
location: device.locationName,
GuestShellVersion: entry.data.packageAppInstalledVer
}

 

Here’s the high-level breakdown of the query:

  • Iterates over all devices of type NX-OS or IOS XE
     
  • Pulls outputs from show guestshell or show app-hosting detail
     
  • Parses for GuestShell state (e.g., "RUNNING", "Activated") and violates if these are true
     
  • Returns device metadata for easy triage (name, OS, version, location, etc.)
     

Example output (once a collection is done with the new custom command set):

GuestShell is deactivated on one device and enabled on two devices, and we see the two violations for the two that are either Activated or RUNNING

 

 

Step 6: Commit and add the Query to Verify

Once verified, commit your NQE query.  To do this select the query and click the commit button on the toolbar:

 

 

Then schedule it to run automatically at every collection cycle:
Navigate to Verify > NQE and click "Add NQE Queries".

 

 

Search for your query name (e.g., GuestShell-Verify), select it, and click Add.

 

 

Verify it's listed under NQE > Verify:

 

 

Continuous GuestShell Verification: Why It Matters

With this setup, GuestShell status is automatically checked with every network snapshot. This means:

  • Instantly know when policy drifts — no surprises, just action.
  • GuestShell changes are fully tracked — every modification, every time.
  • Stop guessing. Start verifying with confidence.
  • We’re enforcing policy at scale, with confidence, and in minutes, not days.

 

Be the first to reply!