toast my way

abusing Windows toast notifications for fun and user manipulation

I wasn’t looking for this. I was casually going through the COM interfaces available on a Windows 11 box, doing what I often do when I have a bit of free time and a vague sense that something interesting is hiding in there. And then I stumbled into something I hadn’t really thought about before: the exact mechanism Windows uses to generate toast notifications.

You know those little pop-ups that appear in the corner of your screen telling you Edge has an update, or that Teams has a new message, or that your security center detected something? Yeah, those. Turns out, under the hood, they’re just WinRT API calls. And if you can make WinRT API calls, you can send whatever you want.

That’s a pretty interesting detail if you already have a implant running in user context.

the basics

Everything starts with an AUMID (Application User Model ID), it’s the identifier Windows uses to associate a notification with a specific application: its icon, its name, its place in the notification center. In order to send a toast, you need one of them.

The good news is, you don’t need to register a new app. There are already plenty of AUMIDs registered on any standard Windows machine. MSEdge, Microsoft Teams, Windows Security and many more, all sitting there ready to be borrowed. And here’s the interesting part that, honestly, I wasn’t aware of: you don’t need to launch the notification from the actual process that owns that AUMID, so wherever you are you can spawn toast notification for any AUMID.

AUMIDs are not generated on the fly, they already exist because applications registered them to integrate with the Windows shell. If you want the full picture, just checks Microsoft Docs. What matters to us is that they’re already sitting there, ready to be borrowed.

That said, getting the list of AUMID is straightforward:

Note: For simplicity, I’m using PowerShell for all the PoCs in this post.
$uwp = Get-StartApps | Select-Object -ExpandProperty AppID
$lnk = & {
    $paths = @(
        "$env:APPDATA\Microsoft\Windows\Start Menu\Programs",
        "$env:ProgramData\Microsoft\Windows\Start Menu\Programs"
    )
    $shell = New-Object -ComObject Shell.Application

    foreach ($path in $paths) {
        Get-ChildItem $path -Recurse -Filter *.lnk -ErrorAction SilentlyContinue | ForEach-Object {
            $folder = $shell.Namespace($_.DirectoryName)
            $item = $folder.ParseName($_.Name)
            $item.ExtendedProperty("System.AppUserModel.ID")
        }
    }
}

($uwp + $lnk) | Where-Object { $_ } | Sort-Object -Unique

With that list in hand, sending a notification is almost embarrassingly simple:

Add-Type -AssemblyName System.Runtime.WindowsRuntime

[Windows.UI.Notifications.ToastNotificationManager,Windows.UI.Notifications,ContentType=WindowsRuntime]
[Windows.Data.Xml.Dom.XmlDocument,Windows.Data.Xml.Dom.XmlDocument,ContentType=WindowsRuntime]

$AUMID = "MSEdge"       # the AUMID string

$xml = @"
<toast>
  <visual>
    <binding template="ToastGeneric">
      <text>Important Update</text>
      <text>Something requires your attention.</text>
    </binding>
  </visual>
</toast>
"@

$doc = New-Object Windows.Data.Xml.Dom.XmlDocument
$doc.LoadXml($xml)

$toast = [Windows.UI.Notifications.ToastNotification]::new($doc)
$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AUMID)
$notifier.Show($toast)

That’s a simple way to send a toast notification as… Microsoft Edge.

so what do you actually do with it?

Here’s where it gets interesting, at least to me. If you have an implant running in user context, you’re not always in a position to escalate immediately, or maybe escalation isn’t even the objective. But you’re sitting right there, in the middle of an active user session, quietly thinking about how to wrap this job up before AI replaces you. And sometimes, a simple question comes to mind: how do you get that person to do something useful for you?

The answer, historically, has involved all sorts of creativity. But toast notifications are a surprisingly elegant channel for this, because they look completely legitimate, they appear from apps the user already trusts, and they can carry interactive elements like buttons, text inputs, protocol links.

What can you actually pull off?

send them to a page

Maybe you want credentials, maybe you want to let them know that the red team is watching you (hi, soc guys!), maybe you just need them to hit a URL you control. A well-crafted notification from MSEdge or Defender with a single “Open” button and a convincing line of text is enough for a lot of users.

<toast>
  <visual>
    <binding template="ToastGeneric">
      <text>Action Required</text>
      <text>Your session requires re-authentication. Click to continue.</text>
    </binding>
  </visual>
  <actions>
    <action content="Continue"
            activationType="protocol"
            arguments="https://your-page-here.com"/>
  </actions>
</toast>

simulate a Teams message

This is where the format really starts pulling its weight. Teams notifications aren’t just title and text: they support sender names, circular avatar overrides, hero images, and inline reply inputs. The whole thing. You can build something that, at a glance, is indistinguishable from a real incoming message from a real person in the org. A name the target recognizes, a face, a short message with just enough context to feel legitimate. The user sees it, they tap it, they go wherever you tell them.

Here’s a hypothesis I find genuinely interesting — call it lateral movement through social engineering. You identify someone with a bit of weight in a team: a lead, a manager, someone people listen to. You send them a notification that looks like a message from a trusted colleague, get them into a call with your social engineering expert. The target is already primed: they clicked because they trusted the sender, they joined because it felt urgent but routine. From there, the expert works the angle with something needs to be resolved right now, the whole team should be looped in so, let’s get everyone together fast. One person trusts you, convinces a group, trust boundaries collapse. Suddenly you’ve gone from a single compromised session to the whole team on a call you control.

fake a security alert

This is a fun one, because it’s genuinely effective on a certain category of targets. Using the Windows Security AUMID (Microsoft.SecHealthUI_xxx), you can push something that looks like a high-severity incident notification, complete with a progress bar showing telemetry processing, severity selectors, and a “Join Meeting” button pointing to whatever you want. For users who take security alerts seriously, this hits differently. If the goal is to get someone to install a tool, join a call, or pull in colleagues, the urgency framing does a lot of the heavy lifting.

But the truth is: non of these are magic, the technique lives and dies on pretext like everything in social engineering. But the delivery channel is unusually clean: it’s native, trusted and it disappears from the notification center on its own.

the toolkit

After playing with these ideas for a while, I wrapped the core functionality into a proper tool: toastnotify-bof.

toastnotify-bof

It’s a BOF that exposes three subcommands: getaumid, sendtoast, and custom.

The getaumid is self-explanatory, sendtoast let you send a simple Title-Body notification for any AUMID. The custom subcommand is where the flexibility lives and where you’ll spend most of your time smashing your head on pretext. Instead of building the XML internally, it takes a base64-encoded payload directly so you can craft arbitrarily complex toast templates (progress bars, selection inputs, images, protocol actions) and deliver them without recompiling anything.

inline-execute toastnotify.o go custom MSEdge <base64-xml-string>

closing thoughts

There’s something almost poetic about this. Windows built an entire notification system designed to pull user attention toward legitimate apps and that same system is perfectly happy to be pointed wherever you want, no questions asked, using identities it already has registered.

If the user clicks, it’s a good day. If they don’t, well, it was just a notification. Not every technique needs to be clever and sometimes the right move is just to ask nicely, from an app they already trust.

This isn’t dark magic, I know. Realistically, there are only a few things you can do with this kind of “toast notification abuse”, and they’re pretty specific, but it was fun to think about. And that’s why I’m sharing it here, I don’t think this kind of research is going to change anything in the offensive field, but I think it could help other red teamers with some very specific tasks during ops.


theme: researcher by ankit sultana