• XSS.stack #1 – первый литературный журнал от юзеров форума

GSM CMAS Сообщения на HackRF One: Моя маленькая история мучений и страданий

tenac1ous

Shellcode
Модератор
Регистрация
22.01.2023
Сообщения
169
Реакции
224
Для решения начать техническую дискуссию по этой теме меня сподвигло несколько причин. Одна из них это просто моя недостаточная квадратность головы для решения таких задач по сути з нуля. Но не будем говорить о грустном, а сделаем небольшой introduction для нашей основной темы ради которой и создается это обсуждение.
1736476980008.png


Вы когда то получали на телефон сообщения рода "Внимание! угроза урагана, землетрясения, отключение Xhamster" и тому подобные? Некоторые еще даже орут резким звуком и вибрируют. Так вот, все эти сообщения попадают под PWS ака "Public Warning Service". Раньше, в стареньком GSM и 3G, подобные сообщения передавались через CBS (Cell Broadcasting Service), а вот с приходом LTE и 5G для аналогичных целей был введен новый стандарт, известный как CMAS (Commercial Mobile Alert System). Зачем же это нам, обычным смертным?

По сути, CMAS – это отличный механизм для распространения фишинга. Задумайтесь, вывод текстовой информации на дисплеи смартфонов в радиусе нескольких сотен метров, с минимальными затратами и без сложных MITM атак, даунгрейдов с LTE на 2G и другой сложной технической мастурбацией, которая требует дорогостоящего оборудования. В отличие от многих других протоколов передачи данных, которые фокусируются на приватности и безопасности, CMAS проектировался с другой целью: доставить важные уведомления быстро и с минимальными трудностями, как для операторов, так и для пользователей. Этот стандарт фактически является уязвимым по дизайну: так как не требуется никакой аутентификации с устройствами, так что кто угодно, кто сможет сгенерировать правильный сигнал, передать сообщение в эфир и оно сработает. Ни про какой rnti там даже речи нет.
1736477139694.png


В конце я озвучу те трудности, с которыми я столкнулся, пытаясь реализовать этот код.

Понимание стандартов и спецификаций​

CMAS – это не просто простое уведомление, а целая система с сотнями страниц документации. Понимание всех этих тонкостей заняло приличное количество времени. Стандарты для передачи сообщений, например, такие как 3GPP TS 36.331 или 3GPP TS 23.041, действительно являются сложными. И если у вас не чешутся руки что бы погрузиться в мир ASN.1 и проприетарной буржуйской документации, то будет довольно трудно вникнуть и разобраться что к чему.
ASN.1 – это вообще отдельная головная боль. Мы ведь все привыкли к JSON или XML, где всё более-менее понятно. Но когда начинаешь работать с Abstract Syntax Notation One, понимаешь, что это как целый мир, где каждое сообщение требует железного понимания как оно работает, что бы было можно вносить хоть какие то модификации. Пытаться получить правильное бинарное представление сообщения, когда я работал з инструментами вроде asn1c было довольно поучитально, но в то же время голова у меня буквально гудела после 3х суток безвылазного изучения этой темы.
Давайте пройдемся по тех. части.

