Автоматизация атак в Burp Suite

burp suite

Сегодня я расскажу как автоматизировать атаки на веб‑при­ложе­ние. Для атак на веб‑при­ложе­ние можно использовать разные инструменты. Я использую Burp Suite и вот почему.

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

Данная утилита пре­дос­тавля­ет не один, а нес­коль­ко спо­собов авто­мати­зации:

  • Мак­росы
  • Пла­гин Stepper
  • Пла­гин Turbo Intruder

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

Стендом для выполнения множество повторяющих действий будет одно из заданий ресур­са PortSwigger Academy.

Описание задачи PortSwigger Academy

Перевод задачи с сай­та PortSwigger Academy:

Двух­фактор­ка в этом задании уяз­вима для перебора. Вы уже знаете имя поль­зовате­ля и пароль, но не име­ете дос­тупа к верифи­каци­онно­му коду поль­зовате­ля 2FA. Что­бы решить эту задачу, перебо­ром получите код 2FA для дос­тупа к стра­нице акка­унта Кар­лоса.

Учет­ные дан­ные жер­твы: carlos:montoya.

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

Подробнее о задании

Итак, дана стра­ница аутен­тифика­ции:

Автоматизация атак Burp Suite. Аутен­тифика­ция
Аутен­тифика­ция

При заполнении учет­ных дан­ных при­ложе­ние отправ­ляет зап­рос на сер­вер:

POST /login2 HTTP/1.1
Host: ace61ff51f4557d880dbab96004f009d.web-security-academy.net
Cookie: session=2gt4P1gFqzyxZJIonAlFv9czYetD5pm0
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

csrf=W9Nei8NhTXl5usVKeynuZ3kbjRHaVjW7&mfa-code=1234

Ес­ли правильно ввести учет­ные дан­ные, откроется стра­ница вво­да одноразового кода.

Автоматизация Burp Suite. Стра­ница вво­да одноразового пароля
Стра­ница вво­да одноразового пароля

Пос­ле вво­да слу­чай­ного OTP-кода при­ложе­ние отпра­вит сле­дующий зап­рос:

POST /login2 HTTP/1.1
Host: ace61ff51f4557d880dbab96004f009d.web-security-academy.net
Cookie: session=2gt4P1gFqzyxZJIonAlFv9czYetD5pm0
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

csrf=W9Nei8NhTXl5usVKeynuZ3kbjRHaVjW7&mfa-code=1234

Ес­ли у нас получится уга­дать одноразовый код, задание будет выполнено. Уга­дать OTP-код не так уже и трудно, шансов: 1 к 10 000. Если взять в учет то, что мы имеем неограниченной количес­тво попыток, положительный резуль­тат нам гаран­тирован.

На что следует обратить внимание?

  • В при­ложе­нии исполь­зуется сес­сион­ный иден­тифика­тор, который предоставляется при вхо­де на сайт. Он изме­няет­ся пос­ле пер­вого эта­па аутен­тифика­ции при помощи кор­рек­тных учет­ных дан­ных.
  • Пос­ле аутен­тифика­ции у нас есть толь­ко две попыт­ки вво­да OTP-кода. Пос­ле двух неудач­ных попыток наша сес­сия инва­лиди­рует­ся и при­ходит­ся начинать весь про­цесс с начала.
  • При­ложе­ние исполь­зует CSRF-токены, которые меня­ются при каж­дом зап­росе. Их необ­ходимо под­хва­тывать и под­менять для каж­дого нашего POST-зап­роса.

Ос­талось авто­мати­зиро­вать про­цесс получе­ния сес­сии, вво­да пер­вичных учет­ных дан­ных, под­хва­та CSRF-токенов и попыток пред­ска­зания OTP-кода. Прис­тупим!

Еще по теме: Лучшие расширения для Burp Suite

Способы решения

Автоматизация атаки с помощью макросов

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

  1. С запущен­ным Burp Suite вхо­дим в сис­тему как Кар­лос (учет­ные дан­ные ука­заны в задаче) и собира­ем пакеты HTTP-аутен­тифика­ции вплоть до про­вер­ки 2FA. Они при­годят­ся нам для нас­трой­ки мак­роса.
  2. Пос­коль­ку сес­сия пос­тоян­но изме­нят­ся и инва­лиди­рует­ся при неус­пешных попыт­ках вво­да кода, нам понадо­бит­ся каким‑то обра­зом ее под­держи­вать. Для это­го мы будем исполь­зовать воз­можнос­ти обра­бот­ки сеан­сов Burp. Перей­дем к их нас­трой­ке.
  3. В меню Burp перей­дите в Project Options → Sessions. На панели Session Handling Rules наж­мите кноп­ку Add. Откро­ется диалог Session handling rule editor. Здесь мы будем добав­лять пра­вила под­держа­ния сес­сии и ее возоб­новле­ния.
  4. В окне диало­га во вклад­ке Scope в раз­деле URL Scope выберем зна­чение Include All URLs, что­бы не утруждать себя тон­кой нас­трой­кой. Сес­сия будет под­держи­вать­ся для любых URL.
  5. Вер­немся на вклад­ку Details и нач­нем соз­давать мак­рос. В раз­деле Rule Actions наж­мем кноп­ку Add и в открыв­шемся окош­ке выберем Run a macro. Здесь и нач­нется про­цесс соз­дания мак­роса, который будет пов­торять­ся при отправ­ке каж­дого нашего зап­роса.
  6. В открыв­шемся окне нас­трой­ки мак­роса выберем зап­росы для авто­мати­зации (это будут зап­росы пер­вично­го вхо­да, получе­ния иден­тифика­тора сес­сии и токена CSRF для отправ­ки пер­вой фор­мы). Для это­го в раз­деле Select macro нажима­ем кноп­ку Add. Здесь мы выбира­ем пакет вхо­да на стра­ницу /login (GET-зап­рос), пакет отправ­ки учет­ных дан­ных с POST-зап­росом к стра­нице /login и пакет вхо­да на стра­ницу /login2, где Burp под­хва­тит токен CSRF для вво­да OTP-кода.
  7. В этой же вклад­ке в ниж­нем пра­вом углу мож­но про­тес­тировать соз­данный нами мак­рос, нажав кноп­ку Test macro. Если мы наж­мем эту кноп­ку, то уви­дим, что Burp выпол­нит три зап­роса под­ряд, под­хва­тит выдан­ные ему Cookie дан­ные и получит токен CSRF, который надо было исполь­зовать для отправ­ки фор­мы. Уже сей­час нам оста­ется толь­ко авто­мати­зиро­вать ввод OTP-кода, и дело сде­лано.
  8. На­жима­ем ОK и зак­рыва­ем диало­говые окна. Теперь при отправ­ке каж­дого зап­роса Burp будет выпол­нять дан­ный мак­рос для получе­ния новой сес­сии, а потом под­став­лять зна­чение сес­сии и зна­чение токена CSRF в исхо­дящий зап­рос для их обновле­ния.
  9. Те­перь возь­мем зап­рос с отправ­кой OTP-кода (POST-зап­рос к стра­нице /login2) и отпра­вим его в Intruder для авто­мати­зации.
  10. Во вклад­ке Intruder’а оставля­ем для наг­рузки толь­ко поле mfa-code (вот так: mfa-code=§1234§) и перехо­дим во вклад­ку Payloads. Здесь выбира­ем для Payload Type зна­чение Numbers и ука­зыва­ем циф­ры, которые мы хотим генери­ровать: From: 0, To: 9999, Step: 1, Min integer digits: 4.
  11. Пе­рехо­дим во вклад­ку Options и нас­тра­иваем Number of threads в зна­чение 1 (это нуж­но потому, что Burp не уме­ет одновре­мен­но под­держи­вать иден­тифика­торы сес­сии для двух и более потоков, толь­ко для одно­го).
  12. Пос­ле это­го запус­каем Intruder и вклю­чаем режим «жду­на».

На уга­дыва­ние кода Intruder понадо­билось поряд­ка десяти минут (мой код был 0643). Это супер­долго! Даже не десятая часть всех попыток. Почему нель­зя быс­трее? Потому что Session Handling не может под­держи­вать сес­сию у двух потоков одновре­мен­но.

Под­ведем итог того, что нам дают мак­росы и что они уме­ют.

Воз­можнос­ти:

  • удоб­но под­держи­вать сеанс сес­сии, пос­тоян­но зах­ватывая иден­тифика­тор сес­сии самос­тоятель­но, даже если он обновля­ется;
  • под­хва­тыва­ются не толь­ко зна­чения сес­сии, но и все зна­чения, которые исполь­зуют­ся для выпол­нения нового зап­роса: перемен­ные, токены CSRF и про­чее.

Проб­лемы:

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

Автоматизация атаки с помощью плагина Stepper

Пла­гин Stepper — это бес­плат­ный пла­гин, дос­тупный в модуле Burp Suite Extender, который помога­ет авто­мати­зиро­вать пос­ледова­тель­нос­ти дей­ствий. Най­ти его мож­но на GitHub.

Раз­работ­чики рас­ска­зыва­ют о Stepper сле­дующее:

Stepper раз­работан как естес­твен­ное раз­витие инс­тру­мен­та Repeater из Burp Suite, пре­дос­тавляя воз­можность соз­давать пос­ледова­тель­нос­ти шагов и опре­делять регуляр­ные выраже­ния для извле­чения зна­чений из отве­тов, которые затем могут быть исполь­зованы в пос­леду­ющих шагах.

Ус­тановим его и вос­поль­зуем­ся им для решения нашей задачи.

Очень важ­но! Если вы дела­ете это пос­ле пре­дыду­щего экспе­римен­та, отклю­чите соз­данные ранее пра­вила обра­бот­ки сес­сий и уда­лите мак­росы!

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

Шаг 1: Во вклад­ке Proxy выбира­ем три зап­роса, которые нам нуж­ны для получе­ния сес­сии, пер­вичной аутен­тифика­ции и извле­чения CSRF-токена. Вот они: GET /login, POST /login, GET /login2. Выделив дан­ные зап­росы, щел­каем на них пра­вой кноп­кой мыши и в под­разде­ле Extensions нажима­ем кноп­ку Add 3 items to Stepper > New Sequence. Нам пред­ложат выб­рать для этой пос­ледова­тель­нос­ти наз­вание. Я назову ее evil.

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

Шаг 2: Пе­рехо­дим в модуль Stepper, который появил­ся во вклад­ках с осталь­ными модуля­ми.

Шаг 3: Здесь мы уви­дим нашу пос­ледова­тель­ность и три пакета, про­нуме­рован­ные от 1 до 3. Каж­дый из пакетов мы можем пов­торно отпра­вить, нажав на кноп­ку Execute Step, что­бы получить при­мер тела отве­та, и про­тес­тировать каж­дый шаг.

Шаг 4: Вы­пол­ним пер­вый шаг, нажав кноп­ку Execute Step. Соз­дадим пер­вую перемен­ную для хра­нения и переда­чи иден­тифика­тора сес­сии, нажав на кноп­ку Add Variable в ниж­нем пра­вом углу модуля. Назовем перемен­ную session и добавим ей усло­вие поис­ка в поле Condition: session=([\d\w]+). Таким обра­зом у нас появит­ся пер­вая перемен­ная сес­сии, которую мы будем проб­расывать по осталь­ным зап­росам и исполь­зовать пов­торно.

Шаг 5: Так­же добавим вто­рую перемен­ную токена CSRF, которую проб­росим на сле­дующий зап­рос отправ­ки учет­ных дан­ных. Наж­мем кноп­ку Add Variable, назовем перемен­ную csrf и добавим усло­вие нахож­дения ее в теле отве­та в поле Condition со сле­дующим зна­чени­ем: name="csrf" value="([\w\d]+)"«.

Вот что получи­лось у меня пос­ле выпол­нения этих шагов.

Пер­вичная нас­трой­ка Stepper
Пер­вичная нас­трой­ка Stepper

Шаг 6: Те­перь мож­но перей­ти к сле­дующе­му зап­росу отправ­ки учет­ных дан­ных и исполь­зовать в нем перемен­ные session и csrf. Для это­го перехо­дим к сле­дующе­му шагу (Step 2) и вмес­то сущес­тву­ющих там зна­чений сес­сии и CSRF-токена под­ста­вим обра­щение к перемен­ным в сле­дующем виде: $VAR:session$ и $VAR:csrf$. Получит­ся что‑то вро­де это­го:

POST /login HTTP/1.1
Host: ac3f1f861fe209fb80374867009900fe.web-security-academy.net
Cookie: session=$VAR:session$
Content-Type: application/x-www-form-urlencoded
Content-Length: 70

csrf=$VAR:csrf$&username=carlos&password=montoya

Шаг 7: Вы­пол­ним этот вто­рой шаг нажати­ем на кноп­ку Execute Step и получим ответ, где нас попыта­ются перенап­равить на стра­ницу /login2 и выдадут нам новый иден­тифика­тор сес­сии, который нам сно­ва нуж­но зах­ватить при помощи регуляр­ных выраже­ний и передать на сле­дующий шаг № 3. Соз­даем такую же перемен­ную session как и в пун­кте 4, и перехо­дим к шагу № 3.

Шаг 8: На шаге № 3 не забыва­ем сно­ва изме­нить зна­чение сес­сии на перемен­ную $VAR:session$ и выпол­няем зап­рос, так как нам прос­то нуж­но получить токен CSRF для пос­ледне­го шага. Пос­ле выпол­нения зап­роса сно­ва добав­ляем пар­синг токена CSRF в виде перемен­ной csrf, как мы это делали в пун­кте 5 ранее.

Шаг 9: Те­перь мы можем поп­робовать выпол­нить всю пос­ледова­тель­ность и про­верить ее работос­пособ­ность. Наж­мем на кноп­ку Execute Sequence в самом низу окна модуля. Видим, что пос­ледова­тель­ность выпол­нилась кор­рек­тно и на пос­леднем шаге мы получа­ем ответ с пред­ложени­ем ввес­ти OTP-код.

Те­перь наша задача запус­тить дан­ную пос­ледова­тель­ность 10 тысяч раз. Для это­го перено­сим POST-зап­рос /login2 из вклад­ки Proxy в Intruder.

Шаг 10: В панели Intruder нам нуж­но убрать сим­волы под­ста­новок § в полях сес­сии и CSRF-токена и оста­вить под­ста­нов­ку толь­ко в поле mfa-code вот так: mfa-code=§1337§.

Шаг 11: Для того что­бы шаги нашей пос­ледова­тель­нос­ти из модуля Stepper выпол­нялись для каж­дого зап­роса из Intruder, добавим в заголов­ки зап­роса сле­дующее: X-Stepper-Execute-Before: [Название вашей последовательности]

Шаг 12: Так­же под­ста­вим име­на наших перемен­ных $VAR:session$ и $VAR:csrf$ в пакет Intruder, толь­ко испра­вим их на $VAR:[Название вашей последовательности]:session$ и $VAR:[Здесь тоже]:csrf$. В Intruder у меня получил­ся сле­дующий пакет зап­роса:

POST /login2 HTTP/1.1
Host: ac311f2c1f2abcbd807689da0068009a.web-security-academy.net
Cookie: session=$VAR:evil:session$
Content-Type: application/x-www-form-urlencoded
X-Stepper-Execute-Before: evil
Content-Length: 51

csrf=$VAR:evil:csrf$&mfa-code=§1337§

В дан­ном при­мере имя моей пос­ледова­тель­нос­ти — evil.

Те­перь перед каж­дым зап­росом из Intruder будет выпол­нять­ся пос­ледова­тель­ность ранее под­готов­ленных зап­росов, которые переда­дут в пакет получен­ные зна­чения сес­сии и CSRF-токена.

Шаг 13: Пос­ледний шаг, нас­тра­иваем наг­рузку во вклад­ке Payloads, точ­но так же, как мы это делали в пре­дыду­щем раз­деле. Выбира­ем в Payload Type зна­чение Numbers и ука­зыва­ем циф­ры, которые мы хотим генери­ровать: From: 0, To: 9999, Step: 1, Min integer digits: 4.

Шаг 14: За­пус­каем нашу ата­ку! Отсле­живать отправ­ленные пакеты мож­но в появив­шей­ся вклад­ке Logger или при помощи модуля Logger++.
В этот раз мне повез­ло боль­ше, мой код был 0261. Что важ­ного мож­но заметить? В отли­чие от пре­дыду­щего вари­анта мы не огра­ниче­ны одним потоком и соз­дали пять потоков, а самые умные мог­ли отклю­чить галоч­ку Set Connection: close в опци­ях наг­рузки и уда­лить этот заголо­вок из пакетов в Stepper и Intruder, что­бы уве­личить ско­рость работы.

Сде­лаем выводы.

Воз­можнос­ти:

  • из‑за того что модуль Stepper под­держи­вает сес­сии, переда­вая зна­чение сес­сии и токена от зап­роса к зап­росу, мы можем исполь­зовать мно­гопо­точ­ное исполне­ние зап­росов и наши перемен­ные не будут кон­флик­товать в потоках;
  • нам ста­новят­ся дос­тупны перек­рес­тные ата­ки, ког­да мы можем запус­кать работу нес­коль­ких пос­ледова­тель­нос­тей парал­лель­но;
  • на­тив­но понят­ная нас­трой­ка перено­са сос­тояний от зап­роса к зап­росу и лег­ко добав­ляемый заголо­вок X-Stepper-Execute-Before:, который запус­кает Stepper для любого модуля.

Проб­лемы:

  • на самом деле Stepper не поз­воля­ет исполь­зовать так мно­го потоков, как хотелось бы. Око­ло трех потоков дей­стви­тель­но успе­вают работать вмес­те, но из‑за осо­бен­ностей кода модуля боль­шее их количес­тво толь­ко тор­мозит выпол­нение;
  • при­ходит­ся вруч­ную нас­тра­ивать перемен­ные для каж­дого зап­роса, что может выг­лядеть изну­ряюще скуч­но.

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

Автоматизация атаки с помощью Turbo Intruder

Turbo Intruder — один из самых мощ­ных инс­тру­мен­тов Burp Suite, и его дол­жен осво­ить каж­дый ува­жающий себя поль­зователь Burp. Его так­же мож­но ска­чать с GitHub.

