• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Полное руководство по эксплуатации UART

tenac1ous

Shellcode
Модератор
Регистрация
22.01.2023
Сообщения
173
Реакции
232
Приветствую, пока у меня идет буйная работа з эмуляциями модемов и прочей сатанинской эзотерикой, я решил разбавить молчание в разделе фрикинга базовой статьей по эксплуатации протокольчика UART, контента этой статьи хватит для того что бы можно было медленно и неуверенно начать свой путь к embedded hardware эксплуатации, если будет понятен интерес со стороны сообщества то можно продвинутся дальше и затронуть JTAG, I2C и SPI в будущем.

Что такое UART​

UART (Universal Asynchronous Receiver-Transmitter) — это двухпроводный протокол последовательной передачи данных, который используется почти во всех embedded устройствах.
Основные линии:
В типичных конфигурациях всегда присутствует один старт-бит (сигнал переходит с высокого уровня на низкий — с положительного напряжения на нулевое или близкое к земле, в соответствии со стандартом TTL, используемым в embedded-устройствах).
Затем следует 5–8 бит данных (или даже 9, если используется режим без бита чётности).
После данных идёт один стоп-бит (сигнал возвращается в высокий уровень — положительное напряжение, такое как 3.3 В или 5 В).
Бит чётности (parity: even, odd или none) иногда добавляют для контроля ошибок передачи.
Всегда первым передаётся младший бит (LSB first).
  • Tx (Transmit) — передача данных (базар)
  • Rx (Receive) — приём данных (терпение базара)
  • GND (Ground) — общий провод (обязателен для корректной работы) (заземление индивидума кулаком после завершения процедуры обмена)
  • (опционально) Vcc — питание, обычно 3.3 В или 5 В, используется для ориентирования на плате, но не подключается при работе с внешним адаптером.

Передающая сторона UART берёт данные, которые внутри микроконтроллера идут "параллельно" (байт целиком), и превращает их в поток битов — один за другим — и отправляет по линии передачи.
Принимающая сторона UART делает обратное: получает этот поток битов, собирает их обратно в байты и отдаёт процессору.

Иными словами: всё, что выходит из TX одного устройства, приходит в RX другого — именно так они "разговаривают"между собой.
1758126049018.png

  • В типичных конфигурациях всегда присутствует один старт-бит (сигнал переходит с высокого уровня на низкий — с положительного напряжения на нулевое или близкое к земле, в соответствии со стандартом TTL, используемым в embedded-устройствах).
  • Затем следует 5–8 бит данных (или даже 9, если используется режим без бита чётности).
  • После данных идёт один стоп-бит (сигнал возвращается в высокий уровень — положительное напряжение, такое как 3.3 В или 5 В).
  • Бит чётности (parity: even, odd или none) иногда добавляют для контроля ошибок передачи.
  • Всегда первым передаётся младший бит (LSB first).
Иными словами, каждая передача — это короткий кадр"вида:
1758126220294.png


Это простая и очень надёжная схема, именно поэтому UART до сих пор так популярен.
В отличие от сложных шин вроде USB, UART не заботится о пакетах, адресации или подтверждениях (наподобии ACK), данные передаются асинхронно, что делает его простым, но потенциально уязвимым каналом. Этот протокол часто остаётся включённым на готовых устройствах даже в продакшн-прошивках, и частенько дает нам доступ к рут шеллу, сниффингу траффика и общей манипуляций сигналами (можно менять поведении устройства на low level)

Как найти пины​

Первое, что делаю — открываю корпус и ищу группу из 3–5 пинов. Иногда они подписаны — праздник! Намного чаще такого удовольствия нам архитектор PCB-шки не дает.
Дальше в ход идёт мультиметр, у меня он вот такой, находится на алике без проблем.
1758126728739.png

Процесс определения такой:
  • используем мультиметр в режиме прозвонки (continuity mode). Один щуп прикладываем к металлическому корпусу устройства (или к болту, винту, любому корпусному элементу), второй — к подозреваемому пину. Если мультиметр пищит / показывает низкое сопротивление — пин “земля” / GND.
  • VCC показывает стабильные 3.3 или 5 В.
  • TX выдаёт пульсирующее напряжение при включении устройства (это микроконтроллер "здоровается").
  • а оставшийся пин — очевидно RX (еще можно определить по постоянному низкому напряжению).

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




Прежде мы перейдем к копанию во всей этой шняге, надо пройтись по терминологии что бы мой лексикон не сбивал вас з толку, вот парочка ключевых терминов:
  • Oversample rate — частота оверсэмплинга: 4, 8, 16, 32.
    При приёме UART контроллер многократно "сэмплирует" входной сигнал в пределах одного бита, чтобы устойчиво определить, соответствует ли уровень 0 или 1. Чем выше oверсэмплинг — тем точнее приём при шуме или рассинхронизации, но тем выше требования к тактированию. Типичные значения — 4, 8, 16 или 32.
  • Peripheral clock — тактовая частота периферии.
    Это тактовый сигнал, который питает UART-модуль микроконтроллера (например, 48 MHz, 80 MHz и т.д.). От него вычисляется реальная скоростная частота передачи (baud).
  • Baud rate divider — делитель для получения нужной скорости.
    Внутри UART есть регистр (делитель), который делит тактовую частоту периферии с учётом выбранного oversample, чтобы получить требуемую скорость передачи (baud). Иначе говоря, контроллер настраивается так, чтобы периферийный такт / (oversample * divider) = желаемый baud.
  • Standard baudrates — стандартные скорости: 9600, 38400, 115200 и т.д.
    Это «обычные» значения скорости, которые поддерживаются большинством устройств и терминалов. 115200 бод — наиболее распространённая скорость для современных MCU; 9600 и 38400 — часто встречаются в старых модулях.
