init
This commit is contained in:
176
writeups/mommymorse.md
Normal file
176
writeups/mommymorse.md
Normal 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:
|
||||

|
||||
|
||||
It does !
|
||||
|
||||
## AM -> FM
|
||||
|
||||
Now that is the fun part of the challenge! Here's what I've done:
|
||||

|
||||
|
||||
|
||||
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):
|
||||

|
||||
|
||||
Into this (FM):
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user