轩辕娅童 发表于 2025-8-27 11:35:20

PHP特性之反射类ReflectionClass机制

PHP特性之反射类ReflectionClass机制


目录

[*]PHP特性之反射类ReflectionClass机制

[*]引例
[*]详细阐述

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



引例

最近在刷polarD&N靶场的时候,做到了一道关于ReflectionClass机制
原题是这样的
<?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('/^+={0,2}$/', $_GET['data'])) {
      unserialize($raw);
    }
} else {
    highlight_file(__FILE__);
}
?>将上述内容作为 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('/^+={0,2}$/', $_GET['data'])) {
      unserialize($raw);
    }
} else {
    highlight_file(__FILE__);
}
?> 位置,导致敏感文件被读取并可能通过后续逻辑泄露。
3.绕过访问控制执行私有危险方法
若类中存在私有方法包含危险操作(如执行系统命令),攻击者可通过反射的setAccessible(true)突破限制并调用:
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!";
      }
    }
}通过?cmd=whoami即可触发命令执行
防御措施


[*]严格过滤输入:对反射操作中使用的类名、方法名、参数进行白名单校验,禁止用户输入直接作为反射参数。
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;
      }
    }
}
[*]避免动态调用危险函数:禁止通过反射调用exec、system、shell_exec等命令执行函数,以及eval、assert等代码执行函数。
[*]谨慎使用setAccessible:除非必要,否则不使用setAccessible(true)绕过访问控制,尤其避免对包含敏感操作的私有方法使用。
[*]限制反射范围:在框架或库中,反射应仅用于已知的、可信的类和方法,避免对用户可控的未知类进行反射操作。
[*]开启 PHP 安全配置:禁用危险函数(disable_functions)、限制 XML 外部实体(libxml_disable_entity_loader(true))等,降低攻击成功概率

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除
页: [1]
查看完整版本: PHP特性之反射类ReflectionClass机制