S'amuser avec le DNS : Video over DNS
Publié le 04/09/2024, dans informatique, linux, dns, video, hack
Je viens de regarder cette conférence express « Bizarre and Unusual Uses of DNS » durant le FOSDEM 2023. Du coup je me suis souvenu qu'il y a quelques années j'étais tombé sur le oneliner Bash qu'il montre à la fin et qui permet de lire une vidéo depuis le DNS. Ça m'avait donné envie de faire pareil : je l'avais fait et en avait parlé dans ce partage d'un article sur « (ab)using DNS as a CDN ». Du coup voici un petit article vite fait pour parler de comment j'ai construit le fichier de zone qui sert cette vidéo.
Principe
Quand on lit la commande, le principe est assez simple : il s'agit d'encoder notre vidéo en base64 et de stocker ça dans un enregistrement DNS TXT.
Bien sur on se souvient qu'une chaîne d'un enregistrement TXT est limité à 255 caractères. Mais on peut en mettre plusieurs à la suite dans un seul enregistrement. On va donc découper notre chaîne base64 en plusieurs chaînes.
Convertir notre vidéo en fichier de zone DNS
Il faut avant tout choisir la vidéo que l'on va mettre dans notre zone. Et si possible réduire sa taille (on va éviter de mettre un film HD dans notre zone, il y a des limites tout de même). Via ffmpeg par exemple, je vous laisse trouver les réglages qui conviendront à votre usage.
Puis on convertit notre vidéo en base64 à raison de 2048 caractères par ligne :
cat video.webm | base64 -w 2048 > video.base64
Enfin on va faire un petit script qui itère sur ce fichier pour nous générer nos enregistrements TXT de 2048 caractères découpés par segments de 255 caractères :
def get_file(file_path):
with open(file_path) as f:
lines = [line.rstrip() for line in f]
return lines
def split_string(string, length=255):
return [(string[i:i+length]) for i in range(0, len(string), length)]
if __name__ == '__main__':
record_label = "rr"
record_ttl = "60"
video_base64 = get_file('video.base64')
record_number = 0
for line in video_base64:
record_number += 1
record_data_array = split_string(line, 255)
record_data = ' '.join(f'"{s}"' for s in record_data_array)
print(str(record_number) + "." + record_label + " " + record_ttl + " IN TXT " + record_data)
Moi je le fais en Python, mais libre à vous de le faire dans le langage de votre choix.
Quand on exécute ce programme et on le redirige vers un fichier, ça nous donne un fichier de zone avec nos enregistrements sous la forme :
X.rr 60 IN TXT "un bloc de base64" "la suite de notre bloc de base64"
Où X est le numéro de notre ligne.
On peut donc à présent servir ce fichier via notre serveur DNS favoris.
Lecture
Et donc pour lire notre vidéo à travers le DNS on peut utiliser le oneliner suivant :
dig TXT +short {1..606}.rr.xn--h-rfa.fr | sed -E 's/[" ]//g' | base64 -d | vlc -
Pour le décortiquer rapidement :
{1..606}permet en Bash de générer une séquence de chiffres allant de 1 à 606 inclus- Donc
digva itérer sur1.rr.xn--h-rfa.fr,2.rr.xn--h-rfa.fr, etc en demandant à chaque fois le typeTXTet en ne gardant que la donnée de la réponse (+short) - Le
seds'occupe de supprimer les guillemets entre nos segments de 255 caractères, en gros il les concatène base64 -dva décoder notre bloc final de 2048 caractèresvlc -va lire le bloc en question sur son entrée
Ainsi VLC va voir arriver rapidement à la suite les données de notre vidéo et la lire.
Conclusion
On peut vraiment mettre tout et n'importe quoi dans le DNS. Il existe plein d'autres exemples amusants de telles expérimentations.
J'espère que ce petit article vous aura amusé et peut-être permis de mieux appréhender le DNS et les données.
Vous pouvez commenter en envoyant un mail via ce bouton (votre adresse ne sera pas publié).
Commenter par mail