2022年春秋杯网络安全联赛春季赛勇者山峰部分wp
Crypto
bob’s enc
bob自己编写了一套加密算法,但是在加密的过程中,似乎混入了一些噪音,你能帮助他恢复出明文吗?
题目
from secret import *
import random
prime = 2141
print len(flag)
flag = map(ord, flag)
flag1 = flag[:21]
flag2 = flag[21:]
row = 64
def add(msg1, msg2):
return [(x + y) % prime for x, y in zip(msg1, msg2)]
def multi(msg1, msg2):
out = []
for l in msg1:
s = 0
for x, y in zip(l, msg2):
s += (x * y) % prime
s %= prime
out.append(s)
return out
def genkey(leng):
l = [[] for i in range(row)]
for x in range(row):
for i in range(leng):
l[x].append(random.randint(0, 511))
return l
key = genkey(len(flag1))
print key
cipher1 = multi(key, flag1)
print cipher1
cipher2 = multi(key, flag2)
noise = [random.randint(0, 6) for i in range(row)]
print add(noise, cipher2)
思路
将flag分为两部分(flag1和flag2),
c
i
p
h
e
r
1
=
m
u
l
t
i
(
k
e
y
,
?
f
l
a
g
1
)
,
c
i
p
h
e
r
2
=
a
d
d
(
n
o
i
s
e
,
m
u
l
t
i
(
k
e
y
,
?
f
l
a
g
2
)
)
cipher_1 = multi(key,\ flag_1), cipher_2= add(noise,multi(key,\ flag_2))
cipher1?=multi(key,?flag1?),cipher2?=add(noise,multi(key,?flag2?)),
c
i
p
h
e
r
1
cipher_1
cipher1?是
k
e
y
key
key和
f
l
a
g
1
flag_1
flag1?相乘,可以看成矩阵相乘,那么反过来可求出
f
l
a
g
1
(
f
l
a
g
1
=
k
e
y
?
1
c
i
p
h
e
r
1
)
flag_1(flag_1=key^{-1}cipher_1)
flag1?(flag1?=key?1cipher1?);而
c
i
p
h
e
r
2
cipher_2
cipher2?是在相乘基础上加上了噪音,在La佬博客上有这类的问题(LWE问题)。
博客下面有两个脚本,试了第一个发现并不行,换第二个可!
脚本
from sage.all import *
from sage.modules.free_module_integer import IntegerLattice
from random import randint
import sys
from itertools import starmap
from operator import mul
with open('out', 'r') as f:
key = eval(f.readline())
c1 = eval(f.readline())
c2 = eval(f.readline())
prime = 2141
K = matrix(Zmod(prime), key[:21])
C1 = vector(Zmod(prime), c1[:21])
m1 = K.inverse() * C1
flag = ''
for i in m1:
flag += chr(i)
print(flag)
def Babai_closest_vector(M, G, target):
small = target
for _ in range(5):
for i in reversed(range(M.nrows())):
c = ((small * G[i]) / (G[i] * G[i])).round()
small -= M[i] * c
return target - small
m = 64
n = 21
q = prime
A_values = key
b_values = c2
A = matrix(ZZ, m + n, m)
for i in range(m):
A[i, i] = q
for x in range(m):
for y in range(n):
A[m + y, x] = A_values[x][y]
lattice = IntegerLattice(A, lll_reduce=True)
gram = lattice.reduced_basis.gram_schmidt()[0]
target = vector(ZZ, b_values)
res = Babai_closest_vector(lattice.reduced_basis, gram, target)
R = IntegerModRing(q)
M = Matrix(R, A_values)
ingredients = M.solve_right(res)
for i in ingredients:
flag += chr(i)
print(flag)
Train
题目内容:Alice发现了一辆小火车,她想要去成功登上这辆火车,你能帮帮她吗?
题目
from Crypto.Util.number import *
from hashlib import sha256
import socketserver
import signal
import string
import random
from secret import flag
banner = br'''
.oooooo..o oooo oooo ooooooooooooo o8o
d8P' `Y8 `888 `888 8' 888 `8 `"'
Y88bo. ooo. .oo. .oo. .oooo. 888 888 888 oooo d8b .oooo. oooo ooo. .oo.
`"Y8888o. `888P"Y88bP"Y88b `P )88b 888 888 888 `888""8P `P )88b `888 `888P"Y88b
`"Y88b 888 888 888 .oP"888 888 888 888 888 .oP"888 888 888 888
oo .d8P 888 888 888 d8( 888 888 888 888 888 d8( 888 888 888 888
8""88888P' o888o o888o o888o `Y888""8o o888o o888o o888o d888b `Y888""8o o888o o888o o888o
'''
n0 = 30798082519452208630254982405300548841337042015746308462162479889627080155514391987610153873334549377764946092629701
g = 64146569863628228208271069055817252751116365290967978172021890038925428672043
def TrainHash(msg):
n = n0
msg = map(ord, msg)
for i in msg:
n = g * (n + i)
n = n & (1 << 383)
return n - 0xf5e33dabb114514
table = string.ascii_letters + string.digits
MENU = br'''
<OPTION>
'''
class Task(socketserver.BaseRequestHandler):
def _recvall(self):
BUFF_SIZE = 2048
data = b''
while True:
part = self.request.recv(BUFF_SIZE)
data += part
if len(part) < BUFF_SIZE:
break
return data.strip()
def send(self, msg, newline=True):
try:
if newline:
msg += b'\n'
self.request.sendall(msg)
except:
pass
def recv(self, prompt=b'SERVER <INPUT>: '):
self.send(prompt, newline=False)
return self._recvall()
def proof_of_work(self):
proof = (''.join([random.choice(table) for _ in range(20)])).encode()
sha = sha256(proof).hexdigest().encode()
self.send(b"[+] sha256(XXXX+" + proof[4:] + b") == " + sha)
XXXX = self.recv(prompt=b'[+] Plz Tell Me XXXX :')
if len(XXXX) != 4 or sha256(XXXX + proof[4:]).hexdigest().encode() != sha:
return False
return sha.decode()
def handle(self):
signal.alarm(30)
FirstBlockHash = self.proof_of_work()
if not FirstBlockHash:
self.request.close()
self.send(banner)
self.send(b"\nPlease give me 2 strings that are same when are hashed =.= ")
string1 = self.recv().decode()
string2 = self.recv().decode()
if TrainHash(string1) == TrainHash(string2):
self.send(b'\nJust do it!~ You can do more!')
if string2.encode()[-50:] == string1.encode()[-50:]:
self.send(flag)
self.send(b"\nConnection has been closed =.= ")
self.request.close()
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = '0.0.0.0', 10012
print("HOST:POST " + HOST + ":" + str(PORT))
server = ForkedServer((HOST, PORT), Task)
server.allow_reuse_address = True
server.serve_forever()
思路
分析个der,随便给两个一样的string就有flag了,送分题嗷
脚本
from pwn import *
import string
import hashlib
table = string.ascii_letters + string.digits
re = remote('101.200.198.40',35946)
re.recvuntil(b'[+] sha256(XXXX+')
x = re.recv(16)
re.recvuntil(b') == ')
y = re.recv(64)
flag = 0
for a in table:
if flag:break
for b in table:
if flag: break
for c in table:
if flag: break
for d in table:
z = (a + b + c + d).encode()
if hashlib.sha256(z + x).hexdigest() == y.decode():
flag = 1
re.recv()
re.sendline(z)
break
re.recvuntil(b'SERVER <INPUT>: ')
re.sendline(b'a')
re.recvuntil(b'SERVER <INPUT>: ')
re.sendline(b'a')
re.interactive()
.sha256(z + x).hexdigest() == y.decode():
flag = 1
re.recv()
re.sendline(z)
break
re.recvuntil(b'SERVER <INPUT>: ')
re.sendline(b'a')
re.recvuntil(b'SERVER <INPUT>: ')
re.sendline(b'a')
re.interactive()
|