nickstadb / serializationdumper Goto Github PK
View Code? Open in Web Editor NEWA tool to dump Java serialization streams in a more human readable form.
License: MIT License
A tool to dump Java serialization streams in a more human readable form.
License: MIT License
Hi, it seems that the same issue similar to #13 is popping up again while trying to deserialize a payload I generated using ysoserial
. Could you let me know if there is something that I am doing wrong? I tried both the release binary and building the jar file from scratch as well with the same error output.
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar Clojure /bin/ls > payload.bin
java -jar SerializationDumper-v1.13.jar payload.bin
javac 11.0.11
openjdk 11.0.11
Unknown RMI packet type - 0xf3
STREAM_MAGIC - 0xfd f7
Invalid STREAM_MAGIC, should be 0xac ed
java -jar SerializationDumper.jar -r byte-stream-InnerString > InnerString.decode
SerializationDumper.java: exception context:
1513 default: //Unknown/unsupported
1514 throw new RuntimeException("Error: Unexpected identifier for obje ct field value 0x" + this.byteToHex(this._data.peek()));
Exception in thread "main" java.lang.RuntimeException: Error: Unexpected identifier for object field value 0x00
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1514)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:971)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:921)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:859)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:455)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:347)
at nb.deser.SerializationDumper.parseStream(SerializationDumper.java:319)
at nb.deser.SerializationDumper.main(SerializationDumper.java:101)
From Test program: Create some objects and set some values.
Employee emp = new Employee();
Address addr = new Address();
ComplexObject co = new ComplexObject("a","b");
InnerString innerstring = new InnerString("x","y");
addr.setStreet("101 Maple Avenue");
addr.setCity("San Mateo");
addr.setZipcode(95616);
emp.setAddress(addr);
emp.setName("John Hines");
emp.setAge(22);
// Prepare stream by stuffing objects in it -- process just InnerString
Object obj;
objectOutputStream = new
ObjectOutputStream(byteArrayOutputStream);
// objectOutputStream.writeObject(addr); // Address - Decodes OKAY
// objectOutputStream.writeObject(emp); // Employee - Decodes OKAY
**objectOutputStream.writeObject(innerstring); // InnerString - Decodes with Exception**
// objectOutputStream.writeObject(co); // ComplexObject - Decodes with Excepton
objectOutputStream.close();
// Pull the bytes out of the objectOutputStream
bytes = byteArrayOutputStream.toByteArray();
// Store bytes to ./byte-stream
**String FILEPATH = "./byte-stream-InnerString";**
File file = new File(FILEPATH);
OutputStream os = new FileOutputStream(file);
os.write(bytes);
os.close();
$ hexdump -C byte-stream-InnerString
00000000 ac ed 00 05 73 72 00 12 62 75 67 74 61 67 2e 49 |....sr..bugtag.I|
00000010 6e 6e 65 72 53 74 72 69 6e 67 da e0 f6 fb ad 97 |nnerString......|
00000020 62 8d 02 00 03 4c 00 07 64 6f 72 6b 69 73 68 74 |b....L..dorkisht|
00000030 00 12 4c 62 75 67 74 61 67 2f 53 69 6e 67 6c 65 |..Lbugtag/Single|
00000040 53 74 72 3b 4c 00 09 69 6e 6e 65 72 43 68 61 72 |Str;L..innerChar|
00000050 74 00 12 4c 62 75 67 74 61 67 2f 49 6e 6e 65 72 |t..Lbugtag/Inner|
00000060 43 68 61 72 3b 4c 00 09 69 6e 6e 65 72 53 74 72 |Char;L..innerStr|
00000070 41 74 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 |At..Ljava/lang/S|
00000080 74 72 69 6e 67 3b 78 70 73 72 00 10 62 75 67 74 |tring;xpsr..bugt|
00000090 61 67 2e 53 69 6e 67 6c 65 53 74 72 fa 8d d0 44 |ag.SingleStr...D|
000000a0 7c d1 ce 5f 02 00 03 4c 00 01 64 71 00 7e 00 03 ||.._...L..dq.~..|
000000b0 4c 00 04 64 6f 72 6b 71 00 7e 00 03 4c 00 01 65 |L..dorkq.~..L..e|
000000c0 71 00 7e 00 03 78 70 74 00 04 5a 31 30 35 74 00 |q.~..xpt..Z105t.|
000000d0 03 5a 31 30 74 00 0c 53 6d 69 6c 65 79 20 3a 2d |.Z10t..Smiley :-|
000000e0 29 31 31 73 72 00 10 62 75 67 74 61 67 2e 49 6e |)11sr..bugtag.In|
000000f0 6e 65 72 43 68 61 72 0b ad b6 d5 dd 81 90 73 02 |nerChar.......s.|
00000100 00 02 43 00 06 69 6e 6e 65 72 43 43 00 06 69 6e |..C..innerCC..in|
00000110 6e 65 72 44 78 70 00 53 00 54 74 00 02 78 79 |nerDxp.S.Tt..xy|
0000011f
Test Object: InnerString
$ cat -n InnerString.java
1 package bugtag;
2 import java.io.ByteArrayInputStream;
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.io.ObjectInputStream;
7 import java.io.ObjectOutputStream;
8 import java.io.ObjectStreamConstants;
9 import java.io.Serializable;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 public class InnerString implements Serializable {
16 String innerStrA = null;
17 InnerChar innerChar = new InnerChar('S', 'T');
18 SingleStr dorkish = new SingleStr("Smiley :-)");
19 public InnerString(String a, String b) {
20 this.innerStrA = a + b;
21 }
22 }
Test Object: SingleStr
[jhines@gps-dev inputstreamfw]$ cat -n SingleStr.java
1 package bugtag;
2 import java.io.ByteArrayInputStream;
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.io.ObjectInputStream;
7 import java.io.ObjectOutputStream;
8 import java.io.ObjectStreamConstants;
9 import java.io.Serializable;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 public class SingleStr implements Serializable {
16 String dork, d, e;
17 SingleStr(String dork) {
18 this.dork = "Z" + dork.length();
19 this.d=this.dork+5;
20 this.e=dork+11;
21 };
22 }
Attached are byte-stream-ComplexObject and byte-stream-InnerString
I am trying to deserialize a webshell from a log4j exploit, and am running in to this error.
java -jar SerializationDumper.jar -r test.bin
STREAM_MAGIC - 0xac ed
STREAM_VERSION - 0x00 05
Contents
TC_OBJECT - 0x73
TC_CLASSDESC - 0x72
className
Length - 23 - 0x00 17
Value - java.util.PriorityQue - 0x6a6176612e75746900106c2e5072696f72697479517565
serialVersionUID - 0x75 65 94 00 20 da 30 b4
newHandle 0x00 7e 00 00
classDescFlags - 0xfb - SC_WRITE_METHOD | SC_SERIALIZABLE | SC_BLOCK_DATA
Exception in thread "main" java.lang.RuntimeException: Error: Illegal classDescFlags, SC_SERIALIZABLE is not compatible with SC_BLOCK_DATA.
at nb.deser.SerializationDumper.readClassDescInfo(SerializationDumper.java:635)
at nb.deser.SerializationDumper.readTC_CLASSDESC(SerializationDumper.java:571)
at nb.deser.SerializationDumper.readNewClassDesc(SerializationDumper.java:527)
at nb.deser.SerializationDumper.readClassDesc(SerializationDumper.java:489)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:461)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:359)
at nb.deser.SerializationDumper.parseStream(SerializationDumper.java:331)
at nb.deser.SerializationDumper.main(SerializationDumper.java:113)
java -jar SerializationDumper-v1.11.jar file.bin
Unknown RMI packet type - 0xef
STREAM_MAGIC - 0xfe fb
Invalid STREAM_MAGIC, should be 0xac ed
Any interest in making this accessible from other Java code?
The company I work for has a process where Java serialized data is stored in persistent files on disk. I'm working on creating a tool for our support reps to inspect this serialized data (to some degree) and came across this tool. Unfortunately, while the main SerializationDumper class is public, there's no public methods on it, so I can't readily make use of it.
I may just fork it (would be happy to contribute back here!) but I was curious if anyone had approached you about this use case.
Exception in thread "main" java.lang.RuntimeException: Error: Unable to parse externalContent
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:865)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:359)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:902)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:359)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:902)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:359)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:902)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1510)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:939)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:886)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:467)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:359)
at nb.deser.SerializationDumper.parseStream(SerializationDumper.java:331)
at nb.deser.SerializationDumper.main(SerializationDumper.java:113)
This is not correct, as it simply converts an int
value to a float
value.
What is needed here, instead, is to invoke Float.intBitsToFloat()
on the int
.
Similarly in method readDoubleField()
.
During deserialization the following exception occurs:
classdata com.mypackage.MyClass values myEnumField (object)
Exception in thread "main" java.lang.RuntimeException: Error: Unexpected identifier for object field value 0x7e
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1519)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:974)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:924)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:862)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:458)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:350)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:878)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:458)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1495)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:974)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:924)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:862)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:458)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:350)
at nb.deser.SerializationDumper.parseStream(SerializationDumper.java:322)
at nb.deser.SerializationDumper.main(SerializationDumper.java:104)
SerializationDumper/src/nb/deser/SerializationDumper.java
Lines 859 to 867 in 49dbece
In the code section above in readClassData, we appear to be looping over all classes in the hierarchy and bailing out if any of them have SC_EXTERNALIZABLE, assuming that they cannot be parsed. But:
Aren't we able to parse a class if both SC_EXTERNALIZABLE and SC_BLOCK_DATA are set? It looks like there is even a condition for this on line 894.
Isn't it possible that some superclasses in the hierarchy are not externalizable? Perhaps this check should be moved inside the for loop below so that we can dump information about the valid superclasses and fields until we actually hit a class that can't be parsed.
Let me know if there's a mistake in my understanding.
RT.
Got the following error:
Exception in thread "main" java.lang.RuntimeException: Error: Invalid classDesc reference (0x00 7e 02 ef
at nb.deser.SerializationDumper.readClassDesc(SerializationDumper.java:494)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:449)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1492)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:971)
at nb.deser.SerializationDumper.readNewArray(SerializationDumper.java:1031)
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:355)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:875)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:455)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1492)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:971)
at nb.deser.SerializationDumper.readClassDataField(SerializationDumper.java:921)
at nb.deser.SerializationDumper.readClassData(SerializationDumper.java:859)
at nb.deser.SerializationDumper.readNewObject(SerializationDumper.java:455)
at nb.deser.SerializationDumper.readObjectField(SerializationDumper.java:1492)
at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:971)
I got a idev file from the "Statistisches Bundesamt" in Germany, the file
command says "Java serialization data, version 5"
While trying to parse, the tool (using the 1.13 binary) says
STREAM_MAGIC - 0xac ed
STREAM_VERSION - 0x00 05
Contents
TC_BLOCKDATA - 0x77
Length - 48 - 0x30
Contents - 0x0000019300000000000000<snip>
Invalid content element type 0x12
Exception in thread "main" java.lang.RuntimeException: Error: Illegal content element type.
at nb.deser.SerializationDumper.readContentElement(SerializationDumper.java:410)
at nb.deser.SerializationDumper.parseStream(SerializationDumper.java:331)
at nb.deser.SerializationDumper.main(SerializationDumper.java:113)
Sadly, I can't make the file public because it contains foreign confident data.
Any clues how to proceed? ;-)
P.S. also happens with current master.
java -jar SerializationDumper.jar -f /pwnjvm/test/8848.bin
Unknown RMI packet type - 0xef
STREAM_MAGIC - 0xef ef
Invalid STREAM_MAGIC, should be 0xac ed
Hello,
There is a questions when i enter a hex-ascii encoded byte string , "Error: Data encoded as hex and passed on the command line must have a length that is a multiple of 2." is displayed in cmd ,but i enter a hex-ascii encoded byte string he remainder of 2 is equal to 0.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.