MuddyWater Weaponizing Teams: False Flag Ransomware & Credential Theft
Has anyone else dug into the recent Rapid7 report regarding MuddyWater (Static Kitten) leveraging Microsoft Teams for initial access? It’s a significant shift in TTPs. Instead of the usual phishing email, they are abusing the inherent trust users have in Teams notifications to distribute malware.
The campaign involves threat actors initiating chats from external tenants, posing as technical support to deliver malicious payloads. While they are using ransomware encryption as a "false flag" to confuse attribution, the primary objective appears to be credential theft and establishing persistence.
Detection is tricky because standard email gateways don't scan Teams messages. We need to focus on the OfficeActivity logs. Specifically, look for spikes in TenantAllowBlockList modifications or unusual external user additions.
Here is a basic KQL query I’m using to hunt for suspicious external Teams activity in Sentinel:
OfficeActivity
| where OfficeWorkload == "MicrosoftTeams"
| where Operation == "MemberAdded" or Operation == "TeamMemberAdded"
| where UserId contains "#EXT#"
| extend Domain = extract(@'\@([^\.]*)', 1, UserId)
| project TimeGenerated, Operation, UserId, Domain, OfficeObjectId
| summarize count() by Domain, bin(TimeGenerated, 1h)
We are also considering disabling external Teams access by default via the Teams Admin Center, but that kills collaboration for sales. How are you balancing the security risk of external federation with business continuity needs?
We noticed a similar trend with other APTs recently. Federation is definitely the weak link here. If you can't fully block external access, look into using Conditional Access policies to restrict external Teams access to only managed devices or compliant locations. It doesn't stop the initial invite, but it prevents the payload from running on unmanaged endpoints. Also, check your SigninLogs for failed MFA attempts immediately following these Teams interactions—that's usually the giveaway for the credential theft phase.
Good catch on the KQL. I'd also recommend correlating this with process creation logs on the endpoints. In cases I've analyzed, the user clicks a link in Teams, which downloads a file that executes PowerShell. Look for chains like teams.exe spawning mshta.exe or powershell.exe with encoded commands.
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688} | Where-Object {$_.Message -match 'teams.exe' -and $_.Message -match 'powershell.exe'}
If you see that, you're already owned regardless of the Teams log policy.
We took the nuclear option and blocked external Teams communication for all groups except specific security groups. It was a painful rollout, but the noise reduction in our SOC was immediate. We also implemented a transport rule that alerts whenever an email contains a 'Click to chat in Teams' link, as attackers often pivot back to email if they can't get in directly. It's a whack-a-mole game, but limiting the blast radius is key.
It's crucial to verify that your Defender Safe Links policies explicitly cover Teams. Many admins configure this for email but overlook the Teams setting. You can check your policy status with PowerShell:
Get-SafeLinksPolicy | Select-Object Name, EnableSafeLinksForTeams
If that returns `False`, your users are clicking links without the standard URL detonation checks. We've combined this with user training specifically focused on spotting the "External" tag in chat headers.
Given the credential theft aspect, keep an eye on outbound SMB traffic following these interactions. MuddyWater often attempts to relay credentials or exfiltrate data via SMB. You can hunt for suspicious SMB connections originating from user workstations rather than standard servers:
kusto DeviceNetworkEvents
| where RemotePort == 445
| where InitiatingProcessFileName != "System" and InitiatingProcessFileName != "svchost.exe"
| summarize count() by DeviceName, RemoteIP
To support the Conditional Access suggestions, you should review your tenant's specific federation policies to ensure you aren't broadly allowing unknown domains. You can check your current external communication policy with this snippet:
Get-CsExternalAccessPolicy -Global | Select-Object Identity, EnableFederationAccess
This helps verify your baseline posture before locking it down further.
Verified Access Required
To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.
Request Access