Прослушивание GSM с помощью HackRF
В качестве предисловия хотел бы сказать, что перехват трафика в публичных сетях является незаконным во многих странах, поэтому описанные действия должны применяться только в отношении своей домашней сети или сетей, разрешение на подобную деятельность в которых было получено законным путем.
Не так давно я изучал возможности HackRF по анализу трафика GSM сетей, синхронизирующий сигнал устройства несколько плавает, но в любом случае результатом будет доступ к различным системным сообщениям. Далее я предполагаю, что у вас установлен linux с gnuradio, а также вы являетесь счастливым обладателем hackrf. Если нет, вы можете использовать live cd, информация о котором есть в разделе «Программное обеспечение» форума. Это отличный вариант, когда hackrf работает прямо «из коробки».
Сначала нам необходимо определить частоту местной GSM станции. Для этого я использовал gprx, который включен в состав live cd. После анализа частот в районе 900 МГц вы увидите что-то вроде этого:
Вы можете увидеть постоянные каналы на 952 МГц и на 944.2 МГц. В дальнейшем эти частоты будут отправными точками.
Теперь же с помощью следующих команд мы должны установить Airprobe.
git clone git://git.gnumonks.org/airprobe.git
git clone git://git.gnumonks.org/airprobe.git
cd airprobe/gsmdecode
./bootstrap
./configure
make
cd airprobe/gsm-receiver
./bootstrap
./configure
make
Установка завершена. Теперь мы можем принимать GSM сигнал. Запустим wireshark с помощью команды
В качестве приемного устройства выберите «lo», а в качестве фильтра выберите gsmtap, как показано на следующем рисунке:
Теперь вернитесь в терминал и введите
cd airprobe/gsm-receiver/src/python
./gsm_receive_rtl.py -s 2e6
Откроется всплывающее окно, и вам необходимо будет отключить автоматический сбор, а также перевести слайдер на максимум. Далее вводим GSM частоты, полученные ранее, в качестве средней частоты.
Также выбираем пиковое и среднее значения в секции опций трассировки, как показано далее:
Вы увидите, что только сигнал верной последовательности (синий график) местами выходит за пиковое значение (зеленый график), тем самым показывая, что это постоянный канал. Теперь нужно начать декодирование. В окне нажимаем на середину этого самого частотного скачка. Вы можете увидеть ошибки, но это нормально. Я начал получать данные таким способом:
Теперь вы можете заметить, что gsm-данные приходят в wireshark. Как я упоминал в начале статьи, синхронизирующий сигнал плавает, поэтому для поддержания заданной частоты вам необходимо продолжать кликать на схему. Тем не менее, программа работает довольно хорошо. Как бы смешно это не звучало, но, обернув ваш hack rf в полотенце (или что-то подобное), вы повысите термальную стабильность синхронизирующего сигнала и уменьшите разброс. Сам по себе этот способ наверняка не покажется вам очень полезным, но я думаю, как минимум, он показывает огромный потенциал HackRF.
Источник
Декодируем GSM с RTL-SDR за 30$
Доброе время суток, Хабр!
Мы живем в удивительное предсингулярное время. Технологии развиваются стремительно. То, что несколько лет назад казалось фантастикой, сегодня становится реальностью. Удивительно, но сейчас при наличии компьютера с простым ТВ-тюнером можно принимать координаты самолетов и кораблей, спутниковые снимки, данные метеозондов.
Я не являюсь специалистом в области информационной безопасности, все операции были проделаны исключительно в целях обучения. В данном тексте речь пойдет о том, как произвести декодирование (не дешифрование) GSM-трафика. По традиции вместо эпиграфа:
Статья 138 УК РФ. Нарушение тайны переписки, телефонных переговоров, почтовых, телеграфных или иных сообщений
1. Нарушение тайны переписки, телефонных переговоров, почтовых, телеграфных или иных сообщений граждан — наказывается штрафом в размере до восьмидесяти тысяч рублей или в размере заработной платы или иного дохода осужденного за период до шести месяцев, либо обязательными работами на срок до трехсот шестидесяти часов, либо исправительными работами на срок до одного года.
Основные вехи
- 1991 — опубликованы первые спецификации стандарта GSM.
- 2005 — первое упоминание
в летописяхТВ-тюнеров на чипе E4000. - 2008 — на конференции Black Hat продемонстрирован взлом GSM при помощи SDR-приемника USRP ценой около 1000$.
- 2008 — первый коммит в публичном репозитории Osmocom OpenBSC, реализующем ПО контроллера базовых станций GSM.
- 2008 — первые коммиты в проекте Airprobe. Внимание, по ссылке проблемы с сертификатом.
- 2009 — Карстен Нол демонстрирует способ взлома алгоритма шифрования A5/1.
- 2010 — первый коммит в публичном репозитории проекта OsmocomBB, реализующем стек протоколов GSM на железе обычных телефонов.
- 2010 — презентация Kraken — ПО, позволяющего дешифровать данные GSM, зашифрованные при помощи алгоритма A5/1. Демонстрация производилась при помощи обычного телефона.
- 2013 — В блоге RTL-SDR опубликован мануал по декодированию трафика GSM.
- 2013 — Домонкош Томчаний опубликовал очередной способ взлома GSM.
Перехват
Для перехвата нам понадобятся:
- Сам тюнер на базе E4000. Месторождение этих чипов исчерпано, поэтому цена тюнеров на их базе со временем растет. Остальные чипы тоже годятся, но они не поддерживают диапазон GSM1800/1900.
- 75-омная антенна. Пойдет и штатная от тюнера. Я разместил обычную телевизионную антенну на подоконнике вот таким экстравагантным способом, прокинув USB-удлинитель.
- Машина с установленным дистрибутивом семейства Debian. Убунту подойдет. Я использовал старый ноутбук с Kali Linux, к которому коннектился через ssh по Wi-Fi. Раскочегарить с первой попытки ПО под Федору мне не удалось, я решил особо не ломать голову и поступить как в примере. Грабли №0: если будете делать установочную флэшку с Kali Linux — прочитайте вот это. Unetbootin не создаст рабочего образа.
- Изрядное количество терпения и вот эта инструкция.
Расписано все довольно подробно, я лишь прокомментирую только те грабли, на которые наступил сам.
Грабли №1: не стоит ставить последнюю версию GNURadio. Начиная с версии 3.7.0 меняются пространства имен и собрать ПО не получится. Используйте версию 3.6.5. Также проверяйте ветки в git-репозитории airprobe. Тегами и комментариями там указано с какой версией GNURadio нужно собирать проекты.
Грабли №2: не забудьте поставить dev-пакеты вдобавок ко всем перечисленным.
Грабли №3: найти рабочую частоту GSM с помощью SDRSharp зачастую нелегко. Домонкош Томчаний предлагает для этой цели программу kalibrate-rtl. Она выдаст нечто вроде:
Выбираем канал с амплитудой побольше и запускаем перехват на нем. В консоли появятся байтики GSM-трафика:
Выводы
Пара слов о дешифровании. Для него, судя по всему, помимо 30$ за тюнер, придется потратиться еще на двухтерабайтный винчестер под радужные таблицы. Скрипт для их генерации нашелся в репозитории Airprobe, думается, что и Kraken найти проблемы не составит.
Чем конкретно этот способ интересен? Тем, что на его базе можно строить дешевые, но довольно серьезные универсальные системы перехвата. Ведь есть еще DECT (ссылки не будет, сайт Osmocom DECT временно лежит), который широко применяется в офисах. Шифрование там послабее, а секреты посерьезнее.
Ну и двухфакторная аутентификация теперь под вопросом.
«Неужели все так плохо?» — спросите вы.
Не совсем. 3G-трафик перехватить таким способом пока не удастся — слишком широкая полоса сигнала. Но злоумышленнику никто не запрещает производить перехват в месте, где такого покрытия нет или с постановкой помехи. И прогресс не стоит на месте. Когда железо типа HackRF Jawbreaker станет дешевле и популярнее, перехват 3G на нем не заставит себя долго ждать.
Источник
Снифер своими руками: отслеживание входящего трафика
Попробуем для начала разобраться с самим понятием
снифер. Откуда оно взялось и что это такое? Разберемся с терминологией. Слово sniffer (дословно с английского это можно перевести как «нюхатель») в самом общем смысле суть некое прослушивающее устройство, внедренное в сеть для перехвата передаваемых по ней данных. В некоторой литературе и документации, а также в электронных словарях типа Lingvo, термин sniffer (network sniffer) отождествляется с такими понятиями, как «анализатор сетевого трафика», «анализатор пакетов», «анализатор протоколов», «сетевой анализатор». А в более узком смысле — это ПО, созданное для мониторинга сетевого потока и/или его анализа. Изначально такие программы задумывались в помощь системным администраторам для анализа проблем сети. Но
сниферы, как большинство программного обеспечения для сисадминов, широко распространились и среди хакеров. Ведь такие вещи можно использовать и для перехвата паролей и другой незашифрованной информации, приходящей из сети, и исходящей в Сеть.
Что мы будем делать
Попробуем разобрать один из способов работы
снифера и напишем такую программу сами. Это будет несложная программа без всяких драйверов, работающая в системе Windows 2000 и выше и требующая прав администратора. Такие ограничения, конечно, не вдохновляют, но все же если писать программу не для корыстных целей, то такие условия достаточно приемлемы. В дальнейшем будет ясно, ЧТО и КАК нас ограничивает. Для перехвата входящего трафика нашему
сниферу не потребуются внешний *.sys и *.dll файлы. Будут использоваться исключительно возможности операционной системы. Условимся сразу, что наш
снифер должен отлавливать приходящие пакеты с самым популярным набором протоколов — таких, как IP, TCP, UDP, ICMP, IGMP, GGP, IPv6, ICMPv6.
Пишем простой снифер
Начнем с того, что нам нужно написать снифер, который можно будет настраивать. Сделаем фильтр по протоколу, т.е. не будем пропускать в лог пакеты, не относящиеся к интересующему нас протоколу. Также реализуем возможности записи в лог IP получателя (наш), IP отправителя, имени протокола и длины пакета. В нашей программе, помимо этого, можно будет задавать имя файла лога. Он будет храниться в той же директории, что и наш
снифер. После всего, что мы сделаем, окно нашей программы будет выглядеть так:
Теперь перейдем к рассмотрению кода. Полный исходник нашей программы и ее рабочий вариант можно скачать по ссылке в конце статьи. Напишем программу на Visual C++ 6.0. Выбор этой среды разработки обоснован тем, что она мне по душе.
Начинаем, естественно, с инициализации сокетов. Пусть это будет WinSock 2.2:
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
Затем создаем сам сокет:
SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
Получаем имя нашего локального хоста и информацию о нем:
CHAR szHostName[16];
gethostname(szHostName, sizeof szHostName);
HOSTENT *phe = gethostbyname(szHostName);
SOCKADDR_IN sa;
ZeroMemory(&sa, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = ((struct in_addr*)phe->h_addr_list[0])->s_addr;
Теперь необходимо привязать локальный адрес к нашему сокету:
И, наконец, самое главное — включение режима promiscuous, о котором мы говорили ранее:
DWORD flag = TRUE;
ioctlsocket(s, SIO_RCVALL, &flag);
Здесь мы включаем режим приема всех приходящих из Сети пакетов, указанием в качестве команды сокету SIO_RCVALL. Объявление этой константы находится в заголовочном файле Mstcpip.h. Переменная flag включает и выключает режим (TRUE/FALSE). В документации Microsoft про эту команду сказано следующее:
Enables a socket to receive all IP packets on the network. The socket handle passed to the WSAIoctl function must be of AF_INET address family, SOCK_RAW socket type, and IPPROTO_IP protocol. The socket also must be bound to an explicit local interface, which means that you cannot bind to
INADDR_ANY.
Что в буквальном смысле означает: команда SIO_RCVALL позволяет сокету принимать все IP пакеты из Сети. Дескриптор сокета (в нашем случае это s), переданный в функцию WSAIoctl (мы используем просто ioctlsocket), должен быть из семейства адресов AF_INET (internetwork), тип этого сокета должен быть SOCK_RAW и протокол — IPPROTO_IP. Сокет также должен быть связан с явным локальным интерфейсом, т.е. нельзя его связать просто с INADDR_ANY. Соблюдая эти правила, мы и создаем сокет с дескриптором s. Очень важно понимать, что Raw-сокеты могут принимать множество неожиданных пакетов.
Заметим, что режим promiscuous включается только при активной системной плате или при выходе в Internet. В общем, он возможен, только когда есть какая-либо Сеть, будь то Internet или LAN. Если мы вызовем функцию ioctlsocket с параметром SIO_RCVALL на машине без сети, то получим ошибку.
Теперь попытаемся понять, почему наш снифер требует привилегий администратора. Microsoft пишет по этому поводу следующее:
Setting this ioctl requires Administrator privilege on the local computer. SIO_RCVALL is available in Windows 2000 and later versions of Windows.
Теперь должно быть ясно, что явно требуются привилегии администратора. Также выясняется и то, что команда SIO_RCVALL доступна, начиная с Windows 2000. Если
снифер запустит не администратор, функция bind не даст привязать сокет к локальному адресу. Она возвратит ошибку WSAEACCES (10013 в десятичной системе — не достаточно прав). Причем в MSDN сказано, что можно поднять свои привилегии включением опции сокета SO_EXCLUSIVEADDRUSE:
Possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4 SP4 or later), another application, service, or kernel mode driver is bound to the same address with exclusive access. Such exclusive access is a new feature of Windows NT 4 SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.
Т.е. мы могли бы просто вызвать setsockopt с параметром SO_EXCLUSIVEADDRUSE следующим образом:
BOOL bOptVal = TRUE;
setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&bOptVal, sizeof(BOOL));
Но, поэкспериментировав с этим, я не пришел к положительному результату, т.е. по-прежнему нам требуются привилегии администратора.
Итак, режим promiscuous включен. Как же нам получить входящие IP пакеты? Очевидно, нужно постоянно вызывать функцию recv (в нашем случае) или WSARecv. Но создавать отдельный поток и делать бесконечный цикл было бы не очень удобно. Гораздо лучше для нас использовать асинхронные сокеты. Тем более, что у нас GUI-программа. Впишем следующий вызов функции WSAAsyncSelect в обработчик кнопки «Start» (эта кнопка не будет доступна, пока promiscuous mode не включен):
case IDC_BUTTON_START:
CHAR szFileName[_MAX_FNAME];
GetDlgItemText(hwndDlg, IDC_EDIT_LOG_FILENAME, szFileName, _MAX_FNAME);
hLogFile = CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, 0);
if (hLogFile == INVALID_HANDLE_VALUE) <
//.
> else <
//.
SetFilePointer(hLogFile, 0, NULL, FILE_END);
//Связываем событие FD_READ с окном
WSAAsyncSelect(s, hwndDlg, WM_RECV, FD_READ);
Здесь мы указываем функции, что окну с хендлом hwndDlg нужно отправить сообщение WM_RECV при наступлении события FD_READ для сокета s. Событие FD_READ приходит, когда сокет готов к чтению данных, т.е. когда приходят данные. Сообщение WM_RECV объявим следующим образом:
#define WM_RECV (WM_USER + 1)
В MSDN про вызов функции recv написано следующее:
Once the socket is bound and the ioctl set, calls to the WSARecv or recv functions return IP datagrams passing through the given interface. Note that you must supply a sufficiently large buffer.
Т.е. мы должны предоставить функции recv буффер достаточного размера. В нашем
снифере он будет равен 64 Кб. Теперь напишем обработчик сообщения
WM_RECV:
case WM_RECV:
if (WSAGETSELECTEVENT(lParam) == FD_READ) <
// Буфер размера 64 Кб
CHAR btBuffer[65536];
// Получаем входящие данные
if (recv(s, btBuffer, sizeof(btBuffer), 0) >= sizeof(IPHeader)) <
IPHeader* hdr = (IPHeader*)btBuffer;
// Вычисляем размер. Т.к. в сети принят прямой порядок байт,
// а не обратный, то придется поменять байты местами.
WORD size = (hdr->iph_length iph_length >> 8);
// Записываем данные
WriteFile(hLogFile, «—Packet begin—\r\n», 18, &dwWritten, 0);
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_OPTION_LOG_TARGET_IP) == TRUE) <
IN_ADDR ia;
ia.s_addr = hdr->iph_dest;
CHAR *pszTargetIP = inet_ntoa(ia);
WriteFile(hLogFile, «To: «, 4, &dwWritten, 0);
WriteFile(hLogFile, pszTargetIP, lstrlen(pszTargetIP), &dwWritten, 0);
WriteFile(hLogFile, «\r\n», 2, &dwWritten, 0);
>
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_OPTION_LOG_SENDER_IP) == TRUE) <
IN_ADDR ia;
ia.s_addr = hdr->iph_src;
CHAR *pszSourceIP = inet_ntoa(ia);
WriteFile(hLogFile, «From: «, 6, &dwWritten, 0);
WriteFile(hLogFile, pszSourceIP, lstrlen(pszSourceIP), &dwWritten, 0);
WriteFile(hLogFile, «\r\n», 2, &dwWritten, 0);
>
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_OPTION_WRITE_PROTO_NAME) == TRUE) <
WriteFile(hLogFile, «Protocol: «, 10, &dwWritten, 0);
switch (hdr->iph_protocol) <
case IPPROTO_IP:
WriteFile(hLogFile, «IP\r\n», 4, &dwWritten, 0);
break;
case IPPROTO_ICMP:
WriteFile(hLogFile, «ICMP\r\n», 6, &dwWritten, 0);
break;
case IPPROTO_IGMP:
WriteFile(hLogFile, «IGMP\r\n», 6, &dwWritten, 0);
break;
case IPPROTO_GGP:
WriteFile(hLogFile, «GGP\r\n», 5, &dwWritten, 0);
break;
case IPPROTO_TCP:
WriteFile(hLogFile, «TCP\r\n», 5, &dwWritten, 0);
break;
case IPPROTO_PUP:
WriteFile(hLogFile, «PUP\r\n», 5, &dwWritten, 0);
break;
case IPPROTO_UDP:
WriteFile(hLogFile, «UDP\r\n», 5, &dwWritten, 0);
break;
case IPPROTO_IDP:
WriteFile(hLogFile, «IDP\r\n», 5, &dwWritten, 0);
break;
case IPPROTO_IPV6:
WriteFile(hLogFile, «IPv6\r\n», 6, &dwWritten, 0);
break;
case IPPROTO_ND:
WriteFile(hLogFile, «ND\r\n», 4, &dwWritten, 0);
break;
case IPPROTO_ICLFXBM:
WriteFile(hLogFile, «ICLFXBM\r\n», 9, &dwWritten, 0);
break;
case IPPROTO_ICMPV6:
WriteFile(hLogFile, «ICMPv6\r\n», 8, &dwWritten, 0);
break;
>
>
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_OPTION_WRITE_PACKET_LEN) == TRUE) <
CHAR szTemp[17];
WriteFile(hLogFile, «Packet length: «, 15, &dwWritten, 0);
wsprintf(szTemp, «%d\r\n», size);
WriteFile(hLogFile, szTemp, lstrlen(szTemp), &dwWritten, 0);
>
SetDlgItemInt(hwndDlg, IDC_EDIT_LOG_SIZE, GetFileSize(hLogFile, NULL), FALSE);
>
>
return TRUE;
Здесь, помимо приема пакета, у нас реализован фильтр по протоколу. Нам не составило бы труда реализовать и фильтр по размеру пакета, по IP адресам, но реализацию этих фильтров я оставляю читателю. Заголовок пакета описывается структурой IPHeader. Она выглядит следующим образом:
//Структура заголовка IP-пакета
typedef struct IPHeader <
UCHAR iph_verlen; // версия и длина заголовка
UCHAR iph_tos; // тип сервиса
USHORT iph_length; // длина всего пакета
USHORT iph_id; // Идентификация
USHORT iph_offset; // флаги и смещения
UCHAR iph_ttl; // время жизни пакета
UCHAR iph_protocol; // протокол
USHORT iph_xsum; // контрольная сумма
ULONG iph_src; // IP-адрес отправителя
ULONG iph_dest; // IP-адрес назначения
>IPHeader;
Теперь посмотрим на получившуюся программу в работе. Для тестирования ее работы я решил использовать подключение к интернету, а также виртуальную локальную сеть. Virtual LAN удобно использовать
когда нет реальной LAN, а работу своей программы необходимо протестировать. Виртуальную LAN довольно удобно настраивать с помощью VMware Workstation (у меня версия 5.5.0). Смоделируем локальную сеть путем установки на виртуальную машину системы Windows 2000 Pro. На хост-машине пусть будет Windows XP SP2. После настройки LAN менеджером виртуальных сетей в VMware, получаем локальную сеть из 2-х компьютеров.
Перед тестированием нужно обязательно не забыть выключить Firewall, т.к. он блокирует входящие пакеты. Убедиться в этом можно, пропинговав машины в обе стороны.
Меня всегда интересовало, как выглядит сообщение при его отправке по локальной сети командой net send. Но нельзя забывать о том, что эта команда работает лишь при включенной службе Messenger. Попробуем послать с виртуальной машины (Windows 2000) сообщение на хост машину (Windows XP SP2) «This is my message!».
. и посмотрим в созданные нашим снифером логи:
Среди прочего мусора, мы видим, что сообщение прибыло в 3-ем пакете. А в 4-ом оно, видимо, завершилось.
Теперь попробуем вариант с Internet’ом. Зайдем на сайт www.google.ru и проверим почтовый ящик, находящийся на pop.mail.ru:
Из данного лога видно все HTML-содержимое главной страницы www.google.ru + содержимое *.gif файлов. Также мы видим ответы smtp- и pop3-сервера.
Мы рассмотрели один из самых простых способов создания программ перехвата входящего трафика. Полученные в результате прочтения данной статьи знания можно использовать в различных целях, будь то тестирование своих сетевых программ, наблюдение за кем-либо или просто ради интереса. Теперь мы точно знаем, что Microsoft предоставляет возможности для создания программ данного типа, хотя и с урезанными привилегиями. Но в большинстве случаев этого бывает достаточно для достижения поставленных целей.
Источник