Skip to content

Leadership1 publisher3 min readPublished

GraphWorm answers token revocation by swapping its own OAuth credentials

CSO Online's teardown of a Webworm implant found an upgrade command that replaces all five credential strings in a single task. The revocation step at the top of most identity runbooks costs the operator one poll cycle.

The Board Room · Leadership desk

Illustration accompanying GraphWorm answers token revocation by swapping its own OAuth credentials

What happened

  • GraphWorm, a custom implant CSO Online ties to the China-nexus group Webworm, authenticates to Microsoft Graph as an OAuth application and uses a OneDrive account as a dead drop instead of a C2 domain.
  • The operator drops an encrypted task file into a job folder, the implant polls it, runs the task and uploads an encrypted result, refreshing a heartbeat file every interval as it goes.
  • Victim identity is a hash of the network adapter's hardware address with CPU and disk serials read through WMI, so a rename or a new egress address still resolves to the same machine.

Compiled by The Board RoomSomething wrong?How this is made

Why it matters

  • constraint Revocation still closes an adversary-in-the-middle case, where the prize is a session cookie, so triage now needs a question ahead of the runbook: is the stolen thing a user session or an application credential the operator can replace on demand?
  • decision Eradication moves back to the host. The only element that survives an identity rotation unchanged is the file on disk, so the case cannot be closed on a platform filing.
  • exposure Detection lands on endpoint and application telemetry owners rather than the firewall team, because every tenant already generates the same TLS traffic to graph.microsoft.com all day.
  • contradiction Vendor writeups on the family are scoped to observed campaigns and do not include this handler, so procedures written from published reporting encode a containment step the sample defeats.

The credentials that carry this implant belong to an application, not to a user. CSO Online's analyst found a client ID, a client secret, a tenant ID and a refresh token more than 1,300 characters long sitting in the binary in cleartext [6]. Revoke them and the implant's next poll fails [9]. The operator is watching, because the implant refreshes a heartbeat file every interval [3], and the reported answer to a revocation is a queued upgrade task pointing at a second OneDrive account registered months earlier [9].

The handler does the swap in one pass. It parses a configuration blob out of the task, destroys the five credential strings held in the beacon object, copies five new ones in, rebuilds the OAuth scope structure, tests a connection against the new OneDrive account, writes the replacement configuration to disk and swaps the live API instance [8]. Nothing on the endpoint changes. The swap brings no new binary, no new persistence mechanism and no new process, and the file on disk is unchanged [9]. A hunt that begins after the rotation has zero fresh host artefacts to key on [1].

Which layer the fix belongs to depends on where that application registration lives. The response CSO Online describes is identifying the application and filing with the platform to get the tokens revoked [9]. The article does not say whether the application appears in a victim tenant's list of enterprise applications. If it does not, a consent-grant review inside the victim's own directory has nothing to find, and only the platform that issued the identity can disable it.

"Cloud-hosted C2 is not new," the analyst wrote [13]. The tasking handler is the new part of the account, confirmed twice, once from extracted strings and once from the decompiled function, with the credential field offsets recovered from the strings matching the offsets the constructor reads [11]. It does not appear in the public reporting on the family [11]. All of it comes off one analyst's decompilation of one sample.

Containment that moves the host fails for a separate reason. The implant builds its victim identifier by hashing the network adapter's hardware address together with CPU and disk serial numbers pulled through WMI, so a rename, a new subnet or a new egress address still resolves to the same box [7]. "Any containment plan that leans on changing the victim's network identity is solving a problem this implant does not have," the analyst wrote [10].

This quarter the consequence is one line in a procedure: after revocation, the case stays open and the endpoint stays unremediated until the file is gone. Over a longer horizon it is the same erosion that overtook domain blocking, where the network layer had a destination to penalise and then lost it [5]. When the blockable identity is an app registration and a cloud account, the operator can hold spares, and CSO Online describes exactly that, a second OneDrive account registered months in advance [9].

What to watch

  • Whether a second GraphWorm sample, from a vendor or from Microsoft, carries the same upgrade handler. The finding currently rests on one binary.
  • Whether the operator's application registration ever shows up in a victim tenant's enterprise application list. That decides whether consent-grant review is the useful second step after revocation.
  • Whether published campaign writeups on Webworm are updated to include credential rotation, since response procedures are built from them.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories