A complete walkthrough of the methodology applied to a real training scenario: pharmaceutical IP theft, dual entry points, and a DCSync that changes everything.

All organizations, names, and data are fictional. This is training assignment A01 from the CTI as a Code repository.
Based on the methodology: “CTI as a Code”
Format: CSV
Contains: IT admin phishing delivery, Oct 15–24
Format: JSON
Contains: IT admin Azure AD sign-ins — Istanbul token replay
Format: JSONL
Contains: CFO workstation — PowerShell, LSASS, persistence, BITS
Format: JSONL
Contains: DC01 security events — DCSync EID 4662
Format: CSV
Contains: Perimeter firewall flows — 381 MB exfil confirmed
Format: JSONL
Contains: SQL Server audit — full xp_cmdshell exfil chain

Download the report to VS Code:
After execution completes, click Export → JSON in ANY.RUN. Save it as:
03-analysis/sandbox-svchost32-anyrun.json
Open in VS Code: press Shift+Alt+F to format. Use Ctrl+Shift+O (Outline) to navigate, Ctrl+F to search:
Search term What you find
destination_ip91.211.251.245 — real C2 IP, port 443
urlhttps://91.211.251.245/ga.js — Malleable C2 profile mimicking Google AnalyticsCookieBase64-encoded beacon metadata in the HTTP Cookie header
User-AgentMozilla/4.0 (compatible; MSIE 8.0...) — hardcoded CS UA string
ProxyServerBeacon installs proxy settings pointing to C2
long-sleepsVT tag — beacon sleeps between check-ins (configurable interval)
The Cobalt Strike Malleable C2 profile: the beacon GETs /ga.js — a path that mimics Google Analytics JavaScript. The Cookie header carries AES-encrypted metadata (victim hostname, PID, username) base64-encoded. The response body delivers shellcode or tasks. A defender looking only at the URL sees legitimate-looking traffic; the anomaly is the 443 connection to a non-Google IP.
Add the C2 IP to ioc-queries.http and click Send Request on the VT and Shodan blocks to pivot immediately.
Found IOCs
- Hash (SHA256) 1cf56da38e5fe05fd2242ff49bafa4271c5ee0868887bf91dafb6f47d1e46ae9 — Cobalt Strike beacon; 48/75 VT detections
- Hash (MD5) cd59d54a7af500f96aa0347bb5daf077 — same sample
- IP 91.211.251.245:443 — real C2 server; HTTPS; confirmed in sandbox network traffic
- URL https://91.211.251.245/ga.js — Malleable C2 endpoint; mimics Google Analytics
- Indicator Cookie-encoded beacon — AES-encrypted victim metadata in HTTP Cookie header
- Indicator long-sleeps — beacon interval; time between C2 check-ins
12. Static Binary Analysis — Hex Editor + Terminal
Open the binary in VS Code Hex Editor:
In VS Code Explorer, right-click svchost32.exe → Open With → Hex Editor
The file opens as a hex+ASCII dual-pane view. The ASCII column on the right makes string hunting visual — scroll through it and strings like /ga.js and Mozilla/4.0 are readable directly without running strings.
Navigate to the PE timestamp:
Press Ctrl+G → type 3C → Enter. This is the e_lfanew field (PE header pointer). Read the 4-byte little-endian value, convert to decimal — that is the offset to the PE signature (PE\0\0). Go to that offset + 8 for the TimeDateStamp field.
For precise extraction, split the screen: keep Hex Editor on the left, open the integrated terminal on the right:
python3 -c "
import pefile, datetime, os
pe = pefile.PE('svchost32.exe')
ts = pe.FILE_HEADER.TimeDateStamp
print(f'Compile timestamp : {datetime.datetime.fromtimestamp(ts, datetime.UTC)} UTC')
print(f'File size on disk : {os.path.getsize(\"svchost32.exe\"):,} bytes')
print(f'PE SizeOfImage : {pe.OPTIONAL_HEADER.SizeOfImage:,} bytes')
overlay = os.path.getsize('svchost32.exe') - pe.OPTIONAL_HEADER.SizeOfImage
if overlay > 0:
print(f'Overlay detected : {overlay:,} bytes after PE end')
print(f'Architecture : {\"x64\" if pe.FILE_HEADER.Machine == 0x8664 else \"x86\"}')
"
Output:
Compile timestamp : 2026-05-15 13:55:55 UTC
File size on disk : 783,320 bytes
Overlay detected : present
Architecture : x64
The PE timestamp (2026-05-15) is plausible and recent — this binary was freshly compiled, not timestomped. The presence of an overlay (data appended after the PE image end) is a Cobalt Strike loader signature: the encrypted beacon shellcode is stored in the overlay and unpacked at runtime.
Extract C2 strings:
strings -n 8 svchost32.exe | grep -E "(https?://|/ga\.js|Mozilla|Cookie|User-Agent|Cache-Control)"
Output includes:
/ga.js
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.1)
Cache-Control: no-cache
The /ga.js path and the MSIE 8.0 User-Agent are configuration strings baked into the Cobalt Strike beacon's Malleable C2 profile at compile time. Any sample sharing these exact strings was built from the same profile.
Check imports — Cobalt Strike loaders minimise their import table:
python3 -c "
import pefile
pe = pefile.PE('svchost32.exe')
print(f'Architecture: {hex(pe.FILE_HEADER.Machine)}')
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
for lib in pe.DIRECTORY_ENTRY_IMPORT:
fns = [i.name.decode() if i.name else f'ord_{i.ordinal}' for i in lib.imports]
print(f'{lib.dll.decode()}: {fns}')
else:
print('No standard import table — uses dynamic API resolution (common in CS loaders)')
"
A Cobalt Strike loader typically has a minimal or absent import table — it resolves APIs at runtime using LoadLibrary/GetProcAddress or custom hash-walking to avoid static analysis. If the import table is empty, that itself is the finding.
Pivot on the Malleable C2 profile strings — search VT for other samples using the same profile:
Add to ioc-queries.http:
### VT — search for samples sharing the same Malleable C2 User-Agent string
GET https://www.virustotal.com/api/v3/intelligence/search?query=content%3A%22MSIE+8.0%22+content%3A%22%2Fga.js%22+type%3Apeexe
x-apikey: {{VT_KEY}}
Found IOCs
- Hash (SHA256) 1cf56da38e5fe05fd2242ff49bafa4271c5ee0868887bf91dafb6f47d1e46ae9 — Cobalt Strike beacon
- Hash (MD5) cd59d54a7af500f96aa0347bb5daf077
- IP 91.211.251.245 — C2 server; confirmed in binary strings and sandbox network traffic
- URL pattern /ga.js — Malleable C2 endpoint; Google Analytics impersonation
- String Mozilla/4.0 (compatible; MSIE 8.0...) — hardcoded CS User-Agent; pivot on VT content search
- Indicator Overlay section — encrypted shellcode stored after PE image end; Cobalt Strike loader signature
- Indicator Minimal import table — dynamic API resolution; evades import-based static detection13. Infrastructure Pivot — REST Client + Global Search
13. Infrastructure Pivot — REST Client + Global Search
The ioc-queries.http file already contains the Shodan, crt.sh, and RDAP blocks. Click through them.
For the crt.sh response: press Ctrl+F in the response pane, search name_value. Two new domains appear: cdn-telemetry-update.biz and windows-cdn-service.net.
Immediately pivot in VS Code global search:
Press Ctrl+Shift+F, type cdn-telemetry-update:
palo-alto/dns-queries.csv → (no results)
Not in the org’s DNS logs — but add both new domains to the IOC list in case they appear in a broader hunt.
For the RDAP response (AiTM domain): Ctrl+F → registration → date 2024-10-18. The phishing email was sent 4 days later. Targeted, purpose-built infrastructure.
Found IOCs
- Domain cdn-telemetry-update.biz — New; crt.sh co-hosted on 203.0.113.87; not yet in org DNS logs
- Domain windows-cdn-service.net — New; crt.sh co-hosted on 203.0.113.87; not yet in org DNS logs
- Date 2024-10-18 — Registration date of mfa-lifetechpharma.com; 4 days before phishing
14. Splunk Correlation (SIEM Validation)
Load the evidence into Splunk from the VS Code integrated terminal to validate that the Sigma rules fire on the real evidence:
/opt/splunk/bin/splunk add oneshot sysmon/WS-CFO-01-sysmon.jsonl \
-sourcetype sysmon_json -index endpoint -host WS-CFO-01
/opt/splunk/bin/splunk add oneshot windows-security/DC01-security.jsonl \
-sourcetype wineventlog -index wineventlog -host DC01
/opt/splunk/bin/splunk add oneshot windows-security/SERVER-RD-02-security.jsonl \
-sourcetype wineventlog -index wineventlog -host SERVER-RD-02
/opt/splunk/bin/splunk add oneshot palo-alto/ngfw-flows.csv \
-sourcetype pan:traffic -index firewall -host pa-3260
/opt/splunk/bin/splunk add oneshot palo-alto/dns-queries.csv \
-sourcetype pan:dns -index firewall -host pa-3260
/opt/splunk/bin/splunk add oneshot sql-audit/SERVER-RD-02-sql-audit.jsonl \
-sourcetype mssql_audit -index database -host SERVER-RD-02
Query 1 — triage: C2 IPs across all indexes:
index=* (203.0.113.87 OR 198.51.100.44) earliest=-30d
| stats count by host, sourcetype, index
| sort -count
Query 2 — DCSync from non-DC (DET-002 validation):
index=wineventlog EventCode=4662
ObjectType="{19195a5b-6da0-11d0-afd3-00c04fd930c9}"
| where NOT match(IpAddress, "^10\.10\.1\.(10|11)$")
| table _time, host, SubjectUserName, IpAddress, ObjectName, Properties
Query 3 — service account off-hours (DET-003 validation):
index=wineventlog EventCode=4624 LogonType=3
TargetUserName=svc_backup
| eval hour=strftime(_time, "%H")
| where hour < 6 OR hour > 22
| table _time, host, TargetUserName, IpAddress | sort _time
Query 4 — exfil scope:
index=wineventlog EventCode=4663 ObjectName="*USPartner2024*"
| stats count as files_accessed, min(_time) as first, max(_time) as last by SubjectUserName, host
Query 5 — full 24-day timeline:
index=* earliest=2024-10-22 latest=2024-11-16
(host=WS-IT-LEVI OR host=WS-CFO-01 OR host=SERVER-RD-02 OR host=DC01)
| eval summary=coalesce(Message, Statement, query, CommandLine, "event")
| table _time, host, sourcetype, summary | sort _time
Found IOCs
- IP 203.0.113.87 — SIEM-validated; C2 traffic confirmed across endpoint and network indexes
- IP 198.51.100.44 — SIEM-validated; exfil traffic confirmed across endpoint and network indexes
- Account svc_backup — DET-002: DCSync from 10.10.3.22 (non-DC); DET-003: off-hours logon
- File pattern USPartner2024* (47 files) — DET-004: bulk access by svc_backup on SERVER-RD-02
- Indicator Off-hours logon — EID 4624 / LogonType 3 outside 06:00–22:00 window
Commit all analysis artifacts
git add 03-analysis/
git commit -m "PROJ-2024-001: evidence analysis — VS Code investigation complete; REST Client queries, RBQL, binary hex analysis, DCSync confirmed, exfil 381MB corroborated in 3 sources"
The timeline in Step R2 is now fully supported. Every event in the table has a source log opened in VS Code, a query or search that confirmed it, and a REST Client or terminal command a third party can replay independently.
Step R2: Timeline — Two Paths, One Actor
1. Open the timeline file
nano 03-analysis/timeline/timeline.md
The template has a header block and a markdown table. Fill the header first:
Project: PROJ-2024-001
Analyst: [your name]
Last updated: 2024-11-15
Time range: 2024-10-18 – 2024-11-15
Evidence label key: CONFIRMED / CORROBORATED / INFERRED / HYPOTHESIZED / GAP
Then add one row per event. Every row needs: timestamp (UTC), host, what happened, which log source you saw it in, an evidence label, and the ATT&CK technique. If you do not have a technique yet, leave it blank and come back — do not skip the label.
2. Add events in chronological order
The timeline reveals what the CFO alert obscured: the breach started 24 days earlier through a completely different person.

