Indice dei contenuti
- Account
- Contatti
- Persone
- I miei Amici
- Following
- Richieste di amicizia ricevute
- Richieste di amicizia inviate
- Utenti bloccati
- Le tue Memorie
- BeReal del giorno delle persone
- BeReal delle persone
- BeReal appuntati
- BeReal appuntati delle persone
- Commenti sui BeReal
- Commenti sui BeReal delle persone
- RealMojis
- Hackemist SDWebImage Cache
- Screenshot
- Messaggi
- Lista delle chat
- Preferenze
- Da fare
- iLEAPP
Introduzione
BeReal è "la prima piattaforma imprevedibile e spontanea dove condividere con i tuoi amici la tua vita reale in una foto una volta al giorno". Ogni giorno ad un'ora differente tutti postano una foto entro due minuti dalla "notifica ⚠️È l'ora di BeReal ⚠️". E' possibile vedere quello che stanno facendo i tuoi amici, commentare i BeReal, chattare con loro e reagire con un RealMoji, un selfie emoji. Tutti i post su BeReal hanno una data di scadenza di 24 ore, ciò significa che il post condiviso sarà visibile agli amici nel loro feed di notizie per 24 ore.
Il BeReal è un'immagine composita della foto scattata dalla fotocamera posteriore e quella della miniatura di un selfie, uno scatto simultaneo con entrambe le fotocamere senza filtri e senza pretese, la "vita pura".
BeReal è un social network francese lanciato nel 2020 da Alexis Berreyat e Kevin Perreau e molto popolare anche all'estero soprattutto tra gli studenti universitari.
Prima di procedere con l'analisi dell'app voglio fare solo una piccola precisazione sul concetto di BeReal: non è solo un'immagine composita (selfie + ambiente) ma può essere anche un Behind The Scenes (selfie + breve video). Inoltre il concetto di immagine "composita" è solo visivo, in realtà i due contenuti sono separati.
Per maggiori dettagli sulle funzionalità dell'app consulta https://bereal.com.
App Store: https://apps.apple.com/us/app/bereal-photos-friends-daily/id1459645446
Per lo studio di questa app sono state utilizzate le versioni 4.0.0 (Dec 18, 2024) e successive fino alla 4.11.0 (Feb 25, 2025) del mio iPhone 8 iOS 16.7.10 test e quelle delle immagine pubbliche di Josh Hickman iOS 17.3, 16.1.2 e 15.3.1 con le rispettive versioni 2.24.0, 1.21.4 e 1.1.0.
Percorsi
Di seguito lo stralcio di BeReal del poster della SANS “iOS Third-Party Apps Forensics Reference Guide Poster” con le informazioni più rilevanti per l’analisi dell’app.
Account
Le informazioni relative all'account sono memorizzate nel file JSON <GUID> nell'Internal App Path "/Library/Caches/disk-bereal-ProfileRepository/". Il nome del file sembra essere un <GUID> statico, A1B45C7AD2D36812F84D02FE91935978: sia nelle immagini di Josh Hickman che nel mio iPhone 8, il file nell'Internal App Path ha sempre lo stesso nome, ovvero lo stesso GUID.
A1B45C7AD2D36812F84D02FE91935978
Per la visualizzazione ho usato dfDataViewer, il mio visualizzatore di (B)Plist, JSON(B), (B)XML, ASN.1, Protobuf, LevelDB, etc. ancora in fase di sviluppo e non pubblico.
= sfondo grigio, indica che la key è presente nelle versioni precedenti alla 4.x.
Il dizionario object:
- createdAt: 756316789.27699995 (data di creazione nel formato MAC Absolute Time 19 dicembre 2024 15:59:49);
- profileType: (tipo di profilo)
- regular: (la chiave rappresenta il tipo, ad es. regular=account standard, brand=marchi, i RealBrand e celebrity=celebrità, i RealPeople);
- fullname: Django (nome completo);
- username: django.f (username/nickname);
- profilePicture: (immagine del profilo)
- url: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/profile/CBEd9NNTW-igELqojHxxx.webp (URL dell'immagine del profilo);
- size: (array)
- [0]: 1000 (larghezza in pixel);
- [1]: 1000 (altezza in pixel);
- width: 1000 (larghezza in pixel);
- height: 1000 (altezza in pixel);
- gender: (identità di genere, ad es. male, female, etc.)
- male (la chiave rappresenta il genere);
- birthDate: -895881600 (data di nascita/compleanno nel formato MAC Absolute Time 12 agosto 197x);
- biography: Digital Forensics Consultant (biografia);
- countryCode: IT (codice paese);
- region: europe-west (zona);
- region: (zona)
- value: europe-west (zona);
- location: Fondi (luogo/indirizzo);
- phoneNumber: +393494955xxx (numero di telefono);
- devices: (array di dispositivi)
- [0].timezone: Europe/Rome (fuso orario);
- [0].clientVersion: 4.0.0 (versione dell'app);
- [0].device: iPhone10,1 16.7.10 (id modello e versione iOS);
- [0].deviceId: 6F3A454F-8C8D-408F-85E9-B5427D715xxx (UID del dispositivo);
- isPrivate: false (è un profilo privato?);
- realmojis: (array di emoji creati con i selfie)
- [0].emoji: 👍 (emoji);
- [0].media: (informazioni sul media)
- url: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/realmoji/JVgRDw52ClLUWdDe.webp (URL del RealMoji);
- id: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'account).
Contatti
I contatti della rubrica sono memorizzati nel file JSON BFF2C013D3A049A79B7E56DF3A4BC444 nell'Internal App Path "/Library/Caches/disk-bereal-RelationshipsContactsManager-contact/".
BFF2C013D3A049A79B7E56DF3A4BC444
L'array object (esempio contatto=4):
- [4].completeName: Luca Talano (nome completo);
- [4].familyName: Talano (cognome);
- [4].middleName: null (secondo nome);
- [4].givenName: Luca (nome);
- [4].nickName: null (nickname);
- [4].photo: iVBORw0KGgoAAAANSUhEUgAAAj.../m9gAAAABJRU5ErkJggg== (foto del contatto codificata in Base64);
- [4].organizationName: null (nome dell'organizzazione);
- [4].phoneNumbers: (numeri di telefono)
- [0]: +393396472xxx.
L'anteprima della foto del contatto Luca Talano
e l'elenco dei contatti sul dispositivo.
Persone
I profili visitati delle persone sono memorizzati nell'Internal App Path "/Library/Caches/PersonRepository/<GUIDs>". Ogni file <GUID> è un JSON che contiene solo un oggetto con i dettagli del profilo, i BeReal del giorno, i commenti etc.
4B76A6B9D11C812F0081DA50AA9FC319 (profilo del mio amico Luigi dopo aver accettato la richiesta di amicizia)
La struttura del profilo è più o meno la stessa di quella dell'account. Di seguito è riportata una rappresentazione parziale dei dati.
L'object object:
- createdAt: 757163847.72399998 (data di creazione nel formato MAC Absolute Time 29 dicembre 2024 11:17:27);
- profileType: (tipo di profilo)
- regular: (la chiave rappresenta il tipo, regular=account standard);
- fullname: Luigi (nome completo);
- username: lmsconos (username/nickname);
- profilePictureURL: null (URL dell'immagine del profilo);
- biography: null (biografia);
- location: null (luogo/indirizzo);
- relationship: (dettagli della relazione);
- status: accepted (richiesta accettata);
- friendedAt: 757163982 (amici dal, nel formato MAC Absolute Time 29 dicembre 2024 11:19:42);
- commonFriends: (amici in comune);
- links: (array di collegamenti)
- [?].url: (URL);
- [?].displayText: (testo visualizzato);
- streakCount: 0 (numero di BeReal consecutivi postati quando si riceve la "notifica ⚠️È l'ora di BeReal ⚠️"; F.A.Q.);
- beRealOfTheDay: (BeReal del giorno)
- postExists: false (ci sono post?);
- series: (informazioni sui post)
- posts: (array di post)
- lastPostDate: (data dell'ultimo post, nel formato MAC Absolute Time);
- momentID: (identificatore univoco del momento);
- user: (dati dell'utente, ad es. id, username, etc.);
- id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco della persona).
Le persone, solo quelle degli account ufficiali ovvero i Marchi e le Celebrità, possono essere anche estrapolate dal JSON "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>/disk-bereal-Production_officialAccountProfiles/<GUID>".
La persona a differenza del caso precedente è memorizzata in un dizionario la cui chiave è l'identificatore univoco della persona.
93B9431273FBA3B3B85FB357A5829440
L'account di Burger King France per esempio (key=zVDl6eo_ua9IKeoF1fzWr):
- officialAccountProfileType: (tipo di profilo)
- brand: (la chiave rappresenta il tipo, brand=Brand);
- fullname: Burger King France (nome completo);
- username: burgerkingfr (username/nickname);
- profilePictureURL: https://cdn-us1.bereal.network/Photos/zVDl6eo_ua9IKeoF1fzWr/profile/nRyiQ9OKzV_ZqwqJTh1oZ.webp (URL dell'immagine del profilo);
- biography: Le seul endroit où vous ne découvrirez toujours pas la tête du CM. (biografia);
- location: null (luogo/indirizzo);
- links: (array di collegamenti)
- [0].url: https://www.burgerking.fr/ (URL);
- [0].displayText: https://www.burgerking.fr/ (testo visualizzato);
- id: zVDl6eo_ua9IKeoF1fzWr (identificatore univoco della persona).
I miei Amici
L'elenco degli amici è memorizzato nel file JSON 5D0D66C27E420224031B3AE11392258F nell'Internal App Path "/Library/Caches/disk-bereal-RelationshipsFriendsListManager/". Dopo aver richiesto l'amicizia a Luigi (il mio amico, secondo numero/account test), che ha accettato ovviamente, ho analizzato il file.
5D0D66C27E420224031B3AE11392258F
L'array object:
- [0].fullname: Luigi (nome completo);
- [0].username: lmsconos (username/nickname);
- [0].profilePictureURL: null (URL dell'immagine del profilo);
- [0].status: accepted (richiesta accettata);
- [0].id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco).
Following
Gli amici seguiti sono memorizzati nel file JSON "/Library/Caches/disk-bereal-Production_FriendsStorage.following/DE5633954D4FAAF02EACA2B033C16475.following". Nella prima fase di test con nessun amico aggiunto, l'array users è vuoto. Successivamente ho aggiunto un marchio (brand) Adidas e una celebrità (celebrity) Abby Anderson e ho potuto definire sia la struttura del JSON che identificare i valori profileType=brand per i marchi che profileType=celebrity per le celebrità.
L'object object:
- relationship: following (seguo);
- totalCount: 2 (totale dei follower);
- users: (l'array con gli utenti seguiti)
- [0].fullname: Abby Anderson (nome completo);
- [0].username: abbyandersonmusic (username/nickname);
- [0].profileType: (tipo di profilo)
- brand: (la chiave rappresenta il tipo, ad es. brand=marchi, celebrity=celebrità);
- [0].profilePictureURL: https://cdn-us1.bereal.network/Photos/ZJZUAZgjp5--tEttgw9B2/profile/89BdOLjv7G29GuokYT7h8.webp (URL dell'immagine del profilo);
- [0].id: ZJZUAZgjp5--tEttgwxxx (identificativo univoco).
Inoltre i follower possono essere anche estrapolati dal JSON "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>/disk-bereal-Production_following/<GUID>".
32C53D01DE07B3825C6DE3A845DF3818
L'array object:
- [0].name: Abby Anderson (nome completo);
- [0].username: abbyandersonmusic (username/nickname);
- [0].type: celebrity (tipo di profilo);
- [0].avatar: https://cdn-us1.bereal.network/Photos/ZJZUAZgjp5--tEttgw9B2/profile/89BdOLjv7G29GuokYT7h8.webp (URL dell'immagine del profilo);
- [0].userID: ZJZUAZgjp5--tEttgwxxx (identificativo univoco).
Richieste di amicizia ricevute
Le richieste di amicizia ricevute sono memorizzate nel file JSON "/Library/Caches/disk-bereal-RelationshipsRequestReceivedListManager/21AE575ACF7691A6ACEB62DC92D8DCBA".
L'array object:
- [0].statusUpdatedAt = : 757163982.85500002 (stato aggiornato alla data, nel formato MAC Absolute Time 29 dicembre 2024 11:19:42);
- [0].fullname: Luigi (nome completo);
- [0].username: lmsconos (username/nickname);
- [0].profileType: (tipo di profilo)
- regular: (la chiave rappresenta il tipo);
- [0].mutualFriends: 0 (amici in comune);
- [0].status: pending (in attesa di conferma, oppure rejected se rifiutata);
- [0].id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco).
Ho "convinto" il mio amico Luigi a registrarsi su BeReal per avere un secondo numero di telefono da poter gestire a richiesta, e l'analisi sopra esposta è il primo risultato ottenuto. Grazie Luigi per il tuo contributo 😁
Richieste di amicizia inviate
Le richieste di amicizia inviate sono memorizzate nel file JSON "/Library/Caches/disk-bereal-RelationshipsRequestSentListManager/9F71A7943D009FD239189A2F53829A52". Dopo aver rimosso Luigi dalla lista dei contatti bloccati, ho inviato una nuova richiesta di amicizia sempre a lui in modo da catturare questo evento.
L'array object:
- [0].statusUpdatedAt: 757362638.41700006 (stato aggiornato alla data, nel formato MAC Absolute Time 31 dicembre 2024 18:30:38);
- [0].fullname: Luigi (nome completo);
- [0].username: lmsconos (username/nickname);
- [0].profileType: (tipo di profilo)
- regular: (la chiave rappresenta il tipo);
- [0].status: sent (richiesta inviata, oppure canceled se annullata);
- [0].mutualFriends: 0 (amici in comune);
- [0].id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco).
Utenti bloccati
La lista degli utenti bloccati è memorizzata nel file "/Library/Caches/disk-bereal-BlockedUserManager/8B96367A4AAA1F1F4D78CE92602C1B90". Dopo aver ricevuto la richiesta di amicizia sempre dal mio amico Luigi, prima di accettare e/o rifiutare, l'ho bloccato per catturare anche la lista dei bloccati.
8B96367A4AAA1F1F4D78CE92602C1B90
L'array object:
- [0].blockedDate: 757174563.18000007 (data del blocco nel formato MAC Absolute Time 29 dicembre 2024 14:16:03);
- [0].fullname: Luigi (nome completo);
- [0].username: lmsconos (username/nickname);
- [0].id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco).
Le tue Memorie
Le memorie, ovvero la raccolta dei BeReal del giorno visibili nel calendario, sono memorizzati nel file JSON "/Library/Caches/disk-bereal-MemoriesRepository-subject-key/2C43A74B75CE53EFAA247E2AEB95B9C0" dal più recente al meno recente.
2C43A74B75CE53EFAA247E2AEB95B9C0
Nota: Il BeReal è del giorno 21 dicembre 2024 e il dispositivo ha il fuso orario Europe/Rome, ovvero UTC+1. Di seguito il valore di memoryDate: 756428400 che corrisponde alla data 20 dicembre 2024 23:00:00, è il giorno 21 dicembre 2024 00:00:00 del calendario del dispositivo.
L'array object (esempio post=6):
- [6].memoryDate: 756428400 (data del ricordo nel formato MAC Absolute Time 20 dicembre 2024 23:00:00);
- [6].isLate: false (il BeReal è successivo allo slot temporale di due minuti per postare?);
- [6].main: (informazioni del BeReal principale)
- analyticsPostType: onTime (onTime=postato al momento della notifica, oppure late=successivo alla notifica);
- takenAt: 756499186.92700005 (data dello scatto nel formato MAC Absolute Time 21 dicembre 2024 18:39:46);
- primary: (tipicamente la camera posteriore)
- mediaType: (photo=foto o video=video)
- photo: (la chiave rappresenta il tipo);
- url: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/qRKzdxZ26Kgt1rVi.webp (URL del media);
- width: 1500 (larghezza dell'immagine);
- height: 2000 (altezza dell'immagine);
- secondary: (selfie, stessa struttura del primary);
- thumbnail: (miniatura della primary, stessa struttura del primary)
- mediaType: (photo=foto o video=video)
- photo: (la chiave rappresenta il tipo);
- url: https://cdn-us1.bereal.network/cdn-cgi/image/height=130/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/qRKzdxZ26Kgt1rVi.webp (URL della miniatura);
- width: 97 (larghezza della miniatura);
- height: 130 (altezza della miniatura);
- [6].allDetailedPosts: (array di post)
- [0].momentAt: 756428400 (data del ricordo nel formato MAC Absolute Time 20 dicembre 2024 23:00:00);
- [0].momentID: RyKjYfWYDaqA4jql2Sxxx (identificatore univoco del momento del BeReal);
- [0].id: JqBYXSaKEoBK7G4-3Zxxx (identificatore univoco del BeReal);
- [0].postType: onTime (onTime=postato al momento della notifica, oppure late=successivo alla notifica);
- [0].details:
- full: (quando il BeReal del giorno è trascorso)
- data: (i dati)
- takenAt: 756499186.92700005 (data dello scatto nel formato MAC Absolute Time 21 dicembre 2024 18:39:46);
- primary: (camera posteriore);
- secondary: (selfie, stessa struttura del primary);
- thumbnail: (miniatura della primary, stessa struttura del primary);
- metadata: (i metadati)
- caption: C.C. Aprilia2 (titolo);
- location: (coordinate del posto, se attiva la geo-localizzazione)
- latitude: ??? (latitudine);
- longitude: ??? (longitudine);
- comments: (array con commenti);
- realmojis: (array di emoji creati con i selfie);
- tags: (array di amici/persone taggate)
- [0].tagName: @lmsconos (tag);
- [0].userId: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificativo univoco della persona);
- preview: (quando il BeReal del giorno è in corso)
- [6].momentID: RyKjYfWYDaqA4jql2Sxxx (identificatore univoco del momento del BeReal).
Il BeReal del giorno è quello principale presente nel main. Analizzando il JSON ho notato che i dettagli dei post sono memorizzati come array di BeReal; a cosa serve un array se il BeReal è uno? Avevo un BeReal in ritardo e così ho provato a fare un primo scatto e l'ho pubblicato; a fianco è comparso un riquadro "+ 1 altri", l'ho selezionato e ho aggiunto un altro BeReal, infine è uscito un altro riquadro con un lucchetto di blocco. Comunque, sia il principale che il secondario (Bonus BeReal) sono comparsi nei dettagli.
Le Memorie sul dispositivo (l'immagine di seguito è successiva a quella dell'analisi sopra esposta):
BeReal del giorno delle persone
I BeReal del giorno, possono essere estrapolati dal profilo delle persone, ovvero dal file "/Library/Caches/PersonRepository/<GUIDs>". Se la persona ha pubblicato il BeReal del giorno, postExists=true, allora o è presente il singolo post oppure la serie non interrotta di post.
4B76A6B9D11C812F0081DA50AA9FC319
La struttura dei post è grosso modo la stessa di quella nelle memorie personali.
I BeReal del giorno, l'array object.beRealOfTheDay.series.posts[i] (es. i=0):
- [0].takenAt: 760026219.66499996 (data di creazione nel formato MAC Absolute Time 31 gennaio 2025 14:23:39);
- [0].updatedAt: 1738333434253 (aggiornato alla data nel formato Unix Epoch in millisecondi 31 gennaio 2025 14:23:54);
- [0].isLate: true (il BeReal è successivo allo slot temporale di due minuti per postare?);
- [0].lateInSeconds: 1774 (se in ritardo, quanti secondi sono trascorsi);
- [0].retakeCounter: 0 (numero di tentativi fatti);
- [0].visibilities: (array di stringhe con la visibilità)
- [0]: friends (amici, ad es. friends=amici, friends-of-friends=amici di amici, public=pubblico);
- [0].primaryMedia: (camera posteriore);
- [0].secondaryMedia: (selfie, stessa struttura del primaryMedia);
- [0].tagsV2: (array di amici/persone taggate V2)
- [?].username: ? (username/nickname);
- [?].fullname: ? (nome completo);
- [?].profilePictureURL: https:// (URL dell'immagine del profilo);
- [?].id: ? (identificativo univoco della persona);
- [0]. ... (altro).
BeReal delle persone
BeReal delle persone sono memorizzati nel file JSON 788BE83F71ACE707BC67184155B6A923 dell'Internal App Path "/disk-bereal-Production_postFeedItems/" del contenitore di gruppo condiviso "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>".
788BE83F71ACE707BC67184155B6A923
L'array object contiene sia la chiave identificatore della persona come stringa e nella posizione successiva l'array con i post. La struttura dei post è la stessa quella del BeReal del giorno.
BeReal appuntati
I BeReal appuntati, Pins nella schermata del profilo, sono i tre BeReal preferiti, i più memorabili e sono memorizzati nel file JSON "/Library/Caches/disk-bereal-MemoriesRepository-pinnedMemories-key/010B69B9B7670B62BF499151211E0B0B".
A differenza del BeReal del giorno che sarà visibile nei feed delle notizie degli amici per sole 24 ore, quello appuntato non ha scadenza.
010B69B9B7670B62BF499151211E0B0B
L'array object:
- [0].takenAt: 757100169.43400002 (data di creazione nel formato MAC Absolute Time 28 dicembre 2024 17:36:09);
- [0].momentDay: 757033200 (data del momento del BeReal nel formato MAC Absolute Time 27 dicembre 2024 23:00:00);
- [0].primary: (fotocamera primaria, in genere quella posteriore)
- mediaType: (photo=foto o video=video)
- photo: (la chiave rappresenta il tipo);
- url: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/xfbzj038hsmlIEc0.webp (URL dell'immagine);
- width: 1500 (larghezza dell'immagine);
- height: 2000 (altezza dell'immagine);
- [0].secondary: (fotocamera secondaria, in genere quella frontale)
- mediaType: (photo=foto o video=video)
- photo: (la chiave rappresenta il tipo);
- url: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/qKg3ejQRQIx_CP_R.webp (URL dell'immagine);
- width: 1502 (larghezza dell'immagine);
- height: 2000 (altezza dell'immagine);
- [0].analyticsPostType: onTime (onTime=postato al momento della notifica, oppure late=successivo alla notifica);
- [0].analyticsMomentID: W_FryMaPGgv9WIR1wF6GX (identificatore univoco della memoria);
- [0].analyticsAuthorID: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'autore);
- [0].id: JqBYXSaKEoBK7G4-3ZMpe (identificatore univoco del BeReal).
L'indice dell'array indica la posizione del pin nella schermata: 0=primo elemento.
BeReal appuntati delle persone
I BeReal appuntati delle persone sono memorizzati nel file JSON "/Library/Caches/disk-bereal-PersonRepository-pinnedMemories-key/33EA32225214D909DAF36160B4DBF769".
Ho chiesto sempre a lui, l'amico Luigi di appuntare un suo BeReal per verificare eventuali modifiche della struttura del JSON rispetto a quella dei miei Pins. Qualcosa si è cambiato e la situazione è quella illustrata di seguito.
Il dizionario object ha come chiave l'id della persona e il suo valore è l'array di BeReal appuntati. In figura è presente una sola persona "mDO7GN3gKaY7d8xTxujhQoY0cxxx", il mio amico Luigi e un solo pin [0] con la struttura di quella del BeReal appuntati precedentemente analizzata.
33EA32225214D909DAF36160B4DBF769
e sul dispositivo
Commenti sui BeReal
I commenti in questione sono quelli dei BeReal personali e possono essere estrapolati dal file JSON delle memorie "/Library/Caches/disk-bereal-MemoriesRepository-subject-key/2C43A74B75CE53EFAA247E2AEB95B9C0".
I commenti sul BeReal object.allDetailedPosts[i], l'array object.allDetailedPosts[i].details.full.metadata.comments:
- [0].creationDate: 757767968.30500007 (data del commento nel formato MAC Absolute Time 05 gennaio 2025 11:06:08);
- [0].userName: django.f (nome utente dell'autore);
- [0].text: Test commento semplice (testo);
- [0].profilePictureUrl: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/profile/CBEd9NNTW-igELqojHZm6.webp (URL dell'immagine del profilo dell'autore);
- [0].uid: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'utente);
- [0].id: zmd1UrmumdwRIcXK2pxxx (identificatore univoco del commento).
Altre informazioni utili per dettagliare i commenti sono contenute nell'object object.allDetailedPosts[i]:
- details.full.metadata.caption: C.C. Maximo Roma (didascalia/titolo);
- details.full.metadata.location: (coordinate del luogo)
- latitude: 41.807670593261719 (latitudine);
- longitude: 12.485980987548828 (longitudine);
- details.full.metadata.realMojis: (array di emoji creati con i selfie)
- [?].emoji: null (emoji);
- [?].media: (informazioni sul media)
- url: null (URL del RealMoji);
- details.momentAt: 757638000 (data della memoria nel formato MAC Absolute Time 03 gennaio 2025 23:00:00);
- details.postType: late (late=successivo alla "notifica ⚠️È l'ora di BeReal ⚠️"; bonus=BeReal extra, non principale; onTime=postato al momento della notifica).
Commenti sui BeReal delle persone
I commenti in questione sono quelli della serie e possono essere estrapolati dal profilo delle persone, ovvero dal file "/Library/Caches/PersonRepository/<GUIDs>".
4B76A6B9D11C812F0081DA50AA9FC319
I commenti sul BeReal, l'array object.beRealOfTheDay.series.posts[i].comment (es. i=0):
- [0].creationDate: 760026328.48600006 (data del commento nel formato MAC Absolute Time 31 gennaio 2025 14:25:28);
- [0].uid: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'autore);
- [0].userName: django.f (nome utente dell'autore);
- [0].text: Il pollice è del Talano 🤣 (testo);
- [0].id: n1RlO5u7KyMaSKhtpWf-C (identificatore univoco del commento).
Altre informazioni utili per dettagliare i commenti sono contenute nell'object object.beRealOfTheDay.series.posts[0]:
- id: O8YAuxdnIVJRLTgE2Y470 (identificatore univoco del BeReal);
- momentID: ljwu8AQ0tyBKnQdaKZ4sw (identificatore univoco della memoria );
- user (informazioni sulla persona):
- id: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificativo univoco della persona);
- username: lmsconos (nome utente della persona);
- realMojis: (array di emoji creati con i selfie, tutte le reazioni personalizzate).
Come nel caso dei BeReal delle persone possono essere estrapolati i commenti dal file file JSON "private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>/disk-bereal-Production_postFeedItems/788BE83F71ACE707BC67184155B6A923".
RealMojis
Il RealMoji, come accennato in precedenza è un emoji personalizzato scattato con la fotocamera frontale, un selfie che figura l'emoji. Sono utilizzati per reagire al BeReal e in numero limitato a sei.
La struttura dei RealMojis:
- realmojis: (array di emoji creati con i selfie)
- [0].date: 760026295.79500008 (data della reazione nel formato MAC Absolute Time 31 gennaio 2025 14:24:55);
- [0].emoji: 👍 (emoji);
- [0].uri: https://cdn-us1.bereal.network/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/realmoji/JVgRDw52ClLUWdDe.webp (URI del RealMoji);
- [0].uid: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'utente);
- [0].userName: django.f (nome utente);
- [0].id: AabwT3kVJva-4kfsqVxxx (identificatore univoco del RealMoji).
Anche per i RealMoji vale lo stesso discorso dei BeReal delle persone e possono essere estrapolati dal file file JSON "private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>/disk-bereal-Production_postFeedItems/788BE83F71ACE707BC67184155B6A923".
Hackemist SDWebImage Cache
SDWebImage è un framework efficace e user-friendly che permette di scaricare, mostrare un'immagine segnaposto mentre il download è in corso e memorizzare nella cache le immagini in modo che non debbano essere scaricate nuovamente ogni volta che l'utente ne visualizza il contenuto. Una cache ottimizzata per l'immagini nelle applicazioni iOS.
La cartella principale è memorizzata nell'Internal App Path "/Library/Caches/com.hackemist.SDImageCache/" e la sottocartella predefinita è "default". L'identificazione del file nella cache è basata sull'algoritmo di hashing MD5 applicato alla stringa che identifica l'URL dell'immagine. Il nome del file finale è il digest con l'estensione del file originale, quello della URL.
Nello specifico da test effettuati, ad esempio, la celebrità Abby Anderson (RealPeople), calcolando l'MD5 della URL dell'immagine del profilo https://cdn-us1.bereal.network/Photos/ZJZUAZgjp5--tEttgw9B2/profile/89BdOLjv7G29GuokYT7h8.webp si ottiene il digest a0ff7a3a151c06c57271d9e90eed8af8 che non corrisponde a nessuno file nella cache.
Calcolando invece l'MD5 solo del path dell'URL senza lo slash iniziale "Photos/ZJZUAZgjp5--tEttgw9B2/profile/89BdOLjv7G29GuokYT7h8.webp", il digest b54f7eab87f5dd8a9e3a02a38ff7bfea concatenato con l'estensione del file originale .webp, fornisce il nome del file cercato b54f7eab87f5dd8a9e3a02a38ff7bfea.webp.
Nota: il calcolo dell'MD5 è sempre fatto sul path dell'URL e non è detto che inizi con /Photos/. Per esempio, nel caso della miniatura (thumbnail) "https://cdn-us1.bereal.network/cdn-cgi/image/height=130/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/AhhZqRzE0gbdDNIG.webp", il calcolo va fatto come già detto sul path senza lo slash "cdn-cgi/image/height=130/Photos/LRHP7nD4UhfzEJacyRtuZE37txxx/post/AhhZqRzE0gbdDNIG.webp" e il nome del file nella cache è 5b3f25bada839a8168382ae770d5e723.webp che è posizionato nella sottocartella "memories_thumbnails_cache".
Screenshot
Se un utente fa uno screenshot di un mio BeReal ad esempio, viene creato un nuovo "record", con il suo identificativo insieme al nome utente e all'URL della foto del profilo e aggiunto alla lista degli screenshot. Questi possono essere estrapolati dalle memorie, ovvero dal file JSON "/Library/Caches/disk-bereal-MemoriesRepository-subject-key/2C43A74B75CE53EFAA247E2AEB95B9C0".
Per il momento non sono riuscito a ottenere uno screenshot da poter analizzare, quella che segue è una ipotetica struttura dei screenshot: DA DEFINIRE
- screenshots: (array di screenshot)
- [0].snappedAt: ?.? (data della cattura nel formato MAC Absolute Time gg mese 2025 00:00:00);
- [0].user: (dati dell'utente che ha fatto la cattura)
- [0].id: ??? (identificatore univoco dello screenshot).
Messaggi
La lista delle conversazioni e i messaggi sono memorizzati nel database SQLite bereal-chat.sqlite dell'Internal App Path "/" del contenitore di gruppo condiviso "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>".
SELECT
M.Z_PK AS "M_PK",
C.Z_PK AS "C_PK",
ME.Z_PK AS "ME_PK",
datetime(M.ZCREATEDAT + 978307200, 'unixepoch') AS "sent",
IIF(C.ZNAME IS NULL OR length(C.ZNAME) = 0, C.ZOWNER, C.ZOWNER || " (" || C.ZNAME || ")") AS "chat_name",
IIF(M.ZSENDER = C.ZOWNER, "Outgoing", "Incoming") AS "direction",
M.ZSTATUS,
M.ZSENDER AS "sender",
IIF(M.ZSENDER = C.ZOWNER, "Local User", C.ZOWNER) AS "recipient",
M.ZBODY,
CASE M.ZBODYTYPE
WHEN 1 THEN "Text"
WHEN 3 THEN "RealMoji"
WHEN 9 THEN "Photo"
WHEN 10 THEN "Deleted"
ELSE "N/D " || M.ZBODYTYPE
END AS "body_type",
ME.ZSOURCE,
ME.ZURL,
M.ZSEQUENCENUMBER,
M.ZCONVERSATIONID --C.ZID
FROM ZMESSAGEMO AS "M"
LEFT JOIN ZCONVERSATIONMO AS "C" ON (M.ZCONVERSATION = C.Z_PK)
LEFT JOIN ZMEDIAMO AS "ME" ON (M.Z_PK = ME.ZMESSAGE)
I campi delle tabelle sono quelli strettamente necessari per l'analisi dei messaggi delle chat. Gli altri saranno trattati a tempo debito nelle prossime analisi.
I messaggi, la tabella ZMESSAGEMO (Z_PK=2):
- Z_PK: 2 (chiave primaria);
- ZCREATEDAT: 757414632.48087 (data di invio nel formato MAC Absolute Time 01 gennaio 2025 08:57:12);
- ZSENDER: LRHP7nD4UhfzEJacyRtuZE37txxx (identificativo univoco del contatto che ha inviato il messaggio);
- ZBODY: 🍾🥂 Happy New Year (il testo del messaggio);
- ZBODYTYPE: 1 (tipo di contenuto, ad es. 1=testo, 3=RealMoji, 9=foto, 10=eliminato, etc.);
- ZCONVERSATION: 1 (chiave esterna della conversazione, Z_PK della tabella ZCONVERSATIONMO);
- ZCONVERSATIONID: iBsq4wcTARL8j7SibeINu (identificatore univoco della conversazione).
Le conversazioni, la tabella ZCONVERSATIONMO (Z_PK=1):
- Z_PK: 1 (chiave primaria);
- ZOWNER: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco del proprietario della chat);
- ZNAME: NULL (nome della chat);
- ZID: iBsq4wcTARL8j7SibeINu (identificatore univoco della conversazione).
I contenuti multimediali, la tabella ZMEDIAMO. Il messaggio sopra dettagliato M.Z_PK=2 è di tipo testo, quindi non ha record associati, ME.Z_PK=NULL; Di seguito sono rappresentati i dati relativi al record M.Z_PK=11 che contiene "una" foto inviata.
Due media sono presenti, uno per per il selfie, la camera frontale e l'altro per la camera posteriore.
- Z_PK: 1 (chiave primaria);
- ZINDEX: 1 (selfie, la camera frontale);
- ZSOURCE: remote (indica la sorgente del media, ad es. remote=online);
- ZURL: https://cdn-c.bereal.network/LRHP7nD4UhfzEJacyRtuZE37txxx/pRyh4XRnMFuFPU6SWI4eay.webp (URL del media);
- ZMESSAGE: 11 (chiave esterna del messaggio, Z_PK della tabella ZMESSAGEMO);
- ZID: 1LBaHNWLkRHezqNKv18jk (identificatore univoco del media).
- Z_PK: 2 (chiave primaria);
- ZINDEX: 0 (la camera posteriore);
- ZSOURCE: remote (indica la sorgente del media, ad es. remote=online);
- ZURL: https://cdn-c.bereal.network/LRHP7nD4UhfzEJacyRtuZE37txxx/p5WrtJhBxMWYCPH2h4aBPB.webp (URL del media);
- ZMESSAGE: 11 (chiave esterna del messaggio, Z_PK della tabella ZMESSAGEMO);
- ZID: mFNALvYbFaf7YDvP-dMpb (identificatore univoco del media).
Il messaggio bordato in arancione "Testo da cancellare", piccola gaffe, da eliminare, come lascia intuire è stato eliminato e nello screenshot successivo, quello a destra, non compare più. L'eliminazione del messaggio è solo logica in quanto il record viene marcato come ZBODYTYPE=10 e nascosto in visualizzazione, ma i dati persistono.
Lista delle chat
La lista delle chat è memorizzata sempre nel database SQLite bereal-chat.sqlite dell'Internal App Path "/" del contenitore di gruppo condiviso "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>".
SELECTC.Z_PK AS "C_PK",S.Z_PK AS "S_PK",M.Z_PK AS "M_PK",datetime(C.ZCREATEDAT + 978307200, 'unixepoch') AS "created",IIF(C.ZNAME IS NULL OR length(C.ZNAME) = 0, C.ZOWNER, C.ZOWNER || " (" || C.ZNAME || ")") AS "chat_name",CASE C.ZTYPE WHEN 1 THEN "private" ELSE "group" END AS "chat_type",C.ZADMINS,C.ZPARTICIPANTS,M.ZBODY,C.ZCURRENTSEQNUM AS "total_messages",datetime(C.ZLASTUPDATETIME, 'unixepoch') AS "last_updated",S.ZUNREADMESSAGECOUNT,C.ZID AS "id"FROM ZCONVERSATIONMO AS "C"LEFT JOIN ZCONVERSATIONSTATUSMO AS "S" ON (C.ZSTATUS = S.Z_PK)LEFT JOIN ZMESSAGEMO AS "M" ON (C.ZLASTMESSAGE = M.Z_PK)
Le conversazioni, la tabella ZCONVERSATIONMO (Z_PK=1):
- Z_PK: 1 (chiave primaria);
- ZCREATEDAT: 757363938.948189 (data di invio nel formato MAC Absolute Time dicembre 2024 18:52:18);
- ZTYPE: 1 (tipo di chat, 1=privata, 2=gruppo);
- ZOWNER: mDO7GN3gKaY7d8xTxujhQoY0cxxx (identificatore univoco del proprietario della chat);
- ZNAME: NULL (nome della chat);
- ZADMINS: <Plist> (BLOB con Plist serializzata degli amministratori, identificatori);
- ZPARTICIPANTS: <Plist> (BLOB con Plist serializzata dei partecipanti, identificatori);
- ZLASTMESSAGE: 13 (chiave esterna dell'ultimo messaggio, Z_PK della tabella ZMESSAGEMO);
- ZCURRENTSEQNUM: 13 (numero totale di messaggi nella chat);
- ZLASTUPDATETIME: 1740234017 (data dell’ultimo aggiornamento nel formato Unix Epoch 22 febbraio 2025 14:20:17);
- ZSTATUS: 1 (chiave esterna dello stato, Z_PK della tabella ZCONVERSATIONSTATUSMO);
- ZID: iBsq4wcTARL8j7SibeINu (identificatore univoco della conversazione).
I messaggi, la tabella ZMESSAGEMO (Z_PK=13):
- Z_PK: 13 (chiave primaria);
- ZBODY: Prova reazione (il testo del messaggio).
Il Plist (NKSA) ZADMINS:
Il Plist (NKSA) ZPARTICIPANTS:
I dettagli dello stato, la tabella ZCONVERSATIONSTATUSMO (Z_PK=1):
- Z_PK: 1 (chiave primaria);
- ZUNREADMESSAGECOUNT: 0 (numero dei messaggi non letti).
Preferenze
Il file group.BeReal.plist dell'Internal App Path "/Library/Preferences/" del contenitore di gruppo condiviso "/private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>" contiene diverse informazioni utili quali: l'id dell'utente BeReal (account), i nomi degli amici (connessioni) associati ai relativi identificatori, username dell'account, percorso locale del file con la foto del profilo, etc.
group.BeReal.plist
- bereal-user-id: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'account);
- myAccount: (informazioni sull'account)
- LRHP7nD4UhfzEJacyRtuZE37txxx: (la chiave del dizionario è l'id dell'account)
- profilePictureURL: file:///private/var/mobile/Containers/Shared/AppGroup/<APP_GUID>/notification/CBEd9NNTW-igELqojHZm6.jpg (percorso del file locale con la foto del profilo);
- username: django.f (username/nickname);
- currentFriends: (dizionario con associati gli id e i nomi degli amici)
- AEmTAl5QEN_LqzV4YLAQh: INTERPOL;
- mDO7GN3gKaY7d8xTxujhQoY0cxxx: Luigi;
- ...
- profilePictureURLs: (dizionario con associati gli id e gli URL della foto del profilo)
- AEmTAl5QEN_LqzV4YLAQh: https://cdn-us1.bereal.network/Photos/AEmTAl5QEN_LqzV4YLAQh/profile/6g1LRjyKPOUamh_wK2gW3.webp (URL dell'immagine del profilo);
- ...
- myUserID: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'account);
- userId: LRHP7nD4UhfzEJacyRtuZE37txxx (identificatore univoco dell'account).
Mentre dal file AlexisBarreyat.BeReal.plist nell'Internal App Path "/Library/Preferences/":
AlexisBarreyat.BeReal.plist
- SAFEDK_LAST_APP_VERSION: 4.9.0 (versione dell'app);
- pushTokensCached: (push token)
- clientVersion: 4.9.0 (versione dell'app);
- device: iPhone10,1 16.7.10 (id modello e versione iOS);
- deviceId: 6F3A454F-8C8D-408F-85E9-B5427D715xxx (UID del dispositivo);
- timezone: Europe/Rome (fuso orario);
- language: it (codice lingua).
Da fare
Questo è un buon punto di partenza per l'analisi dell'app. Una prima cosa da fare è quella di integrare l'analisi degli screenshot e collegare gli allegati della cache Hackemist; il resto, eventi, Cache.db, etc. a tempo debito 😁.
iLEAPP 💖
Come di consueto, al fine di aggiungere un nuova app del poster della SANS “iOS Third-Party Apps Forensics Reference Guide Poster” al progetto iLEAPP (iOS Logs, Events, And Plists Parser) di Alexis Brignoni ho creato il plugin BeReal.py che alla data odierna è in “pull request” e comunque disponibile sul mio GitHub.
Di seguito alcuni screenshot del report di BeReal:
0 comments:
Posta un commento