# [CRIT] [GHSA / CRITICAL] CVE-2026-49980: Rclone: Unauthenticated command execution in `rclone rcd --rc-serve` via inline remote instantiation, bypassing CVE-2026-41179 fix

**Source:** GitHub Security Advisories
**Published:** 2026-06-16
**Article:** https://github.com/advisories/GHSA-qw24-gh76-8rvv

## Threat Profile

Rclone: Unauthenticated command execution in `rclone rcd --rc-serve` via inline remote instantiation, bypassing CVE-2026-41179 fix

## Summary

`rclone rcd --rc-serve` accepts unauthenticated `GET` and `HEAD` requests to paths of the form:

```text
/[remote:path]/object
```

The `remote` value is parsed from the URL and passed to normal backend initialization. Inline remote configuration can set backend options that execute local commands during initialization. As a result, a single unauthentica…

## Indicators of Compromise (high-fidelity only)

- **CVE:** `CVE-2026-49980`
- **CVE:** `CVE-2026-41179`

## MITRE ATT&CK Techniques

- **T1190** — Exploit Public-Facing Application
- **T1059** — Command and Scripting Interpreter
- **T1203** — Exploitation for Client Execution
- **T1133** — External Remote Services
- **T1189** — Drive-by Compromise

## Kill chain phases observed

_(none detected from narrative keywords)_

## Recommended hunts

### Rclone process spawns command interpreter (CVE-2026-49980 post-exploit)

`UC_20_1` · phase: **exploit** · confidence: **High** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats summariesonly=t count, min(_time) as firstTime, max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.parent_process_name="rclone.exe" OR Processes.parent_process_name="rclone") AND Processes.process_name IN ("cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe","bash","sh","dash","zsh","ksh","python","python3","perl","ruby","node") by host, user, Processes.parent_process_name, Processes.parent_process, Processes.process_name, Processes.process | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("rclone.exe", "rclone")
| where InitiatingProcessCommandLine has_any ("rcd", "--rc-serve", "--rc ", "--rc-addr")
| where FileName in~ ("cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe","bash","sh","dash","zsh","ksh","python","python3","perl","ruby","node")
| project Timestamp, DeviceName, AccountName,
          ParentFolderPath = InitiatingProcessFolderPath,
          ParentCmd = InitiatingProcessCommandLine,
          ChildFolderPath = FolderPath,
          ChildCmd = ProcessCommandLine,
          SHA256
| order by Timestamp desc
```

### Vulnerable rclone --rc-serve deployment without HTTP authentication

`UC_20_2` · phase: **recon** · confidence: **High** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats summariesonly=t count, values(Processes.process) as cmds, min(_time) as firstTime, max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process_name="rclone.exe" OR Processes.process_name="rclone") AND Processes.process="*--rc-serve*" by host, user, Processes.process_name | `drop_dm_object_name(Processes)` | eval cmds_lower=lower(mvjoin(cmds, " || ")) | where NOT match(cmds_lower, "--rc-user|--rc-pass|--rc-htpasswd") | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("rclone.exe", "rclone")
| where ProcessCommandLine has "--rc-serve"
| where not (ProcessCommandLine has_any ("--rc-user", "--rc-pass", "--rc-htpasswd"))
| extend RcAddr = extract(@"--rc-addr[\s=]+(\S+)", 1, ProcessCommandLine)
| project Timestamp, DeviceName, AccountName, FolderPath, ProcessCommandLine, RcAddr, SHA256
| order by Timestamp desc
```

### Rclone RC listener bound to non-loopback interface via --rc-addr

