Windows Server Compromise Investigation

Investigation Flow

Windows Server Compromise Investigation Flow

Investigation Setup

Update these attributes in antora.yml before running queries:

Attribute Description Current Value

Compromised server IP

Compromised server hostname

Incident window start

Incident window end

Normal activity baseline start

Normal activity baseline end

Timeline Reconstruction

All Events from Target

-- Windows Server Compromise: Timeline Reconstruction
-- All Events from Target Server

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    logsourcename(logsourceid) AS "Log Source",
    qidname(qid) AS "Event",
    username AS "User",
    sourceip AS "Src IP",
    destinationip AS "Dst IP",
    destinationport AS "Port",
    UTF8(payload) AS "Payload"
FROM events
WHERE sourceip = '<target-server-ip>' OR destinationip = '<target-server-ip>'
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'
Example (server 10.50.2.100, Feb 20-23)
SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    logsourcename(logsourceid) AS "Log Source",
    qidname(qid) AS "Event",
    username AS "User",
    sourceip AS "Src IP",
    destinationip AS "Dst IP",
    destinationport AS "Port",
    UTF8(payload) AS "Payload"
FROM events
WHERE sourceip = '10.50.2.100' OR destinationip = '10.50.2.100'
ORDER BY starttime ASC
START '2026-02-20 00:00' STOP '2026-02-23 23:59'

High Severity Events

-- Windows Server Compromise: High Severity Events

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    magnitude AS "Mag",
    username AS "User",
    UTF8(payload) AS "Payload"
FROM events
WHERE (sourceip = '<target-server-ip>' OR destinationip = '<target-server-ip>')
  AND magnitude >= 5
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

LogMeIn Detection

LogMeIn in Event Payloads

-- Windows Server Compromise: LogMeIn Event Detection

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Details"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    UTF8(payload) ILIKE '%logmein%'
    OR UTF8(payload) ILIKE '%LMIGuardian%'
    OR UTF8(payload) ILIKE '%LMIIgnition%'
    OR UTF8(payload) ILIKE '%LogMeInSystray%'
    OR UTF8(payload) ILIKE '%ramaint%'
    OR UTF8(payload) ILIKE '%LMI_Rescue%'
    OR UTF8(payload) ILIKE '%LogMeIn Hamachi%'
  )
ORDER BY starttime ASC
LAST 90 DAYS
Example
SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Details"
FROM events
WHERE (sourceip = '10.50.2.100' OR LOGSOURCENAME(logsourceid) ILIKE '%SVR-LEGACY-01%')
  AND (
    UTF8(payload) ILIKE '%logmein%'
    OR UTF8(payload) ILIKE '%LMIGuardian%'
    OR UTF8(payload) ILIKE '%LMIIgnition%'
  )
ORDER BY starttime ASC
LAST 90 DAYS

LogMeIn Service Events (4697/7045)

-- Windows Server Compromise: LogMeIn Service Installation (4697/7045)

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Service Details"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    qidname(qid) ILIKE '%service%'
    OR qid IN ({win-service-install}, 7045)
  )
ORDER BY starttime ASC
LAST 90 DAYS

LogMeIn Network Flows

-- Windows Server Compromise: LogMeIn Network Flows

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    sourceip AS "Src",
    destinationip AS "Dst",
    destinationport AS "Port",
    protocolname(protocolid) AS "Proto",
    sourcebytes AS "Bytes Out",
    destinationbytes AS "Bytes In"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND destinationport IN (80, 443, 2002, 8200, 8201)
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Notepad++ Detection

Notepad++ Execution

-- Windows Server Compromise: Notepad++ Execution

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Details"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND UTF8(payload) ILIKE '%notepad++.exe%'
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Process Execution

All Process Creation (4688)

-- Windows Server Compromise: All Process Creation (4688)
-- Note: Use qidname() and payload fallbacks for portability across QRadar deployments.

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    UTF8(payload) AS "Process"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    qidname(qid) ILIKE '%process%creat%'
    OR qidname(qid) ILIKE '%4688%'
    OR UTF8(payload) ILIKE '%<EventID>4688</EventID>%'
    OR CATEGORYNAME(category) ILIKE '%process%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

PowerShell Execution

-- Windows Server Compromise: PowerShell Execution

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    UTF8(payload) AS "Command"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    UTF8(payload) ILIKE '%powershell%'
    OR UTF8(payload) ILIKE '%pwsh%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

LOLBins (Living Off the Land Binaries)

