BChecks — это чекеры, которы­ми ты можешь допол­нить сущес­тву­ющие ска­неры уяз­вимос­тей Burp. Чекер — это шаб­лон наподо­бие популяр­ных шаб­лонов Nuclei. В статье я покажу, как делать прос­тые и быс­трые чекеры, а заод­но раз­берем­ся со скрип­товым язы­ком Burp.

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

warning

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

 

Пассивное сканирование

BChecks иде­аль­но под­ходит для пас­сивно­го ана­лиза, ког­да нет необ­ходимос­ти делать допол­нитель­ные зап­росы. Так ты соберешь мак­симум дан­ных без лиш­них сле­дов на сер­вере.

 

Первый чекер

На­шим «Hello world!» будет скрипт, который отсле­жива­ет отве­ты веб‑при­ложе­ния и ищет в них заголо­вок X-Powered-By. Заголо­вок X-Powered-By ука­зыва­ет на основную тех­нологию веб‑при­ложе­ния, может рас­кры­вать кон­крет­ную вер­сию. Нап­ример, X-Powered-By: PHP/8.3.4 , который говорит о потен­циаль­ной кри­тичес­кой уяз­вимос­ти CVE-2024-4577.

Что­бы начать соз­давать пер­вый BСheck, перей­ди на вклад­ку Extensions и най­ди там BСhecks. Жми New и выбери Blank BCheck. Так ты соз­дашь пус­той шаб­лон.

В Burp есть база примеров шаблонов
В Burp есть база при­меров шаб­лонов

В начале любого шаб­лона ука­зыва­ются метадан­ные:

metadata:
# Версия языка. На сегодня доступна только одна версия языка
language: v2-beta
# При добавлении уязвимости это название подставится в название потенциальной уязвимости
name: "X-Powered-By detected"
# Необязательные параметры, описывающие скрипт
description: "Простой пример пассивного сканирования"
author: "ret0x2A"
tags: "passive", "headers"

До­бавь блок объ­явле­ния перемен­ных define.

define:
# Переменная объявляется с простым присвоением
x_header = "X-Powered-By"
# Можно использовать подстановки
problem = `Нашли заголовок {x_header}, возможен слив технологии`

Переменные

Встро­енный язык под­держи­вает два вари­анта объ­явле­ния перемен­ных: define для кон­стант и run for each для мас­сивов. При исполь­зовании мас­сивов шаб­лон выпол­нит про­вер­ки для каж­дого эле­мен­та мас­сива. Перемен­ные прос­то под­став­ляют­ся как зна­чения.

Жес­тких тре­бова­ний для этих бло­ков нет. Можешь исполь­зовать бло­ки по отдель­нос­ти или вмес­те, можешь вооб­ще обой­тись без них.

Дей­ствия и логика работы про­писы­вают­ся в бло­ке given then. В given явно ука­зыва­ется слу­чай, ког­да ска­нер выпол­нит про­вер­ку. Мы догово­рились, что будем обра­баты­вать отве­ты веб‑при­ложе­ния, зна­чит, нуж­но исполь­зовать given response then:

# Чекер срабатывает при каждом ответе от сайта
given response then
# Ищем хидер в последнем ответе сайта
if {x_header} in {latest.response.headers} then
# Фиксация уязвимости в Burp
report issue:
# Уровень угрозы info|low|medium|high
severity: info
# Точность certain|firm|tentative
confidence: firm
# Для получения значения переменной используй {}
detail: {problem}
end if

О блоке given ... then

Раз­работ­чики Burp пре­дус­мотре­ли given ... then для любых ситу­аций. Если тебе нуж­но выпол­нить скрипт один раз для все­го хос­та, вмес­то response исполь­зуй host. Для каж­дого пути, который нашел Burp, — path. Обра­бот­ка зап­росов — request.

Мож­но при­вязать работу к точ­кам инъ­екции, которые про­веря­ет ска­нер: cookie, header, body, query или ко всем сра­зу — any. Это зас­тавит шаб­лон запус­кать про­вер­ку для каж­дой точ­ки инъ­екции. Нап­ример, header зас­тавит выпол­нить чек для каж­дого заголов­ка в отдель­нос­ти: Host, Content-Type и так далее.

Точ­ки инъ­екции допус­тимо сов­мещать: given query or body insertion point. Эта запись озна­чает: «выпол­ни про­вер­ку как для парамет­ров в URL, так и для парамет­ров в теле зап­роса».

Твой ска­нер готов! Сох­рани код и перехо­ди к запус­ку.

Форматирование

BCheck не предъ­явля­ет тре­бова­ний к фор­матиро­ванию. Отсту­пы могут быть любыми или отсутс­тво­вать вов­се. Даже такая «мешани­на» будет работать:

define:not_found = "404"run for each:wl = "~", ".old", ".bak", ".backup"

Соб­людай разум­ный под­ход, что­бы удоб­но было читать и модифи­циро­вать код.

info

Ис­ходни­ки при­мера дос­тупны на GitHub.

 

Запускаем сканирование

Соз­дай новый скан типа Crawl and Audit, кон­фигура­ция ска­ниро­вания — кас­томная. В бло­ке Issues Reported выбери инди­виду­аль­ные зна­чения и сбрось все типы уяз­вимос­тей, кро­ме BCheck generated issue. В реаль­ных усло­виях ты будешь сов­мещать ска­неры, но сей­час важ­но сок­ратить вре­мя ска­ниро­вания.

Настройка сканера на BCheck
Нас­трой­ка ска­нера на BCheck

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

Burp понимает, что мы искали, и подсвечивает в интерфейсе
Burp понима­ет, что мы иска­ли, и под­све­чива­ет в интерфей­се

При­мер прос­той, но ты можешь рас­ширить его, получив кучу полез­ных ска­неров: поиск токенов и сек­ретных клю­чей, забытые ком­мента­рии раз­работ­чиков (такое встре­чает­ся не толь­ко на YouTube), опре­деле­ние CMS по метате­гу generator и так далее.

 

Ищем интересные файлы

Раз­работ­чики час­то забыва­ют фай­лы, иног­да очень опас­ные. Мне попада­лись пол­ные архи­вы с прод‑вер­сией, вклю­чая клю­чи. Встре­чались дам­пы баз дан­ных, бэкапы фай­лов скрип­тов и кон­фигов и даже дам­пы памяти. В целях обу­чения пой­дем от прос­того к слож­ному и нач­нем с поис­ка .gitignore.

metadata:
language: v2-beta
name: ".gitignore file"
description: "Пример поиска одного файла"
author: "ret0x2A"
tags: "git", "file"
define:
# В блоке define объявляются константы
potential_path = ".gitignore"
# Чекер будет выполнен для каждого пути
given path then
# Выполнить GET-запрос и поместить результат в check
send request called check:
method: "GET"
appending path: {potential_path}
# Если код ответа равен 200, то добавляем уязвимость
if {check.response.status_code} is "200" then
report issue and continue:
severity: high
confidence: certain
detail: `Найден файл {potential_path}.`
remediation: "Не оставляй что попало где попало"
end if

Прос­канируй любой закон­ный хост с фай­лом .gitignore в кор­не и получишь «уяз­вимость». Кри­тичес­кой она помече­на для демонс­тра­ции. Поп­робуй вари­ант с Severity: Low, что­бы уви­деть раз­ницу.

Найден .gitignore
Най­ден .gitignore

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

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

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

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

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

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

    Подписаться

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