反序列化和SSRF漏洞总结

1.反序列化

在理解这个漏洞前,你需要先搞清楚php中serialize(),unserialize()这两个函数。

序列化serialize()

序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:

class S{
        public $test="pikachu";
    }
    $s=new S(); //创建一个对象
    serialize($s); //把这个对象进行序列化
    序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
        O:代表object
        1:代表对象名字长度为一个字符
        S:对象的名称
        1:代表对象里面有一个变量
        s:数据类型
        4:变量名称的长度
        test:变量名称
        s:数据类型
        7:变量值的长度
        pikachu:变量值

反序列化unserialize()

就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
    echo $u->test; //得到的结果为pikachu

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题

常见的几个魔法函数:
        __construct()当一个对象创建时被调用

        __destruct()当一个对象销毁时被调用

        __toString()当一个对象被当作一个字符串使用

        __sleep() 在对象在被序列化之前运行

        __wakeup将在序列化之后立即被调用

        漏洞举例:

        class S{
            var $test = "pikachu";
            function __destruct(){
                echo $this->test;
            }
        }
        $s = $_GET['test'];
        @$unser = unserialize($a);

        payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

上面是pikachu自带的一个payload,我们也可以自己去写一个转换序列化和非序列化的php文件

<?php
  show_source(__FILE__);#对当前文件内容进行高亮输出
  class redeme{#创建一个类
    public function __toString(){#类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。public是公有
      return eval($this->source);#将等会构造的payload执行
    }
  }
  $a=new redeme;
  $a->source="phpinfo()";#要构造进object中的一句话
  $a_new=serialize($a);
  echo $a_new;#先获取序列化的值
  echo "</br>";
  echo unserialize($_GET[8]);#将序列化的值在url传给payload
?>

这是还未将序列化后的值传给payload

将值传入后

当然如果要能实现生成一句话木马的脚本的话,这里function里的函数应该用,fopen去创建一个php文件,然后将后面的内容会添加进去。eg:

function __construct(){
        $fp = fopen("/var/www/html/vuln/unserialize/01/hello.php","w");
        fputs($fp,$this->test);
        fclose($fp);
}

然后看pikachu靶场,这里是利用__construct(),然后让上传一个序列化的内容。输入:O:1:"S":1:{s:4:"test";s:29:"system(dir)";}然后成功弹窗

总结

1.什么是序列化与反序列化︰

序列化是将程序代码对象转换成字节流的过程,而反序列化是将字节流转换成程序代码对象的过程·

2.序列化和反序化的目的︰

为了更方便进行数据和对象的存储、网络传输。

3.为什么要序列化

1.内存中存在大量的对象,会让内存负担过重,就像常见的 session对象,如果有数以万计的用户并发去访问,那就会同样出现数以万计的seson对象,这时We应用会将一些session先序列化存储在硬盘中,等需要使用的时候,再将其反序列化,还原到内存中,节约计算机内存资源。

2.在进行远程过程调用时,需要在网络上传输JavaBean对象,而网络上只允许二进制形式的数据进行传输,这时则需要用到序列化技术。

4.PHP序列化与反序列化

序列化K(Serliation)是一种将对余的状态信息转换为可以存储或传输的形式的过程(转化为信息流/字节流)。在序列化期间,对象将其当前状态马入到低时或持久性存情区以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

反序列化(Jnseidlie),与序列化相对应,useridlize)可以从房列化后的结果中恢复对象.(object),从已存储的表示中创建PHP的值。序列化和反序列化的目的是使得程字间传翰对象会更加方便。

5.反序列化漏河原理

PHP反序列化漏洞又叫PHP对象注入漏洞。深洞的根源在于unserilize)函教的参数可控。如果反序列化C对象中存在魔术方法,而且魔术方法中的代码有能够被用户控制,漏河这样产生了,根据不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。

这些函数在某些情况下会自动调用,其中,反序列化漏洞主要由以下面魔术方法造成:

__construct0:在对象创建时自动被调用;

