Impersonation von GCP-Dienstkonten: die Kette nachverfolgen
Impersonation von Dienstkonten in GCP-Audit-Logs verfolgen: GenerateAccessToken, SignBlob, serviceAccountDelegationInfo, actAs und Token-Creator-Rollen.
Kurz gesagt. Die Impersonation von Dienstkonten hinterlässt zwei Spuren. Der Aufruf zur Ausstellung (GenerateAccessToken, GenerateIdToken, SignBlob, SignJwt in iamcredentials.googleapis.com) ist ein Data-Access-Log und existiert daher nur, wenn das Data-Access-Logging für IAM aktiv war. Die Nutzung des Tokens erscheint in den Logs des Zieldienstes, mit dem Dienstkonto in principalEmail und dem eigentlichen Aufrufer in authenticationInfo.serviceAccountDelegationInfo. Lesen Sie beide und prüfen Sie, wer überhaupt die Rolle Token Creator oder Service Account User erhalten hat.
Impersonation ist legitim und sogar empfohlen: Sie ersetzt herunterladbare Schlüssel durch kurzlebige Tokens. Sie ist zugleich einer der meistgenutzten Wege zur Rechteausweitung in Google Cloud, weil die Berechtigung, die sie erlaubt, iam.serviceAccounts.getAccessToken, oft großzügig vergeben wird. Die Forschung von Rhino Security Labs zur Rechteausweitung in GCP führt getAccessToken, signBlob, signJwt und implicitDelegation als eigene Eskalationsmethoden auf.
Impersonation oder Schlüssel?
Google zieht die Grenze in seiner Dokumentation zur Impersonation klar: Bei der Impersonation sind zwei Identitäten beteiligt (die authentifizierte Identität und das Dienstkonto), bei der Authentifizierung mit einem Schlüssel nur eine. Für Ermittler heißt das:
| Mechanismus | Woran er in den Logs zu erkennen ist |
|---|---|
| Nutzerverwalteter Schlüssel | authenticationInfo.serviceAccountKeyName (siehe geleakter Schlüssel) |
| Impersonation (Token über die IAM Credentials API ausgestellt) | serviceAccountDelegationInfo in den Aufrufen, GenerateAccessToken in den Data-Access-Logs |
| Angehängtes Dienstkonto (VM, Cloud Run, Cloud Functions) | Aufrufe als Dienstkonto, typischerweise von der IP des Workloads, kein Schlüsselname, keine Delegation |
| Workload Identity Federation | principalSubject wie principal://… oder Delegationsinformationen mit einer Drittanbieter-Identität |
Die dritte Zeile ist wichtig: Ein vom Metadatenserver einer VM gestohlenes Token (T1552.005) ist in den Logs keine Impersonation; es sieht aus wie das Dienstkonto der VM, nur von woanders aufgerufen.
Spur 1: der Ausstellungsaufruf
Laut Googles Seite zum Audit-Logging der Service Account Credentials werden diese Methoden unter cloudaudit.googleapis.com/data_access mit dem Dienst iamcredentials.googleapis.com erfasst. Wer Data-Access-Audit-Logs für die IAM API aktiviert, aktiviert sie auch für diese API.
protoPayload.serviceName="iamcredentials.googleapis.com"
protoPayload.methodName=("GenerateAccessToken" OR "GenerateIdToken" OR "SignBlob" OR "SignJwt")
In diesen Einträgen ist principalEmail der Aufrufer (der eigentliche Akteur oder das vorherige Glied der Kette), und das Ziel-Dienstkonto steht in resource.labels.email_id und resourceName, wie Googles Beispiel-Logs zeigen. SignBlob und SignJwt verdienen besondere Aufmerksamkeit: Ein als Dienstkonto signiertes JWT lässt sich gegen ein Token tauschen, und mit signierten Blobs lassen sich signierte URLs fälschen.
Spur 2: die mit dem Token getätigten Aufrufe
Jeder API-Aufruf mit einem Token aus einer Impersonation trägt die Kette:
"authenticationInfo": {
"principalEmail": "deployer@PROJECT.iam.gserviceaccount.com",
"serviceAccountDelegationInfo": [
{ "firstPartyPrincipal": { "principalEmail": "alice@example.com" } }
]
}
Das steht in den Admin-Activity-Logs, die immer aktiv sind. Selbst wenn der Ausstellungsaufruf unsichtbar ist, nennen die mit dem Token getätigten Schreibzugriffe also weiterhin den eigentlichen Aufrufer. Oft ist das die einzige Spur, die Sie bekommen.
Ketten
Impersonation lässt sich verketten: A nimmt die Identität von B an, B die von C (der Parameter delegates von GenerateAccessToken; jeder Schritt erfordert eine Berechtigung für das nächste Dienstkonto, die die Rolle Token Creator liefert). Die Kette wird in serviceAccountDelegationInfo als Array erfasst. So rekonstruieren Sie sie:
- Beginnen Sie beim letzten Aufruf und lesen Sie die Delegationsliste.
- Suchen Sie für jeden Schritt die IAM-Bindung, die ihn erlaubt hat: Wer hat
roles/iam.serviceAccountTokenCreatorauf welchem Dienstkonto, und seit wann? - Prüfen Sie, ob eine dieser Bindungen im Zeitfenster des Vorfalls hinzugefügt wurde (
bindingDeltasADD, siehe SetIamPolicy-Missbrauch).
Im dritten Schritt zeigen sich Angriffe: Eine kompromittierte Identität mit geringen Rechten verschafft sich Token Creator auf einem mächtigen Dienstkonto und stellt dann Tokens dafür aus (T1098.003, dann T1550.001).
actAs: Impersonation über eine Ressource
Die Rolle Service Account User (roles/iam.serviceAccountUser) gewährt iam.serviceAccounts.actAs: das Recht, ein Dienstkonto an eine Ressource anzuhängen. Wer actAs auf einem mächtigen Dienstkonto und compute.instances.create besitzt, kann eine VM starten, die als dieses Konto läuft, und dessen Token vom Metadatenserver lesen. Googles Beispiel-Logs zeigen die Prüfung als Eintrag in authorizationInfo mit "permission": "iam.serviceAccounts.actAs" und "granted": true im Aufruf zur Ressourcenerstellung.
Wenn Sie während eines Vorfalls die Erstellung von VMs, Cloud-Run-Diensten oder Cloud Functions prüfen, lesen Sie daher authorizationInfo und das in der Anfrage gesetzte Dienstkonto, nicht nur, wer die Ressource erstellt hat.
Warnsignale
- Ein menschlicher Benutzer oder eine externe IP stellt Tokens für ein Dienstkonto aus, das normalerweise nur ein Workload nutzt.
GenerateAccessToken-Aufrufe, die direkt nach der Vergabe von Token Creator einsetzen.- Lange Ketten mit einem Dienstkonto in der Mitte, für das niemand verantwortlich ist.
SignJwtoderSignBlobvon Identitäten, die keinen Grund haben, irgendetwas zu signieren.- Aufrufe mit Delegationsinformationen von einer Identität außerhalb Ihrer Domains.
Was der Analyzer zeigt
Im Analyzer:
sa_impersonation(mittel, Rechteausweitung, T1550.001) schlägt bei erfolgreichen Aufrufen vonGenerateAccessToken,GenerateIdToken,SignBlobundSignJwtan, ausgenommen von Google verwaltete Dienst-Agents.token_creator_granted(hoch) schlägt beimADDvon Token Creator, Service Account User, Service Account Key Admin oder Workload Identity User an.- Der Reiter „Entitäten“ zeigt für jede Identität, von wem sie imitiert wurde (aus
serviceAccountDelegationInfo), und die Detailansicht eines Log-Eintrags zeigt „Imitiert durch“.
Die Grenze ist die oben genannte: Ohne Data-Access-Logs für IAM existiert nur die zweite Spur, und das Tool warnt, wenn ein Export überhaupt keine Data-Access-Logs enthält. Siehe Grenzen der Data-Access-Logs.
Behebung
Entfernen Sie Bindungen für Token Creator / Service Account User, die niemand braucht, vergeben Sie diese Rollen lieber auf einzelnen Dienstkonten statt auf dem Projekt, und prüfen Sie, welche Identitäten die Identität Ihrer privilegiertesten Dienstkonten annehmen können. Googles Seite zu Dienstkontoberechtigungen listet auf, was jede Rolle erlaubt.
Häufige Fragen
Wie sehe ich, wer in Google Cloud die Identität eines Dienstkontos angenommen hat?
An zwei Stellen. Der Aufruf zur Token-Ausstellung (GenerateAccessToken, GenerateIdToken, SignBlob, SignJwt in iamcredentials.googleapis.com) ist ein Data-Access-Log, dessen principalEmail der eigentliche Aufrufer ist. Aufrufe mit dem resultierenden Token nennen den eigentlichen Aufrufer in authenticationInfo.serviceAccountDelegationInfo.
Warum finde ich GenerateAccessToken nicht in meinen Logs?
Weil der Aufruf als Data-Access-Audit-Log (ADMIN_READ) erfasst wird, und diese sind standardmäßig deaktiviert. Wer Data-Access-Logs für die IAM API aktiviert, aktiviert sie auch für die Service Account Credentials API.
Weiterführende Links
- Service account impersonation – Dokumentation von Google Cloud.
- Example logs for service accounts – Dokumentation von Google Cloud.
- MITRE ATT&CK T1550.001, Application Access Token.