可以看到我把利用链拆分为了两部分,前面一部分是到有字符串拼接操作为止,后面一部分是从字符串拼接的魔术方法开始,一直到代码执行的触发点 。接下来我们就一边梳理利用链,一边构造POC 。
Model的__destruct方法
public function __destruct(){ echo "lazySave的值:".$this->lazySave."<br>"; if ($this->lazySave) { $this->save(); }}这里要执行save方法,需要lazySave=true
跟进save方法,因为我们关注的只是updateData方法,所以updateData后面的代码我就省略掉了:
public function save(array $data = [], string $sequence = null): bool { // 数据对象赋值 $this->setAttrs($data); if ($this->isEmpty() || false === $this->trigger('BeforeWrite')) { return false; } $result = $this->exists ? $this->updateData() : $this->insertData($sequence); xxxxxxxxxxxx return true; }为了能够顺利执行到updateData(),我们需要保证前面的if条件判断不成立($this->isEmpth()==false和$this->trigger()==true)以及$this->exists=true
isEmpty
public function isEmpty(): bool{ return empty($this->data);}只要保证this->data不为空就行
trigger
protected function trigger(string $event): bool{ if (!$this->withEvent) { return true; } $call = 'on' . Str::studly($event); try { if (method_exists(static::class, $call)) { $result = call_user_func([static::class, $call], $this); } elseif (is_object(self::$event) && method_exists(self::$event, 'trigger')) { $result = self::$event->trigger(static::class . '.' . $event, $this); $result = empty($result) ? true : end($result); } else { $result = true; } return false === $result ? false : true; } catch (ModelEventException $e) { return false; }}看似这么长一串,但是我们只需要令withEvent=false就可以直接发挥true,回到save函数,接下来再令$this->exists==true,然后进入updateData()
protected function updateData(): bool { echo "updateData执行-----<br>"; // 事件回调 if (false === $this->trigger('BeforeUpdate')) { // 经过我们之前的设置,这儿直接跳过 return false; } $this->checkData(); // 获取有更新的数据 $data = $this->getChangedData(); if (empty($data)) { // 关联更新 if (!empty($this->relationWrite)) { $this->autoRelationUpdate(); } return true; } if ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) { // 自动写入更新时间 $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); $this->data[$this->updateTime] = $data[$this->updateTime]; } // 检查允许字段 $allowFields = $this->checkAllowFields(); xxxxxxxxx
推荐阅读
- 教你编译一个基于arm的Linux内核,并用qemu模拟器测试
- 教你编写你的第一个Linux 内核模块“hello_module”
- 黑客全家桶、文字提取利器、深度学习 500 问 | GitHub 热点速览
- 要给五脏及时排毒 教你穴位按摩排毒法
- 柑普茶怎么煮,教你若何更好冲泡柑普茶
- 柑普茶的饮用方法,教你若何更好冲泡柑普茶
- 看好你的系统,小心黑客来“挖矿”!
- 黑客界决战紫禁之巅 你盗我8225份数据库 我公布你的真实身份
- 压缩包的密码藏在哪?老司机教你揪出RAR密码
- 教你如何快速开发一个Dubbo应用