Сообщение CMAS состоит из трех частей:
Код:
Шаг 1 : SIB 1
BCCH-DL-SCH-Message
    message: c1 (0)  // Сообщение c1, значение 0
        c1: systemInformationBlockType1 (1)  // Тип сообщения SIB1
            systemInformationBlockType1  // Основной блок SIB1
                cellAccessRelatedInfo  // Информация, связанная с доступом к ячейке
                    plmn-IdentityList: 1 item  // Список идентификаторов PLMN (1 элемент)
                        Item 0
                            PLMN-IdentityInfo  // Информация об идентификаторе PLMN
                                plmn-Identity  // Идентификатор PLMN
                                    mcc: 3 items  // Код страны (MCC), 3 элемента
                                        Item 0
                                            MCC-MNC-Digit: 0  // Цифра MCC, 0
                                        Item 1
                                            MCC-MNC-Digit: 0  // Цифра MCC, 0
                                        Item 2
                                            MCC-MNC-Digit: 1  // Цифра MCC, 1
                                    mnc: 2 items  // Код сети (MNC), 2 элемента
                                        Item 0
                                            MCC-MNC-Digit: 0  // Цифра MNC, 0
                                        Item 1
                                            MCC-MNC-Digit: 1  // Цифра MNC, 1
                                cellReservedForOperatorUse: notReserved (1)  // Ячейка не зарезервирована для использования оператором
                        trackingAreaCode: 0000 [bit length 16, 0000 0000  0000 0000 decimal value 0]  // Код области отслеживания (TA)
                        cellIdentity: 00000000  // Идентификатор ячейки
                        cellBarred: notBarred (1)  // Ячейка не запрещена
                        intraFreqReselection: notAllowed (1)  // Переход между частотами на той же ячейке не разрешен
                        .... ..0. csg-Indication: False  // Индикатор CSG (не используется)
                    cellSelectionInfo  // Информация о выборе ячейки
                        q-RxLevMin: -110dBm (-55)  // Минимальное значение уровня сигнала
                    p-Max: 23dBm  // Максимальная мощность
                    freqBandIndicator: 4  // Индикатор диапазона частот
                    schedulingInfoList: 3 items  // Список информации о расписании, 3 элемента
                        Item 0
                            SchedulingInfo  // Информация о расписании
                                si-Periodicity: rf16 (1)  // Периодичность передачи SIB, 16 кадров
                                sib-MappingInfo: 0 items  // Отсутствие информации о сопоставлении SIB
                        Item 1
                            SchedulingInfo  // Информация о расписании
                                si-Periodicity: rf32 (2)  // Периодичность передачи SIB, 32 кадра
                                sib-MappingInfo: 1 item  // 1 элемент сопоставления SIB
                                    Item 0
                                        SIB-Type: sibType3 (0)  // Тип SIB, тип 3
                        Item 2
                            SchedulingInfo  // Информация о расписании
                                si-Periodicity: rf32 (2)  // Периодичность передачи SIB, 32 кадра
                                sib-MappingInfo: 1 item  // 1 элемент сопоставления SIB
                                    Item 0
                                        SIB-Type: sibType12-v920 (9)  // Тип SIB, тип 12 версии 920
                    si-WindowLength: ms20 (5)  // Длина окна SI
                    systemInfoValueTag: 0  // Тег информации о системе
                    nonCriticalExtension  // Некритичное расширение
                        nonCriticalExtension  // Некритичное расширение
                            ims-EmergencySupport-r9: true (0)  // Поддержка экстренных услуг IMS

Код:
Шаг 2 : SIB 12

BCCH-DL-SCH-Message
    message: c1 (0)  // Сообщение c1, значение 0
        c1: systemInformation (0)  // Тип сообщения SIB, тип 0
            systemInformation  // Основной блок системы информации
                criticalExtensions: systemInformation-r8 (0)  // Критичные расширения информации, версия 8
                    systemInformation-r8  // Информация системы версии 8
                        sib-TypeAndInfo: 1 item  // Список типов и информации SIB (1 элемент)
                            Item 0
                                sib-TypeAndInfo item: sib12-v920 (10)  // Тип и информация о SIB12, версия 920
                                    sib12-v920  // Данные для SIB12 версии 920
                                        messageIdentifier-r9: CMAS Identifier for CMAS Presidential Level Alerts (4370)  // Идентификатор сообщения CMAS для предупреждений уровня президента
                                        serialNumber-r9: 3000 [bit length 16, 0011 0000  0000 0000 decimal value 12288]  // Серийный номер
                                            00.. .... .... .... = Geographical Scope: Display mode immediate, cell wide (0)  // Географический охват: немедленное отображение на уровне ячейки
                                            ..11 0000 0000 .... = Message Code: 768  // Код сообщения
                                            .... .... .... 0000 = Update Number: 0  // Номер обновления
                                        warningMessageSegmentType-r9: lastSegment (1)  // Тип сегмента предупреждения: последний сегмент
                                        warningMessageSegmentNumber-r9: 0  // Номер сегмента предупреждения
                                        warningMessageSegment-r9: 0154747a0e4acf416137a8d82ecbcf65f7388...  // Сегмент предупреждения
                                        dataCodingScheme-r9: 01  // Схема кодирования данных
                                            0000 .... = Coding Group: Coding Group 0  // Группа кодирования: группа 0
                                            .... 0001 = Language: English (1)  // Язык: английский

Код:
Шаг 3 : Paging