- 2024–10–18 — External
lifetechpharma-corp[.]eu registered as a typosquat domain.
Source: OSINT
Label: CONFIRMED
ATT&CK: T1583.001
Notes: Pre-attack infrastructure preparation. - 2024–10–22 11:23 — Exchange
Phishing email sent to p.levi: “MFA Re-enrollment Required” with AiTM HTML attachment.
Source: M365 ATP
Label: CONFIRMED
ATT&CK: T1566.001
Notes: ATP SCL=4, delivered; threshold was 5. - 2024–10–22 11:31 — WS-IT-LEVI
Unknown activity — GAP-001 begins.
Source: —
Label: GAP
ATT&CK: —
Notes: Sysmon forwarder stopped. - 2024–10–24 02:17 — Azure AD + VPNVPN login as p.levi from Istanbul, Turkey, using hosting/VPS ASN. No MFA challenge recorded. Session lasted 1h 12min.
Source: Azure AD sign-in
Label: CONFIRMED
ATT&CK: T1557, T1133
Notes: 4:17 AM local time; Paz Levi lives in Rehovot. - 2024–10–24 02:19 — DC01
EID 4624: network logon for svc_backup from WS-IT-LEVI / 10.10.3.22. Service account used outside business hours.
Source: Windows Security / Splunk
Label: CONFIRMED
ATT&CK: T1078.002
Notes: svc_backup has Domain Admin rights. - 2024–10–25 03:41 — SERVER-FIN-01
svc_backup accessed \\SERVER-FIN-01\\FinanceReports\\2024\\.
Source: File share audit, partial
Label: CORROBORATED
ATT&CK: T1039
Notes: Log incomplete — access timestamp only, not filenames. - 2024–11–01 09:14 — WS-IT-LEVI
GAP-001 ends. First DNS query to telemetry-cdn-services[.]biz resolving to 203.0.113.87. First C2 beacon from this host.
Source: Palo Alto DNS
Label: CONFIRMED
ATT&CK: T1071.001
Notes: Sysmon service and forwarder restarted at the same time — probable anti-forensics. - 2024–11–01 09:18 — SERVER-RD-02
EID 4624: svc_backup SMB Type 3 logon from WS-IT-LEVI.
Source: Windows Security
Label: CONFIRMED
ATT&CK: T1021.002
Notes: Occurred four minutes after C2 reconnection. - 2024–11–06 02:09 — SERVER-RD-02
EID 4624: svc_backup SMB logon from WS-IT-LEVI.
Source: Windows Security
Label: CONFIRMED
ATT&CK: T1021.002
Notes: Off-hours access. - 2024–11–06 02:10–02:14 — SERVER-RD-02
EID 4663 ×47: svc_backup accessed all 47 files in \\USPartner2024\\. Read activity occurred and modified timestamps were updated.
Source: Windows Security
Label: CONFIRMED
ATT&CK: T1039
Notes: Each file was individually accessed; timestamp modification suggests deliberate metadata manipulation. - 2024–11–06 02:14 — SERVER-RD-02
EID 5156: outbound HTTPS from SERVER-RD-02 to external IP over port 443 during the file access window.
Source: Windows Security + firewall
Label: CONFIRMED
ATT&CK: T1041
Notes: Destination IP confirmed in Palo Alto NGFW log: 198.51.100.44; separate C2 from primary. - 2024–11–06 02:48 — DC01
EID 4662: svc_backup requested DS-Replication-Get-Changes on DC01.
Source: Windows Security
Label: CONFIRMED
ATT&CK: T1003.006
Notes: DCSync indicator. Pentest scope did not include DCSync. Pentest VLAN is 10.10.99.0/24; this event came from 10.10.3.22. - 2024–11–15 17:58 — Exchange
Phishing email sent to m.cohen, the CFO: “Q4-2024 Licensing Agreement” with .xlsm attachment. SPF, DKIM, and DMARC all failed.
Source: M365 Message Trace
Label: CONFIRMED
ATT&CK: T1566.001
Notes: Second entry point — 24 days after the first. - 2024–11–15 18:42 — WS-CFO-01
Outlook spawned PowerShell with -NonI -W Hidden -Enc, downloading a second-stage payload from 203.0.113.87.
Source: CrowdStrike + Sysmon EID 1
Label: CONFIRMED
ATT&CK: T1059.001
Notes: Triggering alert. - 2024–11–15 18:46–20:52 — WS-CFO-01
LSASS memory access observed via Sysmon EID 10 with GrantedAccess 0x1010. Persistence added via Registry Run Key and scheduled task. BITS downloaded a second-stage binary.
Source: Sysmon EID 10/11/13, EID 4698
Label: CONFIRMED
ATT&CK: T1003.001, T1547.001, T1053.005, T1197
Notes: svchost32.exe dropped to AppData\\Roaming. - 2024–11–15 20:52 — SERVER-FIN-01
WMI lateral movement observed: WmiPrvSE spawned PowerShell with -Enc and a different base64 payload.
Source: CrowdStrike
Label: CONFIRMED
ATT&CK: T1021.003, T1059.001
Notes: svc_finreport credentials used. - 2024–11–15 21:01 — SERVER-FIN-01
Finance data staged: FR_2024_consolidated.zip created in C:\\Windows\\Temp\\.
Source: CrowdStrike EID 11
Label: CONFIRMED
ATT&CK: T1039, T1560
Notes: 2.8 MB upload confirmed in firewall logs at 21:14. - 2024–11–15 21:14 — WS-CFO-01
wevtutil.exe cl Security executed, partially clearing the Windows Security log.
Source: CrowdStrike
Label: CONFIRMED
ATT&CK: T1070.001
Notes: Sysmon log remained intact because it was protected.
The evidence label system matters here. Event 12 (DCSync) is CONFIRMED — it exists in DC01’s Windows Security log, forwarded to Splunk, from an IP that is definitively WS-IT-LEVI and definitively not the pentest VLAN. That cannot be waved away as “possible pentest activity.” Event 6 (finance server access) is CORROBORATED — single source with incomplete log — and can only appear in the technical report with an explicit qualifier, not in the executive brief as a stated fact.
3. Save and commit
git add 03-analysis/timeline/timeline.md
git commit -m "PROJ-2024-001: timeline — 18 events Oct 18–Nov 15, dual-path confirmed, GAP-001 bounds established"
Step R3: Claims Ledger — Every Assertion Traced to Evidence
1. Open the claims ledger
nano 03-analysis/claims/claims-ledger.md
The template has a table with six columns: ID, Claim, Evidence, Confidence, Competing Hypotheses, PIR. Start with an empty row for each major assertion you identified in the timeline — then fill each one completely before moving to the next.
For each row, answer these five questions before typing a word:
- What is the exact assertion? (One sentence, falsifiable — could in principle be proven false)
- Which file and line number is the evidence in? (Not “we saw in Splunk” — the actual log reference)
- What confidence level and why? (High / Medium / Low / Insufficient — with explicit rationale)
- What alternative explanations were considered — and why were they ruled out or left open?
- Which PIR does this answer?
If you cannot answer question 4, the claim is not ready to write. Think first.
2. Fill in one claim per confirmed technique or PIR answer
The claims ledger converts the timeline into auditable, falsifiable assertions. Each claim answers five questions: what, evidence, confidence, competing hypotheses, which PIR.

