Skip to content

Commit

Permalink
kittycrypt: first writeup
Browse files Browse the repository at this point in the history
  • Loading branch information
rootlog1 committed Jan 16, 2025
1 parent 659f991 commit a360028
Showing 1 changed file with 62 additions and 5 deletions.
67 changes: 62 additions & 5 deletions 2025/IrisCTF_2025/kittycrypt/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,70 @@
# KittyCrypt

`Description`
There is example input, output and flag_output with encrypt code. Since we know pair of input and output, we can know what is the key and find the flag with that key.

`Solution`

```python
foo = "bar"
import binascii

# Go 코드 CharSet의 역매핑 (이모지 → 16진수 한 글자)
CAT_TO_HEX = {
"🐱": "0", "🐈": "1", "😸": "2", "😹": "3",
"😺": "4", "😻": "5", "😼": "6", "😽": "7",
"😾": "8", "😿": "9", "🙀": "A", "🐱‍👤": "B",
"🐱‍🏍": "C", "🐱‍💻": "D", "🐱‍👓": "E", "🐱‍🚀": "F",
}

def cat_to_hex_str(cat_cipher: str) -> str:
i = 0
hex_chars = []
sorted_keys = sorted(CAT_TO_HEX.keys(), key=len, reverse=True)

while i < len(cat_cipher):
for k in sorted_keys:
if cat_cipher.startswith(k, i):
hex_chars.append(CAT_TO_HEX[k])
i += len(k)
break
else:
raise ValueError(f"Unknown cat emoji at pos={i} -> {cat_cipher[i:i+5]}")
return "".join(hex_chars)

def hex_str_to_keyed_text(hex_str: str) -> str:
raw = binascii.unhexlify(hex_str)
return raw.decode('utf-8', errors='replace')

def recover_key(plaintext: str, keyed_text: str) -> list:
return [ord(k) - ord(p) for p, k in zip(plaintext, keyed_text)]

def decrypt_cat_cipher(cat_cipher: str, keys: list) -> str:
hex_str = cat_to_hex_str(cat_cipher)
keyed_text = hex_str_to_keyed_text(hex_str)

decrypted = []
for i, ch in enumerate(keyed_text):
decrypted.append(chr(ord(ch) - keys[i]))
return "".join(decrypted)

def main():
with open("example_input.txt", "r", encoding="utf-8") as f:
example_plain = f.read()
with open("example_output.txt", "r", encoding="utf-8") as f:
example_cipher = f.read()

ex_hex_str = cat_to_hex_str(example_cipher)
ex_keyed_text = hex_str_to_keyed_text(ex_hex_str)
keys = recover_key(example_plain, ex_keyed_text)

with open("flag_output.txt", "r", encoding="utf-8") as f:
flag_cipher = f.read()

flag_plain = decrypt_cat_cipher(flag_cipher, keys)
print("[+] Flag:")
print(flag_plain)

if __name__ == "__main__":
main()
```

![img](flag.png)

flag is: **flag{foo_bar}**
flag is: **irisctf{s0m371m3s_bY735_4r3n7_wh47_y0u_3xp3c7}**

0 comments on commit a360028

Please sign in to comment.