Содержание статьи

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

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

По­это­му я попытал­ся выс­тро­ить уни­вер­саль­ный рабочий про­цесс, который мог бы как‑то уни­фици­ровать базовые про­вер­ки. Точ­нее, нас­толь­ко уни­вер­саль­ный, нас­коль­ко это воз­можно.

Я пос­тарал­ся сде­лать статью понят­ной и инте­рес­ной для спе­циалис­тов с любым уров­нем и бэк­гра­ундом. Я добав­лял в ворк­флоу такие про­вер­ки, которые, на мой взгляд, необ­ходимо про­водить поч­ти на любом про­екте — будь то Red Team, пен­тест или ана­лиз защищен­ности.

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

Я ста­рал­ся исхо­дить из того, что на стар­те нам известен самый минимум. Если в тво­ей задаче есть какие‑то дру­гие ввод­ные дан­ные и, нап­ример, спи­сок доменов уже известен, то прос­то про­пус­кай до нуж­ного мес­та.

На­ши методы и сце­нарии будут по воз­можнос­ти пас­сивны­ми, но сре­ди них могут попадать­ся и под­разуме­вающие какое‑то минималь­ное вза­имо­дей­ствие. Об этом я буду пре­дуп­реждать сра­зу же — помет­кой «вза­имо­дей­ствие» на слу­чай, если тебе нуж­но пол­ное отсутс­твие активных дей­ствий.

 

Структура папок

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

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

 

Используемый софт

Здесь я крат­ко опи­шу час­то исполь­зуемые ути­литы. Некото­рые из них мало­извес­тны, поэто­му неп­лохо будет ска­зать пару слов о том, как и для чего они при­меня­ются:

  • anew слу­жит для добав­ления в файл уни­каль­ных строк из stdin;
  • html-tool исполь­зует­ся для ана­лиза отве­тов сер­вера;
  • fff мы будем исполь­зовать для сох­ранения заголов­ков и тела отве­та в фай­лы;
  • inscope поз­воля­ет исклю­чать все, что за пре­дела­ми ско­упа;
  • paramrep был мной раз­работан в качес­тве ана­лога для qsreplace. Ути­лита qsreplace мне не пон­равилась тем, что она изме­няет абсо­лют­но все парамет­ры в URL сра­зу (это дела­ет резуль­тат неп­ред­ска­зуемым), а paramrep под­меня­ет парамет­ры по одно­му;
  • curl-impersonate — усо­вер­шенс­тво­ван­ный curl. Поз­воля­ет обхо­дить защиту от ботов, изоб­ражая легитим­ный бра­узер, в том чис­ле путем под­мены JA3-фин­гер­прин­та, что в пос­леднее вре­мя все акту­аль­нее.

Для inscope нуж­но соз­дать в кор­невом катало­ге про­екта фай­лик .scope при­мер­но с таким содер­жимым:

.*\.example\.com$
^example\.com$
 

Цели

Гло­баль­но на эта­пе пас­сивной раз­ведки перед нами сто­ят сле­дующие цели:

  • поз­накомить­ся с тар­гетами, понять, нас­коль­ко они боль­шие и архи­тек­турно слож­ные, какие тех­нологии исполь­зуют­ся;
  • соб­рать спи­сок под­доменов;
  • соб­рать живые под­домены;
  • по­лучить нес­коль­ко опци­ональ­ных фай­лов для руч­ного ана­лиза;
  • соб­рать спи­сок IP-адре­сов;
  • по­лучить спи­сок URL-адре­сов из раз­ных источни­ков в пас­сивном режиме;
  • пос­мотреть в пас­сивном режиме пор­ты и сер­висы;
  • про­верить в пас­сивном режиме уяз­вимос­ти;
  • изу­чить утеч­ки учет­ных дан­ных;
  • соб­рать из откры­тых источни­ков спи­сок email-адре­сов.
 

Первое знакомство

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

 

Букмарклет для сбора URL (взаимодействие)

Свое пер­вое зна­комс­тво с тар­гетом я пред­почитаю начинать с бег­лого взгля­да на цель с помощью спе­циаль­но заготов­ленной JavaScript‑зак­ладки. Она выводит спи­сок уни­каль­ных адре­сов, най­ден­ных на текущей стра­нице.

info

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

Вот код бук­мар­кле­та:

javascript:(async function(){let scanningDiv=document.createElement("div");scanningDiv.style.position="fixed",scanningDiv.style.bottom="0",scanningDiv.style.left="0",scanningDiv.style.width="100%",scanningDiv.style.maxHeight="50%",scanningDiv.style.overflowY="scroll",scanningDiv.style.backgroundColor="white",scanningDiv.style.color="black",scanningDiv.style.padding="10px",scanningDiv.style.zIndex="9999",scanningDiv.style.borderTop="2px solid black",scanningDiv.innerHTML="<h4>Scanning...</h4>",document.body.appendChild(scanningDiv);let e=[],t=new Set;async function n(e){try{const t=await fetch(e);return t.ok?await t.text():(console.error(`Failed to fetch ${e}: ${t.status}`),null)}catch(t){return console.error(`Error fetching ${e}:`,t),null}}function o(e){if(!(e.startsWith("/")||e.startsWith("./")||e.startsWith("../")))return!1;if(e.includes(" ")||/[^\x20-\x7E]/.test(e))return!1;if(e.length<2||e.length>=200)return!1;if(e.includes("{")||e.includes("}")||e.includes(":")||e.includes("?")||e.includes("*")||e.includes("(")||e.includes(")")||e.includes("[")||e.includes("]"))return!1;return!0}function s(e){return[...e.matchAll(/[%27"]((?:\/|\.\.\/|\.\/)[^%27"]+)[%27"]/g)].map(e=>e[1]).filter(o)}async function c(o){if(t.has(o))return;t.add(o),console.log(`Fetching and processing: ${o}`);const c=await n(o);if(c){const t=s(c);e.push(...t)}}const l=performance.getEntriesByType("resource").map(e=>e.name);console.log("Resources found:",l);for(const e of l)await c(e);const i=[...new Set(e)];console.log("Final list of unique paths:",i),console.log("All scanned resources:",Array.from(t)),scanningDiv.innerHTML=`<h4>Unique Paths Found:</h4><ul>${i.map(e=>`<li>${e}</li>`).join("")}</ul>`})();

Как уста­новить и исполь­зовать этот бук­мар­клет:

  • до­бавь новую зак­ладку на панель зак­ладок в бра­узе­ре;
  • за­мени URL зак­ладки фраг­ментом кода на JavaScript;
  • от­крой целевую стра­ницу и щел­кни по бук­мар­кле­ту;
  • ес­ли не сра­бота­ло, поищи раз­решение запус­кать бук­мар­кле­ты в нас­трой­ках безопас­ности бра­узе­ра.
Результат запуска
Ре­зуль­тат запус­ка
 

Онлайновые сервисы

В про­дол­жение зна­комс­тва с целью мы можем исполь­зовать онлай­новые сер­висы для поис­ка информа­ции о сай­те:

  • suip.biz — неп­лохо подой­дет для поис­ка под­доменов;
  • coolakov.ru/tools/ping — поз­воля­ет быс­тро смот­реть ста­тус‑коды по доменам и повер­хностно озна­комить­ся с заголов­ками; более деталь­ный ана­лиз я опи­шу далее.

Этот этап занима­ет нем­ного вре­мени, но уже на нем ты поз­накомишь­ся с целью и потен­циаль­но выявишь такие уяз­вимос­ти, как, нап­ример, subdomain takeover.

 

Проверяем утечки

Для обще­го понима­ния сис­темы и обо­гаще­ния информа­ции неп­лохо было бы пос­мотреть утеч­ки учет­ных дан­ных поль­зовате­лей или сот­рудни­ков нашей цели. Обыч­но этот тип про­верок выделя­ют в отдель­ный вид работ, которым занима­ются спе­циалис­ты по OSINT. Я при­веду нес­коль­ко ресур­сов для при­мера (на самом деле их нам­ного боль­ше):

 

Собираем почты

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

 

EmailHarvester

EmailHarvester — одна из ути­лит для поис­ка и сбо­ра email-адре­сов.

Ни­же при­веде­на bash-коман­да для запус­ка ути­литы и поис­ка по спис­ку доменов:

(trap 'kill 0' SIGINT; while IFS= read -r domain; do target_name=$(echo $domain | sed "s/[^a-zA-Z0-9]/_/g"); echo "Starting EmailHarvester for $domain"; python3 EmailHarvester.py -d "$domain" -s "email_${target_name}.txt"; done < ~debian/Desktop/scope)
 

LinkedIn

Ду­маю, все зна­ют такой ресурс для IT-спе­циалис­тов, как LinkedIn. С его помощью мы можем спар­сить email-адре­са сот­рудни­ков инте­ресу­ющей нас ком­пании. Ниже при­веден при­мер работы неп­лохой ути­литы CrossLinked, которая справ­ляет­ся с этой задачей (и, кста­ти, не тре­бует ни учет­ной записи, ни API-клю­ча).

При­мер коман­ды для запус­ка:

python3 crosslinked.py -f '{first}.{last}@example.ru' "Рога и Копыта"

Тут я пред­лагаю сде­лать неболь­шую паузу и обра­тить вни­мание на то, что у нас уже есть на дан­ный момент:

  • эн­дпо­инты на целевом ресур­се;
  • спи­сок утек­ших учет­ных дан­ных;
  • по­вер­хностное понима­ние лан­дшаф­та, сос­тавлен­ное по активным под­доменам, без глу­боко­го изу­чения;
  • спи­сок email-адре­сов сот­рудни­ков ком­пании.
 

TLD и root domains

В этом раз­деле и далее мы нач­нем занимать­ся, как сей­час мод­но говорить, Attack Surface Managed. Приш­ло вре­мя прис­тупить к сбо­ру акти­вов иссле­дуемой ком­пании и фор­мирова­нию повер­хнос­ти ата­ки.

 

Онлайн

Бы­вают ситу­ации, ког­да заказ­чик не пре­дос­тавля­ет пол­ный спи­сок под­доменов ком­пании. Тог­да нам нуж­но самос­тоятель­но най­ти домены, свя­зан­ные с нашим тар­гетом. В этом может помочь доволь­но извес­тный онлай­новый сер­вис whoxy.com, который пре­дос­тавля­ет мно­го полез­ной информа­ции как нап­рямую, так и кос­венно по иссле­дуемой цели.

 

Из командной строки

Ска­жу сра­зу, что, нес­мотря на мою любовь к CLI, этот метод мне не очень пон­равил­ся, так как при­ходит­ся переп­роверять валид­ность боль­шого объ­ема информа­ции. Вдо­бавок необ­ходимость поис­ка TLD (Top Level Domain) в рам­ках про­ектной деятель­нос­ти встре­чает­ся доволь­но ред­ко. Но все же ути­лита tldfinder сто­ит упо­мина­ния.

При­мер коман­ды:

tldfinder -d google -dm tld | anew domains

Я, впро­чем, пред­почитаю whoxy.com.

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

 

Собираем IP-адреса

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    2 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии