2024-京津冀攻防-wp-crypto 简单比赛简单讲。
RSA 虽然是rsa,也可以当做签到题
1 2 n =48363840702351378505340249679776693226654002838833008943438059390140202146059 e =65537 c =26484031967841531957894805513848822590449042897972657337959532703929962519405
…..直接factordb分解然后解密即可
奇怪的密码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from hashlib import sha256def RTTjiVuSSazJQgkaAxzIlqkoJNjrHCma (a,b ): return '' .join([chr (ord (aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS) ^ ord (rFOZPruKCMieGyqlsazHalDjEurxXZFD)) for aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS,rFOZPruKCMieGyqlsazHalDjEurxXZFD in zip (a,b)])def CTYhfQLxlHLujgcTPvrBvPvCARHRzgZG (data ): return sha256(data).digest()[:8 ]def cKNBqRWpybOxuHbVodCBTRFtmEZkOPtb (subkeys, data ): aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS = 0 YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz = data[:8 ] QduyCChIFHDuxjITwVBOCkITFWucRCwX = data[8 :] for aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS in subkeys: YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz = RTTjiVuSSazJQgkaAxzIlqkoJNjrHCma(RTTjiVuSSazJQgkaAxzIlqkoJNjrHCma(CTYhfQLxlHLujgcTPvrBvPvCARHRzgZG(QduyCChIFHDuxjITwVBOCkITFWucRCwX),aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS),YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz) YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz,QduyCChIFHDuxjITwVBOCkITFWucRCwX = QduyCChIFHDuxjITwVBOCkITFWucRCwX,YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz return QduyCChIFHDuxjITwVBOCkITFWucRCwX + YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvzdef RrLEPBfHqeEZLegXpJufxMLPmKNPPCdw (key ): NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa = [] haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX = key for aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS in xrange(16 ): haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX = CTYhfQLxlHLujgcTPvrBvPvCARHRzgZG(haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX) NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa.append(haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX) return NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGadef DugSDFJhTeJpOOZBYjLhhJypmfwsrfuI (key,data ): NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa = RrLEPBfHqeEZLegXpJufxMLPmKNPPCdw(key) return cKNBqRWpybOxuHbVodCBTRFtmEZkOPtb(NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa, data).encode('hex' )if __name__ == "__main__" : print DugSDFJhTeJpOOZBYjLhhJypmfwsrfuI('explorer' ,'??flag_is_here??' )
本题最大难点其实就是改代码:
第一要f2改变量名 这个不难
第二要把python2的代码改成python3 这个有点难 因为python2的sha256似乎是string的 总之原来的代码写的很不严谨
然后只需要知道要把密钥颠倒一下再跑一次festiel结构就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from hashlib import sha256def xorstr (a,b ): return '' .join([chr (ord (ai) ^ ord (bi)) for ai,bi in zip (a,b)])def xorbytes (a, b ): return bytes ([(ai) ^ (bi) for ai, bi in zip (a, b)])def sha256_ (data ): if not isinstance (data, bytes ): data = data.encode() return sha256(data).digest()[:8 ]def festiel (subkeys, data ): i = 0 if not isinstance (data, bytes ): data_first = data[:8 ].encode() data_last = data[8 :].encode() else : data_first = data[:8 ] data_last = data[8 :] for i in subkeys: data_first = xorbytes(xorbytes(sha256_(data_last),i),data_first) data_first,data_last = data_last,data_first return data_last + data_firstdef genkey (key ): keylist = [] mykey = key for i in range (16 ): mykey = sha256_(mykey) keylist.append(mykey) return keylistdef encrypt (key,data ): key_ = genkey(key) return festiel(key_, data)def decrypt (key, data ): key_ = genkey(key) key_.reverse() return festiel(key_, data)print (decrypt("explorer" ,b'\x1f\xdej{/\xf1]\n\xba\xd6\x91!\\\xa5\xd4p' ))
byte_LFSR 其实说实话这题很简单,但是全场应该是只有我们队出了,我不做评价了。XD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from os import urandomfrom Crypto.Util.number import bytes_to_longfrom random import getrandbitsfrom flag import FLAGclass byte_lfsr : def __init__ (self, init, msg ): self.state = init self.mask = list (map (int , list (bin (msg)[2 :]))) while len (self.mask) % 8 != 0 : self.mask.append(0 ) def next (self ): nextstate = 0 for i, s in enumerate (self.state): nextstate ^= self.mask[i] * s self.state = self.state[1 :] + nextstate.to_bytes(1 , byteorder = 'big' ) bl = byte_lfsr(urandom(8 * len (FLAG)), bytes_to_long(FLAG))for i in range (getrandbits(10 )): bl.next () leak_seq = b"" trick = 1 + getrandbits(2 )for i in range (len (FLAG) * 16 ): bl.next () leak_seq += (bl.state[-1 ] >> trick).to_bytes(1 , byteorder = 'big' )with open (r"output.txt" , "w" ) as f: f.write(leak_seq.hex ())
思考一下
异或运算其实就是模二加法 mask只有1和0 所以这个next的过程其实就是矩阵方程
把生成的字节转化为二进制表示,容易发现trick等于2(很显然不多说 生成一下就知道
把生成字节的逐位二进制作为矩阵,例如
11001010 = [1,1,0,0,1,0,1,0]
以此将a化为一个6*608的矩阵
然后根据这个代码的逻辑我们会发现 $$ (mask_1,mask_2…mask_{304}) \begin{pmatrix}a_{1,1}&a_{1,2}&…&a_{1,6}\\ a_{2,1}&a_{2,2}&…&a_{2,6}\\ a_{3,1}&a_{3,2}&…&a_{3,6}\\ …&…&…&…\\ a_{304,1}&a_{304,2}&…&a_{304,6}\\\end{pmatrix} =(a_{305,1},a_{305,2},…,a_{305,6}) $$ 所以可以这么横向展开 $$ (mask_1,mask_2…mask_{304}) \begin{pmatrix}a_{1,1}&a_{1,2}&…&a_{1,6}&a_{2,1}&a_{2,2}&…&a_{304,6}\\ a_{2,1}&a_{2,2}&…&a_{2,6}&a_{3,1}&a_{3,2}&…&a_{305,6}\\ a_{3,1}&a_{3,2}&…&a_{3,6}&a_{4,1}&a_{4,2}&…&a_{306,6}\\ …&…&…&…&…&…&…&…\\ a_{304,1}&a_{304,2}&…&a_{304,6}&a_{305,1}&a_{305,2}&…&a_{607,6}\\\end{pmatrix} =(a_{305,1},a_{305,2},…,a_{305,6},a_{306,1},…,a_{608,6}) $$ 矩阵显然满秩,所以可以解出来
然后记得注意一下他有可能多一个0,如果解不出来就去除一下,比较简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 from Crypto.Util.number import *from hashlib import sha256from sage.all import * a = "360c2b0209350b2a3a202029300a0222292e211f203714190f1a29272c3d1610121c302819291e33051b291e352f091027031b153a350b0324022f1d390124300f0510363700360c2e063404203a193e292b0d091d2c2c1d0a2a051e2201172e3a011d2610261d0b2d1d0a140e3b0128301c13270014130d3d182e3b222c142e25081a3e38332d221b072804083a350b023c292d24063b0424331b0200211439062a3405033c3a0d083d17132134033924340c0019003b192f1e3c2e270a151c23152e0b3c201d3624373a240c0d3c1e2d16160b2a251131360e173a0c25280211153128370d08273d08272e23072d211e2a3c272b00073635060e1b111f15283c1133033f29101937343318151001383d1b3b3c26361b1a001a233d0d200d070f042d2c20323130141c21160c162a0b0a3c3e0d280e212d0e1433221709202c14140c1f3402181a17160e1a342b133439173e051a3212391d203e303a03312d2a22380b000d271702002f13371509200b273c0d18070f232a3119021e100f1d36281525282d2f27231f3136161728242d000a2b1c3b102038043f1f3f130c2b1437163a063f0e21392b2a11192a3922231c333c1f1f05222c2c1b3a11270032191035023632340f2439290f28213e001a04182c2f3522303c35273b2a0e002a1a081a3c1639290127100f110e123c04222c022137280435261e20262d2c2702101d3f0e0b361f002622153d302f3f1a1907171a1627271e200917201b3e112520130b270b3a2836041d3a0921341d361025271b3b1f391b15040f170a36303e1f300c283a28090e2c1821213d1e3213361334252d3a1d16101816370e37393f" a = bytes .fromhex(a) binary_representation = "" .join([bin (byte)[2 :].zfill(8 ) for byte in a]) binary_list = list (binary_representation) binary_list = [int (bit) for bit in binary_list] num_rows = len (binary_list) // 8 if len (binary_list) % 8 != 0 : binary_list += [0 ] * (8 - len (binary_list) % 8 ) num_rows += 1 binary_matrix = Matrix(GF(2 ), num_rows, 8 , binary_list)[:, 2 :] last_304_rows = binary_matrix[-304 :, :] vector1 = last_304_rows.list () concatenated_matrix = []for i in range (num_rows - 304 ): concatenated_matrix.append(binary_matrix[i:i+304 , :].list ()) concatenated_matrix = Matrix(concatenated_matrix) aa = (vector(GF(2 ),vector1)) x = concatenated_matrix.solve_left(vector(aa)) x = x[:-1 ]print (x)def bits2string (bs ): s = [str (b) for b in bs] return '' .join(s)print (long_to_bytes(int (bits2string(x),2 )))b'flag{ByT3_L45R_15_Just_A_w3ak3r_LFsr!}'