cscg ist super
This commit is contained in:
52
2026/cscg/crypto/intro3/solve.py
Normal file
52
2026/cscg/crypto/intro3/solve.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from z3 import BitVec, Solver, sat
|
||||
|
||||
# Replace this with the actual numbers printed by the program
|
||||
with open("./msg.txt") as f:
|
||||
OUTPUTS = [int(line) for line in f.readlines()[1:]]
|
||||
|
||||
BITS = 56
|
||||
MASK = 0xFF
|
||||
|
||||
# Symbolic variables for the LCG parameters
|
||||
A = BitVec('A', BITS)
|
||||
B = BitVec('B', BITS)
|
||||
SEED = BitVec('SEED', BITS)
|
||||
|
||||
s = Solver()
|
||||
|
||||
# Define the state sequence
|
||||
states = [SEED]
|
||||
for i in range(len(OUTPUTS)):
|
||||
# Next state transition: s_i+1 = (s_i * A + B) & (2**56 - 1)
|
||||
# Z3 BitVec arithmetic handles the modulo 2^n automatically
|
||||
next_state = (states[i] * A) + B
|
||||
states.append(next_state)
|
||||
|
||||
# Known prefix: "CSCG{"
|
||||
known_prefix = "CSCG{"
|
||||
for i, char in enumerate(known_prefix):
|
||||
# output = (state_i+1 & MASK) ^ ord(FLAG[i])
|
||||
# Therefore: (state_i+1 & MASK) == output ^ ord(FLAG[i])
|
||||
s.add((states[i+1] & MASK) == OUTPUTS[i] ^ ord(char))
|
||||
|
||||
# If the flag ends with '}', add that constraint as well
|
||||
s.add((states[len(OUTPUTS)] & MASK) == OUTPUTS[-1] ^ ord('}'))
|
||||
|
||||
if s.check() == sat:
|
||||
model = s.model()
|
||||
print("Found LCG Parameters:")
|
||||
print(f"A: {model[A]}")
|
||||
print(f"B: {model[B]}")
|
||||
print(f"SEED: {model[SEED]}")
|
||||
|
||||
# Recover the flag
|
||||
flag = ""
|
||||
for i in range(len(OUTPUTS)):
|
||||
# Extract the lower 8 bits of the calculated state
|
||||
state_val = model.evaluate(states[i+1]).as_long()
|
||||
flag_char = chr((state_val & MASK) ^ OUTPUTS[i])
|
||||
flag += flag_char
|
||||
|
||||
print(f"Flag: {flag}")
|
||||
else:
|
||||
print("Unsatisfiable: Check if the prefix or output data is correct.")
|
||||
Reference in New Issue
Block a user