<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Shadow</title><author><name>Shadow</name></author><id>https://teletype.in/atom/specialist_infosec</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/specialist_infosec?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/specialist_infosec?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-07-28T14:08:00.551Z</updated><entry><id>specialist_infosec:Geolocation-methods-based-on-photos</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Geolocation-methods-based-on-photos?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Методы геолокации по фотографиям: ландшафт, архитектура, растительность, дорожные знаки</title><published>2026-07-26T17:09:06.130Z</published><updated>2026-07-26T17:09:06.130Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/7e/17/7e17bc42-1a04-47c7-9949-3685766252b1.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/bc/92/bc9267cd-9e12-44ff-902c-b1eebd6a5091.png&quot;&gt;Геолокация по фотографии — это искусство и наука определения места съемки на основе визуальных элементов, присутствующих на изображении. В отличие от метаданных (которые могут быть удалены или подделаны), визуальные элементы объективны: архитектура, ландшафт, дорожные знаки, растительность — это то, что можно проверить и сопоставить с известными географическими базами. Данная статья посвящена систематическому анализу визуальных признаков для геолокации.</summary><content type="html">
  &lt;figure id=&quot;ycvY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bc/92/bc9267cd-9e12-44ff-902c-b1eebd6a5091.png&quot; width=&quot;2199&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;mo9O&quot;&gt;Методы геолокации по фотографиям: ландшафт, архитектура, растительность, дорожные знаки&lt;/h3&gt;
  &lt;p id=&quot;ZGPf&quot;&gt;Геолокация по фотографии — это искусство и наука определения места съемки на основе визуальных элементов, присутствующих на изображении. В отличие от метаданных (которые могут быть удалены или подделаны), визуальные элементы объективны: архитектура, ландшафт, дорожные знаки, растительность — это то, что можно проверить и сопоставить с известными географическими базами. Данная статья посвящена систематическому анализу визуальных признаков для геолокации.&lt;/p&gt;
  &lt;p id=&quot;AkHp&quot;&gt;&lt;strong&gt;Уровни геолокации по фотографии&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Ny61&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/67/55/6755f13a-15cc-4bbe-8d6e-bc4f366de76b.png&quot; width=&quot;945&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YlYR&quot;&gt;&lt;strong&gt;Пирамида геолокации&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;KujG&quot;&gt;
    &lt;li id=&quot;MOJ5&quot;&gt;&lt;strong&gt;Язык и письменность&lt;/strong&gt; - Вывески, надписи, реклама.&lt;/li&gt;
    &lt;li id=&quot;IUtx&quot;&gt;&lt;strong&gt;Архитектура&lt;/strong&gt; - Стиль зданий, форма крыш, строительные материалы.&lt;/li&gt;
    &lt;li id=&quot;6LnF&quot;&gt;&lt;strong&gt;Транспорт&lt;/strong&gt; - Типы автомобилей, номера, дорожная разметка.&lt;/li&gt;
    &lt;li id=&quot;ZXvH&quot;&gt;&lt;strong&gt;Инфраструктура&lt;/strong&gt; - Дорожные знаки, фонари, столбы, опоры ЛЭП.&lt;/li&gt;
    &lt;li id=&quot;Sr4m&quot;&gt;&lt;strong&gt;Ландшафт и природа&lt;/strong&gt; - Растительность, рельеф, водоемы.&lt;/li&gt;
    &lt;li id=&quot;JtvV&quot;&gt;&lt;strong&gt;Погода и освещение&lt;/strong&gt; - Солнце, тени, облака.&lt;/li&gt;
    &lt;li id=&quot;agu5&quot;&gt;&lt;strong&gt;Специфические маркеры&lt;/strong&gt; - Флаги, гербы, памятники, таблички.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;mYon&quot;&gt;&lt;strong&gt;Этап 1: Язык и письменность&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;uR5t&quot;&gt;Это самый быстрый и очевидный способ ограничить географию.&lt;/p&gt;
  &lt;p id=&quot;af1v&quot;&gt;&lt;strong&gt;Что искать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;7ANP&quot;&gt;
    &lt;li id=&quot;VbUG&quot;&gt;&lt;strong&gt;Текст на вывесках:&lt;/strong&gt; Магазины, кафе, остановки, указатели.&lt;/li&gt;
    &lt;li id=&quot;b9rW&quot;&gt;&lt;strong&gt;Язык:&lt;/strong&gt; Русский, украинский, английский, китайский, арабский и т.д.&lt;/li&gt;
    &lt;li id=&quot;8yQH&quot;&gt;&lt;strong&gt;Скрипт (алфавит):&lt;/strong&gt; Кириллица, латиница, арабское письмо, иероглифы.&lt;/li&gt;
    &lt;li id=&quot;X8mx&quot;&gt;&lt;strong&gt;Особенности орфографии:&lt;/strong&gt; Буква «і» указывает на украинский, «ğ» - на турецкий.&lt;/li&gt;
    &lt;li id=&quot;Sfvp&quot;&gt;&lt;strong&gt;Политика языков:&lt;/strong&gt; Некоторые страны имеют два официальных языка - это сужает поиск.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;4rOG&quot;&gt;&lt;strong&gt;Примеры:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;aHfU&quot;&gt;
    &lt;li id=&quot;JW4n&quot;&gt;Надпись на украинском и кириллица - Украина.&lt;/li&gt;
    &lt;li id=&quot;hszr&quot;&gt;Латиница с диакритикой (ě, š, č) - Чехия, Словакия, Польша.&lt;/li&gt;
    &lt;li id=&quot;7DXB&quot;&gt;Арабский шрифт - Ближний Восток.&lt;/li&gt;
    &lt;li id=&quot;IWpy&quot;&gt;Иероглифы (упрощенные) - Китай.&lt;/li&gt;
    &lt;li id=&quot;Mgem&quot;&gt;Иероглифы (традиционные) - Тайвань, Гонконг.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;aPs3&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;bwEv&quot;&gt;
    &lt;li id=&quot;epyp&quot;&gt;Google Translate (распознавание незнакомых языков по фото - Google Lens).&lt;/li&gt;
    &lt;li id=&quot;YbcX&quot;&gt;База Unicode, информация о региональных языках.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7kaQ&quot;&gt;&lt;strong&gt;Этап 2: Архитектура&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;vvUn&quot;&gt;Архитектурный стиль региона - один из самых надежных маркеров, так как он меняется медленно.&lt;/p&gt;
  &lt;p id=&quot;ru0F&quot;&gt;&lt;strong&gt;Ключевые элементы архитектуры:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Vgjy&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f8/76/f876bb49-b5b1-4b6d-a769-4f85f81aa701.png&quot; width=&quot;934&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Ji2w&quot;&gt;&lt;strong&gt;Дополнительные признаки:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;Jmxj&quot;&gt;
    &lt;li id=&quot;eaUx&quot;&gt;&lt;strong&gt;Цвет фасадов&lt;/strong&gt; (в Санкт-Петербурге - пастельные тона, в Скандинавии - яркие цвета, в Париже - бежевый камень).&lt;/li&gt;
    &lt;li id=&quot;jkyN&quot;&gt;&lt;strong&gt;Высота зданий&lt;/strong&gt; (в Европе редко бывают небоскребы, в Азии и США - часто).&lt;/li&gt;
    &lt;li id=&quot;J415&quot;&gt;&lt;strong&gt;Элементы отделки&lt;/strong&gt; (лепнина, мозаика, кафель, скульптуры).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Hv0k&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;YICC&quot;&gt;
    &lt;li id=&quot;wzq0&quot;&gt;Google Lens: найти похожую архитектуру в интернете.&lt;/li&gt;
    &lt;li id=&quot;SRhc&quot;&gt;Базы архитектурных стилей (Wikipedia, архитектурные сайты).&lt;/li&gt;
    &lt;li id=&quot;r0JC&quot;&gt;Google Images и Yandex.Images (поиск по фрагментам).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;q53v&quot;&gt;&lt;strong&gt;Этап 3: Транспорт и автомобили&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4FyM&quot;&gt;Автомобили и другие транспортные средства - отличный маркер региона.&lt;/p&gt;
  &lt;p id=&quot;3tcc&quot;&gt;&lt;strong&gt;Ключевые элементы транспорта:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Km7x&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/21/88/2188b309-5fd3-4071-a5d8-127e0d4cdd50.png&quot; width=&quot;947&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qgtK&quot;&gt;&lt;strong&gt;Анализ номерных знаков:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;6usx&quot;&gt;
    &lt;li id=&quot;xIXO&quot;&gt;&lt;strong&gt;Код региона:&lt;/strong&gt; В России и Казахстане региональный код часто включен в номер.&lt;/li&gt;
    &lt;li id=&quot;ZnfA&quot;&gt;&lt;strong&gt;Страна:&lt;/strong&gt; Цвет и формат номеров регулируются законодательством.&lt;/li&gt;
    &lt;li id=&quot;uNdH&quot;&gt;&lt;strong&gt;Цвет фона:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Ni32&quot;&gt;
      &lt;li id=&quot;f9ZW&quot;&gt;Белый - большинство стран.&lt;/li&gt;
      &lt;li id=&quot;wzrC&quot;&gt;Желтый - Великобритания, Люксембург.&lt;/li&gt;
      &lt;li id=&quot;jo0b&quot;&gt;Зеленый - некоторые коммерческие авто в странах ЕС.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;SaVu&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;8gbn&quot;&gt;
    &lt;li id=&quot;hdaU&quot;&gt;&lt;strong&gt;PlateRecognizer&lt;/strong&gt; (распознавание номеров по фото - платное).&lt;/li&gt;
    &lt;li id=&quot;uqHD&quot;&gt;&lt;strong&gt;Таблицы автомобильных номеров&lt;/strong&gt; (поисковые запросы по формату).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;F3EG&quot;&gt;&lt;strong&gt;Этап 4: Дорожные знаки и инфраструктура&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;CQ0j&quot;&gt;Дорожные знаки имеют национальные особенности, хотя и стандартизированы (Венская конвенция).&lt;/p&gt;
  &lt;p id=&quot;fd8L&quot;&gt;&lt;strong&gt;Ключевые признаки дорожных знаков:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;BcwB&quot;&gt;
    &lt;li id=&quot;JrrG&quot;&gt;&lt;strong&gt;Форма:&lt;/strong&gt; Круглые (запрещающие, предписывающие) vs треугольные (предупреждающие).&lt;/li&gt;
    &lt;li id=&quot;qsJt&quot;&gt;&lt;strong&gt;Цвет:&lt;/strong&gt; Красная кайма (запрет), синий фон (предписание, информация).&lt;/li&gt;
    &lt;li id=&quot;Zq99&quot;&gt;&lt;strong&gt;Оформление:&lt;/strong&gt; Шрифт, пиктограммы, наличие надписей на национальном языке.&lt;/li&gt;
    &lt;li id=&quot;KD6c&quot;&gt;&lt;strong&gt;Столбы и фонари:&lt;/strong&gt; Тип и форма фонарных столбов может указывать на страну.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;th4a&quot;&gt;&lt;strong&gt;Примеры:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;yCzo&quot;&gt;
    &lt;li id=&quot;QlVd&quot;&gt;В России знак «Пешеходный переход» - синий квадрат с белым треугольником. В Европе - знак с пешеходом на зебре, часто желтый фон.&lt;/li&gt;
    &lt;li id=&quot;rQky&quot;&gt;В странах ЕС границы стран часто обозначаются синим щитом с желтыми звездами.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;VX3J&quot;&gt;&lt;strong&gt;Этап 5: Ландшафт и растительность&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;AQcz&quot;&gt;Природные особенности - одни из самых сложных, но и самых достоверных маркеров.&lt;/p&gt;
  &lt;figure id=&quot;AI1r&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c6/8b/c68b1682-0594-4c09-ab3e-b4d2c4c31fac.png&quot; width=&quot;947&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;f15T&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;VhRR&quot;&gt;
    &lt;li id=&quot;QDMK&quot;&gt;&lt;strong&gt;Google Lens&lt;/strong&gt; (распознавание растений и деревьев).&lt;/li&gt;
    &lt;li id=&quot;BoaZ&quot;&gt;&lt;strong&gt;iNaturalist&lt;/strong&gt; (определение растений по фото).&lt;/li&gt;
    &lt;li id=&quot;ld3C&quot;&gt;&lt;strong&gt;Спутниковые карты&lt;/strong&gt; (Google Earth, Sentinel).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;qiOa&quot;&gt;&lt;strong&gt;Этап 6: Погода как маркер сезона и климата&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;6ygl&quot;&gt;Погода на фотографии может указывать на сезон и климатическую зону.&lt;/p&gt;
  &lt;figure id=&quot;QBAr&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/61/f5/61f56fd5-d03d-4055-b208-772c6a5b5311.png&quot; width=&quot;723&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IQ9x&quot;&gt;&lt;strong&gt;Этап 7: Специфические маркеры (памятники, флаги, гербы)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;tqfW&quot;&gt;Это самые сильные маркеры, если их удается идентифицировать.&lt;/p&gt;
  &lt;p id=&quot;OhRz&quot;&gt;&lt;strong&gt;Что искать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;vbTH&quot;&gt;
    &lt;li id=&quot;yajD&quot;&gt;&lt;strong&gt;Флаги:&lt;/strong&gt; Государственный флаг часто виден на зданиях, аэродромах.&lt;/li&gt;
    &lt;li id=&quot;H1Ir&quot;&gt;&lt;strong&gt;Гербы:&lt;/strong&gt; На зданиях администрации, на гербовых печатях.&lt;/li&gt;
    &lt;li id=&quot;Wzbl&quot;&gt;&lt;strong&gt;Памятники:&lt;/strong&gt; Статуи, мемориалы, монументы.&lt;/li&gt;
    &lt;li id=&quot;4yT0&quot;&gt;&lt;strong&gt;Вывески с названиями:&lt;/strong&gt; Улицы, города, крупные сети магазинов.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Qrb5&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;RmTd&quot;&gt;
    &lt;li id=&quot;TJun&quot;&gt;&lt;strong&gt;Поиск по изображению (Reverse Image Search):&lt;/strong&gt; Загружаем фото памятника в Google Images.&lt;/li&gt;
    &lt;li id=&quot;VGfI&quot;&gt;&lt;strong&gt;Википедия:&lt;/strong&gt; Поиск по описанию памятника.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;3DNE&quot;&gt;&lt;strong&gt;Практический пример: геолокация сложного фото&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;DDIt&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; Определить место съемки по фотографии, где видны: здание с красной крышей, река с лодками, белая церковь с голубым куполом.&lt;/p&gt;
  &lt;ol id=&quot;iVcQ&quot;&gt;
    &lt;li id=&quot;HVEW&quot;&gt;&lt;strong&gt;Язык:&lt;/strong&gt; Надпись на здании - по-русски. - Россия или страны СНГ.&lt;/li&gt;
    &lt;li id=&quot;YHJc&quot;&gt;&lt;strong&gt;Архитектура:&lt;/strong&gt; Церковь с голубым куполом - православная. Белые стены, голубой купол - характерно для многих регионов, но чаще на севере России.&lt;/li&gt;
    &lt;li id=&quot;EQ66&quot;&gt;&lt;strong&gt;Ландшафт:&lt;/strong&gt; Река, лодки, на заднем плане лесистые холмы - северный регион.&lt;/li&gt;
    &lt;li id=&quot;vCRx&quot;&gt;&lt;strong&gt;Поиск по фрагментам:&lt;/strong&gt; Вывеска на здании - «Гостиница Рыбацкая». Поиск в Яндекс - есть отель с таким названием в городе Петрозаводск.&lt;/li&gt;
    &lt;li id=&quot;205m&quot;&gt;&lt;strong&gt;Сравнение с панорамами:&lt;/strong&gt; Яндекс.Панорамы показывают это здание на набережной Онежского озера в Петрозаводске.&lt;/li&gt;
    &lt;li id=&quot;4Rp2&quot;&gt;&lt;strong&gt;Кросс-референс:&lt;/strong&gt; В новостях Петрозаводска есть упоминания о реке и церкви, совпадающие по описанию.&lt;/li&gt;
    &lt;li id=&quot;I1Rs&quot;&gt;&lt;strong&gt;Результат:&lt;/strong&gt; Координаты: 61.79° N, 34.39° E (Петрозаводск, Россия).&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;zBeW&quot;&gt;&lt;strong&gt;Этап 8: Поиск по уникальным элементам с помощью Google Lens и поисковиков&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;38qO&quot;&gt;Google Lens (мобильное приложение) позволяет сканировать объекты на фото и искать информацию о них. Это часто быстрее, чем вручную искать по тексту.&lt;/p&gt;
  &lt;p id=&quot;RcLF&quot;&gt;&lt;strong&gt;Использование Google Lens:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;sS7c&quot;&gt;
    &lt;li id=&quot;4vNE&quot;&gt;Открыть фото в приложении Google.&lt;/li&gt;
    &lt;li id=&quot;5Nr9&quot;&gt;Обвести объект (вывеску, памятник, здание).&lt;/li&gt;
    &lt;li id=&quot;vMuz&quot;&gt;Посмотреть результаты поиска.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;3qTY&quot;&gt;&lt;strong&gt;Использование Yandex.Images:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;iE0k&quot;&gt;
    &lt;li id=&quot;isKB&quot;&gt;Загрузка фото и поиск по зданиям, вывескам, ландшафту. В русскоязычном сегменте часто точнее Google.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7Wgj&quot;&gt;&lt;strong&gt;Этап 9: Составление карты-подсказки (Mind Map)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;e4Bl&quot;&gt;Для системного анализа полезно создать карту-подсказку:&lt;/p&gt;
  &lt;pre id=&quot;hYUc&quot;&gt;Фото
├── Язык → [страны]
├── Архитектура → [стиль]
├── Транспорт
│   ├── Номера → [страна/регион]
│   └── Тип машин → [эпоха / регион]
├── Ландшафт
│   ├── Растительность → [климатическая зона]
│   └── Водоемы → [регион]
├── Инфраструктура
│   ├── Столбы → [региональный стиль]
│   └── Знаки → [страна]
└── Погода → [сезон]&lt;/pre&gt;
  &lt;p id=&quot;0Y02&quot;&gt;&lt;strong&gt;Инструментарий геолокации (сводная таблица)&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;6KVY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/15/a3/15a34164-0722-42c2-a98a-be3ebd345ad1.png&quot; width=&quot;942&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;pTHr&quot;&gt;&lt;strong&gt;Ошибки при геолокации&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Ow3u&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/39/9a/399af534-eea6-4970-8edf-acbac15a0db4.png&quot; width=&quot;945&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7wjo&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;ynVP&quot;&gt;Геолокация по фотографии — это детективная работа, требующая комбинации знаний из многих областей: географии, архитектуры, лингвистики, ботаники, культурологии. Ключевой принцип — «триангуляция»: никогда не полагаться на один признак. Комбинация языка, архитектуры, транспорта, инфраструктуры и ландшафта позволяет с высокой точностью определить место съемки даже по одному фото.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Introduction-to-GEOINT</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Introduction-to-GEOINT?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Введение в GEOINT: география как источник разведывательных данных</title><published>2026-07-21T16:52:48.615Z</published><updated>2026-07-21T16:52:48.615Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/34/47/344733f0-5796-43aa-8278-7f9420dc072f.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/b6/2e/b62eb4a1-160e-4585-a486-12258a8f332e.png&quot;&gt;Введение в GEOINT: география как источник разведывательных данных</summary><content type="html">
  &lt;figure id=&quot;seQf&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b6/2e/b62eb4a1-160e-4585-a486-12258a8f332e.png&quot; width=&quot;2199&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;23VM&quot;&gt;&lt;strong&gt;Введение в GEOINT: география как источник разведывательных данных&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;mTQR&quot;&gt;Геопространственный OSINT (GEOINT) — это направление открытой разведки, специализирующееся на сборе, анализе и интерпретации географической информации. В отличие от других направлений OSINT, GEOINT оперирует пространственными данными: координатами, картами, спутниковыми снимками, аэрофотосъемкой, панорамами улиц и даже астронавигационными методами. Геолокация по фотографии, анализ изменений на спутниковых снимках, создание собственных интерактивных карт — всё это инструменты GEOINT, которые позволяют исследователю ответить на вопросы «Где?», «Когда?», «Что изменилось?» и «Почему именно здесь?».&lt;/p&gt;
  &lt;p id=&quot;IHaF&quot;&gt;&lt;strong&gt;Что такое GEOINT и чем он отличается от других направлений OSINT?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;cDma&quot;&gt;GEOINT (Geospatial Intelligence) — это дисциплина, которая использует географические данные для поддержки принятия решений. В контексте открытой разведки это означает:&lt;/p&gt;
  &lt;ol id=&quot;edLk&quot;&gt;
    &lt;li id=&quot;w92d&quot;&gt;&lt;strong&gt;Пассивное извлечение географической информации&lt;/strong&gt; из фотографий, видео, спутниковых снимков, карт и других открытых источников.&lt;/li&gt;
    &lt;li id=&quot;MgBp&quot;&gt;&lt;strong&gt;Анализ пространственных взаимосвязей&lt;/strong&gt; между объектами, событиями и местами.&lt;/li&gt;
    &lt;li id=&quot;BvxL&quot;&gt;&lt;strong&gt;Визуализацию данных на картах&lt;/strong&gt; для выявления закономерностей и трендов.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;fezq&quot;&gt;В отличие от транспортного OSINT, где акцент делается на перемещениях и логистике, GEOINT фокусируется на &lt;strong&gt;статической географии&lt;/strong&gt;: место съемки, ландшафт, инфраструктура, изменения во времени.&lt;/p&gt;
  &lt;p id=&quot;oPcz&quot;&gt;&lt;strong&gt;Почему GEOINT важен для расследований?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;k6CV&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/fa/f7/faf7c645-5de6-41af-b1d3-8c51eceb1cfa.png&quot; width=&quot;942&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;UE1p&quot;&gt;&lt;strong&gt;Основные источники данных в GEOINT&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;MNIS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7b/22/7b226aa8-0e80-4645-8c99-1e76f0b59d53.png&quot; width=&quot;943&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;AIZ5&quot;&gt;&lt;strong&gt;Методологическая схема GEOINT-расследования&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;r3lS&quot;&gt;
    &lt;li id=&quot;jbPU&quot;&gt;&lt;strong&gt;Обнаружение контента:&lt;/strong&gt; Найдено фото/видео с неизвестной локацией.&lt;/li&gt;
    &lt;li id=&quot;IbHi&quot;&gt;&lt;strong&gt;Предварительный визуальный осмотр:&lt;/strong&gt; Анализ видимых элементов — архитектура, язык, природа, транспорт.&lt;/li&gt;
    &lt;li id=&quot;LsPy&quot;&gt;&lt;strong&gt;Извлечение метаданных:&lt;/strong&gt; EXIF, GPS, дата съемки (если не удалены).&lt;/li&gt;
    &lt;li id=&quot;S9wY&quot;&gt;&lt;strong&gt;Поиск по изображению (Reverse Image Search):&lt;/strong&gt; Проверка, не публиковалось ли уже это фото с известной геолокацией.&lt;/li&gt;
    &lt;li id=&quot;jmx8&quot;&gt;&lt;strong&gt;Идентификация ключевых ориентиров:&lt;/strong&gt; Уникальные объекты, которые можно найти на карте.&lt;/li&gt;
    &lt;li id=&quot;FhF6&quot;&gt;&lt;strong&gt;Сравнение с картами и панорамами:&lt;/strong&gt; Google Maps, Яндекс.Панорамы, Mapillary.&lt;/li&gt;
    &lt;li id=&quot;0P4F&quot;&gt;&lt;strong&gt;Анализ теней и освещения:&lt;/strong&gt; Определение времени суток и сезона.&lt;/li&gt;
    &lt;li id=&quot;fybs&quot;&gt;&lt;strong&gt;Кросс-референс с другими источниками:&lt;/strong&gt; Метеоданные, новости, соцсети.&lt;/li&gt;
    &lt;li id=&quot;6cKa&quot;&gt;&lt;strong&gt;Формулирование вывода:&lt;/strong&gt; Точные координаты или район съемки, степень уверенности.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;IJaj&quot;&gt;&lt;strong&gt;Ключевые навыки GEOINT-специалиста&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;ERlb&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/38/57/3857672a-b86f-4bfc-9a89-b7793491d0eb.png&quot; width=&quot;940&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JgYI&quot;&gt;&lt;strong&gt; Юридические ограничения и ответственность в GEOINT&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;BosU&quot;&gt;
    &lt;li id=&quot;4EaD&quot;&gt;Анализ спутниковых снимков публичных сервисов (Sentinel, Google Earth) легален.&lt;/li&gt;
    &lt;li id=&quot;5zWC&quot;&gt;Использование коммерческих спутниковых снимков (Maxar, Planet) для расследований допускается, но требует лицензии.&lt;/li&gt;
    &lt;li id=&quot;hBkT&quot;&gt;Геолокация частных лиц без их согласия (по фото из соцсетей) может нарушать законы о персональных данных.&lt;/li&gt;
    &lt;li id=&quot;zf7r&quot;&gt;Публикация точных координат секретных объектов (военные базы, ядерные объекты и объекты стратегического назначения) может быть запрещена законодательством.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;EdZK&quot;&gt;GEOINT — это многогранная дисциплина, объединяющая географию, картографию, спутниковые технологии, анализ визуальных данных и методы верификации. Она позволяет исследователю не просто видеть объект, а понимать его пространственный контекст: где он находится, какова его история, что изменилось вокруг. &lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Technical-OSINT-cases</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Technical-OSINT-cases?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Кейсы технического OSINT: реальные примеры разведки перед пентестом, обнаружения забытых сервисов и выявления уязвимостей</title><published>2026-07-07T21:39:23.373Z</published><updated>2026-07-07T21:39:23.373Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/ab/46/ab46097e-c5b9-4ef9-8607-9610376389a3.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/f8/12/f81263ff-3ff1-428a-a22e-7be2623ecadb.png&quot;&gt;Технический OSINT — это не просто набор инструментов и методик, а практическая дисциплина, которая применяется в реальных сценариях: от оценки безопасности собственной инфраструктуры до разведки конкурентов и расследования инцидентов. Теория без практики мертва. В этой заключительной статье цикла мы разберем несколько реальных кейсов (обезличенных и агрегированных) из практики технической разведки. Каждый кейс демонстрирует применение методов и инструментов, описанных в предыдущих статьях, и показывает, как пассивный сбор данных может привести к обнаружению критических уязвимостей, забытых активов и инсайтов о стратегии организации.</summary><content type="html">
  &lt;figure id=&quot;qg1C&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f8/12/f81263ff-3ff1-428a-a22e-7be2623ecadb.png&quot; width=&quot;2199&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;6ObK&quot;&gt;Кейсы технического OSINT: реальные примеры разведки перед пентестом, обнаружения забытых сервисов и выявления уязвимостей&lt;/h3&gt;
  &lt;p id=&quot;Ar6x&quot;&gt;Технический OSINT — это не просто набор инструментов и методик, а практическая дисциплина, которая применяется в реальных сценариях: от оценки безопасности собственной инфраструктуры до разведки конкурентов и расследования инцидентов. Теория без практики мертва. В этой заключительной статье цикла мы разберем несколько реальных кейсов (обезличенных и агрегированных) из практики технической разведки. Каждый кейс демонстрирует применение методов и инструментов, описанных в предыдущих статьях, и показывает, как пассивный сбор данных может привести к обнаружению критических уязвимостей, забытых активов и инсайтов о стратегии организации.&lt;/p&gt;
  &lt;p id=&quot;WRBs&quot;&gt;&lt;strong&gt;КЕЙС 1: РАЗВЕДКА ПЕРЕД ПЕНТЕСТОМ (ПЛАНОВАЯ ОЦЕНКА ИНФРАСТРУКТУРЫ)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;26IF&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; Компания «Альфа» (вымышленное название) заказала внешний пентест своего интернет-периметра. У команды пентеста есть только домен &lt;code&gt;alpha.com&lt;/code&gt; и разрешение на активное сканирование. Однако перед любыми активными действиями они проводят пассивную разведку, чтобы не пропустить сервисы, которые не сканируются стандартными средствами, и чтобы правильно спланировать нагрузку.&lt;/p&gt;
  &lt;p id=&quot;gj2x&quot;&gt;&lt;strong&gt;Ход работы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;3qFy&quot;&gt;
    &lt;li id=&quot;Vqbd&quot;&gt;&lt;strong&gt;WHOIS-анализ:&lt;/strong&gt; &lt;code&gt;alpha.com&lt;/code&gt; зарегистрирован 15 лет назад, регистратор — Namecheap. Контакты скрыты PrivacyGuard. DNS-серверы: &lt;code&gt;ns1.alpha.com&lt;/code&gt;, &lt;code&gt;ns2.alpha.com&lt;/code&gt;. Это указывает на то, что компания использует собственные DNS-серверы, а значит, возможно, имеет внутреннюю инфраструктуру.&lt;/li&gt;
    &lt;li id=&quot;m1dq&quot;&gt;&lt;strong&gt;DNS-разведка (dig):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;ZySp&quot;&gt;
      &lt;li id=&quot;6ZdV&quot;&gt;&lt;code&gt;A&lt;/code&gt; → &lt;code&gt;192.0.2.10&lt;/code&gt; (основной веб-сервер).&lt;/li&gt;
      &lt;li id=&quot;mnir&quot;&gt;&lt;code&gt;MX&lt;/code&gt; → &lt;code&gt;mail.alpha.com&lt;/code&gt; (приоритет 10), резервный &lt;code&gt;mx.backup.net&lt;/code&gt; (приоритет 20).&lt;/li&gt;
      &lt;li id=&quot;SuOj&quot;&gt;&lt;code&gt;TXT&lt;/code&gt; → &lt;code&gt;v=spf1 include:spf.protection.outlook.com -all&lt;/code&gt; → используется Office 365.&lt;/li&gt;
      &lt;li id=&quot;peKh&quot;&gt;&lt;code&gt;NS&lt;/code&gt; → &lt;code&gt;ns1.alpha.com&lt;/code&gt;, &lt;code&gt;ns2.alpha.com&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;j1pn&quot;&gt;&lt;strong&gt;Поиск поддоменов (crt.sh + SecurityTrails):&lt;/strong&gt; Найдено 45 поддоменов, в том числе:&lt;/li&gt;
    &lt;ul id=&quot;Yv1I&quot;&gt;
      &lt;li id=&quot;wQJR&quot;&gt;&lt;code&gt;www.alpha.com&lt;/code&gt; (основной сайт).&lt;/li&gt;
      &lt;li id=&quot;ItLe&quot;&gt;&lt;code&gt;mail.alpha.com&lt;/code&gt; (почтовый сервер).&lt;/li&gt;
      &lt;li id=&quot;FRmF&quot;&gt;&lt;code&gt;remote.alpha.com&lt;/code&gt; (удалённый доступ, предположительно VPN).&lt;/li&gt;
      &lt;li id=&quot;Fvp1&quot;&gt;&lt;code&gt;jenkins.alpha.com&lt;/code&gt; (система CI/CD).&lt;/li&gt;
      &lt;li id=&quot;Kuxm&quot;&gt;&lt;code&gt;dev.alpha.com&lt;/code&gt; (тестовый поддомен).&lt;/li&gt;
      &lt;li id=&quot;W16P&quot;&gt;&lt;code&gt;old.alpha.com&lt;/code&gt; (старый сайт).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;jEdL&quot;&gt;&lt;strong&gt;Анализ SSL-сертификатов:&lt;/strong&gt; На &lt;code&gt;jenkins.alpha.com&lt;/code&gt; сертификат выдан Let&amp;#x27;s Encrypt, истекает через 10 дней. Это указывает на то, что сервис жив и активно используется (сертификат обновляется). На &lt;code&gt;old.alpha.com&lt;/code&gt; сертификат истёк год назад — возможно, сервис уже неактивен, но всё ещё доступен по IP.&lt;/li&gt;
    &lt;li id=&quot;vg11&quot;&gt;&lt;strong&gt;Shodan/Censys по IP-адресам поддоменов:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;QYpk&quot;&gt;
      &lt;li id=&quot;jr90&quot;&gt;&lt;code&gt;192.0.2.10&lt;/code&gt; (основной сайт) → порты 80, 443. Сканирование баннеров показало Nginx 1.18.0, PHP 7.4.33.&lt;/li&gt;
      &lt;li id=&quot;J3kl&quot;&gt;&lt;code&gt;198.51.100.22&lt;/code&gt; (&lt;a href=&quot;https://jenkins.alpha.com/&quot; target=&quot;_blank&quot;&gt;jenkins.alpha.com&lt;/a&gt;) → порт 8080 открыт, Jenkins 2.289.1 (уязвимая версия, подверженная CVE-2023-23897).&lt;/li&gt;
      &lt;li id=&quot;8d8N&quot;&gt;&lt;code&gt;203.0.113.45&lt;/code&gt; (&lt;a href=&quot;https://mail.alpha.com/&quot; target=&quot;_blank&quot;&gt;mail.alpha.com&lt;/a&gt;) → порты 25, 587, 993 (SMTP, SMTP over TLS, IMAPS).&lt;/li&gt;
      &lt;li id=&quot;ze9z&quot;&gt;&lt;code&gt;198.51.100.88&lt;/code&gt; (&lt;a href=&quot;https://remote.alpha.com/&quot; target=&quot;_blank&quot;&gt;remote.alpha.com&lt;/a&gt;) → порт 443 с сертификатом, но баннер похож на OpenVPN или SSL-прокси.&lt;/li&gt;
      &lt;li id=&quot;aXcx&quot;&gt;&lt;code&gt;192.0.2.50&lt;/code&gt; (&lt;a href=&quot;https://dev.alpha.com/&quot; target=&quot;_blank&quot;&gt;dev.alpha.com&lt;/a&gt;) → порт 22 (SSH), 80, 443. Баннер SSH: OpenSSH 7.9 (устаревший).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;NH9i&quot;&gt;&lt;strong&gt;WHOIS по IP:&lt;/strong&gt; Все IP-адреса принадлежат &lt;code&gt;ALPHA-AS&lt;/code&gt; (AS12345), зарегистрированному в RIPE. Это означает, что компания использует собственные IP-адреса и не полагается на облачных провайдеров для этих сервисов.&lt;/li&gt;
    &lt;li id=&quot;eToZ&quot;&gt;&lt;strong&gt;Технологический стек (Wappalyzer):&lt;/strong&gt; Основной сайт на Drupal 9.5.3 (уязвимый, CVE-2023-XXXX). Используется jQuery 3.6.0, Bootstrap 4.6. Google Analytics ID &lt;code&gt;UA-123456-1&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;HYwj&quot;&gt;&lt;strong&gt;GitHub-поиск:&lt;/strong&gt; Организация &lt;code&gt;alpha-org&lt;/code&gt; имеет несколько публичных репозиториев. Один из них — &lt;code&gt;alpha-backend&lt;/code&gt; — содержит файл &lt;code&gt;.env.example&lt;/code&gt; с реальными паролями (не были заменены на заглушки). В коде встречается строка &lt;code&gt;DB_PASSWORD=AlphaDb2023&lt;/code&gt;.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;upJK&quot;&gt;&lt;strong&gt;Итог кейса:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;ohHW&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/40/71/4071981f-ebfc-4412-bb32-72483070af5b.png&quot; width=&quot;1218&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9fI3&quot;&gt;&lt;strong&gt;Результат:&lt;/strong&gt; Пентест-команда заранее составила карту активов, выявила три критических вектора атаки и спланировала нагрузку на активные сканеры так, чтобы не вызвать сбоев в работе Jenkins и почтового сервера. Обнаруженный пароль был передан клиенту до начала пентеста, что позволило избежать потенциального взлома до тестирования.&lt;/p&gt;
  &lt;p id=&quot;PKtT&quot;&gt;&lt;strong&gt;КЕЙС 2: ОБНАРУЖЕНИЕ ЗАБЫТОГО СЕРВИСА (JENKINS С УЯЗВИМОСТЬЮ)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;y9Tm&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; Сотрудник отдела безопасности компании «Бета» проводит аудит собственной инфраструктуры. Он подозревает, что в сети есть забытые сервисы, которые не отслеживаются централизованно. В компании используется домен &lt;code&gt;beta.ru&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;2z5K&quot;&gt;&lt;strong&gt;Ход работы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;RxaR&quot;&gt;
    &lt;li id=&quot;SQOy&quot;&gt;&lt;strong&gt;Поиск поддоменов через crt.sh:&lt;/strong&gt;&lt;br /&gt;Запрос &lt;code&gt;%.beta.ru&lt;/code&gt; выдает 120 сертификатов. Среди них есть &lt;code&gt;ci.beta.ru&lt;/code&gt;, который не фигурирует во внутренних документах.&lt;/li&gt;
    &lt;li id=&quot;NGxP&quot;&gt;&lt;strong&gt;Проверка доступности (DNS):&lt;/strong&gt;&lt;br /&gt;&lt;code&gt;ci.beta.ru&lt;/code&gt; резолвится в &lt;code&gt;192.168.1.100&lt;/code&gt; (внутренний IP, но компания использует NAT, и этот IP доступен из интернета через публичный адрес). Это явно внутренний сервер, который был случайно опубликован во внешний DNS.&lt;/li&gt;
    &lt;li id=&quot;aXc0&quot;&gt;&lt;strong&gt;Shodan-поиск по IP (публичному адресу):&lt;/strong&gt;&lt;br /&gt;Порт 8080 открыт, баннер: &lt;code&gt;Jenkins 2.263&lt;/code&gt;. Версия Jenkins 2.263 уязвима к CVE-2022-12345 (удалённое выполнение кода через панель управления).&lt;/li&gt;
    &lt;li id=&quot;kEKF&quot;&gt;&lt;strong&gt;Поиск в истории DNS:&lt;/strong&gt; SecurityTrails показывает, что &lt;code&gt;ci.beta.ru&lt;/code&gt; появился 3 года назад и с тех пор не менял IP. Это подтверждает, что сервис был создан для проекта, который давно завершён, но не выведен из эксплуатации.&lt;/li&gt;
    &lt;li id=&quot;a8MR&quot;&gt;&lt;strong&gt;Проверка сертификата:&lt;/strong&gt; Сертификат для &lt;code&gt;ci.beta.ru&lt;/code&gt; выдан Let&amp;#x27;s Encrypt и истекает через 45 дней. Это значит, что сервис всё ещё обслуживается (автоматическое обновление сертификатов), но никто не помнит, зачем он нужен.&lt;/li&gt;
    &lt;li id=&quot;erQL&quot;&gt;&lt;strong&gt;Анализ заголовков:&lt;/strong&gt; HTTP-заголовки показывают &lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;, &lt;code&gt;X-Frame-Options: SAMEORIGIN&lt;/code&gt;, что хорошо, но отсутствует CSP. Сам Jenkins доступен без аутентификации (что подтверждается при открытии страницы в браузере — панель администрирования видна).&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;cOWn&quot;&gt;&lt;strong&gt;Итог кейса:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;A5dX&quot;&gt;
    &lt;li id=&quot;FqpR&quot;&gt;Обнаружен забытый Jenkins-сервер, доступный из интернета с открытой панелью управления.&lt;/li&gt;
    &lt;li id=&quot;wQLi&quot;&gt;Версия Jenkins имеет критическую уязвимость, которая позволяет выполнить произвольные команды на сервере.&lt;/li&gt;
    &lt;li id=&quot;47cn&quot;&gt;Компания «Бета» немедленно закрыла доступ к сервису, ограничив его внутренней сетью, и инициировала процедуру вывода из эксплуатации.&lt;/li&gt;
    &lt;li id=&quot;kpht&quot;&gt;Это предотвратило возможную компрометацию всей инфраструктуры через данный сервер.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;YVq6&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; Даже если вы не проводите активное сканирование, пассивный OSINT (crt.sh, Shodan) может выявить забытые сервисы, о которых не знает даже служба безопасности.&lt;/p&gt;
  &lt;p id=&quot;EW9M&quot;&gt;&lt;strong&gt;КЕЙС 3: РАССЛЕДОВАНИЕ УТЕЧКИ ДАННЫХ ЧЕРЕЗ GITHUB&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;QW1Z&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; В СМИ появилась новость, что компания «Гамма» (домен &lt;code&gt;gamma.tech&lt;/code&gt;) пострадала от утечки данных клиентов. Отдел безопасности должен выяснить, как произошла утечка и какие данные скомпрометированы.&lt;/p&gt;
  &lt;p id=&quot;iaOm&quot;&gt;&lt;strong&gt;Ход работы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;5BN1&quot;&gt;
    &lt;li id=&quot;iRBW&quot;&gt;&lt;strong&gt;Поиск упоминаний компании в GitHub:&lt;/strong&gt;&lt;br /&gt;Использование GitHub Code Search с операторами: &lt;code&gt;&amp;quot;gamma.tech&amp;quot; password&lt;/code&gt;, &lt;code&gt;&amp;quot;gamma.tech&amp;quot; api_key&lt;/code&gt;, &lt;code&gt;&amp;quot;gamma.tech&amp;quot; secret&lt;/code&gt;, &lt;code&gt;&amp;quot;gamma.tech&amp;quot; token&lt;/code&gt;. Найдено 15 файлов, содержащих упоминания домена.&lt;/li&gt;
    &lt;li id=&quot;9Lx2&quot;&gt;&lt;strong&gt;Анализ найденных файлов:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;F9Qp&quot;&gt;
      &lt;li id=&quot;gAGu&quot;&gt;В репозитории &lt;code&gt;gamma-public&lt;/code&gt; есть файл &lt;code&gt;config/database.yml&lt;/code&gt;, содержащий строку: &lt;code&gt;password: GammaDB2023!&lt;/code&gt;. Этот репозиторий был публичным.&lt;/li&gt;
      &lt;li id=&quot;Y3EB&quot;&gt;В другом репозитории &lt;code&gt;gamma-util&lt;/code&gt; в файле &lt;code&gt;creds.py&lt;/code&gt; найден AWS-ключ: &lt;code&gt;aws_access_key_id = &amp;quot;AKIAXXXXXXXXXXXXXXXX&amp;quot;&lt;/code&gt;, &lt;code&gt;aws_secret_access_key = &amp;quot;abcdefghijklmnopqrstuvwxyz1234567890&amp;quot;&lt;/code&gt;. Ключ действителен.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;mPBD&quot;&gt;&lt;strong&gt;Проверка активности ключей:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Pmmt&quot;&gt;
      &lt;li id=&quot;eqUf&quot;&gt;Подключение к AWS CLI с найденным ключом (в безопасной изолированной среде) показывает, что ключ имеет права на чтение S3-бакетов, включая бакет &lt;code&gt;gamma-customer-data&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;43PE&quot;&gt;Список файлов в бакете содержит дампы баз данных с именами клиентов, email-адресами, телефонными номерами и даже хэшированными паролями (но слабый алгоритм хеширования).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;EZiA&quot;&gt;&lt;strong&gt;Поиск других утечек:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;V7uN&quot;&gt;
      &lt;li id=&quot;WBB8&quot;&gt;Использование Dehashed и Leak-Lookup по email-адресам сотрудников показывает, что несколько сотрудников использовали корпоративные email для регистрации на сторонних сервисах, пароли от которых были скомпрометированы.&lt;/li&gt;
      &lt;li id=&quot;S4X0&quot;&gt;Это позволило злоумышленникам получить доступ к внутренним репозиториям и опубликовать их.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;oOC4&quot;&gt;&lt;strong&gt;Восстановление цепочки:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;lOBo&quot;&gt;
      &lt;li id=&quot;0utY&quot;&gt;Один из разработчиков случайно закоммитил файл с паролями в публичный репозиторий.&lt;/li&gt;
      &lt;li id=&quot;keYl&quot;&gt;Злоумышленник нашёл этот файл через поиск по &lt;code&gt;gamma.tech&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;aq6X&quot;&gt;Используя пароль, получил доступ к базе данных и скачал её.&lt;/li&gt;
      &lt;li id=&quot;IfWe&quot;&gt;Также использовал AWS-ключ для доступа к S3-бакетам.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Fqj4&quot;&gt;&lt;strong&gt;Итог кейса:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;Piqe&quot;&gt;
    &lt;li id=&quot;3PA3&quot;&gt;Причина утечки — человеческая ошибка (публикация секретов в открытом репозитории).&lt;/li&gt;
    &lt;li id=&quot;oLfl&quot;&gt;Скомпрометированы данные более 50 000 клиентов.&lt;/li&gt;
    &lt;li id=&quot;8idn&quot;&gt;Компания «Гамма» немедленно:&lt;/li&gt;
    &lt;ul id=&quot;Vw3J&quot;&gt;
      &lt;li id=&quot;gDhN&quot;&gt;Отозвала все скомпрометированные ключи и пароли.&lt;/li&gt;
      &lt;li id=&quot;82q6&quot;&gt;Удалила публичные репозитории с секретами.&lt;/li&gt;
      &lt;li id=&quot;8SAR&quot;&gt;Внедрила политику автоматического сканирования всех публичных репозиториев на наличие секретов с помощью TruffleHog.&lt;/li&gt;
      &lt;li id=&quot;4GZY&quot;&gt;Уведомила регулятора и клиентов об утечке (в соответствии с GDPR).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;p1GB&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; Поиск по открытым репозиториям — обязательный элемент мониторинга безопасности. Даже одна публичная строка с паролем может привести к катастрофической утечке.&lt;/p&gt;
  &lt;p id=&quot;uhJT&quot;&gt;&lt;strong&gt;КЕЙС 4: МОНИТОРИНГ КОНКУРЕНТА (ОБНАРУЖЕНИЕ НОВОГО ПРОДУКТА)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;WWDJ&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; Компания «Дельта» хочет узнать о планах своего конкурента «Эпсилон» по запуску нового сервиса. Конкурент использует домен &lt;code&gt;epsilon.io&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;KEfC&quot;&gt;&lt;strong&gt;Ход работы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;VAKW&quot;&gt;
    &lt;li id=&quot;Xcfx&quot;&gt;&lt;strong&gt;Настройка мониторинга:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;77YR&quot;&gt;
      &lt;li id=&quot;3hwF&quot;&gt;CertSpotter добавлен на домен &lt;code&gt;epsilon.io&lt;/code&gt; и &lt;code&gt;*.epsilon.io&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;krsi&quot;&gt;Ежедневный скрипт проверяет crt.sh на новые сертификаты для &lt;code&gt;epsilon.io&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;wz4w&quot;&gt;&lt;a href=&quot;https://changedetection.io/&quot; target=&quot;_blank&quot;&gt;Changedetection.io&lt;/a&gt; отслеживает главную страницу &lt;code&gt;epsilon.io&lt;/code&gt; и страницу &lt;code&gt;/careers&lt;/code&gt; (появление новых вакансий).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;iLna&quot;&gt;&lt;strong&gt;Обнаружение через 2 недели:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;hWNP&quot;&gt;
      &lt;li id=&quot;xpRC&quot;&gt;CertSpotter отправляет уведомление: новый сертификат для &lt;code&gt;api.epsilon.io&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;UTkb&quot;&gt;Сертификат выдан Let&amp;#x27;s Encrypt, в SAN указаны &lt;code&gt;api.epsilon.io&lt;/code&gt; и &lt;code&gt;*.api.epsilon.io&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;Qjgf&quot;&gt;&lt;strong&gt;Разведка нового поддомена:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;7qym&quot;&gt;
      &lt;li id=&quot;AJbQ&quot;&gt;&lt;code&gt;api.epsilon.io&lt;/code&gt; разрешается в IP &lt;code&gt;52.0.0.123&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;eyOq&quot;&gt;WHOIS показывает, что IP принадлежит AWS (AS14618).&lt;/li&gt;
      &lt;li id=&quot;msxH&quot;&gt;Порт 443 открыт, баннер HTTP содержит заголовок &lt;code&gt;Server: AmazonS3&lt;/code&gt;. Это указывает на статический сайт, размещённый в S3.&lt;/li&gt;
      &lt;li id=&quot;xysO&quot;&gt;Порт 80 тоже открыт, редиректит на 443.&lt;/li&gt;
      &lt;li id=&quot;EbId&quot;&gt;Открыт также порт 3000, на котором виден заголовок &lt;code&gt;X-Powered-By: Express&lt;/code&gt;. Это указывает на Node.js-приложение.&lt;/li&gt;
      &lt;li id=&quot;oRHJ&quot;&gt;Shodan показывает, что порт 3000 доступен, но баннер содержит ошибку 404.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;hByz&quot;&gt;&lt;strong&gt;Анализ контента:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;BVSD&quot;&gt;
      &lt;li id=&quot;kCkt&quot;&gt;Страница &lt;code&gt;https://api.epsilon.io&lt;/code&gt; содержит Swagger-документацию (openapi.json). В ней перечислены эндпоинты для управления заказами, пользователями и платежами.&lt;/li&gt;
      &lt;li id=&quot;gga5&quot;&gt;Это явно новый API-сервис, который ещё не анонсирован.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;xdr1&quot;&gt;&lt;strong&gt;Связь с вакансиями:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;uxJ7&quot;&gt;
      &lt;li id=&quot;9RWs&quot;&gt;На странице &lt;code&gt;/careers&lt;/code&gt; появилась вакансия «Senior Node.js Developer» для работы над «новым облачным продуктом».&lt;/li&gt;
      &lt;li id=&quot;6LW6&quot;&gt;Это подтверждает, что компания запускает новый B2B-сервис.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;uT1c&quot;&gt;&lt;strong&gt;Итог кейса:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;bILw&quot;&gt;
    &lt;li id=&quot;TT5A&quot;&gt;Компания «Дельта» узнала о запуске нового продукта конкурента за месяц до официального анонса.&lt;/li&gt;
    &lt;li id=&quot;XUxw&quot;&gt;Изучив Swagger-документацию, они смогли оценить функционал и скорректировать свою стратегию.&lt;/li&gt;
    &lt;li id=&quot;Nmps&quot;&gt;Информация была передана в стратегический отдел для анализа рынка.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;2h2R&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; Мониторинг новых сертификатов и поддоменов позволяет выявлять неанонсированные проекты и получать рыночное преимущество.&lt;/p&gt;
  &lt;p id=&quot;lTLj&quot;&gt;&lt;strong&gt;КЕЙС 5: ПОИСК СКРЫТЫХ ПОДДОМЕНОВ ЧЕРЕЗ CT-ЛОГИ И WAYBACK MACHINE&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;DfBV&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; Исследователь безопасности ищет все возможные поддомены компании &lt;code&gt;zeta.space&lt;/code&gt; для составления карты инфраструктуры. В DNS и CT-логах есть поддомены &lt;code&gt;www&lt;/code&gt;, &lt;code&gt;mail&lt;/code&gt;, &lt;code&gt;vpn&lt;/code&gt;. Но он подозревает, что есть ещё забытые.&lt;/p&gt;
  &lt;p id=&quot;YhaX&quot;&gt;&lt;strong&gt;Ход работы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;Mwve&quot;&gt;
    &lt;li id=&quot;1K3i&quot;&gt;&lt;strong&gt;crt.sh (стандартный запрос):&lt;/strong&gt; &lt;code&gt;%.zeta.space&lt;/code&gt; даёт 25 результатов, включая те, что уже известны.&lt;/li&gt;
    &lt;li id=&quot;3try&quot;&gt;&lt;strong&gt;Wayback Machine CDX API:&lt;/strong&gt;bashcurl &amp;quot;https://web.archive.org/cdx/search/cdx?url=zeta.space/*&amp;amp;output=json&amp;amp;limit=100000&amp;quot; &amp;gt; all_pages.jsonВ полученном списке страниц исследователь находит упоминания URL &lt;code&gt;staging.zeta.space&lt;/code&gt;, &lt;code&gt;dev.zeta.space&lt;/code&gt;, &lt;code&gt;test.zeta.space&lt;/code&gt;, которые отсутствуют в CT-логах.&lt;/li&gt;
    &lt;li id=&quot;C84S&quot;&gt;&lt;strong&gt;Проверка доступности:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;5ZlC&quot;&gt;
      &lt;li id=&quot;zDc1&quot;&gt;&lt;code&gt;staging.zeta.space&lt;/code&gt; резолвится в &lt;code&gt;203.0.113.77&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;AZUl&quot;&gt;Порт 80 открыт, на нём видна тестовая страница с ошибкой PHP.&lt;/li&gt;
      &lt;li id=&quot;Qks6&quot;&gt;Порт 443 закрыт (сертификата нет).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;54Xy&quot;&gt;&lt;strong&gt;Анализ контента на Wayback Machine:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Weiz&quot;&gt;
      &lt;li id=&quot;j4oV&quot;&gt;Сохранённая копия &lt;code&gt;staging.zeta.space&lt;/code&gt; от 2 лет назад содержит полную структуру каталогов: &lt;code&gt;/admin&lt;/code&gt;, &lt;code&gt;/backup&lt;/code&gt;, &lt;code&gt;/old&lt;/code&gt;. В папке &lt;code&gt;/backup&lt;/code&gt; лежит файл &lt;code&gt;db_backup_2022.sql&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;74dJ&quot;&gt;&lt;strong&gt;Поиск по файлу в Wayback Machine:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;iJO0&quot;&gt;
      &lt;li id=&quot;Kmb9&quot;&gt;Исследователь скачивает &lt;code&gt;db_backup_2022.sql&lt;/code&gt; (через архивную ссылку) и находит в нём email-адреса сотрудников, включая адреса IT-отдела.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;JDmD&quot;&gt;&lt;strong&gt;Использование email для дальнейшей разведки:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;mvLm&quot;&gt;
      &lt;li id=&quot;KrTj&quot;&gt;Через утечки (Dehashed) находится, что один из email использовался на форумах, где пароль был скомпрометирован.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;pO9u&quot;&gt;&lt;strong&gt;Итог кейса:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;3o1X&quot;&gt;
    &lt;li id=&quot;6vHX&quot;&gt;Обнаружены забытые поддомены (&lt;code&gt;staging&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;), которые всё ещё доступны и содержат уязвимые версии ПО.&lt;/li&gt;
    &lt;li id=&quot;VMRd&quot;&gt;Найден дамп базы данных, который может содержать конфиденциальную информацию.&lt;/li&gt;
    &lt;li id=&quot;aZOx&quot;&gt;Получены email-адреса для дальнейшей социальной инженерии или проверки утечек.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;oyqv&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; Wayback Machine — мощный инструмент для обнаружения поддоменов, которые уже не существуют в DNS или CT-логах, но всё ещё могут быть доступны по IP или содержать следы в архивах.&lt;/p&gt;
  &lt;p id=&quot;70Cv&quot;&gt;&lt;strong&gt;КЕЙС 6: КОМПЛЕКСНОЕ РАССЛЕДОВАНИЕ (ПОЛНАЯ КАРТИНА ЗА 1 ЧАС)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;1cxi&quot;&gt;&lt;strong&gt;Исходные данные:&lt;/strong&gt; Аналитик получает задачу: «Что мы знаем о компании &lt;code&gt;omega.tech&lt;/code&gt;?» У него есть только домен.&lt;/p&gt;
  &lt;p id=&quot;gmyF&quot;&gt;&lt;strong&gt;Ход работы (пошагово, с таймингами):&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;8E4D&quot;&gt;
    &lt;li id=&quot;PXk5&quot;&gt;&lt;strong&gt;WHOIS (2 мин):&lt;/strong&gt; &lt;code&gt;omega.tech&lt;/code&gt; зарегистрирован через GoDaddy, дата создания 2015-03-10, NS: &lt;code&gt;ns1.omega.tech&lt;/code&gt;, контакты скрыты.&lt;/li&gt;
    &lt;li id=&quot;1dUE&quot;&gt;&lt;strong&gt;DNS (3 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;X3BW&quot;&gt;
      &lt;li id=&quot;8XIm&quot;&gt;A → &lt;code&gt;54.0.0.10&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;PAbF&quot;&gt;MX → &lt;code&gt;mail.omega.tech&lt;/code&gt; (приоритет 10), &lt;code&gt;mx2.omega.tech&lt;/code&gt; (20).&lt;/li&gt;
      &lt;li id=&quot;7OlB&quot;&gt;TXT → &lt;code&gt;v=spf1 include:_spf.google.com ~all&lt;/code&gt; (использует Google Workspace).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;3UkB&quot;&gt;&lt;strong&gt;Поддомены (crt.sh + SecurityTrails) (5 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;WKBt&quot;&gt;
      &lt;li id=&quot;7L36&quot;&gt;Найдено 30 поддоменов, включая &lt;code&gt;jenkins&lt;/code&gt;, &lt;code&gt;gitlab&lt;/code&gt;, &lt;code&gt;monitoring&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;P6NM&quot;&gt;&lt;strong&gt;Анализ IP и ASN (5 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;ioQB&quot;&gt;
      &lt;li id=&quot;NXnD&quot;&gt;&lt;code&gt;54.0.0.10&lt;/code&gt; принадлежит AWS (AS14618), регион &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;QY1m&quot;&gt;Другие IP поддоменов принадлежат тому же AWS-аккаунту (определено по схожести IP-диапазонов).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;1boF&quot;&gt;&lt;strong&gt;Shodan/Censys по IP (5 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;3ZgT&quot;&gt;
      &lt;li id=&quot;MzWL&quot;&gt;На &lt;code&gt;54.0.0.10&lt;/code&gt;: порты 80, 443 (Nginx 1.20.0, PHP 8.0).&lt;/li&gt;
      &lt;li id=&quot;JCPv&quot;&gt;На &lt;code&gt;54.0.0.22&lt;/code&gt; (jenkins): порт 8080 (Jenkins 2.303, уязвимый).&lt;/li&gt;
      &lt;li id=&quot;RsPE&quot;&gt;На &lt;code&gt;54.0.0.33&lt;/code&gt; (gitlab): порты 80, 443 (GitLab 14.5).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;2Vd0&quot;&gt;&lt;strong&gt;SSL-сертификаты (3 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;cL9J&quot;&gt;
      &lt;li id=&quot;7tY0&quot;&gt;Все сертификаты выданы Let&amp;#x27;s Encrypt, истекают через 20 дней. Это указывает на единую политику управления.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;gsVE&quot;&gt;&lt;strong&gt;Технологический стек (3 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;WVdf&quot;&gt;
      &lt;li id=&quot;0VpO&quot;&gt;Wappalyzer: основной сайт на WordPress 5.9 с плагинами: WooCommerce, Yoast SEO, WP Rocket. Тема — OceanWP.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;UK5t&quot;&gt;&lt;strong&gt;GitHub-поиск (5 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;ZdTT&quot;&gt;
      &lt;li id=&quot;5cXy&quot;&gt;&lt;code&gt;omega.tech&lt;/code&gt; упоминается в 7 репозиториях. В одном из них есть файл &lt;code&gt;.env&lt;/code&gt; с открытым ключом SMTP.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;4v2y&quot;&gt;&lt;strong&gt;Wayback Machine (5 мин):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;s6Y9&quot;&gt;
      &lt;li id=&quot;7ziQ&quot;&gt;Найдена старая версия сайта 2017 года с контактами и старым списком сотрудников.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;Ilyt&quot;&gt;&lt;strong&gt;Сборка карты инфраструктуры (остальное время):&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;wV56&quot;&gt;
      &lt;li id=&quot;J8Vy&quot;&gt;Визуализация в Maltego: домен → IP → ASN → поддомены → сервисы.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;D2aV&quot;&gt;&lt;strong&gt;Итог за 1 час:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;LmNz&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/18/1b18bc6d-9e4c-4a2f-a136-dbd9fb4d3a39.png&quot; width=&quot;1218&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0zcf&quot;&gt;&lt;strong&gt;Принятое решение:&lt;/strong&gt; Команда безопасности немедленно приступила к анализу обнаруженных уязвимостей, а стратегический отдел использовал информацию о технологиях и инфраструктуре для оценки конкурентных рисков.&lt;/p&gt;
  &lt;p id=&quot;lGU6&quot;&gt;&lt;strong&gt;ЭТИЧЕСКИЕ МОМЕНТЫ: ЧТО ДЕЛАТЬ С НАЙДЕННЫМ&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;DYWx&quot;&gt;Каждый из описанных кейсов поднимает этические вопросы. Вот несколько правил:&lt;/p&gt;
  &lt;ol id=&quot;7UDn&quot;&gt;
    &lt;li id=&quot;CmQo&quot;&gt;&lt;strong&gt;Если вы нашли секрет (пароль, ключ), НЕ ИСПОЛЬЗУЙТЕ ЕГО&lt;/strong&gt; для доступа к системе. Сообщите владельцу через официальный канал (security@company.com, программа Bug Bounty). В некоторых случаях можно использовать отчетные платформы (HackerOne, Bugcrowd).&lt;/li&gt;
    &lt;li id=&quot;mJyq&quot;&gt;&lt;strong&gt;Не распространяйте найденные данные.&lt;/strong&gt; Если вы обнаружили дамп базы данных с персональными данными, не копируйте их, не делитесь ими. Просто уведомите владельца.&lt;/li&gt;
    &lt;li id=&quot;iZWm&quot;&gt;&lt;strong&gt;Соблюдайте законы о персональных данных (GDPR, 152-ФЗ).&lt;/strong&gt; В некоторых юрисдикциях даже хранение найденных данных может быть нарушением.&lt;/li&gt;
    &lt;li id=&quot;BG8I&quot;&gt;&lt;strong&gt;Если вы мониторите конкурента в коммерческих целях&lt;/strong&gt;, используйте только публичные источники. Активное сканирование или взлом — это шпионаж и уголовное преступление.&lt;/li&gt;
    &lt;li id=&quot;2jNn&quot;&gt;&lt;strong&gt;В пентесте с разрешением&lt;/strong&gt; — все найденное документируется и передается заказчику. Не используйте уязвимости для получения несанкционированного доступа, даже если они есть.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;B923&quot;&gt;&lt;strong&gt;ЗАКЛЮЧЕНИЕ&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;50bu&quot;&gt;Технический OSINT — это системный подход к сбору информации об инфраструктуре организаций из открытых источников. Шестнадцать статей этого цикла охватили полный спектр: от DNS-разведки и поиска поддоменов до анализа SSL-сертификатов, портов, заголовков, уязвимостей и репозиториев кода. Мы рассмотрели как базовые инструменты (dig, whois, curl, Wappalyzer), так и продвинутые (Amass, Shodan, Censys, TruffleHog, Grafana, Dash). Мы научились автоматизировать сбор данных, строить дашборды и применять полученные знания в реальных кейсах.&lt;/p&gt;
  &lt;p id=&quot;RMbB&quot;&gt;Главные выводы цикла:&lt;/p&gt;
  &lt;ul id=&quot;xxks&quot;&gt;
    &lt;li id=&quot;fIDL&quot;&gt;&lt;strong&gt;Пассивная разведка безопасна и легальна&lt;/strong&gt; (в отличие от активного сканирования), но даёт до 80% информации об инфраструктуре.&lt;/li&gt;
    &lt;li id=&quot;Lxjp&quot;&gt;&lt;strong&gt;Комбинируйте источники&lt;/strong&gt;: DNS, CT-логи, архивы, GitHub, Shodan — каждый добавляет свои уникальные данные.&lt;/li&gt;
    &lt;li id=&quot;tME0&quot;&gt;&lt;strong&gt;Автоматизация — ключ к масштабу&lt;/strong&gt;: ручной сбор годится для одного-двух доменов; для десятков и сотен нужны скрипты.&lt;/li&gt;
    &lt;li id=&quot;Cyqp&quot;&gt;&lt;strong&gt;Интерпретация важнее сбора&lt;/strong&gt;: найденные данные нужно анализировать, визуализировать и применять.&lt;/li&gt;
    &lt;li id=&quot;q9La&quot;&gt;&lt;strong&gt;Этика — основа профессии&lt;/strong&gt;: собранная информация должна использоваться для защиты, а не для атак.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;a0IJ&quot;&gt;Технический OSINT — это не просто навык, а образ мышления, при котором вы видите интернет как гигантскую базу данных, из которой можно извлекать ценную информацию, не нарушая законов и прав других людей.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:BhH2i_kZYn1</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/BhH2i_kZYn1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Создание дашборда для мониторинга инфраструктуры цели</title><published>2026-07-07T21:33:24.114Z</published><updated>2026-07-07T21:33:24.114Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/f2/21/f2211d1a-d72f-46a4-8345-81be1b638bcb.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/f1/7a/f17a6c0e-92d1-4610-8494-88cd300dabe7.png&quot;&gt;После того как все этапы технического OSINT автоматизированы и данные собираются в базу данных, возникает следующая задача: как сделать эту информацию доступной, наглядной и удобной для анализа. Отчёты в виде JSON или CSV хороши для машинной обработки, но для человека визуализация в виде графиков, карт, таблиц и интерактивных панелей значительно эффективнее. Дашборд (dashboard) — это единая панель управления, которая отображает ключевые показатели, изменения в инфраструктуре, новые поддомены, открытые порты, уязвимости и другие данные в реальном времени (или близком к нему). Данная статья посвящена созданию веб-дашборда для мониторинга инфраструктуры цели с использованием открытых инструментов.</summary><content type="html">
  &lt;figure id=&quot;fn07&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f1/7a/f17a6c0e-92d1-4610-8494-88cd300dabe7.png&quot; width=&quot;1099&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;L9sV&quot;&gt;Создание дашборда для мониторинга инфраструктуры цели&lt;/h3&gt;
  &lt;p id=&quot;64EC&quot;&gt;После того как все этапы технического OSINT автоматизированы и данные собираются в базу данных, возникает следующая задача: как сделать эту информацию доступной, наглядной и удобной для анализа. Отчёты в виде JSON или CSV хороши для машинной обработки, но для человека визуализация в виде графиков, карт, таблиц и интерактивных панелей значительно эффективнее. Дашборд (dashboard) — это единая панель управления, которая отображает ключевые показатели, изменения в инфраструктуре, новые поддомены, открытые порты, уязвимости и другие данные в реальном времени (или близком к нему). Данная статья посвящена созданию веб-дашборда для мониторинга инфраструктуры цели с использованием открытых инструментов.&lt;/p&gt;
  &lt;p id=&quot;aLhK&quot;&gt;&lt;strong&gt;Зачем нужен дашборд в техническом OSINT?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;umTR&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/86/1b/861b4f42-c7ad-41dc-a04a-de2b1fc8d476.png&quot; width=&quot;1212&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xvtX&quot;&gt;&lt;strong&gt;Подходы к созданию дашборда&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;IJz6&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/28/f1/28f1681c-0af0-479a-ad9f-81d4f7ec1db2.png&quot; width=&quot;1111&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IL0v&quot;&gt;В этой статье мы рассмотрим два основных подхода:&lt;/p&gt;
  &lt;ol id=&quot;0ICw&quot;&gt;
    &lt;li id=&quot;z4GP&quot;&gt;&lt;strong&gt;Быстрый старт с Grafana&lt;/strong&gt; — минимальная настройка, мощная визуализация.&lt;/li&gt;
    &lt;li id=&quot;yqIF&quot;&gt;&lt;strong&gt;Гибкий дашборд на Python (Dash)&lt;/strong&gt; — полный контроль над данными и интерфейсом.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;LSAX&quot;&gt;&lt;strong&gt;ВАРИАНТ 1: ДАШБОРД НА GRAFANA + SQLITE&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;8b0x&quot;&gt;Grafana — это популярная платформа для мониторинга и визуализации данных. Она поддерживает множество источников данных, включая SQLite, PostgreSQL, Prometheus, Elasticsearch. Для нашего случая SQLite подходит отлично — данные уже хранятся в ней.&lt;/p&gt;
  &lt;p id=&quot;LEt1&quot;&gt;&lt;strong&gt;Архитектура:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;BdHm&quot;&gt;SQLite Database → Grafana (с плагином SQLite) → Дашборд с панелями&lt;/pre&gt;
  &lt;p id=&quot;WhaW&quot;&gt;&lt;strong&gt;Установка Grafana:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;vHzp&quot;&gt;# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y software-properties-common
sudo add-apt-repository &amp;quot;deb https://packages.grafana.com/oss/deb stable main&amp;quot;
sudo apt-get update
sudo apt-get install grafana

# Запуск
sudo systemctl enable grafana-server
sudo systemctl start grafana-server&lt;/pre&gt;
  &lt;p id=&quot;PaYb&quot;&gt;Grafana будет доступна по адресу &lt;code&gt;http://localhost:3000&lt;/code&gt; (логин/пароль по умолчанию: admin/admin).&lt;/p&gt;
  &lt;p id=&quot;ea1L&quot;&gt;&lt;strong&gt;Подключение SQLite к Grafana:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Apic&quot;&gt;Стандартный Grafana не поддерживает SQLite напрямую. Нужно использовать плагин:&lt;/p&gt;
  &lt;ol id=&quot;jF0V&quot;&gt;
    &lt;li id=&quot;VqZE&quot;&gt;Установить плагин &lt;code&gt;grafana-sqlite-datasource&lt;/code&gt;:bashsudo grafana-cli plugins install frser-sqlite-datasource sudo systemctl restart grafana-server&lt;/li&gt;
    &lt;li id=&quot;TgYO&quot;&gt;В веб-интерфейсе Grafana: Configuration → Data Sources → Add data source → SQLite.&lt;/li&gt;
    &lt;ul id=&quot;aswZ&quot;&gt;
      &lt;li id=&quot;GAfP&quot;&gt;Указать путь к файлу БД: &lt;code&gt;/path/to/osint.db&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Yg4b&quot;&gt;&lt;strong&gt;Создание панелей в Grafana:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;HiT8&quot;&gt;&lt;strong&gt;Панель 1: Количество поддоменов за последние 30 дней (гистограмма)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;dMNn&quot;&gt;SELECT 
    DATE(discovered_at) as date,
    COUNT(*) as count
FROM subdomains
WHERE discovered_at &amp;gt; datetime(&amp;#x27;now&amp;#x27;, &amp;#x27;-30 days&amp;#x27;)
GROUP BY DATE(discovered_at)
ORDER BY date ASC&lt;/pre&gt;
  &lt;p id=&quot;dxa2&quot;&gt;&lt;strong&gt;Панель 2: Таблица последних поддоменов&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;x8Lh&quot;&gt;SELECT subdomain, discovered_at
FROM subdomains
ORDER BY discovered_at DESC
LIMIT 20&lt;/pre&gt;
  &lt;p id=&quot;m38b&quot;&gt;&lt;strong&gt;Панель 3: Истекающие сертификаты (таблица)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;DLnK&quot;&gt;SELECT name, valid_to, 
       julianday(valid_to) - julianday(&amp;#x27;now&amp;#x27;) as days_left
FROM certificates
WHERE days_left &amp;lt; 30 AND days_left &amp;gt; 0
ORDER BY days_left ASC&lt;/pre&gt;
  &lt;p id=&quot;wT9Q&quot;&gt;&lt;strong&gt;Панель 4: Распределение открытых портов (круговая диаграмма)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;IYbz&quot;&gt;SELECT port, COUNT(*) as count
FROM shodan_ports
GROUP BY port
ORDER BY count DESC
LIMIT 10&lt;/pre&gt;
  &lt;p id=&quot;Y2ig&quot;&gt;&lt;strong&gt;Grafana преимущества:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;IzpG&quot;&gt;
    &lt;li id=&quot;mdru&quot;&gt;Быстрая настройка, красивые графики &amp;quot;из коробки&amp;quot;.&lt;/li&gt;
    &lt;li id=&quot;2I7e&quot;&gt;Автообновление данных.&lt;/li&gt;
    &lt;li id=&quot;EpLL&quot;&gt;Поддержка алертов (email, Telegram, Slack).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;BwFZ&quot;&gt;&lt;strong&gt;Grafana недостатки:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;3Y8c&quot;&gt;
    &lt;li id=&quot;wAi1&quot;&gt;Ограниченная кастомизация (сложно добавить нестандартную логику).&lt;/li&gt;
    &lt;li id=&quot;OPQk&quot;&gt;Нужно устанавливать плагин для SQLite (или использовать PostgreSQL).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;LqgI&quot;&gt;&lt;strong&gt;ВАРИАНТ 2: ГИБКИЙ ДАШБОРД НА PYTHON (DASH + PLOTLY)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;BtIp&quot;&gt;Dash — это веб-фреймворк от Plotly для создания аналитических дашбордов на Python. Он позволяет полностью контролировать логику обработки данных и визуализацию, не требуя знаний JavaScript.&lt;/p&gt;
  &lt;p id=&quot;fRl6&quot;&gt;&lt;strong&gt;Архитектура:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;WIXY&quot;&gt;SQLite Database → Python (Dash) → Веб-интерфейс (HTML/CSS/JS)&lt;/pre&gt;
  &lt;p id=&quot;abS9&quot;&gt;&lt;strong&gt;Установка зависимостей:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;ERsQ&quot;&gt;pip install dash plotly pandas&lt;/pre&gt;
  &lt;p id=&quot;gDnS&quot;&gt;&lt;strong&gt;Структура проекта:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;vyvA&quot;&gt;dashboard/
├── app.py              # Главный файл приложения
├── data/
│   └── osint.db        # База данных
├── assets/
│   └── style.css       # Стили (опционально)
└── requirements.txt&lt;/pre&gt;
  &lt;p id=&quot;X8in&quot;&gt;&lt;strong&gt;Создание дашборда (app.py):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Bq32&quot;&gt;import dash
from dash import dcc, html, Input, Output, State
import plotly.graph_objects as go
import plotly.express as px
import sqlite3
import pandas as pd
from datetime import datetime, timedelta

# Инициализация приложения
app = dash.Dash(__name__, title=&amp;quot;OSINT Dashboard&amp;quot;)
server = app.server

# Функция подключения к БД
def get_db_connection():
    conn = sqlite3.connect(&amp;#x27;data/osint.db&amp;#x27;)
    conn.row_factory = sqlite3.Row
    return conn

# ============ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ============

def get_subdomain_history(domain=None, days=30):
    &amp;quot;&amp;quot;&amp;quot;Получение истории поддоменов за последние N дней&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    query = &amp;quot;&amp;quot;&amp;quot;
        SELECT DATE(discovered_at) as date, COUNT(*) as count
        FROM subdomains s
        JOIN domains d ON s.domain_id = d.id
        WHERE d.domain = ? AND discovered_at &amp;gt; datetime(&amp;#x27;now&amp;#x27;, &amp;#x27;-&amp;#x27; || ? || &amp;#x27; days&amp;#x27;)
        GROUP BY DATE(discovered_at)
        ORDER BY date ASC
    &amp;quot;&amp;quot;&amp;quot;
    df = pd.read_sql_query(query, conn, params=(domain, days))
    conn.close()
    return df

def get_recent_subdomains(domain=None, limit=20):
    &amp;quot;&amp;quot;&amp;quot;Получение последних поддоменов&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    query = &amp;quot;&amp;quot;&amp;quot;
        SELECT s.subdomain, s.discovered_at
        FROM subdomains s
        JOIN domains d ON s.domain_id = d.id
        WHERE d.domain = ?
        ORDER BY s.discovered_at DESC
        LIMIT ?
    &amp;quot;&amp;quot;&amp;quot;
    df = pd.read_sql_query(query, conn, params=(domain, limit))
    conn.close()
    return df

def get_expiring_certs(domain=None, days=30):
    &amp;quot;&amp;quot;&amp;quot;Получение истекающих сертификатов&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    query = &amp;quot;&amp;quot;&amp;quot;
        SELECT name, issuer, valid_to,
               julianday(valid_to) - julianday(&amp;#x27;now&amp;#x27;) as days_left
        FROM certificates c
        JOIN domains d ON c.domain_id = d.id
        WHERE d.domain = ? AND days_left &amp;lt; ? AND days_left &amp;gt; 0
        ORDER BY days_left ASC
    &amp;quot;&amp;quot;&amp;quot;
    df = pd.read_sql_query(query, conn, params=(domain, days))
    conn.close()
    return df

def get_port_distribution(domain=None):
    &amp;quot;&amp;quot;&amp;quot;Распределение открытых портов&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    query = &amp;quot;&amp;quot;&amp;quot;
        SELECT port, COUNT(*) as count
        FROM shodan_ports sp
        JOIN domains d ON sp.domain_id = d.id
        WHERE d.domain = ?
        GROUP BY port
        ORDER BY count DESC
        LIMIT 15
    &amp;quot;&amp;quot;&amp;quot;
    df = pd.read_sql_query(query, conn, params=(domain,))
    conn.close()
    return df

def get_tech_stack(domain=None):
    &amp;quot;&amp;quot;&amp;quot;Технологический стек&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    # Предположим, есть таблица technologies
    query = &amp;quot;&amp;quot;&amp;quot;
        SELECT tech_name, COUNT(*) as count
        FROM technologies t
        JOIN domains d ON t.domain_id = d.id
        WHERE d.domain = ?
        GROUP BY tech_name
        ORDER BY count DESC
        LIMIT 15
    &amp;quot;&amp;quot;&amp;quot;
    # Если таблицы нет — заглушка
    df = pd.DataFrame({&amp;#x27;tech_name&amp;#x27;: [&amp;#x27;nginx&amp;#x27;, &amp;#x27;PHP&amp;#x27;, &amp;#x27;WordPress&amp;#x27;, &amp;#x27;jQuery&amp;#x27;, &amp;#x27;Bootstrap&amp;#x27;],
                       &amp;#x27;count&amp;#x27;: [1, 1, 1, 1, 1]})
    conn.close()
    return df

def get_all_domains():
    &amp;quot;&amp;quot;&amp;quot;Список всех отслеживаемых доменов&amp;quot;&amp;quot;&amp;quot;
    conn = get_db_connection()
    df = pd.read_sql_query(&amp;quot;SELECT domain FROM domains ORDER BY domain ASC&amp;quot;, conn)
    conn.close()
    return df[&amp;#x27;domain&amp;#x27;].tolist()

# ============ МАКЕТ ДАШБОРДА ============

app.layout = html.Div([
    # Заголовок
    html.H1(&amp;quot;📊 OSINT Infrastructure Dashboard&amp;quot;, style={&amp;#x27;textAlign&amp;#x27;: &amp;#x27;center&amp;#x27;, &amp;#x27;marginBottom&amp;#x27;: 30}),
    
    # Выбор домена
    html.Div([
        html.Label(&amp;quot;Выберите домен:&amp;quot;),
        dcc.Dropdown(
            id=&amp;#x27;domain-selector&amp;#x27;,
            options=[{&amp;#x27;label&amp;#x27;: d, &amp;#x27;value&amp;#x27;: d} for d in get_all_domains()],
            value=&amp;#x27;example.com&amp;#x27; if &amp;#x27;example.com&amp;#x27; in get_all_domains() else get_all_domains()[0] if get_all_domains() else None,
            style={&amp;#x27;width&amp;#x27;: &amp;#x27;50%&amp;#x27;, &amp;#x27;margin&amp;#x27;: &amp;#x27;10px 0&amp;#x27;}
        )
    ], style={&amp;#x27;padding&amp;#x27;: &amp;#x27;0 20px&amp;#x27;}),
    
    # Верхние карточки (метрики)
    html.Div([
        html.Div([
            html.H3(&amp;quot;🌐 Всего поддоменов&amp;quot;),
            html.H2(id=&amp;#x27;total-subdomains&amp;#x27;, style={&amp;#x27;color&amp;#x27;: &amp;#x27;#2196F3&amp;#x27;})
        ], className=&amp;#x27;metric-card&amp;#x27;),
        html.Div([
            html.H3(&amp;quot;🔄 Изменений за 7 дней&amp;quot;),
            html.H2(id=&amp;#x27;changes-7d&amp;#x27;, style={&amp;#x27;color&amp;#x27;: &amp;#x27;#FF9800&amp;#x27;})
        ], className=&amp;#x27;metric-card&amp;#x27;),
        html.Div([
            html.H3(&amp;quot;⏳ Истекающих сертификатов (&amp;lt;30 дн)&amp;quot;),
            html.H2(id=&amp;#x27;expiring-certs&amp;#x27;, style={&amp;#x27;color&amp;#x27;: &amp;#x27;#F44336&amp;#x27;})
        ], className=&amp;#x27;metric-card&amp;#x27;),
        html.Div([
            html.H3(&amp;quot;🔓 Открытых портов&amp;quot;),
            html.H2(id=&amp;#x27;total-ports&amp;#x27;, style={&amp;#x27;color&amp;#x27;: &amp;#x27;#4CAF50&amp;#x27;})
        ], className=&amp;#x27;metric-card&amp;#x27;),
    ], style={&amp;#x27;display&amp;#x27;: &amp;#x27;flex&amp;#x27;, &amp;#x27;gap&amp;#x27;: &amp;#x27;20px&amp;#x27;, &amp;#x27;padding&amp;#x27;: &amp;#x27;0 20px&amp;#x27;, &amp;#x27;flexWrap&amp;#x27;: &amp;#x27;wrap&amp;#x27;}),
    
    # Графики (сетка 2x2)
    html.Div([
        # График 1: История поддоменов
        html.Div([
            dcc.Graph(id=&amp;#x27;subdomain-history&amp;#x27;)
        ], className=&amp;#x27;graph-card&amp;#x27;),
        
        # График 2: Распределение портов
        html.Div([
            dcc.Graph(id=&amp;#x27;port-distribution&amp;#x27;)
        ], className=&amp;#x27;graph-card&amp;#x27;),
        
        # График 3: Истекающие сертификаты
        html.Div([
            dcc.Graph(id=&amp;#x27;cert-expiry&amp;#x27;)
        ], className=&amp;#x27;graph-card&amp;#x27;),
        
        # График 4: Технологический стек
        html.Div([
            dcc.Graph(id=&amp;#x27;tech-stack&amp;#x27;)
        ], className=&amp;#x27;graph-card&amp;#x27;),
    ], style={&amp;#x27;display&amp;#x27;: &amp;#x27;grid&amp;#x27;, &amp;#x27;gridTemplateColumns&amp;#x27;: &amp;#x27;1fr 1fr&amp;#x27;, &amp;#x27;gap&amp;#x27;: &amp;#x27;20px&amp;#x27;, &amp;#x27;padding&amp;#x27;: &amp;#x27;20px&amp;#x27;}),
    
    # Таблица последних поддоменов
    html.Div([
        html.H3(&amp;quot;🆕 Последние поддомены&amp;quot;),
        html.Div(id=&amp;#x27;recent-subdomains-table&amp;#x27;, style={&amp;#x27;overflowX&amp;#x27;: &amp;#x27;auto&amp;#x27;})
    ], style={&amp;#x27;padding&amp;#x27;: &amp;#x27;0 20px&amp;#x27;, &amp;#x27;marginTop&amp;#x27;: 20}),
    
    # Автообновление (раз в 60 секунд)
    dcc.Interval(
        id=&amp;#x27;interval-component&amp;#x27;,
        interval=60 * 1000,  # 60 секунд
        n_intervals=0
    )
], style={&amp;#x27;maxWidth&amp;#x27;: &amp;#x27;1400px&amp;#x27;, &amp;#x27;margin&amp;#x27;: &amp;#x27;0 auto&amp;#x27;, &amp;#x27;fontFamily&amp;#x27;: &amp;#x27;Arial, sans-serif&amp;#x27;})

# ============ КОЛБЭКИ ============

@app.callback(
    [
        Output(&amp;#x27;total-subdomains&amp;#x27;, &amp;#x27;children&amp;#x27;),
        Output(&amp;#x27;changes-7d&amp;#x27;, &amp;#x27;children&amp;#x27;),
        Output(&amp;#x27;expiring-certs&amp;#x27;, &amp;#x27;children&amp;#x27;),
        Output(&amp;#x27;total-ports&amp;#x27;, &amp;#x27;children&amp;#x27;),
        Output(&amp;#x27;subdomain-history&amp;#x27;, &amp;#x27;figure&amp;#x27;),
        Output(&amp;#x27;port-distribution&amp;#x27;, &amp;#x27;figure&amp;#x27;),
        Output(&amp;#x27;cert-expiry&amp;#x27;, &amp;#x27;figure&amp;#x27;),
        Output(&amp;#x27;tech-stack&amp;#x27;, &amp;#x27;figure&amp;#x27;),
        Output(&amp;#x27;recent-subdomains-table&amp;#x27;, &amp;#x27;children&amp;#x27;),
    ],
    [Input(&amp;#x27;domain-selector&amp;#x27;, &amp;#x27;value&amp;#x27;),
     Input(&amp;#x27;interval-component&amp;#x27;, &amp;#x27;n_intervals&amp;#x27;)]
)
def update_dashboard(domain, n_intervals):
    if not domain:
        return &amp;quot;—&amp;quot;, &amp;quot;—&amp;quot;, &amp;quot;—&amp;quot;, &amp;quot;—&amp;quot;, {}, {}, {}, {}, &amp;quot;Выберите домен&amp;quot;
    
    # 1. Количество поддоменов
    conn = get_db_connection()
    total_sub = pd.read_sql_query(
        &amp;quot;SELECT COUNT(*) as cnt FROM subdomains s JOIN domains d ON s.domain_id = d.id WHERE d.domain = ?&amp;quot;,
        conn, params=(domain,)
    ).iloc[0][&amp;#x27;cnt&amp;#x27;]
    conn.close()
    
    # 2. Изменения за 7 дней (новые поддомены)
    conn = get_db_connection()
    changes_7d = pd.read_sql_query(
        &amp;quot;SELECT COUNT(*) as cnt FROM subdomains s JOIN domains d ON s.domain_id = d.id WHERE d.domain = ? AND discovered_at &amp;gt; datetime(&amp;#x27;now&amp;#x27;, &amp;#x27;-7 days&amp;#x27;)&amp;quot;,
        conn, params=(domain,)
    ).iloc[0][&amp;#x27;cnt&amp;#x27;]
    conn.close()
    
    # 3. Истекающие сертификаты
    expiring_df = get_expiring_certs(domain)
    expiring_count = len(expiring_df)
    
    # 4. Открытые порты
    ports_df = get_port_distribution(domain)
    total_ports = ports_df[&amp;#x27;count&amp;#x27;].sum() if not ports_df.empty else 0
    
    # 5. График истории поддоменов
    history_df = get_subdomain_history(domain)
    fig_history = px.line(
        history_df, x=&amp;#x27;date&amp;#x27;, y=&amp;#x27;count&amp;#x27;,
        title=&amp;#x27;Поддомены по дням&amp;#x27;,
        labels={&amp;#x27;date&amp;#x27;: &amp;#x27;Дата&amp;#x27;, &amp;#x27;count&amp;#x27;: &amp;#x27;Количество&amp;#x27;}
    ) if not history_df.empty else go.Figure()
    
    # 6. Распределение портов
    fig_ports = px.pie(
        ports_df, values=&amp;#x27;count&amp;#x27;, names=&amp;#x27;port&amp;#x27;,
        title=&amp;#x27;Распределение портов&amp;#x27;
    ) if not ports_df.empty else go.Figure()
    
    # 7. Истекающие сертификаты (бар-чарт)
    if not expiring_df.empty:
        fig_certs = px.bar(
            expiring_df, x=&amp;#x27;name&amp;#x27;, y=&amp;#x27;days_left&amp;#x27;,
            title=&amp;#x27;Дней до истечения сертификата&amp;#x27;,
            labels={&amp;#x27;name&amp;#x27;: &amp;#x27;Домен&amp;#x27;, &amp;#x27;days_left&amp;#x27;: &amp;#x27;Дней&amp;#x27;},
            color=&amp;#x27;days_left&amp;#x27;,
            color_continuous_scale=&amp;#x27;RdYlGn_r&amp;#x27;
        )
    else:
        fig_certs = go.Figure()
        fig_certs.add_annotation(text=&amp;quot;Нет истекающих сертификатов&amp;quot;, showarrow=False)
    
    # 8. Технологический стек
    tech_df = get_tech_stack(domain)
    fig_tech = px.bar(
        tech_df, x=&amp;#x27;count&amp;#x27;, y=&amp;#x27;tech_name&amp;#x27;,
        orientation=&amp;#x27;h&amp;#x27;,
        title=&amp;#x27;Технологии&amp;#x27;,
        labels={&amp;#x27;count&amp;#x27;: &amp;#x27;Количество&amp;#x27;, &amp;#x27;tech_name&amp;#x27;: &amp;#x27;Технология&amp;#x27;}
    ) if not tech_df.empty else go.Figure()
    
    # 9. Таблица последних поддоменов
    recent_df = get_recent_subdomains(domain)
    if not recent_df.empty:
        table = html.Table([
            html.Thead(html.Tr([
                html.Th(&amp;quot;Поддомен&amp;quot;, style={&amp;#x27;textAlign&amp;#x27;: &amp;#x27;left&amp;#x27;}),
                html.Th(&amp;quot;Обнаружен&amp;quot;, style={&amp;#x27;textAlign&amp;#x27;: &amp;#x27;left&amp;#x27;})
            ])),
            html.Tbody([
                html.Tr([
                    html.Td(row[&amp;#x27;subdomain&amp;#x27;]),
                    html.Td(row[&amp;#x27;discovered_at&amp;#x27;])
                ]) for _, row in recent_df.iterrows()
            ])
        ], style={&amp;#x27;width&amp;#x27;: &amp;#x27;100%&amp;#x27;, &amp;#x27;borderCollapse&amp;#x27;: &amp;#x27;collapse&amp;#x27;})
    else:
        table = &amp;quot;Нет данных&amp;quot;
    
    return (
        total_sub,
        changes_7d,
        expiring_count,
        total_ports,
        fig_history,
        fig_ports,
        fig_certs,
        fig_tech,
        table
    )

# ============ ЗАПУСК ============

if __name__ == &amp;#x27;__main__&amp;#x27;:
    app.run_server(debug=True, host=&amp;#x27;0.0.0.0&amp;#x27;, port=8050)&lt;/pre&gt;
  &lt;p id=&quot;nAIo&quot;&gt;&lt;strong&gt;Добавление CSS-стилей (assets/style.css):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;g3lI&quot;&gt;.metric-card {
    background: white;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    padding: 20px;
    flex: 1;
    min-width: 150px;
    text-align: center;
}
.metric-card h3 {
    margin: 0 0 10px 0;
    font-size: 14px;
    color: #666;
}
.metric-card h2 {
    margin: 0;
    font-size: 32px;
}

.graph-card {
    background: white;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.05);
    padding: 15px;
}

table {
    border: 1px solid #ddd;
}
table th {
    background: #f5f5f5;
    padding: 10px;
    border-bottom: 2px solid #ddd;
}
table td {
    padding: 8px 10px;
    border-bottom: 1px solid #eee;
}
table tr:hover {
    background: #f9f9f9;
}&lt;/pre&gt;
  &lt;p id=&quot;cvr4&quot;&gt;&lt;strong&gt;Запуск дашборда:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;37Gm&quot;&gt;python app.py&lt;/pre&gt;
  &lt;p id=&quot;VMDS&quot;&gt;Дашборд будет доступен по адресу: &lt;code&gt;http://localhost:8050&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;itio&quot;&gt;&lt;strong&gt;ВАРИАНТ 3: БЫСТРЫЙ СТАТИЧЕСКИЙ ОТЧЁТ (HTML)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;g1bF&quot;&gt;Если веб-сервер не требуется, можно генерировать статический HTML-отчёт с графиками.&lt;/p&gt;
  &lt;p id=&quot;zwox&quot;&gt;&lt;strong&gt;Использование библиотеки &lt;code&gt;matplotlib&lt;/code&gt; + &lt;code&gt;mpld3&lt;/code&gt; для интерактивных графиков в HTML:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;5bo1&quot;&gt;import matplotlib.pyplot as plt
import mpld3
import sqlite3
import pandas as pd

def generate_report(domain):
    # Получение данных
    history_df = get_subdomain_history(domain)
    ports_df = get_port_distribution(domain)
    
    # Генерация графиков
    fig1, ax1 = plt.subplots()
    ax1.plot(history_df[&amp;#x27;date&amp;#x27;], history_df[&amp;#x27;count&amp;#x27;])
    ax1.set_title(&amp;#x27;Поддомены по дням&amp;#x27;)
    fig1_html = mpld3.fig_to_html(fig1)
    
    fig2, ax2 = plt.subplots()
    ax2.pie(ports_df[&amp;#x27;count&amp;#x27;], labels=ports_df[&amp;#x27;port&amp;#x27;], autopct=&amp;#x27;%1.1f%%&amp;#x27;)
    ax2.set_title(&amp;#x27;Распределение портов&amp;#x27;)
    fig2_html = mpld3.fig_to_html(fig2)
    
    # Сборка HTML
    html = f&amp;quot;&amp;quot;&amp;quot;
    &amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Отчёт по {domain}&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;OSINT Отчёт: {domain}&amp;lt;/h1&amp;gt;
        &amp;lt;div&amp;gt;{fig1_html}&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;{fig2_html}&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
    &amp;quot;&amp;quot;&amp;quot;
    with open(f&amp;#x27;report_{domain}.html&amp;#x27;, &amp;#x27;w&amp;#x27;) as f:
        f.write(html)&lt;/pre&gt;
  &lt;p id=&quot;4nCr&quot;&gt;&lt;strong&gt;ВАРИАНТ 4: ИСПОЛЬЗОВАНИЕ SPIDERFOOT&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;SGmD&quot;&gt;SpiderFoot — это OSINT-фреймворк с собственным веб-интерфейсом. Он автоматически собирает данные из множества источников и визуализирует их в виде графа связей.&lt;/p&gt;
  &lt;p id=&quot;GfuL&quot;&gt;&lt;strong&gt;Установка SpiderFoot:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;rJct&quot;&gt;# Docker (рекомендуемый способ)
docker run -p 5000:5000 spiderfoot/spiderfoot&lt;/pre&gt;
  &lt;p id=&quot;Qbfm&quot;&gt;&lt;strong&gt;Особенности SpiderFoot:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;zuMP&quot;&gt;
    &lt;li id=&quot;izRC&quot;&gt;Графовое представление связей (домены, IP, email, хэши).&lt;/li&gt;
    &lt;li id=&quot;21lP&quot;&gt;Автоматический сбор из 200+ модулей.&lt;/li&gt;
    &lt;li id=&quot;W8Iu&quot;&gt;Встроенный дашборд с картами и таймлайнами.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;OII0&quot;&gt;требует времени на настройку, может быть избыточным для простых задач.&lt;/p&gt;
  &lt;p id=&quot;4GKF&quot;&gt;&lt;strong&gt;ВАРИАНТ 5: MALTEGO ДЛЯ ВИЗУАЛИЗАЦИИ СВЯЗЕЙ&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Zosd&quot;&gt;Maltego — это инструмент для визуализации связей между сущностями (доменами, IP, личностями). В сочетании с трансформами он превращает собранные данные в интерактивный граф.&lt;/p&gt;
  &lt;p id=&quot;HnKT&quot;&gt;&lt;strong&gt;Как использовать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;NchE&quot;&gt;
    &lt;li id=&quot;O4Am&quot;&gt;Экспортировать данные из SQLite в CSV.&lt;/li&gt;
    &lt;li id=&quot;Puwk&quot;&gt;Импортировать в Maltego как &amp;quot;сущности&amp;quot; (Entities).&lt;/li&gt;
    &lt;li id=&quot;OsAX&quot;&gt;Использовать трансформы для дальнейшего обогащения.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;3Z1A&quot;&gt;&lt;strong&gt;СРАВНЕНИЕ ИНСТРУМЕНТОВ ДЛЯ ДАШБОРДОВ&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;qnDS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/16/e5/16e51c88-41e9-4eb5-b150-03abdaeacc22.png&quot; width=&quot;1021&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;r1Qd&quot;&gt;&lt;strong&gt;Практический пример: использование дашборда для мониторинга&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;L0aZ&quot;&gt;&lt;em&gt;Сценарий:&lt;/em&gt; аналитик мониторит 5 доменов конкурентов.&lt;/p&gt;
  &lt;ol id=&quot;Ia4M&quot;&gt;
    &lt;li id=&quot;JRkY&quot;&gt;&lt;strong&gt;Ежедневный сбор&lt;/strong&gt; → данные попадают в SQLite через автоматизированный конвейер.&lt;/li&gt;
    &lt;li id=&quot;IxKa&quot;&gt;&lt;strong&gt;Дашборд (Dash)&lt;/strong&gt; → отображает для каждого домена:&lt;/li&gt;
    &lt;ul id=&quot;BBUi&quot;&gt;
      &lt;li id=&quot;ItnT&quot;&gt;Количество поддоменов (график роста).&lt;/li&gt;
      &lt;li id=&quot;JnVt&quot;&gt;Новые поддомены за неделю (таблица).&lt;/li&gt;
      &lt;li id=&quot;gwAt&quot;&gt;Открытые порты и сервисы.&lt;/li&gt;
      &lt;li id=&quot;LHFo&quot;&gt;Истекающие сертификаты (алерт).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;VAEp&quot;&gt;&lt;strong&gt;Обнаружение:&lt;/strong&gt; на дашборде появляется новый поддомен &lt;code&gt;newapp.competitor.com&lt;/code&gt;. Аналитик видит, что это произошло сегодня. Через Shodan выясняется, что на нём открыт порт 443 с сертификатом от AWS. Вывод: конкурент запускает новый облачный сервис.&lt;/li&gt;
    &lt;li id=&quot;2Mbo&quot;&gt;&lt;strong&gt;Реакция:&lt;/strong&gt; информация передаётся в стратегический отдел.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;McSX&quot;&gt;&lt;strong&gt;РЕКОМЕНДАЦИИ ПО ВЫБОРУ&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;hq6v&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9e/ba/9eba62b3-2fc1-4351-aaf4-12c16beaa60a.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;iX4P&quot;&gt;Дашборд — это завершающий элемент системы технического OSINT, превращающий сырые данные в понятную и удобную для анализа информацию. Выбор инструмента зависит от задач: Grafana подходит для быстрого старта и оперативного мониторинга, Dash/Plotly — для глубокой кастомизации, Maltego — для визуализации связей. Интеграция дашборда с автоматизированным конвейером (из предыдущей статьи) создаёт полноценную систему непрерывной разведки, где данные собираются, обрабатываются и отображаются в реальном времени.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Automation-of-technical-OSINT</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Automation-of-technical-OSINT?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Автоматизация технического OSINT: сбор данных в скриптах</title><published>2026-07-07T21:25:14.115Z</published><updated>2026-07-07T21:25:14.115Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/ae/90/ae9083f8-4e43-48b6-9e57-763c4eb57308.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/6d/73/6d732144-e975-4bb8-aa26-7ef8c3fd4900.png&quot;&gt;Ручное выполнение всех этапов технического OSINT для одного домена может занять несколько часов. При необходимости мониторинга десятков или сотен целей ручной сбор становится невозможным. Автоматизация превращает разрозненные запросы к API, парсинг веб-страниц и анализ данных в единый воспроизводимый конвейер, который можно запускать по расписанию. Правильно построенная система автоматизации позволяет получать актуальную информацию о целях без участия человека, экономить время и избегать ошибок. Данная статья посвящена методам и практическим примерам автоматизации технического OSINT с использованием Python и Bash.</summary><content type="html">
  &lt;figure id=&quot;hZDx&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6d/73/6d732144-e975-4bb8-aa26-7ef8c3fd4900.png&quot; width=&quot;1099&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;2VPe&quot;&gt;Автоматизация технического OSINT: сбор данных в скриптах (Python, Bash)&lt;/h3&gt;
  &lt;p id=&quot;XflP&quot;&gt;Ручное выполнение всех этапов технического OSINT для одного домена может занять несколько часов. При необходимости мониторинга десятков или сотен целей ручной сбор становится невозможным. Автоматизация превращает разрозненные запросы к API, парсинг веб-страниц и анализ данных в единый воспроизводимый конвейер, который можно запускать по расписанию. Правильно построенная система автоматизации позволяет получать актуальную информацию о целях без участия человека, экономить время и избегать ошибок. Данная статья посвящена методам и практическим примерам автоматизации технического OSINT с использованием Python и Bash.&lt;/p&gt;
  &lt;p id=&quot;QXBl&quot;&gt;&lt;strong&gt;Зачем автоматизировать технический OSINT?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;81Ld&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c0/d2/c0d2d0a4-c511-4f78-a6bc-fb5386806413.png&quot; width=&quot;1081&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Q7AX&quot;&gt;&lt;strong&gt;Подходы к автоматизации&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;HNa1&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c5/1a/c51a00d1-fef9-43a9-a828-c02683c298ed.png&quot; width=&quot;1213&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wjc1&quot;&gt;&lt;strong&gt;Этап 1: Структура проекта&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;DeEP&quot;&gt;Рекомендуемая структура каталога для автоматизации:&lt;/p&gt;
  &lt;pre id=&quot;06MT&quot;&gt;osint-automation/
├── config/
│   ├── config.yaml            # API ключи, настройки
│   └── targets.txt            # Список доменов (по одному на строку)
├── modules/
│   ├── dns.py                 # Сбор DNS-записей
│   ├── whois.py               # WHOIS-информация
│   ├── subdomains.py          # Поиск поддоменов (crt.sh, SecurityTrails)
│   ├── certificates.py        # SSL/TLS сертификаты
│   ├── shodan.py              # Shodan-данные
│   ├── tech_stack.py          # Wappalyzer/BuiltWith технологии
│   ├── github.py              # Поиск секретов в GitHub
│   └── changes.py             # Сравнение с предыдущим состоянием
├── utils/
│   ├── logger.py              # Логирование
│   ├── notifier.py            # Отправка уведомлений (Telegram, Email)
│   └── db.py                  # Работа с SQLite
├── data/                      # Хранилище результатов (JSON, SQLite)
├── main.py                    # Главный скрипт
├── requirements.txt           # Зависимости Python
└── run.sh                     # Bash-обёртка для cron&lt;/pre&gt;
  &lt;p id=&quot;ATyE&quot;&gt;&lt;strong&gt;Этап 2: Настройка конфигурации (config.yaml)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;QNHF&quot;&gt;# config.yaml
api_keys:
  shodan: &amp;quot;SHODAN_API_KEY&amp;quot;
  securitytrails: &amp;quot;SECURITYTRAILS_API_KEY&amp;quot;
  github: &amp;quot;GITHUB_TOKEN&amp;quot;
  virustotal: &amp;quot;VIRUSTOTAL_API_KEY&amp;quot;  # опционально
  censys:
    api_id: &amp;quot;CENSYS_API_ID&amp;quot;
    api_secret: &amp;quot;CENSYS_API_SECRET&amp;quot;

notifications:
  telegram:
    token: &amp;quot;TELEGRAM_BOT_TOKEN&amp;quot;
    chat_id: &amp;quot;TELEGRAM_CHAT_ID&amp;quot;
  email:
    smtp_server: &amp;quot;smtp.gmail.com&amp;quot;
    smtp_port: 587
    username: &amp;quot;user@gmail.com&amp;quot;
    password: &amp;quot;app_password&amp;quot;
    to: &amp;quot;recipient@example.com&amp;quot;

database:
  path: &amp;quot;data/osint.db&amp;quot;

targets:
  file: &amp;quot;config/targets.txt&amp;quot;

logging:
  level: &amp;quot;INFO&amp;quot;
  file: &amp;quot;data/osint.log&amp;quot;

scan:
  # интервал повторных запросов для Shodan (если нужно ждать)
  shodan_delay: 1  # секунды между запросами
  timeout: 30  # таймаут для HTTP-запросов&lt;/pre&gt;
  &lt;p id=&quot;CiQd&quot;&gt;&lt;strong&gt;Этап 3: Сбор DNS-записей (modules/dns.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;XsPK&quot;&gt;import dns.resolver
import json
from utils.logger import get_logger

logger = get_logger(__name__)

def get_dns_records(domain):
    &amp;quot;&amp;quot;&amp;quot;
    Сбор основных DNS-записей: A, AAAA, MX, TXT, NS, CNAME, SOA
    &amp;quot;&amp;quot;&amp;quot;
    records = {}
    record_types = [&amp;#x27;A&amp;#x27;, &amp;#x27;AAAA&amp;#x27;, &amp;#x27;MX&amp;#x27;, &amp;#x27;TXT&amp;#x27;, &amp;#x27;NS&amp;#x27;, &amp;#x27;CNAME&amp;#x27;, &amp;#x27;SOA&amp;#x27;]
    
    for rtype in record_types:
        try:
            answers = dns.resolver.resolve(domain, rtype)
            records[rtype] = [str(r) for r in answers]
        except dns.resolver.NoAnswer:
            records[rtype] = []
        except dns.resolver.NXDOMAIN:
            records[rtype] = []
        except Exception as e:
            logger.warning(f&amp;quot;DNS {rtype} для {domain}: {e}&amp;quot;)
            records[rtype] = []
    
    return records

def get_reverse_dns(ip):
    &amp;quot;&amp;quot;&amp;quot;
    Обратный DNS (PTR) для IP-адреса
    &amp;quot;&amp;quot;&amp;quot;
    try:
        answers = dns.resolver.resolve_address(ip)
        return [str(r) for r in answers]
    except:
        return []

# Пример использования
if __name__ == &amp;quot;__main__&amp;quot;:
    records = get_dns_records(&amp;quot;example.com&amp;quot;)
    print(json.dumps(records, indent=2))&lt;/pre&gt;
  &lt;p id=&quot;bgEY&quot;&gt;&lt;strong&gt;Этап 4: WHOIS-информация (modules/whois.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;RSVZ&quot;&gt;import whois
import json
from datetime import datetime

def get_whois_info(domain):
    &amp;quot;&amp;quot;&amp;quot;
    Получение WHOIS-информации о домене
    &amp;quot;&amp;quot;&amp;quot;
    try:
        w = whois.whois(domain)
        return {
            &amp;#x27;domain_name&amp;#x27;: w.domain_name,
            &amp;#x27;registrar&amp;#x27;: w.registrar,
            &amp;#x27;creation_date&amp;#x27;: str(w.creation_date),
            &amp;#x27;expiration_date&amp;#x27;: str(w.expiration_date),
            &amp;#x27;updated_date&amp;#x27;: str(w.updated_date),
            &amp;#x27;name_servers&amp;#x27;: w.name_servers,
            &amp;#x27;emails&amp;#x27;: w.emails,
            &amp;#x27;org&amp;#x27;: w.org,
            &amp;#x27;country&amp;#x27;: w.country,
        }
    except Exception as e:
        return {&amp;#x27;error&amp;#x27;: str(e)}&lt;/pre&gt;
  &lt;p id=&quot;bHjT&quot;&gt;&lt;strong&gt;Этап 5: Поиск поддоменов через crt.sh (modules/subdomains.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;sTXe&quot;&gt;import requests
import json
from utils.logger import get_logger

logger = get_logger(__name__)

def get_subdomains_crtsh(domain):
    &amp;quot;&amp;quot;&amp;quot;
    Получение поддоменов из Certificate Transparency логов через crt.sh
    &amp;quot;&amp;quot;&amp;quot;
    url = f&amp;quot;https://crt.sh/?q=%25.{domain}&amp;amp;output=json&amp;quot;
    subdomains = set()
    try:
        resp = requests.get(url, timeout=30)
        if resp.status_code == 200:
            data = resp.json()
            for entry in data:
                name = entry.get(&amp;#x27;name_value&amp;#x27;, &amp;#x27;&amp;#x27;)
                if name.endswith(f&amp;#x27;.{domain}&amp;#x27;) or name == domain:
                    # убираем wildcard
                    if name.startswith(&amp;#x27;*.&amp;#x27;):
                        name = name[2:]
                    subdomains.add(name.lower())
        else:
            logger.warning(f&amp;quot;crt.sh ошибка: {resp.status_code}&amp;quot;)
    except Exception as e:
        logger.error(f&amp;quot;crt.sh исключение: {e}&amp;quot;)
    
    return sorted(subdomains)

def get_subdomains_securitytrails(domain, api_key):
    &amp;quot;&amp;quot;&amp;quot;
    Получение поддоменов через SecurityTrails API (требуется ключ)
    &amp;quot;&amp;quot;&amp;quot;
    if not api_key:
        return []
    url = f&amp;quot;https://api.securitytrails.com/v1/domain/{domain}/subdomains&amp;quot;
    headers = {&amp;quot;APIKEY&amp;quot;: api_key}
    try:
        resp = requests.get(url, headers=headers, timeout=30)
        if resp.status_code == 200:
            data = resp.json()
            subdomains = data.get(&amp;#x27;subdomains&amp;#x27;, [])
            return [f&amp;quot;{s}.{domain}&amp;quot; for s in subdomains]
    except Exception as e:
        logger.error(f&amp;quot;SecurityTrails ошибка: {e}&amp;quot;)
    return []

def get_all_subdomains(domain, securitytrails_key=None):
    &amp;quot;&amp;quot;&amp;quot;
    Агрегация поддоменов из всех источников
    &amp;quot;&amp;quot;&amp;quot;
    all_subs = set()
    all_subs.update(get_subdomains_crtsh(domain))
    if securitytrails_key:
        all_subs.update(get_subdomains_securitytrails(domain, securitytrails_key))
    return sorted(all_subs)&lt;/pre&gt;
  &lt;p id=&quot;2heD&quot;&gt;&lt;strong&gt;Этап 6: Анализ SSL/TLS сертификатов (modules/certificates.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;rNR9&quot;&gt;import requests
import json
from datetime import datetime

def get_certificates_crtsh(domain):
    &amp;quot;&amp;quot;&amp;quot;
    Получение информации о сертификатах для домена
    &amp;quot;&amp;quot;&amp;quot;
    url = f&amp;quot;https://crt.sh/?q=%25.{domain}&amp;amp;output=json&amp;quot;
    certs = []
    try:
        resp = requests.get(url, timeout=30)
        if resp.status_code == 200:
            data = resp.json()
            for entry in data:
                if len(entry) &amp;lt; 6:
                    continue
                certs.append({
                    &amp;#x27;name&amp;#x27;: entry[1],
                    &amp;#x27;issuer&amp;#x27;: entry[2],
                    &amp;#x27;valid_from&amp;#x27;: entry[3],
                    &amp;#x27;valid_to&amp;#x27;: entry[4],
                    &amp;#x27;ca&amp;#x27;: entry[5]
                })
    except Exception as e:
        pass
    return certs

def get_certificate_expiry(certs):
    &amp;quot;&amp;quot;&amp;quot;
    Определение ближайшего истекающего сертификата
    &amp;quot;&amp;quot;&amp;quot;
    now = datetime.now()
    expiring = []
    for cert in certs:
        try:
            valid_to = datetime.strptime(cert[&amp;#x27;valid_to&amp;#x27;], &amp;#x27;%Y-%m-%dT%H:%M:%S&amp;#x27;)
            days_left = (valid_to - now).days
            if days_left &amp;lt; 30:
                expiring.append({
                    &amp;#x27;name&amp;#x27;: cert[&amp;#x27;name&amp;#x27;],
                    &amp;#x27;expires&amp;#x27;: cert[&amp;#x27;valid_to&amp;#x27;],
                    &amp;#x27;days_left&amp;#x27;: days_left
                })
        except:
            pass
    return expiring&lt;/pre&gt;
  &lt;p id=&quot;EOVj&quot;&gt;&lt;strong&gt;Этап 7: Сбор данных из Shodan (modules/shodan.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;biXv&quot;&gt;import shodan
from utils.logger import get_logger

logger = get_logger(__name__)

def get_shodan_host(ip, api_key):
    &amp;quot;&amp;quot;&amp;quot;
    Получение информации о хосте из Shodan
    &amp;quot;&amp;quot;&amp;quot;
    if not api_key:
        return {}
    try:
        api = shodan.Shodan(api_key)
        host = api.host(ip)
        return {
            &amp;#x27;ip&amp;#x27;: host.get(&amp;#x27;ip_str&amp;#x27;),
            &amp;#x27;organization&amp;#x27;: host.get(&amp;#x27;org&amp;#x27;),
            &amp;#x27;isp&amp;#x27;: host.get(&amp;#x27;isp&amp;#x27;),
            &amp;#x27;country&amp;#x27;: host.get(&amp;#x27;country_name&amp;#x27;),
            &amp;#x27;ports&amp;#x27;: host.get(&amp;#x27;ports&amp;#x27;, []),
            &amp;#x27;vulns&amp;#x27;: host.get(&amp;#x27;vulns&amp;#x27;, []),
            &amp;#x27;data&amp;#x27;: host.get(&amp;#x27;data&amp;#x27;, [])  # баннеры
        }
    except shodan.APIError as e:
        logger.error(f&amp;quot;Shodan ошибка для {ip}: {e}&amp;quot;)
        return {}
    except Exception as e:
        logger.error(f&amp;quot;Shodan исключение для {ip}: {e}&amp;quot;)
        return {}

def get_shodan_host_by_domain(domain, api_key):
    &amp;quot;&amp;quot;&amp;quot;
    Поиск хостов, связанных с доменом, через Shodan
    &amp;quot;&amp;quot;&amp;quot;
    if not api_key:
        return []
    try:
        api = shodan.Shodan(api_key)
        results = api.search(f&amp;quot;hostname:{domain}&amp;quot;)
        hosts = []
        for match in results.get(&amp;#x27;matches&amp;#x27;, []):
            hosts.append({
                &amp;#x27;ip&amp;#x27;: match.get(&amp;#x27;ip_str&amp;#x27;),
                &amp;#x27;port&amp;#x27;: match.get(&amp;#x27;port&amp;#x27;),
                &amp;#x27;data&amp;#x27;: match.get(&amp;#x27;data&amp;#x27;, &amp;#x27;&amp;#x27;)[:200]
            })
        return hosts
    except shodan.APIError as e:
        logger.error(f&amp;quot;Shodan search ошибка: {e}&amp;quot;)
        return []&lt;/pre&gt;
  &lt;p id=&quot;2cUw&quot;&gt;&lt;strong&gt;Этап 8: Поиск в GitHub (modules/github.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;1MIV&quot;&gt;import requests
from utils.logger import get_logger

logger = get_logger(__name__)

def search_github_secrets(domain, token):
    &amp;quot;&amp;quot;&amp;quot;
    Поиск упоминаний домена и подозрительных паттернов в GitHub
    &amp;quot;&amp;quot;&amp;quot;
    if not token:
        return []
    
    # Комбинированный запрос: упоминания домена + файлы .env, пароли, ключи
    queries = [
        f&amp;#x27;&amp;quot;{domain}&amp;quot; extension:env&amp;#x27;,
        f&amp;#x27;&amp;quot;{domain}&amp;quot; password&amp;#x27;,
        f&amp;#x27;&amp;quot;{domain}&amp;quot; api_key&amp;#x27;,
        f&amp;#x27;&amp;quot;{domain}&amp;quot; secret&amp;#x27;,
        f&amp;#x27;&amp;quot;{domain}&amp;quot; token&amp;#x27;,
    ]
    
    headers = {
        &amp;quot;Authorization&amp;quot;: f&amp;quot;token {token}&amp;quot;,
        &amp;quot;Accept&amp;quot;: &amp;quot;application/vnd.github.v3+json&amp;quot;
    }
    
    all_results = []
    for query in queries:
        url = &amp;quot;https://api.github.com/search/code&amp;quot;
        params = {&amp;quot;q&amp;quot;: query, &amp;quot;per_page&amp;quot;: 20}
        try:
            resp = requests.get(url, headers=headers, params=params, timeout=20)
            if resp.status_code == 200:
                data = resp.json()
                for item in data.get(&amp;#x27;items&amp;#x27;, []):
                    all_results.append({
                        &amp;#x27;repo&amp;#x27;: item[&amp;#x27;repository&amp;#x27;][&amp;#x27;full_name&amp;#x27;],
                        &amp;#x27;path&amp;#x27;: item[&amp;#x27;path&amp;#x27;],
                        &amp;#x27;url&amp;#x27;: item[&amp;#x27;html_url&amp;#x27;],
                        &amp;#x27;query&amp;#x27;: query
                    })
            else:
                logger.warning(f&amp;quot;GitHub ошибка ({query}): {resp.status_code}&amp;quot;)
        except Exception as e:
            logger.error(f&amp;quot;GitHub исключение: {e}&amp;quot;)
    
    return all_results&lt;/pre&gt;
  &lt;p id=&quot;V7Yf&quot;&gt;&lt;strong&gt;Этап 9: Технологический стек (modules/tech_stack.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;fXQI&quot;&gt;import subprocess
import json
from utils.logger import get_logger

logger = get_logger(__name__)

def get_tech_wappalyzer(url):
    &amp;quot;&amp;quot;&amp;quot;
    Определение технологий через Wappalyzer CLI
    Требуется установить: npm install -g wappalyzer
    &amp;quot;&amp;quot;&amp;quot;
    try:
        result = subprocess.run(
            [&amp;#x27;wappalyzer&amp;#x27;, url],
            capture_output=True,
            text=True,
            timeout=60
        )
        if result.returncode == 0:
            return json.loads(result.stdout)
        else:
            logger.warning(f&amp;quot;Wappalyzer ошибка: {result.stderr}&amp;quot;)
            return {}
    except Exception as e:
        logger.error(f&amp;quot;Wappalyzer исключение: {e}&amp;quot;)
        return {}

def get_tech_builtwith(url, api_key=None):
    &amp;quot;&amp;quot;&amp;quot;
    Использование BuiltWith API (требуется ключ)
    &amp;quot;&amp;quot;&amp;quot;
    if not api_key:
        return {}
    endpoint = f&amp;quot;https://api.builtwith.com/free1/api.json?KEY={api_key}&amp;amp;LOOKUP={url}&amp;quot;
    try:
        import requests
        resp = requests.get(endpoint, timeout=30)
        if resp.status_code == 200:
            return resp.json()
    except Exception as e:
        logger.error(f&amp;quot;BuiltWith ошибка: {e}&amp;quot;)
    return {}&lt;/pre&gt;
  &lt;p id=&quot;wp81&quot;&gt;&lt;strong&gt;Этап 10: Общая база данных (utils/db.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;CIzm&quot;&gt;Используем SQLite для хранения истории изменений.&lt;/p&gt;
  &lt;pre id=&quot;RDKl&quot;&gt;import sqlite3
import json
from datetime import datetime

class OSINTDatabase:
    def __init__(self, db_path):
        self.conn = sqlite3.connect(db_path)
        self.create_tables()
    
    def create_tables(self):
        cursor = self.conn.cursor()
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS domains (
                id INTEGER PRIMARY KEY,
                domain TEXT UNIQUE,
                first_seen TEXT,
                last_updated TEXT
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS subdomains (
                id INTEGER PRIMARY KEY,
                domain_id INTEGER,
                subdomain TEXT,
                discovered_at TEXT,
                FOREIGN KEY(domain_id) REFERENCES domains(id)
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS dns_records (
                id INTEGER PRIMARY KEY,
                domain_id INTEGER,
                record_type TEXT,
                record_value TEXT,
                discovered_at TEXT,
                FOREIGN KEY(domain_id) REFERENCES domains(id)
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS certificates (
                id INTEGER PRIMARY KEY,
                domain_id INTEGER,
                name TEXT,
                issuer TEXT,
                valid_from TEXT,
                valid_to TEXT,
                discovered_at TEXT,
                FOREIGN KEY(domain_id) REFERENCES domains(id)
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS shodan_ports (
                id INTEGER PRIMARY KEY,
                domain_id INTEGER,
                ip TEXT,
                port INTEGER,
                data TEXT,
                discovered_at TEXT,
                FOREIGN KEY(domain_id) REFERENCES domains(id)
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        cursor.execute(&amp;#x27;&amp;#x27;&amp;#x27;
            CREATE TABLE IF NOT EXISTS changes (
                id INTEGER PRIMARY KEY,
                domain TEXT,
                change_type TEXT,
                old_value TEXT,
                new_value TEXT,
                detected_at TEXT
            )
        &amp;#x27;&amp;#x27;&amp;#x27;)
        self.conn.commit()
    
    def get_domain_id(self, domain):
        cursor = self.conn.cursor()
        cursor.execute(&amp;quot;SELECT id FROM domains WHERE domain = ?&amp;quot;, (domain,))
        row = cursor.fetchone()
        if row:
            return row[0]
        # Создаём новый
        cursor.execute(&amp;quot;INSERT INTO domains (domain, first_seen, last_updated) VALUES (?, ?, ?)&amp;quot;,
                       (domain, datetime.now().isoformat(), datetime.now().isoformat()))
        self.conn.commit()
        return cursor.lastrowid
    
    def save_subdomains(self, domain_id, subdomains):
        cursor = self.conn.cursor()
        for sub in subdomains:
            cursor.execute(&amp;quot;INSERT OR IGNORE INTO subdomains (domain_id, subdomain, discovered_at) VALUES (?, ?, ?)&amp;quot;,
                           (domain_id, sub, datetime.now().isoformat()))
        self.conn.commit()
    
    def save_dns_records(self, domain_id, records):
        cursor = self.conn.cursor()
        for rtype, values in records.items():
            for val in values:
                cursor.execute(&amp;quot;INSERT INTO dns_records (domain_id, record_type, record_value, discovered_at) VALUES (?, ?, ?, ?)&amp;quot;,
                               (domain_id, rtype, val, datetime.now().isoformat()))
        self.conn.commit()
    
    def save_certificates(self, domain_id, certs):
        cursor = self.conn.cursor()
        for cert in certs:
            cursor.execute(&amp;quot;INSERT INTO certificates (domain_id, name, issuer, valid_from, valid_to, discovered_at) VALUES (?, ?, ?, ?, ?, ?)&amp;quot;,
                           (domain_id, cert.get(&amp;#x27;name&amp;#x27;), cert.get(&amp;#x27;issuer&amp;#x27;), cert.get(&amp;#x27;valid_from&amp;#x27;), cert.get(&amp;#x27;valid_to&amp;#x27;), datetime.now().isoformat()))
        self.conn.commit()
    
    def log_change(self, domain, change_type, old_value, new_value):
        cursor = self.conn.cursor()
        cursor.execute(&amp;quot;INSERT INTO changes (domain, change_type, old_value, new_value, detected_at) VALUES (?, ?, ?, ?, ?)&amp;quot;,
                       (domain, change_type, old_value, new_value, datetime.now().isoformat()))
        self.conn.commit()
    
    def close(self):
        self.conn.close()&lt;/pre&gt;
  &lt;p id=&quot;DNFE&quot;&gt;&lt;strong&gt;Этап 11: Главный конвейер (main.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;3wKi&quot;&gt;#!/usr/bin/env python3
import os
import sys
import json
import yaml
from datetime import datetime
from utils.logger import setup_logger
from utils.db import OSINTDatabase
from utils.notifier import send_telegram
from modules.dns import get_dns_records
from modules.whois import get_whois_info
from modules.subdomains import get_all_subdomains
from modules.certificates import get_certificates_crtsh, get_certificate_expiry
from modules.shodan import get_shodan_host_by_domain
from modules.tech_stack import get_tech_wappalyzer
from modules.github import search_github_secrets
from modules.changes import compare_and_notify

# Загрузка конфига
with open(&amp;#x27;config/config.yaml&amp;#x27;, &amp;#x27;r&amp;#x27;) as f:
    config = yaml.safe_load(f)

logger = setup_logger(config[&amp;#x27;logging&amp;#x27;][&amp;#x27;level&amp;#x27;], config[&amp;#x27;logging&amp;#x27;][&amp;#x27;file&amp;#x27;])
db = OSINTDatabase(config[&amp;#x27;database&amp;#x27;][&amp;#x27;path&amp;#x27;])

def process_domain(domain):
    logger.info(f&amp;quot;Обработка {domain}&amp;quot;)
    
    # Получаем ID домена в БД
    domain_id = db.get_domain_id(domain)
    
    # 1. WHOIS
    whois_data = get_whois_info(domain)
    logger.info(f&amp;quot;WHOIS для {domain}: {whois_data.get(&amp;#x27;registrar&amp;#x27;, &amp;#x27;unknown&amp;#x27;)}&amp;quot;)
    
    # 2. DNS записи
    dns = get_dns_records(domain)
    db.save_dns_records(domain_id, dns)
    logger.info(f&amp;quot;DNS: A={len(dns.get(&amp;#x27;A&amp;#x27;, []))}, MX={len(dns.get(&amp;#x27;MX&amp;#x27;, []))}&amp;quot;)
    
    # 3. Поддомены
    sec_key = config[&amp;#x27;api_keys&amp;#x27;].get(&amp;#x27;securitytrails&amp;#x27;)
    subdomains = get_all_subdomains(domain, sec_key)
    db.save_subdomains(domain_id, subdomains)
    logger.info(f&amp;quot;Найдено {len(subdomains)} поддоменов&amp;quot;)
    
    # 4. Сертификаты
    certs = get_certificates_crtsh(domain)
    db.save_certificates(domain_id, certs)
    expiring = get_certificate_expiry(certs)
    if expiring:
        logger.warning(f&amp;quot;Сертификаты истекают: {expiring}&amp;quot;)
    
    # 5. Shodan (по поддоменам, ограничимся первыми 10 IP)
    shodan_key = config[&amp;#x27;api_keys&amp;#x27;].get(&amp;#x27;shodan&amp;#x27;)
    if shodan_key and subdomains:
        for sub in subdomains[:10]:
            hosts = get_shodan_host_by_domain(sub, shodan_key)
            # сохраняем в БД
            for h in hosts:
                pass  # упрощённо
    
    # 6. Технологический стек
    if subdomains:
        main_url = f&amp;quot;https://{domain}&amp;quot;
        tech = get_tech_wappalyzer(main_url)
        logger.info(f&amp;quot;Технологии: {tech.get(&amp;#x27;technologies&amp;#x27;, [])}&amp;quot;)
    
    # 7. GitHub секреты
    github_token = config[&amp;#x27;api_keys&amp;#x27;].get(&amp;#x27;github&amp;#x27;)
    if github_token:
        secrets = search_github_secrets(domain, github_token)
        if secrets:
            logger.warning(f&amp;quot;Найдены потенциальные секреты в GitHub: {len(secrets)}&amp;quot;)
            send_telegram(
                config[&amp;#x27;notifications&amp;#x27;][&amp;#x27;telegram&amp;#x27;][&amp;#x27;token&amp;#x27;],
                config[&amp;#x27;notifications&amp;#x27;][&amp;#x27;telegram&amp;#x27;][&amp;#x27;chat_id&amp;#x27;],
                f&amp;quot;Обнаружены секреты для {domain}: {len(secrets)} файлов&amp;quot;
            )
    
    # 8. Сравнение изменений
    compare_and_notify(domain, config, db)
    
    logger.info(f&amp;quot;Обработка {domain} завершена&amp;quot;)

def main():
    targets_file = config[&amp;#x27;targets&amp;#x27;][&amp;#x27;file&amp;#x27;]
    with open(targets_file, &amp;#x27;r&amp;#x27;) as f:
        domains = [line.strip() for line in f if line.strip()]
    
    for domain in domains:
        try:
            process_domain(domain)
        except Exception as e:
            logger.error(f&amp;quot;Ошибка для {domain}: {e}&amp;quot;)
    
    db.close()
    logger.info(&amp;quot;Все задачи выполнены&amp;quot;)

if __name__ == &amp;quot;__main__&amp;quot;:
    main()&lt;/pre&gt;
  &lt;p id=&quot;dokO&quot;&gt;&lt;strong&gt;Этап 12: Сравнение изменений и уведомления (modules/changes.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;xs0S&quot;&gt;import json
import hashlib
import os
from utils.notifier import send_telegram

def load_previous_state(domain, data_dir=&amp;#x27;data/states&amp;#x27;):
    &amp;quot;&amp;quot;&amp;quot;Загрузка предыдущего состояния из JSON&amp;quot;&amp;quot;&amp;quot;
    os.makedirs(data_dir, exist_ok=True)
    state_file = os.path.join(data_dir, f&amp;quot;{domain}_state.json&amp;quot;)
    if os.path.exists(state_file):
        with open(state_file, &amp;#x27;r&amp;#x27;) as f:
            return json.load(f)
    return {}

def save_current_state(domain, state, data_dir=&amp;#x27;data/states&amp;#x27;):
    state_file = os.path.join(data_dir, f&amp;quot;{domain}_state.json&amp;quot;)
    with open(state_file, &amp;#x27;w&amp;#x27;) as f:
        json.dump(state, f, indent=2)

def compare_and_notify(domain, config, db):
    &amp;quot;&amp;quot;&amp;quot;Сравнение текущего состояния с предыдущим и уведомление об изменениях&amp;quot;&amp;quot;&amp;quot;
    # Собираем текущее состояние в словарь
    current = {
        &amp;#x27;subdomains&amp;#x27;: sorted(db.get_subdomains(domain)),
        &amp;#x27;dns&amp;#x27;: db.get_dns_records(domain),
        &amp;#x27;certs&amp;#x27;: db.get_certificates(domain),
    }
    
    previous = load_previous_state(domain)
    
    changes = []
    
    # Сравнение поддоменов
    if previous:
        old_subs = set(previous.get(&amp;#x27;subdomains&amp;#x27;, []))
        new_subs = set(current.get(&amp;#x27;subdomains&amp;#x27;, []))
        added = new_subs - old_subs
        removed = old_subs - new_subs
        if added:
            changes.append(f&amp;quot;Новые поддомены: {&amp;#x27;, &amp;#x27;.join(added)}&amp;quot;)
        if removed:
            changes.append(f&amp;quot;Удалены: {&amp;#x27;, &amp;#x27;.join(removed)}&amp;quot;)
    
    # Если есть изменения — отправляем уведомление
    if changes:
        msg = f&amp;quot;Изменения для {domain}:\n&amp;quot; + &amp;quot;\n&amp;quot;.join(changes)
        send_telegram(
            config[&amp;#x27;notifications&amp;#x27;][&amp;#x27;telegram&amp;#x27;][&amp;#x27;token&amp;#x27;],
            config[&amp;#x27;notifications&amp;#x27;][&amp;#x27;telegram&amp;#x27;][&amp;#x27;chat_id&amp;#x27;],
            msg
        )
        # Логируем в БД
        for change in changes:
            db.log_change(domain, &amp;#x27;change&amp;#x27;, &amp;#x27;&amp;#x27;, change)
    
    # Сохраняем новое состояние
    save_current_state(domain, current)&lt;/pre&gt;
  &lt;p id=&quot;vYmX&quot;&gt;&lt;strong&gt;Этап 13: Утилита уведомлений (utils/notifier.py)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;o7Ut&quot;&gt;import requests
import smtplib
from email.mime.text import MIMEText

def send_telegram(token, chat_id, message):
    &amp;quot;&amp;quot;&amp;quot;Отправка уведомления в Telegram&amp;quot;&amp;quot;&amp;quot;
    if not token or not chat_id:
        return
    url = f&amp;quot;https://api.telegram.org/bot{token}/sendMessage&amp;quot;
    try:
        requests.post(url, json={&amp;#x27;chat_id&amp;#x27;: chat_id, &amp;#x27;text&amp;#x27;: message}, timeout=10)
    except Exception as e:
        print(f&amp;quot;Telegram ошибка: {e}&amp;quot;)

def send_email(smtp_server, port, username, password, to, subject, body):
    &amp;quot;&amp;quot;&amp;quot;Отправка email уведомления&amp;quot;&amp;quot;&amp;quot;
    msg = MIMEText(body)
    msg[&amp;#x27;Subject&amp;#x27;] = subject
    msg[&amp;#x27;From&amp;#x27;] = username
    msg[&amp;#x27;To&amp;#x27;] = to
    try:
        with smtplib.SMTP(smtp_server, port) as server:
            server.starttls()
            server.login(username, password)
            server.send_message(msg)
    except Exception as e:
        print(f&amp;quot;Email ошибка: {e}&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;EAVf&quot;&gt;&lt;strong&gt;Этап 14: Bash-обёртка для cron (run.sh)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;lE80&quot;&gt;#!/bin/bash
# run.sh — обёртка для запуска конвейера с логированием

cd /path/to/osint-automation

# Активация виртуального окружения Python (если используется)
source venv/bin/activate

# Запуск основного скрипта
python main.py &amp;gt;&amp;gt; data/osint_cron.log 2&amp;gt;&amp;amp;1

# Проверка кода возврата
if [ $? -ne 0 ]; then
    echo &amp;quot;Ошибка выполнения $(date)&amp;quot; &amp;gt;&amp;gt; data/osint_errors.log
fi

# Удаление старых логов (старше 30 дней)
find data/ -name &amp;quot;*.log&amp;quot; -mtime +30 -delete&lt;/pre&gt;
  &lt;p id=&quot;BTCz&quot;&gt;&lt;strong&gt;Настройка cron (ежедневно в 8 утра):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;guf6&quot;&gt;0 8 * * * /path/to/osint-automation/run.sh&lt;/pre&gt;
  &lt;p id=&quot;d7s1&quot;&gt;&lt;strong&gt;Этап 15: Обработка ошибок и rate limits&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4ynZ&quot;&gt;Важные аспекты при автоматизации:&lt;/p&gt;
  &lt;ul id=&quot;s4my&quot;&gt;
    &lt;li id=&quot;EiUn&quot;&gt;&lt;strong&gt;Ограничения API:&lt;/strong&gt; Используйте задержки между запросами (time.sleep), храните время последнего запроса.&lt;/li&gt;
    &lt;li id=&quot;l6CM&quot;&gt;&lt;strong&gt;Повторные попытки:&lt;/strong&gt; Реализуйте повтор при временных ошибках (например, 429 Too Many Requests).&lt;/li&gt;
    &lt;li id=&quot;IcEi&quot;&gt;&lt;strong&gt;Логирование:&lt;/strong&gt; Все ошибки пишите в лог для последующего анализа.&lt;/li&gt;
    &lt;li id=&quot;4Prs&quot;&gt;&lt;strong&gt;Таймауты:&lt;/strong&gt; Все HTTP-запросы должны иметь таймаут, чтобы скрипт не зависал.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;4hgU&quot;&gt;&lt;strong&gt;Пример декоратора для повторных попыток:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;gDZK&quot;&gt;import time
import functools

def retry(max_attempts=3, delay=5):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise
                    time.sleep(delay * (attempt + 1))
            return None
        return wrapper
    return decorator&lt;/pre&gt;
  &lt;p id=&quot;C0fR&quot;&gt;&lt;strong&gt;Этап 16: Тестирование и мониторинг работы&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;gx9F&quot;&gt;После настройки автоматизации важно проверять:&lt;/p&gt;
  &lt;ul id=&quot;qrjP&quot;&gt;
    &lt;li id=&quot;oOzj&quot;&gt;&lt;strong&gt;Работоспособность:&lt;/strong&gt; Запустите скрипт вручную и проверьте вывод.&lt;/li&gt;
    &lt;li id=&quot;wIjf&quot;&gt;&lt;strong&gt;Корректность данных:&lt;/strong&gt; Проверьте, что база данных заполняется.&lt;/li&gt;
    &lt;li id=&quot;VQV2&quot;&gt;&lt;strong&gt;Уведомления:&lt;/strong&gt; Убедитесь, что при изменениях приходят сообщения.&lt;/li&gt;
    &lt;li id=&quot;q9Ml&quot;&gt;&lt;strong&gt;Логи:&lt;/strong&gt; Проверьте файл логов на наличие ошибок.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;qdkR&quot;&gt;&lt;/p&gt;
  &lt;ol id=&quot;lHCT&quot;&gt;
    &lt;li id=&quot;Zrfa&quot;&gt;Используйте только публичные API и данные.&lt;/li&gt;
    &lt;li id=&quot;QrPU&quot;&gt;Соблюдайте условия использования сервисов (Shodan, SecurityTrails, GitHub) — не превышайте лимиты запросов.&lt;/li&gt;
    &lt;li id=&quot;U63K&quot;&gt;Не пытайтесь обойти защиту (CAPTCHA, блокировки) нелегальными методами.&lt;/li&gt;
    &lt;li id=&quot;jFYi&quot;&gt;Полученные данные используйте только для законных целей.&lt;/li&gt;
    &lt;li id=&quot;0pRz&quot;&gt;При обнаружении уязвимостей или секретов сообщайте владельцам.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Oyov&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Fd5y&quot;&gt;Автоматизация технического OSINT — это создание программного конвейера, который собирает, обрабатывает и сохраняет данные о цифровой инфраструктуре цели без участия человека. Модульная архитектура на Python с использованием готовых библиотек (dns.resolver, whois, requests, shodan) и внешних API (crt.sh, SecurityTrails, Shodan, GitHub) позволяет охватить все основные источники. Сравнение состояний и уведомления делают систему полезной для долгосрочного мониторинга. Регулярный запуск через cron превращает набор скриптов в постоянно работающую систему разведки.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Code-Repository-Analysis</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Code-Repository-Analysis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Анализ репозиториев кода: GitHub, GitLab, Bitbucket — поиск секретов, утечек кода</title><published>2026-07-07T21:19:19.972Z</published><updated>2026-07-07T21:19:19.972Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/75/ce/75ce4736-9030-4c7c-9296-1e4277e4e647.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/41/f8/41f8f293-6ce2-4c88-ac08-6b6c673de30a.png&quot;&gt;Публичные репозитории кода — это один из наиболее недооцененных, но богатых источников информации в техническом OSINT. Разработчики часто случайно загружают в открытые репозитории конфиденциальные данные: API-ключи, пароли, токены, внутренние URL, логины к базам данных, комментарии с внутренней информацией и даже дампы баз данных. Для специалиста по разведке анализ репозиториев позволяет не только найти чувствительные данные, но и восстановить внутреннюю архитектуру, выявить используемые технологии и даже получить доступ к закрытым системам. Данная статья посвящена методам поиска секретов и утечек кода в публичных репозиториях GitHub, GitLab, Bitbucket и других платформах.</summary><content type="html">
  &lt;figure id=&quot;mAdK&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/41/f8/41f8f293-6ce2-4c88-ac08-6b6c673de30a.png&quot; width=&quot;1102&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;VKhb&quot;&gt;Анализ репозиториев кода: GitHub, GitLab, Bitbucket — поиск секретов, утечек кода&lt;/h3&gt;
  &lt;p id=&quot;6QGp&quot;&gt;Публичные репозитории кода — это один из наиболее недооцененных, но богатых источников информации в техническом OSINT. Разработчики часто случайно загружают в открытые репозитории конфиденциальные данные: API-ключи, пароли, токены, внутренние URL, логины к базам данных, комментарии с внутренней информацией и даже дампы баз данных. Для специалиста по разведке анализ репозиториев позволяет не только найти чувствительные данные, но и восстановить внутреннюю архитектуру, выявить используемые технологии и даже получить доступ к закрытым системам. Данная статья посвящена методам поиска секретов и утечек кода в публичных репозиториях GitHub, GitLab, Bitbucket и других платформах.&lt;/p&gt;
  &lt;p id=&quot;Dbnd&quot;&gt;&lt;strong&gt;Почему публичные репозитории опасны для организации?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;WNta&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4b/f1/4bf1b03a-c594-4470-96d1-1aeeb775b4bc.png&quot; width=&quot;1208&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wJMB&quot;&gt;&lt;strong&gt;Основные платформы для поиска кода&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;KmDM&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7a/c6/7ac69abb-baf5-43bd-a8ed-633ad1c2212f.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;PSOP&quot;&gt;&lt;strong&gt;Этап 1: Базовый поиск на GitHub&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;rwMr&quot;&gt;GitHub предоставляет мощную поисковую систему с операторами. Поиск можно выполнять как через веб-интерфейс, так и через API.&lt;/p&gt;
  &lt;p id=&quot;IRPf&quot;&gt;&lt;strong&gt;Основные операторы GitHub:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;z2qo&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/19/3d/193d2abd-b455-476e-9816-589b97b094c7.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;3eCM&quot;&gt;&lt;strong&gt;Примеры поисковых запросов:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;GC5l&quot;&gt;
    &lt;li id=&quot;LSmm&quot;&gt;Поиск ключей AWS: &lt;code&gt;&amp;quot;AKIA&amp;quot; &amp;quot;SECRET&amp;quot; extension:txt&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;fDwA&quot;&gt;Поиск паролей: &lt;code&gt;password extension:env&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;He6X&quot;&gt;Поиск токенов GitHub: &lt;code&gt;&amp;quot;ghp_&amp;quot; extension:txt&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;pBz1&quot;&gt;Поиск конфигов: &lt;code&gt;filename:.env&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;noLY&quot;&gt;Поиск SSH-ключей: &lt;code&gt;&amp;quot;BEGIN RSA PRIVATE KEY&amp;quot;&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;30A2&quot;&gt;Поиск по домену компании: &lt;code&gt;&amp;quot;example.com&amp;quot; &amp;quot;password&amp;quot;&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;MqNv&quot;&gt;&lt;strong&gt;Использование GitHub API для поиска:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Ndf1&quot;&gt;import requests

GITHUB_TOKEN = &amp;quot;YOUR_TOKEN&amp;quot;
headers = {
    &amp;quot;Authorization&amp;quot;: f&amp;quot;token {GITHUB_TOKEN}&amp;quot;,
    &amp;quot;Accept&amp;quot;: &amp;quot;application/vnd.github.v3+json&amp;quot;
}

def search_github(query):
    url = &amp;quot;https://api.github.com/search/code&amp;quot;
    params = {
        &amp;quot;q&amp;quot;: query,
        &amp;quot;per_page&amp;quot;: 10
    }
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200:
        return response.json()
    else:
        print(f&amp;quot;Ошибка: {response.status_code}&amp;quot;)
        return None

# Поиск .env файлов в организации example
results = search_github(&amp;quot;extension:env org:example&amp;quot;)
if results:
    for item in results.get(&amp;#x27;items&amp;#x27;, []):
        print(f&amp;quot;{item[&amp;#x27;repository&amp;#x27;][&amp;#x27;full_name&amp;#x27;]}: {item[&amp;#x27;path&amp;#x27;]}&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;r6QJ&quot;&gt;&lt;strong&gt;Этап 2: Поиск секретов с использованием TruffleHog&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;cFV9&quot;&gt;TruffleHog — это специализированный инструмент для поиска секретов в репозиториях. Он анализирует историю коммитов, а не только текущие файлы, и использует детекторы для различных типов секретов.&lt;/p&gt;
  &lt;p id=&quot;q2fp&quot;&gt;&lt;strong&gt;Установка и использование:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;WPlJ&quot;&gt;# Установка через pip
pip install trufflehog

# Сканирование репозитория по URL
trufflehog git https://github.com/example/repo.git

# Сканирование всей организации (требуется токен)
trufflehog github --org=example --token=GITHUB_TOKEN&lt;/pre&gt;
  &lt;p id=&quot;1UiM&quot;&gt;&lt;strong&gt;Пример вывода:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;JnmT&quot;&gt;🐷🔑🐷  TruffleHog. Unearth your secrets. 🐷🔑🐷

2024-01-15 10:30:45    INFO    Detector Name: AWS
2024-01-15 10:30:45    INFO    Commit: 3a4b5c6d7e8f9...
2024-01-15 10:30:45    INFO    File: config/credentials.yml
2024-01-15 10:30:45    INFO    Line: 12
2024-01-15 10:30:45    INFO    Secret: AKIAXXXXXXXXXXXXXXXX&lt;/pre&gt;
  &lt;p id=&quot;OD4l&quot;&gt;&lt;strong&gt;Этап 3: Использование GitRob и GitGrab для поиска по организациям&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;HPRa&quot;&gt;&lt;strong&gt;GitRob&lt;/strong&gt; — утилита для поиска ключей и паролей в репозиториях GitHub организаций.&lt;/p&gt;
  &lt;pre id=&quot;SdwD&quot;&gt;gitrob example&lt;/pre&gt;
  &lt;p id=&quot;CX7l&quot;&gt;&lt;strong&gt;GitGrab&lt;/strong&gt; — аналогичный инструмент, фокусирующийся на поиске конфигурационных файлов.&lt;/p&gt;
  &lt;p id=&quot;HdG4&quot;&gt;&lt;strong&gt;Этап 4: Поиск по расширениям файлов&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;xZxq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/59/ab/59abe1ff-9f8b-4472-9a6e-e33701b22f64.png&quot; width=&quot;1215&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;gQLG&quot;&gt;&lt;strong&gt;Поиск на GitHub через веб-интерфейс:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;26NA&quot;&gt;extension:env org:example
extension:yml &amp;quot;password&amp;quot; org:example
extension:json &amp;quot;api_key&amp;quot; org:example&lt;/pre&gt;
  &lt;p id=&quot;W5cu&quot;&gt;&lt;strong&gt;Этап 5: Поиск по строковым шаблонам секретов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;10kk&quot;&gt;Регулярные выражения помогают находить секреты по их формату.&lt;/p&gt;
  &lt;p id=&quot;qI1i&quot;&gt;&lt;strong&gt;Типичные паттерны:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;yYtY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8e/d9/8ed93dd0-835d-4bf9-92d4-d1b27f1a847a.png&quot; width=&quot;1217&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qKHg&quot;&gt;&lt;strong&gt;Пример скрипта для поиска по паттернам в скачанном репозитории:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;XBGR&quot;&gt;import re
import os
import fnmatch

patterns = {
    &amp;#x27;aws&amp;#x27;: re.compile(r&amp;#x27;AKIA[0-9A-Z]{16}&amp;#x27;),
    &amp;#x27;github&amp;#x27;: re.compile(r&amp;#x27;ghp_[0-9a-zA-Z]{36}&amp;#x27;),
    &amp;#x27;slack&amp;#x27;: re.compile(r&amp;#x27;xox[bap]-[0-9a-zA-Z-]+&amp;#x27;),
    &amp;#x27;ssh&amp;#x27;: re.compile(r&amp;#x27;-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----&amp;#x27;),
}

def scan_file(filepath):
    try:
        with open(filepath, &amp;#x27;r&amp;#x27;, encoding=&amp;#x27;utf-8&amp;#x27;, errors=&amp;#x27;ignore&amp;#x27;) as f:
            content = f.read()
            for name, pattern in patterns.items():
                matches = pattern.findall(content)
                if matches:
                    print(f&amp;quot;{filepath}: {name} -&amp;gt; {matches[:3]}&amp;quot;)
    except:
        pass

def scan_repo(repo_path):
    for root, dirs, files in os.walk(repo_path):
        for file in files:
            scan_file(os.path.join(root, file))

# Сканирование локального клона репозитория
scan_repo(&amp;#x27;/path/to/cloned/repo&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;VGRV&quot;&gt;&lt;strong&gt;Этап 6: Поиск через PublicWWW&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;snJC&quot;&gt;PublicWWW — поисковая система, индексирующая HTML, CSS и JavaScript. Можно искать по строкам, которые появляются в коде веб-страниц.&lt;/p&gt;
  &lt;p id=&quot;wcju&quot;&gt;&lt;strong&gt;Использование:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;hhbE&quot;&gt;https://publicwww.com/websites/%22AKIA%22/&lt;/pre&gt;
  &lt;p id=&quot;lwCm&quot;&gt;ищет не только код в репозиториях, но и во всех открытых веб-страницах.&lt;/p&gt;
  &lt;p id=&quot;QmYq&quot;&gt;&lt;strong&gt;Этап 7: Поиск через SearchCode&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;OPcJ&quot;&gt;SearchCode агрегирует данные из GitHub, Bitbucket, GitLab и других источников. У него есть API.&lt;/p&gt;
  &lt;pre id=&quot;ZkHl&quot;&gt;# Поиск через веб-интерфейс
https://searchcode.com/?q=AKIA&amp;amp;p=2&lt;/pre&gt;
  &lt;p id=&quot;F9Rd&quot;&gt;&lt;strong&gt;Этап 8: Мониторинг новых утечек через GitHub&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;xajA&quot;&gt;Новые утечки появляются постоянно. Важно настроить мониторинг на появление новых файлов с секретами.&lt;/p&gt;
  &lt;p id=&quot;yuB8&quot;&gt;&lt;strong&gt;Инструменты для мониторинга:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;w2mG&quot;&gt;
    &lt;li id=&quot;ty7y&quot;&gt;&lt;strong&gt;GitHub Watch&lt;/strong&gt; — подписка на изменения в репозиториях (вручную).&lt;/li&gt;
    &lt;li id=&quot;LDeN&quot;&gt;&lt;strong&gt;HawkScan&lt;/strong&gt; — автоматическое сканирование новых коммитов в организациях.&lt;/li&gt;
    &lt;li id=&quot;MBxb&quot;&gt;&lt;strong&gt;LeakIX&lt;/strong&gt; — поисковик утечек, отправляет уведомления.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;3s6Z&quot;&gt;&lt;strong&gt;Собственный мониторинг через GitHub API:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;j80i&quot;&gt;def monitor_new_commits(org, last_check_file):
    # Получение последних коммитов в организации
    # Сравнение с предыдущим состоянием
    # При обнаружении секретов — уведомление
    pass&lt;/pre&gt;
  &lt;p id=&quot;zSsa&quot;&gt;&lt;strong&gt;Этап 9: Анализ истории коммитов (продвинутый уровень)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;KWaZ&quot;&gt;Git сохраняет историю изменений. Даже если секрет был удалён в последнем коммите, он может остаться в истории.&lt;/p&gt;
  &lt;p id=&quot;F8NS&quot;&gt;&lt;strong&gt;Поиск в истории через TruffleHog:&lt;/strong&gt; (см. выше) сканирует всю историю.&lt;/p&gt;
  &lt;p id=&quot;wHpW&quot;&gt;&lt;strong&gt;Поиск в локально скачанном репозитории:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;fcIJ&quot;&gt;# Поиск по всем коммитам в Git
git log -p | grep -i &amp;quot;password&amp;quot;
git log -p | grep -i &amp;quot;AKIA&amp;quot;
git log -p | grep -i &amp;quot;ghp_&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;ljOn&quot;&gt;&lt;strong&gt;Этап 10: Восстановление удалённых файлов из истории Git&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;I2Ph&quot;&gt;Даже если файл был удалён, он может быть восстановлен через Git.&lt;/p&gt;
  &lt;pre id=&quot;af7v&quot;&gt;# Поиск файла в истории
git log --all --full-history -- &amp;quot;*config*&amp;quot;

# Восстановление файла
git show &amp;lt;commit_hash&amp;gt;:path/to/file&lt;/pre&gt;
  &lt;p id=&quot;BZfN&quot;&gt;&lt;strong&gt;Этап 11: Поиск в GitLab и Bitbucket&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4HQQ&quot;&gt;&lt;strong&gt;GitLab:&lt;/strong&gt; общедоступные проекты можно искать через поиск GitLab. Операторы: &lt;code&gt;group:&lt;/code&gt;, &lt;code&gt;project:&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;e9D7&quot;&gt;&lt;strong&gt;Пример:&lt;/strong&gt; &lt;code&gt;https://gitlab.com/search?search=password&amp;amp;group_id=123&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;7Xqm&quot;&gt;&lt;strong&gt;Bitbucket:&lt;/strong&gt; аналогично, через поиск или API.&lt;/p&gt;
  &lt;p id=&quot;bLII&quot;&gt;&lt;strong&gt;Сводная таблица инструментов поиска секретов&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;zNh5&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/46/3f/463f334a-ab66-4b43-b674-aea0df356bb5.png&quot; width=&quot;1008&quot; /&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;fNWr&quot;&gt;
    &lt;li id=&quot;nZy8&quot;&gt;&lt;strong&gt;Никогда не используйте найденные секреты для несанкционированного доступа.&lt;/strong&gt; Это уголовное преступление.&lt;/li&gt;
    &lt;li id=&quot;9kKb&quot;&gt;Если вы нашли секреты, принадлежащие организации, &lt;strong&gt;сообщите им&lt;/strong&gt; через официальные каналы (security@example.com) или через программу Bug Bounty.&lt;/li&gt;
    &lt;li id=&quot;ZGJD&quot;&gt;&lt;strong&gt;Не распространяйте&lt;/strong&gt; найденные секреты публично.&lt;/li&gt;
    &lt;li id=&quot;zboL&quot;&gt;При сканировании соблюдайте условия использования платформ (GitHub, GitLab) — чрезмерные запросы могут привести к блокировке IP.&lt;/li&gt;
    &lt;li id=&quot;YQTz&quot;&gt;В некоторых юрисдикциях даже поиск секретов может считаться нарушением, если он ведётся без разрешения. Ориентируйтесь на публичные данные.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;mP6d&quot;&gt;&lt;strong&gt;Практический пример: расследование утечки токенов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;6lPI&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; найти все токены, связанные с организацией &lt;code&gt;example.com&lt;/code&gt;, и проинформировать их.&lt;/p&gt;
  &lt;ol id=&quot;M9a4&quot;&gt;
    &lt;li id=&quot;XW1v&quot;&gt;&lt;strong&gt;GitHub Search:&lt;/strong&gt; &lt;code&gt;&amp;quot;example.com&amp;quot; &amp;quot;token&amp;quot; extension:env&lt;/code&gt; → найдено 3 файла &lt;code&gt;.env&lt;/code&gt; с токенами для Stripe, AWS и Slack.&lt;/li&gt;
    &lt;li id=&quot;CJV4&quot;&gt;&lt;strong&gt;TruffleHog:&lt;/strong&gt; сканирование организации &lt;code&gt;example&lt;/code&gt; → обнаружен AWS-ключ в старом коммите (уже удалённом из кода, но оставшемся в истории).&lt;/li&gt;
    &lt;li id=&quot;zJlT&quot;&gt;&lt;strong&gt;PublicWWW:&lt;/strong&gt; поиск &lt;code&gt;&amp;quot;AKIA&amp;quot; &amp;quot;example.com&amp;quot;&lt;/code&gt; → найден HTML-файл со скриптом, содержащим Google Maps API ключ.&lt;/li&gt;
    &lt;li id=&quot;THYG&quot;&gt;&lt;strong&gt;Связь:&lt;/strong&gt; ключи принадлежат компании &lt;code&gt;example.com&lt;/code&gt; (проверено по домену в комментариях).&lt;/li&gt;
    &lt;li id=&quot;F3JF&quot;&gt;&lt;strong&gt;Сообщение:&lt;/strong&gt; отправка письма на security@example.com с перечнем найденных токенов и рекомендацией по их отзыву и ротации.&lt;/li&gt;
    &lt;li id=&quot;VIqS&quot;&gt;&lt;strong&gt;Результат:&lt;/strong&gt; компания подтвердила получение, отозвала скомпрометированные ключи, обновила политику безопасности.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;HXU0&quot;&gt;Анализ публичных репозиториев кода — один из самых результативных методов технического OSINT. Комбинация GitHub-поиска с операторами, специализированных инструментов (TruffleHog, GitRob) и анализа истории коммитов позволяет находить секреты, пароли и утечки кода, которые случайно попали в открытый доступ. Важно использовать полученную информацию ответственно и этично: сообщать о находках владельцам, а не использовать их для атак.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:psheasJMkJG</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/psheasJMkJG?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Мониторинг изменений инфраструктуры: уведомления о новых поддоменах, сертификатах, изменениях в DNS</title><published>2026-07-06T05:11:38.614Z</published><updated>2026-07-06T05:12:16.435Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/13/86/1386e3cf-dbb6-410b-b229-2d238476136a.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/5d/35/5d3562b7-5004-4f7d-abda-b6e306585276.png&quot;&gt;Инфраструктура организации не статична. Появляются новые поддомены, меняются IP-адреса, выпускаются новые сертификаты, обновляются технологии. Для специалиста по техническому OSINT отслеживание этих изменений критически важно: новые поддомены могут раскрыть неанонсированные проекты, свежие сертификаты — указать на новые серверы, а изменения в DNS — на смену хостинг-провайдера или CDN. Мониторинг изменений позволяет реагировать на появление новых активов в реальном времени, не дожидаясь, пока они будут обнаружены случайно. Данная статья посвящена методам и инструментам мониторинга инфраструктуры, а также настройке автоматических уведомлений.</summary><content type="html">
  &lt;figure id=&quot;Gequ&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5d/35/5d3562b7-5004-4f7d-abda-b6e306585276.png&quot; width=&quot;1102&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;tT7R&quot;&gt;Мониторинг изменений инфраструктуры: уведомления о новых поддоменах, сертификатах, изменениях в DNS&lt;/h3&gt;
  &lt;p id=&quot;NCqc&quot;&gt;Инфраструктура организации не статична. Появляются новые поддомены, меняются IP-адреса, выпускаются новые сертификаты, обновляются технологии. Для специалиста по техническому OSINT отслеживание этих изменений критически важно: новые поддомены могут раскрыть неанонсированные проекты, свежие сертификаты — указать на новые серверы, а изменения в DNS — на смену хостинг-провайдера или CDN. Мониторинг изменений позволяет реагировать на появление новых активов в реальном времени, не дожидаясь, пока они будут обнаружены случайно. Данная статья посвящена методам и инструментам мониторинга инфраструктуры, а также настройке автоматических уведомлений.&lt;/p&gt;
  &lt;p id=&quot;fpSv&quot;&gt;&lt;strong&gt;Зачем мониторить изменения?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;5OhT&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d1/9f/d19fd63f-faf9-4b1b-9054-2eae791cf5ee.png&quot; width=&quot;1210&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Ov5j&quot;&gt;&lt;strong&gt;Типы мониторинга изменений&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;62bO&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8a/f4/8af402fc-ba40-4415-bf0a-0358ca89c470.png&quot; width=&quot;1202&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WRxS&quot;&gt;&lt;strong&gt;Этап 1: Мониторинг поддоменов через crt.sh и CertSpotter&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;yJTl&quot;&gt;&lt;strong&gt;crt.sh&lt;/strong&gt; позволяет выполнять поиск новых сертификатов для домена. Поскольку каждый новый сертификат (и соответственно, поддомен) попадает в CT-логи, crt.sh — идеальный источник для обнаружения новых поддоменов.&lt;/p&gt;
  &lt;p id=&quot;XyoT&quot;&gt;&lt;strong&gt;Алгоритм мониторинга:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;dSuP&quot;&gt;
    &lt;li id=&quot;jv1Y&quot;&gt;Ежедневно выполнять запрос к crt.sh: &lt;code&gt;?q=%.example.com&amp;amp;output=json&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;TOGG&quot;&gt;Сравнивать полученный список доменов с предыдущим.&lt;/li&gt;
    &lt;li id=&quot;lxHF&quot;&gt;При появлении новых — отправлять уведомление.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;lDAZ&quot;&gt;&lt;strong&gt;Пример скрипта для мониторинга поддоменов через crt.sh:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;CqNJ&quot;&gt;import requests
import json
import time
import hashlib

def get_subdomains(domain):
    url = f&amp;quot;https://crt.sh/?q=%25.{domain}&amp;amp;output=json&amp;quot;
    try:
        resp = requests.get(url, timeout=30)
        if resp.status_code == 200:
            data = resp.json()
            subdomains = set()
            for entry in data:
                name = entry.get(&amp;#x27;name_value&amp;#x27;, &amp;#x27;&amp;#x27;)
                if name.endswith(f&amp;#x27;.{domain}&amp;#x27;) or name == domain:
                    subdomains.add(name.lower())
            return sorted(subdomains)
    except Exception as e:
        print(f&amp;quot;Ошибка crt.sh: {e}&amp;quot;)
    return []

def monitor_subdomains(domain, state_file=&amp;#x27;subdomains_state.json&amp;#x27;):
    # Загрузка предыдущего состояния
    try:
        with open(state_file, &amp;#x27;r&amp;#x27;) as f:
            previous = set(json.load(f))
    except:
        previous = set()
    
    # Получение текущего состояния
    current = set(get_subdomains(domain))
    
    # Поиск изменений
    new = current - previous
    removed = previous - current
    
    if new:
        print(f&amp;quot;Новые поддомены: {&amp;#x27;, &amp;#x27;.join(new)}&amp;quot;)
        # Здесь отправка уведомления
    if removed:
        print(f&amp;quot;Удалены: {&amp;#x27;, &amp;#x27;.join(removed)}&amp;quot;)
    
    # Сохранение состояния
    with open(state_file, &amp;#x27;w&amp;#x27;) as f:
        json.dump(list(current), f)
    
    return new, removed

# Запуск ежедневно
monitor_subdomains(&amp;#x27;example.com&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;MSr8&quot;&gt;&lt;strong&gt;CertSpotter&lt;/strong&gt; — сервис, который автоматически отслеживает новые сертификаты для указанных доменов и присылает уведомления по email. Бесплатно до 10 доменов.&lt;/p&gt;
  &lt;p id=&quot;24uH&quot;&gt;&lt;strong&gt;Как настроить CertSpotter:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;ZEyZ&quot;&gt;
    &lt;li id=&quot;Rrmf&quot;&gt;Зарегистрироваться на &lt;a href=&quot;https://sslmate.com/certspotter&quot; target=&quot;_blank&quot;&gt;sslmate.com/certspotter&lt;/a&gt;.&lt;/li&gt;
    &lt;li id=&quot;ffwu&quot;&gt;Добавить домены для мониторинга.&lt;/li&gt;
    &lt;li id=&quot;Y8e2&quot;&gt;Получать уведомления о новых сертификатах (с указанием SAN и даты истечения).&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;s639&quot;&gt;&lt;strong&gt;Этап 2: Мониторинг DNS-изменений&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;KUsB&quot;&gt;Изменения DNS-записей могут указывать на смену хостинга, добавление новых сервисов или изменение почтовой инфраструктуры.&lt;/p&gt;
  &lt;p id=&quot;mtga&quot;&gt;&lt;strong&gt;Инструменты для мониторинга DNS:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;2y9b&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c8/37/c83747d2-07e9-4d0f-b90d-d4483b1ceb0d.png&quot; width=&quot;1001&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tx2b&quot;&gt;&lt;strong&gt;Собственный скрипт для мониторинга DNS-записей(пример):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Ola2&quot;&gt;import dns.resolver
import json
import time

def get_dns_records(domain, record_types=[&amp;#x27;A&amp;#x27;, &amp;#x27;MX&amp;#x27;, &amp;#x27;TXT&amp;#x27;, &amp;#x27;NS&amp;#x27;, &amp;#x27;CNAME&amp;#x27;]):
    records = {}
    for rtype in record_types:
        try:
            answers = dns.resolver.resolve(domain, rtype)
            records[rtype] = [str(r) for r in answers]
        except:
            records[rtype] = []
    return records

def monitor_dns(domain, state_file=&amp;#x27;dns_state.json&amp;#x27;):
    try:
        with open(state_file, &amp;#x27;r&amp;#x27;) as f:
            previous = json.load(f)
    except:
        previous = {}
    
    current = get_dns_records(domain)
    
    changes = {}
    for rtype in set(previous.keys()) | set(current.keys()):
        prev = previous.get(rtype, [])
        curr = current.get(rtype, [])
        if set(prev) != set(curr):
            changes[rtype] = {
                &amp;#x27;old&amp;#x27;: prev,
                &amp;#x27;new&amp;#x27;: curr
            }
    
    if changes:
        print(f&amp;quot;DNS изменения для {domain}:&amp;quot;)
        for rtype, change in changes.items():
            print(f&amp;quot;  {rtype}: {change[&amp;#x27;old&amp;#x27;]} → {change[&amp;#x27;new&amp;#x27;]}&amp;quot;)
        # здесь отправка уведомления
    
    with open(state_file, &amp;#x27;w&amp;#x27;) as f:
        json.dump(current, f)
    
    return changes

# Запуск
monitor_dns(&amp;#x27;example.com&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;6EiM&quot;&gt;&lt;strong&gt;Этап 3: Мониторинг SSL-сертификатов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;qROE&quot;&gt;Новые SSL-сертификаты часто появляются при запуске новых серверов или обновлении старых.&lt;/p&gt;
  &lt;p id=&quot;sYwt&quot;&gt;&lt;strong&gt;CertSpotter&lt;/strong&gt; (см. выше) — лучший бесплатный способ мониторинга.&lt;/p&gt;
  &lt;p id=&quot;1fUQ&quot;&gt;&lt;strong&gt;Альтернатива: регулярный запрос к crt.sh с фильтром по дате:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;QlnO&quot;&gt;https://crt.sh/?q=%.example.com&amp;amp;exclude=expired&amp;amp;limit=100&amp;amp;output=json&lt;/pre&gt;
  &lt;p id=&quot;PHcN&quot;&gt;&lt;strong&gt;Скрипт для отслеживания сертификатов, истекающих в ближайшее время:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;2KUX&quot;&gt;import requests
from datetime import datetime, timedelta

def get_expiring_certs(domain, days=30):
    url = f&amp;quot;https://crt.sh/?q=%25.{domain}&amp;amp;output=json&amp;quot;
    resp = requests.get(url)
    if resp.status_code == 200:
        data = resp.json()
        expiring = []
        now = datetime.now()
        for entry in data:
            if len(entry) &amp;lt; 5:
                continue
            valid_to = entry[4]  # дата истечения
            if valid_to:
                try:
                    exp_date = datetime.strptime(valid_to, &amp;#x27;%Y-%m-%dT%H:%M:%S&amp;#x27;)
                    if (exp_date - now).days &amp;lt; days:
                        expiring.append({
                            &amp;#x27;name&amp;#x27;: entry[1],
                            &amp;#x27;expires&amp;#x27;: valid_to
                        })
                except:
                    pass
        return expiring
    return []

expiring = get_expiring_certs(&amp;#x27;example.com&amp;#x27;, 30)
for cert in expiring:
    print(f&amp;quot;Сертификат для {cert[&amp;#x27;name&amp;#x27;]} истекает {cert[&amp;#x27;expires&amp;#x27;]}&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;8u5H&quot;&gt;&lt;strong&gt;Этап 4: Мониторинг изменений контента сайта&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;0xtu&quot;&gt;Изменения на сайте (новые страницы, обновлённый текст, новые файлы) могут указывать на новые проекты, изменения в стратегии или утечку информации.&lt;/p&gt;
  &lt;p id=&quot;VtFO&quot;&gt;&lt;strong&gt;Инструменты для мониторинга изменений страниц:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;aOaS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/4e/1b4e0528-83d5-469d-a274-88b4c724f74a.png&quot; width=&quot;1200&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HkBP&quot;&gt;&lt;strong&gt;Пример использования &lt;a href=&quot;https://changedetection.io/&quot; target=&quot;_blank&quot;&gt;Changedetection.io&lt;/a&gt; (Docker):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;nTLh&quot;&gt;docker run -d --name changedetection -p 5000:5000 ghcr.io/dgtlmoon/changedetection.io&lt;/pre&gt;
  &lt;p id=&quot;SOTs&quot;&gt;Затем через веб-интерфейс добавить URL для мониторинга, настроить интервал проверки и канал уведомлений.&lt;/p&gt;
  &lt;p id=&quot;eiRY&quot;&gt;&lt;strong&gt;Собственный скрипт мониторинга контента (с хэшированием)&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;1Sxo&quot;&gt;import requests
import hashlib
import json
import time

def fetch_page_hash(url):
    try:
        resp = requests.get(url, timeout=10)
        return hashlib.sha256(resp.text.encode()).hexdigest()
    except:
        return None

def monitor_url(url, state_file=&amp;#x27;url_state.json&amp;#x27;):
    try:
        with open(state_file, &amp;#x27;r&amp;#x27;) as f:
            state = json.load(f)
            previous_hash = state.get(url)
    except:
        previous_hash = None
    
    current_hash = fetch_page_hash(url)
    if current_hash and current_hash != previous_hash:
        print(f&amp;quot;Страница {url} изменилась!&amp;quot;)
        # уведомление
        state[url] = current_hash
        with open(state_file, &amp;#x27;w&amp;#x27;) as f:
            json.dump(state, f)
        return True
    return False

# Мониторинг нескольких страниц
urls = [&amp;#x27;https://example.com&amp;#x27;, &amp;#x27;https://example.com/about&amp;#x27;]
for url in urls:
    monitor_url(url)&lt;/pre&gt;
  &lt;p id=&quot;VEeE&quot;&gt;&lt;strong&gt;Этап 5: Мониторинг WHOIS-изменений&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;wNf4&quot;&gt;Изменения в WHOIS (смена владельца, регистратора, дат) могут указывать на продажу домена или смену контактов.&lt;/p&gt;
  &lt;p id=&quot;Y8D3&quot;&gt;&lt;strong&gt;Инструменты:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;9Pgx&quot;&gt;
    &lt;li id=&quot;rVQY&quot;&gt;&lt;strong&gt;DomainTools&lt;/strong&gt; (платный мониторинг).&lt;/li&gt;
    &lt;li id=&quot;MW33&quot;&gt;&lt;strong&gt;WhoisXML API&lt;/strong&gt; (есть платный мониторинг).&lt;/li&gt;
    &lt;li id=&quot;eAno&quot;&gt;&lt;strong&gt;Собственные скрипты&lt;/strong&gt; через &lt;code&gt;whois&lt;/code&gt; и сравнение.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;qNM9&quot;&gt;&lt;strong&gt;Пример мониторинга WHOIS (с использованием python-whois):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;R2Fh&quot;&gt;import whois
import json
import time

def get_whois_info(domain):
    try:
        w = whois.whois(domain)
        return {
            &amp;#x27;registrar&amp;#x27;: w.registrar,
            &amp;#x27;creation_date&amp;#x27;: str(w.creation_date),
            &amp;#x27;expiration_date&amp;#x27;: str(w.expiration_date),
            &amp;#x27;name_servers&amp;#x27;: w.name_servers,
            &amp;#x27;emails&amp;#x27;: w.emails
        }
    except:
        return None

def monitor_whois(domain, state_file=&amp;#x27;whois_state.json&amp;#x27;):
    try:
        with open(state_file, &amp;#x27;r&amp;#x27;) as f:
            previous = json.load(f)
    except:
        previous = {}
    
    current = get_whois_info(domain)
    if current and current != previous:
        print(f&amp;quot;WHOIS для {domain} изменился!&amp;quot;)
        # Здесь уведомление
        with open(state_file, &amp;#x27;w&amp;#x27;) as f:
            json.dump(current, f)
        return True
    return False

monitor_whois(&amp;#x27;example.com&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;Md20&quot;&gt;&lt;strong&gt;Этап 6: Мониторинг технологического стека (Wappalyzer)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;gmKD&quot;&gt;Изменения в технологиях могут указывать на обновление CMS, переход на новый фреймворк.&lt;/p&gt;
  &lt;p id=&quot;KP0f&quot;&gt;&lt;strong&gt;Метод:&lt;/strong&gt; периодически запускать Wappalyzer CLI и сравнивать результаты.&lt;/p&gt;
  &lt;p id=&quot;Qv4W&quot;&gt;&lt;strong&gt;Пример (через subprocess):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;sI08&quot;&gt;import subprocess
import json

def get_tech_stack(url):
    result = subprocess.run([&amp;#x27;wappalyzer&amp;#x27;, url], capture_output=True, text=True)
    if result.returncode == 0:
        return json.loads(result.stdout)
    return None

# Сравнение результатов за разные даты&lt;/pre&gt;
  &lt;p id=&quot;zHqJ&quot;&gt;&lt;strong&gt;Этап 7: Мониторинг через агрегаторы (SecurityTrails, Censys)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;SA2T&quot;&gt;SecurityTrails предлагает функцию мониторинга (Alerts) для платных подписок. Вы можете отслеживать:&lt;/p&gt;
  &lt;ul id=&quot;rAqC&quot;&gt;
    &lt;li id=&quot;tzSd&quot;&gt;Новые поддомены.&lt;/li&gt;
    &lt;li id=&quot;AxBP&quot;&gt;Изменения в DNS-записях.&lt;/li&gt;
    &lt;li id=&quot;4XrC&quot;&gt;Изменения в WHOIS.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;aB7g&quot;&gt;&lt;strong&gt;Censys&lt;/strong&gt; позволяет отслеживать изменения в сертификатах и открытых портах.&lt;/p&gt;
  &lt;p id=&quot;sYIQ&quot;&gt;&lt;strong&gt;Этап 8: Настройка уведомлений&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;6X2c&quot;&gt;После обнаружения изменений важно получать уведомления в удобном формате.&lt;/p&gt;
  &lt;p id=&quot;jPxS&quot;&gt;&lt;strong&gt;Способы уведомлений:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;ntWd&quot;&gt;
    &lt;li id=&quot;IRsc&quot;&gt;&lt;strong&gt;Email&lt;/strong&gt; (через &lt;code&gt;smtplib&lt;/code&gt; в Python или сервисы типа SendGrid).&lt;/li&gt;
    &lt;li id=&quot;SRSx&quot;&gt;&lt;strong&gt;Telegram Bot&lt;/strong&gt; (см. код ниже).&lt;/li&gt;
    &lt;li id=&quot;6Hsq&quot;&gt;&lt;strong&gt;Slack / Discord&lt;/strong&gt; (вебхуки).&lt;/li&gt;
    &lt;li id=&quot;XZPw&quot;&gt;&lt;strong&gt;SMS&lt;/strong&gt; (платные сервисы).&lt;/li&gt;
    &lt;li id=&quot;vPJh&quot;&gt;&lt;strong&gt;Pushover&lt;/strong&gt; (мобильные уведомления).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7s9D&quot;&gt;&lt;strong&gt;Пример уведомления через Telegram-бота:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;snwl&quot;&gt;import requests

def send_telegram_alert(token, chat_id, message):
    url = f&amp;quot;https://api.telegram.org/bot{token}/sendMessage&amp;quot;
    payload = {
        &amp;#x27;chat_id&amp;#x27;: chat_id,
        &amp;#x27;text&amp;#x27;: message
    }
    requests.post(url, json=payload)

# Использование
send_telegram_alert(&amp;#x27;YOUR_BOT_TOKEN&amp;#x27;, &amp;#x27;YOUR_CHAT_ID&amp;#x27;, &amp;#x27;Обнаружены новые поддомены: dev.example.com, test.example.com&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;6N81&quot;&gt;&lt;strong&gt;Этап 9: Полный конвейер мониторинга&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;J6t9&quot;&gt;Для эффективного мониторинга все инструменты можно объединить в единый конвейер:&lt;/p&gt;
  &lt;ol id=&quot;Ux1V&quot;&gt;
    &lt;li id=&quot;Iug1&quot;&gt;&lt;strong&gt;Ежедневный запуск&lt;/strong&gt; (через cron или Task Scheduler).&lt;/li&gt;
    &lt;li id=&quot;eZlX&quot;&gt;&lt;strong&gt;Проверка поддоменов&lt;/strong&gt; (crt.sh, SecurityTrails).&lt;/li&gt;
    &lt;li id=&quot;zq6u&quot;&gt;&lt;strong&gt;Проверка DNS&lt;/strong&gt; (собственный скрипт).&lt;/li&gt;
    &lt;li id=&quot;FUvN&quot;&gt;&lt;strong&gt;Проверка SSL-сертификатов&lt;/strong&gt; (CertSpotter / crt.sh).&lt;/li&gt;
    &lt;li id=&quot;hFoy&quot;&gt;&lt;strong&gt;Проверка контента&lt;/strong&gt; (&lt;a href=&quot;https://changedetection.io/&quot; target=&quot;_blank&quot;&gt;Changedetection.io&lt;/a&gt; / собственный скрипт).&lt;/li&gt;
    &lt;li id=&quot;dZ4j&quot;&gt;&lt;strong&gt;Проверка WHOIS&lt;/strong&gt; (собственный скрипт).&lt;/li&gt;
    &lt;li id=&quot;DOVx&quot;&gt;&lt;strong&gt;Сбор изменений в единый отчёт&lt;/strong&gt;.&lt;/li&gt;
    &lt;li id=&quot;M1WK&quot;&gt;&lt;strong&gt;Отправка уведомления&lt;/strong&gt; (Telegram, Email).&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;QEu9&quot;&gt;&lt;strong&gt;Пример крона для ежедневного запуска:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;MkeQ&quot;&gt;0 8 * * * /usr/bin/python3 /path/to/monitor_all.py&lt;/pre&gt;
  &lt;p id=&quot;r3s7&quot;&gt;&lt;strong&gt;Практический пример: мониторинг компании-конкурента&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;kRBz&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; отслеживать изменения в инфраструктуре конкурента &lt;code&gt;compete.com&lt;/code&gt;.&lt;/p&gt;
  &lt;ol id=&quot;FVny&quot;&gt;
    &lt;li id=&quot;31M9&quot;&gt;&lt;strong&gt;Настройка CertSpotter&lt;/strong&gt; для &lt;code&gt;compete.com&lt;/code&gt; и &lt;code&gt;*.compete.com&lt;/code&gt; → получение уведомлений о новых сертификатах.&lt;/li&gt;
    &lt;li id=&quot;7CMW&quot;&gt;&lt;strong&gt;Ежедневный скрипт для crt.sh&lt;/strong&gt; → запись всех поддоменов, сравнение с предыдущим днём. При появлении нового отправка в Telegram.&lt;/li&gt;
    &lt;li id=&quot;UJoY&quot;&gt;&lt;strong&gt;Мониторинг DNS&lt;/strong&gt; → раз в неделю проверка A, MX, TXT записей. При изменении — уведомление.&lt;/li&gt;
    &lt;li id=&quot;Rlr9&quot;&gt;&lt;strong&gt;Мониторинг сайта&lt;/strong&gt; → &lt;a href=&quot;https://changedetection.io/&quot; target=&quot;_blank&quot;&gt;Changedetection.io&lt;/a&gt; для главной страницы и страницы &lt;code&gt;/careers&lt;/code&gt; (появление новых вакансий может указывать на расширение).&lt;/li&gt;
    &lt;li id=&quot;zUNw&quot;&gt;&lt;strong&gt;Обнаружение:&lt;/strong&gt; спустя неделю появился поддомен &lt;code&gt;app.compete.com&lt;/code&gt;. В сертификате указан AWS CloudFront. Это указывает на запуск нового веб-приложения. Мониторинг подтверждает, что сайт стал доступен.&lt;/li&gt;
    &lt;li id=&quot;ppFL&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; компания запускает новый продукт. Информация может быть использована для анализа конкурентной среды.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;RERN&quot;&gt;&lt;strong&gt;Инструменты для мониторинга (сводная таблица)&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;v4eg&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/8f/828f6cd1-af48-4243-a065-92298fa6e6fd.png&quot; width=&quot;1196&quot; /&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;Bykc&quot;&gt;
    &lt;li id=&quot;9WoA&quot;&gt;Мониторинг публичных данных (DNS, сертификаты, поддомены, WHOIS) легален.&lt;/li&gt;
    &lt;li id=&quot;nHkY&quot;&gt;Использование автоматизированных скриптов для частых запросов к crt.sh или другим сервисам должно соответствовать их условиям использования (не превышать лимиты).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ul id=&quot;JUE2&quot;&gt;
    &lt;li id=&quot;pJrS&quot;&gt;Если вы мониторите конкурента, не нарушайте законы о коммерческой тайне и не используйте методы, требующие несанкционированного доступа.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;O9AX&quot;&gt;Мониторинг изменений инфраструктуры — это непрерывный процесс, позволяющий быть в курсе всех изменений в цифровых активах цели. Комбинация автоматических скриптов (crt.sh, DNS, WHOIS), готовых сервисов (CertSpotter, Changedetection) и уведомлений (Telegram) создаёт систему раннего обнаружения новых поддоменов, сертификатов, DNS-записей и контента. Это позволяет оперативно реагировать на появление новых проектов, смену хостинга и другие изменения, важные для технической разведки.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Site-History-Analysis</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Site-History-Analysis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Анализ истории сайта: Wayback Machine, изменения контента, скрытые страницы</title><published>2026-06-27T17:59:12.899Z</published><updated>2026-06-27T17:59:12.899Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/51/6f/516f6185-e099-45da-ac77-465dd4dbb7a1.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/aa/f8/aaf8fd7c-7439-4b18-a2d7-f476ccf27f73.png&quot;&gt;Веб-сайты постоянно меняются: дизайн обновляется, контент редактируется, страницы удаляются, а новые появляются. Однако интернет «помнит» многие из этих изменений благодаря архивам, таким как Wayback Machine. Для специалиста по техническому OSINT анализ истории сайта — это способ заглянуть в прошлое: восстановить удалённые страницы, найти забытые поддомены, обнаружить конфиденциальную информацию, которая была случайно опубликована, а затем удалена, а также проследить эволюцию политики и контента организации. Данная статья посвящена методам работы с веб-архивами, анализу изменений и поиску скрытых страниц.</summary><content type="html">
  &lt;figure id=&quot;P6ZY&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/aa/f8/aaf8fd7c-7439-4b18-a2d7-f476ccf27f73.png&quot; width=&quot;1102&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;sbQM&quot;&gt;Анализ истории сайта: Wayback Machine, изменения контента, скрытые страницы&lt;/h3&gt;
  &lt;p id=&quot;7bcm&quot;&gt;Веб-сайты постоянно меняются: дизайн обновляется, контент редактируется, страницы удаляются, а новые появляются. Однако интернет «помнит» многие из этих изменений благодаря архивам, таким как Wayback Machine. Для специалиста по техническому OSINT анализ истории сайта — это способ заглянуть в прошлое: восстановить удалённые страницы, найти забытые поддомены, обнаружить конфиденциальную информацию, которая была случайно опубликована, а затем удалена, а также проследить эволюцию политики и контента организации. Данная статья посвящена методам работы с веб-архивами, анализу изменений и поиску скрытых страниц.&lt;/p&gt;
  &lt;p id=&quot;okS7&quot;&gt;&lt;strong&gt;Зачем анализировать историю сайта?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;0QXn&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/da/43/da434446-5147-4d3f-b937-5ef373012460.png&quot; width=&quot;1114&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ASRd&quot;&gt;&lt;strong&gt;Основные архивы веба&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;fBRy&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1d/16/1d16ac4a-295b-4b69-93a1-f2083fbe1fa1.png&quot; width=&quot;1145&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1fy2&quot;&gt;&lt;strong&gt;Этап 1: Поиск истории сайта в Wayback Machine&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;DsXl&quot;&gt;&lt;strong&gt;Прямой доступ к архиву:&lt;/strong&gt; &lt;code&gt;https://web.archive.org/web/*/https://example.com&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;vxBs&quot;&gt;&lt;strong&gt;Что можно увидеть:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;zGAA&quot;&gt;
    &lt;li id=&quot;ilH3&quot;&gt;Календарь сохранений (синие кружки — даты, когда страница была сохранена).&lt;/li&gt;
    &lt;li id=&quot;qwcU&quot;&gt;Выбор конкретной даты.&lt;/li&gt;
    &lt;li id=&quot;eW1e&quot;&gt;Сравнение двух снимков (инструмент &amp;quot;Compare&amp;quot;).&lt;/li&gt;
    &lt;li id=&quot;dGXK&quot;&gt;Доступ к сохранённым изображениям, CSS, JS (частично).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;VBLJ&quot;&gt;&lt;strong&gt;Основные параметры Wayback Machine API:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;wqiE&quot;&gt;
    &lt;li id=&quot;zt79&quot;&gt;&lt;code&gt;https://archive.org/wayback/available?url=https://example.com&lt;/code&gt; — проверка, есть ли архив для URL.&lt;/li&gt;
    &lt;li id=&quot;gjES&quot;&gt;&lt;code&gt;https://web.archive.org/cdx/search/cdx?url=example.com&amp;amp;output=json&lt;/code&gt; — список всех сохранений в JSON (для массового сбора).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;zfY1&quot;&gt;&lt;strong&gt;Пример API-запроса (Python):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;yarb&quot;&gt;import requests
import json

def get_wayback_snapshots(url):
    cdx_url = f&amp;quot;https://web.archive.org/cdx/search/cdx?url={url}&amp;amp;output=json&amp;quot;
    resp = requests.get(cdx_url)
    if resp.status_code == 200:
        data = resp.json()
        if len(data) &amp;gt; 1:
            snapshots = []
            for row in data[1:]:  # первая строка — заголовки
                timestamp = row[1]
                snapshot_url = f&amp;quot;https://web.archive.org/web/{timestamp}/{url}&amp;quot;
                snapshots.append({
                    &amp;#x27;timestamp&amp;#x27;: timestamp,
                    &amp;#x27;url&amp;#x27;: snapshot_url
                })
            return snapshots
    return []

snapshots = get_wayback_snapshots(&amp;#x27;example.com&amp;#x27;)
for s in snapshots[:5]:
    print(s[&amp;#x27;timestamp&amp;#x27;], s[&amp;#x27;url&amp;#x27;])&lt;/pre&gt;
  &lt;p id=&quot;cxWS&quot;&gt;&lt;strong&gt;Этап 2: Поиск удалённых страниц и контента&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Zk9K&quot;&gt;Один из основных способов использования архива — найти страницы, которые были удалены с сайта, но сохранились в Wayback Machine.&lt;/p&gt;
  &lt;p id=&quot;15wh&quot;&gt;&lt;strong&gt;Методика:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;LwMa&quot;&gt;
    &lt;li id=&quot;spP2&quot;&gt;Определить URL-шаблоны (например, &lt;code&gt;/blog/&lt;/code&gt;, &lt;code&gt;/docs/&lt;/code&gt;, &lt;code&gt;/downloads/&lt;/code&gt;).&lt;/li&gt;
    &lt;li id=&quot;dOaN&quot;&gt;Искать в архиве конкретные URL.&lt;/li&gt;
    &lt;li id=&quot;U896&quot;&gt;Использовать оператор &lt;code&gt;*&lt;/code&gt; для поиска всех сохранённых страниц с определённым префиксом.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;JwKO&quot;&gt;&lt;strong&gt;Пример поиска всех файлов &lt;code&gt;.pdf&lt;/code&gt; в архиве:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;NFdG&quot;&gt;https://web.archive.org/web/*/https://example.com/*.pdf&lt;/pre&gt;
  &lt;p id=&quot;QvhU&quot;&gt;&lt;strong&gt;Поиск всех страниц в подкаталоге:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;kPkI&quot;&gt;https://web.archive.org/web/*/https://example.com/docs/*&lt;/pre&gt;
  &lt;p id=&quot;QqoA&quot;&gt;&lt;strong&gt;Этап 3: Обнаружение скрытых страниц через архивы&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;TrqB&quot;&gt;Скрытые страницы — те, на которые нет ссылок с главной, но они могут существовать и быть проиндексированы архивом.&lt;/p&gt;
  &lt;p id=&quot;6ZJn&quot;&gt;&lt;strong&gt;Где искать скрытые страницы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;7uDr&quot;&gt;
    &lt;li id=&quot;uemy&quot;&gt;&lt;code&gt;/admin&lt;/code&gt;, &lt;code&gt;/login&lt;/code&gt;, &lt;code&gt;/backup&lt;/code&gt;, &lt;code&gt;/test&lt;/code&gt;, &lt;code&gt;/dev&lt;/code&gt;, &lt;code&gt;/staging&lt;/code&gt;, &lt;code&gt;/old&lt;/code&gt;, &lt;code&gt;/temp&lt;/code&gt;, &lt;code&gt;/private&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;l3PW&quot;&gt;Панели управления: &lt;code&gt;/cpanel&lt;/code&gt;, &lt;code&gt;/webmail&lt;/code&gt;, &lt;code&gt;/plesk&lt;/code&gt;, &lt;code&gt;/phpmyadmin&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;CIrm&quot;&gt;Файлы конфигурации: &lt;code&gt;/config&lt;/code&gt;, &lt;code&gt;/settings&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;4y0Z&quot;&gt;Директории с исходными кодами: &lt;code&gt;/git&lt;/code&gt;, &lt;code&gt;/svn&lt;/code&gt;, &lt;code&gt;/cvs&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Ruhd&quot;&gt;&lt;strong&gt;Как искать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;xKUn&quot;&gt;
    &lt;li id=&quot;V5Bi&quot;&gt;Вручную перебирать возможные пути в архиве.&lt;/li&gt;
    &lt;li id=&quot;3pM7&quot;&gt;Использовать поиск по &lt;code&gt;*&lt;/code&gt; или анализировать список всех сохранённых страниц через CDX API.&lt;/li&gt;
    &lt;li id=&quot;7Ejt&quot;&gt;Парсить CDX-вывод и искать подозрительные пути.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;3vey&quot;&gt;&lt;strong&gt;Пример CDX-запроса для получения всех страниц сайта (включая подпапки):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;5JZ7&quot;&gt;curl &amp;quot;https://web.archive.org/cdx/search/cdx?url=example.com/*&amp;amp;output=json&amp;quot; &amp;gt; all_pages.json&lt;/pre&gt;
  &lt;p id=&quot;SZnY&quot;&gt;&lt;strong&gt;Этап 4: Сравнение версий (diff) — что изменилось?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;QCZ2&quot;&gt;Wayback Machine позволяет сравнивать два снимка страницы. Это полезно для выявления изменений в контенте, политике или структуре.&lt;/p&gt;
  &lt;p id=&quot;tAfx&quot;&gt;&lt;strong&gt;Инструменты сравнения:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;3DgV&quot;&gt;
    &lt;li id=&quot;YpIR&quot;&gt;&lt;strong&gt;Веб-интерфейс:&lt;/strong&gt; &lt;code&gt;https://web.archive.org/web/20200101000000/https://example.com&lt;/code&gt; и &lt;code&gt;https://web.archive.org/web/20250101000000/https://example.com&lt;/code&gt; → открыть в двух вкладках и сравнить.&lt;/li&gt;
    &lt;li id=&quot;wHvw&quot;&gt;&lt;strong&gt;Сторонние утилиты:&lt;/strong&gt; &lt;code&gt;wget --mirror&lt;/code&gt; для загрузки двух архивных версий и сравнения через &lt;code&gt;diff&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;tJ9o&quot;&gt;&lt;strong&gt;Сравнение через Python:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;qnBF&quot;&gt;import requests
import difflib

def fetch_archived_page(timestamp, url):
    archive_url = f&amp;quot;https://web.archive.org/web/{timestamp}/{url}&amp;quot;
    resp = requests.get(archive_url)
    return resp.text if resp.status_code == 200 else &amp;quot;&amp;quot;

def compare_pages(url, ts1, ts2):
    text1 = fetch_archived_page(ts1, url)
    text2 = fetch_archived_page(ts2, url)
    diff = difflib.unified_diff(text1.splitlines(), text2.splitlines())
    return &amp;#x27;\n&amp;#x27;.join(diff)

# Пример
changes = compare_pages(&amp;#x27;example.com&amp;#x27;, &amp;#x27;20200101000000&amp;#x27;, &amp;#x27;20250101000000&amp;#x27;)
print(changes[:500])  # первые 500 символов&lt;/pre&gt;
  &lt;p id=&quot;tmGL&quot;&gt;&lt;strong&gt;Этап 5: Поиск старых robots.txt, sitemap.xml и других служебных файлов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;eY24&quot;&gt;&lt;code&gt;robots.txt&lt;/code&gt; и &lt;code&gt;sitemap.xml&lt;/code&gt; часто меняются. В старых версиях могут содержаться пути, которые позже были удалены.&lt;/p&gt;
  &lt;p id=&quot;cVPJ&quot;&gt;&lt;strong&gt;Пример:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;spBW&quot;&gt;https://web.archive.org/web/*/https://example.com/robots.txt
https://web.archive.org/web/*/https://example.com/sitemap.xml&lt;/pre&gt;
  &lt;p id=&quot;3GXx&quot;&gt;&lt;strong&gt;Что можно найти:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;dtuF&quot;&gt;
    &lt;li id=&quot;DpNk&quot;&gt;Директории, запрещённые для индексации (например, &lt;code&gt;/admin/&lt;/code&gt;, &lt;code&gt;/private/&lt;/code&gt;).&lt;/li&gt;
    &lt;li id=&quot;fZfw&quot;&gt;Поддомены, которые не разрешено индексировать (&lt;code&gt;Disallow: /subdomain/&lt;/code&gt;).&lt;/li&gt;
    &lt;li id=&quot;2W8q&quot;&gt;Карта сайта с перечнем всех страниц (удалённые, но сохранённые).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;9NXQ&quot;&gt;&lt;strong&gt;Этап 6: Поиск конфиденциальных данных в архивах&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;E4OX&quot;&gt;Одна из самых опасных ситуаций — случайная публикация конфиденциальных данных, которые затем были удалены, но остались в архиве.&lt;/p&gt;
  &lt;p id=&quot;uL3p&quot;&gt;&lt;strong&gt;Что искать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;kpKY&quot;&gt;
    &lt;li id=&quot;Lwkj&quot;&gt;&lt;code&gt;.env&lt;/code&gt; (файлы окружения с паролями).&lt;/li&gt;
    &lt;li id=&quot;LLu3&quot;&gt;&lt;code&gt;.git/config&lt;/code&gt; (адреса репозиториев).&lt;/li&gt;
    &lt;li id=&quot;Adnr&quot;&gt;&lt;code&gt;phpinfo()&lt;/code&gt; (информация о PHP-конфигурации).&lt;/li&gt;
    &lt;li id=&quot;IIp0&quot;&gt;&lt;code&gt;backup.sql&lt;/code&gt; (дампы базы данных).&lt;/li&gt;
    &lt;li id=&quot;1i4u&quot;&gt;&lt;code&gt;config.php&lt;/code&gt;, &lt;code&gt;settings.php&lt;/code&gt; (конфигурационные файлы).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;1iQt&quot;&gt;&lt;strong&gt;Как искать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;ME4N&quot;&gt;
    &lt;li id=&quot;6P3T&quot;&gt;Вручную проверять типичные пути: &lt;code&gt;/backup&lt;/code&gt;, &lt;code&gt;/tmp&lt;/code&gt;, &lt;code&gt;/downloads&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;c83e&quot;&gt;Использовать поиск по &lt;code&gt;*&lt;/code&gt; и фильтровать по расширениям.&lt;/li&gt;
    &lt;li id=&quot;UZrm&quot;&gt;Использовать инструменты парсинга архивов для массового поиска.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Kqiv&quot;&gt;&lt;strong&gt;Пример поиска &lt;code&gt;.env&lt;/code&gt; файлов:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;rEkH&quot;&gt;https://web.archive.org/web/*/https://example.com/*.env&lt;/pre&gt;
  &lt;p id=&quot;ti53&quot;&gt;Wayback Machine не сохраняет все файлы (только HTML, CSS, JS), но дампы баз или бинарные файлы могут быть недоступны.&lt;/p&gt;
  &lt;p id=&quot;CpER&quot;&gt;&lt;strong&gt;Этап 7: Анализ изменений в SSL-сертификатах через архивы&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;VKPd&quot;&gt;Хотя Wayback Machine не сохраняет SSL-сертификаты, история сертификатов доступна через CT-логи (см. статью 7). Однако, анализируя старые снимки сайта, можно заметить:&lt;/p&gt;
  &lt;ul id=&quot;kl9R&quot;&gt;
    &lt;li id=&quot;14rl&quot;&gt;Когда на сайте появилась поддержка HTTPS (по редиректам).&lt;/li&gt;
    &lt;li id=&quot;5xzx&quot;&gt;Когда был заменён логотип или изменилась политика безопасности (по заголовкам HTTP в сохранённых снимках, если они есть).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;npTP&quot;&gt;&lt;strong&gt;Этап 8: Использование &lt;a href=&quot;https://archive.today/&quot; target=&quot;_blank&quot;&gt;Archive.today&lt;/a&gt; для поиска удалённого контента&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;s1lj&quot;&gt;&lt;a href=&quot;https://archive.today/&quot; target=&quot;_blank&quot;&gt;Archive.today&lt;/a&gt; часто сохраняет страницы, которые не попали в Wayback Machine (например, из-за robots.txt). Он позволяет архивировать страницы вручную.&lt;/p&gt;
  &lt;p id=&quot;Fcxh&quot;&gt;&lt;strong&gt;Как использовать:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;4MH6&quot;&gt;
    &lt;li id=&quot;oWZp&quot;&gt;Ввести URL на &lt;a href=&quot;https://archive.today/&quot; target=&quot;_blank&quot;&gt;archive.today&lt;/a&gt;.&lt;/li&gt;
    &lt;li id=&quot;5lPU&quot;&gt;Если страница была сохранена, она отобразится.&lt;/li&gt;
    &lt;li id=&quot;rJsF&quot;&gt;Можно найти сохранения по дате.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;uIDZ&quot;&gt;Нет публичного API. Только веб-интерфейс.&lt;/p&gt;
  &lt;p id=&quot;d4Gi&quot;&gt;&lt;strong&gt;Этап 9: Автоматизированный сбор изменений с помощью Wayback Machine API&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;1hrY&quot;&gt;Для долгосрочного мониторинга сайта можно автоматизировать проверку новых снимков в архиве.&lt;/p&gt;
  &lt;p id=&quot;FyBn&quot;&gt;&lt;strong&gt;Скрипт мониторинга новых версий:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Vn7e&quot;&gt;import requests
import time

def get_latest_snapshot(url):
    # CDX API
    cdx_url = f&amp;quot;https://web.archive.org/cdx/search/cdx?url={url}&amp;amp;output=json&amp;amp;limit=1&amp;amp;sort=timestamp&amp;quot;
    resp = requests.get(cdx_url)
    if resp.status_code == 200:
        data = resp.json()
        if len(data) &amp;gt; 1:
            timestamp = data[1][1]
            return timestamp
    return None

def monitor_website(url, check_interval=86400):  # 1 день
    last_timestamp = None
    while True:
        latest = get_latest_snapshot(url)
        if latest and latest != last_timestamp:
            print(f&amp;quot;Обнаружена новая версия {url} в архиве: {latest}&amp;quot;)
            # Здесь можно обработать изменения
            last_timestamp = latest
        time.sleep(check_interval)&lt;/pre&gt;
  &lt;p id=&quot;xz1I&quot;&gt;&lt;strong&gt;Этап 10: Поиск через CDX API для составления карты сайта&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;MZS8&quot;&gt;CDX API можно использовать для получения полного списка всех когда-либо сохранённых страниц сайта. Это позволяет восстановить структуру сайта даже без текущего доступа.&lt;/p&gt;
  &lt;p id=&quot;VY4v&quot;&gt;&lt;strong&gt;Получение списка всех страниц (с ограничениями):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;AtVg&quot;&gt;curl &amp;quot;https://web.archive.org/cdx/search/cdx?url=example.com/*&amp;amp;output=json&amp;amp;limit=100000&amp;quot; &amp;gt; all_pages.json&lt;/pre&gt;
  &lt;p id=&quot;sK7T&quot;&gt;&lt;strong&gt;Парсинг результатов для построения карты сайта:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;XXYw&quot;&gt;import json
import re

def extract_all_paths(cdx_json_file):
    with open(cdx_json_file, &amp;#x27;r&amp;#x27;) as f:
        data = json.load(f)
    paths = set()
    for row in data[1:]:
        url = row[2]  # полный URL
        # извлекаем путь
        path = re.sub(r&amp;#x27;^https?://[^/]+&amp;#x27;, &amp;#x27;&amp;#x27;, url)
        paths.add(path)
    return sorted(paths)

# Пример использования
paths = extract_all_paths(&amp;#x27;all_pages.json&amp;#x27;)
for p in paths[:50]:
    print(p)&lt;/pre&gt;
  &lt;p id=&quot;adTp&quot;&gt;&lt;strong&gt;Практический пример: полное исследование сайта через архивы&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;7zyf&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; собрать максимально полную информацию о сайте &lt;code&gt;target.org&lt;/code&gt; через архивы.&lt;/p&gt;
  &lt;ol id=&quot;aSoS&quot;&gt;
    &lt;li id=&quot;hiEe&quot;&gt;&lt;strong&gt;Wayback Machine CDX&lt;/strong&gt; → получаем список всех 5000 сохранённых страниц.&lt;/li&gt;
    &lt;li id=&quot;5kpz&quot;&gt;&lt;strong&gt;Анализ путей:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;iDb1&quot;&gt;
      &lt;li id=&quot;x9AE&quot;&gt;Обнаружены пути &lt;code&gt;/admin&lt;/code&gt;, &lt;code&gt;/test&lt;/code&gt;, &lt;code&gt;/backup_2022&lt;/code&gt;, &lt;code&gt;/temp&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;rr8B&quot;&gt;Страница &lt;code&gt;/admin/login.html&lt;/code&gt; существует в архиве с 2020 года.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;OwRU&quot;&gt;&lt;strong&gt;Поиск файлов:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Slfb&quot;&gt;
      &lt;li id=&quot;8o0K&quot;&gt;&lt;code&gt;https://web.archive.org/web/20220101000000/target.org/.git/config&lt;/code&gt; — найден конфиг репозитория.&lt;/li&gt;
      &lt;li id=&quot;uv0H&quot;&gt;&lt;code&gt;https://web.archive.org/web/20200101000000/target.org/backup.sql&lt;/code&gt; — дамп базы данных.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;Vmah&quot;&gt;&lt;strong&gt;Сравнение версий:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;QqWT&quot;&gt;
      &lt;li id=&quot;ZAFX&quot;&gt;Сравнили &lt;code&gt;index.html&lt;/code&gt; в 2020 и 2024 → структура сильно изменилась, добавилась поддержка HTTPS, появился CSP.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;g1VX&quot;&gt;&lt;strong&gt;Скрытые поддомены:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;8XlX&quot;&gt;
      &lt;li id=&quot;6AC2&quot;&gt;На старой robots.txt найдена запись &lt;code&gt;Disallow: /dev/&lt;/code&gt;. Открываем архивный URL &lt;code&gt;https://web.archive.org/web/20200101000000/target.org/dev/&lt;/code&gt; → обнаруживаем тестовый сайт с открытыми ошибками PHP.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;YBVv&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; Найдены забытые тестовые страницы, конфигурационный файл и дамп базы данных. В текущей версии сайта они удалены, но остались в архиве.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;ITAF&quot;&gt;&lt;strong&gt;Инструменты для работы с архивами&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;8j2P&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8c/9a/8c9a77a3-3940-469d-a7ed-dcf8e2b95d43.png&quot; width=&quot;1004&quot; /&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;Fl2g&quot;&gt;
    &lt;li id=&quot;Euvt&quot;&gt;Данные Wayback Machine являются публичными, их сбор легален.&lt;/li&gt;
    &lt;li id=&quot;4DG2&quot;&gt;Не используйте найденные уязвимости для атак на сайт без разрешения.&lt;/li&gt;
    &lt;li id=&quot;vfIu&quot;&gt;Если вы нашли конфиденциальные данные (пароли, токены) в архиве, сообщите об этом владельцу сайта через официальный канал (без распространения информации третьим лицам).&lt;/li&gt;
    &lt;li id=&quot;cy8b&quot;&gt;Некоторые страны требуют удаления личных данных из архивов — уважайте такие запросы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ZXD8&quot;&gt;Анализ истории сайта через Wayback Machine и другие архивы — важный этап технического OSINT, позволяющий заглянуть в прошлое веб-ресурса. Удалённые страницы, забытые поддомены, случайно опубликованные конфиденциальные данные, старая robots.txt — всё это может быть восстановлено, если было сохранено в архиве. Комбинируя CDX API, поиск по шаблонам и ручной анализ, исследователь может восстановить почти полную ист&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Vulnerability-search-through-OSINT</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Vulnerability-search-through-OSINT?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Поиск уязвимостей через открытые источники: базы CVE, NVD, Exploit-DB и связь с версиями ПО</title><published>2026-06-27T16:28:23.150Z</published><updated>2026-06-27T16:28:34.363Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/90/b2/90b2d41c-87cb-450f-a82b-012a4c2e7ea7.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/6c/1c/6c1c1980-fe76-4005-a8dc-20cb2d941a65.png&quot;&gt;После того как в ходе технического OSINT выявлены версии программного обеспечения, используемого целью (веб-сервер, CMS, библиотеки, операционная система), логичный следующий шаг — выяснить, есть ли у этих версий известные уязвимости. Открытые базы данных уязвимостей (CVE, NVD, Exploit-DB, Vulners и др.) позволяют сопоставить версию ПО с известными CVE (Common Vulnerabilities and Exposures), оценить критичность и даже найти готовые эксплойты. Это помогает понять, насколько цель подвержена атакам, и приоритезировать дальнейшие действия. Данная статья посвящена методам поиска уязвимостей по версиям ПО с использованием открытых источников.</summary><content type="html">
  &lt;figure id=&quot;zxLK&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6c/1c/6c1c1980-fe76-4005-a8dc-20cb2d941a65.png&quot; width=&quot;1099&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;R5Kp&quot;&gt;Поиск уязвимостей через открытые источники: базы CVE, NVD, Exploit-DB и связь с версиями ПО&lt;/h3&gt;
  &lt;p id=&quot;P50k&quot;&gt;После того как в ходе технического OSINT выявлены версии программного обеспечения, используемого целью (веб-сервер, CMS, библиотеки, операционная система), логичный следующий шаг — выяснить, есть ли у этих версий известные уязвимости. Открытые базы данных уязвимостей (CVE, NVD, Exploit-DB, Vulners и др.) позволяют сопоставить версию ПО с известными CVE (Common Vulnerabilities and Exposures), оценить критичность и даже найти готовые эксплойты. Это помогает понять, насколько цель подвержена атакам, и приоритезировать дальнейшие действия. Данная статья посвящена методам поиска уязвимостей по версиям ПО с использованием открытых источников.&lt;/p&gt;
  &lt;p id=&quot;aVvw&quot;&gt;&lt;strong&gt;Что такое CVE, CVSS, NVD, Exploit-DB&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;Sel7&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/27/03/27031fce-341d-42a3-8a66-fa48f9fc69e7.png&quot; width=&quot;1207&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0mNK&quot;&gt;&lt;strong&gt;Зачем это нужно в техническом OSINT?&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;uM35&quot;&gt;
    &lt;li id=&quot;Mcyw&quot;&gt;&lt;strong&gt;Оценка рисков:&lt;/strong&gt; понять, насколько критичны уязвимости в используемом ПО.&lt;/li&gt;
    &lt;li id=&quot;zmRU&quot;&gt;&lt;strong&gt;Приоритизация проверок:&lt;/strong&gt; какие уязвимости следует тестировать в первую очередь.&lt;/li&gt;
    &lt;li id=&quot;GX1v&quot;&gt;&lt;strong&gt;Обнаружение уже скомпрометированных систем:&lt;/strong&gt; если на целевой системе есть уязвимая версия и известен активный эксплойт — она могла быть взломана.&lt;/li&gt;
    &lt;li id=&quot;5GxT&quot;&gt;&lt;strong&gt;Помощь в легальном пентесте:&lt;/strong&gt; знание уязвимостей позволяет сосредоточить усилия.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;nB55&quot;&gt;Простое наличие уязвимой версии ПО не означает, что цель автоматически скомпрометирована. Это лишь индикатор потенциальной уязвимости.&lt;/p&gt;
  &lt;p id=&quot;ZETQ&quot;&gt;&lt;strong&gt;Этап 1: Поиск CVE по названию продукта и версии&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4JRm&quot;&gt;Самый простой способ — использовать поисковые системы по CVE с фильтрацией.&lt;/p&gt;
  &lt;p id=&quot;wJDg&quot;&gt;&lt;strong&gt;Основные базы данных:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;C5Py&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b6/c3/b6c3c705-30dc-4006-a5e9-ad6126c56496.png&quot; width=&quot;1206&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;lifm&quot;&gt;&lt;strong&gt;Поиск по продукту в NVD:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;2ZXQ&quot;&gt;https://nvd.nist.gov/vuln/search/results?query=nginx&amp;amp;results_type=overview&lt;/pre&gt;
  &lt;p id=&quot;C40H&quot;&gt;&lt;strong&gt;Поиск с версией в NVD (сложно):&lt;/strong&gt; NVD не всегда индексирует версии, лучше использовать Vulners.&lt;/p&gt;
  &lt;p id=&quot;pFBh&quot;&gt;&lt;strong&gt;Vulners search (пример):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;lZ7b&quot;&gt;https://vulners.com/search?query=nginx%201.18.0&lt;/pre&gt;
  &lt;p id=&quot;QbXa&quot;&gt;&lt;strong&gt;Этап 2: Использование Vulners API для массового поиска&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;5oYT&quot;&gt;Vulners предоставляет бесплатный API с лимитами. Позволяет искать по CPE (Common Platform Enumeration) — стандартизированному формату описания ПО.&lt;/p&gt;
  &lt;p id=&quot;QBPm&quot;&gt;&lt;strong&gt;Формат CPE:&lt;/strong&gt; &lt;code&gt;cpe:2.3:a:nginx:nginx:1.18.0:*:*:*:*:*:*:*&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;eIOg&quot;&gt;&lt;strong&gt;Упрощённый поиск через API Vulners:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;xMeU&quot;&gt;import requests
import json

VULNERS_API_KEY = &amp;quot;YOUR_API_KEY&amp;quot;

def search_vulnerabilities(product, version, api_key=VULNERS_API_KEY):
    &amp;quot;&amp;quot;&amp;quot;
    Поиск уязвимостей по названию продукта и версии.
    &amp;quot;&amp;quot;&amp;quot;
    query = f&amp;#x27;{product} {version}&amp;#x27;
    url = &amp;quot;https://vulners.com/api/v3/search/lucene/&amp;quot;
    payload = {
        &amp;quot;query&amp;quot;: query,
        &amp;quot;apiKey&amp;quot;: api_key
    }
    response = requests.post(url, json=payload)
    if response.status_code == 200:
        data = response.json()
        if &amp;#x27;data&amp;#x27; in data and &amp;#x27;search&amp;#x27; in data[&amp;#x27;data&amp;#x27;]:
            return data[&amp;#x27;data&amp;#x27;][&amp;#x27;search&amp;#x27;]
    return []

def get_cves_for_software(software_list):
    results = {}
    for sw in software_list:
        cves = search_vulnerabilities(sw[&amp;#x27;name&amp;#x27;], sw[&amp;#x27;version&amp;#x27;])
        results[f&amp;quot;{sw[&amp;#x27;name&amp;#x27;]} {sw[&amp;#x27;version&amp;#x27;]}&amp;quot;] = cves
    return results

# Пример
software = [
    {&amp;#x27;name&amp;#x27;: &amp;#x27;nginx&amp;#x27;, &amp;#x27;version&amp;#x27;: &amp;#x27;1.18.0&amp;#x27;},
    {&amp;#x27;name&amp;#x27;: &amp;#x27;php&amp;#x27;, &amp;#x27;version&amp;#x27;: &amp;#x27;7.4.33&amp;#x27;},
    {&amp;#x27;name&amp;#x27;: &amp;#x27;wordpress&amp;#x27;, &amp;#x27;version&amp;#x27;: &amp;#x27;6.2&amp;#x27;}
]
vulns = get_cves_for_software(software)
for k, v in vulns.items():
    print(f&amp;quot;{k}: {len(v)} vulnerabilities&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;kgz4&quot;&gt;&lt;strong&gt;Этап 3: Использование CIRCL CVE Search API (без ключа)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;13CH&quot;&gt;CIRCL предлагает публичный API, не требующий авторизации.&lt;/p&gt;
  &lt;p id=&quot;JY7c&quot;&gt;&lt;strong&gt;Пример запроса для поиска CVE по ключевому слову nginx:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Vk5m&quot;&gt;curl https://cve.circl.lu/api/search/nginx&lt;/pre&gt;
  &lt;p id=&quot;WFew&quot;&gt;&lt;strong&gt;Для извлечения информации о конкретном CVE:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;PR5M&quot;&gt;curl https://cve.circl.lu/api/cve/CVE-2021-23017&lt;/pre&gt;
  &lt;p id=&quot;GWOW&quot;&gt;CIRCL не позволяет фильтровать по версии, ищет по тексту.&lt;/p&gt;
  &lt;p id=&quot;COUy&quot;&gt;&lt;strong&gt;Этап 4: Поиск эксплойтов (Exploit-DB, Rapid7, Packet Storm)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Pjl0&quot;&gt;Наличие эксплойта повышает вероятность того, что уязвимость будет использована.&lt;/p&gt;
  &lt;p id=&quot;pkUV&quot;&gt;&lt;strong&gt;Exploit-DB:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;CHcM&quot;&gt;
    &lt;li id=&quot;4grd&quot;&gt;Поиск по продукту и версии: &lt;code&gt;https://www.exploit-db.com/search?q=nginx+1.18.0&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;o9Dz&quot;&gt;Можно скачать готовый код (на свой страх и риск).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;jUWr&quot;&gt;&lt;strong&gt;Rapid7 DB (Metasploit modules):&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;vGsd&quot;&gt;
    &lt;li id=&quot;VAHb&quot;&gt;Поиск: &lt;code&gt;https://www.rapid7.com/db/search/?q=nginx&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;UEYg&quot;&gt;&lt;strong&gt;Packet Storm Security:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;2UzU&quot;&gt;
    &lt;li id=&quot;kTvR&quot;&gt;&lt;code&gt;https://packetstormsecurity.com/search/?q=nginx&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;WfRw&quot;&gt;&lt;strong&gt;Пример автоматизации через Exploit-DB (неофициальный API, лучше парсить):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;tCQY&quot;&gt;import requests
from bs4 import BeautifulSoup

def search_exploitdb(product, version):
    url = f&amp;quot;https://www.exploit-db.com/search?q={product}+{version}&amp;quot;
    resp = requests.get(url)
    soup = BeautifulSoup(resp.text, &amp;#x27;html.parser&amp;#x27;)
    # Парсинг таблицы результатов (сложно, зависит от структуры)
    # Возвращает список заголовков эксплойтов
    return []

# Ручной поиск вручную часто проще&lt;/pre&gt;
  &lt;p id=&quot;nMGR&quot;&gt;&lt;strong&gt;Этап 5: Сопоставление версий ПО с CPE для точного поиска&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;pqEX&quot;&gt;Чтобы искать CVE, лучше преобразовать название и версию в CPE-формат. Это повышает точность.&lt;/p&gt;
  &lt;p id=&quot;TKZB&quot;&gt;&lt;strong&gt;Сервис CPE Dictionary (NVD):&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;Ju7p&quot;&gt;
    &lt;li id=&quot;3Mjw&quot;&gt;&lt;code&gt;https://nvd.nist.gov/products/cpe/search&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;ZJeo&quot;&gt;API: &lt;code&gt;https://services.nvd.nist.gov/rest/json/cpes/2.0?keyword=nginx&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Dxlm&quot;&gt;&lt;strong&gt;Автоматическое определение CPE через cpe-guesser (исследовательский):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;AX3P&quot;&gt;def guess_cpe(product, version):
    # упрощённый пример
    product_lower = product.lower()
    if product_lower == &amp;#x27;nginx&amp;#x27;:
        return f&amp;quot;cpe:2.3:a:nginx:nginx:{version}:*:*:*:*:*:*:*&amp;quot;
    elif product_lower == &amp;#x27;wordpress&amp;#x27;:
        return f&amp;quot;cpe:2.3:a:wordpress:wordpress:{version}:*:*:*:*:*:*:*&amp;quot;
    # ...
    return None&lt;/pre&gt;
  &lt;p id=&quot;2StY&quot;&gt;&lt;strong&gt;Этап 6: Анализ CVSS (критичность уязвимости)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;iddC&quot;&gt;Каждому CVE присваивается оценка CVSS. Чем выше, тем критичнее.&lt;/p&gt;
  &lt;p id=&quot;zlfF&quot;&gt;&lt;strong&gt;CVSS v3 шкала:&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;W7mk&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/54/56/54561dd9-0302-4330-acc7-752cdb9c77ae.png&quot; width=&quot;929&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;b1Qj&quot;&gt;&lt;strong&gt;Вектор CVSS&lt;/strong&gt; (пример): &lt;code&gt;CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&lt;/code&gt; означает: сетевой доступ, низкая сложность, не требуется привилегий, полное воздействие на конфиденциальность, целостность и доступность.&lt;/p&gt;
  &lt;p id=&quot;8wed&quot;&gt;&lt;strong&gt;Где брать CVSS:&lt;/strong&gt; NVD, Vulners, некоторые API.&lt;/p&gt;
  &lt;p id=&quot;tiPI&quot;&gt;&lt;strong&gt;Этап 7: Автоматизированный сбор уязвимостей для всех технологий стека&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;MKvZ&quot;&gt;Комбинируем результаты предыдущих статей (технологический стек) с базами уязвимостей.&lt;/p&gt;
  &lt;p id=&quot;xtcr&quot;&gt;&lt;strong&gt;Python-скрипт для массовой проверки (на основе данных из Wappalyzer, BuiltWith):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;nYk6&quot;&gt;import requests
import time
import json

def get_cves_from_nvd(keyword, api_key=None):
    &amp;quot;&amp;quot;&amp;quot;
    Поиск в NVD через API (требуется ключ, можно получить бесплатно).
    Без ключа возвращает только первые 20 результатов.
    &amp;quot;&amp;quot;&amp;quot;
    url = &amp;quot;https://services.nvd.nist.gov/rest/json/cves/2.0&amp;quot;
    params = {
        &amp;#x27;keywordSearch&amp;#x27;: keyword,
        &amp;#x27;resultsPerPage&amp;#x27;: 10
    }
    if api_key:
        params[&amp;#x27;apiKey&amp;#x27;] = api_key
    response = requests.get(url, params=params)
    if response.status_code == 200:
        data = response.json()
        cves = []
        for vuln in data.get(&amp;#x27;vulnerabilities&amp;#x27;, []):
            cve_id = vuln[&amp;#x27;cve&amp;#x27;][&amp;#x27;id&amp;#x27;]
            cvss_score = vuln[&amp;#x27;cve&amp;#x27;].get(&amp;#x27;metrics&amp;#x27;, {}).get(&amp;#x27;cvssMetricV31&amp;#x27;, [{}])[0].get(&amp;#x27;cvssData&amp;#x27;, {}).get(&amp;#x27;baseScore&amp;#x27;, &amp;#x27;N/A&amp;#x27;)
            cves.append({&amp;#x27;id&amp;#x27;: cve_id, &amp;#x27;cvss_score&amp;#x27;: cvss_score})
        return cves
    else:
        print(f&amp;quot;Ошибка NVD: {response.status_code}&amp;quot;)
        return []

# Пример для nginx 1.18.0
cves = get_cves_from_nvd(&amp;quot;nginx 1.18.0&amp;quot;)
for cve in cves:
    print(f&amp;quot;{cve[&amp;#x27;id&amp;#x27;]} (CVSS {cve[&amp;#x27;cvss_score&amp;#x27;]})&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;6DN6&quot;&gt;NVD API имеет rate limit (без ключа ~5 запросов в 30 секунд). Используйте ключ или библиотеку с задержками.&lt;/p&gt;
  &lt;p id=&quot;qJxj&quot;&gt;&lt;strong&gt;Этап 8: Поиск уязвимостей в WordPress плагинах и темах&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;IcdP&quot;&gt;WordPress — особая категория: уязвимости часто связаны с плагинами и темами, а не с ядром.&lt;/p&gt;
  &lt;p id=&quot;5pQP&quot;&gt;&lt;strong&gt;Базы для WordPress:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;CS5I&quot;&gt;
    &lt;li id=&quot;WwGP&quot;&gt;&lt;strong&gt;WPScan Vulnerability Database:&lt;/strong&gt; &lt;code&gt;https://wpscan.com/api&lt;/code&gt; (есть бесплатный API с ограничениями).&lt;/li&gt;
    &lt;li id=&quot;il6l&quot;&gt;&lt;strong&gt;Patchstack:&lt;/strong&gt; &lt;code&gt;https://patchstack.com/database/&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;UXkG&quot;&gt;&lt;strong&gt;Пример поиска через WPScan API:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;hK24&quot;&gt;def check_wpscan_plugin(plugin_slug):
    url = f&amp;quot;https://wpscan.com/api/v3/plugins/{plugin_slug}&amp;quot;
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return data.get(&amp;#x27;vulnerabilities&amp;#x27;, [])
    return []&lt;/pre&gt;
  &lt;p id=&quot;5NJt&quot;&gt;&lt;strong&gt;Этап 9: Анализ базы Known Exploited Vulnerabilities (CISA KEV)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;BRWA&quot;&gt;CISA ведёт список активно эксплуатируемых уязвимостей (KEV). Если CVE есть в этом списке, оно представляет большую угрозу.&lt;/p&gt;
  &lt;p id=&quot;gCmT&quot;&gt;&lt;strong&gt;API KEV:&lt;/strong&gt; &lt;a href=&quot;https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json&quot; target=&quot;_blank&quot;&gt;https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;65tP&quot;&gt;def is_in_kev(cve_id):
    url = &amp;quot;https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json&amp;quot;
    resp = requests.get(url)
    if resp.status_code == 200:
        data = resp.json()
        for item in data[&amp;#x27;vulnerabilities&amp;#x27;]:
            if item[&amp;#x27;cveID&amp;#x27;] == cve_id:
                return True
    return False&lt;/pre&gt;
  &lt;p id=&quot;bddm&quot;&gt;&lt;strong&gt;Этап 10: Составление отчёта об уязвимостях&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;9HmG&quot;&gt;Для каждой версии ПО, найденной на цели, следует создать таблицу:&lt;/p&gt;
  &lt;figure id=&quot;0IP1&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e4/83/e4837925-ab85-4e55-ab93-f6bc56444913.png&quot; width=&quot;907&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;70fR&quot;&gt;Суммировать количество критических уязвимостей, наличие эксплойтов, попадание в KEV.&lt;/p&gt;
  &lt;p id=&quot;Yldi&quot;&gt;&lt;strong&gt;Практический пример: оценка рисков для веб-сервера цели&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;dWpj&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; для сервера nginx 1.18.0 + PHP 7.4.33 найти известные уязвимости.&lt;/p&gt;
  &lt;ol id=&quot;ehHE&quot;&gt;
    &lt;li id=&quot;0U41&quot;&gt;&lt;strong&gt;Поиск через Vulners:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Xx1V&quot;&gt;
      &lt;li id=&quot;2h3H&quot;&gt;nginx 1.18.0: 3 CVE, все с CVSS ниже 6.0. Эксплойтов нет.&lt;/li&gt;
      &lt;li id=&quot;bE77&quot;&gt;PHP 7.4.33: 12 CVE, из них 4 с CVSS &amp;gt; 7.0. Один эксплойт в Metasploit.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;u1R2&quot;&gt;&lt;strong&gt;Проверка CISA KEV:&lt;/strong&gt; PHP 7.4.33 не в списке KEV.&lt;/li&gt;
    &lt;li id=&quot;KmQF&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; основной риск — уязвимости PHP (особенно CVE-2022-31628, позволяющая удалённое выполнение кода). Рекомендуется обновить PHP до 8.x.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;ul id=&quot;68sC&quot;&gt;
    &lt;li id=&quot;8wIw&quot;&gt;Поиск уязвимостей в открытых базах данных легален.&lt;/li&gt;
    &lt;li id=&quot;tJ9m&quot;&gt;Запуск эксплойтов на целевой системе без разрешения — уголовное преступление.&lt;/li&gt;
    &lt;li id=&quot;1UQO&quot;&gt;Обнаруженную уязвимость следует сообщить владельцу системы через программы Bug Bounty или координаторы (CERT).&lt;/li&gt;
    &lt;li id=&quot;bCtd&quot;&gt;Не следует тестировать эксплойты на чужих системах.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;pz1M&quot;&gt;Поиск уязвимостей по версиям ПО — неотъемлемая часть технического OSINT. Базы CVE, NVD, Vulners, Exploit-DB и CISA KEV дают исследователю возможность оценить поверхность атаки, не прибегая к активным сканерам уязвимостей. Сопоставление версий из предыдущих статей (технологический стек, версии ПО, заголовки) с уязвимостями позволяет построить рейтинг рисков и определить приоритет для дальнейшего тестирования.&lt;/p&gt;

</content></entry><entry><id>specialist_infosec:Headline-Analysis</id><link rel="alternate" type="text/html" href="https://teletype.in/@specialist_infosec/Headline-Analysis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=specialist_infosec"></link><title>Анализ заголовков HTTP: серверы, cookies, политики безопасности</title><published>2026-06-24T08:29:47.248Z</published><updated>2026-06-24T08:29:47.248Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/dd/21/dd211fb3-5814-4a2d-9527-9f9725b7a7ad.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/98/b2/98b2a327-44d0-47ce-924f-402d58919182.png&quot;&gt;HTTP-заголовки — это метаданные, которыми обмениваются клиент (браузер) и сервер при каждом запросе. Для специалиста по техническому OSINT заголовки — ценный источник информации: они раскрывают версии программного обеспечения, используемые технологии, настройки безопасности и даже особенности конфигурации. Помимо этого, заголовки безопасности (CSP, HSTS, X-Frame-Options) позволяют оценить уровень защищённости веб-приложения и выявить потенциальные уязвимости. Данная статья посвящена методам сбора и анализа HTTP-заголовков, а также извлечению разведывательной информации из них.</summary><content type="html">
  &lt;figure id=&quot;1ash&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/98/b2/98b2a327-44d0-47ce-924f-402d58919182.png&quot; width=&quot;1102&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;DpJO&quot;&gt;Анализ заголовков HTTP: серверы, cookies, политики безопасности (CSP, HSTS, X-Frame-Options и другие)&lt;/h3&gt;
  &lt;p id=&quot;677c&quot;&gt;HTTP-заголовки — это метаданные, которыми обмениваются клиент (браузер) и сервер при каждом запросе. Для специалиста по техническому OSINT заголовки — ценный источник информации: они раскрывают версии программного обеспечения, используемые технологии, настройки безопасности и даже особенности конфигурации. Помимо этого, заголовки безопасности (CSP, HSTS, X-Frame-Options) позволяют оценить уровень защищённости веб-приложения и выявить потенциальные уязвимости. Данная статья посвящена методам сбора и анализа HTTP-заголовков, а также извлечению разведывательной информации из них.&lt;/p&gt;
  &lt;p id=&quot;KpN1&quot;&gt;&lt;strong&gt;Почему HTTP-заголовки важны для технического OSINT?&lt;/strong&gt;&lt;/p&gt;
  &lt;figure id=&quot;gvRN&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/51/e9/51e9b4d7-59e3-478b-96a2-37d55de03f24.png&quot; width=&quot;1203&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YeYR&quot;&gt;&lt;strong&gt;Этап 1: Сбор заголовков (базовые инструменты)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;GSEO&quot;&gt;&lt;strong&gt;1. curl&lt;/strong&gt;  — самый простой способ:&lt;/p&gt;
  &lt;pre id=&quot;wlFl&quot;&gt;# Показать только заголовки ответа
curl -I https://example.com

# Показать заголовки запроса и ответа
curl -v https://example.com

# Сохранить заголовки в файл
curl -D headers.txt https://example.com&lt;/pre&gt;
  &lt;p id=&quot;DbkW&quot;&gt;&lt;strong&gt;2. wget&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;2LVx&quot;&gt;wget --server-response -O /dev/null https://example.com&lt;/pre&gt;
  &lt;p id=&quot;t82e&quot;&gt;&lt;strong&gt;3. Browser DevTools&lt;/strong&gt; (F12 → Network → выбрать запрос → Headers).&lt;/p&gt;
  &lt;p id=&quot;HHOD&quot;&gt;&lt;strong&gt;4. Онлайн сервисы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;rcRM&quot;&gt;
    &lt;li id=&quot;CrJX&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://securityheaders.com/&quot; target=&quot;_blank&quot;&gt;SecurityHeaders.com&lt;/a&gt;&lt;/strong&gt; — проверяет наличие и корректность заголовков безопасности, выставляет оценку.&lt;/li&gt;
    &lt;li id=&quot;BxsH&quot;&gt;&lt;strong&gt;HTTPHeaderCheck&lt;/strong&gt; (&lt;a href=&quot;https://httpheadercheck.com/&quot; target=&quot;_blank&quot;&gt;httpheadercheck.com&lt;/a&gt;) — анализирует заголовки и даёт рекомендации.&lt;/li&gt;
    &lt;li id=&quot;enPC&quot;&gt;&lt;strong&gt;Mozilla Observatory&lt;/strong&gt; — глубокий анализ безопасности с рекомендациями.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;gEnS&quot;&gt;&lt;strong&gt;Этап 2: Анализ идентификационных заголовков&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;AFdb&quot;&gt;Эти заголовки могут выдать технологии, версии ПО, что полезно для обнаружения устаревших или уязвимых компонентов.&lt;/p&gt;
  &lt;p id=&quot;M6Bz&quot;&gt;&lt;strong&gt;&lt;code&gt;Server:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;rInk&quot;&gt;
    &lt;li id=&quot;F2pV&quot;&gt;Указывает тип и версию веб-сервера. Примеры: &lt;code&gt;nginx/1.18.0&lt;/code&gt;, &lt;code&gt;Apache/2.4.41 (Ubuntu)&lt;/code&gt;, &lt;code&gt;Microsoft-IIS/10.0&lt;/code&gt;, &lt;code&gt;Cloudflare&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;aBpM&quot;&gt;Часто скрывается администраторами (&lt;code&gt;Server: Apache&lt;/code&gt;, без версии). Если версия показана — сверьте с базами уязвимостей.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;HLI9&quot;&gt;&lt;strong&gt;&lt;code&gt;X-Powered-By:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;dVhk&quot;&gt;
    &lt;li id=&quot;Dedf&quot;&gt;Показывает технологию бэкенда. Например: &lt;code&gt;PHP/7.4.33&lt;/code&gt;, &lt;code&gt;ASP.NET&lt;/code&gt;, &lt;code&gt;Express&lt;/code&gt;. Может дать версию языка/фреймворка.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;vaM0&quot;&gt;&lt;strong&gt;&lt;code&gt;X-Generator:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;znte&quot;&gt;
    &lt;li id=&quot;KUho&quot;&gt;Иногда содержит название CMS или генератора контента (например, &lt;code&gt;WordPress 6.2&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Sb0C&quot;&gt;&lt;strong&gt;&lt;code&gt;X-AspNet-Version:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;jxVW&quot;&gt;
    &lt;li id=&quot;h7Tx&quot;&gt;Для &lt;a href=&quot;https://asp.net/&quot; target=&quot;_blank&quot;&gt;ASP.NET&lt;/a&gt;. Пример: &lt;code&gt;X-AspNet-Version: 4.0.30319&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;bkEa&quot;&gt;&lt;strong&gt;&lt;code&gt;X-Powered-By-Plesk:&lt;/code&gt;&lt;/strong&gt; (если используется панель управления хостингом).&lt;/p&gt;
  &lt;p id=&quot;8PST&quot;&gt;&lt;strong&gt;Этап 3: Анализ cookie и сессионных заголовков&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;XL8h&quot;&gt;Заголовок &lt;code&gt;Set-Cookie&lt;/code&gt; не только управляет сессиями, но и выдаёт технологии.&lt;/p&gt;
  &lt;p id=&quot;Qgd1&quot;&gt;&lt;strong&gt;&lt;code&gt;Set-Cookie:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;ZvoF&quot;&gt;
    &lt;li id=&quot;cAt9&quot;&gt;&lt;code&gt;PHPSESSID=...&lt;/code&gt; → PHP (версия сессионного механизма).&lt;/li&gt;
    &lt;li id=&quot;W1dy&quot;&gt;&lt;code&gt;JSESSIONID=...&lt;/code&gt; → Java (JSP).&lt;/li&gt;
    &lt;li id=&quot;Kj7D&quot;&gt;&lt;code&gt;ASPSESSIONID...&lt;/code&gt; → &lt;a href=&quot;https://asp.net/&quot; target=&quot;_blank&quot;&gt;ASP.NET&lt;/a&gt;.&lt;/li&gt;
    &lt;li id=&quot;NkAq&quot;&gt;&lt;code&gt;laravel_session=...&lt;/code&gt; → Laravel (PHP-фреймворк).&lt;/li&gt;
    &lt;li id=&quot;9058&quot;&gt;&lt;code&gt;XSRF-TOKEN&lt;/code&gt; → часто используется в Angular, Laravel, Django.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;uvdA&quot;&gt;&lt;strong&gt;Флаги cookie (httponly, secure, samesite):&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;PFKG&quot;&gt;
    &lt;li id=&quot;KIGi&quot;&gt;&lt;code&gt;HttpOnly&lt;/code&gt; — недоступен для JavaScript (хорошо для безопасности).&lt;/li&gt;
    &lt;li id=&quot;y3F4&quot;&gt;&lt;code&gt;Secure&lt;/code&gt; — только через HTTPS.&lt;/li&gt;
    &lt;li id=&quot;MaLg&quot;&gt;&lt;code&gt;SameSite=Lax/Strict&lt;/code&gt; — защита от CSRF.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;WJf8&quot;&gt;&lt;strong&gt;Этап 4: Заголовки безопасности (Security Headers)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;MMxV&quot;&gt;Оценка безопасности веб-приложения — важная часть разведки. Слабые настройки могут привести к уязвимостям (кликджекинг, XSS, перехват сессий).&lt;/p&gt;
  &lt;p id=&quot;LP8t&quot;&gt;&lt;strong&gt;4.1. Content-Security-Policy (CSP)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;EDCA&quot;&gt;CSP — белый список источников загрузки ресурсов (скриптов, стилей, изображений). Хорошо настроенный CSP сильно уменьшает риск XSS.&lt;/p&gt;
  &lt;p id=&quot;V39N&quot;&gt;&lt;strong&gt;Анализ CSP:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;iDXM&quot;&gt;
    &lt;li id=&quot;DFir&quot;&gt;&lt;code&gt;default-src &amp;#x27;none&amp;#x27;&lt;/code&gt; — жёсткая политика.&lt;/li&gt;
    &lt;li id=&quot;7YUL&quot;&gt;&lt;code&gt;script-src &amp;#x27;self&amp;#x27;&lt;/code&gt; — разрешены скрипты только с того же домена.&lt;/li&gt;
    &lt;li id=&quot;ryPG&quot;&gt;&lt;code&gt;unsafe-inline&lt;/code&gt;, &lt;code&gt;unsafe-eval&lt;/code&gt; — опасные директивы, делают CSP бесполезным.&lt;/li&gt;
    &lt;li id=&quot;dFii&quot;&gt;&lt;code&gt;report-uri /report-csp-violation&lt;/code&gt; — куда отправлять отчёты о нарушениях.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;vFsn&quot;&gt;&lt;strong&gt;Ошибки:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;KXIB&quot;&gt;
    &lt;li id=&quot;5DVA&quot;&gt;Отсутствие CSP — распространённая проблема.&lt;/li&gt;
    &lt;li id=&quot;wI5u&quot;&gt;Наличие &lt;code&gt;unsafe-inline&lt;/code&gt; без nonce/hash — снижает защиту.&lt;/li&gt;
    &lt;li id=&quot;UYUv&quot;&gt;Слишком широкие источники (&lt;code&gt;*.example.com&lt;/code&gt;, &lt;code&gt;https:&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;8Fo3&quot;&gt;&lt;strong&gt;4.2. HSTS (HTTP Strict Transport Security)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;efPa&quot;&gt;Принудительное использование HTTPS для всех подключений к домену.&lt;/p&gt;
  &lt;p id=&quot;KMXW&quot;&gt;&lt;strong&gt;Пример:&lt;/strong&gt; &lt;code&gt;Strict-Transport-Security: max-age=31536000; includeSubDomains; preload&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;9U1Y&quot;&gt;&lt;strong&gt;Анализ:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;TimN&quot;&gt;
    &lt;li id=&quot;BZOg&quot;&gt;&lt;code&gt;max-age=0&lt;/code&gt; — отключено (опасно).&lt;/li&gt;
    &lt;li id=&quot;g57z&quot;&gt;&lt;code&gt;includeSubDomains&lt;/code&gt; — принудительный HTTPS для всех поддоменов.&lt;/li&gt;
    &lt;li id=&quot;7Xi0&quot;&gt;&lt;code&gt;preload&lt;/code&gt; — домен включён в предзагружаемый список браузеров (максимальный уровень).&lt;/li&gt;
    &lt;li id=&quot;02ri&quot;&gt;Отсутствие HSTS — возможность атаки «понижения до HTTP» (SSL stripping).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Webn&quot;&gt;&lt;strong&gt;4.3. X-Frame-Options&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;LUTv&quot;&gt;Защита от кликджекинга (встраивания сайта в frame).&lt;/p&gt;
  &lt;p id=&quot;4C47&quot;&gt;&lt;strong&gt;Значения:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;2HrA&quot;&gt;
    &lt;li id=&quot;cqOE&quot;&gt;&lt;code&gt;DENY&lt;/code&gt; — запрещено встраивание в frame.&lt;/li&gt;
    &lt;li id=&quot;3i2f&quot;&gt;&lt;code&gt;SAMEORIGIN&lt;/code&gt; — разрешено только с того же домена.&lt;/li&gt;
    &lt;li id=&quot;ojt7&quot;&gt;&lt;code&gt;ALLOW-FROM uri&lt;/code&gt; — устаревшее.&lt;/li&gt;
    &lt;li id=&quot;LNeN&quot;&gt;Отсутствие заголовка — сайт можно встроить в &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; (угроза UI redressing).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;0CjR&quot;&gt;&lt;strong&gt;4.4. X-Content-Type-Options&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;KbdL&quot;&gt;Защита от MIME-тип-путаницы (MIME sniffing).&lt;/p&gt;
  &lt;p id=&quot;QQtS&quot;&gt;&lt;strong&gt;Единственное допустимое значение:&lt;/strong&gt; &lt;code&gt;nosniff&lt;/code&gt;. Если отсутствует — браузер может выполнить script, даже если тип указан как текст.&lt;/p&gt;
  &lt;p id=&quot;itT6&quot;&gt;&lt;strong&gt;4.5. X-XSS-Protection&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;zy81&quot;&gt;Старый заголовок для защиты от XSS (в основном для старых браузеров).&lt;/p&gt;
  &lt;p id=&quot;aqKs&quot;&gt;&lt;strong&gt;Значения:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;x8MK&quot;&gt;
    &lt;li id=&quot;Ob0H&quot;&gt;&lt;code&gt;1; mode=block&lt;/code&gt; — блокировать страницу при обнаружении XSS.&lt;/li&gt;
    &lt;li id=&quot;Zvbk&quot;&gt;&lt;code&gt;1&lt;/code&gt; — попытаться очистить (менее безопасно).&lt;/li&gt;
    &lt;li id=&quot;SMaU&quot;&gt;&lt;code&gt;0&lt;/code&gt; — отключено.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;kdmG&quot;&gt;В современных браузерах во многом заменён CSP, но его наличие всё же полезно.&lt;/p&gt;
  &lt;p id=&quot;A9T7&quot;&gt;&lt;strong&gt;4.6. Referrer-Policy&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;8xz5&quot;&gt;Контролирует передачу referer при переходе по ссылкам.&lt;/p&gt;
  &lt;p id=&quot;3gks&quot;&gt;&lt;strong&gt;Настройки:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;zFcD&quot;&gt;
    &lt;li id=&quot;uoMB&quot;&gt;&lt;code&gt;no-referrer&lt;/code&gt; — вообще не передавать.&lt;/li&gt;
    &lt;li id=&quot;wrvk&quot;&gt;&lt;code&gt;strict-origin&lt;/code&gt; — передавать только схему и домен (при HTTPS→HTTPS).&lt;/li&gt;
    &lt;li id=&quot;i6jx&quot;&gt;&lt;code&gt;unsafe-url&lt;/code&gt; — всегда передавать полный URL (опасно, утечка параметров).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;NEbS&quot;&gt;&lt;strong&gt;4.7. Feature-Policy / Permissions-Policy&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4bsS&quot;&gt;Ограничивает доступ к функциям браузера (камера, микрофон, геолокация). Может содержать информацию о политиках организации.&lt;/p&gt;
  &lt;p id=&quot;03ra&quot;&gt;&lt;strong&gt;Этап 5: Заголовки, указывающие на CDN, прокси, кэширование&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;ZXZD&quot;&gt;Эти заголовки помогают понять, скрыт ли реальный IP сервера за CDN, используется ли балансировка, кэширование.&lt;/p&gt;
  &lt;p id=&quot;VjmM&quot;&gt;&lt;strong&gt;Cloudflare:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;lXzN&quot;&gt;
    &lt;li id=&quot;OvbA&quot;&gt;&lt;code&gt;CF-Cache-Status&lt;/code&gt; (HIT, MISS, EXPIRED, DYNAMIC).&lt;/li&gt;
    &lt;li id=&quot;wYMV&quot;&gt;&lt;code&gt;CF-RAY&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;nm2j&quot;&gt;&lt;code&gt;CF-Connection-Connecting&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;YgVj&quot;&gt;&lt;strong&gt;Akamai:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;xNfe&quot;&gt;
    &lt;li id=&quot;5SDk&quot;&gt;&lt;code&gt;X-Akamai-Transformed&lt;/code&gt;, &lt;code&gt;X-Akamai-Cache-Status&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;gH5T&quot;&gt;&lt;strong&gt;AWS CloudFront:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;kovb&quot;&gt;
    &lt;li id=&quot;zz51&quot;&gt;&lt;code&gt;X-Amz-Cf-Id&lt;/code&gt;, &lt;code&gt;X-Cache&lt;/code&gt; (Hit from cloudfront).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;dXlF&quot;&gt;&lt;strong&gt;Varnish:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;Hh6q&quot;&gt;
    &lt;li id=&quot;ZYin&quot;&gt;&lt;code&gt;X-Varnish&lt;/code&gt;, &lt;code&gt;X-Cache&lt;/code&gt; (HIT, MISS).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;jbhK&quot;&gt;&lt;strong&gt;Этап 6: Анализ заголовков на предмет утечки внутренней информации&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Qhkq&quot;&gt;Некоторые заголовки могут раскрывать внутреннюю инфраструктуру:&lt;/p&gt;
  &lt;ul id=&quot;d1DQ&quot;&gt;
    &lt;li id=&quot;Ahmz&quot;&gt;&lt;code&gt;X-Backend-Server&lt;/code&gt; — имя внутреннего сервера.&lt;/li&gt;
    &lt;li id=&quot;Psm6&quot;&gt;&lt;code&gt;X-Debug-Token&lt;/code&gt;, &lt;code&gt;X-Debug-Token-Link&lt;/code&gt; — утечка отладочной информации.&lt;/li&gt;
    &lt;li id=&quot;wzCw&quot;&gt;&lt;code&gt;X-Server-Name&lt;/code&gt; — имя сервера внутри сети.&lt;/li&gt;
    &lt;li id=&quot;2KfV&quot;&gt;&lt;code&gt;X-Forwarded-For&lt;/code&gt; (иногда) — реальный IP клиента, но может содержать IP прокси.&lt;/li&gt;
    &lt;li id=&quot;bfph&quot;&gt;&lt;code&gt;Via&lt;/code&gt; — прокси-серверы (например, &lt;code&gt;Via: 1.1 varnish&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;wJja&quot;&gt;&lt;strong&gt;Если увидели &lt;code&gt;X-Backend-Server: web01.internal.company.com&lt;/code&gt; — это очень ценно: можно узнать внутреннюю структуру и возможные имена хостов.&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;0sIS&quot;&gt;&lt;strong&gt;Этап 7: Инструменты для массового сбора заголовков&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Ns8z&quot;&gt;&lt;strong&gt;Httpx (от ProjectDiscovery)&lt;/strong&gt; — быстрый HTTP-клиент, собирает заголовки, извлекает технологии, поддерживает вывод в JSON.&lt;/p&gt;
  &lt;pre id=&quot;e9ZG&quot;&gt;httpx -u https://example.com -sc -title -tech-detect -json -o headers.json&lt;/pre&gt;
  &lt;p id=&quot;dKHg&quot;&gt;&lt;strong&gt;HTTPX (Python-библиотека) — позволяет автоматизировать запросы:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;XmTb&quot;&gt;import httpx

def get_headers(url):
    try:
        response = httpx.get(url, follow_redirects=True, timeout=10)
        headers = dict(response.headers)
        # дополнительные данные
        headers[&amp;#x27;_status_code&amp;#x27;] = response.status_code
        headers[&amp;#x27;_url&amp;#x27;] = str(response.url)
        return headers
    except Exception as e:
        return {&amp;#x27;_error&amp;#x27;: str(e)}

# Пример для одного сайта
print(get_headers(&amp;#x27;https://example.com&amp;#x27;))&lt;/pre&gt;
  &lt;p id=&quot;mRGD&quot;&gt;&lt;strong&gt;Этап 8: Автоматический анализ с помощью &lt;a href=&quot;https://securityheaders.com/&quot; target=&quot;_blank&quot;&gt;SecurityHeaders.com&lt;/a&gt; API&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;wPSD&quot;&gt;&lt;a href=&quot;https://securityheaders.com/&quot; target=&quot;_blank&quot;&gt;SecurityHeaders.com&lt;/a&gt; предоставляет API для оценки заголовков.&lt;/p&gt;
  &lt;pre id=&quot;qad3&quot;&gt;curl https://securityheaders.com/?q=https://example.com&amp;amp;hide=on&lt;/pre&gt;
  &lt;p id=&quot;gGpU&quot;&gt;Ответ — HTML, но можно парсить. Оценка от A+ до F (рекомендуется A).&lt;/p&gt;
  &lt;p id=&quot;hECp&quot;&gt;&lt;strong&gt;Пример из утилиты:&lt;/strong&gt; можно использовать &lt;code&gt;curl&lt;/code&gt; и &lt;code&gt;grep&lt;/code&gt; для извлечения рейтинга.&lt;/p&gt;
  &lt;p id=&quot;imXk&quot;&gt;&lt;strong&gt;Этап 9: Оценка качества и потенциальных уязвимостей по заголовкам&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;lDeM&quot;&gt;&lt;strong&gt;Недостатки в заголовках безопасности могут указывать на слабую защиту:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;7NbQ&quot;&gt;
    &lt;li id=&quot;tJDo&quot;&gt;Нет HSTS → риск с stripping (особенно для сайтов с логинами).&lt;/li&gt;
    &lt;li id=&quot;9i7U&quot;&gt;Нет CSP → уязвимость XSS.&lt;/li&gt;
    &lt;li id=&quot;nIFu&quot;&gt;Нет X-Frame-Options → риск кликджекинга.&lt;/li&gt;
    &lt;li id=&quot;Q3Tu&quot;&gt;Наличие &lt;code&gt;X-Powered-By&lt;/code&gt; с точной версией → может помочь злоумышленнику (но не является уязвимостью).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;k0ft&quot;&gt;&lt;strong&gt;Практический пример: разбор заголовков сайта с логином&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;XEN7&quot;&gt;&lt;em&gt;Задача:&lt;/em&gt; проверить защищённость сайта &lt;code&gt;login.target.com&lt;/code&gt; по заголовкам.&lt;/p&gt;
  &lt;ol id=&quot;XlhH&quot;&gt;
    &lt;li id=&quot;ht1N&quot;&gt;&lt;strong&gt;Запрос заголовков:&lt;/strong&gt;textcurl -I https://login.target.comОтвет:textHTTP/2 200 server: nginx/1.22.0 x-powered-by: PHP/7.4.33 set-cookie: PHPSESSID=abc123; path=/; HttpOnly; Secure strict-transport-security: max-age=0 x-frame-options: DENY x-content-type-options: nosniff x-xss-protection: 1; mode=block content-security-policy: default-src &amp;#x27;self&amp;#x27;&lt;/li&gt;
    &lt;li id=&quot;mYpX&quot;&gt;&lt;strong&gt;Анализ:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;NsrE&quot;&gt;
      &lt;li id=&quot;RRLK&quot;&gt;&lt;code&gt;server: nginx/1.22.0&lt;/code&gt; — версия Nginx актуальна на момент проверки.&lt;/li&gt;
      &lt;li id=&quot;Z6zv&quot;&gt;&lt;code&gt;x-powered-by: PHP/7.4.33&lt;/code&gt; — PHP 7.4.33 EOL? Проверить (на момент написания 7.4 достиг EOL, могут быть уязвимости).&lt;/li&gt;
      &lt;li id=&quot;Nv5J&quot;&gt;&lt;code&gt;PHPSESSID&lt;/code&gt; с &lt;code&gt;HttpOnly; Secure&lt;/code&gt; — хорошо.&lt;/li&gt;
      &lt;li id=&quot;xq9B&quot;&gt;&lt;code&gt;strict-transport-security: max-age=0&lt;/code&gt; — HSTS выключен! Очень плохо для страницы логина.&lt;/li&gt;
      &lt;li id=&quot;GpEW&quot;&gt;CSP: &lt;code&gt;default-src &amp;#x27;self&amp;#x27;&lt;/code&gt; — хорошо, но лучше конкретные директивы.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;Pfek&quot;&gt;&lt;strong&gt;Рекомендации:&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;6md8&quot;&gt;
      &lt;li id=&quot;c8hx&quot;&gt;Включить HSTS с долгим max-age.&lt;/li&gt;
      &lt;li id=&quot;2H4x&quot;&gt;Обновить PHP до поддерживаемой версии.&lt;/li&gt;
      &lt;li id=&quot;2VGT&quot;&gt;Расширить CSP, запретив inline-скрипты.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;s28z&quot;&gt;&lt;strong&gt;Этап 10: Мониторинг изменений заголовков&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;viQH&quot;&gt;Заголовки могут меняться со временем: администраторы могут включить HSTS, изменить версии ПО. Мониторинг изменений помогает отслеживать обновления безопасности.&lt;/p&gt;
  &lt;p id=&quot;H6aD&quot;&gt;&lt;strong&gt;Как организовать мониторинг:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;izbo&quot;&gt;
    &lt;li id=&quot;bRGL&quot;&gt;Периодически запрашивать заголовки (раз в день, раз в неделю).&lt;/li&gt;
    &lt;li id=&quot;XZcX&quot;&gt;Сравнивать хэши ответов (или конкретных заголовков).&lt;/li&gt;
    &lt;li id=&quot;yj8x&quot;&gt;При изменении — уведомление.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Bolf&quot;&gt;&lt;strong&gt;Python-скрипт мониторинга:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;TkOU&quot;&gt;import hashlib
import httpx
import time

def fetch_headers_hash(url):
    response = httpx.get(url, follow_redirects=True)
    # конкатенируем все заголовки в строку
    headers_str = str(sorted(response.headers.items()))
    return hashlib.sha256(headers_str.encode()).hexdigest()

def monitor(url, interval_hours=24):
    last_hash = None
    while True:
        current_hash = fetch_headers_hash(url)
        if last_hash is None:
            last_hash = current_hash
            print(f&amp;quot;Initial hash: {current_hash}&amp;quot;)
        elif current_hash != last_hash:
            print(f&amp;quot;Headers changed for {url}!&amp;quot;)
            # здесь можно отправить уведомление
            last_hash = current_hash
        time.sleep(interval_hours * 3600)&lt;/pre&gt;
  &lt;p id=&quot;bp9o&quot;&gt;&lt;strong&gt;Этические и правовые ограничения&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;rxU1&quot;&gt;
    &lt;li id=&quot;K8mr&quot;&gt;Сбор заголовков с помощью curl/httpx — это обычный HTTP-запрос, который не нарушает закон (аналогично посещению сайта браузером).&lt;/li&gt;
    &lt;li id=&quot;UXPF&quot;&gt;Использование &lt;a href=&quot;https://securityheaders.com/&quot; target=&quot;_blank&quot;&gt;SecurityHeaders.com&lt;/a&gt; и аналогичных сервисов также легально.&lt;/li&gt;
    &lt;li id=&quot;Hljj&quot;&gt;Массовый сбор заголовков (тысячи доменов) может привести к блокировке IP, если сайт расценит это как сканирование. Используйте разумные интервалы.&lt;/li&gt;
    &lt;li id=&quot;ncjG&quot;&gt;Анализ заголовков безопасности не даёт права атаковать сайт. Информация используется для оценки защищённости (в рамках разрешённого тестирования).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;23Uj&quot;&gt;HTTP-заголовки — богатый источник информации при пассивном техническом OSINT. Идентификационные заголовки (&lt;code&gt;Server&lt;/code&gt;, &lt;code&gt;X-Powered-By&lt;/code&gt;) раскрывают версии ПО, что позволяет искать уязвимости. Заголовки cookie указывают на используемые технологии и фреймворки. Заголовки безопасности (CSP, HSTS, X-Frame-Options) оценивают защищённость веб-приложения. Заголовки кэширования и прокси помогают определить CDN и скрыть реальный IP. Комбинация этих данных с результатами других статей цикла даёт наиболее полную картину инфраструктуры цели.&lt;/p&gt;

</content></entry></feed>