совет: если вы настраиваете UART и видите всякий мусор в консоли, пробуйте сначала стандартные скорости (115200, 57600, 38400, 19200, 9600). Если точность критична и периферийный такт нестабилен, можно поэкспериментировать с разными oversample-значениями и корректными делителями (согласно даташиту MCU).

Первый контакт: подключение и настройка​

Далее берем USB-TTL адаптер (обычно чип CP2102 или FTDI), цепляем:
TX <-> RX,
RX <-> TX,
GND <-> GND.
ВНИМАНИЕ - Никогда не подключайте питание от адаптера, чтобы не спалить плату!
Вот такие адаптеры отлично подходят и очень дешевые


Наглядная схема подключения на примере малинки:
1758128344537.png


Важный параметр это скорость — с ней часто промахиваются новички. Начинаем с 115200 бод, если видим кракозябры - тогда пробуйте 57600, 38400, 9600. Есть даже утилита baudrate.py (baudrate.py -p /dev/ttyUSB0) , которая сама подбирает скорость — экономит время.
Полезные утилиты для доступа к serial console:

Minicom/picocom - https://wiki.emacinc.com/wiki/Getting_Started_With_Minicom
Screen - https://www.cyberciti.biz/faq/unix-linux-apple-osx-bsd-screen-set-baud-rate/

Открываем screen /dev/ttyUSB0 115200 — и если повезло, видим священные строки загрузки ядра или U-Boot. Иногда если успеть нажать пробел то можно попасть в консоль загрузчика. А там можно дать полет творческому мышлению: дампить память, изменять переменные окружения, грузить альтернативный initramfs.
1758129584502.png

Немного автоматизации
Если в консоли много команд, их можно перебрать скриптом с pySerial: отправляю строку, читаю ответ. Так можно находить скрытые команды быстрее, чем вручную:
Python:
import serial, time
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.5)
for cmd in ["help","debug","factory","reboot"]:
    ser.write((cmd+"\n").encode())
    time.sleep(0.2)
    print(ser.read(4096).decode(errors='ignore'))













После того как вы получили доступ к serial console через UART, можно выдохнуть, самая геморойная часть уже позади.
Можно начать проходится по нашему чек листу:

Наблюдаем за логами

Для начала рекомендую понаблюдать за логами, просто смотреть что пишет железка:
  • Сообщения загрузчика (U-Boot, RedBoot и т.д.): версии прошивки, параметры загрузки, пути к rootfs.​
  • Логи ядра: монтирование разделов, запуск демонов, ошибки.
  • Сообщения сервисов: иногда прямо на консоль выводятся пароли по умолчанию или ключи от API.
Попытка прервать загрузку
На многих устройствах, если при старте нажать пробел или Ctrl+C, загрузчик останавливается и даёт командную строку (=>):
  • printenv — посмотреть переменные окружения.
  • setenv / saveenv — изменить поведение загрузки (например, загрузить систему в режим отладки).
  • bootm, tftpboot, mmc read — команды, которые можно использовать для дампа памяти или запуска своих образов.

Промты для авторизации
Если устройство грузит Linux или RTOS, после логов часто появляется приглашение:
1758130058279.png


Тут можно попробовать:
  • Дефолтные логины: root, admin, user.
  • Дефолтные пароли: root, admin, 1234, пустой пароль.
  • Если пароль известен из прошивки (или отреверсен из нее) — использовать его.
Сбор информации внутри устройства (если ядро линукс)
  • Проверяем версии (uname -a, cat /etc/release).
  • Смотрим запущенные процессы (ps, top).
  • Ищем файлы с паролями и ключами (grep -R password /etc).
  • Читаем и если есть привелегии пишем конфиги (/etc/config, /etc/network, /etc/shadow ).
Иногда консоль не совсем Linux-shell, а кастомный CLI производителя.
Тогда пробуй:
  • Комманды на подобии help, ?, .h, debug, factory.
  • Перебрать команды с помощью небольшого скрипта и смотреть, на что устройство реагирует.

Дамп и модификация прошивки
  • Пробуем читать флеш-память (md, dump, sf read) и сохранять её через UART (или через TFTP).
  • Если чуствуете себе черезмерно смелым то пробуйте заливать свою прошивку или initramfs (например, для отладки или получения полноценного shell).
На этом наше базовое ознакомление з этим протоколом подходит к концу, надеюсь интересующимся - порнавилось. До новых встреч!
 

Вложения

  • 1758129518215.png
    1758129518215.png
    17 КБ · Просмотры: 8
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх