記錄一道完全超出我能力的CTF神仙題(不愧是世界級比賽的真題orz),此題我僅解出了第一部分的flag,第二部分則參考了WP。不得不說這種題目解出來還是很有自豪感的嘛~ 直接看題!
0x01 第一部分flag
打開題目:
隨便點擊幾個瀏覽可以看出題目環境是一個論壇,我們先注冊個賬號:
通過一些簡單的測試像是sql注入,目錄爆破,源碼泄露這種常見套路走不通了hhhhhh,最后不斷嘗試:在展示文章的頁面 post.wtf 下發現路徑穿越漏洞(如果應用程序使用用戶可控制的數據,以危險的方式訪問位於應用服務器或其它后端文件系統的文件或目錄,就會出現路徑遍歷。攻擊者可以將路徑遍歷序列放入文件名內,向上回溯,從而訪問服務器上的任何文件)
,可以獲得網站源碼:
尋找flag關鍵字:
代碼格式化:
發現如下部分:
可以看到只要登錄 admin 賬號就可以獲得 flag1:
在泄露的源碼里得知有 users 目錄,繼續嘗試路徑穿越:
可以看到里面有我們的賬號信息和admin的信息,看到這些字符串如果經驗豐富的話可以猜測是cookie或者是代表我們身份的令牌:老套路抓包試試:
可以看到我們用戶名下面的第二行就是代表我們身份的令牌,admin的令牌也知道了,可以進行 cookie 欺騙啦HHH~,抓包修改!
拿到第一個flag!
0x02:第二個flag
get_flag1和get_flag2是Set-UID(SUID)二進制文件,我們想要提升到flag1和flag2用戶的權限以讀取這些文本文件並不容易,因此,我們需要代碼執行
因為 wtf 不是常規的網頁文件,故尋找解析 wtf 文件的代碼:
格式化代碼:
1 max_page_include_depth=64 2 3 page_include_depth=0 4 5 function include_page { 6 7 # include_page pathname 8 9 local pathname=$1 10 11 local cmd= 12 13 [[ ${pathname(-4)} = '.wtf' ]]; 14 15 local can_execute=$; 16 17 page_include_depth=$(($page_include_depth+1)) 18 19 if [[ $page_include_depth -lt $max_page_include_depth ]] 20 21 then 22 23 local line; 24 25 while read -r line; do 26 27 # check if we're in a script line or not ($ at the beginning implies script line) 28 29 # also, our extension needs to be .wtf 30 31 [[ $ = ${line01} && ${can_execute} = 0 ]]; 32 33 is_script=$; 34 35 36 # execute the line. 37 38 if [[ $is_script = 0 ]] 39 40 then 41 42 cmd+=$'n'${line#$}; 43 44 else 45 46 if [[ -n $cmd ]] 47 48 then 49 50 eval $cmd log Error during execution of ${cmd}; 51 52 cmd= 53 54 fi 55 56 echo $line 57 58 fi 59 60 done ${pathname} 61 62 else 63 64 echo pMax include depth exceeded! 65 pfi 66 67 }
通過這段代碼我們發現服務器能夠解析並執行 wtf 文件,如果還能夠上傳 wtf 文件並執行的話,就可以達到控制服務器的目的。
於是繼續審計代碼,發現如下代碼給了這個機會:
1 function reply { 2 3 local post_id=$1; 4 5 local username=$2; 6 7 local text=$3; 8 9 local hashed=$(hash_username "${username}"); 10 11 12 curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1); 13 14 next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}"); 15 16 next_file=(posts/${post_id}/${next_reply_id}); 17 18 echo "${username}" > "${next_file}"; 19 20 echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}"; 21 22 echo "${text}" >> "${next_file}"; 23 24 25 # add post this is in reply to to posts cache 26 27 echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts"; 28 29 }
這是評論功能的后台代碼,這部分也是存在路徑穿越的。
這行代碼把用戶名寫在了評論文件的內容中:echo "${username}" > "${next_file}";
通過上面的分析:如果用戶名是一段可執行代碼,而且寫入的文件是 wtf 格式的,那么這個文件就能夠執行我們想要的代碼。 (而且wtf.sh只運行文件擴展名為.wtf的腳本和前綴為'$'的行)
先普通地評論一下,知曉評論發送的數據包的結構,在普通評論的基礎上,進行路徑穿越,上傳后門sh.wtf
:
%09
是水平制表符,必須添加,不然后台會把我們的后門當做目錄去解析。
訪問后門,發現成功寫入:
為了寫入惡意代碼,我們得讓用戶名里攜帶代碼,故注冊這樣一個用戶:${find,/,-iname,get_flag2} 寫入后門:
訪問后門,執行代碼,尋找get_flag2
(因為之前獲得 flag1 的時候是 get_flag1
):
獲得 flag2 所在的路徑。
繼續注冊新用戶:$/usr/bin/get_flag2 寫入后門:
訪問后門,獲得 flag2:
0x03總結
第一部分的話仔細研究還是能做的:路徑穿越和cookie欺騙還是很常規的CTF賽題
此題的第二部分對於我目前是超出了能力范圍,所以我也是借鑒了網上得WP(https://blog.cindemor.com/post/ctf-fairy-1.html)
代碼審計能力還是要加強啊orz,還有一些小細節如“%09
是水平制表符,必須添加,不然后台會把我們的后門當做目錄去解析。”當時也沒有想到T_T。
這種國際賽題雖然難,還是要做的嘛~~迎難而上才能突破自己鴨!
今天剛報名了下學期的省賽 接下來還是要繼續去各大平台刷題總結 。加油啦!!
萌新的第一篇博客 請各位大佬多多指教啦!