[{"content":"This is the first post in Detection Deep Dive, a series where I take a single ATT\u0026amp;CK technique, trace how real adversaries use it, build the detection logic, and — the part most write-ups skip — say plainly what the detection won\u0026rsquo;t catch.\nWe\u0026rsquo;re starting with one of the most abused sub-techniques in the matrix: encoded PowerShell command execution, T1059.001.\nWhy attackers reach for -EncodedCommand PowerShell\u0026rsquo;s -EncodedCommand (aliases: -enc, -e) accepts a Base64-encoded, UTF-16LE string and executes it. Attackers love it for three reasons: it defeats naive string-matching on command lines, it survives copy-paste and cross-process handoff cleanly, and it\u0026rsquo;s everywhere by default. Loaders, C2 stagers, and living-off-the-land scripts all lean on it.\nHere\u0026rsquo;s what a benign encoded invocation looks like decoded:\n# What the operator typed (harmless example): powershell.exe -NoProfile -EncodedCommand VwByAGkAdABlAC0ASABvAHMAdAAgACIAaABlAGwAbABvACIA # Decoding the Base64 (UTF-16LE) yields: Write-Host \u0026#34;hello\u0026#34; The tell isn\u0026rsquo;t the payload — it\u0026rsquo;s the shape of the invocation: a Base64 blob passed to an encoding flag.\nThe detection Here\u0026rsquo;s a starting-point KQL detection for Microsoft Defender XDR / Advanced Hunting. It looks for the encoding flags across PowerShell process launches:\nDeviceProcessEvents | where Timestamp \u0026gt; ago(24h) | where FileName in~ (\u0026#34;powershell.exe\u0026#34;, \u0026#34;pwsh.exe\u0026#34;) | where ProcessCommandLine matches regex @\u0026#34;(?i)\\s-e(nc(odedcommand)?)?\\s\u0026#34; | extend AccountUpn = tostring(AccountName) | project Timestamp, DeviceName, AccountUpn, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine | sort by Timestamp desc A few deliberate choices:\nin~ and the (?i) flag keep the match case-insensitive — attackers mix case (-EnCoDeD) specifically to dodge case-sensitive rules. Matching the flag family (-e, -enc, -encodedcommand) with one regex catches all abbreviations PowerShell accepts. Pulling InitiatingProcessCommandLine gives you the parent context — a Word document spawning encoded PowerShell is a very different story from a sanctioned admin script. Tuning: the false positives you will get Encoded PowerShell is not inherently malicious. Plenty of legitimate software uses it. If you deploy the query above raw, you\u0026rsquo;ll drown. Here\u0026rsquo;s where the real detection-engineering work is:\nSource of FP How to handle it Endpoint management (SCCM, Intune) Baseline the initiating process; allowlist known management parents Vendor agents \u0026amp; installers Allowlist by signed publisher + expected path Scheduled tasks from IT Correlate against known task GUIDs Your own detection tooling Exclude your SOAR / automation service accounts A more production-shaped version layers exclusions on top:\nDeviceProcessEvents | where Timestamp \u0026gt; ago(24h) | where FileName in~ (\u0026#34;powershell.exe\u0026#34;, \u0026#34;pwsh.exe\u0026#34;) | where ProcessCommandLine matches regex @\u0026#34;(?i)\\s-e(nc(odedcommand)?)?\\s\u0026#34; // --- environment-specific allowlist; tune to YOUR baseline --- | where InitiatingProcessFileName !in~ (\u0026#34;ccmexec.exe\u0026#34;, \u0026#34;intunemanagementextension.exe\u0026#34;) | where not(AccountName has_any (\u0026#34;svc-soar\u0026#34;, \u0026#34;svc-automation\u0026#34;)) | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine | sort by Timestamp desc Don\u0026rsquo;t copy those exclusions blindly — they\u0026rsquo;re placeholders. The point is the method: baseline first, then subtract the known-good.\nWhat this detection can\u0026rsquo;t see Every honest detection write-up needs this section. Attackers who know you\u0026rsquo;re watching for -EncodedCommand will:\nSkip the flag entirely and pipe a decoded string to Invoke-Expression, assembling it from concatenated fragments at runtime. Use alternate execution — System.Management.Automation reflectively loaded inside another process, so powershell.exe never appears on a command line at all. Downgrade to PowerShell v2 to evade script-block logging (-Version 2), which is itself a stronger detection signal than the encoding. The durable lesson: command-line detection is a tripwire for the lazy and the noisy, not a wall against the careful. Pair it with script-block logging (Event ID 4104) and AMSI telemetry, which see the decoded content regardless of how it was passed in. That\u0026rsquo;s a deep dive for a future post.\nTakeaways Encoded PowerShell is cheap to detect at the command-line layer and cheap to evade at the same layer — which is exactly why it belongs in a layered stack, not as a standalone control. Ship the tripwire, tune it against your baseline, and back it with content-layer visibility.\nNext in the series: turning script-block logs into a detection that survives the evasions above.\nHave a technique you want covered? Find me on GitHub or email.\n","permalink":"http://mattswann.dev/posts/detection-deep-dive-encoded-powershell/","summary":"The first entry in the Detection Deep Dive series: mapping encoded PowerShell execution to detection logic in Microsoft Defender, tuning out the false positives, and knowing what the detection can\u0026rsquo;t see.","title":"Detection Deep Dive: Encoded PowerShell Commands (T1059.001)"},{"content":"Back in April of this year, an AI-powered phishing campaign known as EvilTokens took the spotlight in the infosec world. While the term \u0026ldquo;AI-powered\u0026rdquo; is often used as a buzzword these days, it was certainly fitting for this campaign, as an article by Huntress outlined the use of AI in bypassing email filters, generating phishing lures, and even identifying potential targets for the campaign. Adding to the power of the EvilTokens campaign was the fact that it was sold as a Phishing-as-a-Service (PhaaS) platform for as little as a few hundred dollars USD, with full access to the platform costing a mere $1,500 — trivial for most cybercrime organizations.\nIdentifying the campaign The EvilTokens campaign can be identified by a number of indicators. First, despite AI generating a number of unique subject lines, the overall lure theme revolved around a small handful of topics, including bid proposals or RFPs, bogus DocuSigns, fake voicemails, and bogus HR documents. Next was the use of legitimate security vendor redirects — URLs related to Trend Micro, Mimecast, and Cisco — to give the impression of a legitimate link, which would then redirect to the actual phishing landing page. On top of these, the campaign leveraged high-reputation serverless platforms such as Vercel, Cloudflare Workers, and AWS Lambda to host the redirection, further obfuscating the phishing traffic, as reported by Microsoft.\nUltimately, the phishing lure would land at a device code authorization flow page — a technique growing in popularity among threat actors that tricks the victim into copying an attacker-controlled device code into a legitimate Microsoft authorization prompt. That hands the attacker access to the victim\u0026rsquo;s M365 account, enabling token theft and, ultimately, unauthorized access into the victim\u0026rsquo;s M365 tenant.\nThe detection With the above in mind, detecting the campaign is actually quite simple. In one campaign observed by the author, phishing emails matching all of the above characteristics were hitting user inboxes spoofed as coming from the potential victim themselves. The spoofing should immediately throw red flags on SPF, DKIM, and DMARC — and indeed it did — though the email protections at the time did not stop these spoofed emails from hitting user inboxes rather than quarantine or junk. Thankfully, through a single KQL detection query paired with Microsoft Defender for Endpoint (MDE) automation rules, we can build a workflow that quickly deals with these emails.\nLet\u0026rsquo;s start with the query:\nEmailEvents | where tolower(RecipientEmailAddress) == tolower(SenderFromAddress) | extend DKIMcheck = tostring(parse_json(AuthenticationDetails).DKIM) | extend DMARCcheck = tostring(parse_json(AuthenticationDetails).DMARC) | where DKIMcheck contains \u0026#34;none\u0026#34; and DMARCcheck !contains \u0026#34;pass\u0026#34; | where DeliveryLocation contains \u0026#34;Inbox/folder\u0026#34; | where not(EmailDirection contains \u0026#34;Intra-org\u0026#34;) | project TimeGenerated, DKIMcheck, DMARCcheck, DeliveryAction, DeliveryLocation, RecipientEmailAddress, SenderFromAddress, SenderIPv4, Subject, NetworkMessageId, EmailDirection This query leverages the EmailEvents table available in Microsoft Sentinel and MDE, which logs email activity within the M365 tenant. We\u0026rsquo;re looking specifically at emails where the sender and recipient are identical, indicating the spoofing described above. From there, we extract additional DKIM and DMARC details from the JSON-formatted AuthenticationDetails column and filter to find only emails that fail both. Last, we filter on DeliveryLocation to show only emails that land in user inboxes, and filter out intra-org communication to remove false positives. This query showed a 100% success rate at catching every single phishing email attributed to the EvilTokens campaign.\nOperationalizing with MDE automation Once this query is operationalized in MDE, you have the option to set automated actions any time the query fires. An unfortunate intricacy of MDE is that while many tables allow for Near Real Time (NRT) querying and actions, some — including EmailEvents — do not, though the next best option is every 5 minutes.\nFor this query, we set the MDE automated action to run every 5 minutes and delete any emails the query detects. The end effect: while emails may technically still hit user inboxes, they are soft-deleted within 5 minutes — most often before the user has the opportunity to view the email, follow the link, and potentially be phished.\nWithin 48 hours of implementing this query and automation, over 1,200 malicious emails were prevented from being accessed by users, virtually nullifying the entire campaign\u0026rsquo;s effect on the target organization.\nThe takeaway With powerful AI becoming commonplace in both the attacker and defender lifecycle, the barrier to entry for sophisticated phishing has never been lower, and defenders should expect campaigns like this to become the norm rather than the exception. But as flashy as the \u0026ldquo;AI-powered\u0026rdquo; label may be, this campaign also proves that the fundamentals still win. A single well-crafted KQL query paired with a 5-minute automation loop was enough to neutralize over 1,200 malicious emails in two days. No expensive tooling, no LLMs — just a sharp eye for the anomalies attackers can\u0026rsquo;t avoid creating.\nThe takeaway for defenders is simple: when attackers innovate at the lure layer, look for the unchanging fundamentals underneath.\nOriginally published on Medium.\n","permalink":"http://mattswann.dev/posts/eviltokens-kql-phishing/","summary":"An AI-powered PhaaS campaign leaned on legit-vendor redirects and device-code phishing — but spoofing left a fingerprint. One KQL query plus a 5-minute MDE automation loop neutralized over 1,200 malicious emails in 48 hours.","title":"How a Single KQL Query Stopped an Entire EvilTokens Phishing Campaign"},{"content":"I\u0026rsquo;m Matt Swann, a cyber intelligence analyst and detection engineer working across the Microsoft security stack — Sentinel, Defender XDR, Entra ID, and Intune.\nThis site is where I turn threat intelligence into detection logic: KQL detections, malware analysis, and detection-as-code. Most posts fall into one of a few running series:\nDetection Deep Dive — one ATT\u0026amp;CK technique at a time: how it\u0026rsquo;s abused, how to detect it, how to tune it, and what the detection can\u0026rsquo;t see. RaaS Teardown — ransomware-as-a-service groups broken down into TTPs and mapped to detection opportunities. Deobfuscation Lab — static analysis walkthroughs: unpacking obfuscation in scripts and binaries. Detection-as-Code — building a CI/CD pipeline that makes a Git repo the source of truth for detections. Everything here is my own work and opinion, not my employer\u0026rsquo;s.\nFind me: GitHub · LinkedIn · matt@mattswann.dev\n","permalink":"http://mattswann.dev/about/","summary":"About Matt Swann","title":"About"}]