PCCH-Message
    message: c1 (0)  // Сообщение c1, значение 0
        c1: paging (0)  // Тип сообщения: Paging
            paging  // Блок пагинга
                nonCriticalExtension  // Некритичное расширение
                    nonCriticalExtension  // Некритичное расширение
                        cmas-Indication-r9: true (0)  // Индикатор CMAS (Система оповещения для мобильных устройств)
                            [Expert Info (Warn/Sequence): Commercial Mobile Alert System Indication!]  // Сообщение предупреждения о CMAS
                                [Commercial Mobile Alert System Indication!]  // Уведомление о системе коммерческого мобильного оповещения
                                    [Severity level: Warn]  // Уровень серьезности: предупреждение
                                    [Group: Sequence]  // Группа: последовательность

В процессе написания кода для реализации системы CMAS я столкнулся с множеством сложностей, связанных как с теоретическими аспектами стандарта, так и с практическим применением знаний в реальной разработке. Каждая трудность стала для меня шагом к более глубокому пониманию работы с мобильными сетями и протоколами передачи данных. Но все же я пока не смог полноценно завершить эту задачу. После прочтения спецификаций 3GGP, документации Amarisoft, Matlab и LTE Toolbox, я написал код который должен передавать логику работы (синтаксис возможно не полностью идеальный). Мне будет полезно обсудить его работу и процедуры з кем то знающим, плюс это будет полезный контент для форума.
Вот сам код:
C-подобный:
% Initialize LTE Toolbox configuration for TDD
enb = lteRMCDL('R.4'); % Using Reference Measurement Channel (RMC) R.4 for TDD mode
enb.TDDConfig = 1; % TDD Configuration 1
enb.SSC = 7; % Special Subframe Configuration
enb.TotSubframes = 40; % Total subframes to simulate
enb.NFrame = 0; % Initial frame number
enb.NSubframe = 0; % Initial subframe number
enb.NCellID = 17; % Physical layer cell identity
enb.CyclicPrefix = 'Normal'; % Cyclic Prefix configuration
enb.DuplexMode = 'TDD'; % Duplex mode
enb.PHICHDuration = 'Normal'; % PHICH Duration
enb.CFI = 3; % Control Format Indicator

% Initialize PDSCH configuration
enb.PDSCH.TxScheme = 'Port0'; % Transmission scheme
enb.PDSCH.Modulation = {'QPSK'}; % Modulation scheme
enb.PDSCH.RVSeq = [0 1 2 3]; % Redundancy Version sequence
enb.PDSCH.PRBSet = (0:enb.NDLRB-1)'; % Resource block allocation

% Configure SIB1
sib1 = struct();
sib1.cellAccessRelatedInfo.plmn_IdentityList = struct('PLMN-IdentityInfo', ...
    struct('plmn_Identity', struct('mcc', [0 0 1], 'mnc', [0 1]), ...
    'cellReservedForOperatorUse', 'notReserved'));
sib1.cellAccessRelatedInfo.trackingAreaCode = '0000000000000000'; % bit length 16
sib1.cellAccessRelatedInfo.cellIdentity = '0000000000000000000000000000'; % bit length 28
sib1.cellAccessRelatedInfo.cellBarred = 'notBarred';
sib1.cellAccessRelatedInfo.intraFreqReselection = 'notAllowed';
sib1.cellAccessRelatedInfo.csg_Indication = false;
sib1.cellSelectionInfo.q_RxLevMin = -110;
sib1.p_Max = 23;
sib1.freqBandIndicator = 4;
sib1.schedulingInfoList = struct('si_Periodicity', {'rf16', 'rf32'}, ...
    'sib_MappingInfo', {{}, {'sibType12-v920'}});
sib1.si_WindowLength = 'ms20';
sib1.systemInfoValueTag = 0;
sib1.nonCriticalExtension = struct('ims_EmergencySupport_r9', true);

% Configure SIB12
sib12 = struct();
sib12.messageIdentifier_r9 = '0010001000100010'; % CMAS Identifier for Presidential Level Alerts (4370)
sib12.serialNumber_r9 = '0011000000000000'; % bit length 16, decimal value 12288
sib12.warningMessageSegmentType_r9 = 'lastSegment';
sib12.warningMessageSegmentNumber_r9 = 0;
sib12.warningMessageSegment_r9 = '0154747a0e4acf416137a8d82ecbcf65f7388...'; % Example message content
sib12.dataCodingScheme_r9 = '01'; % Coding Group 0 (Language using GSM 7 bit default alphabet), Language: English

% Configure Paging
paging = struct();
paging.cmas_Indication_r9 = true;
paging.nonCriticalExtension = struct('cmas_Indication_r9', true);

% Placeholder for ASN.1 encoding function
% Replace with actual ASN.1 encoding using an external library/tool
function encodedData = ASN1Encode(data)
    % Placeholder for ASN.1 encoding
    encodedData = uint8([]); % Replace with actual encoded data
end

% Custom function to generate SIB1 message
function sib1Msg = generateSIB1(sib1)
    bcchMessage = struct();
    bcchMessage.message = struct('c1', struct('systemInformationBlockType1', sib1));
    sib1Msg = ASN1Encode(bcchMessage); % Encode SIB1 struct
end

% Custom function to generate SIB12 message
function sib12Msg = generateSIB12(sib12)
    bcchMessage = struct();
    bcchMessage.message = struct('c1', struct('systemInformation', struct('sibType12', sib12)));
    sib12Msg = ASN1Encode(bcchMessage); % Encode SIB12 struct
end

% Custom function to generate Paging message
function pagingMsg = generatePaging(paging)
    pcchMessage = struct();
    pcchMessage.message = struct('c1', struct('paging', paging));
    pagingMsg = ASN1Encode(pcchMessage); % Encode Paging struct
end
% Simulate the transmission of SIB1, SIB12, and Paging
txWaveform = [];
for nSubframe = 0:enb.TotSubframes-1
    % Update frame and subframe numbers
    enb.NSubframe = mod(nSubframe, 10);
    if enb.NSubframe == 0
        enb.NFrame = enb.NFrame + 1;
    end
    
    % Generate the empty resource grid for the subframe
    txGrid = lteDLResourceGrid(enb);
    
    % Generate and map PSS and SSS in specific subframes
    if any(enb.NSubframe == [0, 5])
        pssSymbols = ltePSS(enb);
        pssIndices = ltePSSIndices(enb);
        txGrid(pssIndices) = pssSymbols;

        sssSymbols = lteSSS(enb);
        sssIndices = lteSSSIndices(enb);
        txGrid(sssIndices) = sssSymbols;
    end
    
    % Generate and transmit SIB1
    if mod(enb.NFrame, 8) == 0 && enb.NSubframe == 5
        sib1Msg = generateSIB1(sib1);
        assert(length(sib1Msg) * 8 <= 512, 'SIB1 data exceeds allowed length.');
        enb.PDSCH.PRBSet = (0:5)'; % Limited PRB for SIB1
        sib1Bits = lteBCH(enb, sib1Msg); % BCH channel coding
        sib1Symbols = lteDLSCH(enb, enb.PDSCH, sib1Bits); % Modulation
        pdschIndices = ltePDSCHIndices(enb, enb.PDSCH, enb.PDSCH.PRBSet);
        txGrid(pdschIndices) = sib1Symbols;
    end
    
    % Generate and transmit SIB12
    if mod(enb.NFrame, 32) == 0 && enb.NSubframe == 5
        sib12Msg = generateSIB12(sib12);
        assert(length(sib12Msg) * 8 <= 512, 'SIB12 data exceeds allowed length.');
        enb.PDSCH.PRBSet = (0:5)'; % Limited PRB for SIB12
        sib12Bits = lteBCH(enb, sib12Msg); % BCH channel coding
        sib12Symbols = lteDLSCH(enb, enb.PDSCH, sib12Bits); % Modulation
        pdschIndices = ltePDSCHIndices(enb, enb.PDSCH, enb.PDSCH.PRBSet);
        txGrid(pdschIndices) = sib12Symbols;
    end
    
    % Generate and transmit Paging
    if mod(enb.NFrame, 4) == 0
        pagingMsg = generatePaging(paging);
        assert(length(pagingMsg) * 8 <= 512, 'Paging data exceeds allowed length.');
        enb.PDSCH.PRBSet = (0:5)'; % Limited PRB for Paging
        pagingBits = lteBCH(enb, pagingMsg); % BCH channel coding
        pagingSymbols = lteDLSCH(enb, enb.PDSCH, pagingBits); % Modulation
        pdschIndices = ltePDSCHIndices(enb, enb.PDSCH, enb.PDSCH.PRBSet);
        txGrid(pdschIndices) = pagingSymbols;
    end
    
    % OFDM modulation
    subframeWaveform = lteOFDMModulate(enb, txGrid);
    txWaveform = [txWaveform; subframeWaveform];
end

% Convert the I/Q stream to int16 format
scaledTxWaveform = int16(txWaveform * 32767);

% Export the I/Q stream to a binary file in int16 format
fileID = fopen('lte_iq_stream.bin', 'w');
fwrite(fileID, [real(scaledTxWaveform) imag(scaledTxWaveform)]', 'int16');
fclose(fileID);

disp('I/Q stream has been exported to lte_iq_stream.bin in int16 format.');

На данный момент у меня встали несколько вопросов.
Как правильно внедрить схемы ASN1 в код в матлабе что бы их можно было правильно кодировать?
Где взять полноценные файлы .asn кроме текстовых вставок из спецификаций 3GGP?
Имеет ли смысл работать в TDD если для реализации сигнала не важно какой режим выбран?

В моей голове самый оптимальный вариант это скомпилировать ASN1 структуры в бинарный формат а потом его вплетать в LTE фрейм. Возможно я выбрал не тот подход и всю эту задачу можно гораздо проще осуществить, буду рад любым коментариям и любому техническому обсуждению.
 
UPD!
Для формирования корректного ASN1 сообщения и его последущей компиляции я немного модифицировал код з этого сайта. Буду держать в курсе.

 
UPD2!
Во всей этой ASN1 каше, лучиком света стало творение компании OSS, великий и могучий ASN1 Studio, я понял что редактировать и структурировать спецификации через код матлаба, даже если использовать MEX функции з кодом СИ это гиблое дело (по крайней мере для меня), питоновские либа типа asn1tools хороши, но комерческая софтина просто делает этот процесс легче.

Было решено "запекать" сообщения в бинарный формат uper, з заранее установлеными значениями, а уже потом вплетать их в код матлабы.
 
UPD2!
Во всей этой ASN1 каше, лучиком света стало творение компании OSS, великий и могучий ASN1 Studio, я понял что редактировать и структурировать спецификации через код матлаба, даже если использовать MEX функции з кодом СИ это гиблое дело (по крайней мере для меня), питоновские либа типа asn1tools хороши, но комерческая софтина просто делает этот процесс легче.

Было решено "запекать" сообщения в бинарный формат uper, з заранее установлеными значениями, а уже потом вплетать их в код матлабы.
Здравствуйте!
Как продвигаются дела на данный момент? Тема кажется весьма интересной. Можете ли предоставить частичный PoC?)
 
Частичный возможно скину в ближайшем будущем. Полный код выкладывать на публичный доступ не планировалось, но если интересно, на гите есть наработки з добавленым sib12 в srsRAN, чисто технически ты можешь создать правильную TDD конфигурацию, вывести весь трафик на ZMQ (виртуальное SDR), и уже его просто записать в правильный формат I/Q потока (int8). Все это в бинарь и хакрф_трансфером на саму железку. Так будет проще нежели создавать нужные функции в матлабе используя только документации от 3GGP :)
 
Можно использовать стек srsRAN и Open5GS, тогда CMAS сообщения можно отправлять сразу через cli интерфейс
Но не забывай вначале тебе надо будет подключить окружающие телефоны к своей БС, поднятой на SDR-ке, подделав MCC/MNC, что уже есть нарушение. Далее, так как, в отличии от оператора вы не знаете Ki на сим карте, телефон просто не авторизуется вашей БС и соответственно не увидит ваше широковещетельное CMAS сообщение.
Тут нужно тебе вначале решить вопрос авторизации, а потом уже двигаться дальше. Стек 2G я не рассматриваю ввиду полной устаревшести.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
tenac1ous , gliderexpert
Насколько я понимаю, то для данной "атаки" en1gma ошибается, не нужно кемпить абонентов на свою бску? или я не прав?
Не совсем, надо инициировать процедуру intra-rat handover и в этот момент отправить нужный SIB.
SIBы не шифрованы, поэтому телефон их принимает и обрабатывает еще до этапа авторизации.
 
Не совсем, надо инициировать процедуру intra-rat handover и в этот момент отправить нужный SIB.
SIBы не шифрованы, поэтому телефон их принимает и обрабатывает еще до этапа авторизации.
то есть истина посредине :) и кемпить по сути не надо, но и "бска поднимается"
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Там урезанная БСка может быть, без приемника.
 
Можно попробовать настроить БС в режим так называемой открытой сети без авторизации по АКА, т.е. телефон допускается к сети даже без успешной авторизации. Примерно так работают Emergency call. Но многие телефоны (по моему iPhone так точно) имеют защиту и не подключатся к такой сети.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх