New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Contributing Java Serialization Framework #11748
Comments
Thanks for posting! Happy to discuss here on GitHub. Pinging @schierlm :) |
Not much discussion so far... Anyway, my 2¢:
|
Another thing that I forgot to mention before is that due to subtle issues with the loader, I had to change the Stage interface into an abstract class (otherwise causes an exception). this should not make much of a functional difference but is a breaking API change. Should we take these to metasploit-payloads? I could prepare some PRs and open issues for the things to discuss.
For some very specific uses this could possibly work, but in many more generic, as the JMX stuff is, which gadgets can be exploited depends highly on the actual target application/codebase, so you really want to support as many gadgets as possible, preferrably (as the JMX module does) autodetecting which are available or the ability to try multiple. I don't think creating one module for each one and then having the user try works here. |
I only had a quick look at your code, so in case I misunderstood anything, sorry for that. I see that you are injecting the config by building the actual config properties in dynamically generated code. I would have gone the way of just embedding "resources" as byte array (or as string which you getBytes() with an appropriate charset) in the class file (as I prefer not to generate code, I would have a huge byte[] or String containing all the resources and use a method to split them up), and then have the payload loader load these resources instead of your custom Map. So the payload loader will still construct a Properties, but not from the resource stream but from a ByteArrayInputStream that you provided. Or (as I said) have a custom ClassLoader class template that overrides getResource to lookup your "embedded" resources, so you can use unmodified payload class (also embedded as a resource into that classloader and loaded by it). An extreme way of that method is how Meterpreter's second level stager works by constructing an In any cases, I would prefer if it is possible to use all existing ARCH_JAVA payload classes and stages (both in-tree and out-of-tree) unmodified with your library and/or exploits that use your library. Also to keep the on-wire staging protocol unchanged, so that you can point the reverse_tcp variant to external tools that stage completely different payloads than those included with Metasploit. But that would mean that you cannot "cherry-pick" features but rather have to try that the ClassLoader that ultimately loads your stage classes can load any classes (and interfaces), not just the ones you tested and patched. I am kind of "out of the business" and did not really follow latest serialization exploits, so I am a bit surprised that it can be an obstacle from such an exploit to load (via an intermediate classloader) interfaces or resources. It may be that the exploited classloader is limited (but that is also true for other existing exploits that do not exploit serialization issues but e.g. Applet privilege elevation), but in that case using that limited classloader to load another classloader which in turn loads the rest would be preferrable from my point, over patching existing classes (those classes you know of) to work with the limitations of that particular class loader. For maintainability of generated classes, I would always start with a class file generated by javac (loaded by your library), and then modify the constant pool or (if really required) the bytecode arrays of the method bodies. Generating the whole class "by hand" works too of course, but the number of people who are able to read and maintain that code are a lot fewer than the ones who can maintain code that "just patches existing classes". Also, I would not try to introduce a new namespace java/classfile/* for the payloads, but use normal java/* payloads (not only meterpreter, but also shell and possibly out-of-tree ones) and have your library/mixin take care of mangling/wrapping the exploit. Out of curiosity: What is the exact problem with loading Stage as an interface, which can be alleviated by loading it as an abstract class instead? |
Thanks for having a look and the comments. I'll have a try at a more general wrapper, I think using a wrapper with a embedded JAR URLClassloader should avoid most of the issues there. All these specifics are coming from the TemplatesImpl class, which is an "utility" (I think the only one) that allows inband loading/execution of arbitrary supplied bytecode starting out from a arbitrary method call/property access that can be achieved via a deserialization gadget. That class defines classes at runtime from an embedded bytecode array, which need have to have some specific properties (intended usage I think is XSLT transformations compiled to bytecode).
I started out that way, but having the configuration strings in the class, I ended up fighting the optimizer quite a bit, so I settled for directly generating it. We'll probably still have to do some bytecode generation (to work around constant size limits we likely need array initialization), but I guess we can have most of the wrapper compiled from source.
This is also coming from TemplatesImpl. You can't have custom interfaces there, as these have getSuperclass() == null, causing a NPE in TemplatesImpl.defineTransletClasses. This should no longer be an issue if we do the wrapping as these can then be loaded from the embedded JAR.
Sure, that was just to avoid messing with the "normal" meterpreter payload right now. |
Some progress to show finally. Now we have a much cleaner generic loader for the Translet stuff which can invoke code from arbitrary JARs so we can inject the stock Java meterpreter (or something else): I haven't adjusted the remaining code to use that yet, but it should show the concept. I believe this now addresses the meterpreter side nicely. Also I think this implicitly puts the gadget generation / payload generation boundary naturally between the exploit module and the payload module as we now can now simply use the JAR produced by the payload module. This means that the exploit module will be responsible for creating the gadget object graph and setting up possibly required services. I'll have another go to see how this could be designed so that it is reusable. |
One more question, as I finally may have a chance to continue working on this some time soon: I think we should keep much of the functionality in a reusable library, any suggestion how to go about this? Target rex-java? There is a bit of code that can be shared I guess, however we will end up with some duplication I suppose, as parts perform the same tasks, only on a much higher level abstraction (I don't remember the details right now, but I think I could not use the rex-java serialization API as a basis because of some issues regarding references). Or go for a separate library? |
So I went ahead and did quite a bit of cleanup and refactoring, we now have:
A bunch of questions/remarks:
There are still a bunch of open tasks and some improvements I'd like to make. Would you care to have another look at the design? What is the next move from here? |
Did anyone have a chance to have a look yet? |
It might be worth opening a pull request with the changes rather than just keeping it on a branch. If it's not ready you can mark it as a draft.
|
Hi,
Along with some new RMI/JMX scanner/exploitation modules we have built a general framework for exploiting Java serialization related issues. Both we would be happy to contribute. The serialization framework could be used to easily implement a wide variety of other exploits.
As this is a rather large chunk of code and I had to cut some corners to get what I wanted
(which also might be because my lacking insight in metasploit internals) I'd like to start
out with this "meta" issue so that we can decide whether you like it, how we can go about
this whole process, how to split that up and maybe come up some design improvements.
Let me know if there is a better platform to have these discussions.
Apart from the actual RMI/JMX modules most currently lives in a single ruby library:
(apart from serialization issues also supports the vectors from exploit/multi/misc/java_{rmi,jmx}_server)
What probably needs some discussion:
currently a customized Java meterpreter is required, as the regular one requires loading resource files through the ClassLoader with is unsupported by the Xalan Templates classloader that is used by many gadgets to achieve bytecode execution. This affects both the configuration and the staging method and could be considered somewhat invasive. To support this some utilities to patch and generate Java classfiles are included. To avoid having to go generate and decode a JAR file this also currently has a method bypassing the regular payload generation to get the class files.
the definition of payload becomes somewhat blurry here, and I haven't found a good solution to this yet. Essentially for a regular exploit one would have to select
Ideas how to do this could be done would be very welcome. I suppose the goal should be to remove most of the burden from the using modules. Also, one should be able to get the actual model object structure of the deserialization gadget, to be able to embed it into large object graphs, which is somewhat against the binary nature of payloads at this point.
Moritz
The text was updated successfully, but these errors were encountered: