2 min read

crackmes.one - Sexy 1337 writeup (zh-TW)

crackmes.one - Sexy 1337 writeup (zh-TW)

題目連結: https://crackmes.one/crackme/6715466c9b533b4c22bd18bb

1) 先看 main:決定要追的兩個函式

main 可以一次抓到三個關鍵事實:

  • generate_password(local_48, "sexy1337")
    ⇒ 有一個「以固定種子產生密碼」的步驟
  • encrypt_decrypt(local_48, 0xffffffaa)encrypt_decrypt(local_88, 0xffffffaa)
    同一把 key(0xAA)分別作用在「正確密碼」與「使用者輸入」上
  • strcmp(local_88, local_48)
    ⇒ 最終比較發生在兩次加密(XOR)之後

結論:先去看「密碼怎麼被產生」→ generate_password;再回來驗證「同鑰 XOR 的效果」→ encrypt_decrypt

2) 追 generate_password:算出「密碼明文」

for (i = 0; i < strlen(seed); i++) {
  dst[i] = seed[i] + 3;
}
dst[len] = '\0';
  • 種子是固定字串:"sexy1337"
  • 逐字元 +3(ASCII Caesar shift)

手算:

  • s→v、e→h、x→{、y→|、1→4、3→6、3→6、7→:
  • 得到密碼明文:vh{|466:

到這裡,我們已經知道「正確密碼的未 XOR 版本」。

3) 看 encrypt_decrypt:確認「同鑰 XOR」的等價性

for (...) {
  buf[i] ^= 0xAA;   // 0xffffffaa 的低 8 位即 0xAA
}

main兩邊都做 ^ 0xAA 後再 strcmp
XOR 的性質:a == b ⇔ (a ^ k) == (b ^ k)
因此「兩邊都 XOR 同一把鑰」等價於直接比較原文

推論:我們只要在輸入框裡輸入剛剛算出的明文vh{|466:),就會與「產生後亦 XOR 的密碼」在 XOR 後相等。

4) 回到 main:收斂成最終輸入

main 的剩餘細節只是讀字串、去掉換行,然後 strcmp
既然比較等價於比較原文,我們的最終輸入就是:

vh{|466:

總結

  • main 發現「先生成密碼、雙方同鑰 XOR、最後 strcmp」的流程
  • generate_password 算出明文密碼 vh{|466:
  • encrypt_decrypt 的「同鑰 XOR 等價比較原文」確認邏輯
  • 回到 main 下結論:直接輸入 vh{|466: 即可通關

經驗分享

上面提到的程式碼,是經過ghidra反編譯過的程式碼,所以我們是透過分析反編譯的程式碼解出這題喔!