找回密码
 立即注册
首页 业界区 业界 PHP特性之反射类ReflectionClass机制

PHP特性之反射类ReflectionClass机制

轩辕娅童 5 天前
PHP特性之反射类ReflectionClass机制


目录

  • PHP特性之反射类ReflectionClass机制

    • 引例
    • 详细阐述

      • 反射机制的核心作用
      • ReflectionClass 的基本使用流程
      • 常用方法与应用场景
      • 反射机制进一步的利用
      • 防御措施



引例

最近在刷polarD&N靶场的时候,做到了一道关于ReflectionClass机制
原题是这样的
  1. <?php
  2. class FlagReader {
  3.     private $logfile = "/tmp/log.txt";
  4.     protected $content = "<?php system(\$_GET['cmd']); ?>";
  5.     public function __toString() {
  6.         if (file_exists('/flag')) {
  7.             return file_get_contents('/flag');
  8.         } else {
  9.             return "Flag file not found!";
  10.         }
  11.     }
  12. }
  13. class DataValidator {
  14.     public static function check($input) {
  15.         $filtered = preg_replace('/[^\w]/', '', $input);
  16.         return strlen($filtered) > 10 ? true : false;
  17.     }
  18.     public function __invoke($data) {
  19.         return self::check($data);
  20.     }
  21. }
  22. class FakeDanger {
  23.     private $buffer;
  24.    
  25.     public function __construct($data) {
  26.         $this->buffer = base64_encode($data);
  27.     }
  28.     public function __wakeup() {
  29.         if (rand(0, 100) > 50) {
  30.             $this->buffer = str_rot13($this->buffer);
  31.         }
  32.     }
  33. }
  34. class VulnerableClass {
  35.     public $logger;
  36.     private $debugMode = false;
  37.     public function __destruct() {
  38.         if ($this->debugMode) {
  39.             echo $this->logger;
  40.         } else {
  41.             $this->cleanup();
  42.         }
  43.     }
  44.     private function cleanup() {
  45.         if ($this->logger instanceof DataValidator) {
  46.             $this->logger = null;
  47.         }
  48.     }
  49. }
  50. function sanitize_input($data) {
  51.     $data = trim($data);
  52.     return htmlspecialchars($data, ENT_QUOTES);
  53. }
  54. if(isset($_GET['data'])) {
  55.     $raw = base64_decode($_GET['data']);
  56.     if (preg_match('/^[a-zA-Z0-9\/+]+={0,2}$/', $_GET['data'])) {
  57.         unserialize($raw);
  58.     }
  59. } else {
  60.     highlight_file(__FILE__);
  61. }
  62. ?>
复制代码
将上述内容作为 xml 参数传入(即 ?xml=上述XML内容),PHP 解析后会将 /etc/passwd 文件内容替换到 <?php

class FlagReader {
    private $logfile = "/tmp/log.txt";
    protected $content = "<?php system(\$_GET['cmd']); ?>";

    public function __toString() {

        if (file_exists('/flag')) {
            return file_get_contents('/flag');
        } else {
            return "Flag file not found!";
        }
    }
}

class DataValidator {
    public static function check($input) {
        $filtered = preg_replace('/[^\w]/', '', $input);
        return strlen($filtered) > 10 ? true : false;
    }

    public function __invoke($data) {
        return self::check($data);
    }
}

class FakeDanger {
    private $buffer;
   
    public function __construct($data) {
        $this->buffer = base64_encode($data);
    }

    public function __wakeup() {
        if (rand(0, 100) > 50) {
            $this->buffer = str_rot13($this->buffer);
        }
    }
}

class VulnerableClass {
    public $logger;
    private $debugMode = false;

    public function __destruct() {
        if ($this->debugMode) {
            echo $this->logger;
        } else {
            $this->cleanup();
        }
    }

    private function cleanup() {
        if ($this->logger instanceof DataValidator) {
            $this->logger = null;
        }
    }
}


function sanitize_input($data) {
    $data = trim($data);
    return htmlspecialchars($data, ENT_QUOTES);
}

if(isset($_GET['data'])) {
    $raw = base64_decode($_GET['data']);
    if (preg_match('/^[a-zA-Z0-9\/+]+={0,2}$/', $_GET['data'])) {
        unserialize($raw);
    }
} else {
    highlight_file(__FILE__);
}
?> 位置,导致敏感文件被读取并可能通过后续逻辑泄露。
3.绕过访问控制执行私有危险方法
若类中存在私有方法包含危险操作(如执行系统命令),攻击者可通过反射的setAccessible(true)突破限制并调用:
  1. class FlagReader {
  2.     private $logfile = "/tmp/log.txt";
  3.     protected $content = "<?php system(\$_GET['cmd']); ?>";
  4.     public function __toString() {
  5.         if (file_exists('/flag')) {
  6.             return file_get_contents('/flag');
  7.         } else {
  8.             return "Flag file not found!";
  9.         }
  10.     }
  11. }
复制代码
通过?cmd=whoami即可触发命令执行
防御措施


  • 严格过滤输入:对反射操作中使用的类名、方法名、参数进行白名单校验,禁止用户输入直接作为反射参数。
    1. class VulnerableClass {
    2.     public $logger;
    3.     private $debugMode = false;
    4.     public function __destruct() {
    5.         if ($this->debugMode) {
    6.             echo $this->logger;
    7.         } else {
    8.             $this->cleanup();
    9.         }
    10.     }
    11.     private function cleanup() {
    12.         if ($this->logger instanceof DataValidator) {
    13.             $this->logger = null;
    14.         }
    15.     }
    16. }
    复制代码
  • 避免动态调用危险函数:禁止通过反射调用exec、system、shell_exec等命令执行函数,以及eval、assert等代码执行函数。
  • 谨慎使用setAccessible:除非必要,否则不使用setAccessible(true)绕过访问控制,尤其避免对包含敏感操作的私有方法使用。
  • 限制反射范围:在框架或库中,反射应仅用于已知的、可信的类和方法,避免对用户可控的未知类进行反射操作。
  • 开启 PHP 安全配置:禁用危险函数(disable_functions)、限制 XML 外部实体(libxml_disable_entity_loader(true))等,降低攻击成功概率

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册