[9] : des ofb - 2 - 47 solves : crypto: Decrypt the message, find the flag, and then marvel at how broken everything is. https://s3.amazonaws.com/bostonkeyparty/2016/e0289aac2e337e21bcf0a0048e138d933b929a8c.tarダウンロードしたファイルを解凍すると、Pythonのプログラムと暗号文ができます。
(略)Pythonのプログラムを確認すると、DESのOFBモードで暗号化されていることが分かります。また、IV(初期化ベクトル)はソース中に記載があり分かりますが、KEYと平文は与えられていません。
IV = '13245678'
a = DES.new(KEY, DES.MODE_OFB, IV)
(略)
まず、DESのOFBモードについて確認してみましょう。OFBモードは、IVをKEYを用いて暗号化し、それをまた暗号化し、それを繰り返して乱数列を生成します。そして、その乱数列と平文とのXORをとったものを暗号文として出力します。
また、以下のサイトの解説も分かりやすいです。
http://www.triplefalcon.com/Lexicon/Encryption-Block-Mode-1.htm#OFB
ここで、暗号文を確認します。
ADDRESS 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEFザーッと目を通すと、16バイトごとに表示した場合、一列(縦方向)に出現するバイトデータにかなり偏りがあるように見えます。つまり、縦方向に見た場合、ASCIIコード(印字可能文字)に対して固定のバイト値でXORを取っているのではないかと推測できます。
------------------------------------------------------------------------------
00000000 70 2B 7B EF 93 27 53 D3 43 13 5C 5B 41 16 43 57 p+{��'SモC.\[A.CW
00000010 04 26 3E A1 D6 7F 1B DD 45 13 5B 47 15 42 5F 5D .&>。ヨ..ンE.[G.B_]
00000020 04 35 2E E8 85 7F 1A D3 5F 09 38 63 5D 53 43 50 .5.閻..モ_.8c]SCP
00000030 41 36 7B AA 82 62 00 9C 7F 5C 50 58 50 44 17 51 A6{ェC...\PXPD.Q
00000040 4A 64 2F E5 93 2B 1E D5 5F 57 12 40 5A 16 44 4D Jd/蜩+.ユ_W.@Z.DM
00000050 42 22 3E FF FC 5F 1B D9 11 60 5E 5D 5B 51 44 18 B">.��.ル.`^][QD.
00000060 45 2A 3F AD B7 79 01 D3 46 40 12 5B 53 16 58 4D E*?ュキy.モF@.[S.XM
00000070 50 36 3A EA 93 64 06 CF 11 75 5D 46 41 43 59 5D P6:齠d.マ.u]FACY]
00000080 08 4E 14 FF D6 7F 1C 9C 45 52 59 51 15 77 45 55 .N..ヨ..廢RYQ.wEU
00000090 57 64 3A EA 97 62 1D CF 45 13 53 14 66 53 56 18 Wd:齬b.マE.S.fSV.
000000A0 4B 22 7B F9 84 64 06 DE 5D 56 41 18 3F 77 59 5C K"{d.゙]VA.?wY\
000000B0 04 26 22 AD 99 7B 03 D3 42 5A 5C 53 15 53 59 5C .&"ュ几.モBZ\S.SY\
000000C0 04 30 33 E8 9B 31 53 C8 5E 13 56 5D 50 1A 17 4C .03陋1Sネ^.V]P..L
000000D0 4B 64 28 E1 93 6E 03 B6 7F 5C 12 59 5A 44 52 03 Kd(癈n.カ.\.YZDR.
000000E0 04 25 35 E9 D6 69 0A 9C 50 13 41 58 50 53 47 14 .%5鰒i.弃.AXPSG.
000000F0 04 30 34 AD 85 6A 0A 9C 46 56 12 51 5B 52 3D 6C .04ュ��.廡V.Q[R=l
00000100 4C 21 7B C5 93 6A 01 C8 1C 52 51 5C 50 1A 17 59 L!{ナ屠.ネ.RQ\P..Y
したがって、一列すべての暗号データについて、XORをとったときにASCIIコード(印字可能文字)になる値を求めるプログラムを書いてみます。
import re実行すると、次の出力を得ることができます。
def is_allowed_chars(s):
m = re.search(r'^[\x0A\x0D\x20-\x7D]+$', s)
return True if m else False
f = open('ciphertext', 'rb')
ciphertext = f.read()
f.close()
i = 0
while i < 16:
print '%x' % i + '=========='
j = 0
while j < 256:
flag = 0
ppp = bytearray()
for x in ciphertext:
ppp.append(ord(x) ^ j)
for c in range(i, len(ppp), 16):
if not is_allowed_chars(chr(ppp[c])):
flag = 1
break
if flag == 0:
print ' ' + '%x' % j
j = j + 1
i = i + 1
0==========ここで得られた値より16バイトのバイト配列と暗号文とのXORをとり、フラグ形式であるBKPCTF{が出現するパターンを数回試行錯誤して求めます。その後、不明な8、9、10(a)バイト目の値については、復号後の平文より単語になるように値を決定します。
22
23
24
25
26
27
2c
2d
30
31
1==========
44
2==========
5b
3==========
8a
8d
4==========
f6
5==========
b
c
6==========
59
5e
73
7==========
bb
bc
8==========
9==========
a==========
b==========
33
34
c==========
35
d==========
22
23
32
33
34
35
36
37
e==========
30
37
f==========
38
次のとおり、XORをとる16バイトのバイト配列を決定し、暗号文を復号するプログラムを書きます。
ooo = [0x24, 0x44, 0x5b, 0x8d, 0xf6, 0x0b, 0x73, 0xbc, 0x31, 0x33, 0x32, 0x34, 0x35, 0x36, 0x37, 0x38]実行すると、下記のとおり復号されました。
f = open('ciphertext', 'rb')
ciphertext = f.read()
f.close()
ppp = bytearray()
c = 0
for x in ciphertext:
ppp.append(ord(x) ^ ooo[c % 16])
c = c + 1
f = open('ans/ooo.txt', 'wb')
f.write(ppp)
f.close()
To be, or not to be, that is the question:したがって、フラグは、
Whether 'tis Nobler in the mind to suffer
The Slings and Arrows of outrageous Fortune,
Or to take Arms against a Sea of troubles,
And by opposing end them: to die, to sleep
No more; and by a sleep, to say we end
The Heart-ache, and the thousand Natural shocks
That Flesh is heir to? 'Tis a consummation
Devoutly to be wished. To die, to sleep,
To sleep, perchance to Dream; aye, there's the rub,
For in that sleep of death, what dreams may come,
When we have shuffled off this mortal coil,
Must give us pause. There's the respect
That makes Calamity of so long life:
For who would bear the Whips and Scorns of time,
The Oppressor's wrong, the proud man's Contumely,
The pangs of despised Love, the Law窶冱 delay,
The insolence of Office, and the Spurns
That patient merit of the unworthy takes,
When he himself might his Quietus make
With a bare Bodkin? Who would Fardels bear,
To grunt and sweat under a weary life,
But that the dread of something after death,
The undiscovered Country, from whose bourn
No Traveller returns, Puzzles the will,
And makes us rather bear those ills we have,
Than fly to others that we know not of.
Thus Conscience does make Cowards of us all,
And thus the Native hue of Resolution
Is sicklied o'er, with the pale cast of Thought,
And enterprises of great pitch and moment,
With this regard their Currents turn awry,
And lose the name of Action. Soft you now,
The fair Ophelia? Nymph, in thy Orisons
Be all my sins remembered. BKPCTF{so_its_just_a_short_repeating_otp!}
BKPCTF{so_its_just_a_short_repeating_otp!}です。