IT-инфраструктура для бизнеса и творчества
Разработка
NTA

Как провести аудит кибербезопасности web-ресурсов компании абсолютно бесплатно и своими силами?

Аудит кибербезопасности внешних web-ресурсов – это процесс проверки на наличие потенциальных уязвимостей web-компонентов сайтов, платформ, которые посещают пользователи из внешней сети интернет.

Выявленные недостатки классифицируются в соответствии с международными подходами к оценке критичности эксплуатации рисков информационной безопасности. Изучением уязвимостей занимается международное некоммерческое сообщество OWASP (Open Web Application Security Project). Более подробно можно почитать на русскоязычном форуме по ссылке.

Существует бесплатный инструмент «Vulners» в виде веб-расширения для браузера (Chrome, Yandex, Edge, Firefox). Он использует пассивный сбор данных о web-сервере и установленных компонентах, анализирует версии и проверяет наличие уязвимостей в базе данных. На сегодня база данных «Vulners» является самым масштабным источником информации об обнаруженных багах веб-компонентов, включает в себя информацию из более чем 100 авторитетных ресурсов в сфере ИБ. Благодаря пассивному анализу, риски влияния на работоспособность исследуемых ресурсов минимальны, и нам не нужно согласовывать свои действия с бизнесом, что значительно упрощает задачу.

Целью проекта было провести оценку уровня защищённости Кибербезопасности web-ресурсов компании и сформировать рекомендации по устранению рисков для отдела, который занимается проверкой информационной безопасности.

Идея была в следующем – список сайтов проверить с помощью Vulners, собрать информацию об уязвимостях, сверить с данными на официальном сайте ФСТЭК России и на основании данных регулятора, сформировать аудиторский отчёт с выводами и рекомендациями по устранению.

Для решения проекта мы использовали язык Python и библиотеки Pandas, Numpy, OS, BeautifulSoup, Selenium.

Функция (def parse_vulners(soup)): выполняет парсинг сайта, результат анализа Vulners

def parse_vulners(soup): data = [] domain_linked_site = soup.find_all("span", {"class":"domain-name amber-text text-darken-4"}) site_names = [str(i).split(">")[1].strip("</span") for i in domain_linked_site] list_vuln = soup.find_all("ul", {"class":"collapsible"}) for num, vuln_block in enumerate(list_vuln): soft_block = vuln_block.find_all("div", {"class":"collapsible-header"}) soft_name = [str(i).split(">")[3].split('<!--')[0] for i in soft_block] version = [str(i).split(">")[7].split('<!--')[0].strip(' - ') for i in soft_block] score = [str(i).split(">")[11].strip('</span') for i in soft_block] text_vuln_codes = vuln_block.find_all("span", {"class": "title"}) codes = [str(i).split(">")[1].strip("</span") for i in text_vuln_codes] text_code_scores = vuln_block.find_all("a", {"class": "secondary-content"}) code_scores = [str(i).split(">")[2].strip("</span") for i in text_code_scores] site_name = site_names[num] for i in range(len(score)): data.append([site_name, soft_name[i], version[i], score[i], find_vuln_code(score[i], codes, code_scores)]) return data

Функция (def get_web_page(url_site)): с помощью Selenium запускает Chrome, активирует расширение (Vulners) и собирает всю информацию со страницы.

def get_web_page(url_site): executable_path = "./chromedriver" os.environ["webdriver.chrome.driver"] = executable_path options = Options() options.add_extension('./extension_2_0_1_0.crx') driver = webdriver.Chrome(executable_path=executable_path, options=options) driver.get(url_site) vulners = driver.get("chrome-extension://dgdelbjijbkahooafjfnonijppnffhmd/index.html") driver.find_element_by_css_selector('.vulners-start-btn.waves-effect.waves-light.btn-large.amber.darken-4').click() soup = BeautifulSoup(driver.page_source, 'html.parser') driver.close() driver.quit() return soup

Основное тело программы:

#считываем список сайтов sites = pd.read_excel('Сводный список.xlsx') list_url = sites['Домен'].values.tolist() #конкатенация строк для проверки сайтов c протоколом https list_url = ["https://"+i for i in not_prepared_2] len(list_url) #создаём DataFrame для заполнения результатов df = pd.DataFrame(columns = ['URL', 'vulner_link', 'Software', 'Soft_version', 'Ratings', 'Vulner_code']) not_preparrr = [] %%time #пробегаем по каждому сайту – Сводный список.xlsx for url_site in list_url: print('Prepare {0}'.format(url_site)) #получаем страницу с результатом на вкладке Vulners page = get_web_page(url_site) try: #проводим поиск необходимой информации (парсим данные) p_soft = parse_vulners(page) #каждую уязвимость для сайта заносим в таблицу for soft in p_soft: row = df.shape[0] df.at[row, 'URL'] = url_site df.at[row, 'vulner_link'] = soft[0] df.at[row, 'Software'] = soft[1] df.at[row, 'Soft_version'] = soft[2] df.at[row, 'Ratings'] = soft[3] df.at[row, 'Vulner_code'] = soft[4] except Exception as e: not_preparrr.append(url_site) print(e) #в случае когда ничего не обнаружено print('Нет уязвимостей для сайта {0}'.format(url_site))

На официальной странице ФСТЭК – «Банк данных угроз безопасности информации» скачиваем файл со сведениями об угрозах. Производим join по уникальному коду уязвимости CVE.

Результатом всех манипуляций получился отчёт в виде сводной таблицы с информацией об уязвимых компонентах и рекомендациях по устранениям недостатков ИБ:

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

(function () { let cdnUrl = `https://specialsf378ef5-a.akamaihd.net/SelectelBranding/images/` let previousArticleNumber = null let currentArticleNumber = 0 let platform = 'Desktop' let articles = [ { name: 'camera', url: `${cdnUrl}CameraCat`, text: 'умную камеру для\u00A0наблюдения за\u00A0котиками', link: 'https://vc.ru/selectel/306690', num: 3 }, { name: 'chill', url: `${cdnUrl}ChillCat`, text: 'трекер, который подскажет, когда пора отдохнуть', link: 'https://vc.ru/promo/288561-eye-tracker', num: 1 }, { name: 'cloud', url: `${cdnUrl}CloudCat`, text: 'котика: даёшь ему «пять», а\u00A0он делает бэкап в облако', link: 'https://vc.ru/dev/294799-maneki-neko', num: 2 } ] let buttonCycle = document.querySelector('.button--cycle') let buttonChoose = document.querySelector('.button--choose') let buttonMobile = document.querySelector('.button--mobile') let textField = document.querySelector('.selectel-footer-subtitle') let imageAgent = document.querySelector('.image--agent') let banner = document.querySelector('.selectel-footer') buttonCycle.addEventListener('click', cycleClick) buttonChoose.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) buttonMobile.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) let media = window.matchMedia("(max-width: 570px)") media.addEventListener('change', matchMedia) function matchMedia() { if (media.matches) { platform = 'Mobile' } else { platform = 'Desktop' } update() } matchMedia() function cycleClick(event) { sendEvent(`Promo ${articles[currentArticleNumber].num} Right`, 'Click') if (event) { event.preventDefault() event.stopPropagation() } window.open('https://vc.ru/tag/selectelDIY', '_blank') //cycle(event) } function cycle(event) { // incrementArticleNumber() textField.innerHTML = generatedText() imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?3' imageAgent.setAttribute("class", "") imageAgent.classList.add('image--agent', articles[currentArticleNumber].name) banner.href = articles[currentArticleNumber].link } function update() { banner.href = articles[currentArticleNumber].link imageAgent.src = articles[currentArticleNumber].url + platform + '.svg' textField.innerHTML = generatedText() } function incrementArticleNumber() { previousArticleNumber = currentArticleNumber if (currentArticleNumber >= articles.length - 1) { currentArticleNumber = 0 } else { currentArticleNumber++ } } const sendEvent = (label, action = 'Click') => { const value = `SelectelDIY — loc: Footer — ${label} — ${action}`; if (window.dataLayer !== undefined) { window.dataLayer.push({ event: 'data_event', data_description: value, }); } }; function generatedText() { let defaultText if (platform === 'Desktop') { defaultText = `Мы тут собрали %text%. Хотите научим?` } else { defaultText = `Мы тут собрали %text%.` } return defaultText.replace('%text%', articles[currentArticleNumber].text) } function getRandom(min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min } (function create() { currentArticleNumber = getRandom(0, articles.length - 1) cycle() let page = document.querySelector('.page--entry') if (page) { function insertAfter() { let parents = page.querySelectorAll('[data-id="7"]') let referenceNode = parents[0] referenceNode.parentNode.insertBefore(banner, referenceNode.nextSibling); loaded() } setTimeout(() => insertAfter(), 0) } }()) function loaded() { banner.classList.add('loaded') } loadImages([ `${cdnUrl}CameraCatDesktop.svg`, `${cdnUrl}ChillCatDesktop.svg`, `${cdnUrl}CloudCatDesktop.svg`, `${cdnUrl}CameraCatMobile.svg`, `${cdnUrl}ChillCatMobile.svg`, `${cdnUrl}CloudCatMobile.svg?3`, ]) function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); } }())
0
0 комментариев
Популярные
По порядку
Читать все 0 комментариев
DiDi впервые показал в России электромобиль для водителей такси

Его представили 7 декабря на форуме «Открытые инновации» в Сколково.

Ozon запустил встроенный в маркетплейс онлайн-кошелёк «Ozon Счёт» Статьи редакции

Им можно оплачивать заказы только на Ozon, пользователям доступен кешбэк.

«Газпромбанк» взял семь номинаций на двух премиях

Редко удается получить сразу несколько наград, а ещё реже получается это сделать на двух премиях сразу. Тем не менее, у нас получилось: стали лауреатами Digital Leaders и «Время инноваций»!

Досудебная претензия к Эльдорадо

Начало сей чудной истории:

Увлечение самолётами, которое переросло в бизнес

Предприниматель из Волгограда производит и продаёт по всему миру симуляторы дополненной реальности.

Что такое контент-план для соцсетей и как с ним работать

Продолжаем разбираться с контентом для бизнеса. Сегодня обсудим контент-план — что это такое, какие задачи решает и почему работает не всегда. В конце статьи разберёмся, как интегрировать в контент-план непредсказуемые инфоповоды

Из компании, где уволили 900 человек одним видеозвонком, ушли три руководителя, а основатель извинился Статьи редакции

Вишал Гарг сказал, что поступил слишком резко, но сокращать людей надо было раньше.

Выступление Вишала Гарга
Сезон подкаста как эксперимент: научили ведущих бегать и отправили на полумарафон. Кейс Sports.ru и adidas
Мне отказано в возврате денег за обучение в geekbrains data scientist, которое ещё не началось

Пишу отзыв про geekbrains. Купила в черную пятницу у них курсы по Datsscientist, курсы куплены в рассрочку, были необходимы, чтобы усилить знания по питону для создания торговых ботов. Но так как в группе не нашлось свободных мест, то старт обучения ближайший БУДЕТ только 27 декабря (встреча с деканом), сами платные модули начнутся 10 января, то…

Как и чем сейчас живут московские рестораны, отмеченные гидом «Мишлен»

Узнали и рассказываем, как повлиял звездный статус на рестораны «Деликатессен» и «Паризьен», и за что их сотрудники получают повышенные чаевые.

null