# babycrypto1
## Source code
```python#!/usr/bin/env pythonfrom base64 import b64decodefrom base64 import b64encodeimport socketimport multiprocessing
from Crypto.Cipher import AESfrom Crypto.Random import get_random_bytesfrom Crypto.Util.Padding import pad, unpadimport hashlibimport sys
class AESCipher:    def __init__(self, key):        self.key = key
    def encrypt(self, data):        iv = get_random_bytes(AES.block_size)        self.cipher = AES.new(self.key, AES.MODE_CBC, iv)        return b64encode(iv + self.cipher.encrypt(pad(data,             AES.block_size)))
    def encrypt_iv(self, data, iv):        self.cipher = AES.new(self.key, AES.MODE_CBC, iv)        return b64encode(iv + self.cipher.encrypt(pad(data,             AES.block_size)))
    def decrypt(self, data):        raw = b64decode(data)        self.cipher = AES.new(self.key, AES.MODE_CBC, raw[:AES.block_size])        return unpad(self.cipher.decrypt(raw[AES.block_size:]), AES.block_size)
flag = open("flag", "rb").read().strip()
COMMAND = [b'test',b'show']
def run_server(client, aes_key, token):    client.send(b'test Command: ' + AESCipher(aes_key).encrypt(token+COMMAND[0]) + b'\n')    client.send(b'**Cipher oracle**\n')    client.send(b'IV...: ')    iv = b64decode(client.recv(1024).decode().strip())    client.send(b'Message...: ')    msg = b64decode(client.recv(1024).decode().strip())    client.send(b'Ciphertext:' + AESCipher(aes_key).encrypt_iv(msg,iv) + b'\n\n')    while(True):        client.send(b'Enter your command: ')        tt = client.recv(1024).strip()        tt2 = AESCipher(aes_key).decrypt(tt)        client.send(tt2 + b'\n')        if tt2 == token+COMMAND[1]:            client.send(b'The flag is: ' + flag)            client.close()            break
if __name__ == '__main__':    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)    server.bind(('0.0.0.0', 16001))    server.listen(1)
    while True:        client, address = server.accept()
        aes_key = get_random_bytes(AES.block_size)        token = b64encode(get_random_bytes(AES.block_size*10))[:AES.block_size*10]
        process = multiprocessing.Process(target=run_server, args=(client, aes_key, token))        process.daemon = True        process.start()```
## Solution
Reading the source code, we can see that the idea is to replace the last block of encryption with `show` instead of `test`.In addition, the server allows us to encrypt a string with a given IV.
![AESDecryption](https://susanou.github.io/Writeups/assets/img/CTFImg/CBC_decryption.svg.png)
When you look at the following diagram of AES_CBC decryption, you see that the last block is basically decrypted and then XORed with the previous block. So if we encrypt the string `show` with the previous block as the IV we would get the correct final block.Then we just need to replace that in the string that we were given at the start from the server and we can go ahead and send that to the serevr.
### Solution Code
```python![](from base64 import b64decodefrom base64 import b64encodefrom Crypto.Cipher import AESfrom Crypto.Random import get_random_bytesfrom Crypto.Util.Padding import pad, unpad
from pwn import *
import hashlibimport sys
r = remote("35.200.115.41", 16001, level='debug')
line = str(r.recvline().replace(b'\n', b'')).split(": ")http://)r.recv()
testcommand = line[1]
iv = b64encode(b64decode(testcommand)[:16])
token = b64encode(b64decode(testcommand)[16:AES.block_size*10+16])tokenlast = b64decode(token)[-16:]r.sendline(b64encode(tokenlast))
r.sendline(b64encode(b'show'))line = str(r.recvline().replace(b'\n', b'')).split(":")
encryptedshow = line[2]
payload = b64encode(b64decode(iv)+b64decode(token)+b64decode(encryptedshow)[16:])r.recvuntil(b'Enter your command: ')r.sendline(testcommand)r.recvuntil(b'Enter your command: ')r.sendline(payload)r.recv()r.recv()```
## Rabbit Holes
- One thing that I kept doing was XORing `show` with the IV and the lastblock that have it work and send the IV at the start of the string sent by the server as the encryption IV but this didn't work because `show` was XORed with the lastblock before encryption- I also tried padding `show` to make it have the right length but that didn't work because the data was additionally padded