CL-001 — Initial access via AiTM phishing against IT admin p.levi
- Claim: Initial access was via AiTM phishing against IT admin p.levi on October 22, 2024.
- Evidence: M365 ATP log shows AiTM HTML lure delivered at 11:23 and opened at 11:31. VPN login from Istanbul occurred at 02:17 on October 24 with no MFA challenge, indicating likely stolen session token replay.
- Confidence: High
- Competing Hypotheses: Credential purchase or insider activity cannot be fully ruled out without WS-IT-LEVI disk forensics, which is blocked by legal hold. However, the AiTM lure plus token replay pattern is more parsimonious.
- PIR: PIR-002
CL-002 — Use of svc_backup Domain Admin credentials to access formula files
- Claim: The adversary used svc_backup Domain Admin credentials to access SERVER-RD-02 and the formula files.
- Evidence: EID 4624 on SERVER-RD-02 shows svc_backup Type 3 logon from WS-IT-LEVI. EID 4663 occurred 47 times on formula files.
- Confidence: High
- Competing Hypotheses: Legitimate backup operation is ruled out because backup jobs run from SERVER-WSUS-01 / 10.10.4.x, not from WS-IT-LEVI. The timestamp, 02:09 UTC, is outside the maintenance window.
- PIR: PIR-002
CL-003 — Exfiltration of 47 formula files on November 6, 2024
- Claim: The 47 formula files in USPartner2024 were exfiltrated on November 6, 2024.
- Evidence: EID 4663 occurred 47 times, showing file access. EID 5156 shows outbound HTTPS from SERVER-RD-02 at the same time. Palo Alto NGFW flow shows 10.10.2.15 → 198.51.100.44:443, with 381 MB outbound between 02:14 and 02:19 UTC.
- Confidence: High
- Competing Hypotheses: File access for indexing or backup is ruled out because no backup job ran at this time. The 381 MB outbound volume matches the compressed formula package. The destination IP is not in the allowlist and resolves to a VPS hosting provider.
- PIR: PIR-001 — ANSWERED: YES
CL-004 — DCSync executed via svc_backup on November 6
- Claim: DCSync was executed via svc_backup Domain Admin rights on November 6 at 02:48 UTC.
- Evidence: DC01 EID 4662 shows DS-Replication-Get-Changes GUID from 10.10.3.22, which is WS-IT-LEVI. The subject username was svc_backup.
- Confidence: High
- Competing Hypotheses: Legitimate AD replication is ruled out because the event originated from a workstation IP, not a domain controller. Authorized pentest scope explicitly excluded DCSync and used only 10.10.99.x IPs.
- PIR: PIR-003
CL-005 — CFO path and IT admin path are same threat actor
- Claim: Path A, involving the CFO on November 15, and Path B, involving the IT admin on October 22, are attributable to the same threat actor.
- Evidence: Both svchost32.exe and UpdateHelper.dll share the same fake PE compile timestamp: 2018-04-09. The secondary C2 sys-update-cdn[.]net was hard-coded in the CFO implant and also used in SERVER-RD-02 DNS activity.
- Confidence: High
- Competing Hypotheses: Coincidence would require two separate actors to target the same organization at the same time using a near-identical toolchain. This is extremely implausible.
- PIR: PIR-002
CL-006 — Full domain compromise via DCSync
- Claim: The adversary achieved full domain compromise via DCSync. All Active Directory credentials must be treated as compromised.
- Evidence: CL-004 confirms DCSync activity. svc_backup held Domain Admin rights. DCSync requests included krbtgt and privileged account hashes.
- Confidence: High
- Competing Hypotheses: DCSync may have been partial or failed, but this cannot be confirmed without full DC01 log access. Treating the environment as fully compromised is the conservative and operationally correct response until disproven.
- PIR: PIR-003
CL-003 is the pivotal claim. The US partner’s formulas are gone. That drives the PIR-001 answer and the entire notification timeline. CL-004 and CL-006 change the scope of remediation from “contain these three hosts” to “rotate all AD credentials, treat all 80 servers as potentially compromised.”
3. Update project.yml PIR status
When a PIR is answered, open project.yml and change the status field immediately:
nano project.yml
Change:
- id: PIR-001
status: open
To:
- id: PIR-001
status: answered # CL-003 — exfiltration confirmed, 381 MB, Nov 6
4. Commit the claims ledger
git add 03-analysis/claims/claims-ledger.md project.yml
git commit -m "PROJ-2024-001: claims — 6 claims; PIR-001 ANSWERED YES (CL-003 exfil confirmed); PIR-003 CONFIRMED ONGOING (CL-006 DCSync)"
Step R4: ATT&CK Mapping — Where Detection Failed
1. Open the ATT&CK mapping file
nano 03-analysis/attck-mapping/attck-mapping.md
For each technique you identified in the timeline, add one row. The four columns that matter most operationally are: Confidence (how sure are you the technique was used), Rule Fired? (yes/no/partial — check your SIEM), and Gap Type (what kind of work is needed to close this detection hole).
Gap types: Rule missing / Data source missing / Coverage incomplete / Architectural gap. Pick one. If you are unsure, write your best guess and flag it for SOC review.
Also update project.yml — fill the attck_techniques list:
nano project.yml
scope:
attck_techniques:
- T1566.001
- T1557
- T1133
- T1078.002
- T1059.001
- T1003.001
- T1003.006
- T1021.003
- T1197
- T1047
- T1070.001
- T1547.001
2. Fill one row per technique

