Query Details

HUNT 07 M365 Teams Apps Bots Installed 90d

Query

// Hunt    : M365 - Teams Bots and Apps Installed Timeline (90d)
// Purpose : Full inventory of all bots, tabs, and apps installed into Teams
//           over 90 days, with publisher and installer enrichment.
//           Supports shadow IT discovery and post-compromise persistence review.
// Tables  : OfficeActivity
// Period  : P90D
//==========================================================================================

let LookbackDays = 90d;

OfficeActivity
| where TimeGenerated > ago(LookbackDays)
| where RecordType == "MicrosoftTeams"
| where Operation in (
    "AppInstalled", "BotAddedToTeam", "TabAdded",
    "ConnectorAdded", "SideLoadedApp",
    "AppUpgraded", "AppUninstalled")
| extend
    AppName       = tostring(ExtraProperties[0].Value),
    AppPublisher  = tostring(ExtraProperties[1].Value)
| extend AppNameLower = tolower(AppName)
| extend IsSuspicious = AppNameLower has_any (dynamic([
    "ngrok", "webhook", "tunnel", "shell", "exec", "proxy", "revealer",
    "forward", "exfil", "bypass", "pentest", "hack", "rat "
]))
| summarize
    InstallCount  = count(),
    Teams         = make_set(TeamName, 15),
    Channels      = make_set(ChannelName, 10),
    Installers    = make_set(UserId, 10),
    FirstInstall  = min(TimeGenerated),
    LastInstall   = max(TimeGenerated),
    IsSuspicious  = any(IsSuspicious)
    by AppName, AppPublisher, Operation
| sort by IsSuspicious desc, InstallCount desc
| project
    AppName,
    AppPublisher,
    Operation,
    InstallCount,
    Teams,
    Channels,
    Installers,
    IsSuspicious,
    FirstInstall,
    LastInstall

Explanation

This query is designed to provide a comprehensive overview of all bots, tabs, and apps installed in Microsoft Teams over the past 90 days. It helps in identifying potential shadow IT activities and reviewing any post-compromise persistence. Here's a simplified breakdown of what the query does:

  1. Data Source: It pulls data from the OfficeActivity table, focusing on activities related to Microsoft Teams.

  2. Time Frame: It looks at activities from the last 90 days.

  3. Activity Filtering: It filters for specific operations such as app installations, bot additions, tab additions, connector additions, side-loaded apps, app upgrades, and app uninstallations.

  4. Data Enrichment:

    • Extracts the app name and publisher from the activity details.
    • Converts the app name to lowercase for consistency.
  5. Suspicion Check: It flags apps as suspicious if their names contain certain keywords associated with potentially risky activities (e.g., "ngrok", "webhook", "tunnel", etc.).

  6. Data Aggregation:

    • Counts the number of installations.
    • Lists up to 15 teams and 10 channels where the app was installed.
    • Lists up to 10 users who installed the app.
    • Records the first and last installation dates.
    • Indicates if any installation was flagged as suspicious.
  7. Sorting and Presentation:

    • Sorts the results by suspicion status and installation count.
    • Displays relevant information such as app name, publisher, operation type, installation count, involved teams and channels, installers, suspicion status, and installation dates.

This query is useful for IT administrators to monitor and manage app usage within Teams, ensuring compliance and security.

Details

David Alonso profile picture

David Alonso

Released: March 18, 2026

Tables

OfficeActivity

Keywords

OfficeActivityMicrosoftTeamsAppNameAppPublisherTeamNameChannelNameUserIdTimeGenerated

Operators

letagoinextendtostringtolowerhas_anydynamicsummarizecountmake_setminmaxanybysortdescproject

Actions