- PVSM.RU - https://www.pvsm.ru -
Думаю, стоит сразу указать ссылку, т.к. дальше я буду ссылаться на видеозапись, которую, к сожалению, нельзя прикрепить на Хабр...
Ссылка на материалы: ССЫЛКА [1]
Хакеры взломали ос��ещение жилого дома и пустили по нему бегущей строкой свои требования: миллион фруктов юдзу и вертолет. А что было в начале их требований?
Нам доступно: перехваченный трафик в формате pcap и видео запись [2], на которой видно как хакеры взламывают освещение жилого дома.
Для начала посмотрим видеозапись инцидента... Заметим, что мы попали в ситуацию, которая постоянно рассматривается в кинофильмах: хакеры взломали освещение дома и используют его как баннер :-)
Что ж... Откроем запись трафика в Wireshark. И увидим, что записаны пакеты ZigBee (это протокол обмена между энерго-эффективными IoT устройствами). Заметим, что у нас первые 65 пакетов — это команды Off. То есть происходит «очистка экрана». Для удобства отфильтруем пакеты:
zbee_nwk.dst != 0x0000 && zbee_nwk.dst != 0xffff && zbee_zcl
где получатель покета не 0x0000 (не злоумышленник) и не 0xffff (Broadcast), а так же в пакете есть протокол ZigBee Cluster Library (в нём хранится команда On/Off).

Посмотрев по адресам destination в пакетах, мы можем понять, что матрица будет иметь размер 13х5. А "поковыряв" пакеты в сыром виде, заметим, что последний байт является командой Off(0x00) или On(0x01).
В целом, на этом решение и заканчивается... Дальше нужно просто распарсить все пакеты, которые удовлетворяют фильтру (1), а это всего лишь 5083 пакета :-)
Для парсинга будем использовать библиотеку Scapy. Подключаем следующие модули:
import scapy.all as scapy
from scapy.config import conf
from scapy.layers.zigbee import ZigbeeClusterLibrary
from scapy.layers.zigbee import ZigbeeNWK
Conf нужен для уточнения, что мы работаем с пакетами ZigBee.
ZigbeeClusterLibrary нужен для проверки наличия данного протокола в пакете.
ZigbeeNWK нужен для проверки наличия данного протокола в пакете, а так же для получения источника и получателя пакета.
Затем, собираем все наши пакеты с командами в один список.
print("[*] Поиск пакетов с On/Off командами... ", end='')
for i, pkt in enumerate(packets):
if pkt.haslayer(ZigbeeNWK) and pkt.haslayer(ZigbeeClusterLibrary):
znl = pkt[ZigbeeNWK]
if znl.source != 0x0000 or znl.destination == 0xffff:
continue
raw = bytes(pkt)
state = -1
if raw[-1] == ON_CMD:
state = ON_CMD
if raw[-1] == OFF_CMD:
state = OFF_CMD
commands.append((pkt.time, znl.destination, state))
Группируем пакеты в кадры по временным задержкам. Кстати, найти эту задержку можно с помощью Wireshark: задержка между пакетами, которые отрисовывают один «кусок» символа имеют задержку 0.16 секунд.
def group_commands_by_time_window(commands:list, window_sec:float=0.8):
if not commands:
return []
frames: list = []
current_frame: list = []
start_time: float = commands[0][0]
for t, addr, cmd in commands:
if t - start_time <= window_sec:
current_frame.append((addr, cmd))
else:
frames.append(current_frame)
current_frame = [(addr, cmd)]
start_time = t
if current_frame:
frames.append(current_frame)
return frames
После группировки пакетов в кадры, преобразуем эти кадры в матрицы из 0 и 1.
def render_frame(frame:list, matr:list[list[int]], width:int, height:int) -> list[list[int]]:
if len(matr) == 0:
matrix: list[list[int]] = [
[
0 for i in range(width)
] for j in range(height)
]
else:
matrix = matr
for addr, state in frame:
cell_idx: int = addr % (width * height)
row: int = cell_idx // width
col: int = cell_idx % width
if row < height and col < width:
matrix[row][col] = state
return matrix
Ну и выводим кадры с задержкой 0.16 секунд.
matrix: list[list[int]] = []
for i, frame in enumerate(frames):
os.system('cls' if os.name == 'nt' else 'clear')
print(f"=== Кадр #{i+1} ({len(frame)} команд) ===")
matrix = render_frame(frame, matrix, height=HEIGHT, width=WIDTH)
print_matrix(matrix)
time.sleep(FRAME_INTERVAL)
Запустим наш скрипт и поучим графический вывод флага, как это было у хакеров, только вместо здания у нас терминал :-)

После запишем наш флаг: TCTF{WIR3L3SS_BUT_N0T_T00_S3CUR3}
Мы прошли решение задачи шаг за шагом. Жду каких-либо дополнений, замечаний или вопросов в комментариях :-)

Автор: Grokir
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/444804
Ссылки в тексте:
[1] ССЫЛКА: https://github.com/Grokir/T-CTF_2025_Kapirunning_line#
[2] видео запись: https://github.com/Grokir/T-CTF_2025_Kapirunning_line/blob/main/capybarquee_7a6157e.mp4
[3] Источник: https://habr.com/ru/articles/996766/?utm_source=habrahabr&utm_medium=rss&utm_campaign=996766
Нажмите здесь для печати.