AccessUSB: «флешка всевластия» для телевизоров LG
Многие современные телевизоры имеют скрытые сервисные меню, через которые можно посмотреть и изменить различные параметры, недоступные в обычном пользовательском меню. В телевизорах LG есть 2 основных сервисных меню - InStart и EzAdjust, которые можно вызвать посылкой "секретных" ИК кодов, отсутствующих на обычном пульте. Подробности о том, как открыть эти меню, легко найти в интернете, не буду на этом останавливаться, один из вариантов - в этой статье. К сожалению, многие интересные опции в сервисных меню были недоступны для изменения.
В меню InStart меня заинтересовала строка Access USB Status. Гугление не давало никакой информации о том, что это за Access USB, но интуиция подсказывала, что это что-то интересное.
Кроме того, изучая информацию в интернете, я узнал что у более старых телевизоров была возможность подключиться по RS232 и получить debug консоль. В новых моделях телевизоров физический RS232 отсутствует, однако удалось выяснить, что возможность консольного подключения не исчезла - консольное соединение в новых ТВ можно получить, подключив переходник USB-UART на PL2303. Сделав шнурик из пары PL2303 и введя команду debug я опять наткнулся на упоминание AccessUSB:
- Код: Выделить всё
Access USB is NOT opened!!!
Решено было разобраться что это за AccessUSB, что даёт, и по какому протоколу работает. Для начала нужно было получить прошивку ТВ. Прошивки для телевизоров LG распространяются в формате epk - это проприетарный формат LG, запакованный, зашифрованный и подписанный, однако её можно распаковать с помощью opensource тулзы epk2extract (большое спасибо создателям этой тулзы). Распаковав прошивку и пройдясь поиском по строке "AccessUSB", я обнаружил основные модули, которые отвечают за взаимодействие с AccessUSB: physical-device-manager - занимается определением подключаемых устройств, и securitymanager - отвечает за авторизацию.
Обнаружение AccessUSB в системе
Для начала надо было выяснить, каким образом AccessUSB вообще определяется в системе, для этого я начал исследовать physical-device-manager. Операционная система LG - WebOS - как и Android, основана на ядре Linux, но использует хромиум вместо явы для исполнения javascript приложений, и естественно другое внутреннее API. Впрочем, системные сервисы представляют собой обычные линуксовые ELF файлы под ARM архитектуру. Несмотря на то, что ядро Linux способно определять и использовать со встроенными драйверами большое число различных устройств, в WebOS будет доступно только то, что определит physical-device-manager, который также представляет собой нативный ELF файл.
При загрузке его в IDA обнаружилось, что почти все присутствующие функции были экспортируемыми, и соответственно известны их имена, что весьма облегчило задачу. Я обнаружил таблицу допустимых устройств и определил названия и типы её полей, чему помимо названий функций также поспособствовали сообщения для логирования.
Видно, что телевизор может поддерживать USB камеры, WIFI модули, и другие устройства, однако большинство из них должны иметь определенный VID/PID, и большинство - VID_043E - LG. Вот так и осуществляется vendor lock.
В списке на предпоследнем месте обнаружилось искомое - AccessUSB, а чуть выше - pl2303 USB2SERIAL, используемый для подключения консоли. Итак, AccessUSB - это устройство с VID_16C0&PID_05E1 и Class_02.USB class 02 - это Communications Device Class - по сути - тот же USB-UART. В линуксе подобные устройства работают через стандартный драйвер cdc_acm и определяются как ttyACM. Я сделал прошивку для микроконтроллера STM32 с поддержкой USB, которая реализует этот протокол с требуемыми ID. При подключении к ТВ он определил это устройство:
При попытке входа в сервисные меню стал запрашиваться 6-символьный пароль вместо обычного 4-символьного (обычно вход в сервисные меню "защищён" дефолтным паролем 0413, который не менялся похоже никогда):
Дальше естественно авторизация не проходила - теперь предстояло исследовать и реализовать протокол авторизации.
Протокол AccessUSB
За авторизацию AccessUSB отвечает securitymanager, также ARM ELF. Я полностью отреверсил протокол, он оказался явно проприетарный, но относительно простой. Выяснилось, что в отличие от захардкоженного 4-символьного пароля, который проверял сам ТВ, 6-символьный пароль передавался в хешированном виде в AccessUSB для проверки (в чем смысл хешировать 6-цифирьный пароль - я без понятия). Еще выяснилось, что помимо ошибки Invalid Password в протоколе предусмотрены также ошибки Time Expiration и Count Expiration - таким образом, оригинальное AccessUSB может иметь ограничения по времени и/или количеству использований.
Но основная проблема оказалась в том, что на последнем этапе авторизации необходимо было сформировать сообщение, зашифрованное RSA2048. В прошивке ТВ был только открытый ключ, а закрытый содержится только в AccessUSB. Кроме того, в протоколе была предусмотрена возможность сменить сертификат авторизации, однако этот сертификат также должен быть подписан, но уже RSA4096 - в общем хрен редьки не слаще.
Поскольку взлом RSA2048 - задача на данный момент нерешаемая, пришлось считерить - заменить ключ RSA в памяти на свой. Таким образом, чтобы получить рут надо уже иметь рут, однако есть способы рутануть телевизор и без AccessUSB, так что проблема решаемая.
Возможности, предоставляемые AccessUSB
Итак, реализовав протокол и заменив ключ RSA, я наконец смог добиться успешной авторизации моего AccessUSB и исследовать предоставляемые им возможности.
В меню InStart изменился статус AccessUSB:
Разблокировались многие недоступные ранее опции, в частности появилась возможность переключить телевизор в debug режим:
Переключение в debug режим само по себе даёт доступы, аналогичные наличию AccessUSB, так что в принципе достаточно получить рут любым способом и найти как включить debug режим - изменением переменной в памяти или ещё как-то.
В меню EzAdjust появилась возможнось без ограничений изменять любые ToolOption-ы, например включить DVR (возможность записывать телепередачи):
Подключившись по консоли и введя команду debug, я попал в консоль Debug Mode:
- Код: Выделить всё
Enter Debug Mode: if you want exit form debug, input 'x'
По кнопке F1 отображается help:
- Код: Выделить всё
=================================================================================
[Pages] List of pages of special key
**[system ] for system
[tmanager ] job control
---------------------------------------------------------------------------------
[Global] Helps about global special key
[F01][func:0x00000000]: Show this page help message
[F02][func:0x00000000]: Move to prev page
[F03][func:0x00000000]: Move to next page
[F04][func:0x00000000]: Show Process List
[F07][func:0x00000000]: Toggle kernel print
[F08][func:0x00000000]: Toggle process name
[F09][func:0x00000000]: Toggle debug message output
[F10][func:0x00000000]: Enter debug main menu
---------------------------------------------------------------------------------
[system] Helps about function of special key
[ `][func:0x00000000]: show memory status
[ ~][func:0x00000000]: Setting Marker
[! ][func:0x00000000]: Control Memory Manager
[ @][func:0x00000000]: Toggle log level for SM System
[ #][func:0x00000000]: Control log msg type
[ $][func:0x00000000]: Dump Memory Pool
[ %][func:0x00000000]: Control Memory checking opt
[ ^][func:0x00000000]: Control Memory checking Threshold
[ +][cmd: true]: sload
[ |][func:0x00000000]: check close (0)
[F05][cmd: true]: mask i
[F06][func:0x00000000]: Task Menu
[F11][func:0x00000000]: top
[F12][func:0x00000000]: monitor
[S+F03][cmd: true]: /info/map
[S+F04][cmd: true]: exc -1
[S+F05][cmd: true]: /info/maps -1
[S+F06][cmd: true]: /info/sema -1
[S+F07][func:0x00000000]: show current phy.memory
[S+F08][func:0x00000000]: show all phy.memory
[S+F09][func:0x00000000]: show timelog
[S+F10][func:0x00000000]: gdb menu
=================================================================================
По F10 попадаем в debug main menu, его хелп:
- Код: Выделить всё
help,? Print this help message
============================================================
md Memory dump
mm Modify memory
mf Memory fill
mmap Map kernel physical memory to user vitrual memory
dsm Disassemble memory
regs Dump current exception registers
num Print number in hex/dec/bin
uptime Print system up time
sload load symbol info
sh enter shell
call Call a function
mask control mask print
esyslog syslog
escreen display screen from file
gdb gdb current process
] ts Show OSA Task status ---] task@systemInfo
] prio set task priority ---] prio@systemInfo
* show Show Various status
remote Remote Login Mode
cfg Show current CFG.set value
ver Show VERsion data
browser Excute Browser shell
reset Reset system
part Show current MTD.map info.
* orgm Enter Org style debug menu
* cmddbg Enter Command-Line Style debug menu
] ejobs Display Process List ---] ejobs@tmgr
] efg Switch focused terminal ---] efg@tmgr
] exc Dump exception log ---] exc@tmgr
] efork Create new cmdline task ---] efork@tmgr
] bcast Broadcast command to all process ---] bcast@tmgr
] print Control Print ---] print@tmgr
] log Dump Log Buffer ---] log@tmgr
] baud Control Baudrate ---] baud@tmgr
] elogout logout network connection ---] elogout@tmgr
------ debugMain ----------------------------------------
* test Test basic functions
* info systemInfo
* mem memory debugging
] mprof Set Msg Profile (per MQ) ---] mprof@memory debugging
* tmgr tmgr
============================================================
exit Exit from debugMain menu
Введя команду sh, получаем рутовую Linux консоль. Можно развлекаться по полной. Можно узнать характеристики процессора (cat /proc/cpuinfo), объем доступной памяти (cat /proc/meminfo) и т.д. Выяснилось, что характеристики Smart TV мягко говоря не очень - способны конкурировать разве что с современными ему самыми дешёвыми смартфонами.
Выводы
В ходе данного исследования я выяснил, что AccessUSB представляет собой аппаратный ключ, вероятно выполненный в форм-факторе USB-флешки, дающий расширенный доступ к сервисным опциям и рутовую консоль.
Позже мне удалось исследовать другой телевизор, на несколько лет моложе моего. Выяснилось что поддержка AccessUSB сохранилась, ни протокол, ни ключи не изменились. У меня нет информации про самые последние модели, но вполне возможно, что и там всё осталось по старому.
На данный момент у меня нет никакой информации о том, кто имеет доступ к оригинальным AccessUSB - только сотрудники LG или эти ключи поставляются также и в сервисные центры, однако наличие возможности установить ограничения по времени и/или числу использований вероятно свидетельствует в пользу того, что какие-то сервисные центры могут их получать.
К сожалению, отсутствие закрытого ключа RSA не даёт возможность создать полнофункциональный аналог оригинального AccessUSB, однако если найдётся кто-то, имеющий доступ к оригинальному AccessUSB и желающий получить полнофункциональный клон без ограничений - пишите в приват или комменты, обсудим что можно сделать.
Из комментариев к статье:
saboteur_kiev писал(а):Естественно, что в любом техническом устройстве есть определенные инженерные доступы, которые затем режутся в продакшене различными методами.
Поскольку разработка телевизоров, включая как и модули ядра ОС, так и аппаратные изменения выполняются разными командами разработчиков и аутсорсеров, нужна возможность блокировать доступ к таким вещам обычным пользователям. И в случае утери инженерных плат (где есть все эти rs232 и так далее разъемы), следовало дополнительно ограничить это еще и хардварными ключами.
Когда я работал в проекте WebOs, у нас у каждого инженера был отдельный телевизор с инженерной платой, и один accessusb на отдел.
Если случайно перевел телевизор в Release режим то вернуть его в debug можно было только при поомщи accessusb
Спасибо за ностальжи, было приятно увидеть скриншоты, которые лет 10 назад были обыденностью на работе =)