Comment est votre modulation ?
Catégorie : Sécurité matérielle
Difficulté :
- Comment est votre modulation ? [1/2] - Simple
- Comment est votre modulation ? [2/2] - Moyen
Comment est votre modulation ? [1/2]
Énoncé
Lors de votre séance bras à la salle, alors que vous faisiez, tant bien que mal, votre dernière répétition un haltère à la main, un inconnu vient vous voir et vous glisse à l'oreille : "L'amplitude, c'est important !". Il vous tend ensuite une clé USB et part en courant. Sur cette clé, vous trouvez un fichier ainsi que le message suivant :
Porteuse : 7kHz Fréquence d'échantillonage : 350kHz Valence : 256 Débit : 1000 symboles/sec Format : float32
If you don't know what it is, well, just ASK.
Analyse
D'après l'énoncé, on sait qu'une modulation ASK (Amplitude Shift Keying) a été utilisée. L'énoncé donne également la valence (256) qui correspond ici au nombre d'amplitude possible pour notre signal.
ASQUOI ?
La modulation ASK-256 (Amplitude Shift Keying 256) est une technique de modulation numérique qui utilise 256 niveaux d'amplitude distincts pour représenter les données. Dans cette modulation, l'amplitude du signal porteur est variée selon les données à transmettre, chaque niveau d'amplitude représentant un ensemble de 8 bits (puisque 2^8 = 256). Cela permet de transmettre une grande quantité d'informations par cycle de signal. ASK-256 est particulièrement utilisé dans les systèmes de communication où la largeur de bande est limitée mais où il est crucial de transmettre des données à des débits élevés. Cependant, cette modulation nécessite une excellente qualité de signal et une faible distorsion pour être efficace, car les nombreux niveaux d'amplitude peuvent être sensibles au bruit et aux interférences.
Modulation AM
Commencons par le pendant analogique de l'ASK, l'AM ! La modulation AM n'est finalement que la multiplication entre un signal (analogique ici, par exemple une musique dans le contexte d'une radio) sur une porteuse (généralement une sinusoide). Prenons l'exemple de j'écoute la radio "107.7", en réalité le nombre d'une station radio reflete la fréquence du signal porteur de celle-ci. Dans cette exemple une porteuse de 107.7 MHz est utilisée (bon.. c'est en FM.. mais l'exemple tiens la route). Dans notre énoncé on sait que la porteuse est de 7Khz.
Modulation ASK
En ASK, on ne cherche pas à multiplier un signal analogique à une porteuse mais un signal numérique (discret). Comment faire ?
La première chose est finalement de construire un signal analogique avec nos données numériques pour par la suite reprendre une modulation type AM. La construction de notre signal n'est finalement que la génération d'une amplitude pour une donnée (exemple, la valeur 1 donnera une amplitude de 1 et la valeur 0 donnera une amplitude de 0). Dans le cas d'une valence de 256, on va mapper pour chaque combinaison de 8bits possible. Pourquoi 8 ? Car 2^8=256.
Une fois le signal construit, on le multiplie à notre porteuse... Et voilà !
Démodulation AM/ASK
Comment récupérer notre signal d'origine ? Dans le cas d'une station radio c'est facile, le contenu étant un son, la bande de fréquence utilise ne dépasse jamais les 20khz, donc un filtre passe bas (filtre qui ne laisse passer que les fréquences en dessous d'un certain seuil) permet de récupérer notre signal original. Mais en ASK, chaque passage d'une amplitude à une autre ressemble à un signal carré, et comment faire un carré avec des signaux ? Avec une infinité d'harmonique. C'est a dire qu'une fois le filtre passe bas passé on perd un ensemble d'harmonique important à la construction du signal.
La solution ? Supprimer la porteuse !
Solution
Comment supprimer la porteuse ? Et bien on peut recourir à plusieurs techniques :
- Dans un monde analogique, on peut multiplier notre porteuse pour la décaler vers des fréquences plus hautes et opérer un filtre bas dans le but de récupérer un maximum d'harmoniques. En tout cas, à moindre coup d'implémentation en électronique c'est ce que je ferais
- Dans un monde ou les SDR dominent, on peut simplement reconstruire l'enveloppe
- Dans un monde de fénéant, on peut facilement reconstruire l'enveloppe en détectant les maximum de notre signal et en persistant l'amplitude (détection d'enveloppe à la mano)
Je vais reprendre le WU de retyuil qui a une solution bien plus concise que la mienne
import struct
import matplotlib.pyplot as plt
# Récupération du signal
with open('flag.raw','rb') as f:
data = f.read()
f = []
for i in range(len(data)//4):
f.append(struct.unpack('f', data[i*4:(i+1)*4])[0])
time = [i for i in range(len(f))]
# Chaque échantillon étant persistés sur 350 points
# En récupérant le maxima sur 350 points on effectue une détection d'enveloppe simple à la mano, merci 'retyuil'
maxi = []
for k in range(len(f)//350):
res = max(f[k*350:(k+1)*350])*255
res = int(res)
res = bytes([res])
maxi.append(res)
# Reconstruction du flag original
im = b''
for i in maxi:
im += i
with open('flag.png','wb') as f:
f.write(im)
import struct
import matplotlib.pyplot as plt
# Récupération du signal
with open('flag.raw','rb') as f:
data = f.read()
f = []
for i in range(len(data)//4):
f.append(struct.unpack('f', data[i*4:(i+1)*4])[0])
time = [i for i in range(len(f))]
# Chaque échantillon étant persistés sur 350 points
# En récupérant le maxima sur 350 points on effectue une détection d'enveloppe simple à la mano, merci 'retyuil'
maxi = []
for k in range(len(f)//350):
res = max(f[k*350:(k+1)*350])*255
res = int(res)
res = bytes([res])
maxi.append(res)
# Reconstruction du flag original
im = b''
for i in maxi:
im += i
with open('flag.png','wb') as f:
f.write(im)
Comment est votre modulation ? [2/2]
Énoncé
Aujourd'hui c'est séance jambes ! Voilà une semaine que vous appliquez le conseil précédent : "L'amplitude, c'est important !". Alors que vous mettez en œuvre ce conseil, le même homme ressurgit de nulle part et vous dit cette fois : "Il n'y a pas que l'amplitude qui est importante ! Ce n'est qu'une partie des critères qui font une bonne séance". Il vous jette ensuite une clé USB au visage et part en courant. Voici les données qui se trouvent sur cette dernière :
Porteuse : 7kHz Fréquence d'échantillonage : 350kHz Valence : 256
Analyse
Alors, qu'est-ce qu'on à la ?
- OFDM
- QAM
OFDM
L'OFDM (Orthogonal Frequency Division Multiplexing) est une technique de modulation multiporteuse largement utilisée dans les systèmes de communication modernes, comme le Wi-Fi, la 4G/5G et les réseaux de diffusion numérique. Elle divise le spectre de fréquence disponible en de nombreuses sous-porteuses orthogonales, chacune modulée par une séquence de symboles de données. L'orthogonalité des sous-porteuses permet d'éviter les interférences entre elles, améliorant ainsi l'efficacité spectrale. L'OFDM est particulièrement avantageux dans les environnements à évanouissement sélectif en fréquence, car il permet de répartir les données sur plusieurs sous-porteuses, rendant le système plus résilient aux interférences et aux atténuations de signal. De plus, l'utilisation de la transformée de Fourier rapide (FFT) simplifie la modulation et la démodulation, rendant l'OFDM efficace en termes de calculs.
QAM
Le QAM (Quadrature Amplitude Modulation) est une méthode de modulation qui combine à la fois l'amplitude et la phase des signaux porteurs pour représenter les données. En QAM, deux signaux porteurs sinusoïdaux, déphasés de 90 degrés (quadrature), sont modulés en amplitude avec les données à transmettre, puis additionnés. Chaque combinaison unique d'amplitude et de phase correspond à un symbole distinct dans un diagramme constellation, permettant ainsi de transmettre plusieurs bits par symbole. Par exemple, le 16-QAM utilise 16 combinaisons différentes pour transmettre 4 bits par symbole, tandis que le 256-QAM utilise 256 combinaisons pour transmettre 8 bits par symbole. Le QAM est largement utilisé dans les systèmes de communication numériques, comme les modems, les télévisions par câble et les réseaux sans fil, en raison de sa capacité à offrir des taux de transmission de données élevés tout en utilisant efficacement la bande passante disponible.
Solution
Je passe la thoérie vu que généralement lorsqu'on croise de l'OFDM / QAM c'est qu'on a déjà un très bon socle de connaissance sur le sujet.
import numpy as np
# Récupération du signal
flag_data = np.fromfile('fichiers/flag.iq', dtype = "complex64")
# Découpe en paquets
taille_paquet = int(F_E*T)
received_block = [ received_data[i:i+taille_paquet] for i in range(0, len(received_data), taille_paquet) ]
print(f"La taille d'un paquet est de {taille_paquet} données, il y a {len(received_block)} paquets")
# Démodulation OFDM
# Finalement un simple ifft suffit
fft_symbols = np.fft.fft(received_block, axis=1)
data_carriers = fft_symbols[:, :NB_SOUS_PORTEUSES] / 350
# Démodulation QAM
def inverse_QAM16(complex_symbol):
real_part = int(np.round((complex_symbol.real + 3) / 2))
imag_part = int(np.round((3 - complex_symbol.imag) / 2))
return (real_part << 2) | imag_part
rdata = []
for data in data_carriers:
for i in range(0, len(data), 2):
rdata.append(inverse_QAM16(data[i]) << 4 | inverse_QAM16(data[i+1]))
rdata = bytes(rdata)
# Reconstruction du flag
with open("flag.png", "wb") as f:
f.write(rdata)
import numpy as np
# Récupération du signal
flag_data = np.fromfile('fichiers/flag.iq', dtype = "complex64")
# Découpe en paquets
taille_paquet = int(F_E*T)
received_block = [ received_data[i:i+taille_paquet] for i in range(0, len(received_data), taille_paquet) ]
print(f"La taille d'un paquet est de {taille_paquet} données, il y a {len(received_block)} paquets")
# Démodulation OFDM
# Finalement un simple ifft suffit
fft_symbols = np.fft.fft(received_block, axis=1)
data_carriers = fft_symbols[:, :NB_SOUS_PORTEUSES] / 350
# Démodulation QAM
def inverse_QAM16(complex_symbol):
real_part = int(np.round((complex_symbol.real + 3) / 2))
imag_part = int(np.round((3 - complex_symbol.imag) / 2))
return (real_part << 2) | imag_part
rdata = []
for data in data_carriers:
for i in range(0, len(data), 2):
rdata.append(inverse_QAM16(data[i]) << 4 | inverse_QAM16(data[i+1]))
rdata = bytes(rdata)
# Reconstruction du flag
with open("flag.png", "wb") as f:
f.write(rdata)