`UC_20_3` · phase: **recon** · confidence: **High** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats summariesonly=t count, values(Processes.process) as cmds, min(_time) as firstTime, max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process_name="rclone.exe" OR Processes.process_name="rclone") AND Processes.process="*--rc-addr*" by host, user, Processes.process_name, Processes.process | `drop_dm_object_name(Processes)` | rex field=process "--rc-addr[\s=]+(?<rc_addr>\S+)" | where NOT match(rc_addr, "(?i)^(127\.0\.0\.1|localhost|\[?::1\]?)(:\d+)?$") | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("rclone.exe", "rclone")
| where ProcessCommandLine has "--rc-addr"
| extend RcAddr = extract(@"--rc-addr[\s=]+(\S+)", 1, ProcessCommandLine)
| where isnotempty(RcAddr)
| where not (RcAddr matches regex @"(?i)^(127\.0\.0\.1|localhost|\[?::1\]?)(:\d+)?$")
| extend NoAuth = not (ProcessCommandLine has_any ("--rc-user", "--rc-pass", "--rc-htpasswd"))
| project Timestamp, DeviceName, AccountName, FolderPath, ProcessCommandLine, RcAddr, NoAuth
| order by NoAuth desc, Timestamp desc
```

### Browser process initiating connection to local rclone RC port 5572

`UC_20_4` · phase: **delivery** · confidence: **Medium** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats summariesonly=t count, min(_time) as firstTime, max(_time) as lastTime from datamodel=Network_Traffic.All_Traffic where (All_Traffic.app IN ("firefox","chrome","msedge","brave","chromium","opera") OR All_Traffic.process_name IN ("firefox.exe","chrome.exe","msedge.exe","brave.exe","chromium.exe","opera.exe","firefox","chrome","chromium","brave")) AND (All_Traffic.dest_ip="127.0.0.1" OR All_Traffic.dest_ip="::1") AND All_Traffic.dest_port=5572 by host, All_Traffic.process_name, All_Traffic.app, All_Traffic.dest_ip, All_Traffic.dest_port | `drop_dm_object_name(All_Traffic)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
```

**Defender KQL:**
```kql
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("firefox.exe","chrome.exe","msedge.exe","brave.exe","opera.exe","chromium.exe","firefox","chrome","chromium","brave","opera")
| where RemoteIP in ("127.0.0.1","::1") and RemotePort == 5572
| project Timestamp, DeviceName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, InitiatingProcessAccountName,
          RemoteIP, RemotePort, RemoteUrl
| order by Timestamp desc
```

### Devices with vulnerable rclone (CVE-2026-49980) in software inventory

`UC_20_5` · phase: **recon** · confidence: **High** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats summariesonly=t count, values(Vulnerabilities.signature) as cves, values(Vulnerabilities.severity) as severity, values(Vulnerabilities.url) as url, min(_time) as firstTime, max(_time) as lastTime from datamodel=Vulnerabilities.Vulnerabilities where Vulnerabilities.signature="CVE-2026-49980" by Vulnerabilities.dest, Vulnerabilities.dest_category | `drop_dm_object_name(Vulnerabilities)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
```

**Defender KQL:**
```kql
let VulnByCve = DeviceTvmSoftwareVulnerabilities
    | where CveId == "CVE-2026-49980"
    | project DeviceId, DeviceName, OSPlatform, SoftwareVendor, SoftwareName, SoftwareVersion, VulnerabilitySeverityLevel, RecommendedSecurityUpdate;
let VulnByInventory = DeviceTvmSoftwareInventory
    | where SoftwareName has "rclone"
    | extend Major = toint(extract(@"^(\d+)\.", 1, SoftwareVersion)),
             Minor = toint(extract(@"^\d+\.(\d+)", 1, SoftwareVersion)),
             Patch = toint(extract(@"^\d+\.\d+\.(\d+)", 1, SoftwareVersion))
    | where Major == 1 and (Minor < 74 or (Minor == 74 and Patch <= 2))
    | where Major == 1 and (Minor > 46 or (Minor == 46 and Patch >= 0))
    | project DeviceId, DeviceName, OSPlatform, SoftwareVendor, SoftwareName, SoftwareVersion, VulnerabilitySeverityLevel = "Critical", RecommendedSecurityUpdate = "Upgrade to rclone 1.74.3+";
union VulnByCve, VulnByInventory
| summarize arg_max(SoftwareVersion, *) by DeviceId
| join kind=leftouter (
    DeviceInfo
    | summarize arg_max(Timestamp, IsInternetFacing, PublicIP) by DeviceId
  ) on DeviceId
| project DeviceName, OSPlatform, SoftwareName, SoftwareVersion, VulnerabilitySeverityLevel, IsInternetFacing, PublicIP, RecommendedSecurityUpdate
| order by IsInternetFacing desc, DeviceName asc
```

### IOC-driven hunts (use shared templates)

These are standard IOC-substitution hunts — the canonical SPL and KQL live once in [`_TEMPLATES.md`](../_TEMPLATES.md), so we don't repeat the same boilerplate on every CVE / hash / network-IOC briefing.

- **Asset exposure — vulnerability matches article CVE(s)** ([template](../_TEMPLATES.md#asset-exposure)) — phase: **recon**, confidence: **High**
  - CVE(s): `CVE-2026-49980`, `CVE-2026-41179`


## Why this matters

Severity classified as **CRIT** based on: CVE present, 6 use case(s) fired, 5 technique(s) inferred. Read the full article for actor attribution, tooling details, and any defanged IOCs in the body that aren't visible in the RSS summary.
