RC RANDOM CHAOS

One write past the chunk, read-write on the repo

How a heap overflow primitive chains with an SSO misconfiguration to reach internal source repos, with MITRE ATT&CK mapping and telemetry gaps.

· 7 min read
One write past the chunk, read-write on the repo

Two primitives compromise a source-code repository. One is a heap-based buffer overflow in an internal-facing service. The other is a trust-boundary error in the SSO layer that fronts the code platform. Neither is novel. Chained, they move an operator from a network foothold to read/write access on internal repositories. Public detail on the specific incident is thin. What follows is the mechanism, not a vendor-confirmed intrusion timeline.

The entry bug is CWE-122, heap-based buffer overflow, and its output condition is CWE-787, out-of-bounds write. The root cause is constant across most instances of the class. A length is taken from attacker-controlled input. A copy runs into a heap allocation sized for a different, smaller value. No bounds check gates the copy against the destination capacity. The write runs past the end of the chunk.

Where that write lands is the whole exploit. On glibc, allocations come from the arena. Small requests are served from tcache bins, larger ones from fastbins and the unsorted bin. A linear overflow past one chunk writes into the header of the chunk that follows it - the size field, and for a freed chunk, the forward pointer. Two target categories exist. Allocator metadata, meaning the chunk header and the tcache next pointer. Or an adjacent application object, meaning a struct carrying a function pointer or a C++ object carrying a vtable pointer.

Placement is not left to chance. The operator grooms the heap so a controllable victim object sits directly after the overflowable buffer. Deterministic allocate-and-free sequences at chosen request sizes drive the allocator to co-locate the two. Once adjacency holds, the overflow rewrites the victim. Poisoning the tcache next pointer returns an attacker-chosen address on the next allocation of that size bin, which is an arbitrary write primitive. Overwriting a vtable pointer with a controlled address redirects the next virtual call, which is control-flow hijack. The attacker controls the copy length and the copy content. That is the entire input requirement.

On Windows the same class targets the Low Fragmentation Heap. The LFH buckets same-sized allocations, which makes grooming more predictable, not less. Mitigations apply on both platforms. ASLR randomises base addresses. DEP and NX mark the heap non-executable. glibc mangles heap pointers and enforces safe-linking on tcache. Windows adds Control Flow Guard and, on recent hardware, CET shadow stacks. None of these defeat an arbitrary read/write primitive. They raise the cost of turning it into code execution. The operator needs an information leak to defeat ASLR and a technique that survives CFI. An overflow that also over-reads adjacent heap memory and returns it in a response collapses both requirements into one bug. No payload is described here.

Code execution in the service process is not the objective. The repositories are. Two routes lead there. The compromised service may hold a token or service-account credential already scoped to the code platform, in which case the operator reuses it. Or the operator pivots into the SSO trust itself. The second route is durable, because it survives the memory patch.

The code platform - self-hosted Git, GitHub Enterprise, or GitLab - trusts an identity assertion from an IdP to establish a session. The misconfiguration classes that break that trust are well documented. SAML is the common case. Signature validation not enforced across the full document lets an operator run XML Signature Wrapping, restructuring the response so the signed element still validates while the service processes an injected, unsigned assertion carrying an attacker-chosen subject and group claim. Audience restriction not validated lets an assertion minted for one service replay against another. Recipient, Destination, and InResponseTo not checked enable replay and IdP-initiated injection where no authentication request was ever issued.

The high-value variant is signing-key exposure. If the service compromise reaches the IdP token-signing certificate, a secrets store holding it, or the key in process memory, the operator mints arbitrary assertions offline. This is Golden SAML, MITRE T1606.002. Any subject, any group membership, any validity window, no interaction with the IdP, and therefore no failed-login and no successful-login event at the identity provider.

OIDC deployments fail along a parallel set of lines. The session rests on a signed JWT. The break conditions are alg confusion where an RS256 token is re-signed as HS256 using the public key as the HMAC secret, acceptance of alg:none, missing aud or iss validation, and kid or jku injection that points signature verification at a key the operator controls. The outcome matches the SAML case. A token the service accepts as authentic, carrying claims the operator wrote.

With a forged or replayed credential carrying a privileged subject, the operator holds an authenticated session to the code platform. What follows is ordinary platform use turned hostile. Personal access token creation for persistence. SSH key registration. Organisation and repository enumeration through the REST and GraphQL APIs. Then repository cloning at scale. Okta and comparable providers are the assertion source. The service-side validation is where the trust actually fails.

The ATT&CK mapping is direct. T1190 for exploitation of the internal-facing application. T1203 and T1055 for execution and in-process manipulation. T1210 for exploitation of remote services during lateral movement. T1606.002 for forged SAML tokens. T1550.001 for use of application access tokens and alternate authentication material. T1213 for data from information repositories, the source code itself. T1567 for exfiltration over a web service.

None of this is theoretical. Nobelium used stolen token-signing certificates to mint SAML tokens against federated services during the SolarWinds campaign. Scattered Spider and ShinyHunters have repeatedly abused SSO paths, help-desk resets, and OAuth token theft to reach bulk repository and data theft. The shape recurs across code-theft incidents. A memory bug for entry. An identity-trust error for reach.

Telemetry is where the chain is either caught or missed, and most of it is missed. The heap overflow leaves signal only if it crashes. A crash surfaces as Windows Error Reporting output, a Sysmon process-termination record, and a segfault in the service log. A clean exploit does not crash. The over-read that leaks pointers writes nothing out of bounds and produces no fault. That path leaves no OS-level artifact at all. Detection there depends on anomalies in the service’s own request stream - oversized length fields, malformed structures, response sizes that do not match the request - not on endpoint telemetry.

The forged-assertion case is harder still. A Golden SAML token never reaches the IdP, so the Okta system log records no authentication for the impersonated user. The service records a successful session with no matching identity-provider event. That orphan is the detection, and it is visible only by joining service-side session logs to IdP authentication logs and finding the session that has no parent. XML Signature Wrapping and replay surface at the service as assertions missing InResponseTo, carrying an unexpected Destination, or arriving through an IdP-initiated flow on a deployment that only issues service-initiated requests. A missing InResponseTo on a service-initiated-only configuration is a concrete signal.

Post-session activity is where defenders realistically catch it. Personal access token creation events. First-seen SSH keys on a privileged account. First-seen device fingerprint or source ASN for an identity that normally logs in from one place. And clone volume. Pulling several hundred repositories inside a short window is a data-movement anomaly regardless of how clean the session that issued the requests was. GitHub audit-log events such as git.clone and repo.download_zip, or GraphQL enumeration bursts, carry that signal. The session reads as valid. The volume does not.

The blind spot is precise. A correctly signed, correctly scoped, replayed or forged assertion is indistinguishable from a legitimate login when the service is viewed alone. Git operations from a valid session are indistinguishable from developer activity at the level of a single request. Detection lives in correlation across identity and service logs and in volume over time, not in any single event a SIEM rule can match in isolation.

Patch boundary matters because the two bugs are independent. Patching the heap overflow removes the entry primitive and closes the door the operator came through. It does nothing to the identity path they pivoted onto. After the memory fix, any forged assertion, any leaked signing key, and any service that still accepts unsigned or partially signed assertions remains fully live. If key exposure is possible, signing-certificate rotation is mandatory, and an assertion minted before rotation stays valid until both the session and the key turn over.

The controls that break the chain sit at the mechanism level, one per primitive. On the identity side, signature validation over the complete assertion, enforced audience and recipient binding, InResponseTo validation, and IdP-initiated flows disabled where service-initiated is the only legitimate path. On the memory side, the specific bounds check and allocator hardening. Neither substitutes for the other, because neither bug depends on the other to function.

A live chain of this kind is an incident, not a config review. It calls for signing-certificate rotation, session invalidation, and incident-response engagement. For an Australian entity, exposure of source code and credentials on this scale triggers assessment under the Notifiable Data Breaches scheme, and SOCI obligations where the affected asset is in scope. Escalation goes to the security team, not into a backlog.

The shape is durable. One memory bug for entry. One trust error for reach. The repositories were never the hard part.

See also: NordVPN for tunneled traffic when operating outside controlled networks.


#ad Contains an affiliate link.

Share

Keep Reading

Latest on the Wire

Full wire →

New signal daily · RSS

Stay in the loop

New writing delivered when it's ready. No schedule, no spam.