Pull to refresh

Как написать сканер уязвимостей и зарабатывать на эксплойтах

Reading time 8 min
Views 17K

TLDR: О том как я уволился с работы безопасника и написал свой сканер уязвимостей.
И как на этом можно заработать. В конце куски кода сканера и спецификация.


Кто и что взламывает


В 1970х, давным-давно, интернет выглядел вот так.



Основную угрозу ему представляли исследователи и энтузиасты первыми добравшиеся до документации и сетей крупных корпораций.


С тех пор интернет сильно изменился. Атаки на сети, сервисы и веб-приложения стали повседневностью. Каждый день разработчики и исследователи находят десятки уязвимостей. Параллельно с этим взламываются десятки тысяч сайтов.


Это хорошо видно на карте атак Лаборатории Касперского. Она отображает срабатывания IDS, сканирования уязвимостей и атаки ботнетов. Выглядит карта как такая красивая картина и на ней миллионы атак в день только по России.




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


Моя карьера сложилась так, что несколько лет я отвечал за безопасность сетевого периметра и защиту веб-приложений. О том, во что вылились мои переживания того периода, я расскажу в этой статье.


Если вы работаете\работали в телекоме, банке, провайдере или вы разработчик в большой компании, а особенно, если вы безопасник, то вы знаете, что безопасность в компании, у которой больше 10-15 сайтов — это треш, ад, погибель.


Давайте попробуем улучшить ситуацию. Говорят, что безопасность это процессы.
И процессов много.


Кратко их перечислю:


  • Threat Management
  • Vulnerability Management
  • Risk Management
  • Patch Management
  • Identity & Acess Management
  • Security Awarness
  • Security Provider Management
    И другие.

Перечисленные виды в статье рассматривать не будем, ура.
Их много, и польза варьируется от размера организации, видов активов и их критичности.


Мы поговорим о процессе, который будет приносить пользу даже для малого бизнеса.
От интернет-магазина с сотней тысяч рублей выручки, до огромной корпорации с десятками дата-центров.


Обнаружение уязвимостей


Для того, чтобы понять какие есть способы нас взломать, давайте посмотрим на себя глазами злоумышленника.


Анализ защищенности состоит из нескольких этапов. Для каждого этапа приведу базовый набор утилит которыми можно воспользоваться.


  • Сбор информации о том, какие IP, домены, подсети есть у нашей цели. Вместо того, чтобы стучаться в парадную дверь, лучше найти менее защищенные точки входа.
    dnsrecon, Fierce, Censys, reverse-PTR-lookup.
  • Анализ сервисов на наличие известных уязвимостей (CVE). Для них часто встречаются публичные эксплойты
    Vulners, exploit-DB, NIST, CVEdetails
  • Анализ сервисов на слабые пароли.
    potator, hydra
  • Анализ веб-приложений на наличие уязвимостей
    Zap, Burp, w3af, Arachni

Круто


Окей, круто. У нас есть способ и инструменты для того, чтобы проверить 1 сайт.
На проверку + разбор одного сервиса уйдет несколько дней, чтобы разобраться досконально — неделя и больше.


Не круто


Проблема в том, что у нас может быть не один сервис. А например /20 подсеть.
4096 адресов. На каждом может быть 65535 сервисов. Не круто.


Да, существуют автоматизированные решения. Qualys, Acunetix, Nessus, есть и отечественные вендоры. Разбор того, чем они хороши и плохи, предлагаю оставить для другой статьи.


Они не решали моих задач. Решил, что надо это исправить. Уволился с работы и примерно год у нас с товарищами ушел на разработку.


Как написать сканер уязвимостей


Начнем с требований к системе которую мы хотели получить:


  • Проводит разведку и находит относящиеся к цели домены и ip
  • Контролирует сетевой периметр. Видит когда в диапазоне появился новый адрес или появился субдомен у защищаемого сайта
  • Постоянно проверяет адреса, видит когда открываются и закрываются сетевые порты
  • Находит уязвимости и известные эксплойты по баннерам/CPE
  • Подбирает слабые пароли
  • Находит ошибки конфигурации приложений и ОС
  • Находит уязвимости в CMS и их плагинах
  • Интерактивно находит XSS, SQLi, XXE, RCE, LFI, RFI и те из OWASP to 10, которые поддаются автоматизированному поиску
  • Делает это не один раз, а постоянно перепроверяет мои ресурсы и реагирует если возникли новые уязвимости сам

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


Для этого используем горизонтально-масштабируемую систему. В неё можно "на лету" добавлять новые ноды и новые типы сканеров. Сейчас сканер использует 7 нод и разделен на 2 взаимодействующие локации в Германии и США. Если интересно, мы напишем про это в другой статье.


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


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


Итак, у нас порядка 20 различных приложений, которые представляют из себя компоненты необходимые для покрытия L3-L7 уровней для автоматизированного пентеста.


Интерфейс для сканера


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


Задумались, что нужно знать любому возможному сканеру чтобы идентифицировать цель. Составили таблицу.


Тип проверки                          Входные данные                       
 Интеграция с базами эксплойтов и CVE Вендор: Продукт: Версия (CPE)          
PoC эксплойт для сервиса              IP, порт, CVE                        
Брутилка                              IP, порт, протокол прикладного уровня
Сканер CMS                            Домен, порт                          
Cканер веб-уязвимостей                Домен или IP, порт                   
PoC веб-уязвимости                    URI                                  
Сканер портов                         IP                                   

После первичной проверки nmap и плагином который обращается к CVEdetails для каждого хоста мы получаем набор таких объектов. Мы называем их Metadata.


JSON-представление:


           {
             "cves": [],
             "service": "mysql",
             "protocol": "tcp",
             "target": "example.com",
             "time": "1513941789",
             "product": "mysql",
             "vendor": "mysql",
             "version": "5.1.63-community",
             "port": 3306,
             "uri": ""
           }

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


У всех сканеров есть родитель — ScanManager, который делает элегантно:


product(scanners, metadata_as_list)

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


Поговорим о том, что представляет из себя Сканер.
Рассматривали три варианта:


  • Реализовать каждый сканер как микросервис, который поддерживает наш RPC
  • Реализовать каждый сканер как сервис и использовать общую шину сообщений
  • Третий вариант

Но мы очень ленивые и поняли, что в случае первых двух вариантов помимо самих сканеров понадобится еще какая-то инфраструктура для деплоя, написание RPC, отлов багов этого RPC. Плюс мы хотели писать все на Python.


Попробовали несколько решений. Посмотрели на похожие проекты по управлению сканерами, такие как Яндексовая Molly и Minion от Mozilla. Посмотрели на то как устроена работа w3af, Zap. У Burp очень интересная plugin architecture.


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


Формат Сканеров


Сканер запускаемый на нашей платформе должен быть объектом, унаследованным от базового класса Scanner.


Любой сканер должен принимать на вход объект типа Metadata и возвращать объекты типа Vulnerability.


class Scanner(object):
   name = "scanner_base"
   vuln_type = "default_vuln_type"
   user_options = {}
   Vulnerability_body_fields_to_web_interface = []

   def __init__(self, opts, target, metadata):
       self.metadata = metadata
       self.opts = opts
       self.target = target

   @staticmetod
   def circuit(Metadata):
       '''
       Логика работы сканера.
       Принимает на вход объекты типа Metadata.
       Результатом работы должны быть экземпляры класса CVE.
       '''
       return [Vulnerability(), Vulnerability()]

   def check_start_condition(self):
       '''
       Проверка параметров, которым должен соответствовать Target для запуска сканера
       True, если сканер должен запуститься. В другом случае False.
       '''
       return True

   class ScannerError(Exception):
       def __init__(self, value):
           self.value = value
       def __str__(self):
           return repr(self.value)