-- Windows Server Compromise: LOLBins (Living Off the Land Binaries)

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    UTF8(payload) AS "Execution"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    UTF8(payload) ILIKE '%certutil%'
    OR UTF8(payload) ILIKE '%bitsadmin%'
    OR UTF8(payload) ILIKE '%regsvr32%'
    OR UTF8(payload) ILIKE '%rundll32%'
    OR UTF8(payload) ILIKE '%msiexec%'
    OR UTF8(payload) ILIKE '%installutil%'
    OR UTF8(payload) ILIKE '%regasm%'
    OR UTF8(payload) ILIKE '%regsvcs%'
    OR UTF8(payload) ILIKE '%msbuild%'
    OR UTF8(payload) ILIKE '%cmstp%'
    OR UTF8(payload) ILIKE '%odbcconf%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Persistence Mechanisms

Service Installation (4697/7045)

-- Windows Server Compromise: Service Installation (4697/7045)
-- Note: 4697=Security log, 7045=System log. Use qidname() for portability.

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Service"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    qidname(qid) ILIKE '%service%install%'
    OR qidname(qid) ILIKE '%new service%'
    OR qidname(qid) ILIKE '%4697%'
    OR qidname(qid) ILIKE '%7045%'
    OR UTF8(payload) ILIKE '%<EventID>4697</EventID>%'
    OR UTF8(payload) ILIKE '%<EventID>7045</EventID>%'
    OR UTF8(payload) ILIKE '%sc.exe%create%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Scheduled Task Creation (4698/4702)

-- Windows Server Compromise: Scheduled Task Creation (4698/4702)
-- Note: 4698=task created, 4702=task updated. Use qidname() for portability.

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "User",
    UTF8(payload) AS "Task"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    qidname(qid) ILIKE '%scheduled%task%'
    OR qidname(qid) ILIKE '%4698%'
    OR qidname(qid) ILIKE '%4702%'
    OR UTF8(payload) ILIKE '%<EventID>4698</EventID>%'
    OR UTF8(payload) ILIKE '%<EventID>4702</EventID>%'
    OR UTF8(payload) ILIKE '%schtasks%'
    OR UTF8(payload) ILIKE '%at.exe%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Authentication Analysis

Successful Logons (4624)

-- Windows Server Compromise: Successful Logons (4624)
-- Note: qid values are QRadar-specific. Use qidname() fallback for portability.

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    sourceip AS "From IP",
    UTF8(payload) AS "Logon Details"
