April 18, 2020

Боевой OSINT s01e01 - OSINT & RDP

Специально для каналов Cybred и Inside

Это первая часть цикла туториалов по боевому OSINT'у, которая охватывает подготовку (техническую и интеллектуальную) и рассказывает как настроить мониторинг уязвимости Bluekeep в больницах с использованием баз данных Shodan и Elasticsearch.

Вступление

Эти учебные пособия дадут вам представление о методах OSINT, используемых киберпреступниками для поиска различных организаций и людей с целью мошенничества и взлома. Это не очередная статья, ведущая на другой сайт с кучей ссылок и описанием того, что они делают, а скорее технические сведения для профессиональных аналитиков безопасности, обладающих хотя бы некоторыми навыками программирования и аналитическим складом ума. Я хотел бы показать каждую область OSINT - социальные сети, Dark Web, утечки, промышленный / корпоративный шпионаж и тому подобное.

Первая статья серии посвящена правильной подготовке, то есть настройке среды, комбинированию нескольких инструментов и установке базы данных. Каждая представленная методика будет поддерживаться исследованиями, и в этой части мы рассмотрим открытые протоколы удаленных рабочих столов с уязвимостью Bluekeep и акцентом на медицинские и финансовые учреждения.

В дополнение к статье я покажу некоторые приемы OSINT & RDP, чтобы найти машины для конкретных шпионских целей, используя Credential Stuffing и обратный поиск по изображениям, так что давайте начнем.

Подготовка

Я чувствую, что о психологической подготовке к OSINT-расследованиям и о том, что вы должны иметь аналитический ум, уметь документировать сведения и строить отношения между ними, уже все было сказано. Конечно, каждое задание в ходе его решения требует своего рода разного мышления, но в момент планирования мы каждый раз должны использовать какой - то общий подход. Лично для меня лучше всего подходит нисходящий подход - исходя из общей идеи, разделить основную цель на более мелкие задачи и сосредоточиться на деталях в конце.

В нашем случае основная цель состоит в том, чтобы найти уязвимые RDP службы в медицинских / финансовых учреждениях, которые могут содержать конфиденциальную информацию, не найденную никем ранее. Чтобы достичь этой цели, нам нужно разбить ее на более мелкие задачи:

  • Получить информацию об открытых RDP
  • Сохранить эту информацию
  • Периодически проверять наличие свежей информации
  • Сравнивать полученные данные с уже имеющимися

Вычленение небольших задач позволяет выбрать конкретные технологии для исследования, а также источники данных. Сейчас мы можем подумать о технических аспектах, таких как тип базы данных (облачная / локальная), язык программирования (включая IDE), сервисы и предпочитаемая операционная система. Давайте трансформируем наши цели в технические требования:

  • Использовать Python и Shodan API для загрузки информации о незащищенных RDP
  • Установить Elasticsearch для хранения данных
  • Использовать Cron для выполнения задач по расписанию
  • Опять же, использовать Python для сравнения новых результатов с уже имеющимися в базе данных

Конечно, есть нечто большее, следующий шаг - определить лучший запрос в Shodan, определить идеальное время проверки и настроить Elasticsearch. Это всего лишь пример, но я использовал этот подход много раз во время исследований или разработки инструментов, и он меня ни разу не подвел.

Мы все разобрали и теперь можем перейти к техническому аспекту.

Техническая подготовка

Эта часть требует базовых навыков работы с терминалом Linux и Python, но если вы их не имеете, не спешите закрывать статью - я все прокомментирую. Давайте начнем с настройки собственной базы данных.

Elasticsearch - это инструмент с открытым исходным кодом для поиска и анализа различных типов данных, включая текстовые, числовые, геопространственные, структурированные и неструктурированные.

Документация делает процесс установки очень простым; сначала нам нужно скачать и установить публичный ключ репозитория

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Установить https-transport:

sudo apt-get install apt-transport-https

Создать файл с информацией о репозитории:

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list

Обновить кэш и устанавить ElasticSearch:

sudo apt-get update && sudo apt-get install elasticsearch

Запустить немедленно Unit elasticsearch.service:

