The Cookie That Was an Object: Spotting Java Deserialization

Digital Forensics & IR Level 2/4 ~3 min October 16, 2026

The challenge

Pennywharf's Java app stores your session in a cookie and trusts it on the way back in. The cookie is not a signed token and it is not JSON: it is the raw session object, encoded. That matters, because if the server rebuilds an object straight from bytes a client sent, the client gets to choose what gets built. Decode the cookie in the workbench and read the signature at the very start. Name the format this cookie is really in.

What you'll learn

  • Decode a base64 blob and read its leading magic bytes
  • Recognise ac ed 00 05 as the Java serialization stream header
  • Explain why deserializing client-controlled bytes is dangerous
  • List the front-of-blob tells for Java, pickle, .NET and PHP
  • State the safe alternative: opaque session ids and data-only formats

Skills tested

Encoding analysisFormat fingerprintingDeserialization awareness

Prerequisites

  • What base64 is
  • The idea that files and blobs start with a signature

How it works

A cookie that holds state can do it two safe ways: an opaque id that points at server-side data, or a signed, data-only token. It can also do it the dangerous way, by shipping the actual object, serialized. When the server reads that cookie back it reconstructs an object directly from bytes the client sent.

Each serialization format announces itself at the front. Java streams begin ac ed 00 05 (base64 rO0AB). Decoding this cookie shows exactly that, then a class descriptor. Rebuilding such an object runs code paths chosen by the attacker, and with the right classes present that becomes remote code execution. No key is involved, because nothing was encrypted.

Fingerprinting the blob is the first move: 80 04 / gASV is a Python pickle, AAEAAAD///// is .NET, O:4: is PHP.

Common mistakes

  • Treating it as a JWT. There are no dots and no header/payload/signature; it does not decode to JSON.
  • Stopping at the class name. The readable com.loomhaus.Session is a hint, but the signature ac ed 00 05 is the proof.
  • Hunting for a key. The cookie is encoded, not encrypted; From Base64 is the whole decode.
  • Answering base64. Base64 is the transport wrapper, not what the bytes are.

How to defend against it

Do not rebuild objects from input a client can set.

  • Keep session state on the server behind an opaque, random, unguessable id. The cookie should carry the id, never the object.
  • If state must round-trip through the client, use a data-only format (JSON) parsed into known fields, and sign it so it cannot be tampered with.
  • If a legacy path must deserialize, use strict allowlists of permitted classes and keep dangerous gadget libraries off the classpath.

Full solution

Pro and Max members unlock the complete step-by-step walkthrough.

Go Pro

Community stats

160 completions
82% success rate
M2F14M3 First blood

Related Daily Hacks

36,000+ Hackers Real labs Free
Start Hacking Free or solve today's hack, no account needed