**Tags:** re go

Rating:

# nobus-101

After reverse-engineering the binary, we learned that it uses the Dual_EC_DRBG backdoored

keys. The curve generatoin itself is deterministic, but we needed to reverse it. It looks like

this:

```python

MAGIC = 0x132867e88e82431dc40ba24e11bf3ec7ffb18764a3b4df1f5957fd5f37d8be40

def gen_backdoor():

P = P256.G

e = MAGIC

d = mod_inv(e, P256.q)

Q = e * P

return P, Q, d

```

This makes it possible to recover the seed using only two random numbers, using the well-studied

attack technique on Dual_EC_DRBG keys.

We modified the https://github.com/AntonKueltz/dual-ec-poc attack to get a deterministic

seed recovery.

The interesting piece of our code is:

```python

def recover_s(bits0, bits1, Q, d):

for high_bits in range(2**16):

guess = (high_bits << (8 * 30)) | bits0

on_curve, y = find_point_on_p256(guess)

if on_curve:

# use the backdoor to guess the next 30 bytes

point = Point(guess, y, curve=P256)

s = (d * point).x

r = (s * Q).x & (2**(8 * 30) - 1)

if r == bits1:

return s

def main():

P, Q, d = gen_backdoor()

data = requests.get("http://nobus101.insomnihack.ch:13337/prng").text

bits0, bits1, *rest = data.split()

bits0 = int(bits0, 16)

bits1 = int(bits1, 16)

s = recover_s(bits0, bits1, Q, d)

curve = DualEC(s, P, Q)

prediction = hex(curve.genbits())[2:].rjust(60, '0')

text = requests.post("http://nobus101.insomnihack.ch:13337/flag", data=prediction.encode())

print(text.text)

```

This allowed us to recover the flag.

```

INS{7ru57_7h3_5c13nc3}

```

Original writeup (https://github.com/p4-team/ctf/blob/master/2022-01-29-insomnihack/nobus-101/README.md).