0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SECCON CTF 2019 write-up

Posted at

##概要
SECCON CTF 2019のうち、crypt問題のcoffee_breakのwrite-upを記載します。
##問題
The program "encrypt.py" gets one string argument and outputs ciphertext.
Example:

$ python encrypt.py "test_text"
gYYpbhlXwuM59PtV1qctnQ==

The following text is ciphertext with "encrypt.py".
FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905
Please download "encrypt.py" from the following url.

encrypt.pyは以下のとおり。

encrypt.py
import sys
from Crypto.Cipher import AES
import base64

def encrypt(key, text):
    s = ''
    for i in range(len(text)):
        s += chr((((ord(text[i]) - 0x20) + (ord(key[i % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
    return s

key1 = "SECCON"
key2 = "seccon2019"
text = sys.argv[1]

enc1 = encrypt(key1, text)
cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
p = 16 - (len(enc1) % 16)
enc2 = cipher.encrypt(enc1 + chr(p) * p)
print(base64.b64encode(enc2).decode('ascii'))

##解法

"encrypt.py"はテキスト文を暗号化するプログラムのようです。
暗号化されたテキストを復号すればflagが手に入りそうです。

まずはencrypt関数を復号する関数(decrypt関数)を作成することにしました。
encrypt関数は、引数で与えられたテキスト(text)を文字ごとに、文字コードへ変換→計算→文字へ
変換しています。
なので、足されたものを引いて、引かれたものを足せば元に戻りそうです。
encrypt関数とdecrypt関数のみを含んだプログラムで動作確認をしつつ作成した関数が以下になります。

def decrypt(key, encTxt):
        t= ''
        for j in range(len(encTxt)):
                t += chr((((ord(encTxt[j]) -0x20) - (ord(key[j % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
        return t

"encrypt.py"の後半部分ですが、AESで暗号化しています。
AESは共通鍵暗号方式(暗号化と復号が同じ鍵を使用)なので、key2をそのまま流用可能です。
なお、pはブロックの端数を埋めるためのもの(パディング)です。
復号用の関数は以下のようになります。

decrypt.py
import sys
from Crypto.Cipher import AES
import base64

def decrypt(key, encTxt):
        t= ''
        for j in range(len(encTxt)):
                t += chr((((ord(encTxt[j]) -0x20) - (ord(key[j % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
        return t

key1 = "SECCON"
key2 = "seccon2019"
text = sys.argv[1]

dec1 = base64.b64decode(text)
cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
dec2 = cipher.decrypt(dec1).decode("ascii")
print(decrypt(key1, dec2))

これを実行すると以下のようになります。

$ python decrypt.py FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905
SECCON{Success_Decryption_Yeah_Yeah_SECCON}?AA56

flagが得られました。"}"以降の文字列はAES復号の際に付与されたパディングなので無視します。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?