__sleep):在对象序列化的时候自动被调用;

__destructO:在脚本运行结束时自动被调用;

__wakeup()∶在反序列化为对象时自动被调用;

__toString0:直接输出对象引用时自动被调用;

__invoke):当一个类(对象)被当作函数执行时调用此方法。

__call0:魔术方法会在对象调用的方法不存在时,自动执行。

__get0 :当读取不可访问或不存在的属性的值会被调用

__tostring:打印(输出/对象被当作字符串调用)一个对象时,如果定义了__toString()方法,就能在测试时,通过echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。
__construct():构造函数,PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。


6.PHP反序列化漏洞利用


CVE-2016-7124
当序列化字符串中表示对象属性的值大于真实的属性个数时会跳过__wakeup()的执行
PHP5 < 5.6.25
PHP7 < 7.0.10

7.反序列化POP链

起点寻找需留意可以自动调用的方法,常见的起点为可以自动调用的魔术方法,于目前自动调用的魔术方法有如下两个:
1、__destruct:当查询运行结束时自动调用
2、__wakeup:当调用反序列化函数时自动调用终点一般为危险动态调用或危险函数,常见函数如下所示:
1、rce类:system、exec、shell_exec、passthru、eval、assert、call_user_func
2、文件类:file_get_contents、file_put_contents、 fread、fwrite、readfile
3、文件包含类:include、include_once、require、require_once
跳板为在漏洞利用过程中承接点,利用这些转接点(跳板)达到最终的目的:起点魔术方法(__destruct/__wakep) --> 魔术方法跳板 --> 魔术方法跳板 ··· -->终点危险函数

8.防御:

➢ 审查代码逻辑,函数内容若是用户可控,必须添加过滤。
➢ 限制序列化与反序列化类。

2.SSRF

SSRF(Server-Side Request Forgery:服务器端请求伪造)

其形成原因大多是由于服务端提供了从此其他服务器应用获取数据的功能,但是又没有对目标地址进行严格的过滤与限制,导致攻击者可以传入任何地址来让后端服务器对其发起请求,并返回对该目标请求的数据

数据流:攻击者----->服务器---->目标地址

根据后台使用的函数的不同,对应的影响和利用方法又有不一样 :

PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()

如果一定要通过后台服务器远程去对用户指定("或者预埋在前端的请求")的地址进行资源请求,则请做好目标地址的过滤

靶场演练:pikachu

ssrf(curl)

可以去尝试url参数是否可控

那么我们可以尝试去访问远程php文件

ssrf(file_get_contents())

这一关传参为file,可以去访问服务器下的配置文件如:C:/Windows/System32/drivers/etc/hosts

总结

SSRF(Server-Side Request Forgery:服务请求伪造)是一种由攻击者构造,从而让服务端发起请求的一种安全漏洞, 它将一个可以发起网络请求的服务当作跳板来攻击其他服务,SSRF的攻击目标一般是内网。 当服务端提供了从其他服务器获取数据的功能(如:从指定URL地址获取网页文本内容、加载指定地址的图片、下载等), 但是没有对目标地址做过滤与限制时就会出现SSRF。

怎么寻找SSRF

网页的功能
图片、文章的收藏
在线翻译
文件处理、编码处理、转码等服务
通过urL分享内容
设置邮件接收服务器
从URL关键字寻找:share、url 、src、source 、target 、imgaurl 、doman ..
//payload:
//file:///etc/passwd 读取文件 -----本地服务器的信息泄露(重要文件)
//http://192.168.1.15:22 根据banner返回,错误提示,时间延迟扫描端口 -----服务器内容信息的收集;
//有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP

常用协议SSRF利用的协议

( 1 ) file:在有回显的情况下,利用file协议可以读取任意内容

( 2 ) dict:泄露安装软件版本信息,查看端口,操作内网redis服务等

( 3 ) gopher : gopher支持发出GET、POST请求:可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell

( 4) http/s:探测内网主机存活

参考文章

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值