Многие современные телевизоры имеют скрытые сервисные меню, через которые можно посмотреть и изменить различные параметры, недоступные в обычном пользовательском меню. В телевизорах 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:
Hidden text
=================================================================================
[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, его хелп:
Hidden text
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 и желающий получить полнофункциональный клон без ограничений - пишите в приват или комменты, обсудим что можно сделать.