Using SerializationDumper for Java Deserialization and CTFs

I recently found out about SerializationDumper, and I wanted to share an example usage.

SerializationDumper – Introduction

During the BSidesRDU EverSec CTF, there was a ysoserial challenge that I used CyberChef to solve.

That said, a bit after the conference, I found out about SerializationDumper, which also solved it like a breeze.

You can find the tool on GitHub, and you can use it to dump any Java serialization streams.

Installation

First, I cloned the repository to my local machine.

[email protected]:~/tools# git clone https://github.com/NickstaDB/SerializationDumper
Cloning into 'SerializationDumper'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 65 (delta 0), reused 4 (delta 0), pack-reused 59
Unpacking objects: 100% (65/65), done.

Next, I tried to run the build.sh script, but did not have my Java runtime installed.

[email protected]:~/tools# cd SerializationDumper/
root[email protected]:~/tools# ls
LICENSE      MANIFEST.MF  README.md    build.bat    build.sh     src/
[email protected]:~/tools/SerializationDumper# chmod +x build.sh 
[email protected]:~/tools/SerializationDumper# ./build.sh 
No Java runtime present, requesting install.
No Java runtime present, requesting install.

Once I fixed my Java installation, the tool installed fine.

[email protected]:~/tools/SerializationDumper# ./build.sh 
mkdir: out: File exists
added manifest
adding: nb/(in = 0) (out= 0)(stored 0%)
adding: nb/deser/(in = 0) (out= 0)(stored 0%)
adding: nb/deser/SerializationDumper.class(in = 23776) (out= 11001)(deflated 53%)
adding: nb/deser/support/(in = 0) (out= 0)(stored 0%)
adding: nb/deser/support/ClassDetails.class(in = 1823) (out= 867)(deflated 52%)
adding: nb/deser/support/ClassDataDesc.class(in = 1993) (out= 956)(deflated 52%)
adding: nb/deser/support/ClassField.class(in = 655) (out= 388)(deflated 40%)

Usage/Capturing Flags

With SerializationDumper installed, I ran it against the ysoserial payload from the CTF. Unfortunately, I received a STREAM_MAGIC error, and it would not dump the stream.

[email protected]:~/tools/SerializationDumper# java -jar SerializationDumper.jar -r ctf-serialization.txt 

Unknown RMI packet type - 0x72
STREAM_MAGIC - 0x4f 30
Invalid STREAM_MAGIC, should be 0xac ed

After looking at the error and my input file, I realized that it wanted the actual serialized data as opposed to the base64 encoded version.

[email protected]:~/tools/SerializationDumper# cat ctf-serialization.txt | base64 -D > ctf-decoded.txt

With the decoded payload, I was able to successfully dump the stream. Note: I removed a lot of the output, as it tends to be very long.

[email protected]:~/tools/SerializationDumper# java -jar SerializationDumper.jar -r ctf-decoded.txt 

STREAM_MAGIC - 0xac ed
STREAM_VERSION - 0x00 05
Contents
  TC_OBJECT - 0x73
    TC_CLASSDESC - 0x72
      className
        Length - 23 - 0x00 17
        Value - java.util.PriorityQueue - 0x6a6176612e7574696c2e5072696f726974795175657565
      serialVersionUID - 0x94 da 30 b4 fb 3f 82 b1
      newHandle 0x00 7e 00 00
      classDescFlags - 0x03 - SC_WRITE_METHOD | SC_SERIALIZABLE
      fieldCount - 2 - 0x00 02
      Fields
        0:
          Int - I - 0x49
          fieldName
            Length - 4 - 0x00 04
            Value - size - 0x73697a65
        1:
          Object - L - 0x4c
          fieldName
            Length - 10 - 0x00 0a
            Value - comparator - 0x636f6d70617261746f72
          className1
            TC_STRING - 0x74
              newHandle 0x00 7e 00 01
              Length - 22 - 0x00 16
              Value - Ljava/util/Comparator; - 0x4c6a6176612f7574696c2f436f6d70617261746f723b
      classAnnotations
        TC_ENDBLOCKDATA - 0x78
      superClassDesc
        TC_NULL - 0x70
    newHandle 0x00 7e 00 02
    classdata
      java.util.PriorityQueue
        values
          size
            (int)2 - 0x00 00 00 02

