thinkphp_5.0.24 rce漏洞思路学习
起点:
thinkphp/library/think/process/pipes/Windows.php
removeFiles
方法
跳板:
file_exists
方法能够触发__toString
魔术方法
$filename
跳板利用点:
thinkphp/library/think/Model.php
Model抽象类的 __toString
跟进toJson方法至toArray方法
如下图Model抽象类的toArray方法,存在三个地方可以执行__call
但是我们目的是调用Output类的__call且能够继续利用,调试后选择第三处当做调板
$item[$key] = $value ? $value->getAttr($attr) : null;
观察第三处
$item[$key] = $value ? $value->getAttr($attr) : null;
溯源$values
变量,比较关键是下面两行
$modelRelation = $this->$relation();
$value = $this->getRelationData($modelRelation);
$modelRelation
值可以利用Model类中的getError
方法
跟进getRelationData方法,这里最后传入的$modelRelation需要Relation类型
最后返回值$values需要经过if语句判断
$this->parent && !$modelRelation->isSelfRelation() && get_class($modelRelation->getModel()) == get_class($this->parent)
全局搜索下,可以利用HasOne类
最后$attr值
,由$bindAttr = $modelRelation->getBindAttr();
执行后的结果.
至此代码执行到$item[$key] = $value ? $value->getAttr($attr) : null;
就能够执行Output类__call魔术方法
跟进Output类block方法
继续跟进writelin方法,最后会调用write方法
这里$this->handle可控,全局搜索write方法,进一步利用
定位到:thinkphp/library/think/session/driver/Memcached.php
类: Memcached
继续搜索可用set
方法
定位到:thinkphp/library/think/cache/driver/File.php
类:File
最后可以直接执行file_put_contents
方法写入shell
$filename
可控且可以利用伪协议绕过exit
$data
值比较棘手,这里有个坑,由于最后调用set方法
中的参数来自先前调用的write方法
只能为true,且这里$expire
只能为数值,这样文件内容就无法写shell
继续执行,跟进下方的setTagItem
方法
会再执行一次set方法
,且这里文件内容$value
通过$name
赋值(文件名)
所以可以在文件名上做手脚
示例:php://filter/write=string.rot13/resource=./<?cuc cucvasb();?>
POP链: