2024-京津冀攻防-wp-crypto

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 sha256
def 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 + YrUtRcPtwQENaWFbWzxfiwhqCGDIxuvz
def RrLEPBfHqeEZLegXpJufxMLPmKNPPCdw(key):
NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa = []
haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX = key
for aLQVDGitlxRDIaIUmPsjiuNUrctWLWDS in xrange(16):
haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX = CTYhfQLxlHLujgcTPvrBvPvCARHRzgZG(haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX)
NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa.append(haWaAGvxpxofNMpRfBaOVtaWFSwTpLDX)
return NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa
def DugSDFJhTeJpOOZBYjLhhJypmfwsrfuI(key,data):
NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa = RrLEPBfHqeEZLegXpJufxMLPmKNPPCdw(key)
return cKNBqRWpybOxuHbVodCBTRFtmEZkOPtb(NZaLtVqEwfLuKnkUjgRUNUoMKBJTuGGa, data).encode('hex')
if __name__ == "__main__":
print DugSDFJhTeJpOOZBYjLhhJypmfwsrfuI('explorer','??flag_is_here??')
#the result is "1fde6a7b2ff15d0abad691215ca5d470"

本题最大难点其实就是改代码:

第一要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 sha256
def 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() # 如果 data 不是 bytes 类型,则进行编码
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_first
def genkey(key):
keylist = []
mykey = key
for i in range(16):
mykey = sha256_(mykey)
keylist.append(mykey)
return keylist
def 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'))
#the result is "1fde6a7b2ff15d0abad691215ca5d470"

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 urandom
from Crypto.Util.number import bytes_to_long
from random import getrandbits
from flag import FLAG

class 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 sha256
from 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:]

#print(binary_matrix) #608
last_304_rows = binary_matrix[-304:, :]
vector1 = last_304_rows.list()#304*6
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!}'

2024-京津冀攻防-wp-crypto
https://py-thok.github.io/2024/09/07/2024-京津冀攻防-wp-crypto/
作者
PYthok-Ptk
发布于
2024年9月7日
许可协议