WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类

目录

一、序列化和反序列化

二、为什么会出现反序列化漏洞

三、序列化和反序列化演示

<演示一>

<演示二>

<演示二>

四、漏洞出现演示

<演示一>

<演示二>

四、ctfshow靶场真题实操

<真题一>

<真题二>

<真题三>

<真题四>


一、序列化和反序列化

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

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

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

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

  • 比如我们在传输类似这种内容的时候,内容里包括很多空格,传输起来容易发生错误,也比较浪费空间。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第1张图片

  • 因此就将其转换为了字符串或者数组的形式去发送,之后再进行反序列化就可以将原本的数据输出出来,这样可以使数据传输更加稳定,效率也更高。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第2张图片

二、为什么会出现反序列化漏洞

        在php里有时会存在一些魔术方法,可以控制优先执行什么或者初始化什么,但是如果魔术方法使用不当,就可能会造成反序列化漏洞。

         原理 :未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL 注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
        魔术方法利用点分析:
触发:unserialize 函数的变量可控,文件中存在可利用的类,类中有魔术方法:
__construct():     //构造函数,当对象 new 的时候会自动调用
__destruct():    //析构函数当对象被销毁时会被自动调用
__wakeup():     //unserialize()时会被自动调用
__invoke():     //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call():     //在对象上下文中调用不可访问的方法时触发
__callStatci():     //在静态上下文中调用不可访问的方法时触发
__get():     //用于从不可访问的属性读取数据
__set():     //用于将数据写入不可访问的属性
__isset():     //在不可访问的属性上调用 isset()或 empty()触发
__unset():     //在不可访问的属性上使用 unset()时触发
__toString():     //把类当作字符串使用时触发
__sleep():     //serialize()函数会检查类中是否存在一个魔术方法__sleep(),如果存在,该方法会被优先调用

三、序列化和反序列化演示

<演示一>

1.这里是一段经典的系列化和反序列化的代码。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第3张图片

2.先将后两行注释掉,仅让其输出$s,可以看到其内容如下。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第4张图片

3.下面是对其序列化的内容的解释。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第5张图片

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第6张图片

4. 将代码修改成下面的样式。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第7张图片

5.将$u输出出来如下图所示。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第8张图片

6.完整的解释如下图所示。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第9张图片

        总结:就是一种典型的数据传输方法,可以更好的保证代码的正确性和完整性。

<演示二>

1.再来看一段代码。
        魔术方法通常就是看其前面有没有两个下划线——“__”

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第10张图片

2.我们首先将代码更改成下面的样式。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第11张图片

 3.此时访问可以可到下面的返回结果。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第12张图片

4.这里我们仅仅创建了一个对象,就将下面的两个函数给调用了,从而输出了对应的内容。

        总结:无需函数,创建对象就会调用魔术方法。 

<演示二>

1.再来看一段代码。
WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第13张图片

 2.执行结果如下图所示。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第14张图片

3.我们将代码更改为下面的样式。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第15张图片

 4.将上面序列化后的代码使用参数上传上去。

 5.网页返回下面的结果。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第16张图片

6.在代码里我们没有进行创建,但是仍然返回的end,是因为我们上传了序列化的内容,此时默认就进行了调用。

7.将代码再次更改。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第17张图片

8.此时再次执行可以发现test()被触发出来了。

         总结:传递序列化字符串,就相当于默认实现获取对象里的数据,包括调用里面的函数,也就是说即使不去创建对象,也能够触发对象里的变量以及函数,触发过程就是按照魔术方法的触发逻辑,

四、漏洞出现演示

<演示一>

1.打开下面的代码。

2.创建一个对象,会先调用__construct,然后销毁调用__destruct。运行结果如下图所示。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第18张图片

3.更改代码然后执行,将序列化字符串输出出来然后复制。WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第19张图片

4.将代码更改成下图样式。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第20张图片

5.将序列化的代码当作参数进行上传,之后可以看到页面内依然返回了ipconfig执行结果。相当于此时没有创建对象,只是输入了序列化字符串,就默认调用了__destruct代码。

<演示二>

1.打开下面的代码。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第21张图片 2.此时访问后,会先执行__construct,显示“xiaodisec”,然后回执行__destruct,执行系统命令ipconfig。 WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第22张图片

3.更改代码然后访问,来获取cc的序列化代码。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第23张图片

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第24张图片4.将代码更改为下面的样式来接收序列化的代码c。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第25张图片5.将序列化代码c当作参数提交,此时执行了__destruct,没有执行__construct,因为我们这里皆有进行“new”操作。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第26张图片

6.此时我们可以想到更改参数c的内容来执行一些其它的命令,下面进行尝试。

7.将参数里的ipconfig更改为“var”,然后将前面的长度改为“3”,执行后可以得到下面的返回结果,成功执行了“var”命令。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第27张图片

        这里就是序列化漏洞的核心点,前面讲解的所有都是为这一步做准备!

        总结:在反序列化操作里,对象里设置好的一些变量也可以进行修改,这里就是将ipconfig修改成了ver。也就是说,有时只要创建对象,就会调用对象内的魔术方法;或者当类似于unserialize的这种函数出现时,即使没有创建对象,也可以通过控制输入的参数,去让它调用对象里的内容。

        这种漏洞一般出现在白盒里,在黑盒里要想发现几乎是不可能的,因为需要看到源代码对源代码的代码逻辑进行分析后才能分析到是否存在反序列化漏洞。

四、ctfshow靶场真题实操

        靶场地址:ctf.show

<真题一>

1.找到对应题目进入靶场。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第28张图片

2.打开靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第29张图片

3.进入靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第30张图片

4.分析代码后得到下面的解题思路:

  • 首先触发vipOneKeyGetFlag。
  • 然后让$this->isVip为真即可。

5.继续分析代码:

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第31张图片

  • 仅需让username='xxxxxx';password='xxxxxx'即可。 

 6.开始操作。

http://eaece883-4d1b-411b-989d-b09aae68b5df.challenge.ctf.show/?username=xxxxxx&password=xxxxxx

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第32张图片

7.成功得到了flag。

<真题二>

1.找到对应题目进入靶场。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第33张图片

 2.打开靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第34张图片

3.进入靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第35张图片

4.分析代码后可以想到进行下面的操作。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第36张图片

5.将POP链复制下来。

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

6.打开Hack Firefox访问靶场链接。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第37张图片

7.使用burp抓包。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第38张图片

8.将抓到的数据包发送到Repeater。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第39张图片

9.根据源代码可以知道它接收的是cookie里的user数据,并且会检测username和password因此对数据包进行下面的修改。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第40张图片10.放包后可以看到成功获取到了flag。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第41张图片

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第42张图片

<真题三>

1.找到对应题目进入靶场。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第43张图片

 2.打开靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第44张图片

 3.进入靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第45张图片

4.分析代码后可以想到进行下面的操作。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第46张图片

 5.将POP链复制下来。

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

6.打开Hack Firefox访问靶场链接。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第47张图片

7.使用burp抓包。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第48张图片

 8.将抓到的数据包发送到Repeater。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第49张图片

9.根据源代码可以知道它接收的是cookie里的user数据,并且会检测username和password因此对数据包进行下面的修改,然后放包。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第50张图片10.可以看到成功获取到了flag。

<真题四>

1.找到对应题目进入靶场。 

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第51张图片

 2.打开靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第52张图片

3.进入靶场。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第53张图片

4.这关里可以看到有多个class,因此我们就先要看哪个地方能获取到flag,但是我们并没有找到直接和flag相关的操作,但是我们在下面看到了函数eval。

        补充: eval()函数可以把字符串按照php代码来执行。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第54张图片

5.因为这里只可能eval会与flag相关,所以我们就判断谁会触发eval。

6.可以看到getInfo会触发eval,__destruct会触发getInfo,而__destruct触发时class='info',当将'info'修改成backDoor后就可以调用到eval函数了。

7.复制class代码到在线工具内,然后将无用的代码删除后修改,之后执行。 

O%3A11%3A%22ctfShouUser%22%3A1%3A%7Bs%3A18%3A%22%00ctfShouUser%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

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第55张图片

8.打开Hack Firefox访问靶场链接。WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第56张图片

9.使用burp抓包。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第57张图片

 10.将抓到的数据包发送到Repeater。  

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第58张图片

9.对数据包进行下面的修改然后放包,可以得到flag。

WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类_第59张图片10.成功获取到了flag。

你可能感兴趣的:(序列化与反序列化漏洞,php,安全,开发语言,web安全,序列化反序列化)