T1566.001 — Phishing attachment, CFO .xlsm
- Evidence: M365 ATP log
- Confidence: High
- Rule Fired?: Partial — ATP delivered; SCL=4, threshold=5
- Gap Type: Coverage incomplete — SCL threshold tuning
T1557 — AiTM credential theft, IT admin
- Evidence: VPN login pattern + AiTM HTML lure
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — no AiTM session token detection
T1133 — VPN access with stolen credentials
- Evidence: VPN log: Istanbul, off-hours, no prior history
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — no anomalous VPN authentication alert
T1078.002 — Valid account abuse, svc_backup
- Evidence: EID 4624, multiple events
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — service account off-hours logon undetected
T1059.001 — Encoded PowerShell, both hosts
- Evidence: Sysmon EID 1, CrowdStrike
- Confidence: High
- Rule Fired?: Yes, CFO only, via CrowdStrike behavioral detection
- Gap Type: Coverage incomplete — CFO only; IT admin host fired no alert
T1003.001 — LSASS memory access
- Evidence: Sysmon EID 10, GrantedAccess 0x1010
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — Sysmon EID 10 not alerted on
T1003.006 — DCSync
- Evidence: DC01 EID 4662
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — EID 4662 audit configured but no alert rule
T1021.003 — WMI lateral movement to SERVER-FIN-01
- Evidence: CrowdStrike: WmiPrvSE → PowerShell
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — WmiPrvSE parent alert not deployed
T1197 — BITS download, second stage
- Evidence: Sysmon EID 1, bitsadmin
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — BITS external download not monitored
T1047 — WMI execution, lateral movement
- Evidence: CrowdStrike log
- Confidence: High
- Rule Fired?: No
- Gap Type: Data source missing — WMI logging not in SIEM
T1070.001 — Event log cleared
- Evidence: CrowdStrike EID 1102
- Confidence: High
- Rule Fired?: No
- Gap Type: Rule missing — wevtutil alert not deployed
T1547.001 — Registry Run Key persistence
- Evidence: Sysmon EID 13
- Confidence: High
- Rule Fired?: No
- Gap Type: Coverage incomplete — EID 13 ingested but no alert rule on AppData\\Roaming paths
The gap taxonomy tells the engineering team exactly what work is required:
- Rule missing (7 techniques): Data is in SIEM. A detection engineer can write and deploy the rule. These are sprint items.
- Coverage incomplete (3 techniques): Rule or data exists but is mis-tuned or partial. These require tuning, not new infrastructure.
- Data source missing (1 technique): WMI execution logging is not in the SIEM. This requires an infrastructure change before rules can be written.
The DCSync gap (T1003.006) is particularly stark: the Advanced Audit Policy that generates EID 4662 was correctly configured on DC01, the event was forwarded to Splunk, and the event was visible in Splunk. There was no alert rule. A single Splunk search rule on source=WinEventLog:Security EventCode=4662 ObjectType="{19195a5b-6da0-11d0-afd3-00c04fd930c9}" from a non-DC IP would have fired and contained this incident before the formula exfiltration.
3. Commit the ATT&CK mapping
git add 03-analysis/attck-mapping/attck-mapping.md project.yml
git commit -m "PROJ-2024-001: ATT&CK mapping — 12 techniques, 7 rule-missing, 3 coverage-incomplete, 1 data-source-missing, 1 arch-gap"
Step R5: Attribution Assessment — Same Actor or Two?
1. Open the attribution file
nano 03-analysis/attribution/attribution.md
Write attribution only after the claims ledger is complete. The attribution file has three sections: evidence for unification (or separation), confidence ladder scoring, and the exact language to use in deliverables. Fill them in that order.
Do not start with a hypothesis. Start with the evidence you have from the claims ledger, then see where it points.
2. Score the evidence against the confidence ladder
The investigation faces a key analytical question: Path A (CFO phishing, November 15) and Path B (IT admin AiTM, October 22) — are they the same actor?
Evidence for unification (same actor):
- Shared PE compile timestamp: Both dropped binaries — svchost32.exe (CFO host) and UpdateHelper.dll (IT admin host) — carry an identical fake compile timestamp of 2018-04-09. This is a known toolchain fingerprint. The probability of two unrelated actors both timestomping to the same date is extremely low.
- Shared secondary C2 domain in memory: Strings extracted from svchost32.exe include sys-update-cdn[.]net — the domain that appeared only in SERVER-RD-02's DNS logs during the formula exfiltration. The CFO's implant knew about infrastructure used during the Path B operation. This is only explicable if the same actor controlled both implants.
- Coordinated operations timeline: The CFO was targeted on the same day that the finance server data was being staged on SERVER-FIN-01 via lateral movement from the IT admin path. Two independent actors staging finance data simultaneously at the same target is implausible.
Assessment: Single threat actor, dual delivery mechanism.
The actor compromised the IT admin first (October 22), used that access for data theft (November 6), then independently targeted the CFO to expand access to finance data. The two phishing lures used different delivery infrastructure (different sender domains, different sending IPs from the same /24 block) — consistent with an actor who maintains parallel operational tracks.
Attribution confidence: Medium-High. Apply the confidence ladder from Step R5 of the methodology to score this case:

Ladder tier: Medium-High — TTP overlap + infrastructure match present; independent confirmation absent. The toolset has not been definitively matched to a named cluster, which prevents elevation to High.
What to write: “Activity assessed as a single threat actor based on shared toolchain indicators (PE timestamp, secondary C2 domain). Tradecraft and targeting profile are consistent with Iranian-nexus industrial espionage operations targeting Israeli pharmaceutical IP. Attribution to a named cluster is not warranted without CERT-IL deconfliction or independent confirmation. Confidence: Medium-High.”
3. Paste the final language into attribution.md and commit
git add 03-analysis/attribution/attribution.md
git commit -m "PROJ-2024-001: attribution — single actor, Medium-High confidence, shared PE timestamp + secondary C2, Iranian-nexus tradecraft consistent"
Step R6: Detection Rules — Four That Would Have Changed the Outcome
1. Create one file per rule
Each rule gets its own file in 04-detections/sigma/:
cp 04-detections/sigma/SIGMA-TEMPLATE.yml 04-detections/sigma/DET-001-anomalous-vpn-auth.yml
cp 04-detections/sigma/SIGMA-TEMPLATE.yml 04-detections/sigma/DET-002-dcsync-non-dc.yml
cp 04-detections/sigma/SIGMA-TEMPLATE.yml 04-detections/sigma/DET-003-svc-account-offhours.yml
cp 04-detections/sigma/SIGMA-TEMPLATE.yml 04-detections/sigma/DET-004-wmiprvse-powershell.yml
Open the first one:
nano 04-detections/sigma/DET-001-anomalous-vpn-auth.yml
Every rule must reference the CL-ID it would have detected and the gap type it closes. That is how the detection backlog stays traceable to the investigation.
2. Fill each rule
Each rule is written with a reference to the claim it would have detected and the evidence gap it closes.
DET-001: Anomalous VPN Authentication from Non-Corporate Source
title: Anomalous VPN Authentication — New Geography or Hosting ASN
id: a1b2c3d4-5678-9abc-def0-1234567890ab
status: experimental
description: >
Detects VPN authentication success from a source IP with no prior history for
this user, specifically from IPs geolocated outside Israel or from hosting/VPN
ASNs. Covers T1133 and T1557 (session token replay after AiTM interception).
Derived from PROJ-001 — CL-001, p.levi VPN from Istanbul at 02:17 UTC.
logsource:
category: network
product: cisco_anyconnect
detection:
selection:
event.action: vpn_auth_success
user.name|exists: true
filter_known:
source.geo.country_iso_code: 'IL'
source.as.number|not|startswith: ['AS47583', 'AS16276'] # hosting VPS ASNs
condition: selection and not filter_known
falsepositives:
- Legitimate international travel — validate against HR travel records
- Remote contractors working abroad
level: high
tags:
- attack.initial_access
- attack.t1133
- attack.credential_access
- attack.t1557
DET-002: DCSync Attack Detection
title: DCSync Attack via Non-DC Account
id: b2c3d4e5-6789-abcd-ef01-234567890abc
status: production
description: >
Detects DCSync by looking for EID 4662 with the DS-Replication-Get-Changes
GUID originating from a workstation IP rather than a domain controller.
Derived from PROJ-001 — CL-004: svc_backup performed DCSync from WS-IT-LEVI
using Domain Admin rights that were never revoked after an August 2024
emergency backup restoration.
logsource:
category: windows
product: windows
service: security
detection:
selection:
EventID: 4662
ObjectType: '{19195a5b-6da0-11d0-afd3-00c04fd930c9}' # DS-Replication-Get-Changes
Properties|contains:
- '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2' # DS-Replication-Get-Changes-All
- '89e95b76-444d-4c62-991a-0facbeda640c' # DS-Replication-Get-Changes-In-Filtered-Set
filter_legitimate_dc:
IpAddress|startswith:
- '10.10.1.10' # DC01 — add all DC IPs here
- '10.10.1.11' # DC02
condition: selection and not filter_legitimate_dc
falsepositives:
- Azure AD Connect sync account — must be explicitly whitelisted
- Authorized red team / pentest — validate scope before dismissing
level: critical
tags:
- attack.credential_access
- attack.t1003.006
DET-003: Service Account Off-Hours Authentication
title: Service Account Authentication Outside Business Hours
id: c3d4e5f6-789a-bcde-f012-34567890abcd
status: experimental
description: >
Detects authentication by a service account (accounts matching svc_* naming
pattern) outside business hours (22:00–06:00) to a non-designated system.
Covers T1078.002 (Valid Accounts: Domain Accounts) for svc_backup lateral
movement in PROJ-001.
logsource:
category: windows
product: windows
service: security
detection:
selection:
EventID: 4624
LogonType: 3
SubjectUserName|startswith: 'svc_'
filter_business_hours:
TimeCreated|windash|lt: '22:00:00'
TimeCreated|windash|gt: '06:00:00'
filter_known_backup_host:
IpAddress: '10.10.4.15' # SERVER-WSUS-01 — legitimate backup source
condition: selection and not filter_business_hours and not filter_known_backup_host
falsepositives:
- Scheduled tasks that legitimately run at night — review and whitelist specific pairs
level: medium
tags:
- attack.lateral_movement
- attack.t1078.002
DET-004: WmiPrvSE Spawning PowerShell
title: WMI Remote Execution — PowerShell Child of WmiPrvSE
id: d4e5f6a7-89ab-cdef-0123-4567890abcde
status: production
description: >
Detects WMI-based lateral movement (T1021.003) where WmiPrvSE.exe spawns
PowerShell on a remote system. This is the pattern from PROJ-001 step 16:
lateral movement from WS-CFO-01 to SERVER-FIN-01 via WMI using svc_finreport
credentials. CrowdStrike detected the PowerShell on SERVER-FIN-01 but the
originating WMI connection from the CFO host had no coverage.
logsource:
category: process_creation
product: windows
detection:
selection:
ParentImage|endswith: '\WmiPrvSE.exe'
Image|endswith: '\powershell.exe'
suspicious_flags:
CommandLine|contains:
- '-Enc'
- '-EncodedCommand'
- '-NonI'
- '-W Hidden'
condition: selection and suspicious_flags
falsepositives:
- SCCM WMI-based software deployment with PowerShell post-install scripts
level: high
tags:
- attack.lateral_movement
- attack.execution
- attack.t1021.003
- attack.t1059.001
Validation: All four rules were validated against the PROJ-001 evidence set using Hayabusa before deployment. DET-001 fires on the October 24 Istanbul VPN login. DET-002 fires on the November 6 DCSync event. DET-003 fires on every svc_backup off-hours logon. DET-004 fires on the SERVER-FIN-01 WMI execution.
3. Validate each rule against your evidence set
# Run Hayabusa against the collected logs to confirm rules fire on known-bad events
hayabusa csv-timeline -d 01-evidence/ -r 04-detections/sigma/ -o validation-results.csv
Review the output. A rule that does not fire on its own evidence set should not be deployed.
4. Update project.yml deliverables count and commit
nano project.yml
deliverables:
- type: sigma-rules
count: 4
status: complete
git add 04-detections/sigma/ project.yml
git commit -m "PROJ-2024-001: detections — DET-001 to DET-004 written and validated PASS against evidence set via Hayabusa"
Step R7: Deliverables — What Each Stakeholder Gets
1. Open the deliverable templates
nano 05-deliverables/executive-brief.md
nano 05-deliverables/soc-handoff.md
The executive brief answers three questions only: what happened, what was confirmed stolen or compromised, and what must happen in the next 24 hours. One page. No technical jargon. Every PIR that is answered gets a one-line answer at the top.
The SOC handoff lists: current IOCs (with confidence ratings), detection rules deployed, hunting queries still open, and escalation criteria. The SOC receives this, not the executive brief.
2. Fill the executive brief
Executive brief (1 page, TLP:AMBER) — what the CISO needs in 90 minutes:
An adversary assessed as Iranian-nexus compromised LifeTech Pharma through two separate phishing attacks over 24 days. Using stolen IT administrator credentials, they accessed and exfiltrated the 47-file US licensing formula package on November 6, 2024. They also performed a DCSync attack on the domain controller, which means all Active Directory credentials must be treated as compromised.
PIR-001 ANSWERED: The US partner formula package was exfiltrated. 381 MB outbound confirmed in firewall logs.
PIR-003 ANSWERED: Active compromise ongoing. The CFO alert on November 15 is a second wave from the same actor, still active at time of investigation.
Immediate actions: Full AD credential rotation; quarantine WS-CFO-01 and SERVER-FIN-01; notify INCD (72h clock from discovery: expires November 17 02:14 IST); brief the US licensing partner.
SOC handoff (technical):
Current IOCs: 203.0.113.87, 198.51.100.44, telemetry-cdn-services[.]biz, sys-update-cdn[.]net, uslifepartner-group[.]com, lifetechpharma-corp[.]eu.
Four detection rules deployed (DET-001 through DET-004). Two hunting queries: (1) pivot on C2 domains across all 838 endpoints — the 3 confirmed hosts may not be all; (2) hunt for any svc_backup authentication from non-WSUS IPs in the past 30 days.
3. Update project.yml status to closed and commit everything
nano project.yml
project:
status: closed
pirs:
- id: PIR-001
status: answered # CL-003
- id: PIR-002
status: answered # CL-001
- id: PIR-003
status: answered # CL-006 - ongoing, AD rotation required
git add 05-deliverables/ project.yml
git commit -m "PROJ-2024-001: deliverables — executive brief, SOC handoff, INCD notification ready; all PIRs answered; project closed"
The Git History: What a Completed Investigation Looks Like

b9a2f1c PROJ-001: deliverables — executive brief, SOC handoff, INCD notification ready
7c8d3e4 PROJ-001: detections — DET-001 through DET-004 validated PASS via Hayabusa
5f2a9b1 PROJ-001: attribution — single actor assessed (shared PE timestamp + secondary C2)
3e4c7d8 PROJ-001: ATT&CK mapping — 12 techniques, 7 rule-missing, 3 incomplete, 1 data-missing
1b6f2a5 PROJ-001: claims — 6 claims; PIR-001 ANSWERED YES (CL-003); PIR-003 CONFIRMED ONGOING (CL-006)
9a3e7c2 PROJ-001: timeline — 18 events Oct 22–Nov 15; dual-path confirmed, same actor assessed
6f1b4d9 PROJ-001: evidence inventory — 6 sources, GAP-001 documented, firewall log retrieval urgent
2c8a5e3 PROJ-001: scope — signed off 22:55 IST; PIR-001/002/003, TLP AMBER, legal hold WS-IT-LEVI
a1d7f4b PROJ-001: intake — CFO PowerShell alert, legal hold WS-IT-LEVI, formula data in scope
0e9c2b7 PROJ-001: scaffold initialized
Each commit is a phase. Each message states the project ID, the phase, and a one-line summary of what was concluded. When a lawyer asks six months from now “what did you know and when did you know it?” — the git log answers.
Key Lessons
The alert was not the beginning. The SOC received its first signal 52 hours after the breach was already in progress — and 15 days after the formula files were gone. The triggering alert was the second entry point. A detection rule on anomalous VPN authentication (DET-001) would have fired on October 24 at 02:17 UTC — before any lateral movement, before any data access.
Gaps are findings, not absences. The 10-day Sysmon gap on WS-IT-LEVI coincided exactly with the delivery of a phishing email. Stopping a logging service is T1562.001 — Impair Defenses. A gap is not “we don’t know what happened.” A gap that coincides with a malicious delivery is evidence of anti-forensics.
DCSync changes everything. The scope of remediation is not “three infected hosts.” When DCSync is confirmed via Domain Admin rights, every credential in the AD is potentially compromised. The scope is all 80 servers. The IR Lead needs to know this before the 90-minute CISO brief, not after.
Claims need competing hypotheses. CL-003 (exfiltration confirmed) is only defensible as “high confidence” because specific alternative explanations were checked and explicitly ruled out — scheduled backup (wrong source IP, wrong timing), authorized developer activity (no jobs scheduled). Without the competing hypothesis analysis, a claim is an assertion. With it, it is analysis.
This scenario is training assignment A01 from the
SOCIAL SHARE CARD GENERATOR