Giter VIP home page Giter VIP logo

Comments (9)

mbechler avatar mbechler commented on July 20, 2024 1

@Marcono1234 I also implemented a custom serializer a while ago https://github.com/mb-syss/ruby-serialize, unfortunately in ruby (as the original intention was to contribute this to metasploit, which did not work out) that also already contains property based defintions for most of the ysoserial payloads. Maybe that is of some help in case you want to go further.

from ysoserial.

h3xstream avatar h3xstream commented on July 20, 2024

@frohoff Are you actively working on the option 2?
I would try using classloader isolation to support conflicting librairies.
Also, I would suggest doing a multi-module project with Gradle to keep the needed complexity to the minimum.

from ysoserial.

frohoff avatar frohoff commented on July 20, 2024

I haven't been actively working on either but have been weighing the options. @mbechler was giving his thoughts on this over on #20 but perhaps we can move the discussion here.

There's already some limited classloader isolation implemented as part of the unit test harness here that uses JBoss Shrinkwrap to resolve dependencies at runtime:
https://github.com/frohoff/ysoserial/blob/master/src/test/java/ysoserial/payloads/PayloadsTest.java#L91

I don't have much experience with Gradle. Presuming we went with Option 2, would Gradle provide advantages over Maven's multi-module and aggregator support?

In addition to the already discussed concerns/trade-offs, conflicting dependency versions also present a packaging issue since two versions of the same jars/classes can't be simply shaded into the same "all" jar. It seems like this can be addressed by either:

  • packaging each dependency/version inside the "all" jar as an isolated nested jar and/or directory and implementing a custom ClassLoader a la One-Jar
  • don't package dependencies with the application at all and resolve (and download) them all at runtime

from ysoserial.

h3xstream avatar h3xstream commented on July 20, 2024

@frohoff Quick response to the Gradle interrogation. The use of Gradle of would be analog to a Maven project for submodule.

I would push Gradle because it would make build configuration smaller and simpler to understand. The "scripting" capabilities will help greatly handling the custom packaging (lib isolation, etc).

from ysoserial.

pwntester avatar pwntester commented on July 20, 2024

Not sure, how the maven/gradle option would work, but ideally users should not specify special goals to generate the payloads. The reflection way seems better to me if we can define which jars should be loaded in runtime for a particular gadget, although that may involve heavy use of Reflection to operate the loaded classes

from ysoserial.

mbechler avatar mbechler commented on July 20, 2024

It looks to me that we are facing three kinds of incompatibilities:

  1. pure serialization - i.e. across different library versions (many of the gadgets don't have a serialization api/version) or even different standardized implementations (like my EL stuff):
    For that case runtime isolation is enough, a nice way to specify and resolve these things at runtime would be great. Bundling is of limited help.
  2. partial binary/source - some class in the gadget chain was slightly modified (maybe renamed) across versions (my hibernate stuff would be an example)
    Starting from here we cannot statically compile against the library using a single compile classpath. But compiling using multiple modules will also result in code duplication (potentially multiple times if there would be more of these changes). Here, I think, using reflection definitely scales better. Bundling could still be useful, although potentially could blow the JAR size out of proportion.
  3. full - i.e. a gadget chain is present in one version, another has another one (looks like the spring aop PR is one of those - but maybe also 2.)
    In that case it could be nice (if you don't have to use reflection anyways) to not have to use reflection (for at least one of them), that could be achieved by a multi module build. But how common will these really be - I wouldn't know. Bundling may be useful (so that each payload has one working bundled variant).

So in conclusion,

  • I don't think that generally splitting up all the payloads into separate modules is worth the effort (and the introduced complexity). There may be cases where this is helpful - so maybe it could be done optionally (like having a base module and packaging others as embedded jars). Using reflection, even without any additonal support, isn't really that hurtful.
  • I think it would be a good idea to remove the embedded gadget dependencies and resolve them at runtime. The resulting jar is already getting quite big now (without multiple versions of the same library) and there are cases where one has to match a specific version anyways.
  • Having that runtime classpath isolation is a must in any case, so that would be a good way to start.

from ysoserial.

frohoff avatar frohoff commented on July 20, 2024

Another option to consider might be implementing gadget chains in Groovy, potentially using Grape for dependency management.

from ysoserial.

Marcono1234 avatar Marcono1234 commented on July 20, 2024

Would another alternative be to create the serialization data manually instead of using ObjectOutputStream? This could have the following advantages:

  • It does not require the dependencies on the class path.
  • It does not require reflection to access internals of classes.
    This will probably become even more important over time, especially for JDK classes, since it will be necessary to provide command line flags to allow illegal reflective access, see for example JEP 403 which prevents illegal reflective access on JDK classes by default for Java 17 and newer (#203).
  • It would allow creating serialization data for JDK classes without requiring a specific Java version at runtime.
  • In some corner cases it might allow creating serialization data which cannot be achieved by only using reflection (e.g. because a writeObject implementation validates or normalizes field data)

The main disadvantage is that manually creating the serialization data could be more error-prone and verbose. One approach could be to obtain the current serialization data produced by ysoserial, pass it to a tool such as SerializationDumper and then based on its output manually use a library for creating the serialization data1. It looks also like ObjectInputStream still works when 'redundant' data (at least from the standpoint of ysoserial), such as superclass data or unused fields, are omitted. This would allow creating smaller payloads and would make the manual creation of serialization data not as verbose.


1 A bit of self advertisement, but I recently created a library called 'serial-builder' for creating serialization data. Though it is not unlikely that there are better or less verbose libraries out there.

Edit: I added code generation support to my 'serial-builder' library so it should hopefully be a lot easier to use and to get started with, in case there is interest in using it here. Any feedback is appreciated!

from ysoserial.

Marcono1234 avatar Marcono1234 commented on July 20, 2024

For testing Gradle supports Test Suites which can have different dependencies. So this would allow to have multiple test suites with different versions of the same dependency.

But I am not sure if that would provide a big advantage compared to the Maven multi-module approach described in the comments above, since the test classes might also differ between the modules.

from ysoserial.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.