pwneglyph logo
web php deserialization gadget-chain array-map callable rce

Use array_map (or another higher-order function) on attacker-controlled object state to call an arbitrary callable from deserialization.

array_map Gadget Inside a Deserialized Object

array_map is a surprisingly strong primitive when the callback comes from attacker-controlled object state. The gadget turns deserialization into a controlled function call without needing a full magic-method RCE chain.

Why It Works

  • A method that runs array_map($this->cb, $this->items) over attacker-set properties is effectively call_user_func with attacker arguments.

Vulnerable Pattern

  • Deserialized objects whose methods later run array_map, usort, call_user_func, or similar higher-order functions over attacker-controlled properties.

Exploit Flow

  1. Identify which object fields control the callback name and the array contents.
  2. Pick a low-risk callback first (e.g. phpinfo) to confirm invocation.
  3. Once invocation is proven, pivot to a callback giving filesystem access, command execution, or a second-stage include.

Variations

  • Methods, static callbacks, invokable objects, or wrapper functions that accept callables indirectly.

Common Blockers

  • Callable allowlists, incompatible callback signatures, or Snuffleupagus rules blocking the most dangerous functions.

PoC Sketch

// deserialize a Notes object where:
//   filters["input"] = "phpinfo"
//   all_notes = ["x"]
// then hit a route that calls filter=input

Good Situations To Use It

  • You have object injection but no obvious magic-method RCE.
  • A method runs a higher-order function over your properties.
  • A useful callback isn't on the blocklist.

Sources

  • fcsc2026/web/secure_mood_notes_2