sudo systemctl enable elasticsearch.service –now

Для проверки работоспособности открыть:

http://localhost:9200

Конфигурацию и дальнейший менеджмент вы можете найти здесь.

Python является одним из лучших языков программирования для решения такого рода задач-сценариев, и хорошая IDE может ускорить весь процесс разработки, сделав нашу жизнь намного проще. Я не хочу сказать, что люди пишущие в блокноте неэффективны, но IDE помогает свободно перемещаться по коду и быстро управлять репозиторием. Моя любимая IDE - Pycharm, она создает отдельную виртуальную среду для каждого проекта, поддерживает кастомизацию, несколько терминалов, локальную историю и множество других функций.

Что вы должны знать об этой IDE, так это горячие клавиши. Иногда, когда я работаю с Pycharm, я часами не касаюсь своей мыши - хоткеи ускоряют работу и делает работу чрезвычайно простой. Вот парочка наиболее полезных

2x shift – быстрый поиск по всему проекту
Ctrl + / - закомментировать/раскомментировать текущую строку
Ctrl + Shift + / - закомментировать/раскомментировать выделенный код
Shift + f10 – выполнить код
Shift + f9 – режим отладки
Ctrl + r – замена в тексте
Ctrl + h – история
Alt + f12 – открыть терминал

Вы можете найти их все на сайте Jetbrains.

OSINT & Bluekeep

Импортируем необходимые пакеты в наш проект

from elasticsearch import Elasticsearch
import requests
import json
import email.message
import smtplib

Создадим индекс под названием rdp-monitoring, где мы будем хранить все данные.

es.indices.create(index='rdp-monitoring', ignore=400)

Теперь можно перейти к получению машин с открытым RDP в Shodan.

Несколько переменных, которые мы должны определить

SHODAN_API_KEY = ""
query = "port:3389 org:hospital"
endpoint = "https://api.shodan.io/shodan/host/search?key="+SHODAN_API_KEY+"&query="+query+"&page="
cve = "CVE-2019-0708"
fresh = []

Fresh - это пустой список, который будет содержать новые (свежие) IP-адреса.

И код для извлечения хостов, уязвимых для Bluekeep

try:
    shodan_request = requests.get(endpoint)
    shodan_json = json.loads(shodan_request.text)
    for result in shodan_json['matches']:
        if not exists(result['ip_str']):
            check_each_host = requests.get("https://api.shodan.io/shodan/host/" + result['ip_str'] + "?key=" + SHODAN_API_KEY)
            check_each_host_json = json.loads(check_each_host.content)
            if 'vulns' in check_each_host_json:
                if cve in check_each_host_json['vulns']:
                    fresh.append(result['ip_str'])
                    print("New IP:" + result['ip_str'])
                    es.index(index="rdp-monitoring", id=check_each_host_json['ip_str'], body={"organization": check_each_host_json['org']})
        else:
            print("IP exists")

    if fresh:
        send_notification(fresh)

except Exception as e:
    print(e)

Он отправляет API-запрос в Shodan с текстом «port: 3389 org: hospital» (я не нашел дорки для Bluekeep), перебирает результаты в цикле, а затем делает еще один запрос для проверки каждого хоста на наличие CVE-2019-0708. Shodan не всегда возвращает vulns в общих результатах поиска, поэтому мы должны проверять каждый IP отдельно (check_each_host).

После этого мы проверяем, есть ли какие-либо уязвимости, если да - то содержит ли полученный список наш CVE-2019-0708. Содержит - добавляем его в Elasticsearch.

es.index(index="rdp-monitoring", id=check_each_host_json['ip_str'], body={"organization": check_each_host_json['org']})
Я использую IP-адрес в качестве поля идентификатора для упрощения поиска без использования фильтрации источников.

Скрипт проверяет только первую страницу, на которой около 70 результатов, - вы можете дописать код использующий пагинацию для получения дополнительных результатов.

Итак, мы сохранили IP-адреса и связанные с ними организации в Elasticsearch, но если скрипт будет запущен в следующий раз, он будет должен распознать, какие записи еще не находятся в базе данных. Для этого мы можем написать дополнительную функцию «exists»

