![](https://habrastorage.org/webt/xo/le/jh/xolejhmv9ffyukalmikgp50na3k.png)
Эта статья предназначается для всех, кто имеет опыт в разработке *nix/ПО/эксплойтов, но не обладает или почти не обладает знаниями оборудования/электроники! Хоть мы и не будем рассматривать все подробности простых схем (для этого есть множество отличных онлайн-ресурсов), информация изложена так, что не требует предыдущего опыта работы.
Основная задача статьи — помочь тем, кто пытается заниматься исследованием уязвимостей и/или разработкой эксплойтов физического устройства без системы отладки, оболочки и прошивки. Иными словами, мы попробуем добраться до root shell без сложностей поиска уязвимостей нулевого дня!
Разведка
Прежде чем переходить к исследуемому устройству, полезно провести предварительное изучение. В США все устройства, использующие радиочастотную связь (RF, Radio Frequency), например, WiFi, Bluetooth и т. п., должны проходить тестирование и проверку FCC. Эти тесты доступны публично, и обычно в них содержатся изображения внутренностей устройства!
Чтобы найти эти тесты FCC, нужно для начала узнать FCC ID. Этот ID всегда указан на корпусе устройства и обычно объединён с другой технической информацией и спецификациями. У данного устройства FCC ID находится на нижней крышке.
![](https://habrastorage.org/webt/l7/bk/cm/l7bkcmns6aajoidwhzknkqiv_u4.jpeg)
Для автоматизации процесса этот ID можно поискать непосредственно на официальном сайте поиска FCC или воспользоваться сайтами наподобие fcc.io или fccid.io. На них вы можете найти разнообразные документы: руководства пользователя, информацию о радиочастотном тестировании и фотографии внутренностей и внешнего вида устройства! Эти фотографии могут помочь в поиске возможных интерфейсов отладки оборудования, интересных компонентов, архитектуры ЦП и т. д.
Вскрываем оборудование
Обычно детали аппаратных устройств скрепляются вместе винтами, клеем и (почти всегда) пластмассовыми защёлками. Эти защёлки — проклятие любого хакера оборудования, однако их обычно удаётся открыть, аккуратно надавив отвёрткой с плоским шлицем или другим узким инструментом. (Помните, что острые края инструмента всегда должны быть направлены в противоположную от вас сторону!)
Подсказка: если устройство не разбирается, то проверьте под наклейками или резиновыми ножками в нижней части устройства, там могут быть винты.
При изучении документации FCC или внутренностей устройства мы стремимся решить следующие важные задачи:
1. Больше узнать об устройстве
Найдите ЦП. Обычно это самый большой чёрный квадрат на плате. Прочитайте его маркировку и найдите её в поисковом движке, обычно там есть технические описания архитектуры, контактов и многого другого.
Любой другой большой чип на печатной плате тоже может дать полезную информацию об устройстве (ОЗУ, накопитель и т. п.).
2. Получить прошивку устройства
См. подраздел «При помощи оборудования» в разделе «Получение прошивки».
3. Найти оболочки
Процесс получения shell и проведения интерактивной сессии отладки оборудования описан ниже.
Общение с оборудованием
В программировании двоичные файлы могут компилироваться с отладочными символами; аналогично этому, разработчики оборудования могут добавлять в устройства такие элементы, как отладочные разъёмы, позволяющие обмениваться данными с компонентами печатной платы. Эти интерфейсы используются для отладки при разработке и часто необходимы при производстве устройств для загрузки прошивок и/или проведения автоматизированных тестов. Поэтому такие разъёмы не убираются из готового устройства и могут служить замечательными точками входа для любопытного реверс-разработчика.
![](https://habrastorage.org/webt/iv/he/ml/ivhemlotxzpcnm-6xb0v1tyiatc.png)
Отладочные разъёмы (или контакты) обычно состоят из группы соединений, выстроенных в стандартную, легко узнаваемую структуру на печатной плате. Они могут быть уже припаянными к разъёму печатной платы (благодаря чему к ним можно легко подключать внешние устройства), или же вам придётся разогревать паяльник и припаивать к ним новые провода.
Примечание: отладочные разъёмы для встроенных ЦП часто представляют собой непосредственные соединения с контактами на самом ЦП. Если отладочные разъёмы сломаны или отсутствуют, то можно не обращать внимания на остальную часть платы и подключиться напрямую к этим контактам ЦП. С такими мелкими соединениями помогают специальные инструменты наподобие pcbite.
Хотя протоколов связи с оборудованием очень много (JTAG, I2C, SPI, CAN ...), в этой статье мы рассмотрим UART, потому что это один из самых популярных протоколов интерфейсов отладки.
Что за UART?
Universal Asynchronous Receiver/Transmitter (UART) — это простой, но изящный протокол. Как понятно из названия, он позволяет устройству асинхронно получать и передавать данные. UART-соединение обычно выглядит вот так:
![](https://habrastorage.org/webt/6l/n9/aj/6ln9ajvpuiwgkadkyz797hof8kc.png)
Интерфейс UART состоит из четырёх контактов:
- GND: низкое напряжение, например, 0 В.
- Vcc: высокое напряжение, обычно от 3,3 В до 12 В.
- Rx (приём).
- Tx (передача).
Контакты Rx и Tx имеют высокое напряжение в режиме простоя и колеблются между низким и высоким напряжением при передаче информации.
При помощи анализатора цепей мы можем исследовать реальную передачу UART.
![](https://habrastorage.org/webt/eu/yz/uy/euyzuyx9vjyp9k3u5xnwqkz3lns.png)
В каждой строке показано изменение напряжения на отдельном контакте UART в процессе передачи. Здесь мы замеряем, как устройство получает данные.
- Канал 0 (GND) постоянно имеет низкое напряжение.
- Канал 1 (Vcc) постоянно имеет высокое напряжение.
- Канал 2 (Rx) попеременно имеет низкое и высокое напряжение в процессе передачи данных.
- Канал 3 (Tx) постоянно имеет высокое напряжение (то есть передача данных отсутствует).
Данные передаются в виде битов (нулей и единиц), закодированных как импульсы низкого и высокого напряжений на контакте Rx. В протоколе UART описывается — как биты упаковываются в кадры размером 5-9 бит, включающие в себя специальные контрольные биты (старт/стоп) и биты коррекции ошибок (чётности). Однако важная особенность заключается в том, что принимающее устройство должно замерять эти напряжения с той же скоростью, с которой передающее устройство их отправляет. Если принимающее устройство выполняет измерения слишком быстро или слишком медленно, то полученные биты будут неверными. Следовательно, нам нужно сделать так, чтобы оба устройства общались на одной скорости. Поэтому нам нужно упомянуть…
▍ Скорости передачи информации (скорость в бодах)
Подробное описание бодов, скорости в бодах, скорости в битах и другого можно прочитать на stackoverflow. Однако для наших задач можно принять, что скорость в бодах UART-устройства — это просто количество передаваемых по проводу битов в секунду.
Большинство устройств работает со скоростью 9600 бод (9600 бит/с или 1200 байт/с) или 115200 бод. Существует много стандартных скоростей (обычно кратных 9600), но 9600 и 115200 почти всегда используются по умолчанию. Трюки для определения скоростей будут изложены ниже.
▍ Разъём UART
Заглянув внутрь устройства, вы можете увидеть нечто подобное:
![](https://habrastorage.org/webt/2v/zd/ms/2vzdmsdstxvfy7ypu7tocvzpv7u.jpeg)
Этот безымянный производитель даже любезно промаркировал контакты!
Естественно, каждый инженер может реализовывать проекты по-разному. В первую очередь нужно искать следующее:
1. Маркировку Rx и Tx
Если контакты Rx/Tx промаркированы, то почти всегда в пятидесяти процентах случаев обозначение Rx подразумевает или «здесь можно получать данные», или «отсюда устройство получает данные». (Тоже справедливо и для контакта Tx).
Примечание: Rx и Tx работают под одинаковым напряжением, поэтому ошибка обычно не приводит к проблемам (при необходимости провода можно позже поменять местами).
2. Контакт Vcc
Не всегда понятно, для чего предназначается контакт Vcc. Обычно, если плата уже запитана (например, через USB или блок питания), то необходимость работать с контактом Vcc отсутствует, поскольку он уже подключён к внутреннему Vcc платы. Неправильная работа с эти контактом и попытка подключить к нему другой источник питания может привести к короткому замыканию двух источников питания, сгоранию устройства и повреждению оборудования! (К сожалению, я знаю это по собственному опыту.) Короче, НЕ ПОДКЛЮЧАЙТЕСЬ К ЭТОМУ КОНТАКТУ.
Получаем Root Shell
Всё это здорово, но вы читаете эту статью не ради аппаратных протоколов, а чтобы получить root shell!
Как говорилось выше, при работе с UART присутствует некоторая неопределённость. Иногда контакт Vcc вообще отсутствует, иногда маркировка может быть ошибочной и т.п. Однако если вы увидите на плате три или четыре контакта в ряд, то это, скорее всего, UART.
Если на вашей плате отладочные контакты промаркированы, то сразу переходите к разделу «Взаимодействие». В противном случае надо браться за мультиметр!
▍ Идентифицируем контакты
Существует множество способов реверс-инжиниринга выводов UART, от простой удачи до оборудования за тысячу с лишним долларов. Мы выберем более дешёвый вариант: мультиметр! Если у вас его нет, то в продаже есть мультиметры ценой от 5 долларов. Для UART не требуется ничего крутого, подойдёт любой мультиметр, который может показывать напряжение в диапазоне 0 — 12 В и имеет режим проверки целостности цепи. (Например, этот или этот).
Разобравшись с мультиметром, выполните следующие действия:
- Найдите выводы, которые похожи на UART. (Там может быть два, три или четыре контакта)
- Включите устройство обычным образом.
- Переключите мультиметр в режим проверки целостности цепи. Обычно он выглядит как символ диода (
).
- Приложите чёрный щуп мультиметра к заземлённому компоненту (обычно это любой металлический участок — ради безопасности используйте корпуса выводов, радиочастотные экраны и т. п.)
На изображении ниже радиочастотные экраны — это большие прямоугольные металлические крышки компонентов, излучающих радиоволны; экраны почти всегда заземлены.
![](https://habrastorage.org/webt/cl/d4/56/cld456fcarb_96zsad6y5d61vyq.png)
1. Коснитесь красным щупом каждого контакта предполагаемого UART. Если звучит сигнал (или показания на экране мультиметра меняются), то вы нашли контакт заземления! Примечание: контакт заземления обычно имеет квадратную форму, но не всегда.
2. Переключите мультиметр в режим постоянного тока. Обычно он выглядит как “V” со сплошной горизонтальной линией над пунктирной линией. Если у мультиметра есть фиксированные диапазоны напряжений, выберите ближайший к 12 В (с округлением вверх).
3. Прижмите чёрный щуп мультиметра к найденному ранее контакту заземления.
4. Касайтесь красным щупом каждого контакта предполагаемого UART. Если мультиметр показывает 3,3 В или 5 В, то это, скорее всего, контакт приёма. Это может быть и контакт Vcc, поэтому можно проверить цепь на целостность с запитанным контактом коаксиального разъёма или USB-входа. Если значения колеблются в диапазоне от 3,3 В/5 В до 0 В, то это, скорее всего, контакт передачи. Если мультиметр показывает 0 В (или <0,5 В), то это, скорее всего, контакт заземления.
Контакт заземления — самый важный. Если вам удастся также найти Vcc, то можно просто случайным образом решить, где находятся Rx и Tx, а потом поменять их местами в случае отсутствия соединения.
▍ Взаимодействие
Отлично! Теперь, когда мы идентифицировали потенциальные контакты UART, нам нужно каким-то образом начать с ними общаться. Для этого подойдёт любой преобразователь USB-to-serial. Однако самыми простыми являются четырёхконтактные переходники наподобие такого или такого (он лучше). Эти переходники имеют следующие контакты:
Красный: Vcc (Нам его использовать не нужно!)
Чёрный: заземление
Зелёный: передача (со стороны переходника)
Белый: приём (в переходник)
Подключите эти провода к соответствующим контактам UART устройства следующим образом:
- Чёрный провод к заземлению устройства.
- Зелёный провод к контакту приёма устройства.
- Белый провод к контакту передачи устройства.
- Красный провод ни к чему не подключается!
![](https://habrastorage.org/webt/ph/xi/tw/phxitw5h2dlvntjpxlsbnxvhpzu.jpeg)
▍ Обмен данными
И мы приближаемся к финишу! Подключите USB-кабель и запустите ПО, способное работать с последовательным соединением:
В Linux-подобных системах:
1.
sudo screen /dev/ttyUSB0 [baudrate]
2.
sudo gtkterm -p /dev/ttyUSB0 -s [baudrate]
3. minicom/miniterm — тоже отличные специализированные CLI-инструменты для этого
В системах Windows можно использовать для последовательного соединения PuTTY.
Как говорилось выше, важно подобрать скорость целевого устройства, чтобы правильно общаться с ним. Так как в устройствах обычно используются стандартные скорости, можно воспользоваться скриптом наподобие baudrate.py для циклической проверки всех скоростей.
▍ Устранение неполадок
❒ Я не получаю вывод!
1. Убедитесь, что инструменты последовательной связи запущены под root/admin.
2. Снова проверьте контакты (попробуйте поменять местами Rx и Tx).
3. Убедитесь, что на устройство подаётся питание так, как это задумано производителем (т. е. не по красному последовательному проводу).
❒ Вывод представляет собой мусор из поломанных символов и Unicode
Скорее всего, неверно установлена скорость в бодах. Попробуйте пройтись по скрипту baudrate.py, возможно, какие-то другие скорости дадут вам нужную информацию.
❒ Устройство не запускается!
Возможно, это особенность работы с кабелем usb-to-serial. Раньше у меня бывало так, что после включения питания кабель посылает 1 В в свою линию передачи, из-за чего некоторые устройства перестают запускаться. Просто отключите кабель, перезапустите устройство, подождите секунду и подключите кабель.
❒ А что дальше?
После успешного подключения по UART вы, скорее всего, наткнётесь на лог запуск устройства, выдающий потоки отладочной информации. Если вам повезёт, то подождав несколько секунд и нажав на [ENTER], вы получите доступ к интерактивной оболочке, запущенной под root.
В противном случае придётся использовать различные трюки:
1. Если в начале процесса запуска вы увидите запрос ввода или нажатия определённых клавиш, нажмите их!
- Возможно, вы перейдёте в интерактивную оболочку загрузчика устройства. Хотя операционная система ещё не загрузилась, вы можете изучить содержимое nvram, сдампить прошивку, выполнять произвольную запись в участки памяти и принудительно запускать в устройстве оболочку, изменив аргументы init (см. этот пост)
2. Если командная строка загрузчика отсутствует или для неё установлена длительность 0 секунд, то есть несколько вариантов:
- Быстро нажимать CTRL+C при запуске. Это странный трюк, но в нескольких случаях он сработал.
- Если устройство использует загрузчик U-Boot, то можно заставить оборудование перебросить вас в интерактивную оболочку загрузчика. По умолчанию, если U-Boot не может считать образ прошивки из флэш-памяти в ОЗУ, то он вызовет панику и переключится в режим интерактивной оболочки восстановления. Чтобы вызвать эту панику (прости, U-Boot), на короткое время заземлите линию данных ввода-вывода флэш-чипа во время запуска. В этом вам помогут технические описания (даташиты) производителя!
Получение прошивки
Теперь, когда у вас есть оболочка с root, вы, вероятно, хотите заняться хакингом, и в этом случае вам пригодится копия прошивки оборудования. Процесс получения прошивки выходит за рамки этой статьи, но вот несколько возможных вариантов действий:
▍ 1. Скачивание непосредственно у производителя (самый простой способ):
Некоторые производители оборудования (OEM, Official Equipment Manufacturer) выкладывают сжатые образы прошивок на свои веб-сайты (предназначенные для обновлений вручную). Если не можете найти страницу скачивания, попробуйте ввести в поисковом движке "[название устройства]” “firmware”. Например: центр скачивания Netgear
▍ 2. Сетевой перехват
К сожалению для безопасности устройства (но к счастью для нас!) многие потребительские устройства общаются с конечными точками OEM по HTTP. Из-за отсутствия SSL/TLS иногда во время обновления прошивки можно перехватить сетевой трафик для получения файлов. При этом есть возможность и загрузки зловредных обновлений прошивок. (См. этот пост ZDI).
▍ 3. При помощи оборудования
Последовательное соединение: для автоматизации этого процесса существует множество отличных инструментов и руководств, например, это. Из загрузчика устройства обычно можно считывать содержимое флэш-памяти, в котором содержится образ прошивки! (Так как он ещё не был скопирован в ОЗУ.)
Дамп флэш-памяти: существует множество специализированных руководств, например, это. При помощи специализированных аппаратных инструментов (например, TL866II+) можно физически подключиться к флэш-чипам платы (отпаяв их или специальными зажимами), а затем считать содержимое.
FIN
![](https://habrastorage.org/webt/xb/o4/gm/xbo4gmrlicdllfwrmtuypqrlcgg.jpeg)