a = getPrime(256) private_key = random.getrandbits(256) ^ a xenny = Xenny(private_key) client_socket.send(banner.encode()) co = 5 whileTrue: client_socket.send(Menu.encode()) choice = client_socket.recv(1024).decode().strip() if choice == '1' : if co == 0: raise CountError("No more!!!!") client_socket.send("give me something sign: ".encode()) s = client_socket.recv(1024)[:-1] ifb"xenny"in s: client_socket.send("What makes you think you can pose as Xenny?\n".encode()) break sign = xenny.signature(s) client_socket.send(f"{sign}\n".encode()) co -= 1 elif choice == '2': client_socket.send("sign: ".encode())
a = getPrime(256) private_key = random.getrandbits(256) ^ a xenny = Xenny(private_key) client_socket.send(banner.encode()) co = 5 whileTrue: client_socket.send(Menu.encode()) choice = client_socket.recv(1024).decode().strip() if choice == '1' : if co == 0: raise CountError("No more!!!!") client_socket.send("give me something sign: ".encode()) s = client_socket.recv(1024)[:-1] ifb"xenny"in s: client_socket.send("What makes you think you can pose as Xenny?\n".encode()) break sign = xenny.signature(s) client_socket.send(f"{sign}\n".encode()) co -= 1 elif choice == '2': client_socket.send("sign: ".encode())
目的是拿到flag。
除了程序代码以外,在随便乱试的时候还能看出一些程序的功能,比如:
输入3后,似乎可以进行MT19937产生的32bit的伪随机数预测,虽然预测正确好像也没什么用
输入2后,如果输入的确实是十六进制串,也即没有让程序报错,那么程序会返回的是”Only xenny can get flag”
from fastecdsa.curve import secp256k1 from hashlib import sha256
length = 5 h = [int(sha256(i).hexdigest(),16) for i in [b"0",b"1",b"2",b"3",b"4"]] R = [31096735160651542514594148009444423392167145102850530827072444936893298085958, 1667700963153923083527357426619475090281803852648628765437316264051704897418, 16771314321505205143350123534500543552096118001424456331703672486750061761147, 111915263401277449638289396518382362342281446247506473910053678600849562173658, 4006411196893119279631442159210712836445881069979083382732132911330173248009] S = [81657507529738672978079292900378814222549660333861377490434484387584127131100, 18471119190696882624802078010087114511389523902107255054021489181061816819234, 60234894853906247501079104442478939240255694078000750083432688313202661346696, 86544211048945675316874110304800510445472680246693352484986608188131953425157, 78874088475992399611084479122315153430100025584295640315650967987201653683057] #d = 64875426355440626643099882733692643061105383093107059159523050961269086610413 sigs = [] for i inrange(length): sigs.append((h[i],R[i],S[i]))
T = 2^100 L = Matrix(ZZ,256+length+2,256+length+1) for i inrange(256+1): L[i,i] = 1 for i inrange(length): for j inrange(256): temp = bin(h[i])[2:].zfill(256)[::-1] L[j,i+256+1] = -S[i]*2*2^j*int(temp[j])*T L[256,i+256+1] = h[i]*(S[i]-1)*T L[257,i+256+1] = (S[i]-R[i])*T L[258+i,i+256+1] = secp256k1.q*T
res = L.LLL() for i in res: if(all(j == 0or j == 1for j in i) and (1in i)): tt = i[:-6][::-1] temp = "".join(list(map(str,tt))) print(int(temp,2))
from Pwn4Sage.pwn import * from tqdm import * from Crypto.Util.number import * from fastecdsa.curve import secp256k1 as CURVE from hashlib import sha256
#context.log_level = 'debug'
sh = remote("1.14.108.193",32252)
R = [] S = [] z = [int(sha256(i).hexdigest(),16) for i in [b"0",b"1",b"2",b"3",b"4"]] if(1): for i inrange(5): sh.sendline(b"1")
sh.recvuntil(b"give me something sign:") msg = str(i).encode() sh.sendline(msg) rs = sh.recvline().strip().decode() r,s = int(rs[:len(rs)//2],16),int(rs[len(rs)//2:],16) R.append(r) S.append(s) print(R) print(S) sigs = [] for i inrange(5): sigs.append((z[i],R[i],S[i]))
#part2 get d defrecover_d(sigs): P = PolynomialRing(Zmod(CURVE.q), "d", 256) ds = P.gens() dd = sum([2 ** i * di for i, di inenumerate(ds)]) polys = [] for z, r, s in sigs: d_and_z = sum([2 ** i * ((z & (1 << i)) >> i) * di for i, di inenumerate(ds)]) # fact: (a xor b) = a + b - 2 * (a and b) k = dd + z - 2 * d_and_z polys.append((s * k) - (z + r * dd)) M, v = Sequence(polys).coefficient_matrix() print(v.T) M = M.T.dense_matrix() a, b = M.dimensions() B = block_matrix( ZZ, [[matrix.identity(b) * CURVE.q, matrix.zero(b, a)], [M, matrix.identity(a)]] ) B[:, :b] *= 2 ^ 64 print("LLL", B.dimensions()) for row in B.LLL(): if row[:b] == 0and row[-1] == 1andall(0 <= x <= 1for x in row[b:-1]): dbits = row[b:-1] d = int("".join(map(str, dbits[::-1])), 2) return d
d = recover_d(sigs) print(d) #part3 get flag h = int(sha256(b"xenny").hexdigest(),16) k = h^^d r = (k*CURVE.G).x s = inverse(k,CURVE.q) * (h + r*d) % CURVE.q signature = hex(r)[2:].zfill(64)+hex(s)[2:].zfill(64)
from fastecdsa.curve import secp256k1 from hashlib import sha256
length = 5 h = [int(sha256(i).hexdigest(),16) for i in [b"0",b"1",b"2",b"3",b"4",b"5"]] R = [55438565207338188985477948297707383628133456043967096650050086162051382496685, 34370854298730072144481322984891357107485048475128920596006200148827039913808, 42184687889006972324884463428221215625989889935954570330229503951065096406265, 11807003657326746264282983667121063011176360419977702570602350915945501544482, 47805548692870774375076399860895996704082492117937603108794432517276992511135, 105429926378257594893189380170635466553420743820842445505795357046243674098923] S = [91437568456730022379614175047567583259582804228196202671899274499409848470343, 68469458461887354512592080860220721446661199513502071317692562031156156711233, 8599215819039971355550707782160988410370689757696771960517487446632997405198, 2897666418217511899561751558853778473112016259151461180116106453564309557576, 7457580251740237348721776132961481664010839036161094090135121076623209719605, 79701192002212969894680356281723834279212313476946240809672720170860816327146] #d = 76843059829300774502301911378398708933327237745683561605401157268735347763583 sigs = [] for i inrange(length): sigs.append((h[i],R[i],S[i]))
T = 2^100 L = Matrix(ZZ,256+length+1,256+length+1) for i inrange(256+1): L[i,i] = 1 for i inrange(length): for j inrange(256): temp = bin(h[i])[2:].zfill(256)[::-1] L[j,i+256+1] = ((S[i]-R[i])*2^j-S[i]*2*2^j*int(temp[j]))*T L[256,i+256+1] = h[i]*(S[i]-1)*T L[257+i,i+256+1] = secp256k1.q*T
res = L.LLL() for i in res: if(all(j == 0or j == 1for j in i) and (1in i)): tt = i[:-length-1][::-1] temp = "".join(list(map(str,tt))) print(int(temp,2)) if(all(j == 0or j == -1for j in i) and (-1in i)): tt = i[:-length-1][::-1] for i inrange(len(tt)): tt[i] = -tt[i] temp = "".join(list(map(str,tt))) print(int(temp,2))
from Crypto.Util.number import * from hashlib import * import os from Crypto.Cipher import AES from Crypto.Util import Counter from random import * import socket import threading import base64
FLAG = bytes(os.getenv("DASFLAG").encode())
classProof(): defS(self,n): factors = set() while n % 2 == 0: factors.add(2) n //= 2 for i inrange(3, int(n**0.5) + 1, 2): while n % i == 0: factors.add(i) n //= i if n > 2: factors.add(n) return factors
defY(self,n): if n == 1: return1
result = n for p in self.S(n): result *= (1 - 1 / p) returnint(result)
defproof(self,n): res = 0 for m inrange(1, n+1): for l inrange(1, m+1): for k inrange(1, l+1): for j inrange(1, k+1): for i inrange(1, j+1): for h inrange(1, i+1): for g inrange(1, h+1): for f inrange(1, g+1): for e inrange(1, f+1): for d inrange(1, e+1): for c inrange(1, d+1): for b inrange(1, c+1): for a inrange(1, b+1): res += b//a*(self.Y(a)) return res
classHarukii_Oracle:
def__init__(self,key): self.k = key
defpad(self, plaintext): block_size = randint(1,len(plaintext)-1) iflen(plaintext) < block_size : return plaintext else: padding_length = len(plaintext) // 16 padding_byets = bytes([padding_length]) plaintext = plaintext.replace(padding_byets,b"\x00") p = plaintext[:16] for i inrange(1 , padding_length+1): p += padding_byets + plaintext[16*i:16*(i+1)] return p
classProof(): defS(self,n): factors = set() while n % 2 == 0: factors.add(2) n //= 2 for i inrange(3, int(n**0.5) + 1, 2): while n % i == 0: factors.add(i) n //= i if n > 2: factors.add(n) return factors
defY(self,n): if n == 1: return1
result = n for p in self.S(n): result *= (1 - 1 / p) returnint(result)
defproof(self,n): res = 0 for m inrange(1, n+1): for l inrange(1, m+1): for k inrange(1, l+1): for j inrange(1, k+1): for i inrange(1, j+1): for h inrange(1, i+1): for g inrange(1, h+1): for f inrange(1, g+1): for e inrange(1, f+1): for d inrange(1, e+1): for c inrange(1, d+1): for b inrange(1, c+1): for a inrange(1, b+1): res += b//a*(self.Y(a)) return res