def exists(ip):
    try:
        es.get(index='rdp-monitoring', id=ip)
        return True
    except:
     return False

Он просто пытается получить документ на основе индекса и идентификатора, который в нашем случае является IP-адресом. Если запись не существует, происходит ошибка, которую мы обрабатываем и возвращаем False.

Последняя часть состоит в том, чтобы всегда быть в курсе событий и получать сообщения на почту каждый раз, когда скрипт находит новые машины. Для этого нам нужно написать еще одну функцию, которая использует учетную будет использовать учетную запись Gmail и отправлять сообщения

def send_notification(ips):
    body = "<h1>New IPs in hospitals with Bluekeep</h1><br>"
    ips_text = ""
    for ip in ips:
        ips_text = ips_text + "https://beta.shodan.io/host/" + ip + "<br>"
    
    msg = email.message.Message()
    msg['Subject'] = 'RDP Monitoring'
    msg['From'] = "@gmail.com"
    msg['To'] = "@gmail.com"
    msg.add_header('Content-Type', 'text/html')
    msg.set_payload(body + ips_text)
    gmail_user = "@gmail.com"
    gmail_password = ""        
        
        
    try:
        server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
        server.ehlo()
        server.login(gmail_user, gmail_password)
        server.sendmail(msg['From'], [msg['To']], msg.as_string())
        server.close()
        print('Email sent!')
        except Exception as e:
        print(e)
        print('Something went wrong...')
    pass

Это самый простой код, найденный где-то в сети и модифицированный для поддержки text/html контента. По сути, мы просто создаем информационный текст с нашими свежими IP-адресами (сохраненными в новом списке) и отправляем его на заданный адрес электронной почты. Чтобы скрипт корректно работал, вы также должны ввести свой адрес электронной почты и пароль в коде, а также войти в свою учетную запись Gmail в браузере с того же компьютера.

После его запуска, новые записи появятся в Elasticsearch

Вы можете добавить скрипт в Cron или скомбинировать его с другим инструментами в вашем арсенале.

Не только больницы являются интересной целью, запрос «port: 3389 org: bank» вернет вам все машины с открытым RDP в финансовых учреждениях, в названиях которых фигурирует слово «bank». Если пойти еще дальше, то использование свободного текстового поиска и таких слов, как «scada», покажет потенциальные системы промышленного контроля, компрометация которых бесценна.

Credential stuffing & RDP

Единожды скомпрометировав учетные данные пользователя на одном сайте, Credential stuffing предполагает доступ к прочим сервисам, на которых была зарегистрирована жертва, под теми же данными. В большинстве случаев после создания дампа, киберпреступники проверяют пары имя_пользователя/почта:пароль на других популярных платформах, таких как Facebook, Spotify, Netflix и т. д. Это тема была предметом моего исследования в прошлом году, вы можете прочитать больше тут.

Протокол для подключения к удаленному рабочему столу не является исключением, - если пользователь везде использует один и тот же пароль, он должен знать, что единоразовый слив его учетных данных на одном сайте, может привести к компрометации даже его личного ПК. Shodan использует OCR (оптическое распознавание символов) для извлечения текста из изображений и в некоторых случаях распознанный текст с экрана входа включает имена пользователей и версию Windows.

Когда вы ищете RDP для конкретной компании, не забывайте использовать метод свободного текстового поиска, - компьютер может находиться в облаке и отображать имя организации в поле имени пользователя или в предупреждении о безопасности.

