FEAL - CSAW CTF 2014 Quals Crypto300
-
Upload
yokaro-mon -
Category
Engineering
-
view
943 -
download
0
Transcript of FEAL - CSAW CTF 2014 Quals Crypto300
FEAL
APPENDIX FOR KATAGAITAI CTF TECHTALK CSAW CTF 2014 QUALS - CRYPT0 300
YOU0708@YOKARO-MON
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
NOTICE
▸ This material is an appendix for katagaitai CTF TechTalk
▸ https://atnd.org/events/71810
▸ An modified version was used in katagaitai CTF
▸ Encryption key (SUBKEY) is fixed hex strings
FEAL 4.3
CSAW CTF 2014 QUALS CRYPT0 300 FEAL
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
FEAL 4.3
▸ Feal 4.3 is used for the question
You must first solve a puzzle, a sha1 sum ending in 16 bit's set to 1, it must be of length 21 bytes, starting with PkExU2wOJRG/XBDB
Welcome to feal 4.3Please decrypt: edcf27af7821cc71615f329e78d1f65e
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
FBOX IN FEAL 4.3
▸ Feal 4.3 uses “rot 3” in fBox
▸ Differential values are not same with Feal 4
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
DIFFERENTIAL VALUEIn [1]: import array
In [2]: %pastedef rot3(x): return ((x<<3)|(x>>5))&0xffdef gBox(a,b,mode): return rot3((a+b+mode)%256)def fBox(plain):(snip.)
In [3]: x1 = array.array("B", "80800000".decode("hex"))
In [4]: fBox(x1)Out[4]: [10, 64, 8, 68]
In [5]: x2 = array.array("B", "00000000".decode("hex"))
In [6]: fBox(x2)Out[6]: [10, 64, 8, 64]
In [7]: for a, b in zip(fBox(x1), fBox(x2)): print a ^ b, ....: 0 0 0 4 ΔY = 0x00000004
BREAKING FEAL 4.3
CSAW CTF 2014 QUALS CRYPT0 300 FEAL
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K3 FEALの最終ラウンドの差分解析49
0x02000000
key
f
出力差分(ΔC1)
ΔC1+ΔC2入力差分(ΔX1) 入力差分(ΔX2)
出力差分(ΔC2)
f(C1+C2+key)+f(C1’+C2’+key)
この値は?
ΔC1 = f(C1+C2+key)+f(C1’+C2’+key)+0x02000000
0x00000004
0x00000004
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K3k3 = Noneif k3 == None: print "[*] start k3 attack" p1, p2, c1, c2, dc1, dc2, dcL, dcR = get_dataset(f, n, array.array(“B”,"8080000080800000".decode("hex")))
for k3 in xrange(65536): k3 = array.array("B", "%04x"%k3) for i in xrange(n): if dcL[i] != list_xor( list_xor( fBox(list_xor(dc1[i], k3)), fBox(list_xor(dc2[i], k3))), array("B", “00000004”.decode("hex")) ): break else: print "[*] found k3: %s" % "".join(map(chr, k3)) break else: print "[!] could not find k3" return
SUBKEY is hex string
Multiple candidates will be find if you use few plainest sets
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K2
0x02000000
key
f
出力差分(ΔC1)
ΔC1+ΔC2入力差分(ΔX1) 入力差分(ΔX2)
出力差分(ΔC2)
f(C1+C2+key)+f(C1’+C2’+key)
この値は?
ΔC1 = f(C1+C2+key)+f(C1’+C2’+key)+0x02000000
0x80800000
0x80800000
It can be calculated from encrypted value and k3
It can be calculated from encrypted value and k3
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K2for i in xrange(n): c1L = list_xor(c1[i][:4], c1[i][4:]) c1R = list_xor(c1[i][:4], fBox(list_xor(k3, list_xor(c1[i][4:], c1[i][:4])))) c2L = list_xor(c2[i][:4], c2[i][4:]) c2R = list_xor(c2[i][:4], fBox(list_xor(k3, list_xor(c2[i][4:], c2[i][:4])))) c1[i] = c1L + c1R c2[i] = c2L + c2R dcL[i] = list_xor(c1L, c2L)
for k2 in xrange(65536): k2 = array.array("B", "%04x"%k2) for i in xrange(n): if dcL[i] != list_xor( list_xor( fBox(list_xor(c1[i][4:], k2)), fBox(list_xor(c2[i][4:], k2))), array("B", "80800000".decode("hex"))): break else: print "[*] found k2: %s" % "".join(map(chr, k2)) breakelse: print "[!] could not find k2" return
Calculate ΔC1, ΔC2 using k3
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K1
▸ You must re-generate plaintext sets to change result after fBox
FEALの差分解析41
� 次の差分を持つ平文ペアを入力する� 0x8080000080800000
� 同じ鍵で暗号化されているため鍵の入力差分は0
0x80800000 0x80800000
0x80800000
0
0x02000000
ここの差分は不明
0
ΔC1 is fixed value It means: k1 can not be calculated
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K1
▸ e.g. ΔX = 0x0000000040000000
FEALの差分解析41
� 次の差分を持つ平文ペアを入力する� 0x8080000080800000
� 同じ鍵で暗号化されているため鍵の入力差分は0
0x80800000 0x80800000
0x80800000
0
0x02000000
ここの差分は不明
0
0x00000000 0x40000000
0x40000000????
????
ΔX1 = 0x40000000
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K1
0x02000000
key
f
出力差分(ΔC1)
ΔC1+ΔC2入力差分(ΔX1) 入力差分(ΔX2)
出力差分(ΔC2)
f(C1+C2+key)+f(C1’+C2’+key)
この値は?
ΔC1 = f(C1+C2+key)+f(C1’+C2’+key)+0x02000000
0x40000000
0x40000000
It can be calculated from encrypted value and k3
It can be calculated from encrypted value, k3, and k2
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K1p1, p2, c1, c2, dc1, dc2, dcL, dcR = get_dataset(f, n, array.array("B","0000000040000000".decode("hex")))for i in xrange(n): c1L = list_xor(c1[i][:4], c1[i][4:]) c1R = list_xor(c1[i][:4], fBox(list_xor(k3, list_xor(c1[i][4:], c1[i][:4])))) c2L = list_xor(c2[i][:4], c2[i][4:]) c2R = list_xor(c2[i][:4], fBox(list_xor(k3, list_xor(c2[i][4:], c2[i][:4])))) c1[i] = c1L + c1R c2[i] = c2L + c2R dcL[i] = list_xor(c1L, c2L) c1L = c1[i][4:] c1R = list_xor(c1[i][:4], fBox(list_xor(k2, c1[i][4:]))) c2L = c2[i][4:] c2R = list_xor(c2[i][:4], fBox(list_xor(k2, c2[i][4:]))) c1[i] = c1L + c1R c2[i] = c2L + c2R dcL[i] = list_xor(c1L, c2L)
for k1 in xrange(65536): k1 = array.array("B", "%04x"%k1) for i in xrange(n): if dcL[i] != list_xor( list_xor( fBox(list_xor(c1[i][4:], k2)), fBox(list_xor(c2[i][4:], k2))), array("B", "80800000".decode("hex"))):
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K0
▸ e.g. ΔX = 0x0000000040000000
FEALの差分解析41
� 次の差分を持つ平文ペアを入力する� 0x8080000080800000
� 同じ鍵で暗号化されているため鍵の入力差分は0
0x80800000 0x80800000
0x80800000
0
0x02000000
ここの差分は不明
0
0x00000000 0x40000000
0x0400000????
????
ΔX1 = 0x00000000
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K0for i in xrange(n): c1L = c1[i][4:] c1R = list_xor(c1[i][:4], fBox(list_xor(k1, c1[i][4:]))) c2L = c2[i][4:] c2R = list_xor(c2[i][:4], fBox(list_xor(k1, c2[i][4:]))) c1[i] = c1L + c1R c2[i] = c2L + c2R dcL[i] = list_xor(c1L, c2L)
for k0 in xrange(65536): k0 = array.array("B", "%04x"%k0) for i in xrange(n): if dcL[i] != list_xor(fBox(list_xor(c1[i][4:], k0)), fBox(list_xor(c2[i][4:], k0))): break else: print "[*] found k0: %s" % "".join(map(chr, k0)) breakelse: print "[!] could not find k0" return
CSAW CTF 2014 QUALS - CRYPT0 300: FEAL
K4, K5, FLAG
k4 = list_xor(list_xor(fBox(list_xor(k0, c1[0][4:])), c1[0][:4]), p1[0][:4])print "[*] found k4: %s" % "".join(map(chr, k4))
k5 = list_xor(list_xor(list_xor(p1[0][:4], k4), c1[0][4:]), p1[0][4:])print "[*] found k5: %s" % "".join(map(chr, k5))
k = [k0, k1, k2, k3, k4, k5]print "[*] got encryption key:", k
flag = "".join(map(chr, feal.decrypt(array("B", flag1), k))) + "".join(map(chr, feal.decrypt(array("B", flag2), k)))print "[*] the flag is:", flag
THANK YOU!
CSAW CTF 2014 QUALS CRYPT0 300 FEAL