Bentornati a un altro video bonus.
Nel frattempo, abbiamo più video bonus che video normali.
Ma sì, è per questo che siamo qui.
Vorrei mostrarvi tutto quello che so sull'hacking delle app e quindi potremmo avere molti
contenuti bonus.
Va bene.
In questo video vogliamo sfruttare il content provider all'interno della nostra applicazione dannosa.
Eseguiremo quindi tutti e tre i vettori di attacco, che abbiamo visto nell'ultimo video: il
primo, l'iniezione SQL, il successivo, il bypass del percorso.
Quindi il bypass dei permessi personalizzati.
Infine, chiediamo semplicemente questa autorizzazione e vediamo se l'utente ce la concede.
Se questo è il caso, allora possiamo anche interrogare le password interne della nostra password.
Sicuro.
Incredibile.
Giusto?
Andiamo quindi a scrivere la nostra applicazione.
Abbiamo bisogno del nostro studio Android.
Quindi, all'interno degli strumenti di Android Studio, Ben, eccolo qui.
Quindi iniziamo con questo.
Stiamo ancora parlando di applicazioni sicure e sì, inizieremo con l'iniezione SQL.
Quindi scriveremo il nostro risolutore di contenuti, che chiederà al fornitore di contenuti di fornire tali contenuti
sotto forma di metodi.
Inserire, aggiornare, interrogare, cancellare.
E poi useremo il metodo query per iniettare la nostra sintassi SQL.
Sì.
Sembra assolutamente complesso, ma se avete guardato l'ultimo video in cui abbiamo fatto tutto questo nel
gestore attività alla fine, non è stato così complesso.
E all'interno della nostra applicazione, voglio dire, l'approccio è ancora esattamente lo stesso.
Va bene.
Creiamo ora un nuovo progetto.
Quindi, per il nuovo progetto, scegliamo un'attività vuota perché vogliamo che sia il più pulito possibile.
E poi, vediamo, diamo un nome a questo backup non sicuro.
Credo che questo sia un buon nome per l'applicazione.
Una lingua.
Chava e io torniamo a nougat, ma l'SDK di target bit è appellabile 30 e lì dobbiamo regolare molte
cose.
Quindi l'intero concetto di privacy è cambiato in Android 11 e successivi.
Per questo vorrei mostrarvi come scrivere un'applicazione che possa sfruttare questi
problemi anche sugli smartphone moderni.
Perché in seguito, se parliamo di browser e tutto il resto, questo non funzionerà più sugli smartphone
moderni.
In due o tre anni, tutto questo sarà completamente scomparso.
Dobbiamo adottare un nuovo approccio qui e sì, è per questo che siamo qui, giusto?
Quindi, andiamo avanti.
Ok, quindi torniamo a nougat, ma stiamo puntando alla versione 11 OC e ora dobbiamo aspettare che il processo
Gradle sia terminato.
Quindi potrebbe volerci un po' di tempo.
E ci vediamo tra poco.
Va bene.
Un attimo dopo, siamo tornati.
Questo qui è il nostro spazio di lavoro.
Abbiamo la nostra attività principale.
Abbiamo il nostro metodo di creazione.
Cosa manca?
L'interazione con il fornitore di contenuti, ovviamente.
Come possiamo interagire con questo?
Se si ripensa alla parte teorica, il fornitore di contenuti o l'accesso al fornitore di contenuti
funziona nel modo seguente.
Dobbiamo definire un risolutore di contenuti, e il risolutore di contenuti chiede al fornitore di contenuti di fornire il contenuto
dopo quello che riceviamo indietro e il cursore, che è semplicemente.
Justin Sì, diciamo che è un punto di inserimento nel database.
Con questo cursore possiamo accedere a questi dati.
Va bene.
Ok.
Come possiamo farlo?
A dire il vero, non è così difficile.
Dobbiamo solo considerare alcune novità di Android 11 per quanto riguarda la privacy di un'applicazione.
E questo è anche il motivo per cui vorrei mostrarvi tutte queste cose perché in seguito, se parlate
di strumenti come il browser e cose del genere, questi strumenti non funzioneranno più in futuro.
Per quanto riguarda gli smartphone più recenti, a partire dal livello API 30, quindi Android 11 e successivi, sono state apportate
molte modifiche alle impostazioni della privacy, che negheranno l'accesso all'applicazione del conducente,
ad esempio.
Pertanto, dobbiamo sapere come farlo da soli ed è per questo che siamo qui.
E sì, suggerirei di farlo semplicemente per questo fornitore di contenuti.
Suggerisco quindi di ricominciare semplicemente da qui.
Iniziamo quindi ad accedere alla tabella delle password.
La tabella delle password è inclusa nel content provider, nel content provider DB, e questa è stata
esportata.
Quindi possiamo semplicemente interagire con questo.
Se riusciamo a interagire con questo e se tutto funziona, possiamo eseguire il nostro testo, la nostra SQL injection,
il nostro bypass dei permessi utente.
E infine, ma non per questo meno importante, che cos'era?
Sì, non è un vero e proprio attacco.
Si tratta semplicemente di chiedere l'autorizzazione al cliente.
Questo qui.
Quei due.
Se si dispone di questi due permessi, è possibile accedere anche alla tabella delle chiavi.
Va bene.
Ok.
Ma prima, vediamo, come possiamo interagire con la tabella delle password in questo qui?
E prima di tutto, voglio dire, dobbiamo capire questo, URI.
Quindi questa parte può essere semplicemente copiata da qui, e non possiamo includerla qui.
Dobbiamo quindi definire un nuovo URI.
Questo è il nostro URI e questo è il nostro alias per accedere alla tabella delle password in questa applicazione.
Va bene.
Quindi l'indirizzamento è facile.
Ma ora la domanda è: come possiamo creare il nostro content resolver?
E questa parte è più facile di quanto si pensi, perché è già il metodo che fa tutto.
Quindi possiamo semplicemente chiamare get content resolver qui.
Lo abbiamo già e possiamo accedere a questi metodi.
Possiamo già vedere la query.
Abbiamo anche inserisci sì, inserisci aggiornamento e cose del genere.
Quindi stiamo definendo il nostro risolutore di contenuti e la nostra applicazione.
E poi chiediamo a questo fornitore di contenuti di fornire l'accesso ai metodi di inserimento, interrogazione, aggiornamento e
anche cancellazione.
Quindi questi sono stati definiti qui, ma possiamo accedervi con il risolutore di contenuti se l'applicazione
ci dà accesso, come nel caso della tabella delle password, perché è stata esportata.
Va bene.
Vediamo quindi di tornare a questo.
Accediamo semplicemente al metodo di interrogazione.
Quindi domanda.
E qui abbiamo due tipi di metodi.
Quindi ne abbiamo uno con l'asse di selezione delle stringhe di proiezione.
Questo è esattamente quello che vogliamo avere.
E di questo non sono sicuro.
Molto args annullare.
Non importa.
Questo è il caso di prenderlo.
Ok.
E ora dobbiamo fornire tutti questi parametri.
Voglio dire, Uri, questo dovrebbe essere chiaro, giusto?
Uri è il nostro URI.
Ok.
Poi dobbiamo definire gli argomenti della proiezione, che potrebbero essere importanti in seguito per la nostra
iniezione SQL, ma per ora li manteniamo semplicemente nulli.
Ciò significa che se non forniamo alcun accesso alla proiezione, verrà selezionato tutto ciò che si trova nella tabella
del passaporto.
Va bene.
E facciamo lo stesso per la selezione, anche per la selezione AX.
E infine, ma non meno importante, anche per l'ordinamento.
Sì.
Ok.
Questo metodo sta tornando indietro nel cursore.
Dobbiamo quindi ottenere questo cursore.
Dobbiamo definirlo qui.
Query, cursore, importiamolo.
E poi abbiamo già finito.
Ecco come si può accedere ai dati della tabella delle password C.
Incredibile, vero?
Assolutamente sì.
Per stamparlo, possiamo usarlo nel modo seguente system, system. fuori. println e poi possiamo usare il nostro
cursore di query.
Ma qui abbiamo un piccolo problema, perché il nostro cursore di query è un oggetto, quindi è un oggetto
cursore e quindi non possiamo semplicemente stampare un oggetto.
Se si stampa un oggetto, si ottiene semplicemente qualcosa come ET e poi questo, per esempio,
forse.
Quindi questo è solo un indirizzo.
Questo è l'indirizzo dell'oggetto, ma non il suo contenuto.
Se si vuole ottenere il contenuto, dobbiamo usare qualcosa.
Oppure credo che si tratti di utility del database.
Sì, è un database utils.
E qui abbiamo, vediamo, il cursore sulla stringa.
Qualcosa del genere.
Il dump del cursore era un'idiozia.
Cursore stupido.
Sì.
Cursore stupido a stringa.
Quindi, questo prenderà l'intero oggetto cursore, tutte le informazioni incluse
al suo interno e ci fornirà una stringa, che potremo salvare in una variabile o stampare direttamente
qui.
Così vicino.
Va bene.
Ecco quindi tutto ciò che serve per accedere alla tabella dei passaporti e per stamparla in un formato
leggibile.
Va bene.
Ok.
Vediamo se funziona.
Utilizziamo l'applicazione Run.
Quindi, a sinistra, abbiamo la versione 30 del livello dello smartphone e dell'app e abbiamo molte impostazioni sulla privacy.
E questo potrebbe essere il motivo.
Vediamo un esempio.
Sì.
Se siete alla ricerca di un sistema fuori.
Qui non c'è nulla all'interno.
Vediamo.
No.
Non c'è un sistema di uscita.
Quindi non si accede all'oggetto cursore.
E infatti, se si stampa questo cursore, vediamo.
Cursore.
Facciamo così.
Ok.
Credo che il loggerhead sembri bloccarsi un po' e quindi usiamo AdBlock Lochhead nel caso
in cui si stia usando la shell ADB dallo studio Android, annulliamo la connessione dallo studio
Android e sì, possiamo semplicemente usarlo da soli in questo momento.
Quindi AdBlock a.
Vediamo.
Um.
Ok.
Immagino che dovremo cercarlo.
Quindi puliamo il gatto della serratura e poi cerchiamo il punto di sistema.
Rendiamola un po' più grande e rilanciamo semplicemente questa app.
Sì, possiamo vedere che il cursore è nullo, quindi l'intero oggetto è nullo, il che significa che sembra che non
ci sia accesso.
E sì, in effetti non abbiamo accesso.
Ma ora la domanda è: perché non abbiamo accesso?
Perché l'applicazione è in esecuzione sullo smartphone e questo fornitore di contenuti è stato esportato.
Questo è tutto quello che c'è da sapere, giusto?
Sfortunatamente, non perché un Android 11 è già stato menzionato.
C'è stato un grande cambiamento per quanto riguarda la privacy.
Quindi queste applicazioni sono state automaticamente bloccate un po'.
Se volete interagire subito con questa applicazione, dobbiamo dire che siamo visibili per questa applicazione.
Non è un grosso problema perché noi siamo l'attaccante o l'applicazione che attacca e vogliamo
accedere all'applicazione.
Pertanto, se dite a questo ladro che siamo visibili per questa applicazione in questo momento, non perdiamo
nessuna informazione sensibile.
Ma dobbiamo dirlo nella nostra applicazione.
Ecco perché vorrei mostrarvi tutte le cose qui, perché se in seguito diamo un'occhiata all'applicazione
del browser, questi approcci non funzioneranno più perché il browser non è consapevole della visibilità dell'app
nella versione 11 e successive di Android.
E non lo sarà perché il browser non sarà più supportato.
Pertanto, dobbiamo essere in grado di scrivere le nostre applicazioni per eseguire tutti questi compiti.
Va bene.
Quindi ora la domanda è: come possiamo rendere visibile la nostra applicazione per questa applicazione?
A dire il vero, anche questo è un aspetto che devo verificare, perché è necessario definirlo nel manifest di Android.
Ma non sono sicuro di questi testi.
Credo che sia molto importante e il nome del pacchetto, ma prima di girare in tondo, cerchiamo semplicemente
questo.
Quindi vediamo.
Ok, le parole chiave sono applicazione Android e visibilità e possiamo vedere la visibilità del pacchetto in Android
11 e vediamo.
Ok.
Cambiare noi.
Vediamo.
Pacchetto visibile in Android.
Ok.
Qui abbiamo le informazioni generiche.
Alcune immagini sono ancora visibili automaticamente.
Potrebbe trattarsi di applicazioni di sistema.
Non ne sono sicuro.
E sì, credo che questo sia il percorso che stiamo cercando.
Dobbiamo quindi definire queste query.
Vediamo.
Sì.
All'interno del manifest di Android, dobbiamo definire questa query.
Quindi eccolo qui.
Sì, è Claire Rhys.
Quindi questo è.
Sono cose che non ricordo, ma so che esistono e che possiamo semplicemente consultare.
Non è un grosso problema.
E poi credo che l'altro attributo sia stato un pacchetto che l'ha dimenticato.
Prendiamo semplicemente questo insieme.
Ok.
Quindi dobbiamo definire il pacchetto, ma vogliamo che sia visibile per cui è un'applicazione sicura e possiamo
ricavare le informazioni dal nome del pacchetto dal manifest Android dell'applicazione CIF.
Va bene.
E tutto questo avviene adesso.
Sì.
Quindi questo dovrebbe tornare all'attività principale.
Vediamo se riusciamo a riconnetterci con ADB.
Ok.
Quindi vediamo.
Apriamo un nuovo terminale e riavviamo il server ADB.
Quindi è stato riavviato.
E ora vediamo.
Ora possiamo selezionarlo qui e dovremmo riaverlo.
Sì.
Sembra buono.
Ok.
Ora installiamo questa applicazione.
Qui stiamo stampando l'oggetto query, quindi dovremmo ottenere un indirizzo.
Ma sì, vedremo che funziona se questo non restituisce più null.
Installiamo quindi questa applicazione.
E.
E cerchiamo il sistema di uscita.
Sì, un cursore perfetto.
E poi abbiamo questo oggetto cursore qui.
Ecco l'indirizzo di questo oggetto cursore.
Bello.
Abbiamo quindi interrogato la tabella delle password di questa applicazione.
Va bene, stampiamo il testo, perché altrimenti sarebbe super sfigato.
Ti ricordi ancora come possiamo farlo?
Come si estrae una stringa da questo oggetto cursore?
Certo che sì.
DB o database utils.
Sì.
Credo che questa volta avesse ragione.
OC database utils e poi cursore due stringhe.
Lo vedo già qui.
Bello.
Va bene.
E vediamo se funziona.
Corri!
Quindi l'applicazione è stata reinstallata e qui.
Perfetto.
Bello.
Ora abbiamo tutti questi dati.
Possiamo vedere il nostro cursore e T che la password del servizio ID non è stampabile.
Ci occuperemo in seguito dei dati del blocco e dell'e-mail.
Va bene.
Quindi questi sono i dati in uscita dal fornitore di contenuti di questa applicazione dalla tabella delle password.
Bello.
Ma facciamo una piccola modifica perché non abbiamo accesso al LOGCAT in seguito.
Pertanto, stampiamoli direttamente nella nostra applicazione.
Pertanto, dobbiamo solo apportare una piccola modifica al layout.
Non è necessario in questo momento, ma sembra molto elegante e quindi lo facciamo.
Va bene, vediamo.
All'interno della cartella delle risorse, abbiamo questa attività di layout, il layout principale, e qui abbiamo la visualizzazione
del testo già presente.
Utilizziamo questa vista di testo per stampare i dati.
Voglio dire, questo sembra assolutamente sì, assolutamente zero solido.
E quindi, questa sarebbe una bella prova di concetto o una dimostrazione per il cliente.
Come possiamo farlo?
Andiamo nel menu del codice e dobbiamo fornire un ID a questa voce, in modo da poterla
indirizzare in seguito nella visualizzazione del codice e del testo dell'ID.
Sì.
Ok.
Ora abbiamo un ID per questa vista di testo e possiamo indirizzare questa vista di testo in base a questo ID.
Va bene.
Ok.
Cambiamo anche lo sfondo di questa applicazione, sfondo Android, e rendiamo questo
spazio vuoto e questo testo qui.
Non è l'inferno del mondo.
È un hacking in corso.
Questo è il testo che viene normalmente visualizzato, ma verrà rapidamente sovrascritto
con i dati che stiamo recuperando da quelle tabelle, ma comunque manteniamo questo come una sorta
di segnaposto e poi collare Android e prendiamo questo colore.
Sembra una figata.
E poi anche le dimensioni del testo di Android.
28 DPI.
Dovrebbe essere una buona cosa.
E credo che ci siamo riusciti.
Sì, devo andare.
Magari aggiungiamo un po' di imbottitura.
Ultimo ma non meno importante, l'imbottitura a sinistra.
Diciamo 100 OC.
Ora abbiamo finito.
Sì.
Ok.
Ora prendiamo questa parte.
Quindi abbiamo una vista di testo.
Abbiamo questa vista di testo e dobbiamo assegnarla al nostro metodo create.
Quindi, all'interno del nostro metodo create, recuperiamo l'ID da questa vista di testo e lo assegniamo
a questo oggetto.
Quindi la vista testo, la digitalizziamo e poi usiamo la vista file per ID e ora usiamo il nostro
ID.
In passato abbiamo fornito esattamente questo tipo di servizio.
E poi, invece del sistema in out, usiamo la vista testo, impostando il testo.
Sì.
Ok.
Un'ultima piccola modifica all'interno del manifesto.
Eliminiamo la barra delle azioni in alto, perché è molto fastidiosa, e possiamo farlo all'interno
del tema, eliminando semplicemente questa parte e utilizzando un design a tema, senza barra delle azioni.
Ok, installiamo questa applicazione e vediamo come si presenta, credo.
Piuttosto sorprendente.
Quindi.
Questi dati dovrebbero ora essere riempiti nella vista di testo che abbiamo inserito nel nostro layout, che è già stata
inserita qui.
Quindi il nostro "hello world".
Ok.
Sì, dobbiamo fare un piccolo aggiustamento.
Le dimensioni del testo sono un po' troppo grandi.
Quindi scendiamo forse a 20.
E anche l'imbottitura è un po' troppo alta e vicina.
Direi che è vicino.
Si tratta davvero di qualcosa come 14?
Il suono così, così poco.
Ma credo che 14 sia un buon risultato.
Quindi vediamo.
Sì.
Ok.
Credo che per ora ci limiteremo a questo.
Tuttavia, è sorprendente vedere i dati di un'altra applicazione sul nostro schermo.
Come attaccante, ovviamente, non dobbiamo visualizzarli su uno schermo.
Naturalmente, potremmo anche inviarli a un server HTTP tramite https.
Pertanto, tutti gli aggressori dovrebbero prestare attenzione a una connessione crittografata.
E poi, sì, possiamo semplicemente recuperarlo.
Pertanto, non è necessario alcun accesso fisico allo smartphone.
Ma credo che per ora sia sufficiente come prova di concetto.
Bene, ora torniamo al nostro vettore di attacco.
Sì.
Commentiamo semplicemente questo punto.
Questo è molto il tavolo di verifica dei passaporti.
Sta funzionando.
Ok.
Quindi prendiamo questa parte e regoliamo le nostre cose.
Quindi.
Ora vogliamo fare quanto segue.
Cominciamo con il bypass semplice, quello dei permessi dell'utente.
Quindi la nostra applicazione riceve normalmente questi due permessi, ma abbiamo visto
che se terminiamo o scusate se aggiungiamo questo alla fine del nostro URI, possiamo semplicemente bypassare questo permesso.
Quindi facciamo così.
Allora recuperiamo questo.
Yuri.
Ok.
E descriviamo anche questo qui.
Va bene.
Insomma, non dobbiamo cambiare nulla oltre all'euro.
Questo è tutto.
E questo funzionerebbe già adesso, appena uscito dalla scatola.
Incredibile, vero?
Vediamo.
Eseguiamo semplicemente questo.
E ora, al posto delle voci del passaporto, dovrebbero esserci la password in chiaro e il pin.
Vediamo.
Incredibile.
Funziona.
Abbiamo la password e il pin.
Voglio dire, non è pazzesco?
Stiamo aprendo la nostra applicazione e viene visualizzato il passaporto di un'altra applicazione di passaporto.
Applicazione sicura.
Assolutamente giusto.
Ok.
Ma ad essere onesti, voglio dire, quest'anno è stato un po' troppo facile, no?
Quindi basta aggiungere questo o anche questo.
Sì, ma funziona.
Funziona.
Ok.
Questo è il nostro primo tentativo.
Sì, certo.
In seguito, condividerò l'intero codice dell'applicazione.
Passiamo quindi al secondo tentativo.
E questo è ora quello che vogliamo scegliere un'iniezione SQL o quello che manca e il permesso dell'utente.
Dobbiamo quindi ricorrere all'iniezione SQL.
Ok.
Quindi, SQL injection.
Dobbiamo interrogare la tabella dei passaporti per inserire la nostra istruzione SQL.
L'istruzione SQL verrà inserita nella proiezione, quindi l'istruzione SQL verrà inserita tramite il parametro di proiezione
e dobbiamo capire qual è il parametro di previsione.
Ma credo che non sia un grosso problema.
Quindi la proiezione o la sintassi SQL è qualcosa come select all from past what's there and then a bunch of other stuff.
E vogliamo cambiare questo punto in Seleziona tutto da chiave.
Ricordate che ora ci stiamo rivolgendo al nome della tabella, non allo schema URI o non ce l'ho più.
Questo, questo è lo schema URI e questo viene referenziato da una chiave, ma il nome della tabella è semplicemente
chiave.
Pertanto, nell'istruzione SQL dobbiamo rivolgerci direttamente alla tabella delle chiavi, non a questo schema.
Ok.
Quindi vogliamo avere qualcosa come select all from key e poi commentare il resto, cioè tutto quello che
c'è qui, cioè qualcosa come i passaporti, che vengono semplicemente ignorati.
Ok, questo significa che la nostra protezione deve essere questo percorso qui.
Quindi questo percorso, e credo sia tutto.
Quindi questo è il nostro tentativo e facciamolo, ok?
Prima di eseguire la nostra SQL injection, vediamo se possiamo accedere ai dati tramite i parametri del programma.
Aggiungiamo quindi semplicemente un parametro di protezione, qualcosa di simile, perché così avremo select
all from passports e dovremmo ottenere i dati.
E se questo funziona, allora possiamo giocare con questo.
Va bene.
Ok.
Vogliamo quindi accedere alla tabella dei passaporti e ora vediamo che tipo è questo parametro del programma?
Lo è.
È un array di stringhe.
Ok.
Dobbiamo quindi definire un nuovo array di stringhe e l'alternativo in questa previsione, nuovo array di stringhe.
E possiamo definire un nuovo array di stringhe in questo modo.
Va bene.
E questo è tutto.
Sì, dovrebbe funzionare.
Quindi, se lo avviamo adesso, dovremmo ottenere gli stessi dati che abbiamo visto prima con la tabella
delle password, perché ora non stiamo facendo nulla di diverso, ma stiamo usando il nostro parametro di proiezione qui.
Vediamo.
Sì.
Funziona perfettamente.
Ora dobbiamo solo inserire la nostra istruzione SQL, che è tutta da chiave, e questo è tutto.
E questa è la nostra iniezione SQL.
Quindi vediamo.
Ops, facciamo partire questo.
Sarebbe anche interessante se si inserisce in virgolette singole se si ottiene il messaggio di
errore, ma credo di no.
Sì.
Bello.
Quindi possiamo vedere che ora funziona.
Abbiamo un'iniezione SQL attraverso la tabella delle password nella tabella delle chiavi basata sul fornitore di contenuti.
Cioè.
Beh, questo è già abbastanza sorprendente.
E infine, ma non meno importante, ora stiamo accedendo alla tabella delle chiavi.
Il terzo tentativo consiste nell'accedere alla tabella delle chiavi e utilizzare questi due permessi.
In questo modo chiediamo all'utente di concederci questi permessi.
E se l'utente ci concede questi permessi, possiamo semplicemente accedere a questi dati qui.
Quindi, sì, facciamo le cose per bene.
Ok.
Quindi, copiamo questi due o forse definiamo prima il nostro piano.
Questa è la seconda di dieci opere.
I miei commenti sono sempre meno omogenei.
Andiamo ancora più lontano.
Ops.
No.
Questo è il terzo tentativo di concedere le autorizzazioni personalizzate della maggior parte delle applicazioni C.
Gli aspetti da considerare sono i seguenti.
Dobbiamo definirli nel manifesto.
Oh, fammi pensare.
Sì, credo che dobbiamo anche sì, fare la richiesta, quindi dobbiamo chiederli in fase di esecuzione.
Questo è stato incluso nella versione 6 di Android ed è comune.
Quindi, la prima volta che si utilizzano questi permessi, si aprirà una finestra di dialogo.
Se non lo chiediamo, i permessi non saranno concessi e non potremo accedere al fornitore di contenuti.
Quindi dobbiamo assolutamente chiederli.
Ma credo che sia tutto.
Sì.
Questo è tutto.
Ok, quindi facciamo questo all'interno del manifest.
Sì.
Dobbiamo cambiare questa situazione.
Questa è la definizione di permesso personalizzato.
E se si vuole usare questo, bisogna usare l'autorizzazione dell'utente.
Quindi ecco.
Oh, sì.
Ok.
Per quanto riguarda questo aspetto, credo che ci siano problemi perché si tratta di un'etichetta specifica di Android
e la descrizione deve essere definita in queste stringhe.
Dobbiamo quindi creare delle stringhe per questi elementi.
Potremmo usarli o anche semplicemente cancellarli.
Allora credo che ci sia qualcosa come "non riconosciuto".
Ok.
Vi mostrerò entrambi molto velocemente.
Quindi, nel caso in cui si voglia definire un'etichetta, occorre andare nelle stringhe, che sono all'interno dei valori.
Corde.
E poi dobbiamo definirne uno nuovo.
Stringa e poi nome.
E poi vediamo, chiamiamo questo permesso descrizione e poi possiamo inserire il testo qui.
Sì.
E poi possiamo affrontare la questione in questo modo.
Quindi la nostra etichetta è ora.
Hmm.
Vediamo.
L'ho già dimenticato.
Descrizione del permesso.
Ecco fatto.
Ok.
Quindi, sì, l'abbiamo eliminato.
Abbiamo creato questa etichetta, quindi usiamola.
Ma non sono sicuro che funzioni comunque in questo modo.
Ok.
Ora abbiamo l'autorizzazione inclusa nella nostra applicazione, ma se la installiamo, non verrà
concessa automaticamente.
Pertanto, dobbiamo chiedere all'utente di abilitarlo e possiamo farlo nel modo seguente.
Quindi, per prima cosa, prendiamo il codice.
Ok.
Quindi sì, possiamo
farlo in questo modo e vogliamo variare la chiave in questo modo.
Quindi questo viene protetto.
Vediamo.
Vediamo se non funziona, perché dovrebbe essere così.
Sì.
L'applicazione sembra bloccarsi.
Vediamo.
Perché abbiamo questo?
Immagino.
Qui.
Sì, qui possiamo vedere che la nostra applicazione ha l'UID 10.124 e richiede di avere questi permessi.
Li abbiamo impostati nel manifest di Android.
Sì.
Ma se si dà un'occhiata all'applicazione stessa.
Ops.
Impostazioni.
E possiamo vedere che anche questo è stato negato.
Questi sono i due permessi che consentono di modificare i dati principali.
Quindi sono stati negati.
Pertanto, dobbiamo chiedere all'utente di concederci tali permessi e possiamo farlo nel modo seguente.
Quindi dobbiamo fare questo.
È il più vicino.
Prima di avviare l'interazione con il fornitore di contenuti, è necessario eseguire questa operazione, che può essere eseguita
nel modo seguente.
Vediamo se riesco a ricordare l'attività di combattimento di questa app e poi ok, forse è attiva.
Sì, è un combattimento di attività in questo modo e poi una richiesta di autorizzazione.
E qui non abbiamo tutte e tre le opzioni.
Ok.
La prima è la nostra attività.
È facile, perché questo è l'oggetto, questa è l'attività principale.
E poi abbiamo questa serie di permessi.
Ok, questo è questo qui.
Prendiamo semplicemente le chiavi di lettura.
Va bene.
E poi, ultimo ma non meno importante, c'è questo codice di richiesta.
Non me lo ricordo più, quindi vediamo.
Ok, eccoci alla lezione di combattimento dell'attività.
Vediamo.
Permesso, richiesta, permesso.
Questo metodo.
Ok.
Abbiamo un permesso di attività e un codice di richiesta a partire da zero.
Ok, vediamo.
Codice richiesta.
Eccolo qui.
Codice di richiesta specifico per l'applicazione da abbinare allo strumento di segnalazione del resort.
Ah, sì.
Ora mi ricordo.
Ok.
Quindi, se abbiamo chiesto più volte, possiamo tenere traccia del fatto che l'autorizzazione sia già
stata concessa o meno.
Quindi possiamo prendere il valore che vogliamo.
Deve essere più grande.
Pari a zero.
Ok, perfetto.
Quindi torniamo qui.
Prendiamo semplicemente.
Sono più di 9000.
Quindi 9001.
Sì, il permesso è un array di stringhe.
Ok, quindi definiamo un nuovo.
Oh, credo che l'abbiamo già qui.
Quindi il permesso.
E ora definiamo.
Nuovo array di stringhe e poi possiamo usarlo qui.
Ok.
Quindi dovrebbe funzionare?
Lo spero.
Vediamo.
Corri!
Ok.
Se l'applicazione viene avviata, dovrebbe apparire subito questo pop-up perché stiamo accedendo direttamente.
Sì, ok.
Sì.
Consente di vedere se il backup deve eseguire un'azione sconosciuta.
Voglio dire, ovviamente, cosa potrebbe andare storto?
Giusto.
Quindi diciamo che è consentito.
E.
Ecco fatto.
Bello.
Quindi abbiamo visto che questa voce è stata sviluppata anche se il percorso che è stato aggirato nel nostro primo tentativo è stato impostato
correttamente con l'espressione regolare, possiamo ancora usarlo in questo modo se chiediamo
gentilmente all'utente di darci quei permessi.
Ok.
Credo sia meglio che facciate una copia di questo perché questo funziona e non sappiamo se il nostro secondo tentativo
funzionerà in questo momento e poi abbiamo ottenuto il fallback.
Ok.
Questa è la nostra sintassi per interrogare la tabella delle password.
Ok.
Ora abbiamo un problema con il valore del blocco.
Eseguiamo quindi questo forse ancora una volta.
Sì.
Quindi, possiamo vedere perfettamente che tutto ciò che è presente nello stream può essere facilmente stampato con il metodo
utils dump cursor del nostro database.
Ma questa password è costituita da dati binari e i dati binari non possono essere stampati in questo modo e quindi dobbiamo semplicemente
ordinare che non siano stampabili.
Ad esempio, se si apre un nuovo terminale e vogliamo stamparlo e trasportarlo, restituire una nuova riga in questo
modo.
Se stampiamo questo documento, possiamo vedere che ci sono dei dati, ma non
sappiamo quanti e quali dati.
Sì, potrebbero esserci delle nuove linee e potrebbero essere due nuove linee.
A proposito, se si usa echo senza parametri, viene automaticamente aggiunta una nuova riga.
Quindi, se stiamo usando Echo con Dash PN, possiamo vedere che c'è solo una nuova riga.
Ora sappiamo che si tratta di un nuovo personaggio della linea.
Ma quanti ritorni a capo abbiamo?
Cioè, uno, potrebbe essere anche tre, potrebbe essere quattro.
Non lo sappiamo.
Pertanto, non è possibile stampare dati binari in questo modo.
Ciò che dobbiamo fare è codificarli.
Ma di questo si parlerà più avanti.
Ma prima vediamo come ottenere questi dati binari.
Quindi vogliamo recuperare le nostre righe.
Qui possiamo vedere questo ID riga zero, il che significa che più voci abbiamo, più righe abbiamo.
Quindi questo è zero.
Poi potremmo anche avere uno, due, tre.
Dipende dalla quantità di voci e vogliamo esaminare ogni voce e poi vogliamo prendere
tutti quei blob di password per memorizzarli separatamente, perché poi possiamo usare
una certa codifica per stamparli.
Va bene.
Sì.
Sembra assolutamente complesso.
E ad essere onesti, questo è un sollevamento Android davvero pesante in questo momento.
Non c'è bisogno di sapere nulla di tutto questo.
Quindi, quello che faremo adesso è scrivere il codice che avete come riferimento, nel caso in cui abbiate
bisogno di una prova di concetto da parte del cliente, potete semplicemente riguardare questo video.
Altrimenti potete semplicemente appoggiarvi e rilassarvi.
Se questa parte è interessante per voi, perfetto.
Nel caso in cui tutto ciò vi abbia sopraffatto, non preoccupatevi.
Dopo questo video, potete dimenticare completamente tutto ciò che avete visto qui, almeno per quanto
riguarda questa parte, perché non è assolutamente necessario per andare avanti in questo corso.
È già stato menzionato come video bonus.
Questo video bonus serve a fornire informazioni aggiuntive che non sono richieste in questo corso, ma semplicemente
a mostrarvi come gestire queste cose, che possono essere utili.
Va bene.
Ok.
Quindi vediamo.
Ok.
Abbiamo una riga ID, che è zero, e qui abbiamo le colonne ID underscore, servizio, nome utente, password.
Va bene.
Quindi, ciò che dobbiamo fare ora è, e questo è il nostro oggetto cursore, assicurarci
di avere un oggetto cursore e possiamo farlo controllando se l'oggetto cursore non è uguale a no.
Abbiamo visto che, se non ci è consentito interrogare la tabella del passaporto, ci viene restituito
un null e l'applicazione fallirebbe se provassimo ad andare avanti a questo punto.
Pertanto, controlliamo se l'oggetto è presente.
Quindi, se la nostra applicazione è visibile per questa applicazione if e poi stiamo anche
controllando se ci sono voci nel nostro database e possiamo farlo con query cursor count, get count.
Sì, certo, fatevi contare.
E poi controlliamo se è maggiore di zero.
Ok.
Quindi controllare se ci sono voci nella tabella dei passaporti.
Ok.
Ora dobbiamo assicurarci di raggiungere la colonna dei passaporti e questo può essere fatto nel modo seguente.
Assegniamo una variabile indice, forse index e il nostro indice è ora vediamo il nostro cursore e poi sì, otteniamo l'indice della colonna
o lanciamo.
E ora diciamo, ok, vogliamo avere l'indice della nostra colonna password perché avendo il campo
indice che è, vediamo, dovrebbe essere.
E questo è zero uno, due tre.
Quindi è l'indice tre, ma è la quarta voce perché iniziamo a contare da zero.
Ora abbiamo questo campo indice che può essere usato per recuperare i dati e quindi possiamo indirizzare
questa colonna in base all'indice e ottenere i dati in base all'indice.
Va bene.
Abbiamo quindi questo indice e ora assicuriamoci che l'indice sia maggiore, uguale a zero, perché altrimenti
non avremo la tabella dei passaporti, o meglio, la colonna dei passaporti.
E se questo è il caso, allora sì, vogliamo ottenere tutti i dati de blob.
Quindi interrogare il cursore, ottenere il blob.
Qui possiamo vedere che ora dobbiamo fornire l'indice e creare un nuovo array in cui memorizzare
i dati.
Quindi è un array di byte, un blob di password.
Inizializziamo anche questo con zero.
Ok.
E ora.
Sì, possiamo provare a stamparlo.
Ovviamente non funzionerà.
Sì, credo che ci sia un indirizzo o qualcosa di simile.
Ma possiamo già vedere se stiamo stampando e con quale frequenza.
Forse c'è un errore elettrico.
Quindi vediamo.
Eseguiamo nuovamente questa applicazione.
Non si blocca?
Spero di no.
Och, si sta bloccando.
Vediamo.
Oh.
Ok.
L'indice non rientra nell'intervallo.
Non si tratta di un errore di battitura.
Stiamo controllando e abbiamo questo problema.
Forse una cosa che dobbiamo assicurarci è che siamo all'inizio del nostro cursore.
Il problema potrebbe essere questo.
Quindi il nostro cursore ha molte voci e dipende dalla posizione del cursore.
Se si utilizza la query, non sono sicuro che arrivi alla fine.
È quindi necessario riportare il cursore all'inizio.
Sì.
I cursori sono assolutamente complicati e mi ci è voluto un mese per capirli.
È necessario, ad esempio, per accedere ai contatti e agli SMS.
Quindi, queste cose losche, forse è bene saperle.
Ma sì, è anche un po'...
È una sofferenza.
Come possiamo farlo?
Usiamo if e poi usiamo very cursor move to first, che restituisce un valore booleano ma
imposta anche il cursore all'inizio.
Trovo che sia assolutamente confuso perché stiamo facendo due passi e non è così chiaro qui.
Bene.
Giusto.
Ok, allora prendiamo questo.
Spero che si tratti di un errore.
Vediamo.
Osservare tutto qui.
Guarda lo smartphone.
Sì.
Perfetto.
Quindi, sì, assolutamente ridicolo.
Se si sta confrontando questo cursore, questo cursore potrebbe essere impostato alla fine.
Pertanto, stiamo cercando di accedere a un indice che non è più disponibile.
Ma ora possiamo vedere che il sistema è uscito e qui non abbiamo un array di byte.
Bello, vero?
Sì, è solo un indirizzo.
Quindi non possiamo fare nulla con questo.
Dobbiamo recuperare i valori di questo caso.
Ok.
Come possiamo farlo?
Abbiamo un metodo efficace per farlo.
E il metodo è base64.
Quindi Base64 non è una codifica e può essere usato per stampare caratteri ASCII non stampabili.
Come già accennato, Base64 sarà molto usato durante questo corso perché
è una codifica comune e sì, è bello da identificare e si possono fare un sacco di cose con Base64. Se non avete familiarità
con Base64, guardate il video bonus che lo riguarda, perché altrimenti questo video
non sarebbe troppo lungo.
Ok, vediamo se vogliamo stampare l'array di byte.
Possiamo usare la base 64.
Abbiamo già il punto e il CO a stringa.
Sì, il metodo è esattamente questo.
Quindi questo viene preso in input dall'array.
Perfetto.
Questo è il nostro blob di password.
E poi c'è questa flessione.
Ma questo flex è semplicemente base 64 e alcuni possono essere utilizzati in diversi tipi di codifica.
Ad esempio, i caratteri speciali come l'Underscore non sono normalmente utilizzati nelle RFC.
Si tratta di un certo set di char e noi ci limitiamo ad aiutare con la flessibilità.
Non facciamo alcuno stravagante.
Utilizziamo il set di caratteri comuni e non forniamo alcun carattere aggiuntivo alla nostra codifica.
Quindi, trattatela come una normale codifica base64 e il flag per questa, per questo valore standard è zero.
Quindi utilizziamo la decodifica base64.
No.
Un po' confuso.
Oh, scusate, codificare due stringhe, vogliamo codificarle e poi bloccare la password e azzerare i nostri flag,
che è semplicemente una comune codifica base64.
Bene, ora eseguiamo questo e vediamo.
Dovrebbe già funzionare.
Sono un po' emozionato.
Bello.
Eccolo qui, in questo momento.
Quindi la nostra password, che non è stampabile, viene stampata qui.
Incredibile, vero?
Quindi possiamo usarlo subito per recuperare i valori dei byte.
Quindi, se questa volta state facendo un'eco con i loop di dash, non sono sicuro di questo, ma questo è stato memorizzato nella
cache.
Quindi, se si fa l'eco senza aggiungere una nuova riga perché vogliamo stamparla esattamente com'è,
non vogliamo aggiungere i nostri caratteri alla stringa in questo momento e possiamo
usare la base 64 slash DX.
Spiacenti, ora questo è l'output e possiamo capire perché il nostro smartphone dice "unprintable".
Voglio dire, cos'è questo punto interrogativo qui?
Questo, questo potrebbe essere un nuovo personaggio della linea.
Che cos'è questo?
Non possiamo occuparci di questo, ma fondamentalmente di quattro.
E ora abbiamo i byte grezzi.
Per stampare o restituire i byte grezzi in un valore esadecimale, possiamo usare x x x dx dash p che prenderà quei
byte e ne darà una rappresentazione esadecimale.
Quindi, se si digita x 60 trattino p, abbiamo finalmente i byte grezzi in una bella rappresentazione esadecimale.
Incredibile, vero?
Assolutamente sì.
Quindi aggiungiamo anche questa password al nostro output qui.
Quindi no.
Non solo.
Vediamo.
Ok, commentiamolo qui e poi aggiungiamolo al nostro testo.
Creiamo quindi un nuovo output di stringa.
E questo è proprio adesso.
Manteniamolo qui.
Questa è la prima parte.
Ops.
Questa è la prima parte.
E poi aggiungiamo il nostro output base64.
Siamo in attesa di un nuovo carattere di riga e poi di una password codificata uguale e aggiungiamo questa parte.
E poi l'assemblea che stampa questo.
Abbiamo ancora questo cursore.
Va bene.
Quindi, alla fine, dovrebbe esserci questa password codificata e questa stringa codificata in base64.
Quindi vediamo.
Si potrebbe anche stampare direttamente la rappresentazione esadecimale, ma credo che questo sia sufficiente
per lo sviluppo di applicazioni Android se si dispone di valori ASCII.
Sì, ce l'abbiamo.
Perfetto.
Quindi ora abbiamo anche questa password, che prima non era stampabile.
Quindi, avendo questa stringa codificata in base64, possiamo semplicemente usarla e farla passare attraverso
60 come abbiamo fatto qui.
Va bene.
Per questo motivo il video si conclude qui.
E ancora una volta, l'escalation è stata piuttosto rapida.
Riassumiamo quindi rapidamente la questione.
Ok.
Quindi, dopo, vi fornirò il codice sorgente di questa applicazione che avete tutto.
Abbiamo quindi iniziato con un semplice confronto e con la tabella delle password di diversi fornitori di contenuti.
Va bene.
Poi abbiamo fatto un po' di sviluppo di app Android e qui ci sono stati i nostri vettori di attacco, l'idea iniziale
di questo video: come interagire con il content provider e come sfruttare il content provider.
Il primo tentativo è stato Non ne sono più sicuro.
Immagino che stesse aggirando l'autorizzazione dell'utente.
E poi abbiamo avuto la nostra iniezione SQL per accedere alla tabella protetta attraverso quelle non protette.
Infine, abbiamo aggiunto i permessi di questi utenti alla nostra applicazione e abbiamo chiesto gentilmente
all'utente di fornirci tali permessi.
Nel caso in cui l'utente facesse clic su questo punto, tutte le password verrebbero eliminate.
Quindi questo sarebbe il caso peggiore per l'utente.
L'utente deve solo fare clic una volta.
Così possiamo usarlo come pop-up più e più volte.
Va bene.
Quindi questo è tutto per questa funzione al momento.
Va bene.
Quindi questo video è diventato ancora una volta un po' più lungo del previsto.
Mi dispiace per questo, ma credo che le cose che abbiamo imparato qui siano davvero necessarie
o essenziali per affrontare queste cose.
Inoltre, nuove applicazioni.
Altrimenti, dovrete capire da soli come gestire la visibilità dell'app, stampare i dati del blocco
e poi il fornitore di contenuti e cose del genere.
Pertanto, vorrei includere tutte le cose in questo video per mostrarvi tutto ciò che so, in
modo che non dobbiate più cercarlo.
Va bene.
Ok.
La prossima è la vulnerabilità del path traversal.
E poi abbiamo finito con i fornitori di contenuti, se avete domande, lasciate un commento
sotto il video.
Per il resto, non vedo l'ora di vederti nella prossima edizione.
Ci vediamo lì.