Как я проводил обратную разработку таинственного UDP-трафика в гостиничном номере

от автора

Всем привет! Я на какое-то время поселился в гостинице. Гостиница из современных, с умными телевизорами и всякими другими подключенными устройствами. Меня одолело любопытство, и я открыл Wireshark, как сделал бы на моем месте любой любитель покопаться в технике.

Я был очень удивлен, когда увидел большое количество UDP-трафика на порте 2046. Взглянул на него, но много толку это не дало – порт оказался не из стандартных, так что разбираться предстояло вручную.

Сначала я заподозрил, что эти данные нужны для стриминга телепередач на телевизоры, но размер пакета выглядел мелковатым, даже для единичного видеофрейма.

UDP-пакеты приходили не на мой IP, и я не проводил ARP-спуфинг, соответственно, эти пакеты рассылались всем. Изучив их повнимательнее, я установил, что это пакеты Multicast. По сути, это значит, что пакеты отправляются однократно и одновременно приходят на несколько устройств. Я заметил и еще кое-что: все пакеты были одинакового размера (634 байта).

Я решил написать скрипт для извлечения и анализа этих данных на Python. Начнем с кода, с помощью которого я стал принимать пакеты Multicast. В нижеприведенном фрагменте 234.0.0.2 – это IP, который я получил на Wireshark.

import socket import struct  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('', 2046))  mreq = struct.pack("4sl", socket.inet_aton("234.0.0.2"), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)  while True:     data = s.recv(2048)     print(data)

Дополнительно я использовал binascii, чтобы конвертировать всё это в hex и облегчить себе процесс чтения байтов. Пронаблюдав, как тысячи пакетов сменяют друг друга на моей коносли, я заметил, что первые 15 байтов или около того у всех одинаковы. Эти байты, вероятно, указывали на протокол и ID пакета/команды, но так как мне приходило всё одно и то же, я не сумел ничего расследовать в этом плане.

Стыдно признаться, сколько времени мне потребовалось, чтобы заметить цепочку символов LAME3.91UUUUUUU в конце каждого пакета. Я заподозрил, что это аудиоданные, сжатые MPEG, но, когда для пробы сохранил один пакет как test.mp3, мультиплеер не смог его проиграть, а утилита file определила его только как test.mp3: data. То, что в пакете имеются данные, было и так очевидно, а если бы они представляли собой аудио MPEG, file должна была бы их узнать.

Поэтому я решил написать еще один скрипт на Python, который сохранял бы данные из пакетов со смещением. То есть файл test1 он должен был сохранить, пропустив один байт из пакета, файл test2 – пропустив два байта и так далее. Вот какой я использовал код и вот что из этого получилось:

 data = s.recv(2048) for i in range(25):     open("test{}".format(i), "wb+").write(data[i:])

После этого я запустил file test* и вуаля! Теперь мы знаем, что, чтобы добраться до данных аудио MPEG, нужно пропустить восемь байтов:

$ file test* test0:    data test1:    UNIF v-16624417 format NES ROM image test10:   UNIF v-763093498 format NES ROM image test11:   UNIF v-1093499874 format NES ROM image test12:   data test13:   TTComp archive, binary, 4K dictionary test14:   data test15:   data test16:   UNIF v-1939734368 format NES ROM image test17:   UNIF v-1198759424 format NES ROM image test18:   UNIF v-256340894 format NES ROM image test19:   UNIF v-839862132 format NES ROM image test2:    UNIF v-67173804 format NES ROM image test20:   data test21:   data test22:   data test23:   DOS executable (COM, 0x8C-variant) test24:   COM executable for DOS test3:    UNIF v-1325662462 format NES ROM image test4:    data test5:    data test6:    data test7:    data test8:    MPEG ADTS, layer III, v1, 192 kbps, 44.1 kHz, JntStereo test9:    UNIF v-2078407168 format NES ROM image
while True:     data = s.recv(2048)     sys.stdout.buffer.write(data[8:])

Дальше нам нужно просто непрерывно читать пакеты один за другим, пропуская в каждом по восемь байтов, и тогда всё отлично воспроизведется.

Что же кроется в этом аудио? Следы коварно спрятанного жучка, который подслушивает за мной? Что-то имеющее отношение к умному телевизору в моем номере? Что-то связанное с работой гостиничных систем? Есть только один способ узнать.

$ python3 listen_2046.py > test.mp3 * wait a little to get a recording * ^C  $ mplayer test.mp3 MPlayer (C) 2000-2016 MPlayer Team 224 audio & 451 video codecs  Playing test.mp3. libavformat version 57.25.100 (external) Audio only file format detected. ===== Starting playback... A:   3.9 (03.8) of 13.0 (13.0)  0.7%

Что за чертовщина? И на это я тратил своё время? Это музыка вызова лифта, её играют в коридорах возле лифтов. Ну ладно, зато теперь я могу слушать ее и у себя в номере.


ссылка на оригинал статьи https://habr.com/ru/articles/721508/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *