Твиты / Уязвимый Казнет и не только
-А что там с безопасностью TV - приложений?

Недавно перед релизом проводил анализ TV - приложения. Это сервис для умных телевизоров Samsung на TizenOS, просмотр ТВ-контента и платная медиатека.
Во время анализа я наткнулся на момент, который оказался куда интереснее всего остального.
Как и большинство подобных сервисов, приложение давало бесплатный тестовый период, примерно три дня. Логика простая, устройство определяется как уникальное, получает триал, а дальше либо оплата, либо доступ закрывается. В ходе анализа стало известно, что для идентификации используется MAC-адрес и DUID (уникальный идентификатор устройства). Получались они стандартными средствами Tizen API через webapis.network.getMac() и webapis.productinfo.getDuid().
Логика казалась выстроенной, но ключевой нюанс был в том, что MAC и DUID получались на стороне клиента.
Если источник данных сам клиент, значит их можно изменить?
После изучения документации стало понятно, что функции получения MAC и DUID - обычные jаvascript-методы в окружении Tizen. А значит, их можно переопределить до того, как приложение начнет использовать их в своей логике.
Идея была простой: при каждом запуске возвращать случайные значения вместо реальных. Новое значение DUID, новый MAC - с точки зрения сервера это каждый раз новое устройство.
Я написал небольшой скрипт, который переопределяет webapis.network.getMac и webapis.productinfo.getDuid, подставляя рандомные данные перед инициализацией основного кода приложения. В итоге при каждом перезапуске сервис видел "новый телевизор" и снова выдавал триальный период.
<script src="$WEBAPIS/webapis/webapis.js"></script>
<script>
function GenFakeDUID() {
const length = 13;
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
function GenFakeMAC(){
var hexDigits = "0123456789ABCDEF";
var macAddress = "";
for (var i = 0; i < 6; i++) {
macAddress+=hexDigits.charAt(Math.round(Math.random() * 15));
macAddress+=hexDigits.charAt(Math.round(Math.random() * 15));
if (i != 5) macAddress += ":";
}
return macAddress;
}
(function() {
webapis.network.getMac = function(){
return GenFakeMAC();
}
webapis.productinfo.getDuid = function(){
return GenFakeDUID();
}
})();
</script>Фактически логика триала полностью обходилась без каких-либо сложных манипуляций. Не было взлома сервера, не было подмены трафика, только работа с тем, чему система доверяла по умолчанию. А еще, при такой реализации подписку можно оформить на одно устройство, а затем использовать ее на нескольких, так как система продолжает полагаться исключительно на клиентские идентификаторы.
Ради интереса я проверил и другие уже существующие приложения и оказалось, что многие из них устроены аналогичным образом.
