← All field notes
command-injectionedge-appliancecredential-exposurefor responders

Command injection on a mobile gateway: patching the box is not the incident, the stored keys are

An OS command-injection flaw in an internet-facing mobile-access gateway lets an unauthenticated attacker run commands as a privileged account and read the appliance's stored integration secrets: the LDAP bind, back-end API keys, and TLS and signing certificates. That makes it a credential-exposure event for every back-end the gateway touched. Here is why patching the appliance does not contain it, and why the real work is rotating every secret it held and auditing the systems those secrets could reach.

A command-injection bug on an internet-facing mobile-access gateway teaches a lesson responders keep relearning: the vulnerable box is not the incident. When an unauthenticated attacker can run OS commands on the appliance that brokers access between managed devices and your back-end systems, the flaw is only the first move. What matters is what that appliance was holding. Ivanti Sentry is the current example on the CISA KEV list, but the shape is generic to this class of exposed gateway. By the time you notice, patching the appliance fixes the injection and almost nothing else.

How it works

The gateway exposes an administrative endpoint to the internet, and that endpoint passes attacker-supplied input into an OS command without sanitizing it. An unauthenticated request carrying shell metacharacters causes the appliance’s web tier to spawn a shell and run the attacker’s commands (T1190, Exploit Public-Facing Application, and T1059, Command and Scripting Interpreter). Appliances commonly run their web tier as a privileged local account, so those commands run with broad rights on the box. No credential was needed to get in.

The attacker does not stay interested in the appliance for its own sake. The first thing worth reading is the configuration store. A gateway like this brokers connections between mobile devices and back-end resources such as Exchange, a file service, and the directory, which means it has to authenticate to each of those on the device’s behalf. So it stores the secrets to do that: an LDAP bind account, back-end API keys, and the TLS and signing certificates it presents to each system. The attacker reads those off disk (T1552, Unsecured Credentials). Now they hold valid credentials to every back-end the gateway touched.

Why the gateway holds the keys

This is the part that turns a single-appliance bug into a multi-system credential incident. A broker appliance is, by design, a keyring. It cannot mediate access to mail, files, and the directory without holding standing credentials to all three. Those secrets are usually broad and long-lived, because they were provisioned once to make the integration work and then left alone.

So when the box is compromised, the loss is not the box. It is every secret on it. And those secrets do not stop working when you patch. The stolen LDAP bind authenticates to the directory from anywhere (T1078, Valid Accounts). The stolen certificates and API keys open the mail and file back-ends (T1550, Use Alternate Authentication Material). The attacker copied all of it off the appliance in the first minutes, and it stays valid until you rotate it. Patching the injection closes the door the attacker used to get in. It does nothing about the keys they walked out with.

How to detect it

The execution signal is process lineage on the appliance. A management-tier web process has no business spawning a shell. A child shell process off the gateway’s web service, running commands like id or uname immediately after an unauthenticated POST to the administrative endpoint, is the injection landing. Constant background scanning, connection spikes, and CPU are noise on an internet-facing box and will not tell you anything.

The second signal is off the appliance entirely. Watch the back-ends for the gateway’s own service identities being used from the wrong place: an LDAP bind from the gateway’s service account originating from an external host, or the gateway’s certificates presented from an address that is not the appliance. That is the stolen secret being used, and it is often the clearest proof the incident crossed from the box into your systems.

How to contain and shut it down

This is the part people get wrong. Patching and rebooting the appliance clears the shell, but it does not undo the copied secrets, and the attacker is still holding them. Treat every secret the gateway stored as exposed:

  • Isolate the appliance and apply the vendor fix to close the injection. This is step one, not containment.
  • Rotate the LDAP bind credential, every back-end API key, and reissue the TLS and signing certificates the gateway held. Assume all of it was copied.
  • Audit each back-end the gateway could reach. Pull the directory’s LDAP bind events and the mail and file-service access logs, filtered to the gateway’s service identities and the post-compromise window, to scope what the stolen secrets actually did.
  • Then scope obligations honestly. The exposure is bounded by the back-ends those secrets could open, not by the appliance, which held no records itself. Notification follows the data type and jurisdiction of the reachable mail, file, and directory data.

Eradication closes the class, not the one appliance. Get management interfaces off the public internet, run appliances least-privileged, and scope the integration identities to short-lived, per-service secrets so a single appliance compromise does not hand over the keys to every back-end. Then inventory the rest of the edge fleet for the same pattern.

Practice it

We built this as a scenario in GraphLattice Range: an unauthenticated command injection on an internet-facing mobile gateway, the config store read, and the gateway’s own LDAP bind used against the directory from outside. It forces the non-obvious call under time pressure. Patch the box and monitor, or treat every stored secret as gone and rotate the whole keyring. Teams that have made that call in a drill make it faster when it is real.