Turbo Intruder пред­став­ляет собой рас­ширение Burp Suite для отправ­ки боль­шого количес­тва зап­росов HTTP и ана­лиза резуль­татов. Оно приз­вано допол­нить Burp Intruder, обра­баты­вая ата­ки, тре­бующие исклю­читель­ной ско­рос­ти, про­дол­житель­нос­ти или слож­ности. Этот модуль отли­чают сле­дующие осо­бен­ности.

  • Быс­тро­та: Turbo Intruder исполь­зует стек HTTP, соз­данный вруч­ную с нуля с уче­том ско­рос­ти. В резуль­тате на мно­гих целях он может серь­езно обог­нать даже мод­ные асин­хрон­ные скрип­ты на Go (на самом деле стек мож­но выб­рать, и боль­шинс­тво из них будут вам зна­комы).
  • Мас­шта­биру­емость: Turbo Intruder может дос­тичь плос­кого исполь­зования памяти, что поз­воля­ет про­водить надеж­ные мно­год­невные ата­ки. Его так­же мож­но запус­кать в headless-окру­жении через коман­дную стро­ку.
  • Гиб­кость: Ата­ки кон­фигури­руют­ся с помощью Python. Это поз­воля­ет выпол­нять слож­ные тре­бова­ния, нап­ример под­писан­ные зап­росы и мно­гос­тупен­чатые пос­ледова­тель­нос­ти атак. Кро­ме того, поль­зователь­ский стек HTTP поз­воля­ет обра­баты­вать неп­равиль­но сфор­мирован­ные зап­росы, которые лома­ют дру­гие биб­лиоте­ки.
  • Удобс­тво: скуч­ные резуль­таты могут быть авто­мати­чес­ки отфиль­тро­ваны с помощью усо­вер­шенс­тво­ван­ного алго­рит­ма дифов, адап­тирован­ного из Backslash Powered Scanner. Это озна­чает, что вы можете запус­тить ата­ку и получить полез­ные резуль­таты в два кли­ка.

Для исполь­зования Turbo Intruder необ­ходимо зна­ние основ Python. Тем не менее все, что нам нуж­но для начала, — это уста­новить Turbo Intruder из модуля Extender.

Пос­ле уста­нов­ки сра­зу же перей­дем к решению задачи.

  • Вы­берем самый пер­вый пакет в пос­ледова­тель­нос­ти во вклад­ке Proxy (пакет GET /login) и наж­мем на него пра­вой кноп­кой мыши. А даль­ше выберем пункт Extensions → Send to turbo intruder.
  • В открыв­шей­ся панели Turbo Intruder появит­ся зап­рос и при­меры скрип­тов, которые мож­но выб­рать для исполь­зования и модифи­кации. В дан­ном слу­чае все, что нам нуж­но для победы, — это написать скрипт, который поз­волит решить задание. Ниже я при­веду свой при­мер кода и объ­ясню логику скрип­та (сде­лайте мне скид­ку на качес­тво, вспом­нив о том, что пен­тесте­ры не уме­ют кодить):
import re
import time
# Регулярки для вытаскивания идентификаторов сессии и CSRF-токенов
re_csrf = 'name="csrf" value="([\w\d]+)"'
re_session = 'session=([\d\w]+)'
iterable = 0
def queueRequests(target, wordlists):
    global engine
    # Включаем один запрос на один коннект, чтобы не нарушать логику выполнения, коннекты в соответствии с тем, что выдержит приложение.
    # Все эти значения придется калибровать от сервера к серверу. Сервер задачи не очень хорошо держит высокую нагрузку, поэтому ограничимся пятью параллельными соединениями
    engine = RequestEngine(endpoint='https://ac051f441e762a3780359cb6002300a2.web-security-academy.net:443',concurrentConnections=5,requestsPerConnection=1)
    # Запускаем первые запросы, которые спровоцируют запуск последующих запросов.
    # Делаем задержку в одну секунду, чтобы потоки не исполнялись синхронно, а чередовались.
    for x in xrange(1,6):
        print '1. GET /login Request'
        engine.queue(target.req,'')
        time.sleep(1)
