# [CRIT] Lessons from AWS CodeBuild’s Memory-Dump Incident (CVE-2025-8217)

**Source:** StepSecurity
**Published:** 2025-08-09
**Article:** https://www.stepsecurity.io/blog/lessons-from-aws-codebuilds-memory-dump-incident-cve-2025-8217

## Threat Profile

Back to Blog Threat Intel Lessons from AWS CodeBuild’s Memory-Dump Incident (CVE-2025-8217) How threat actors exploited AWS CodeBuild pipelines by stealing secrets from CI/CD memory—and the proactive defenses organizations can deploy to detect, respond to, and prevent such attacks. Jatin Kumar View LinkedIn July 29, 2025
Share on X Share on X Share on LinkedIn Share on Facebook Follow our RSS feed 
Table of Contents Loading nav... 
The July 2025 AWS CodeBuild security incident highlights anew so…

## Indicators of Compromise (high-fidelity only)

- **CVE:** `CVE-2025-8217`
- **CVE:** `CVE-2025-30066`
- **CVE:** `CVE-2025-30154`
- **SHA1:** `0e58ed8671d6b60d0890c21b07f8835ace038e67`

## MITRE ATT&CK Techniques

- **T1190** — Exploit Public-Facing Application
- **T1059.001** — PowerShell
- **T1027** — Obfuscated Files or Information
- **T1219** — Remote Access Software
- **T1195.002** — Compromise Software Supply Chain
- **T1003.007** — OS Credential Dumping: Proc Filesystem
- **T1552.001** — Unsecured Credentials: Credentials In Files
- **T1195.002** — Supply Chain Compromise: Compromise Software Supply Chain

## Kill chain phases observed

_(none detected from narrative keywords)_

## Recommended hunts

### Linux process opens /proc/<pid>/mem or /proc/<pid>/maps on a build/CI host (CVE-2025-8217 / CVE-2025-30066 memory dump TTP)

`UC_823_5` · phase: **actions** · confidence: **High** · AI-generated for this article

**Splunk SPL (CIM):**
```spl
| tstats `summariesonly` count min(_time) as firstTime max(_time) as lastTime values(Filesystem.process_name) as process_name values(Filesystem.process_path) as process_path values(Filesystem.process_id) as process_id values(Filesystem.user) as user values(Filesystem.file_path) as file_path from datamodel=Endpoint.Filesystem where (Filesystem.file_path="/proc/*/mem" OR Filesystem.file_path="/proc/*/maps") Filesystem.process_name!=gdb Filesystem.process_name!=lldb Filesystem.process_name!=strace Filesystem.process_name!=ltrace Filesystem.process_name!=perf Filesystem.process_name!=systemd-coredump Filesystem.process_name!=gcore Filesystem.process_name!=valgrind Filesystem.process_name!=apport by Filesystem.dest Filesystem.process_name Filesystem.process_id Filesystem.file_path | `drop_dm_object_name(Filesystem)` | rex field=file_path "^/proc/(?<accessed_pid>\d+)/(mem|maps)$" | where accessed_pid!=process_id | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | sort 0 - lastTime
```

**Defender KQL:**
```kql
// Linux-only — /proc is a Linux concept. Restrict to Linux endpoints (CI runners, build agents).
let _linux_hosts = DeviceInfo
    | where Timestamp > ago(1d)
    | where OSPlatform == "Linux"
    | summarize by DeviceId;
let _debuggers = dynamic(["gdb","lldb","strace","ltrace","perf","systemd-coredump","gcore","valgrind","apport","abrt-hook-ccpp","crash"]);
DeviceFileEvents
| where Timestamp > ago(7d)
| where DeviceId in (_linux_hosts)
// Article's Python payload: open('/proc/{pid}/maps','r') and open('/proc/{pid}/mem','rb')
| where FolderPath matches regex @"^/proc/\d+/?$"
| where FileName in~ ("mem","maps")
| where InitiatingProcessFileName !in~ (_debuggers)
// Exclude self-introspection (process reading /proc/self/* — common in libc/golang runtimes)
| extend AccessedPid = extract(@"^/proc/(\d+)", 1, FolderPath)
| where AccessedPid != tostring(InitiatingProcessId)
| project Timestamp, DeviceName, InitiatingProcessAccountName,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessFolderPath, InitiatingProcessParentFileName,
          FolderPath, FileName, AccessedPid, InitiatingProcessSHA256
| order by Timestamp desc
```

### PowerShell encoded / obfuscated command

`UC_PS_OBFUSCATED` · phase: **exploit** · confidence: **High**

**Splunk SPL (CIM):**
```spl
| tstats `summariesonly` count min(_time) as firstTime max(_time) as lastTime
    from datamodel=Endpoint.Processes
    where Processes.process_name IN ("powershell.exe","pwsh.exe")
      AND (Processes.process="*-enc *" OR Processes.process="*EncodedCommand*"
        OR Processes.process="*FromBase64String*" OR Processes.process="*-nop*"
        OR Processes.process="*-w hidden*" OR Processes.process="*Invoke-Expression*"
        OR Processes.process="*IEX(*" OR Processes.process="*DownloadString*"
        OR Processes.process="*Net.WebClient*")
    by Processes.dest, Processes.user, Processes.process_name, Processes.process, Processes.parent_process_name
| `drop_dm_object_name(Processes)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(7d)
| where AccountName !endswith "$"
| where FileName in~ ("powershell.exe","pwsh.exe")
| where ProcessCommandLine matches regex @"(?i)(-enc|encodedcommand|frombase64string|-nop|-w\s+hidden|invoke-expression|iex\s*\(|downloadstring|net\.webclient)"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine
```

### RMM tool installed by non-IT user — remote-access utility for hands-on-keyboard

`UC_RMM_TOOLS` · phase: **install** · confidence: **High**

**Splunk SPL (CIM):**
```spl
| tstats `summariesonly` count min(_time) as firstTime max(_time) as lastTime
    from datamodel=Endpoint.Processes
    where Processes.process_name IN ("AnyDesk.exe","TeamViewer.exe","TeamViewer_Service.exe",
        "ScreenConnect.ClientService.exe","ConnectWiseControl.ClientService.exe",
        "atera_agent.exe","SplashtopStreamer.exe","RustDesk.exe","NinjaOne.exe","kaseya*.exe")
    by Processes.dest, Processes.user, Processes.process_name, Processes.process, Processes.parent_process_name
| `drop_dm_object_name(Processes)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(7d)
| where AccountName !endswith "$"
| where FileName in~ ("AnyDesk.exe","TeamViewer.exe","TeamViewer_Service.exe",
        "ScreenConnect.ClientService.exe","ConnectWiseControl.ClientService.exe",
        "atera_agent.exe","SplashtopStreamer.exe","RustDesk.exe","NinjaOne.exe")
   or FileName matches regex @"(?i)kaseya.*\.exe"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
```

### Trusted vendor binary / installer launching unusual children

`UC_SUPPLY_CHAIN` · phase: **exploit** · confidence: **Medium**

**Splunk SPL (CIM):**
```spl
| tstats `summariesonly` count min(_time) as firstTime max(_time) as lastTime
    from datamodel=Endpoint.Processes
    where Processes.parent_process_name IN ("setup.exe","installer.exe","update.exe")
      AND Processes.process_name IN ("powershell.exe","cmd.exe","rundll32.exe","regsvr32.exe","mshta.exe","wscript.exe","cscript.exe","wmic.exe","bitsadmin.exe")
    by Processes.dest, Processes.user, Processes.parent_process_name, Processes.process_name, Processes.process
| `drop_dm_object_name(Processes)`
```

**Defender KQL:**
```kql
DeviceProcessEvents
| where Timestamp > ago(7d)
| where AccountName !endswith "$"
| where InitiatingProcessFileName in~ ("setup.exe","installer.exe","update.exe")
| where FileName in~ ("powershell.exe","cmd.exe","rundll32.exe","regsvr32.exe","mshta.exe","wscript.exe","cscript.exe","wmic.exe","bitsadmin.exe")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
```

### 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-2025-8217`, `CVE-2025-30066`, `CVE-2025-30154`

- **File hash IOCs — endpoint file/process match** ([template](../_TEMPLATES.md#hash-ioc)) — phase: **install**, confidence: **High**
  - file hash IOC(s): `0e58ed8671d6b60d0890c21b07f8835ace038e67`


## Why this matters

Severity classified as **CRIT** based on: CVE present, IOCs present, 6 use case(s) fired, 8 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.
