# 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).