この大会は2018/11/9 21:00(JST)~2018/11/11 21:00(JST)に開催されました。
今回もチームで参戦。結果は 916.6点で1466チーム中55位でした。
自分で解けた問題をWriteupとして書いておきます。
xor game (Crypto)
xorの鍵が不明で、その鍵を突き止める問題。
暗号化データをBase64デコードして、XOR Cracker(https://wiremask.eu/tools/xor-cracker/)にかける。
その結果を参考にして調整しながら、鍵を求める。
from Crypto.Util.strxor import strxor import base64 def dec(data, key): key = (key * (len(data) / len(key) + 1))[:len(data)] return strxor(data, key) with open('cipher.txt', 'r') as f: data = f.read() b64enc = base64.b64decode(data) with open('cipher', 'wb') as f: f.write(b64enc) ## arrange ## print dec(b64enc, 'xor_is_interesting!@#')
これを実行すると、きちんと復号できていることが分かる。
Life, thin and light-off time and time again Frivolous tireless one I heard the echo, from the valleys and the heart Open to the lonely soul of sickle harvesting Repeat outrightly, but also repeat the well-being of Eventually swaying in the desert oasis I believe I am Born as the bright summer flowers Do not withered undefeated fiery demon rule Heart rate and breathing to bear the load of the cumbersome Bored Two I heard the music, from the moon and carcass Auxiliary extreme aestheticism bait to capture misty Filling the intense life, but also filling the pure There are always memories throughout the earth I believe I am Died as the quiet beauty of autumn leaves Sheng is not chaos, smoke gesture Even wilt also retained bone proudly Qing Feng muscle Occult Three I hear love, I believe in love Love is a pool of struggling blue-green algae As desolate micro-burst of wind Bleeding through my veins Years stationed in the belief Four I believe that all can hear Even anticipate discrete, I met the other their own Some can not grasp the moment Left to the East to go West, the dead must not return to nowhere See, I wear Zan Flowers on my head, in full bloom along the way all the way Frequently missed some, but also deeply moved by wind, frost, snow or rain Five Prajna Paramita, soon as soon as life be beautiful like summer flowers and death like autumn leaves Also care about what has
hctf{xor_is_interesting!@#}
xor?rsa (Crypto)
$ nc rsa.2018.hctf.io 10086 Welcome to flag getting system give me your token > 2jrCI4AslZF63Or3g0BCLzKoe0rXGTYZ n=25275261816080723577383625252321605813293020177515415346273626867915569138289688717413356558193996845476305528125832070604557462428746989292112808118629779995853500422163753237317584703994425361069816700082487715542167171713699666726887235382197073068733120714572524136047731843566904816054447149749558432678912765881098765528412138624603442724195067422316458776382746088522690538448161527517375561342031327658770828995835520042246472144202767031798115768655362628916139166585435054566298105440647015024307766333320215539234184515515996807842360812897141090870808136031078799184603768964924810402365848053621310874371 c1=11165085713561189003280953910551795650069641727697255665204270392356119682302194809551085381412459067137708791048033212887178854783178521082866084322294736924387003502539404006446446960913768668751546334339464672969536040183161881553997971542237143014930493145940738807334373127733697348176468962798526646137597541643569114699950367076718329916819155968155932149333397328469867074678751467552042630972042728542318490144115620371495906795551552788089985932610796897659179997445268713553678805380667254387708279651188394366215609009582176348204515365158369592961753687386325076074438007962972262423575684012468736502784 c2=3692619448894086202620380631082268435018623838407343923441472120868415709925497517010788618542797329154197746377107382855787882364201552243204454392390226061058770734934557129438642712750088115325177185876919748092262061559995643597615670605259279309223337082989077402836087239826642767218219888576126501421187433421552115165902886235999884421474474839807257919154091416829866712451600989516801908414284252064861856712338940516499148321453909303775761944595561080379704862572754567977567513085826683733515940571450314778688781004557900332788704156673505934867551765430160894036472529704734924702982507494191016739987 now give me you answer
それぞれパラメータは以下のようになっている。
p = 1024ビットランダム素数 q = 1024ビットランダム素数 n = p * q e = 5 kbits = nのビット数 // (2*e*e) m1 = nのビット数のランダム整数 m2 = m1 ^ kbitsのランダム整数 c1 = pow(m1, e, n) c2 = pow(m2, e, n)
m1とm2を求める問題。kbitsが上記の定義なので、m1とm2の差は小さく、Coppersmith's Short Pad Attackでそれぞれ復号できる。
# solve.sage import socket def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def short_pad_attack(c1, c2, e, n): PRxy.<x,y> = PolynomialRing(Zmod(n)) PRx.<xn> = PolynomialRing(Zmod(n)) PRZZ.<xz,yz> = PolynomialRing(Zmod(n)) g1 = x^e - c1 g2 = (x+y)^e - c2 q1 = g1.change_ring(PRZZ) q2 = g2.change_ring(PRZZ) h = q2.resultant(q1) h = h.univariate_polynomial() h = h.change_ring(PRx).subs(y=xn) h = h.monic() kbits = n.nbits()//(2*e*e) diff = h.small_roots(X=2^kbits, beta=0.5)[0] return diff def related_message_attack(c1, c2, diff, e, n): PRx.<x> = PolynomialRing(Zmod(n)) g1 = x^e - c1 g2 = (x+diff)^e - c2 def gcd(g1, g2): while g2: g1, g2 = g2, g1 % g2 return g1.monic() return -gcd(g1, g2)[0] token = '2jrCI4AslZF63Or3g0BCLzKoe0rXGTYZ' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('rsa.2018.hctf.io', 10086)) data = recvuntil(s, '> ') print data + token s.sendall(token + '\n') data = recvuntil(s, '\n').strip() print data n = Integer(data[2:]) e = 5 data = recvuntil(s, '\n').strip() print data c1 = Integer(data[3:]) data = recvuntil(s, '\n').strip() print data c2 = Integer(data[3:]) diff = short_pad_attack(c1, c2, e, n) m1 = related_message_attack(c1, c2, diff, e, n) m2 = m1 + diff data = recvuntil(s, '\n').strip() print data print m1 s.sendall(str(m1) + '\n') print m2 s.sendall(str(m2) + '\n') data = s.recv(1024) print data
hctf{c81d20647f1ff3d55fc25626cd29ec4d95a3d66977973569a5a7a1b2487a1e9a}