APT используют две тактики для получения доступа к сети - концентрация на персонале без технических знаний и знаний в области безопасности (HR'ы, например), выполнение скрытой вредоносной нагрузки без обнаружения и, в самом конце, повышение привилегий.

Ориентация на высокопоставленных лиц (CEO, CISO, старшее руководство) для почти что автоматического получения доступа к конфиденциальным данным зависит от полномочий жертв. Часто киберпреступники отправляют фишинговые электронные письма высшему руководству, например старшим аналитикам и инженерам, которые работают в критических отраслях - в медицине, правительстве, образовании.

HaveIBeenPwned & RDP

Чтобы убедиться в том, стоит ли взламывать какой-либо RDP, основываясь на открытом имени пользователя, нам нужно задействовать OSINT и навыки работы с электронной почтой.

Во-первых, давайте найдем RDP с электронной почтой, используемой в качестве логина для входа в учетную запись. Для этого можно использовать запрос „port:3389 has_screenshot:true 'gmail'”, изменяя gmail на любого другого провайдера электронной почты или компанию. К сожалению, по неизвестным мне причинам, Shodan не может использовать поиск с символом «@», который бы точно указывал на то, что мы ищем именно электронную почту.

Следующий код извлекает адреса электронной почты Gmail из открытых RDP

query = "port:3389 has_screenshot:true gmail"
endpoint = "https://api.shodan.io/shodan/host/search?key="+SHODAN_API_KEY+"&query="+query+"&page="

req = requests.get(endpoint)
req_json = json.loads(req.text)

for match in req_json['matches']:
    text = match['opts']['screenshot']['text'].split("\n")
    for line in text:
        if "@" in line:
            print(line)

Быстрый поиск одного из адресов электронной почты (полученных при выполнении того кода, что я указал выше), показывает нам, что он был скомпрометирован в 7 различных утечках.

Это много, и даже если пароль на каждом сайте уникален, при этом он не был сгенерирован случайным образом, можно найти схему, по которой владелец учетки придумывает пароли на каждый сайт, и угадать его пароль от RDP.

Но стоит ли эксплуатировать эту машину для получения конфиденциальных данных? Нам нужно выяснить, кто является владельцем адреса электронной почты. Быстрый поиск в Google показывает, что это [УДАЛЕНО] инженер, окончивший [УДАЛЕНО].

Это один из способов, как вы можете найти владельца или данные от его учетной записи от RDP, он не автоматизирован и завязан на ручном поиске по нескольким причинам - OCR не всегда все корректно распознает и иногда содержит странные символы, электронная почта может включать «...» вместо домена верхнего уровня, потому что RDP предпочитает не показывать полное имя пользователя, если оно неактивно. В конце концов, результаты должны быть проверены вручную, чтобы определить конечные цели.

Reverse Image search & RDP

Это также необычная техника, о которой я никогда не слышал, - она непременно утомительна, но может окупиться, подтвердив окончательные сомнения. Если на машине не обнаружен какой-либо адрес электронной почты и она не связана с какой-либо организацией, изображение профиля пользователя может помочь вам определить владельца машины и потенциальную ценность с точки зрения наличия секретных документов.

Нам нужно вырезать изображение профиля из скриншота с RDP и попытаться его найти на одном из сервисов обратного поиска по изображениям.

В данном случае мне пришлось проверить фотография сразу на нескольких сервисах для получения нужных результатов. Люди, как и пароли, часто используют одну и ту же свою фотографию на разных сайтах, в особенности на LinkedIn.

Имена пользователей RDP в формате имени и фамилии легче исследовать, - вы должны искать учетные записи в социальных сетях и упоминания в Интернете искомого человека, однако они не всегда уникальны, поэтому такой поиск лучше комбинировать с поиском по изображению. В моем случае, изображения были повторно использованы во многих социальных сетях, поэтому было легко определить, кто является старшим владельцем продукта и генеральным директором финансовой компании.

Заключение

OSINT широко используется не только правоохранительными органами и исследователями, но и киберпреступниками. Под киберпреступниками я подразумеваю актеров, которые нацелены на конкретных людей и компании, чтобы получить как можно большую прибыль - конфиденциальные документы, данные клиентов, интеллектуальную собственность или просто деньги. Зная их методы, вы можете защитить себя и не стать легкой мишенью.

Для исследователей мониторинг незащищенных машин Bluekeep позволяет взглянуть на потенциальные компании, которые в скором времени скопроментируют и предсказать новостные заголовки.

Предоставляя учебные пособия и делясь знаниями, я надеюсь частично покрыть свои медицинские счета. Если вам нравится моя работа и вы используете мои инструменты, пожалуйста, помогите мне, сделав пожертвование на Paypal.


Прочитать оригинал этого материала на английском можно здесь.