Tags: misc crypto unintended 

Rating: 5.0

100 points, 250 solves
My super secure service is available now!

Heck, even with the source, I bet you won't figure it out.

```
nc misc.2020.chall.actf.co 20301
```

Author: JoshDaBosh

Source code :
```
import random, time
import string
import base64
import os

def otp(a, b):
r = ""
for i, j in zip(a, b):
r += chr(ord(i) ^ ord(j))
return r

def genSample():
p = ''.join([string.ascii_letters[random.randint(0, len(string.ascii_letters)-1)] for _ in range(random.randint(1, 30))])
k = ''.join([string.ascii_letters[random.randint(0, len(string.ascii_letters)-1)] for _ in range(len(p))])

x = otp(p, k)

return x, p, k

random.seed(int(time.time()))

print("Welcome to my one time pad service!\nIt's so unbreakable that *if* you do manage to decrypt my text, I'll give you a flag!")
print("You will be given the ciphertext and key for samples, and the ciphertext for when you try to decrypt. All will be given in base 64, but when you enter your answer, give it in ASCII.")
print("Enter:")
print("\t1) Request sample")
print("\t2) Try your luck at decrypting something!")

while True:
choice = int(input("> "))
if choice == 1:
x, p, k = genSample()
print(base64.b64encode(x.encode()).decode(), "with key", base64.b64encode(k.encode()).decode())

elif choice == 2:
x, p, k = genSample()
print(base64.b64encode(x.encode()).decode())
a = input("Your answer: ").strip()
if a == p:
print(os.environ.get("FLAG"))
break

else:
print("Wrong! The correct answer was", p, "with key", k)
```

First of all we notice that the encrypted string is generated based on time.
And the decoded string is giving to us when we submit a wrong answer.

All we have to do is create 2 simultanious connection wich will create the same encrypted string
we submit the wrong answer and retrieve the correct one and then submit it to the 2nd connection.

This is not the intended way but still, i thought you may want to know about this.

Here is the used script :

```python
#!/usr/bin/python3

from pwn import *

con1 = remote("misc.2020.chall.actf.co", 20301)
con2 = remote("misc.2020.chall.actf.co", 20301)

for i in range(6):
con1.recvline()
con2.recvline()

con1.recv(1024)
con2.recv(1024)

con1.sendline("2")
con2.sendline("2")

#for i in range(2):
con1.recvline()
con2.recvline()

con1.sendline("garbage")
con1.recv(1024)
con2.sendline(con1.recvline().decode().split(" ")[5])

con1.close()
log.warning(f"Flag: {con2.recvline().decode().split(' ')[2]}")

```

ZaxiomsMarch 19, 2020, 6:57 p.m.

Woah, that's actually really, really smart!