challenge1.py
:Memory.O_STACK
holds the address of the beginning of the stack, which is 0xEA0
, as in most implementations.0xEA0
and 0xEB0
.I
is a general purpose 16-bit register for memory addresses.68006900aea0d89fffff
and receive the display!FCSC{e50f91bc6418a7a79b0c3fe74bb5e600}
0000
encrypts 10 input bytes (at I
) with the secret key0001
verifies if our input is the secret key00E1
clears the ALU cache0000
opcode). Only the VF register is returned to unsafe space (to carry a return value).encrypt
and verify
, where some bytes are dynamically replaced with bytes from the key.{:02X}
, which are placeholders for the secret key bytes.encrypt
routine does indeed encrypt our input with the secret key using simple XOR operations, one byte at a time.verify
routine is quite similar to the encrypt
one. The main change is that the XOR results are ORed together: if the final result is 0, we know the comparison was successful.verify
routine returns 1 in VF
(cu.py
, control unit code):alu.py
):functools
is used, with max size 16. The ALU has two possible states: AVAILABLE
or PENDING
. In cu.py
:PENDING
state, the PC
register is rolled back two bytes, in other words the instruction is executed twice, and the next time it'll have switched to the AVAILABLE
state. However, when the operation is cached, the ALU doesn't enter the PENDING
state.encrypt
routine.P[k] = (0, ..., 0xFF, ..., 0)
(10 bytes) with 0xFF
at the k-th position.P xor S
, where S
is the secret key, by putting P
at position I
and calling 0000
. In particular, the operation 0xFF xor S[k]
will be performed and put in cache. We can then bruteforce S[k]
by computing 0xFF xor i
for i
in [0, 255] and counting the number of cycles each of these XOR operations lasted.00E1
instruction at each iteration to avoid any problems. This allows us to recover the secret key in 2560 encryptions worst case, but it will run pretty fast anyways since everything is run server-side (we'll just send our ROM exploit once).aea061016000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6000f055f11e6200aea0f21e60fff055630000e1aea00000650866fff5158633f007af80f05568006900d89f4006127073013300124caf00f21e8030f055aea0f21e6000f0557201320a1242af000001af146800690ad89f