This commit is contained in:
2022-08-09 16:00:04 +01:00
commit 8e2093187a
4 changed files with 720 additions and 0 deletions

176
writeups/mommymorse.md Normal file
View File

@@ -0,0 +1,176 @@
---
date: 2022-04-30
toc: true
title: Mommy morse
tags: ["FCSC2022", "hardware"]
---
The little warm up with daddy morse is now over, let's see what mommy has to offer !
## What is this about ?
Daddy morse was just about transmitting on or off signals (well, kindof).
Mommy morse wants us to fiddle with frequencies and all: I'm pretty sure that this whole thing is about Frequency modulation/Frequency shift keying.
We have to encode data the following way:
- sample rate: 24kHz
- `.` : 5kHz carrier wave for 1ms
- `-`: 5kHz carrier wave for 5ms
- Space between two letters: 1kHz carrier wave for 5ms
- Space between two words: 1kHz carrier wave for 20ms
To flag this challenge, I was at first trying to do everything in python with numpy, just as I did with Daddy morse.
In the end, I just kept the message -> AM part and did the rest in Gnu Radio.
## Message -> AM
Here is the script that I used to generate my AM signal:
```python
import numpy as np
SAMP_RATE = 24e3
TIMING_DOT = 1/1000
TIMING_DASH = 5/1000
TIMING_SEP_LETTER = 5/1000
TIMING_SPACE = 20/1000
dot_count = int(TIMING_DOT * SAMP_RATE)
dash_count = int(TIMING_DASH * SAMP_RATE)
letters_count = int(TIMING_SEP_LETTER * SAMP_RATE)
word_count = int(TIMING_SPACE * SAMP_RATE)
alphabet = { 'A':'.-', 'B':'-...',
'C':'-.-.', 'D':'-..', 'E':'.',
'F':'..-.', 'G':'--.', 'H':'....',
'I':'..', 'J':'.---', 'K':'-.-',
'L':'.-..', 'M':'--', 'N':'-.',
'O':'---', 'P':'.--.', 'Q':'--.-',
'R':'.-.', 'S':'...', 'T':'-',
'U':'..-', 'V':'...-', 'W':'.--',
'X':'-..-', 'Y':'-.--', 'Z':'--..',
'1':'.----', '2':'..---', '3':'...--',
'4':'....-', '5':'.....', '6':'-....',
'7':'--...', '8':'---..', '9':'----.',
'0':'-----', ', ':'--..--', '.':'.-.-.-',
'?':'..--..', '/':'-..-.', '-':'-....-',
'(':'-.--.', ')':'-.--.-'}
def build(phrase):
res = []
for w in phrase.split(" "):
tmp = ""
for l in w:
if l not in alphabet:
pass
else:
tmp += "{} ".format(alphabet[l])
res.append(tmp[:-1])
return res
def generate(morse):
res = []
for w in morse:
for c in w:
if c == ".":
data = [(1+1j) for _ in range(dot_count)] + [0j for _ in range(dot_count)]
elif c == "-":
data = [(1+1j) for _ in range(dash_count)] + [0j for _ in range(dot_count)]
else:
data = [0j for _ in range(letters_count)]
res = res[:-dot_count]
res.extend(data)
if w[-1] == '.' or w[-1] == '-':
res = res[:-dot_count]
res.extend([0j] * word_count)
res = res[:-word_count]
return np.array(res,dtype=np.complex64)
sentence = "CAN I GET THE FLAG"
morse = build(sentence)
data = generate(morse)
filename = sentence.replace(" ", "-").lower()
print(f"Writing data to {filename}.iq")
with open(f"{filename}.iq", "wb") as file:
file.write(data)
```
Quick launch:
```sh
1 python hardware/mommymorse/script.py
Writing data to can-i-get-the-flag.iq
0
```
And let's see if URH appreciates what I've done:
![img](https://notes.alxczl.fr/uploads/3d47d9b47a6ee23685015020e.png)
It does !
## AM -> FM
Now that is the fun part of the challenge! Here's what I've done:
![img](https://notes.alxczl.fr/uploads/3d47d9b47a6ee23685015020f.png)
You can open and try this circuit by yourself with `script.grc`.
## Kesseussai ????
Okay sorry, please bear with me.
First and foremost, set the samp_rate variable to 24KHz as specified by the challenge, **this is important**.
Then, load the AM signal with a *File Source* block (do not forget to turn off repeat on this block or your FM file won't work with this challenge).
Create a constant source block that always outputs `(1 + 1j)` and link both that block and the file source to a subtract block: this will give us the opposite of our AM signal.
Create two signal sources, one at 1KHz (for the spaces) and one at 5KHz (for the non-spaces chars), they will be used to convert that AM signal to FM.
Now create two multiply blocks:
- Link the subtract block and the 1KHz signal source with the first multiply
- Link the File source and the 5KHz signal with the second multiply
This will transform this (AM):
![img](https://notes.alxczl.fr/uploads/3d47d9b47a6ee236850150210.png)
Into this (FM):
![img](https://notes.alxczl.fr/uploads/3d47d9b47a6ee236850150211.png)
We still need to add these two multiply blocks, so create add Add block and link them with it.
And that's pretty much it, link your add block to a file sink (and some graphs if you like to visualize your hard work) and voila:
![img](https://notes.alxczl.fr/uploads/3d47d9b47a6ee236850150212.png)
# Lemme get the flag
Just a little edit to the `client.py` a bit:
```python
from pwn import *
import numpy as np
import base64
HOST = args.HOST or "challenges.france-cybersecurity-challenge.fr"
PORT = args.PORT or 2252
c = remote(HOST, PORT)
hello_signal = np.fromfile("res.iq", dtype = np.complex64)
encoded_signal = base64.b64encode(hello_signal.tobytes())
c.recvuntil(b"> ")
c.sendline(encoded_signal)
print(c.recvline())
```
Now just go ahead and execute it:
```sh
0 hardware/mommy morse python client.py
[+] Opening connection to challenges.france-cybersecurity-challenge.fr on port 2252: Done
b'Well done: FCSC{490b88345a22d35554b3e319b1200b985cc7683e975969d07841cd56dd488649}\n'
[*] Closed connection to challenges.france-cybersecurity-challenge.fr port 2252
```