Формат уязвимостей


Следующей задачей, которая стояла перед нами — создать унифицированный формат в котором мы можем хранить вывод любого сканера. Будь то веб-комбайн, брутилка директорий или PoC эксплойт для memcached.


Мы решили не городить своих форматов, а воспользоваться индустриальным стандартом — форматом CVE. Мы обогатим CVE метаданными нашей уязвимости для удобства хранения и поиска. Для хранения сканер-специфичных данных добавим поле body. То, какие ключи из body должны быть отображены в веб-интерфейсе, определяется Scanner.


class Vulnerability(object):
   '''К этому типу должны приводиться все уязвимости перед сохранением
   body хранит специфичные для сканера поля.
   '''
   def __init__(self, target, port, scanner, text, VulnerabilityTypes, Score, protocol,
                UpdateDate=None, scan_date=None, Complexity=None, Access=None, CWEID=None, Authentication=None,
                Integ=None, PublishDate=None, Conf=None, ofExploits=0, Avail=None,
                CVEID=None, references=None, GainedAccessLevel=None, false_positive=False,
                fixed=None, body=None):
       scan_date = scan_date if scan_date is not None else calendar.timegm(gmtime())
       references = references or []
       body = body or {}

       self.name = self.construct_cve_name(VulnerabilityTypes, protocol, target, port, credentials, uri, params)

       self.data = {
           "target" : target,
           "port" : int(port),
           "Scanner": scanner,
           "Scan_date": scan_date,
           "Name": name,
           "UpdateDate": UpdateDate,
           "VulnerabilityTypes": VulnerabilityTypes,
           "Complexity": Complexity,
           "text": text,
           "Access": Access,
           "CWEID": CWEID,
           "Hash": sha1(self.name.encode('utf-8')).hexdigest(),
           "Authentication": Authentication,
           "Integ": Integ,
           "PublishDate": PublishDate,
           "Conf": Conf,
           "ofExploits": ofExploits,
           "Score": Score,
           "Avail": Avail,
           "CVEID": CVEID,
           "References": references,
           "GainedAccessLevel": GainedAccessLevel,
           "FalsePositive": false_positive,
           "Fixed": fixed,
           "Body": body
       }

   @staticmethod
   def construct_cve_name(VulnerabilityTypes, protocol, target, port, credentials, uri, params):
       # vuln_type:host:port:protocol:credentials:uri:params
       return "{}:{}:{}:{}:{}:{}:{}".format(
           VulnerabilityTypes,
           target,
           port,
           protocol,
           credentials,
           uri,
           params)

   def __str__(self):
       return self.data

   def __repr__(self):
       return self.name

Постарались дать авторам сканеров максимум свободы в реализации.
И предлагаем вам поучаствовать в разработке.


Как зарабатывать на эксплойтах.


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


Сканер называется METASCAN. Если у вас есть свои скрипты или 1-day PoC-эксплоты, а может быть вы сами автор сканера. Присылайте нам модули в формате Scanner на david.ordyan@metascan.ru !


Будем выплачивать вознаграждения авторам модулей на ежемесячной основе и объявляем приём модулей до 30го ноября.
Тестировать мы их будем путем прогона по нашей клиентской базе в более чем 2000 сайтов и подсчете количества детектов.


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


  • 31 337 рублей за 1е место.
  • 13 370 рублей за 2е и 3е место.

А также предложим предложим им заключить договора и получать награду за использование их сканеров ежемесячно, до тех пор, пока они будут находить уязвимости.


После ноября расширим программу приема сканеров.


Пишите на david.ordyan@metascan.ru или в TG https://t.me/METASCAN
BB8E 3D9B 04FF 70C9 A260 CD45 E0BF 4EB4 9838 A7EC


Примеры и код будут появляться тут

Tags:
Hubs:
+5
Comments 15
Comments Comments 15

Articles