I found the command that the flag was located in towards the bottom of the stream.

Index 1186:
  (byte)1 - 0x01
Index 1187:
  (byte)0 - 0x00
Index 1188:
  (byte)16 - 0x10
Index 1189:
  (byte)106 (ASCII: j) - 0x6a
Index 1190:
  (byte)97 (ASCII: a) - 0x61
Index 1191:
  (byte)118 (ASCII: v) - 0x76
Index 1192:
  (byte)97 (ASCII: a) - 0x61
Index 1193:
  (byte)47 (ASCII: /) - 0x2f
Index 1194:
  (byte)108 (ASCII: l) - 0x6c
Index 1195:
  (byte)97 (ASCII: a) - 0x61
Index 1196:
  (byte)110 (ASCII: n) - 0x6e
Index 1197:
  (byte)103 (ASCII: g) - 0x67
Index 1198:
  (byte)47 (ASCII: /) - 0x2f
Index 1199:
  (byte)83 (ASCII: S) - 0x53
Index 1200:
  (byte)116 (ASCII: t) - 0x74
Index 1201:
  (byte)114 (ASCII: r) - 0x72
Index 1202:
  (byte)105 (ASCII: i) - 0x69
Index 1203:
  (byte)110 (ASCII: n) - 0x6e
Index 1204:
  (byte)103 (ASCII: g) - 0x67
Index 1205:
  (byte)7 - 0x07
Index 1206:
  (byte)0 - 0x00
Index 1207:
  (byte)48 (ASCII: 0) - 0x30
Index 1208:
  (byte)1 - 0x01
Index 1209:
  (byte)0 - 0x00
Index 1210:
  (byte)16 - 0x10
Index 1211:
  (byte)101 (ASCII: e) - 0x65
Index 1212:
  (byte)99 (ASCII: c) - 0x63
Index 1213:
  (byte)104 (ASCII: h) - 0x68
Index 1214:
  (byte)111 (ASCII: o) - 0x6f
Index 1215:
  (byte)32 (ASCII:  ) - 0x20
Index 1216:
  (byte)121 (ASCII: y) - 0x79
Index 1217:
  (byte)115 (ASCII: s) - 0x73
Index 1218:
  (byte)48 (ASCII: 0) - 0x30
Index 1219:
  (byte)115 (ASCII: s) - 0x73
Index 1220:
  (byte)51 (ASCII: 3) - 0x33
Index 1221:
  (byte)114 (ASCII: r) - 0x72
Index 1222:
  (byte)105 (ASCII: i) - 0x69
Index 1223:
  (byte)52 (ASCII: 4) - 0x34
Index 1224:
  (byte)48 (ASCII: 0) - 0x30
Index 1225:
  (byte)85 (ASCII: U) - 0x55
Index 1226:
  (byte)115 (ASCII: s) - 0x73
Index 1227:
  (byte)8 - 0x08
Index 1228:
  (byte)0 - 0x00
Index 1229:
  (byte)50 (ASCII: 2) - 0x32
Index 1230:
  (byte)1 - 0x01
Index 1231:
  (byte)0 - 0x00
Index 1232:
  (byte)4 - 0x04
Index 1233:
  (byte)101 (ASCII: e) - 0x65
Index 1234:
  (byte)120 (ASCII: x) - 0x78
Index 1235:
  (byte)101 (ASCII: e) - 0x65
Index 1236:
  (byte)99 (ASCII: c) - 0x63
Index 1237:
  (byte)1 - 0x01
Index 1238:
  (byte)0 - 0x00

If you can’t tell, this runs `exec echo ys0s3ri40Us`, which was the flag for the CTF challenge.

SerializationDumper - Flag

SerializationDumper – Conclusion

This was a handy tool and made dumping the stream easy.

It can also now rebuild streams with some modification, so should make some deserialization exploitation easier.

I would love if it had some logic to make things more human readable, but that would take a lot more work.

I’m hoping to do an actual Java deserialization post soon, so let me know if you have a notable example or target.

2 thoughts on “Using SerializationDumper for Java Deserialization and CTFs”

  1. Pingback: Using SerializationDumper for Java Deserialization and CTFs | doyler.net – The Library 6.0

  2. Pingback: Bug Bytes #48 – 20 char XSS, HackerOne accidental account takeover & one-time ☎️ – INTIGRITI

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.