PHP|Thinkphp最新版本漏洞分析( 二 )


           if (!empty($this->relationWrite)) {
               $this->autoRelationUpdate();
           
           return true;
       
       if ($this->autoWriteTimestamp && $this->updateTime) {
           // 自动写入更新时间
           $data[$this->updateTime
      = $this->autoWriteTimestamp();
           $this->data[$this->updateTime
= $data[$this->updateTime
;
       
       // 检查允许字段
       $allowFields = $this->checkAllowFields();

跟进checkAllowFields方法 , 漏洞方法是db , 默认也是会触发该方法 , 继续跟进 。

protected function checkAllowFields(): array
   {
       // 检测字段
       if (empty($this->field)) {
           if (!empty($this->schema)) {
               $this->field = array_keys(array_merge($this->schema $this->jsonType));
            else {
               $query = $this->db();

跟进db方法 , 存在$this->table . $this->suffix字符串拼接 , 可以触发__toString魔术方法 , 把$this->table设为触发__toString类即可 。

public function db($scope = [
): Query
   {
       /** @var Query $query */
       $query = self::$db->connect($this->connection)
           ->name($this->name . $this->suffix)
           ->pk($this->pk);
       if (!empty($this->table)) {
           $query->table($this->table . $this->suffix);
       

全局搜索__toString方法 , 最后选择vendor\\topthink\\think-orm\\src\\model\\concern\\Conversion.php类中的__toString方法 。
跟进__toString方法 , 调用了toJson方法 。

跟进toJson方法 , 调用了toArray方法 , 然后以JSON格式返回 。

跟进toArray方法漏洞方法是getAtrr默认就会触发 , 只需把$data设为数组就行 。

public function toArray(): array
   {
       $item       = [
;
       $hasVisible = false;

       foreach ($this->visible as $key => $val) {
           if (is_string($val)) {
               if (strpos($val '.')) {
                   [$relation $name
         = explode('.' $val);
                   $this->visible[$relation
[
= $name;
                else {
                   $this->visible[$val
= true;
                   $hasVisible          = true;
               
               unset($this->visible[$key
);