CASE
#073
Skuggaheimar Case Files  ·  Mjolnir Security
Incident Response Social Engineering Extortion Case File Jun 08, 2026 22 min read

The Psychic Extortionist

The threat actor knew the IT admin's 96-character password. Then they knew the new one, an hour later. Three days of full-spectrum forensics found nothing. The answer was in a five-minute conversation about someone's morning routine.

Scroll
Case #073  ·  Engagement File
Case Type Extortion / Social Engineering — Slack Account Compromise, Credential Harvesting via Impersonation
Industry Professional Services (mid-size firm, ~200 staff, anonymized sector)
Duration 3 days full forensics + 1 day human intelligence — 4 days total
Year Year 4 of operations
Notoriety The one where three days of forensics was solved in five minutes by asking someone about their morning

The following is a lightly anonymised account of a real incident response engagement. All individual and organisational identifiers have been altered. Technical findings are presented as they occurred. We are publishing this case because it illustrates a failure mode that no amount of technical forensic capability can detect — not because the evidence isn't there, but because investigators forget to look in the one place that doesn't require a tool: the human being sitting across the table from them.

The Engagement

The Email Nobody Wanted to Receive

The organisation's IT admin — we will call him Nathan — arrived at his desk on a Tuesday morning to find an email in his personal inbox from an address he did not recognise. The subject line was blank. The body contained a single line of text: his domain administrator password. All 96 characters of it. Verbatim. Correct.

The email continued, in the unhurried tone of someone who believes they hold all the cards, to explain that the sender had 'complete access' to the organisation's systems, had been 'inside for weeks,' and would publish unspecified sensitive data unless a payment was made in Monero within 48 hours. The email included a wallet address and, in a touch that suggested the sender had done this before, a reassurance that payment would be 'quick and private.'

Nathan did the correct thing. He did not pay. He escalated to his manager, changed the password immediately, and the organisation contacted us within the hour. We were on-site by afternoon.

At 16:22 that same afternoon — approximately one hour after the password had been changed — Nathan received a second email from the same address. It contained his new password.

Somewhere, a threat actor had just demonstrated what appeared to be real-time visibility into a domain administrator's credential changes. We began to feel the particular combination of professional interest and personal unease that this line of work occasionally produces.

Three Days of Finding Nothing

The investigation that followed was, for approximately 72 hours, one of the most technically thorough and completely unrewarding engagements we had run to that point in the practice. We approached the problem systematically and eliminated hypotheses in sequence.

Investigation Track Scope Result
Endpoint forensics Nathan's workstation, domain controllers (4), all servers — full triage: MFT, Prefetch, Amcache, SRUM, browser history, PowerShell logs Clean — No RAT, keylogger, unsigned driver, or suspicious process
Network traffic analysis Perimeter firewall, internal switches, DNS logs — 14 days of traffic reviewed Clean — No anomalous outbound beaconing, C2 patterns, or unusual DNS
Active Directory audit Security.evtx on all DCs, last 30 days — logons, privilege escalation, replication events, password change sources Clean — No unauthorised logons, no privilege escalation. Password changes confirmed by Nathan, from his workstation, from the corporate IP
Email header analysis Both threat actor emails — full RFC 5322 headers Partial — Emails routed via anonymous remailer chain terminating at Tor exit node. No sender origin beyond Tor
Dark web / threat intel Breach databases, paste sites, forum monitoring Clean — Nathan's credentials not present in any known breach dataset, paste site, or dark web market. Password never exposed
Credential manager audit Windows Credential Manager, browser saved passwords, all endpoints Clean — No third-party password managers installed. Password stored only in Nathan's head and in Active Directory. No cloud sync
Keylogger sweep All endpoints — memory and disk. Sysmon Event ID 10 (LSASS access), hook monitoring, unsigned code in persistence locations Clean — No keylogger found. No LSASS hook. No suspicious Sysmon events. No unsigned code in known persistence locations

After 72 hours, we had eliminated every technical hypothesis on the board. No malware. No keylogger. No network compromise. No credential exposure in any known breach dataset. The password had not been phished via email. Nathan did not use any external service where the password could have been captured. The organisation's systems showed no sign of intrusion. The threat actor had not been 'inside for weeks' — that claim appeared to be fabricated posturing, as we had found zero evidence of any persistent access.

The second email — the one with the updated password, sent within an hour of the change — was the puzzle piece that kept everything in focus. If this were a keylogger or a RAT, we would have found it. If this were a breach database exposure, the original password would have appeared somewhere. If this were a man-in-the-middle attack on the domain controller, the network logs would have shown it. None of those things were true.

Which left a possibility that technical forensics cannot locate: a human being. Someone who knew the password because they had been told it.

The Human Pivot

The Question We Should Have Asked on Day One

On the morning of day four, we sat down with Nathan for what we framed as a routine debrief — not an interrogation, not an accusation, just a structured conversation about his typical working day. We asked him to walk us through his morning from the moment he arrived at the office to the moment the first extortion email had appeared. We wanted to understand what was normal so we could identify what was abnormal.

Nathan talked through his morning comfortably. He arrived at 8:30. He made coffee. He checked his email. He reviewed the overnight monitoring dashboard. He responded to a few Slack messages. He had been helping someone set up a new application on the file server — routine work.

We almost missed it. He said it in the same tone he had used for everything else, and it very nearly slid past us: 'Oh, and ████ (the VP of IT) messaged me on Slack asking for my domain admin password for something he was setting up.'

We stopped him there.

He had given his 96-character domain administrator password to someone who messaged him on Slack. He had not called them. He had not walked to their office. He had typed it into a chat window because the display name said it was his boss.

The VP of IT Was in the Bahamas

We stepped out of the room and called HR. The VP of IT — let's call him Raymond — had been on approved vacation leave for five days. He was in the Bahamas. He had been there since the weekend before the extortion email arrived. He had not been in the office. He had not been on the corporate network. He had not been, in any demonstrable sense of the word, asking Nathan for passwords.

Raymond's Slack account did not have multi-factor authentication enabled. The VP of IT, the person responsible for setting the organisation's security posture, had declined to enable MFA on his own collaboration account because — and this is a direct quote relayed to us by the IT team — it was 'too complicated' and 'slowed him down in the morning.'

The threat actor had not compromised the organisation's systems. They had compromised Raymond's Slack account, impersonated him in a conversation with Nathan, asked for the domain admin password, received it, and then done it again after the password was changed. The entire intrusion chain was a chat message and an IT admin who trusted a display name.

Finding 01: Slack Account Compromise

Artifact: Slack Audit Logs — member_logged_in and user_session_start Events
Path: Slack Admin Console → Settings → Audit Logs  |  Requires: Slack Business+ or Enterprise Grid plan
  • Audit log events relevant to account compromise: member_logged_in, user_session_start, user_session_invalidated
  • Each login event includes: actor (user ID), ip_address, user_agent, date_time, context (device/browser)
  • Paid plan required: Free and Pro plans do not include audit log access — Business+ provides 90-day retention
  • API access: Slack Audit Logs API (GET /audit/v1/logs) — requires Org Owner or Org Admin token
  • Suspicious pattern: login from foreign IP + no corresponding office network login = external session
  • Cross-reference: login IP vs known employee IP ranges (office egress + VPN + known residential IPs)
# Slack Audit Log — anomalous member_logged_in events from Tor exit node
# during Raymond's vacation, Linux UA vs Raymond's macOS

import requests, json
from datetime import datetime, timezone

SLACK_TOKEN = 'xoxp-████████████████████████████████████████████'
HEADERS     = {'Authorization': f'Bearer {SLACK_TOKEN}'}

# Define time window (UTC): 7 days before and after extortion email
date_from = int(datetime(2024, ██, ██, 0, 0, tzinfo=timezone.utc).timestamp())
date_to   = int(datetime(2024, ██, ██, 23, 59, tzinfo=timezone.utc).timestamp())

params = {
    'action': 'member_logged_in',
    'actor':  'U████████',   # Raymond's Slack user ID
    'oldest':  date_from,
    'latest':  date_to,
    'limit':   200
}

r = requests.get('https://api.slack.com/audit/v1/logs', headers=HEADERS, params=params)
events = r.json()['entries']

for e in sorted(events, key=lambda x: x['date_create']):
    ts  = datetime.fromtimestamp(e['date_create'], tz=timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
    ip  = e.get('context',{}).get('ip_address','unknown')
    ua  = e.get('context',{}).get('ua','unknown')[:60]
    print(f'{ts}  |  IP: {ip:<20}  |  UA: {ua}')

# OUTPUT:
# 2024-██-██ 07:44:12 UTC  |  IP: 203.0.113.██       |  UA: Slack/4.35 (macOS)   ← Raymond's normal
# 2024-██-██ 08:01:44 UTC  |  IP: 203.0.113.██       |  UA: Slack/4.35 (macOS)   ← Raymond's normal
# 2024-██-██ 11:22:09 UTC  |  IP: 198.51.100.██      |  UA: Slack/4.35 (macOS)   ← Last known office login
#
# --- Raymond's vacation begins ---
#
# 2024-██-██ 03:14:41 UTC  |  IP: 185.220.██.██      |  UA: Mozilla/5.0 Chrome/120 Linux  ← ANOMALOUS
# 2024-██-██ 03:16:02 UTC  |  IP: 185.220.██.██      |  UA: Mozilla/5.0 Chrome/120 Linux
# 2024-██-██ 06:44:03 UTC  |  IP: 185.220.██.██      |  UA: Mozilla/5.0 Chrome/120 Linux
#
# 185.220.xx.xx = Tor exit node (confirmed via Tor Project exit list)
# User-agent: web browser on Linux — Raymond uses macOS exclusively (MDM enrolled)
# Raymond was in the Bahamas — confirmed with HR and carrier roaming records
# These logins are not Raymond.

The forensic picture was clean. Raymond's normal login pattern was the Slack desktop client on macOS, from the corporate office IP. The anomalous sessions were a web browser on Linux, from a Tor exit node, at 3 AM and 6 AM local time — while Raymond was five time zones away on a beach. No MFA challenge had been required or presented. The account had no second factor. The attacker had needed only Raymond's Slack email address and password.

Finding 01

Raymond's Slack Account Accessed from Tor Exit Node During Vacation — Linux Browser UA vs Raymond's macOS Slack Client, No MFA

Slack Audit Log confirmed three member_logged_in events from 185.220.xx.xx (Tor exit node) during the period when Raymond was confirmed on approved vacation leave. User-agent was a Linux web browser — Raymond's enrolled devices are exclusively macOS. Raymond's account had no MFA configured. No step-up challenge was presented or required. The attacker had authenticated to Raymond's Slack account with credentials alone and established a persistent browser session used to impersonate Raymond in direct messages.

Finding 02: The Impersonation

Artifact: Slack DM Message History — Direct Message Logs via Export
Path: Slack Admin Console → Settings → Import/Export Data (Business+ / Enterprise Grid) | Or: eDiscovery API
  • DM content export: available to Workspace Owners/Admins on Business+ and Enterprise Grid plans
  • Export format: JSON per channel/DM — messages array with user, text, ts (Unix timestamp), attachments
  • Audit log does not contain message text — full export required for content reconstruction
  • message_deleted events in audit log confirm if messages were subsequently removed by the actor
  • Retention policy: Slack default = indefinite on paid plans; some orgs enable auto-delete
  • Critical: request export immediately — if the attacker deleted the DM thread, it may be unrecoverable
# Slack DM export — full impersonation thread reconstructed
# Password typed into chat within 38 seconds of first request

import json
from datetime import datetime, timezone

with open('direct_messages/D████████████.json') as f:
    messages = json.load(f)

target_date = '2024-██-██'
for msg in messages:
    ts_dt = datetime.fromtimestamp(float(msg['ts']), tz=timezone.utc)
    if ts_dt.strftime('%Y-%m-%d') == target_date:
        user = msg.get('user', 'unknown')
        text = msg.get('text', '[no text]')
        print(f'[{ts_dt.strftime("%H:%M:%S UTC")}] {user}: {text}')

# OUTPUT — full DM thread on date of compromise (user IDs resolved to display names):
#
# [08:47:03 UTC]  raymond.████ (VP IT):   Hey Nathan, I need the DA password for the
#                                          ████████ server migration I'm working on.
#                                          Can you send it in DM?
#
# [08:47:41 UTC]  nathan.████ (IT Admin): Sure! Here it is:
#                                          [REDACTED — 96-character password]
#
# [08:47:55 UTC]  raymond.████ (VP IT):   Thanks. All good.
#
# [14:33:18 UTC]  raymond.████ (VP IT):   Password stopped working. Can you send the
#                                          updated one? Something must have changed.
#
# [14:34:02 UTC]  nathan.████ (IT Admin): Oh weird! Here's the new one:
#                                          [REDACTED — new 96-character password]
#
# [14:34:11 UTC]  raymond.████ (VP IT):   Got it. Cheers.
#
# Total time from first request to credential handover: 38 seconds
# Total time from password change to re-acquisition: 44 seconds
# Nathan did not call Raymond. Did not email. Did not verify via any out-of-band channel.
# He typed a 96-character domain administrator password into a Slack DM.

Thirty-eight seconds from request to credential handover. The attacker, operating as Raymond's account, asked for the domain admin password citing a server migration. Nathan typed it into the chat. Thirty-eight seconds.

The second exchange — acquiring the newly changed password — was even faster. The attacker had monitored the first email's delivery, sent the extortion email with the original credential, and then waited. When the password was changed and the 'new password' email arrived as a follow-up extortion message, Nathan's first action was apparently to check whether Raymond's migration had broken. It had. Raymond asked for the updated password. Nathan provided it in 44 seconds.

At no point did Nathan call Raymond, walk to his office, send an email from a separate channel, or perform any verification that the person he was talking to was who their display name claimed. This is not an unusual failure. It is a human reflex — we trust the context we are given, especially from authority figures, especially in a tool we use dozens of times a day. The attacker understood this perfectly.

Finding 02

Slack DM Thread Confirms Full Impersonation Exchange — Password Handed Over in 38 Seconds, New Password in 44 Seconds, No Out-of-Band Verification

Slack DM export confirmed the attacker, operating from Raymond's compromised account, sent two credential requests to Nathan across a 6-hour window on the day of the extortion email. Nathan responded to both requests within seconds, providing the 96-character domain administrator password and its replacement without any out-of-band verification. The message tone was casual and professional — consistent with Raymond's normal communication style, presumably because the attacker had been reading Raymond's prior DM history to match it. Nathan reported that the request 'sounded exactly like Raymond.'

Finding 03: How Raymond's Slack Was Compromised

Artifact: Slack Password Reset Audit + Breach Database Analysis
Path: Slack Audit Log: member_login_failed, reactivation_link_sent | HIBP API: haveibeenpwned.com/api/v3
  • Failed login attempts: member_login_failed events in Slack audit log precede successful login
  • 3 failed attempts then success — not a spray, not brute force. Attacker had a candidate password list
  • HIBP check: did Raymond's work email appear in known breach datasets?
  • LinkedIn breach (2012): 117M credentials — hashed, widely cracked and distributed
  • Credential reuse: same base password + predictable variations across accounts since 2012
  • MFA absent: cracked password was the sole barrier between attacker and Raymond's account
# Slack failed login events + HIBP
# 3 attempts before success; Raymond's email in LinkedIn 2012 breach
# password was a variant of cracked hash

params_failed = {
    'action': 'user_login_failed',
    'actor':  'U████████',
    'oldest':  int(datetime(2024, ██, ██, 0, 0, tzinfo=timezone.utc).timestamp()),
    'latest':  int(datetime(2024, ██, ██, 3, 14, tzinfo=timezone.utc).timestamp()),
    'limit':   50
}
r_fail = requests.get('https://api.slack.com/audit/v1/logs', headers=HEADERS, params=params_failed)

# OUTPUT:
# 2024-██-██ 03:11:04 UTC  |  IP: 185.220.██.██  |  action: user_login_failed
# 2024-██-██ 03:11:47 UTC  |  IP: 185.220.██.██  |  action: user_login_failed
# 2024-██-██ 03:13:19 UTC  |  IP: 185.220.██.██  |  action: user_login_failed
# 2024-██-██ 03:14:41 UTC  |  IP: 185.220.██.██  |  action: member_logged_in   ← SUCCESS
# 3 failed attempts then success — attacker had a candidate list, not a blank

# HIBP check — Raymond's work email address:
import requests as rq
hibp_r = rq.get(
    'https://haveibeenpwned.com/api/v3/breachedaccount/raymond.████@firm.com',
    headers={'hibp-api-key': '████████████████████████', 'User-Agent': 'MjolnirSecurityIR'}
)
if hibp_r.status_code == 200:
    breaches = [b['Name'] for b in hibp_r.json()]
    print(f'Breaches: {breaches}')

# OUTPUT:
# Breaches: ['LinkedIn', 'Adobe', '████████ (2021 forum breach)']
#
# LinkedIn breach (2012): 117M credentials — hashed, widely cracked
# Raymond had used a variant of the same base password since at least 2012
# Slack password was a variation on the cracked LinkedIn hash
# Attacker had access to breach data + hashcat + time

Raymond's work email address appeared in the 2012 LinkedIn breach — 117 million credentials, widely distributed and largely cracked. His Slack password was a variation on the same base password he had been using since at least 2012, with predictable modifications: a number appended, a capital letter shifted. The attacker had sourced Raymond's email from the breach data, cracked or purchased the corresponding hash, tried the known variants, and succeeded on the fourth attempt.

The irony is complete: Raymond had declined to enable MFA because it was 'too complicated and slowed him down in the morning.' The time cost of MFA on a Slack login is approximately four seconds. The time cost of the investigation it prevented was four days of our time, three days of the organisation's operational disruption, and a conversation with Ontario Provincial Police.

Finding 03

Raymond's Slack Password Cracked from 2012 LinkedIn Breach Data — 3 Attempts to Success, 12-Year-Old Credential Variant Still in Use

Slack audit log showed 3 failed login attempts immediately preceding successful unauthorised access — consistent with targeted credential testing rather than mass spray. HIBP confirmed Raymond's work email appeared in the 2012 LinkedIn breach (117M credentials, widely cracked). Raymond had used a variation of the same base password across multiple accounts since at least 2012, modifying it predictably (appended numbers, capitalisation shifts). The Slack password was a recognisable variant of the cracked LinkedIn credential. Raymond's refusal to enable MFA — citing complexity — meant the cracked password was the sole barrier between the attacker and his account.

Finding 04: Attribution and Police Referral

Artifact: Email Header Analysis — Extortion Email Origin + Tor Exit Node Attribution
Path: Full RFC 5322 headers from both extortion emails | Tor exit node analysis via Tor Project relay descriptors
  • Received chain: traces the path an email took through mail servers — each hop adds a Received header
  • Tor exit node as SMTP relay: actor connects to a relay via Tor — source IP is the exit node
  • Exit node IP attribution: Tor exit nodes are publicly listed in the Tor Project's exit relay list
  • OPSEC failure: second extortion email sent from same exit node as first — and as the Slack login
  • Attribution chain: Tor exit IP + Slack login IP match = same actor, single infrastructure fingerprint
  • Law enforcement use: Tor relay operator contact information available via public relay descriptors
# Email header analysis — originating IP 185.220.xx.xx matches Slack audit log
# foreign login IP; same Tor exit node used for both operations
# OPP referral package compiled

import email, re

with open('extortion_email_1.eml') as f:
    msg = email.message_from_file(f)

received_headers = msg.get_all('Received', [])
print('Received chain (first to last hop):')
for i, header in enumerate(reversed(received_headers)):
    ips = re.findall(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', header)
    print(f'  Hop {i+1}: {ips}')

# OUTPUT:
# Hop 1: ['185.220.██.██']  ← originating IP — Tor exit node
# Hop 2: ['10.██.██.██']    ← anonymous remailer internal IP
# Hop 3: ['209.██.██.██']   ← remailer egress MX
# Hop 4: ['████.████.com']  ← recipient MX (organisation's mail server)

# Originating IP: 185.220.██.██
# Cross-reference against Slack audit log anomalous login IP:
# Slack anomalous login IP: 185.220.██.██  ← SAME EXIT NODE

# Tor relay descriptor (public record):
# Nickname:    ████████████
# Country:     CA  ← Canadian exit node
# Contact:     ████████████████████ [operator contact for legal process]

# Ontario Provincial Police referral package:
# - Both extortion emails + full headers (originating IP 185.220.xx.xx)
# - Slack audit log: same IP logging into Raymond's account
# - Slack DM export: impersonation and credential harvesting
# - HIBP evidence: credential compromise source
# - Tor relay operator contact: for legal process to exit node operator
# - Full timeline reconstruction
# OPP case file opened. Investigation ongoing at time of this writing.

The threat actor's operational security had failed at a fundamental level: the same Tor exit node used to log into Raymond's Slack account had been used to send both extortion emails. This linked the Slack compromise and the extortion under a single infrastructure fingerprint and produced a referral package for Ontario Provincial Police that documented the full chain of events from Raymond's credential compromise to the extortion demand.

The extortion threats, framed in the email as backed by 'weeks of access' and 'complete system compromise,' were undermined entirely by the forensic investigation. There had been no system access. There had been no persistent presence. There had been a compromised Slack account, a trusting IT admin, and a threat actor who understood that a credential you receive in a chat message is just as useful as one you steal from a keylogger — and considerably less likely to be detected.

Finding 04

Extortion Email and Slack Login Share Identical Tor Exit Node — Single Actor Attribution; OPP Referral Package Compiled

RFC 5322 header analysis of both extortion emails confirmed originating IP 185.220.xx.xx — identical to the Tor exit node used for all anomalous Slack logins. This creates a single-actor attribution linking the credential compromise, the impersonation, and the extortion under one infrastructure fingerprint. The claimed 'weeks of system access' and 'complete compromise' were not supported by any forensic evidence — the entire operation consisted of Slack impersonation and credential harvesting via social engineering. A referral package was compiled for Ontario Provincial Police including email headers, Slack audit logs, DM export, and Tor relay operator information for legal process.

Reconstructed Attack Timeline

Timestamp Artifact Source Event
Unknown (years prior) HaveIBeenPwned / LinkedIn 2012 breach Raymond's work email and associated password hash captured in LinkedIn 2012 data breach (117M credentials). Hash cracked offline — base password and common variations known to attacker community.
T-0 03:11 UTC Slack Audit Log (user_login_failed) Attacker begins testing password variants against Raymond's Slack account from Tor exit node 185.220.xx.xx. Three failed attempts using LinkedIn breach variants.
T-0 03:14 UTC Slack Audit Log (member_logged_in) Fourth attempt succeeds. Raymond's Slack account accessed via web browser on Linux, no MFA challenge. Attacker now has full access to Raymond's DM history, channel memberships, and display name.
T-0 03:14–08:40 UTC Slack session (attacker) Attacker reads Raymond's DM history to understand communication patterns, identify IT admin contacts, and learn terminology Raymond uses. Identifies Nathan as the IT admin and notes prior technical exchanges.
T-0 08:47 UTC Slack DM export Attacker, operating as Raymond, sends DM to Nathan: "I need the DA password for the [X] server migration I'm working on. Can you send it in DM?"
T-0 08:47 UTC (+38 sec) Slack DM export Nathan responds with 96-character domain administrator password. No out-of-band verification. No callback. No question about why the VP of IT would need the DA password for a migration.
T-0 08:47–09:30 UTC Email headers Attacker sends first extortion email to Nathan's personal email from same Tor exit node. Email contains the 96-character password verbatim. Extortion demand: Monero payment within 48 hours.
T-0 ~09:15 UTC HR records / Nathan interview Nathan reads extortion email. Changes domain administrator password immediately. Escalates to management. Organisation contacts Mjolnir Security.
T-0 14:33 UTC Slack DM export Attacker, still in Raymond's session, sends second DM to Nathan: "Password stopped working. Can you send the updated one?"
T-0 14:34 UTC (+44 sec) Slack DM export Nathan provides the new 96-character password. Again, no verification.
T-0 ~15:00 UTC Email headers Attacker sends second extortion email containing new password. Ratchets up pressure, shortens deadline.
T+1 to T+3 days Mjolnir Security IR Full forensic investigation: endpoints, network, DCs, dark web, breach databases. Zero technical indicators of compromise found. No malware, no keylogger, no persistent access.
T+4 (morning) Human intelligence Routine debrief conversation with Nathan. Nathan mentions VP of IT asked for password over Slack. Pivot to Slack audit logs.
T+4 (afternoon) Slack Audit Log + DM export Slack paid plan logs confirm: Raymond's account accessed from Tor exit node during his confirmed vacation. DM export reconstructs both credential-harvesting exchanges. Raymond confirmed in Bahamas by HR.
T+4 (evening) Law enforcement referral Ontario Provincial Police notified. Referral package compiled: email headers, Slack audit logs, DM export, Tor node attribution, timeline. Case file opened.

Lessons for Incident Responders

  1. 01
    Start with the human before the hardware. The technical investigation in this case was thorough and correct — and would have found evidence if technical evidence existed. It found nothing because the compromise was not technical. The human intelligence pivot on Day 4 broke the case in five minutes. A structured interview covering the victim's typical day and recent interactions should happen in the first hours of any investigation, not as a fallback after days of negative technical findings.
  2. 02
    Ask the awkward question early: "Did you share your credentials with anyone, through any channel, in the past [X] days?" People often do not volunteer this information because they know, on some level, that they should not have done it. They will answer if asked directly. In this case, Nathan answered within ninety seconds of being asked about his day — he mentioned the Slack message casually, as if it were routine, because from his perspective it had been.
  3. 03
    Slack audit logs require a paid plan and must be requested immediately. Free and Pro plans do not retain audit logs, and Business+ plans retain 90 days. In a case where Slack activity is relevant, confirm the plan tier and export logs within the first 24 hours. The DM content export is separate from audit logs and also requires admin access. Document your request and the export timestamp for chain-of-custody purposes.
  4. 04
    Same-infrastructure OPSEC failures are common and valuable. When two actions in an incident share the same IP, user-agent, or other identifier, that link is often the strongest single piece of attribution evidence available. In this case, the same Tor exit node appearing in both the Slack login logs and the email headers was the link that allowed a referral package to be built for law enforcement. Always cross-reference IPs across every log source in parallel.

Lessons for Security Engineers, IT Leadership & HR

  1. 01
    MFA is not optional for any account used in communications that involve privileged information. A VP of IT who declines MFA 'because it slows me down' has made a risk decision on behalf of every person who trusts a message from their account. That decision should not be theirs alone to make. MFA for all staff in privileged roles — IT, finance, executive — should be a policy enforced by the organisation, not a personal preference.
  2. 02
    Credentials must never be shared through any asynchronous text channel — Slack, Teams, email, SMS, or any other system where the identity of the sender cannot be verified in real time. If someone asks for a privileged credential via a chat message, the response should be a phone call to a known number, not a reply. This is a trainable behaviour and should be a named, specific item in security awareness training: credentials are never shared in chat, for any reason, for anyone.
  3. 03
    Slack and Microsoft Teams impersonation is the fastest-growing social engineering vector in enterprise environments precisely because people trust the context they are given. An attacker who has access to a manager's account has access to their communication history, their writing style, their direct reports list, and the implicit authority of their name. The technical barrier to impersonation is zero; the social barrier, in most organisations, is also zero. Out-of-band verification for credential requests eliminates this attack surface completely.
  4. 04
    Breach monitoring for all staff email addresses is a basic security hygiene measure that this case illustrates in the sharpest possible terms. Raymond's email address had been in the LinkedIn breach for twelve years. A free HIBP check would have flagged it. A policy requiring password changes for any account whose email appears in a breach database would have rotated the credential before it was usable. The cost of this control is approximately the time it takes to run a CSV through the HIBP API once a quarter.

Mjolnir Security — Incident Response & Social Engineering Defence

This engagement illustrates that technical forensics and human intelligence are not alternatives — they are complements. If your organisation has experienced a suspected compromise, or if you want to assess your exposure to Slack and Teams impersonation attacks before an incident occurs, our team is available 24/7.

Digital Forensics & IR Slack / Teams Security Review Social Engineering Assessment Security Awareness Training MFA Implementation Credential Monitoring Law Enforcement Liaison

mjolnirsecurity.com ↗  ·  24/7 Incident Line: +1 (888) 655-6564