RatHat Android Malware – ADB Shell Persistence, Credential Theft, and AI-Assisted Control

Threat Overview

Zimperium researchers disclosed RatHat, an Android malware family distributed through smishing, malvertising, deceptive download portals, and third-party forums. The victim must install a malicious APK and grant powerful Accessibility permissions. RatHat then automates Developer Options and Wireless Debugging, reads the local ADB pairing code, and pairs with the device’s ADB daemon to obtain shell-level execution. It stages a Go agent as liblocal-service.so and an FRP client as libmedia_codec.so. The independent agent can survive removal of the visible app and reinstall it.

References

Impacted Systems

Android devices where users can sideload APKs and grant Accessibility permissions. Infection requires social engineering and user installation and is not a zero-click exploit. RatHat abuses Wireless Debugging and local ADB self-pairing to obtain shell context. Enterprise exposure is highest for unmanaged or weakly controlled Android devices used for corporate identity, MFA, banking, or privileged access.

Why this matters

RatHat can steal credentials and OTPs while maintaining shell access outside the visible application’s lifecycle. A compromised mobile device can become an identity-compromise vector even after the user believes the malicious app was removed.

Exploitation Status

Confirmed malware campaign documented by Zimperium. Distribution uses social engineering rather than exploitation of an Android zero-day. Researcher attribution points to operators likely based in China, but that is not evidence of state sponsorship.

What this hunt looks for

Sentinel cannot directly observe Android ADB and Accessibility behavior without specialized mobile telemetry. The available hunt identifies managed Android users and pivots to new sign-in IPs, risky sign-ins, authentication-method changes, and unusual geography.

Required logs

IntuneDevices plus Entra SigninLogs and AuditLogs ingested into Microsoft Sentinel. Direct RatHat detection requires mobile EDR or MTD telemetry that is not assumed here.

First Pass – Managed Android Device Inventory

IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize arg_max(TimeGenerated, *) by DeviceId
| project TimeGenerated,DeviceName,UserEmail,Manufacturer,Model,OS,OSVersion,ComplianceState,LastContact
| order by TimeGenerated desc

Android Devices by User

IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize LastSeen=max(TimeGenerated),Devices=make_set(DeviceName,20),Models=make_set(Model,20),OSVersions=make_set(OSVersion,20) by UserEmail
| order by LastSeen desc

Android Users With New Sign-In IPs

let AndroidUsers=IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize by UserEmail;
let Known=SigninLogs
| where TimeGenerated between (ago(30d)..ago(2d))
| join kind=inner AndroidUsers on $left.UserPrincipalName == $right.UserEmail
| summarize by UserPrincipalName,IPAddress;
SigninLogs
| where TimeGenerated >= ago(2d)
| join kind=inner AndroidUsers on $left.UserPrincipalName == $right.UserEmail
| join kind=leftanti Known on UserPrincipalName,IPAddress
| project TimeGenerated,UserPrincipalName,IPAddress,AppDisplayName,ClientAppUsed,DeviceDetail,LocationDetails,ResultType
| order by TimeGenerated desc

Android Users With Risky Sign-Ins

let AndroidUsers=IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize by UserEmail;
SigninLogs
| where TimeGenerated >= ago(14d)
| join kind=inner AndroidUsers on $left.UserPrincipalName == $right.UserEmail
| where RiskLevelDuringSignIn !in~ ("none","hidden","")
| project TimeGenerated,UserPrincipalName,IPAddress,AppDisplayName,RiskLevelDuringSignIn,RiskState,RiskDetail,DeviceDetail,LocationDetails
| order by TimeGenerated desc

Android Users With Authentication Method Changes

let AndroidUsers=IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize by UserEmail;
AuditLogs
| where TimeGenerated >= ago(30d)
| where OperationName has_any ("authentication method","security info")
| mv-expand TargetResources
| extend TargetUPN=tostring(TargetResources.userPrincipalName)
| join kind=inner AndroidUsers on $left.TargetUPN == $right.UserEmail
| project TimeGenerated,OperationName,TargetUPN,InitiatedBy,Result,ResultReason
| order by TimeGenerated desc

Android Users With Suspicious Session Geography

let AndroidUsers=IntuneDevices
| where TimeGenerated >= ago(30d)
| where OS has "Android"
| summarize by UserEmail;
SigninLogs
| where TimeGenerated >= ago(14d)
| join kind=inner AndroidUsers on $left.UserPrincipalName == $right.UserEmail
| summarize Countries=make_set(tostring(LocationDetails.countryOrRegion),20),IPs=make_set(IPAddress,50),Apps=make_set(AppDisplayName,30),FirstSeen=min(TimeGenerated),LastSeen=max(TimeGenerated) by UserPrincipalName
| where array_length(Countries) > 1
| order by LastSeen desc

Detection Notes

There is no reliable Sentinel-native ADB or Accessibility event source in the stated customer inventories. The first-pass query is asset identification. Identity anomalies are indirect and may be benign. Direct detection of the native libraries, Wireless Debugging activation, or FRP tunnels requires mobile EDR or MTD telemetry.

Leave a comment