Skip to main content

Chinese state-sponsored threat actors are targeting network infrastructure worldwide, leveraging compromised routers and edge devices to establish long-term persistence and exfiltrate sensitive data. A recent joint cybersecurity advisory from NSA, CISA, FBI, and international partners highlights the scale of this threat and provides detailed mitigation guidance.

At Forward Networks, we’ve created a purpose-built NQE query to help customers quickly identify two of the most common risks associated with this campaign:

  • Known exploited vulnerabilities used by the threat actors to gain initial access
     
  • Permissive ACLs that may allow traffic to flow to attacker-controlled IP addresses
     

Why this threat matters

The campaign—tracked in industry reporting under names such as Salt Typhoon and RedMike—isn’t limited to a single vendor or region. Attackers embed themselves in network devices, sometimes at ISPs or providers, then use those footholds to:

  • Steal authentication information by redirecting TACACS+/RADIUS traffic
     
  • Map customer infrastructure by harvesting routing protocols and inventories
     
  • Mirror sensitive traffic across entire organizations into attacker-controlled infrastructure
     

Even hardened organizations may be exposed if partners, vendors, or service providers have been compromised. Because ACLs and configs change constantly, it’s nearly impossible to manually audit at scale.

 

How Forward and NQE help

Using Forward’s Network Digital Twin, this NQE automates the first and most critical step in defending against Salt Typhoon: identifying the biggest holes in your defenses.

The query will:

  • Flag any network devices running software with known vulnerabilities linked to this campaign
     
  • Detect ACLs that permit traffic to the ~90 malicious IP addresses cited in the advisory
     

Instead of combing through millions of ACL entries by hand, Forward customers can run this check in seconds. This allows security and networking teams to quickly focus remediation efforts where they matter most.

Customer outcomes

This NQE delivers immediate value:

  • Rapid visibility into whether your environment is exposed to these high-risk TTPs
     
  • Prioritization of patching and ACL hardening so you can close the largest gaps first
     
  • Confidence that remediation worked by rerunning the query after changes
     

While this check does not need to be run continuously, we recommend rerunning it whenever ACLs or firewall rules are modified, since configuration drift can easily reintroduce risk.

 

Part of a broader defense strategy

This query should be considered a tactical first step. For long-term resilience, the advisory also recommends following best practices such as robust change management, continuous compliance with STIGs, and strict isolation of management traffic.

Forward Enterprise complements these recommendations by:

  • Automating compliance with STIGs and other frameworks
     
  • Continuously validating ACLs, routing, and segmentation
     
  • Supporting incident response with blast radius analysis and historical snapshots
     

Together, these capabilities help organizations not only detect current compromise indicators but also build a standardized, proactive security posture against advanced persistent threats.

 

Use it in your environment

Here’s the Forward NQE to run in your own instance:

/**
* @intent Identify settings that might lead to Salt Typhoon compromises
* @description Checks for the following:
* 1. Overly permissing ACLs where one of the known bad IP address is permitted in our out
* 2. Known suspect ACL names
* 3. Presence of one of the CVEs known to be exploited by Salt Typhoon
* If any of the conditions are true on a device - produces a violation
*/
SaltTIPStrings =
<"1.222.84.29",
"167.88.173.252",
"37.120.239.52",
"45.61.159.25",
"103.168.91.231",
"167.88.173.58",
"38.71.99.145",
"45.61.165.157",
"103.199.17.238",
"167.88.175.175",
"43.254.132.118",
"5.181.132.95",
"103.253.40.199",
"167.88.175.231",
"45.125.64.195",
"59.148.233.250",
"103.7.58.162",
"172.86.101.123",
"45.125.67.144",
"61.19.148.66",
"104.194.129.137",
"172.86.102.83",
"45.125.67.226",
"63.141.234.109",
"104.194.147.15",
"172.86.106.15",
"45.146.120.210",
"63.245.1.13",
"104.194.150.26",
"172.86.106.234",
"45.146.120.213",
"63.245.1.34",
"104.194.153.181",
"172.86.106.39",
"45.59.118.136",
"74.48.78.66",
"104.194.154.150",
"172.86.108.11",
"45.59.120.171",
"74.48.78.116",
"104.194.154.222",
"172.86.124.235",
"45.61.128.29",
"74.48.84.119",
"107.189.15.206",
"172.86.65.145",
"45.61.132.125",
"85.195.89.94",
"14.143.247.202",
"172.86.70.73",
"45.61.133.157",
"89.117.1.147",
"142.171.227.16",
"172.86.80.15",
"45.61.133.31",
"89.117.2.39",
"144.172.76.213",
"190.131.194.90",
"45.61.133.61",
"89.41.26.142",
"144.172.79.4",
"193.239.86.132",
"45.61.133.77",
"91.231.186.227",
"146.70.24.144",
"193.239.86.146",
"45.61.133.79",
"91.245.253.99",
"146.70.79.68",
"193.43.104.185",
"45.61.134.134",
"146.70.79.78",
"193.56.255.209",
"45.61.134.22",
"146.70.79.81",
"193.56.255.210",
"45.61.134.223",
"164.82.20.53",
"212.236.17.237",
"45.61.149.200",
"167.88.164.166",
"23.227.196.22",
"45.61.149.62",
"167.88.172.70",
"23.227.199.77",
"45.61.151.12",
"167.88.173.158",
"23.227.202.253",
"45.61.154.130"
];

SaltTIPs =
foreach str in SaltTIPStrings
select ipAddress(str);

SaltCVEStrings =
<"CVE-2024-21887",
"CVE-2023-46805",
"CVE-2024-3400",
"CVE-2023-20273",
"CVE-2023-20198",
"CVE-2023-20198",
"CVE-2018-0171"
];

badIPsinRange(range) =
foreach item in SaltTIPs
let IPinSrc = any(foreach subnet in range
where item in subnet
select true)
where IPinSrc
select item;

permissiveACLs(device) =
foreach aclEntry in device.aclEntries
let SuspiciousName = aclEntry.name in
n"access-list 20", "access-list 50", "access-list 10"]
where aclEntry.action == AclAction.PERMIT
let badIPsIn = badIPsinRange(aclEntry.headerMatches.ipv4Src)
let badIPsOut = badIPsinRange(aclEntry.headerMatches.ipv4Dst)
where length(badIPsIn) > 0 || length(badIPsOut) > 0 || SuspiciousName
select {
name: aclEntry.name,
BadIPSources: length(badIPsIn),
headerMatchesIpv4Src: aclEntry.headerMatches.ipv4Src,
BadIPDest: length(badIPsOut),
headerMatchesIpv4Dst: aclEntry.headerMatches.ipv4Dst,
actionAlternative: when aclEntry.action is
DENY -> "DENY";
PBR -> "PBR";
PERMIT -> "PERMIT",
description: aclEntry.description,
implicitRule: aclEntry.implicitRule,
defaultRule: aclEntry.defaultRule,
lifecycleDataTruncatedHitCount: aclEntry.lifecycleData?.truncatedHitCount
};

knownCVEs(device) =
foreach finding in device.cveFindings
where finding.cveId in SaltCVEStrings
where finding.isVulnerable
select finding.cveId;

/* body of the query */
foreach device in network.devices
let foundCVEs = knownCVEs(device)
let foundACLs = permissiveACLs(device)
select {
violation: length(foundCVEs) > 0 || length(foundACLs) > 0,
name: device.name,
CVEs: foundCVEs,
PermissiveACLs: (foreach acl in foundACLs
select distinct acl.name)
}

 

For full context and additional mitigation recommendations, see the official joint advisory PDF.

 

Questions? Ask below, or reach out to your Forward Networks team. 

 

Be the first to reply!

Reply