def handleResponse(req, interesting):
    global engine
    global iterable
    if 'Location: /my-account' in req.response:
        # Если мы в ответе получили данный заголовок, значит, мы победили
        table.add(req)
        print 'You Win!'
        return None
    if 'Incorrect security code' in req.response:
        # Если мы получили в ответе сообщение о неправильно введенном коде, значит, мы использовали одну попытку, и тогда мы запускаем новую итерацию запросов
        table.add(req)
        print '1. GET /login Request'
        engine.queue(target.req,'')
        return None
    if 'Please enter your 4-digit security code' in req.response:
        # Если в ответе мы получаем предложение ввести ОТР, то отправляем запрос с попыткой ввода ОТР
        match_csrf = re.search(re_csrf, req.response)
        match_session = re.search(re_session, req.getRequest())
        req = '''POST /login2 HTTP/1.1\r\nHost: ac051f441e762a3780359cb6002300a2.web-security-academy.net\r\nCookie: session=%s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 51\r\n\r\ncsrf=%s&mfa-code=%s'''
        print '4. POST /login2 Request'
        engine.queue(req, [match_session.group(1),match_csrf.group(1),str(iterable).zfill(4)])
        iterable += 1
        print 'Iterable: ' + str(iterable)
        return None
    if 'Location: /login2' in req.response:
        # Если в ответе мы получаем сообщение о переходе на страницу /login2, значит, мы ранее ввели корректные креды и теперь получаем новый идентификатор сессии и переходим на страницу для взятия CSRF для запроса с OTP
        match_session = re.search(re_session, req.response)
        req = '''GET /login2 HTTP/1.1\r\nHost: ac051f441e762a3780359cb6002300a2.web-security-academy.net\r\nCookie: session=%s\r\n\r\n'''
        print '3. GET /login2 Request'
        engine.queue(req, match_session.group(1))
        return None
    if '

Так как в Turbo Intruder нет воз­можнос­ти удоб­но под­держи­вать сес­сию меж­ду зап­росами, при­ходит­ся делать это руками, иног­да прос­то соз­давая новые зап­росы на осно­ве получен­ных иден­тифика­торов сес­сии из пос­ледне­го отве­та, иног­да на осно­ве дан­ных сес­сии, которые в зап­росе ранее.

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

При помощи дан­ного скрип­та мне уда­лось выпол­нить 400 попыток (~1500 зап­росов) за 30 секунд и решить задание при­мер­но в 20 раз быс­трее, чем в прош­лых при­мерах. Если быть чес­тным, то мож­но было пот­ратить чуть боль­ше вре­мени на калиб­ровку парамет­ров concurrentConnections, requestsPerConnection и pipeline и решить задачу еще быс­трее, но мне хва­тило и это­го.

Под­ведем ито­ги для это­го при­мера.

Воз­можнос­ти:

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

Проб­лемы:

  • нуж­но писать код, и это мало отли­чает­ся от написа­ния скрип­тов с нуля, хоть и дает боль­шое пре­иму­щес­тво в исполь­зовании под­готов­ленных абс­трак­ций для мно­гопо­точ­ного и парал­лель­ного выпол­нения зап­росов;
  • нет докумен­тации к инс­тру­мен­ту, кро­ме ряда при­меров, которых вам дол­жно хва­тить;
  • в наибо­лее быс­трых движ­ках зап­росов для Intruder зап­росы и отве­ты не логиру­ются в модули Logger или Logger++, что не поз­воля­ет удоб­но прос­матри­вать про­исхо­дящее в сети. При­ходит­ся исполь­зовать спо­собы отладки, встро­енные в сам Turbo Intruder и его абс­трак­ции.

Заключение

Лич­но мне импо­ниру­ет инс­тру­мент Turbo Intruder, но для нович­ков модуль Stepper или встро­енные мак­росы могут ока­зать­ся про­ще в исполь­зовании. Тем не менее для реаль­ных задач мак­росы и Stepper могут не подой­ти из‑за сво­ей мед­литель­нос­ти.

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

Еще по теме: Как искать уязвимости на сайтах

ВКонтакте
OK
Telegram
WhatsApp
Viber

Один комментарий

  1. Avatar
    Семён

    Вопрос .Как сделать так , чтобы в tor браузер был постоянный ip адрес ..У меня проблема в том , что так как на один сайт я постоянно захожу с разных ip , то всё время приходится подтверждать личность (приходит код на телефон ) как сделать так , чтобы всё время был 1 ip на сайте?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *