adding validated services? patching forcad_local.py
This commit is contained in:
82
ctfcup2025-school-final/sploits/sonobank/crypto_sploit.py
Normal file
82
ctfcup2025-school-final/sploits/sonobank/crypto_sploit.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from sage.all import *
|
||||
from socket import socket, AF_INET, SOCK_DGRAM
|
||||
import uuid
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import unpad
|
||||
import hashlib
|
||||
|
||||
IP = "127.0.0.1"
|
||||
flag_id = "b0e29b3a-f560-449c-ad59-1b760c4aab47"
|
||||
|
||||
PR = PolynomialRing(GF(2), "x")
|
||||
|
||||
def bits(n):
|
||||
return [int(c) for c in bin(n)[2:]][::-1]
|
||||
|
||||
def unbits(bs):
|
||||
return sum(int(x) << i for i, x in enumerate(list(bs)))
|
||||
|
||||
get_crypto_params_payload = bytes((
|
||||
0xF0,
|
||||
0x7D,
|
||||
0x53,
|
||||
0x58,
|
||||
0x05,
|
||||
0xF7
|
||||
))
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
sock.bind(("0.0.0.0", 0))
|
||||
sock.connect((IP, 5004))
|
||||
|
||||
sock.sendall(get_crypto_params_payload)
|
||||
msg = sock.recv(1024)
|
||||
|
||||
modulus = PR(bits(int.from_bytes(msg[5:5 + 64], "big")))
|
||||
base = PR(bits(int.from_bytes(msg[5 + 64:5 + 64 + 64], "big")))
|
||||
|
||||
|
||||
get_crypto_params_payload = bytes((
|
||||
0xF0,
|
||||
0x7D,
|
||||
0x53,
|
||||
0x58,
|
||||
0x03,
|
||||
*uuid.UUID(flag_id).bytes,
|
||||
0xF7
|
||||
))
|
||||
|
||||
sock.sendall(get_crypto_params_payload)
|
||||
msg = sock.recv(1024)
|
||||
h = PR(bits(int.from_bytes(msg[5:5 + 64], "big")))
|
||||
c1 = PR(bits(int.from_bytes(msg[5 + 64:5 + 64*2], "big")))
|
||||
iv = msg[5 + 64*2:5 + 64*2 + 16]
|
||||
ct = msg[5 + 64*2 + 16:-1]
|
||||
|
||||
fact = factor(modulus)
|
||||
assert len(fact) == 1
|
||||
assert fact[0][1] == 5
|
||||
D = fact[0][0].degree()
|
||||
|
||||
# part modulo p
|
||||
R = GF(2 ** D, 'a', modulus=fact[0][0])
|
||||
print(R)
|
||||
r = R(c1).log(base)
|
||||
|
||||
# remaining part
|
||||
R = PR.quotient(modulus)
|
||||
newbase = R(base) ** (2 ** D - 1)
|
||||
newres = R(c1) ** (2 ** D - 1)
|
||||
for x in range(1, 8):
|
||||
if newbase ** x == newres:
|
||||
break
|
||||
else:
|
||||
print("failed to find part")
|
||||
r = crt([r, x], [2 ** D - 1, 8])
|
||||
assert R(base) ** r == R(c1)
|
||||
|
||||
shared_key = int(unbits(list(R(h) ** r))).to_bytes(64, "big")
|
||||
key = hashlib.sha256(shared_key).digest()[:16]
|
||||
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||
pt = unpad(cipher.decrypt(ct), 16)
|
||||
print(pt)
|
||||
Reference in New Issue
Block a user