題目來源:csaw-ctf-2016-quals
題目描述:題目環境是一個論壇,有注冊、登錄、發布、評論的功能。
flag1
進入環境, 在展示文章的頁面 post.wtf 下發現路徑穿越漏洞,可以獲得網站源碼
源代碼中搜索flag關鍵字發現,當登錄用戶為admin時,可以get_flag1
先嘗試注冊一個賬號並登錄,發現如下 cookie
在泄露的源碼里得知有 users 目錄
繼續嘗試路徑穿越
發現自己注冊的賬號以及 admin 都被顯示了出來,對比之前的 cookie,發現這個就是TOKEN的值。
admin 的TOKEN也知道了,可以進行 cookie 欺騙。
故登錄 admin 所需的東西如下
登錄成功,獲得 flag1:xctf{cb49256d1ab48803
flag2
因為 wtf 不是常規的網頁文件,故尋找解析 wtf 文件的代碼:
通過源碼可以發現對bash命令的調用,訪問http://220.249.52.133:32374/wtf.sh得到linux腳本代碼。
進行審計后可發現,上傳wtf文件並執行,就可以控制服務器。
function include_page { # include_page pathname local pathname=$1 local cmd= [[ ${pathname(-4)} = '.wtf' ]]; local can_execute=$; page_include_depth=$(($page_include_depth+1)) if [[ $page_include_depth -lt $max_page_include_depth ]] then local line; while read -r line; do # check if we're in a script line or not ($ at the beginning implies script line) # also, our extension needs to be .wtf [[ $ = ${line01} && ${can_execute} = 0 ]]; is_script=$; # execute the line. if [[ $is_script = 0 ]] then cmd+=$'n'${line#$}; else if [[ -n $cmd ]] then eval $cmd log Error during execution of ${cmd}; cmd= fi echo $line fi done ${pathname} else echo pMax include depth exceeded!p fi }
繼續進行審計,發現reply函數也存在路徑穿越漏洞。
function reply { local post_id=$1; local username=$2; local text=$3; local hashed=$(hash_username "${username}"); curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1); next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}"); next_file=(posts/${post_id}/${next_reply_id}); echo "${username}" > "${next_file}"; echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}"; echo "${text}" >> "${next_file}"; # add post this is in reply to to posts cache echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts"; }
這是評論功能的后台代碼,下面這行代碼把用戶名寫在了評論文件的內容中
echo "${username}" > "${next_file}";
如果用戶名是一段可執行代碼,而且寫入的文件后綴是wtf,那么這個文件就能夠執行我們想要的代碼。 (wtf.sh只運行文件擴展名為.wtf的腳本和前綴為’$'的行)
先普通地評論一下,知曉評論發送的數據包的結構
在普通評論的基礎上,進行路徑穿越,上傳后門sh.wtf
%09是水平制表符,必須添加,不然后台會把我們的后門當做目錄去解析。
訪問后門,發現成功寫入用戶名
為了寫入惡意代碼,我們得讓用戶名里攜帶代碼,故
首先注冊這樣一個用戶
${find,/,-iname,get_flag2}
這里前面加個$是wtf文件執行命令的寫法
尋找 所有目錄下 不分大小寫,名為 get_flag2 的文件
登錄,寫入后門
訪問后門路徑,執行代碼,尋找get_flag2(因為之前獲得 flag1 的時候是 get_flag1)
獲得 flag2 所在的路徑:/usr/bin/get_flag2
繼續注冊新用戶
$/usr/bin/get_flag2
登錄,寫入后門
訪問后門路徑,執行代碼,獲得 flag2:149e5ec49d3c29ca}
故最終的flag為:xctf{cb49256d1ab48803149e5ec49d3c29ca}
參考:https://blog.cindemor.com/post/ctf-fairy-1.html