<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Still learning. Still fixing.</title>
  <link>https://maldito.me/blog/</link>
  <atom:link href="https://maldito.me/blog/feed.xml" rel="self" type="application/rss+xml"/>
  <description>Notes on modern workplace, identity and security.</description>
  <language>en-au</language>
  <lastBuildDate>Wed, 28 Oct 2026 03:39:15 +0000</lastBuildDate>
  <item>
    <title>Before you block legacy authentication, find out who still uses it</title>
    <link>https://maldito.me/blog/legacy-auth-before-you-block/</link>
    <guid isPermaLink="true">https://maldito.me/blog/legacy-auth-before-you-block/</guid>
    <pubDate>Tue, 13 Oct 2026 09:00:00 +0000</pubDate>
    <description>Blocking legacy auth is a one-click policy and one of the most effective. The click is easy. Knowing what breaks when you click it is the actual work.</description>
    <content:encoded><![CDATA[<p>Legacy authentication is any sign-in that uses a protocol which can't do MFA: IMAP, POP, SMTP AUTH, Exchange ActiveSync with basic auth, older Office clients, and a long tail of "other clients". If an attacker has a password, legacy auth is how they use it without being challenged.</p>
<p>Microsoft turned basic auth off in Exchange Online for most protocols a while ago, so a lot of people assume this is done. It isn't quite. SMTP AUTH can still be enabled per mailbox, third-party apps still try, and Conditional Access is the thing that actually says no.</p>
<h2>Look first</h2>
<p>The Entra sign-in logs will tell you exactly who is still using it. Filter on <strong>Client app</strong> and tick everything under <em>Legacy Authentication Clients</em>. Go back thirty days. What you'll find, nearly every time:</p>
<ul><li>a <strong>multifunction printer</strong> scanning to email over SMTP AUTH using a real user's credentials,</li><li>a <strong>line-of-business system</strong> sending notifications the same way,</li><li>a <strong>shared mailbox</strong> someone checks from an old mail client on their phone,</li><li>a handful of <strong>service accounts</strong> whose owners left years ago.</li></ul>
<p>There is also a built-in workbook, <em>Sign-ins using Legacy Authentication</em>, which gives you the same view with charts, which is useful when you have to show someone why this matters.</p>
<h2>Fix the holdouts, then block</h2>
<p>Each holdout has a proper home:</p>
<p><strong>Printers and apps that send mail.</strong> Options, in order of preference: Microsoft's <em>High Volume Email</em> or Azure Communication Services Email for anything that sends a lot; direct send via your MX record for internal-only notifications; an SMTP relay connector scoped to the device's IP if it must relay externally; or, as a last resort, SMTP AUTH enabled on one dedicated mailbox with a strong password and no other access. The thing to avoid is the printer using a person's account.</p>
<p><strong>Old mail clients.</strong> The person updates the app, or uses Outlook. This is a conversation, not a project.</p>
<p><strong>Orphaned service accounts.</strong> Disable, wait two weeks, delete.</p>
<p>Then the policy. Conditional Access has a template for it: <strong>Block legacy authentication</strong>, all users, all resources, client apps set to the legacy categories, grant block. Put the break-glass accounts in the exclusion and nothing else. Run it in report-only for a week first and check the log for anything you missed, then turn it on.</p>
<h2>The part people forget</h2>
<p>The policy stops the <em>sign-in</em>. It doesn't change the mailbox setting that allows SMTP AUTH, which means if someone later creates an exclusion, the door is open again. Disable SMTP AUTH at the organisation level in Exchange Online (<code>Set-TransportConfig -SmtpClientAuthenticationDisabled $true</code>) and enable it only on the one mailbox that genuinely needs it. Two layers; either one covers for the other.</p>
<p>It is a small piece of work, usually a day or two spread across a fortnight. I'd put it ahead of almost anything else on a tenant hardening list, because it closes the one path where a stolen password is enough on its own.</p>]]></content:encoded>
  </item>
  <item>
    <title>The two Essential Eight controls everyone underestimates</title>
    <link>https://maldito.me/blog/essential-eight-underestimated/</link>
    <guid isPermaLink="true">https://maldito.me/blog/essential-eight-underestimated/</guid>
    <pubDate>Tue, 25 Aug 2026 09:00:00 +0000</pubDate>
    <description>Application control and patching look like the simple ones on paper. In practice they are where most Essential Eight uplifts stall, and for the same reason.</description>
    <content:encoded><![CDATA[<p>When an organisation decides to get serious about the Essential Eight, the conversation usually starts with MFA and admin privileges. Fair enough; those are visible and the tooling is mature. The two that end up consuming the budget are the ones that looked easy in the planning workshop: <strong>application control</strong> and <strong>patch applications</strong>.</p>
<p>They stall for the same reason. Both require you to know what's actually running on your fleet, and almost nobody does.</p>
<h2>Application control</h2>
<p>The maturity model wants you to prevent the execution of unapproved executables, scripts, installers, compiled HTML and the rest, from user-writable locations at Maturity Level One, then everywhere at Level Two, with rulesets validated annually and a growing list of blocked drivers and known-bad binaries as you go up.</p>
<p>The technology is not the hard part. Windows Defender Application Control (now App Control for Business) or AppLocker will do it, and Intune will push it. The hard part is the week after you turn on audit mode and discover:</p>
<ul><li>the finance team runs a macro-enabled workbook that shells out to a console app nobody has seen since 2014,</li><li>the engineers have a <code>tools</code> folder in their profile that every one of them depends on,</li><li>three line-of-business apps update themselves by dropping a new executable into <code>%LocalAppData%</code>.</li></ul>
<p>None of that shows up in an application inventory. It only shows up in audit logs, which is why audit mode is not optional and three months of it is not excessive. Collect the events centrally (the Intune device log collection or a Log Analytics workspace will do), build the allow rules from what you see, and publish rules by <strong>publisher</strong> wherever the binary is signed, so an update doesn't become a block.</p>
<p>The thing to avoid is the shortcut where someone allows an entire path because it was noisy. A rule that allows everything under <code>C:\Program Files</code> sounds reasonable until you remember that's a writable location for a lot of installers. Keep path rules for places standard users can't write to, and nothing else.</p>
<h2>Patch applications</h2>
<p>The requirement reads simply: patch within 48 hours when an exploit exists, otherwise within two weeks, for internet-facing services and the apps that interact with untrusted content; remove the things the vendor no longer supports; and use a vulnerability scanner to find what you missed.</p>
<p>What stalls it:</p>
<p><strong>The 48 hours.</strong> Not the patching, the deciding. If the only way to know a vulnerability is being exploited is for someone to read advisories in the evening, you won't make 48 hours. Subscribe to the ASD alerts and the CISA Known Exploited Vulnerabilities feed, and give one person the job of reading them.</p>
<p><strong>Apps that aren't yours.</strong> Windows Update for Business handles Windows and Office well. It does nothing for the PDF reader, the browser you don't standardise on, Java, the VPN client, and the forty other things people installed. You need either the Microsoft Store apps via Intune (good, where the app is there), an app catalogue like the Enterprise App Catalog or a third-party patching tool, or a willingness to repackage. Pick one; the mixed approach is where things get missed.</p>
<p><strong>Unsupported software.</strong> Every fleet has it. The old Access runtime, the scanner driver tool, the EOL browser kept "for one system". Removal is a conversation with the business, not a technical task, and it is better had early.</p>
<p><strong>The scanner.</strong> Defender Vulnerability Management is already there if you have the licence, and it is the fastest way to turn "we think we're patched" into a list. Run it before you declare the control met, not after the assessor asks.</p>
<h2>Why they're worth it</h2>
<p>Both controls do the same thing from different angles: they stop attacker code from running on your endpoints. Everything else in the Essential Eight limits the damage once it's running. That's why these two are hard, and why they matter most.</p>
<p>If you're planning an uplift, put them first on the timeline, not last, and give them the audit period they need. The rest of the eight will go faster for it.</p>]]></content:encoded>
  </item>
  <item>
    <title>Why your Autopilot devices sit on the Enrollment Status Page</title>
    <link>https://maldito.me/blog/autopilot-esp-stalls/</link>
    <guid isPermaLink="true">https://maldito.me/blog/autopilot-esp-stalls/</guid>
    <pubDate>Tue, 07 Jul 2026 09:00:00 +0000</pubDate>
    <description>The ESP is where Autopilot goes to die. Nearly every stall comes down to one of five causes, and none of them are mysterious once you know where to look.</description>
    <content:encoded><![CDATA[<p>A device that sits at "Identifying" or "Preparing your device for management" for forty minutes is the most common Autopilot complaint I get. The person watching it assumes something is broken. Usually nothing is broken; the device is waiting for something that was never going to arrive.</p>
<p>Here are the five causes I see over and over, roughly in order.</p>
<h2>1. The profile hasn't been assigned yet</h2>
<p>"Identifying" means the device is checking whether it has an Autopilot profile. If the hardware hash was uploaded five minutes ago, the profile assignment can take a while to catch up, and the device will keep asking. Check the device in Intune under <strong>Windows Autopilot devices</strong>; the profile status should say <em>Assigned</em>, not <em>Pending</em>. If it is pending, wait, don't rebuild.</p>
<h2>2. Too many apps are blocking</h2>
<p>The ESP tracks the apps you tell it to track, and it won't let the user through until they're installed. The default is <em>all</em> required apps. On a fleet with twenty required Win32 apps, that's twenty installs, some with dependencies, some with detection rules that misfire, all before the user sees a desktop.</p>
<p>Pick the three or four apps the person needs to be productive in the first hour (the security agent, the VPN client, the browser) and block on those only. Everything else installs in the background once they're in.</p>
<h2>3. A detection rule that never comes true</h2>
<p>An app that installs fine but whose detection rule looks for a version string that doesn't match will report as failed, and the ESP will wait for a retry that fails the same way. Test detection rules on a machine that already has the app, before you make the app blocking.</p>
<h2>4. Hybrid join waiting on a domain controller</h2>
<p>Hybrid Entra join during Autopilot needs line of sight to a domain controller for the device to finish the join. If the device is at someone's kitchen table, it doesn't have that. The ESP sits there, and so does the user.</p>
<p>If you are still doing hybrid join for new devices, this is the moment to ask whether you need to. Entra-joined with Intune, plus Cloud Kerberos Trust for the things that still need on-premises access, is a simpler device that doesn't stall.</p>
<h2>5. The timeout is doing its job</h2>
<p>The ESP has a timeout, 60 minutes by default. When it fires, the user gets an error and the device is left half-configured. People read this as the cause; it's the symptom. Something above took longer than an hour.</p>
<h2>Where to look</h2>
<ul><li>On the device, during the ESP: <code>Shift+F10</code> opens a command prompt. The log worth reading is <code>C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log</code>. It shows which app it is waiting on and why.</li><li>In Intune: <strong>Devices &gt; Monitor &gt; Autopilot deployments</strong> shows each phase and how long it took, which tells you where the time went across the fleet rather than one machine.</li><li>Turn on <strong>Show app and profile configuration progress</strong> in the ESP profile if it is off. People tolerate a wait they can see.</li></ul>
<h2>The settings I ship</h2>
<p>For most customers: ESP on, show progress, block on three apps, timeout 60 minutes, <em>don't</em> allow the user to reset the device on failure (they'll just do it again), and a plain-English message that tells them who to call. The rest is making sure those three apps always install.</p>
<p>Autopilot is a good tool. It just does exactly what it's told, and the ESP is where you find out what you told it.</p>]]></content:encoded>
  </item>
  <item>
    <title>The Conditional Access exclusions that quietly undo MFA</title>
    <link>https://maldito.me/blog/conditional-access-exclusions/</link>
    <guid isPermaLink="true">https://maldito.me/blog/conditional-access-exclusions/</guid>
    <pubDate>Tue, 19 May 2026 09:00:00 +0000</pubDate>
    <description>Most tenants I review have MFA &quot;enforced&quot;. Most of them also have a handful of exclusions that mean it isn&#x27;t. Here is where they hide.</description>
    <content:encoded><![CDATA[<p>When I'm asked to look at a Microsoft 365 tenant, the first thing I check isn't whether MFA is turned on. It almost always is. The question is who it is turned on <em>for</em>, and the answer is usually "everyone, except...".</p>
<p>Those exceptions are the interesting part. Every one of them was added for a reason that made sense on the day. Nobody went back.</p>
<h2>Where the gaps live</h2>
<p><strong>The exclusion group that grew.</strong> The policy excludes a group called something like <code>CA-Exclude-MFA</code>. It was created for one vendor account during a migration. Two years later it has forty members: ex-contractors, a shared mailbox someone signs into, the CEO's assistant, a few people who "had trouble with the app". Open the group and read the membership. Then ask who owns it. Nobody will.</p>
<p><strong>Break-glass accounts without a fence.</strong> You should have emergency access accounts excluded from Conditional Access; that part is right. But they need a long random password in a safe place, no licences, and an alert the moment they sign in. Half the tenants I see have the exclusion and none of the rest.</p>
<p><strong>Trusted locations.</strong> "Don't prompt for MFA from the office" was a kindness in 2019. It is now a policy that says anyone on the office Wi-Fi, including the guest network if the ranges overlap, is trusted. Check the named location's IP ranges against what the network team actually runs today. They have usually changed.</p>
<p><strong>Selected apps instead of all apps.</strong> A policy targeting "Office 365" and a few named apps leaves everything else open: Azure management, Graph Explorer, third-party apps registered later. Target all resources and exclude deliberately, not the other way around.</p>
<p><strong>Device platform conditions.</strong> A policy that only applies to Windows and macOS is a policy that doesn't apply to anything that presents a different user agent. Platform is a hint, not a control. If the intent is "only managed devices", say that with a device compliance or hybrid join requirement.</p>
<p><strong>Report-only forever.</strong> A well-designed policy sitting in report-only mode for eighteen months is doing exactly nothing. Report-only is a staging step, not a destination.</p>
<h2>How I find them</h2>
<ol><li>Export every policy. The Entra portal will do it one at a time; the Graph PowerShell module will do it in one go: <code>Get-MgIdentityConditionalAccessPolicy | ConvertTo-Json -Depth 10</code>.</li><li>For each policy, list the excluded users, groups and roles. Resolve the groups to people.</li><li>Open the sign-in logs, filter for interactive sign-ins where Conditional Access shows <strong>Not applied</strong> or <strong>Success</strong> with no MFA, and look at who those accounts are.</li><li>Use the <em>What If</em> tool for the accounts you're worried about. It is the fastest way to see what a specific person is actually subject to.</li></ol>
<p>The output of that is a short list of named accounts that can sign in with a password alone. That list is the real MFA coverage of the tenant, whatever the dashboard says.</p>
<h2>Fixing it without breaking things</h2>
<p>Don't delete the exclusion group. Empty it one member at a time, with a reason recorded against each removal, and give each person a week's warning. Vendor accounts move to a policy of their own with a tighter scope. Shared mailboxes stop having people sign into them directly. The break-glass accounts get their alert.</p>
<p>It's unglamorous work. It is also the single change that most improves a tenant's security posture, because the attacker doesn't care about your policy. They care about the forty accounts it doesn't cover.</p>]]></content:encoded>
  </item>
</channel>
</rss>