FROM events
WHERE destinationip = '<target-server-ip>'
  AND (
    qidname(qid) ILIKE '%logon%success%'
    OR qidname(qid) ILIKE '%4624%'
    OR CATEGORYNAME(category) ILIKE '%authentication%success%'
    OR UTF8(payload) ILIKE '%<EventID>4624</EventID>%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Failed Logons (4625)

-- Windows Server Compromise: Failed Logons (4625)
-- Note: qid values are QRadar-specific. Use qidname() fallback for portability.

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    sourceip AS "From IP",
    COUNT(*) AS "Attempts"
FROM events
WHERE destinationip = '<target-server-ip>'
  AND (
    qidname(qid) ILIKE '%logon%fail%'
    OR qidname(qid) ILIKE '%4625%'
    OR CATEGORYNAME(category) ILIKE '%authentication%fail%'
    OR UTF8(payload) ILIKE '%<EventID>4625</EventID>%'
  )
GROUP BY DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss'), username, sourceip
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Account Manipulation

-- Windows Server Compromise: Account Manipulation

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    qidname(qid) AS "Event",
    username AS "Actor",
    UTF8(payload) AS "Details"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND qid IN (
    {win-user-create},  -- 4720 User created
    4722,  -- User enabled
    4723,  -- Password change attempt
    4724,  -- Password reset
    4725,  -- User disabled
    4726,  -- User deleted
    4728,  -- Member added to security group
    4732,  -- Member added to local group
    4756   -- Member added to universal group
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Network Analysis

All Outbound Flows

-- Windows Server Compromise: All Outbound Flows

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    destinationip AS "Dst",
    destinationport AS "Port",
    protocolname(protocolid) AS "Proto",
    sourcebytes AS "Out",
    destinationbytes AS "In"
FROM flows
WHERE sourceip = '<target-server-ip>'
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

External Destinations Only

-- Windows Server Compromise: External Destinations Only

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    destinationip AS "External IP",
    destinationport AS "Port",
    sourcebytes AS "Bytes Out",
    destinationbytes AS "Bytes In"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND NOT INCIDR('10.0.0.0/8', destinationip)
  AND NOT INCIDR('172.16.0.0/12', destinationip)
  AND NOT INCIDR('192.168.0.0/16', destinationip)
  AND NOT INCIDR('127.0.0.0/8', destinationip)
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Lateral Movement Detection

RDP FROM Target Server

-- Windows Server Compromise: RDP FROM Target Server

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    destinationip AS "Target",
    SUM(sourcebytes) AS "Bytes"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND destinationport = 3389
GROUP BY DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss'), destinationip
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

SMB FROM Target Server

-- Windows Server Compromise: SMB FROM Target Server

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    destinationip AS "Target",
    SUM(sourcebytes) AS "Bytes Out",
    SUM(destinationbytes) AS "Bytes In"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND destinationport = 445
GROUP BY DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss'), destinationip
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

PsExec/Admin Share Indicators

-- Windows Server Compromise: PsExec/Admin Share Indicators

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    username AS "User",
    UTF8(payload) AS "Details"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    UTF8(payload) ILIKE '%psexec%'
    OR UTF8(payload) ILIKE '%PSEXESVC%'
    OR UTF8(payload) ILIKE '%\\ADMIN$%'
    OR UTF8(payload) ILIKE '%\\IPC$%'
    OR UTF8(payload) ILIKE '%\\C$%'
  )
ORDER BY starttime ASC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Data Exfiltration Indicators

Large Outbound Transfers (>10MB)

-- Windows Server Compromise: Large Outbound Transfers (>10MB)

SELECT
    DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS "Time",
    destinationip AS "Dst",
    destinationport AS "Port",
    sourcebytes AS "Bytes",
    ROUND(sourcebytes / 1048576.0, 2) AS "MB"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND sourcebytes > 10485760
ORDER BY sourcebytes DESC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

DNS Query Volume (Tunneling Check)

-- Windows Server Compromise: DNS Query Volume (Tunneling Check)

SELECT
    destinationip AS "DNS Server",
    COUNT(*) AS "Queries",
    SUM(sourcebytes) AS "Bytes"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND destinationport = 53
GROUP BY destinationip
ORDER BY "Queries" DESC
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Baseline Comparison

Baseline: Normal Processes

-- Windows Server Compromise: Baseline Normal Processes
-- Note: Use qidname() and payload fallbacks for portability across QRadar deployments.

SELECT
    UTF8(payload) AS "Process",
    COUNT(*) AS "Count"
FROM events
WHERE (sourceip = '<target-server-ip>' OR LOGSOURCENAME(logsourceid) ILIKE '%<target-server-hostname>%')
  AND (
    qidname(qid) ILIKE '%process%creat%'
    OR qidname(qid) ILIKE '%4688%'
    OR UTF8(payload) ILIKE '%<EventID>4688</EventID>%'
    OR CATEGORYNAME(category) ILIKE '%process%'
  )
GROUP BY UTF8(payload)
ORDER BY "Count" DESC
LIMIT 100
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Baseline: Normal Network Destinations

-- Windows Server Compromise: Baseline Normal Network Destinations

SELECT
    destinationip AS "Dst",
    destinationport AS "Port",
    COUNT(*) AS "Flows",
    SUM(sourcebytes) AS "Bytes Out"
FROM flows
WHERE sourceip = '<target-server-ip>'
GROUP BY destinationip, destinationport
ORDER BY "Flows" DESC
LIMIT 100
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

IOC Extraction

Unique External IPs Contacted

-- Windows Server Compromise: IOC - Unique External IPs Contacted

SELECT DISTINCT destinationip AS "External IP"
FROM flows
WHERE sourceip = '<target-server-ip>'
  AND NOT INCIDR('10.0.0.0/8', destinationip)
  AND NOT INCIDR('172.16.0.0/12', destinationip)
  AND NOT INCIDR('192.168.0.0/16', destinationip)
  AND NOT INCIDR('127.0.0.0/8', destinationip)
ORDER BY destinationip
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'

Unique User Accounts

-- Windows Server Compromise: IOC - Unique User Accounts

SELECT DISTINCT username AS "User"
FROM events
WHERE (sourceip = '<target-server-ip>' OR destinationip = '<target-server-ip>')
  AND username IS NOT NULL
  AND username <> ''
ORDER BY username
START '<YYYY-MM-DD> 00:00' STOP '<YYYY-MM-DD> 23:59'