Содержание статьи
- Ищем сплоиты из Python
- Без ТЗ результат ХЗ
- Как устроена либа для питоньего поиска
- As easy as «pip install vulners»
- Пробуем искать
- Linux vulnerability scanner. Без регистрации и SMS
- А мои данные точно никуда не утекут?
- Плагин для Burp Suite
- Зачем нужен плагин
- Автоматизируй это!
- Как задетектить все
- Если ты не пользуешься Burp Suite...
- Outro
INFO
Если ты до этого не сталкивался с Vulners, почитай эту статью. Она даст базовое понимание, о чем вообще речь и зачем нужен Vulners.
Также посмотри этот материал о консольной тулзе для поиска сплоитов getsploit. Мы же займемся более низкоуровневым жонглированием API из Python.
Ищем сплоиты из Python
Чем дальше развивался Vulners, тем больше мы получали писем с просьбами дать описание нашего API.
Конечно, начали мы с самого простого — сделали Swagger. Но вскоре заметили, что даже мы сами, используя свой API, изобретаем велосипеды по два раза в день. Каждый разработчик внутри проекта создал свой враппер, чтобы обращаться к Vulners из своих утилит. В конце концов нас самих достал такой зоопарк, и мы решили унифицировать работу с API хотя бы для Python. Вот так и появился публичный питоний API.
Без ТЗ результат ХЗ
Для начала мы собрали статистику обращений к API и выяснили, что самые часто запрашиваемые функции — это:
- поиск;
- запросы на выгрузку коллекций для локального использования;
- попытки использовать API от Vulners Burp Scanner Plugin;
- переиспользование вызовов утилиты getsploit.
Ну что же, какие вызовы надо реализовать в будущем враппере, стало понятно. Но ведь пользователи Python-библиотек совсем не хотят разбираться, что в какой параметр отправляется (для этого API-либа и нужна). Так что основная задача — сделать API удобным и простым. Время программировать!
Как устроена либа для питоньего поиска
Как и в любом враппере, начали мы с велосипеда — сделали простую обертку на базе requests для того, чтобы обращаться к JSON API.
Тут все просто: создается opener, который потом обрабатывает все запросы твоего приложения в рамках одной сессии. И сюда же вынесены основные URL, чтобы можно было потом добавлять новые пути для запросов.
class Vulners(object):
def __init__(self, proxies=None):
"""
Set default URLs and create session object
:param proxies: {} dict for proxy supporting. Example: {"https": "myproxy.com:3128"}
"""
# Default URL's for the Vulners API
self.__vulners_urls = {
'search': "https://vulners.com/api/v3/search/lucene/",
'software': "https://vulners.com/api/v3/burp/software/",
'id': "https://vulners.com/api/v3/search/id/",
'suggest': "https://vulners.com/api/v3/search/suggest/",
'ai': "https://vulners.com/api/v3/ai/scoretext/",
'archive': "https://vulners.com/api/v3/archive/collection/"
}
# Default search parameters
self.__search_size = 100
# Requests opener
self.__opener = requests.session()
self.__opener.headers = {'User-Agent': 'Vulners Python API %s' % api_version}
if proxies is not None:
if not isinstance(proxies, dict):
raise TypeError("Proxies must be a dict type")
self.__opener.proxies.update(proxies)
Вторым «подкапотным» помощником стали обертки для инициации GET- и POST-запросов. Они просто перекидывают переданный dict по URL из списка, определенного в init.
После получения результата функция adapt_response_content или возвращает dict, сформированный из JSON-ответа сервера, или отдает его в raw-виде в случае не JSON-ответа.
def __vulners_get_request(self, vulners_url_key, json_parameters):
"""
Tech wrapper for the unified
:param vulners_url_key: Key for the self.vulners_urls dict
:param json_parameters: {} dict for the API call
:return: 'data' key from the response
"""
# Return result
response = self.__opener.get(self.__vulners_urls[vulners_url_key], params=json_parameters)
return self.__adapt_response_content(response)
def __vulners_post_request(self, vulners_url_key, json_parameters):
"""
Tech wrapper for the unified
:param vulners_url_key: Key for the self.vulners_urls dict
:param json_parameters: {} dict for the API call
:return: 'data' key from the response
"""
# Return result
response = self.__opener.post(self.__vulners_urls[vulners_url_key], json=json_parameters)
return self.__adapt_response_content(response)
Ты спросишь: разве это лучше, чем самому дергать питоний requests? Ведь с такими вызовами все еще не разобраться без знания API Vulners. И будешь прав. Поэтому мы сделали публичные вызовы-обертки, которые реализуют функциональность Vulners без лишних приседаний.
Вот, например, как выглядит поиск уязвимостей по CPE-строке. И пользователю абсолютно не нужно знать, что и куда потом раскладывается в запросе и в каком виде надо подавать параметры.
def cpeVulnerabilities(self, cpeString):
"""
Find software vulnerabilities using CPE string. See CPE references at https://cpe.mitre.org/specification/
:param cpe: CPE software string, see https://cpe.mitre.org/specification/
:return: {merged by family dict}
"""
dataDocs = {}
if len(cpeString.split(":")) <= 4:
raise ValueError("Malformed CPE string. Please, refer to the https://cpe.mitre.org/specification/. Awaiting like 'cpe:/a:cybozu:garoon:4.2.1'")
version = cpeString.split(":")[4]
results = self.__burpSoftware(cpeString, version, type='cpe')
for element in results.get('search'):
elementData = element.get('_source')
dataDocs[elementData.get('bulletinFamily')] = dataDocs.get(elementData.get('bulletinFamily'), []) + [elementData]
return dataDocs
Соответственно, организация кода внутри библиотеки получилась достаточно прозрачной.
Все методы, доступные без двойного подчеркивания, публичные и организуют запросы на внутренние реализации методов, которые формируют необходимые запросы к API и обеспечивают проверку типизации и контента.
As easy as «pip install vulners»
Но ведь что там под капотом у нас, как это работает, обычно никому не интересно! Библиотека должна дать результат — удобные и практичные вызовы, которые решают поставленные задачи: ищут сплоиты и инфу об уязвимостях. Для того чтобы тебе не пришлось ставить ее руками с GitHub, мы поместили ее в репозиторий PyPI.
Ставим:
pip install -U vulners
И импортируем библиотеку в своем коде:
import vulners
vulners_api = vulners.Vulners()
Вот и все, что тебе понадобится для использования Vulners API. Теперь можно попробовать решить твои задачи, используя этот инструмент.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»