diff --git a/README.md b/README.md index 1c62328..73d7aee 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@ The tool does not deserialize the stream (i.e. objects in the stream are not ins This tool was developed to support research into Java deserialization vulnerabilities after spending many hours manually decoding raw serialization streams to debug code! -Download v1.11 built and ready to run from here: [https://github.com/NickstaDB/SerializationDumper/releases/download/1.13/SerializationDumper-v1.13.jar](https://github.com/NickstaDB/SerializationDumper/releases/download/1.13/SerializationDumper-v1.13.jar "SerializationDumper-v1.13.jar") +Download v1.14 built and ready to run from here: [https://github.com/NickstaDB/SerializationDumper/releases/download/v1.14/SerializationDumper-v1.14.jar](https://github.com/NickstaDB/SerializationDumper/releases/download/v1.14/SerializationDumper-v1.14.jar "SerializationDumper-v1.14.jar") \* See the limitations section below for more details. +**Update 21/06/2024:** Fixed bugs in `readFloatField()` and `readDoubleField()`. + **Update 19/12/2018:** SerializationDumper now supports rebuilding serialization streams so you can dump a Java serialization stream to a text file, modify the hex or string values, then convert the text file back into a binary serialization stream. See the section below on [Rebuilding Serialization Streams](#rebuilding-serialization-streams) for an example of this. ## Building diff --git a/src/nb/deser/SerializationDumper.java b/src/nb/deser/SerializationDumper.java index 17e91f6..8e51e42 100644 --- a/src/nb/deser/SerializationDumper.java +++ b/src/nb/deser/SerializationDumper.java @@ -1042,20 +1042,32 @@ private void readNewArray() { this.print("Array size - " + size + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4)); //Array data - this.print("Values"); - this.increaseIndent(); - for(int i = 0; i < size; ++i) { - //Print element index - this.print("Index " + i + ":"); + if (cd.getClassName().charAt(1)=='B') { + StringBuilder build = new StringBuilder(); + for(int i = 0; i < size; ++i) { + byte b = this._data.pop(); + build.append(this.byteToHex(b)); + }; + this.print("Value " + build.toString()); + + } + else { + this.print("Values"); this.increaseIndent(); - - //Read the field values based on the classDesc read above - this.readFieldValue((byte)cd.getClassName().charAt(1)); - - //Revert indent + for(int i = 0; i < size; ++i) { + //Print element index + this.print("Index " + i + ":"); + this.increaseIndent(); + + //Read the field values based on the classDesc read above + this.readFieldValue((byte)cd.getClassName().charAt(1)); + + //Revert indent + this.decreaseIndent(); + } this.decreaseIndent(); - } - this.decreaseIndent(); + }; + //Revert indent this.decreaseIndent(); @@ -1397,15 +1409,16 @@ private void readDoubleField() { byte b1, b2, b3, b4, b5, b6, b7, b8; b1 = this._data.pop(); b2 = this._data.pop(); b3 = this._data.pop(); b4 = this._data.pop(); b5 = this._data.pop(); b6 = this._data.pop(); b7 = this._data.pop(); b8 = this._data.pop(); - this.print("(double)" + (double)(((b1 << 56) & 0xff00000000000000L) + - ((b2 << 48) & 0xff000000000000L) + - ((b3 << 40) & 0xff0000000000L) + - ((b4 << 32) & 0xff00000000L) + - ((b5 << 24) & 0xff000000 ) + - ((b6 << 16) & 0xff0000 ) + - ((b7 << 8) & 0xff00 ) + - ( b8 & 0xff )) + " - 0x" + this.byteToHex(b1) + - " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4) + " " + this.byteToHex(b5) + " " + this.byteToHex(b6) + " " + + this.print("(double)" + Double.longBitsToDouble((((long)b1 << 56) & 0xff00000000000000L) + + (((long)b2 << 48) & 0xff000000000000L) + + (((long)b3 << 40) & 0xff0000000000L) + + (((long)b4 << 32) & 0xff00000000L) + + (( b5 << 24) & 0xff000000 ) + + (( b6 << 16) & 0xff0000 ) + + (( b7 << 8) & 0xff00 ) + + (( b8 ) & 0xff )) + + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + + " " + this.byteToHex(b4) + " " + this.byteToHex(b5) + " " + this.byteToHex(b6) + " " + this.byteToHex(b7) + " " + this.byteToHex(b8)); } @@ -1415,10 +1428,11 @@ private void readDoubleField() { private void readFloatField() { byte b1, b2, b3, b4; b1 = this._data.pop(); b2 = this._data.pop(); b3 = this._data.pop(); b4 = this._data.pop(); - this.print("(float)" + (float)(((b1 << 24) & 0xff000000) + - ((b2 << 16) & 0xff0000) + - ((b3 << 8) & 0xff00) + - ( b4 & 0xff)) + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + + this.print("(float)" + Float.intBitsToFloat(((b1 << 24) & 0xff000000) + + ((b2 << 16) & 0xff0000) + + ((b3 << 8) & 0xff00) + + ( b4 & 0xff)) + + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4)); } @@ -1492,6 +1506,14 @@ private void readArrayField() { case (byte)0x71: //TC_REFERENCE this.readPrevObject(); break; + + case (byte)0x77: //TC_BLOCKDATA + this.readBlockData(); + break; + + case (byte)0x7a: //TC_BLOCKDATALONG + this.readLongBlockData(); + break; default: //Unknown throw new RuntimeException("Error: Unexpected array field value type (0x" + this.byteToHex(this._data.peek()));