Неотдавна получих партида смарт часовници с възможност за геолокация, които след тестване бяха изпратени в архива. Бях натоварен със задачата да намеря приложение на тези устройства, с което започна историята на реверсивното им инженерство, за която ще ви разкажа в тази статия.
Ще започна с преглед на техните външни особености и схеми, след което ще ви разкажа подробно за това как препрограмирах тези часовници, като дори им промених фърмуера, за да могат да изпълняват и други задачи.
Първи преглед
В стандартния си вид часовникът няма никакви особености и е придружен само от една страница с инструкции как да се зарежда и използва. Всеки комплект се състоеше от часовник и зарядно устройство. Нямаше README, уебсайтове или портали за разработчици. Имаше само един капацитивен сензор на повърхността на часовника, който включваше дисплей, на който потребителят можеше да види времето, да следи сърдечния ритъм и да получи някаква информация за настройка.

Екранът за отстраняване на грешки предостави полезна информация за идентифициране на часовника. Забелязах, че IP адресът, показан на екрана, е един и същ за всички часовници от един и същи модел. Първоначално помислих, че това е IP адресът на сървъра, с който часовникът комуникира.

Часовникът е със защита от клас IP67. Това означава, че е водоустойчив, а с моите ограничени инструменти нямаше как да получа достъп до вътрешността му, без да го повредя. В духа на откривателството реших да опитам да отворя часовника с клещи. Не беше лесно, но след час усърдно чоплене успях да „сваля“ горния капак на корпуса.

Отвореното устройство.

Вътре имаше печатна платка с LiPo батерия. В корпуса бяха вградени и две антени, свързани към u.FL конекторите на платката.
Реверсивното инженерство на платката
Часовникът се управлява от чипа nRF52832 с поддръжката на Bluetooth и съдържа още два основни чипа: Wi-Fi модула ESP8285 и клетъчния чип на SIMCOM. Първоначално бях объркан от присъствието на Wi-Fi микроконтролера, тъй като нищо не подсказваше, че часовникът има Wi-Fi поддръжка. Но по-късно разбрах, че той се използва за триангулация в градските райони.
Тъй като точността на GPS в градските райони е доста слаба, приблизителното местоположение на часовника може да се определи с помощта на Wi-Fi хотспотовете, като се използват данните от клетъчната мрежа плюс GPS данните. Съдейки по схемата, nRF52832 се свързва с чипа SIMCOM чрез UART и изпраща команди за връзка с мобилната мрежа. Знаейки това, се съсредоточих върху намирането на UART или пиновете за програмиране на чипа nRF52832, тъй като той беше основният и това са връзките, които обикновено се използват за комуникация с микроконтролера.

На платката има доста щифтове, които принадлежат на UART и са предназначени за програмиране. Една от интересните пътечки минаваше от двата позлатени щифта от дясната страна на платката към SWDIO и SWCLK на чипа nRF52832, както и към линия, която очаквах да се използва за зареждане на часовника. SWDIO и SWCLK са изводите JTAG за програмиране на чипа. От долната страна на предния капак на часовника също има пружинни щифтове, които се свързват накъсо с подложките SWDIO и SWCLK, когато часовникът е затворен.
А тези контакти бяха свързани и с медните щифтове на лицевата страна на часовника, осигурявайки външен достъп до възможността за програмиране. Външният достъп до програмирането е малко странен, тъй като обикновено фърмуерът на устройството се поставя на платката от завода и впоследствие се актуализира чрез Wi-Fi или Bluetooth. Обикновено не би имало нужда от достъп до изхода за програмиране. Въпреки това тази функция се оказа изключително полезна по-късно, тъй като гарантира, че не е необходимо да отварям останалата част от часовника, за да получа достъп до фърмуера. Необходимостта от отваряне на всяко устройство щеше да обезсмисли задачата ми да променя функционалността му, тъй като щеше да е много трудно да сглобя часовника след това.
По-интересното беше, че пружинните контакти, свързани към SWCLK и SWDIO на зарядното устройство, бяха свързани към D+ и D- изводите на microUSB порта, които обикновено се използват за пренос на данни. Това означаваше, че няма да ми се налага да създавам специална платформа за препрограмиране на часовника – просто трябва да разкача microUSB кабела, за да свържа линията за програмиране към всеки часовник. Хубав нюанс.


След като свързах часовника с моя JLink дебъгер чрез порта за зареждане, първото нещо, което забелязах, беше, че той създава възможност за дебъгване с помощта на приложението JLink RTT Viewer. Чудесно!!! И макар че възможността да наблюдавам изхода за отстраняване на грешки беше много полезна, поради липсата на вход, конфигуриран за RTT модула, нямаше начин да се изпращат команди към часовника. Въпреки това данните от изхода потвърдиха предположенията ми за вътрешното окабеляване на часовника.

След няколко експериментални опита за изпращане на команди чрез JLink реших да разгледам фърмуера. След като Jlink беше свързан, успях да направя дъмп с помощта на командата nrfjprog, придружена от флаговете –readcode и –readram:

Оказа се, че фърмуерът не е защитен от четене или писане, така че успях да получа копие на цялото нещо. В този момент имах две възможности за преконфигуриране на функционалността на часовника:
- Препрограмиране на устройството с изцяло нов фърмуер.
- Да променя IP адреса и порта, така че часовникът да изпраща данни към сървър, който аз контролирам.
Тъй като препрограмирането на часовника е свързано с много дълъг процес, реших да избера пътя на пача.
Преминаваме към Ghidra
За да определя подходящите функции и променливи в Ghidra, трябваше да направя дамп на RAM и флаш паметта. Тъй като това е гол код от устройство Cortex M0+, трябваше да декомпилирам фърмуера в ARM формат с директно подреждане на байтовете, след което Ghidra успя да генерира получетим псевдокод.

На този етап трябваше да открия IP адреса, който според мен беше зададен някъде в кода. Часовникът изпраща данни по клетъчната връзка към сървър, чийто адрес е показан на екрана за отстраняване на грешки. Ако можех да актуализирам IP адреса, можех също така да пренасоча данните, изпращани от часовника, към моя си контролен сървър.
Първите ми опити да намеря низа на IP адреса, който виждах на екрана на часовника, обаче бяха неуспешни.
Следващият ми опит беше да намеря най-близкия низ от изхода за отстраняване на грешки, който виждах в RTT Viewer. Оказа се, че това е AT+CIPOPEN=0, представляваща серийна команда, изпратена от nRF52832 към модула SIMCOM, която го инструктира да отвори връзка към IP адреса, посочен като аргумент. След като намерих този ред, използвайки IP адреса на сървъра, с който комуникира часовникът, можах да намеря мястото в паметта, където е записан този адрес.

Търсенето на низа за формата беше по-успешно. Намереното съвпадение съдържаше модел на низ, подобен на модела за IP адрес. Той се извиква във функция, подозрително подобна на sprintf.

Функцията sprintf се позовава на масив, съхраняван в DAT_20000887, който, ако се съди по картата на паметта на чипа nRF52832 по-долу, съответства на областта за данни в RAM.

Отивайки в областта за разполагане на RAM, установих, че в нея са записани две функции. Интересна беше само първата част на тази област, защото там се намираше IP адресът. Втората част дава възможност да се извършват последващи актуализации на този адрес по въздуха – по безжичен път.

Преминавайки към първата функция, открих тези твърдо кодирани шестнадесетични променливи, записани в масив в рамките на главната функция. Тези променливи отговаряха точно на IP адреса, който видях на екрана за отстраняване на грешки на часовника.

Тези области от паметта представляваха шест байта данни за фърмуера, които трябваше да променя, за да сменя IP адреса и порта.

Тук имаше малка засечка: номерът на порта беше стойността 38899, записана като два байта – 0x0c и 0x68. Компилираната програма използваше инструкцията movn, която прилагаше логическата операция NOT към твърдо кодираните стойности, преди те да бъдат поставени в оперативната памет. Чисто технически е възможно тази инструкция да бъде променена, като се премахне операцията NOT. Но аз се опитах да минимизирам броя на байтовете, които трябва да бъдат променени, затова добавих допълнителна операция при преобразуването на номера на порта в подходящите шестнадесетични стойности.
Препрограмирането на смарт часовника
Въз основа на това познание успях да напиша прост скрипт за промяна на фърмуера за всеки IP адрес и порт. Този скрипт също така актуализира контролната сума на всеки променен ред, така че фърмуерът да отговаря на очаквания формат. След като приключих с нанасянето на пачовете, прехвърлих фърмуера в часовника с помощта на програмата Programmer на Nordic Semiconductor.


И се радвам да съобщя, че всичко мина перфектно! Като актуализирах фърмуера, за да комуникира с моя сървър, успях да получа данните от часовника и да ги обработя.

С това приключва фазата на реверсивното инженерство. Научих много по време на процеса, тъй като имах малко опит в реверсивното препрограмиране на ARM-базирани устройства. Въпреки това имах добра представа за това как бих проектирал това устройство и какви възможности има то, което помогна значително да се стесни обхватът на търсенето.
Интересна подробност беше начинът, по който интерфейсът за програмиране беше свързан към USB порта – нещо, което не съм виждал в други подобни часовници. Липсата на каквато и да е защита за четене/запис на фърмуера също е нетипична, тъй като другите IoT устройства обикновено имат такава защита, когато се пускат в производство, за да се предотврати евентуално клониране.
Както и да е, процесът беше много интересен, а възможността да се намерят нови приложения за електроника, която иначе би била оставена да събира прах в склада или изхвърлена, придаде на проекта допълнителен смисъл.
В коментарите към статията обръщат внимание, че това изглежда е някакъв специален смарт часовник за затворници. Разбира се, в публикуваната по-горе информация някои неща са изпуснати, а някои други са съзнателно променени. Но все пак информацията е достатъчна някой да се замисли как би могъл да накара този часовник да изпраща фалшиви координати. Но това са само предположения.
Всичко важно от света на технологиите, директно в пощата ти.
С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.
Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!