N-central Web Exploitation and Persistence
An attacker has exploited unauthenticated N-central web vulnerabilities to gain administrative control, subsequently establishing persistence through rogue user accounts and Cloudflare protocol tunnels.
Based on research by Huntress 2026-09-20 12 steps · 5 queries T1090.003 T1133 T1136 T1190 T1572
Brief
Why now
N-able recently reported active exploitation of a critical vulnerability in N-central. As detailed by Huntress in their report, Critical N-able N-central Vulnerability and Active Exploitation, attackers bypass authentication to gain administrative control over the appliance. Because RMM tools manage thousands of downstream endpoints, a compromise here is a tier-zero event. Traditional detections often miss the shift from a web exploit to long-term persistence.
How the Hunt Flows
The first phase identifies the N-central infrastructure. A query scans the hb_software_inventory surface for any host running N-able or N-central software. This scoping ensures the subsequent queries target only the relevant appliances.
The hunt then pivots to hb_http_activity to find the initial breach. It searches for two specific patterns: reconnaissance probes against the getPierDetails endpoint and RCE attempts using URL-encoded slashes in API paths. These encoded characters attempt to bypass simple web application firewalls that expect standard path delimiters.
After identifying potential access attempts, the hunt looks for persistence markers. It stack-counts email domains from the hb_auth_signin surface to find anomalous accounts, specifically those using the .invalid suffix reported in recent campaigns. It simultaneously searches hb_process_activity for the execution of the Cloudflared tunneling agent. This binary is not a standard component of the N-central appliance and is a strong indicator of a persistent backdoor.
In the final phase, an analyst correlates these findings. If a host shows both successful URL-encoded API exploitation and the subsequent appearance of a rogue account or a Cloudflare tunnel, the hunt confirms a breach and triggers isolation procedures.
What this Hunt Cannot See
Log retention is a primary constraint. If the exploit occurred more than 14 days ago, the HTTP and authentication logs likely already rotated. Furthermore, this hunt relies on the visibility of URL paths. If the appliance traffic is encrypted and not decrypted by an intermediary proxy or recorded by server-side logs, the URL-encoded path traversal attempts remain invisible to the network-level queries.
In this series
Steps
-
Identify N-central Infrastructure
Query · scopingIdentify systems running N-central software which may be vulnerable.
reads hb_software_inventorysqlSELECT device_hostname, package_name, package_version, vendor_name FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%n-central%' OR LOWER(vendor_name) LIKE '%n-able%')What a hit looks like. A list of hosts acting as N-central appliances. Silence means no N-central software is installed.
-
API Reconnaissance Probes
Query · enrichmentIdentify early staging activity where attackers map the environment by probing specific endpoints or connecting from reported IPs.
reads hb_http_activitysqlSELECT device_hostname, src_endpoint_ip, url_full, user_agent, status_code, time FROM hb_http_activity WHERE (LOWER(url_full) LIKE '%' || LOWER('{{recon_path}}') || '%' OR instr(',' || '{{intruder_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')What a hit looks like. HTTP requests from reported malicious IPs or targeting the getPierDetails endpoint.
-
URL-Encoded API Exploitation
Query · detection candidateDetect attempts to bypass authentication or execute code using URL-encoded slashes in API paths.
reads hb_http_activitysqlSELECT device_hostname, src_endpoint_ip, url_path, url_query, status_code, time FROM hb_http_activity WHERE (url_path LIKE '%%2F%' OR url_query LIKE '%%2F%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')What a hit looks like. Successful requests that include encoded slashes in the path or query, indicating an RCE attempt.
-
Triage Initial Access Attempts
Agent triageAnalyze whether the web activity indicates a successful exploit against the N-central appliance.
-
Stack-count Rare Account Domains
Query · baselineIdentify anomalous accounts by stack-counting email domains, looking for the reported .invalid suffix.
reads hb_auth_signinsqlSELECT LOWER(SUBSTR(actor_user_name, INSTR(actor_user_name, '@') + 1)) AS domain, COUNT(DISTINCT dst_endpoint_name) AS host_count, MIN(time) AS first_seen FROM hb_auth_signin WHERE actor_user_name LIKE '%@%' AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY domain HAVING host_count <= 2 ORDER BY host_count ASCWhat a hit looks like. The .invalid domain or other rare, spoofed domains appearing on only one or two hosts.
-
Cloudflare Tunnel Agent Execution
Query · triageIdentify the Cloudflared process which is a persistent backdoor for the attacker.
reads hb_process_activitysqlSELECT device_hostname, process_name, process_cmd_line, user_name, time FROM hb_process_activity WHERE (LOWER(process_name) LIKE '%cloudflared%' OR LOWER(process_cmd_line) LIKE '%cloudflared%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')What a hit looks like. Processes running the Cloudflared binary on the N-central host, which is not standard for the appliance.
-
Evaluate Breach and Severity
Agent triageCombine evidence of exploitation with subsequent persistence to confirm a breach.
-
Route on Breach Confirmation
DecisionRoute the hunt to immediate isolation if a breach is confirmed.
-
Isolate Compromised N-central Host
Response actionPrevent further lateral movement or data exfiltration.
-
Analyst Forensic Review
Analyst taskConfirm the findings and identify the full scope of the breach.
-
Cleanup and Close
Analyst taskFinalize the hunt and ensure all N-central systems are patched.
Coverage
Scenario coverage
| Stage | Covered | How, or why not |
|---|---|---|
| N-central API Reconnaissance T1190 |
Yes | api-recon-activity |
| Pre-Auth RCE and Auth Bypass T1190 |
Yes | url-encoded-exploit |
| Malicious Account Creation T1136 |
Yes | rare-account-domains |
| Cloudflare Protocol Tunneling T1572 · T1090.003 |
Yes | tunnel-agent-execution |
| Masqueraded Binary in User Folder T1036.005 |
Out of scope | Belongs to another part of the 'Critical N-able N-central Vulnerability and Active Exploitation' series. |
| Abuse of RMM Take Control T1133 |
Out of scope | Belongs to another part of the 'Critical N-able N-central Vulnerability and Active Exploitation' series. |
| Post-Exploitation Process Discovery T1057 |
Out of scope | Belongs to another part of the 'Critical N-able N-central Vulnerability and Active Exploitation' series. |
Blind spots
- Needs Extended retention for N-central appliance logs. Attackers may have exploited the system and rotated relevant logs before the hunt executed. It would answer Did the exploit occur before the 14-day lookback period?.
- Needs TLS decryption for appliance traffic. Without server-side or proxy logging, path-based indicators are invisible to the network. It would answer Are the URL-encoded path traversal attempts visible in the encrypted HTTPS stream?.
Parameters & data
Parameters
| Parameter | Type | Default | What it is |
|---|---|---|---|
intruder_ips | list[ip] | 23.234.100.105, 23.234.97.68, 173.249.252.176, 185.156.46.150, 23.234.94.43, 68.235.46.235, 173.249.252.200 | Known malicious IPs reported in the N-able advisories. |
lookback_days | number | 14 | Days of history to examine. |
recon_path | string | /remoteControlAction.do?method=getPierDetails | Specific endpoint targeted during reconnaissance. |
scope_hosts | list[host] | — | Specific N-central hostnames to target; leave empty to scan the entire estate. |
Telemetry
| Source | Category | Telemetry |
|---|---|---|
| Endpoint telemetry (hb_ surfaces) | endpoint | endpoint |
| Identity / sign-in telemetry | identity | identity |
| Web server / proxy logs | siem | network |
Source
---
analysis: A single rule might alert on Cloudflared, but this hunt correlates initial
web exploitation with the appearance of rare accounts and tunnels, providing context
to confirm a full intrusion chain.
blind_spots:
- id: limited-log-retention
question: Did the exploit occur before the 14-day lookback period?
requires: Extended retention for N-central appliance logs
risk: Attackers may have exploited the system and rotated relevant logs before the
hunt executed.
stage: initial-access-rce
- id: missing-http-decryption
question: Are the URL-encoded path traversal attempts visible in the encrypted HTTPS
stream?
requires: TLS decryption for appliance traffic
risk: Without server-side or proxy logging, path-based indicators are invisible
to the network.
stage: initial-access-rce
coverage:
- stage: reconnaissance-api-probing
status: covered
steps:
- api-recon-activity
- stage: initial-access-rce
status: covered
steps:
- url-encoded-exploit
- stage: persistence-account-manipulation
status: covered
steps:
- rare-account-domains
- stage: persistence-c2-tunneling
status: covered
steps:
- tunnel-agent-execution
- reason: Belongs to another part of the 'Critical N-able N-central Vulnerability
and Active Exploitation' series.
stage: defense-evasion-masquerading
status: out_of_scope
- reason: Belongs to another part of the 'Critical N-able N-central Vulnerability
and Active Exploitation' series.
stage: lateral-movement-rmm-abuse
status: out_of_scope
- reason: Belongs to another part of the 'Critical N-able N-central Vulnerability
and Active Exploitation' series.
stage: discovery-process-enumeration
status: out_of_scope
guardrails:
claims: no_unsupported
evidence: citation_required
missing_data: not_benign
telemetry: untrusted
hunt:
applicability: campaign-specific
handoff: promote-to-detection
justification: N-central RMM tools provide unauthenticated access to thousands of
downstream endpoints. The active zero-day exploitation and high CVSS score make
this a critical operational risk.
methodology: model-assisted
trigger: intel-report
hypothesis: An attacker has exploited unauthenticated N-central web vulnerabilities
to gain administrative control, subsequently establishing persistence through rogue
user accounts and Cloudflare protocol tunnels.
labels:
- hunt
- attack.t1190
- attack.t1133
- attack.t1572
- attack.t1090.003
- attack.t1136
name: N-central Web Exploitation and Persistence
parameters:
intruder_ips:
default:
- 23.234.100.105
- 23.234.97.68
- 173.249.252.176
- 185.156.46.150
- 23.234.94.43
- 68.235.46.235
- 173.249.252.200
description: Known malicious IPs reported in the N-able advisories.
from:
kind: article
observed: '2026-09-06'
ref: https://www.huntress.com/blog/n-able-vulnerability-exploitation
type: list[ip]
lookback_days:
default: '14'
description: Days of history to examine.
type: number
recon_path:
default: /remoteControlAction.do?method=getPierDetails
description: Specific endpoint targeted during reconnaissance.
type: string
scope_hosts:
default: []
description: Specific N-central hostnames to target; leave empty to scan the entire
estate.
type: list[host]
provenance:
authors:
- name: Huntbase hunt generation
org: huntbase.io
generated:
by: huntbase-hunt-generation
from: https://www.huntress.com/blog/n-able-vulnerability-exploitation
gates:
- dry-run
- lint
- critic
model: hb_google/gemini-3-flash-preview
rationale: Narrow the hunt to N-central appliances identified in the software inventory.
Focus on external-facing servers first.
references:
- name: "Huntress \u2014 Critical N-able N-central Vulnerability and Active Exploitation"
url: https://www.huntress.com/blog/n-able-vulnerability-exploitation
related:
- hunt: n-central-lateral-movement-rmm
reason: This hunt identifies the beachhead; a following hunt must track lateral
movement from N-central to downstream endpoints using RMM features.
relation: follows
scenario:
stages:
- name: N-central API Reconnaissance
observables:
- GET /remoteControlAction.do?method=getPierDetails
- 23.234.100.105
- 173.249.252.200
- 185.156.46.150
slug: reconnaissance-api-probing
tactic: reconnaissance
techniques:
- T1190
- name: Pre-Auth RCE and Auth Bypass
observables:
- CVE-2026-86218
- CVE-2026-18556
- CVE-2026-18577
- URL-encoded API requests using %2F
slug: initial-access-rce
tactic: initial-access
techniques:
- T1190
- name: Malicious Account Creation
observables:
- Email addresses appended with '.invalid'
- Usernames with subtle character swaps
- Spoofed domains in email addresses
slug: persistence-account-manipulation
tactic: persistence
techniques:
- T1136
- name: Cloudflare Protocol Tunneling
observables:
- Service name 'Cloudflared'
- 'Cloudflare tunnel account tag: 5568cd69c754b392121f1dbb8f900fda'
slug: persistence-c2-tunneling
tactic: command-and-control
techniques:
- T1572
- T1090.003
- name: Masqueraded Binary in User Folder
observables:
- svchost.exe located in Documents folder
slug: defense-evasion-masquerading
tactic: defense-evasion
techniques:
- T1036.005
- name: Abuse of RMM Take Control
observables:
- MSP Support account session logins
- Take Control session activity (Event IDs 4102, 8192, 8193)
slug: lateral-movement-rmm-abuse
tactic: lateral-movement
techniques:
- T1133
- name: Post-Exploitation Process Discovery
observables:
- Process list requests following exploitation
slug: discovery-process-enumeration
tactic: discovery
techniques:
- T1057
summary: Attackers are exploiting multiple vulnerabilities in N-able N-central,
including a zero-day RCE, to gain unauthenticated access to RMM consoles. Post-exploitation,
they maintain persistence via Cloudflare tunnels and malicious user creation before
using the built-in 'Take Control' feature to move laterally across managed endpoints.
series:
index: 1
slug: critical-n-able-n-central-vulnerability-and-active-exploitation
title: Critical N-able N-central Vulnerability and Active Exploitation
total: 2
severity: high
targets:
analyst:
name: Tier-2 analyst
role: analyst
endpoint:
category: endpoint
name: Endpoint telemetry (hb_ surfaces)
telemetry:
- endpoint
hunter:
agent: true
name: Hunt agent
identity:
category: identity
name: Identity / sign-in telemetry
telemetry:
- identity
web:
category: siem
name: Web server / proxy logs
telemetry:
- network
tlp: clear
type: investigation
---
# N-central Web Exploitation and Persistence
This hunt tracks the September 2026 N-central zero-day campaign. It begins by identifying systems running vulnerable software, then looks for reconnaissance on the pier details endpoint and RCE attempts involving URL-encoded path traversals. Finally, it pivots to find post-exploitation persistence: unauthorized user accounts with anomalous email suffixes and the execution of the Cloudflared tunneling agent.
## identify-ncentral-hosts
<!-- Identify N-central Infrastructure -->
Identify systems running N-central software which may be vulnerable.
```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of hosts acting as N-central appliances. Silence means no N-central
software is installed.
reads:
- device_hostname
- package_name
- package_version
- vendor_name
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, package_name, package_version, vendor_name FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%n-central%' OR LOWER(vendor_name) LIKE '%n-able%')
```
## early-probes
<!-- Initial Probing and Exploitation -->
parallel:
- → api-recon-activity
- → url-encoded-exploit
join: → triage-initial-access
## api-recon-activity
<!-- API Reconnaissance Probes -->
Identify early staging activity where attackers map the environment by probing specific endpoints or connecting from reported IPs.
```sqlite target=web role=enrichment params=(recon_path=recon_path, intruder_ips=intruder_ips, scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: HTTP requests from reported malicious IPs or targeting the getPierDetails
endpoint.
reads:
- device_hostname
- src_endpoint_ip
- url_full
- user_agent
- status_code
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, src_endpoint_ip, url_full, user_agent, status_code, time FROM hb_http_activity WHERE (LOWER(url_full) LIKE '%' || LOWER('{{recon_path}}') || '%' OR instr(',' || '{{intruder_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```
## url-encoded-exploit
<!-- URL-Encoded API Exploitation -->
Detect attempts to bypass authentication or execute code using URL-encoded slashes in API paths.
```sqlite target=web role=detection-candidate params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: Successful requests that include encoded slashes in the path or query, indicating
an RCE attempt.
reads:
- device_hostname
- src_endpoint_ip
- url_path
- url_query
- status_code
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, src_endpoint_ip, url_path, url_query, status_code, time FROM hb_http_activity WHERE (url_path LIKE '%%2F%' OR url_query LIKE '%%2F%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```
## triage-initial-access
<!-- Triage Initial Access Attempts -->
```agent target=hunter
cite: required
context:
- api-recon-activity
- url-encoded-exploit
max_iterations: 3
objective: Determine if any N-central host shows evidence of successful exploitation
via URL-encoded path manipulation or reconnaissance from known malicious IPs.
success_criteria: A verdict for each host citing relevant HTTP requests and status
codes.
tools:
- endpoint
- identity
- web
```
## persistence-hunt
<!-- Hunt for Persistence Markers -->
parallel:
- → rare-account-domains
- → tunnel-agent-execution
join: → evaluate-breach
## rare-account-domains
<!-- Stack-count Rare Account Domains -->
Identify anomalous accounts by stack-counting email domains, looking for the reported .invalid suffix.
```sqlite target=identity role=baseline params=(lookback_days=lookback_days)
~~~yaml
baseline:
compare: first_seen
window: '{{lookback_days}}d'
expected: The .invalid domain or other rare, spoofed domains appearing on only one
or two hosts.
prevalence:
by: dst_endpoint_name
key:
- actor_user_name
rare_below: 3
reads:
- actor_user_name
- dst_endpoint_name
- time
silence: not_evidence_of_absence
source: hb_auth_signin
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT LOWER(SUBSTR(actor_user_name, INSTR(actor_user_name, '@') + 1)) AS domain, COUNT(DISTINCT dst_endpoint_name) AS host_count, MIN(time) AS first_seen FROM hb_auth_signin WHERE actor_user_name LIKE '%@%' AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY domain HAVING host_count <= 2 ORDER BY host_count ASC
```
## tunnel-agent-execution
<!-- Cloudflare Tunnel Agent Execution -->
Identify the Cloudflared process which is a persistent backdoor for the attacker.
```sqlite target=endpoint role=triage params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
expected: Processes running the Cloudflared binary on the N-central host, which is
not standard for the appliance.
reads:
- device_hostname
- process_name
- process_cmd_line
- user_name
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, process_name, process_cmd_line, user_name, time FROM hb_process_activity WHERE (LOWER(process_name) LIKE '%cloudflared%' OR LOWER(process_cmd_line) LIKE '%cloudflared%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```
## evaluate-breach
<!-- Evaluate Breach and Severity -->
```agent target=hunter
cite: required
context:
- triage-initial-access
- rare-account-domains
- tunnel-agent-execution
max_iterations: 4
objective: Determine if any host shows evidence of both unauthenticated API exploitation
and subsequent persistence via rogue accounts or Cloudflare tunnels.
success_criteria: A per-host verdict citing specific rows from the HTTP, Auth, and
Process surfaces.
tools:
- endpoint
- identity
- web
```
## route-breach
<!-- Route on Breach Confirmation -->
if~: "the agent evaluation confirms successful exploitation followed by rogue account creation or tunnel deployment" (confidence: high, judge=hunter)
then: → contain-and-isolate
indeterminate: → analyst-review
unavailable: → analyst-review (blind_spot: limited-log-retention)
else: → close-out
## contain-and-isolate
<!-- Isolate Compromised N-central Host -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the host at the network level, terminate the Cloudflared process, and collect the envoy_proxy_HTTPS.log file.
```
→ analyst-review
## analyst-review
<!-- Analyst Forensic Review -->
```manual target=analyst
Review the identified HTTP sessions and rogue accounts. Audit N-central internal logs for any configuration changes made by the .invalid accounts.
```
→ close-out
## close-out
<!-- Cleanup and Close -->
```manual target=analyst
Ensure all N-central hosts are upgraded to 2026.3 HF4. Document any confirmed IOCs found during the hunt.
```
→ end
Run it
Take this hunt into your environment.
Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.
Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, critic, then reviewed by a person.