Newsgroup: it.comp.sicurezza.varie
Titolo: [Algoritmo di autenticazione] Qualcuno mi dia un'idea ! :P

Un saluto a tutti. Mi sono addentrato, giusto per
divertimento, nella scrittura di un piccolo sistema di port knocking in
Python.
PREMESSA
Per chi non sapesse di cose si tratta: un sistema di port knocking consiste
in due applicativi, uno knocking daemon e uno knocking client.
Lo knocking daemon non è altro che uno sniffer in ascolto su una interfaccia
di rete, il quale, nel caso in cui il client mandi dei pacchetti TCP su una
determinata sequenza di porte (es: 1000, 1500, 2000), esegue un comando di
sistema (generalmente si apre una porta sul firewall che precedentemente era
chiusa).
L'applicativo allo stato attuale è praticamente completo ma vista la natura
estremamente semplicistica del sistema precedentemente descritto mi
piacerebbe aggiungere un po' di sicurezza in più implementando un primitivo
sistema di autenticazione. Allo stato attuale, infatti, una qualunque
persona posta tra il client e il server potrebbe sniffare la combinazione di
pacchetti mandati dal client e usarli a sua volta per eseguire il comando
sul server.
Attualmente i pacchetti mandati dal client non contengono alcun tipo di
payload (eseguono banalmente una semplice connect() senza trasportare alcun
dato). La mia idea era quella di inserire all'interno del payload una
password da far verificare al server.
Il problema di un applicativo di questo tipo è che non stabilendo una
connessione TCP vera e propria (di fatto i pacchetti viaggiano solo dal
client verso il server)non dà modo di implementare algoritmi di cifratura a
chiave pubblica, ad esempio.
Inizialmente pensai di mandare i pacchetti dal client inserendo un hash
della password ma un sistema di questo tipo è ugualmente vulnerabile ad
attacchi MITM (l'attacker potrebbe sniffare il valore di hash e impiegarlo
direttamente senza nemmeno conoscere la password in chiaro).
Data la mia inesperienza in campo crittografico chiedo quindi aiuto a voi.
Un sistema di questo tipo potrebbe riuscire ad integrare un sistema di
autenticazione? Se si come? Mi viene in mente SSHd che se opportunamente
configurato rilascia un certificato (sotto forma di file) il quale dovrà
essere portato sempre in giro da parte di chi intende autenticarsi
remotamente, ma sinceramente non so come funzioni... Una cosa di questo
tipo, ad es, andrebbe più che bene.
billiejoex

 autenticazione?
Beh, ti direi di usare un sistema challenge/response con digest, ma il
client andrebbe modificato.

 con digest, ma il client andrebbe modificato.
oppure si potrebbe utilizzare un sistema a chiave pubblica
in pratica il server dovrebbe generare una coppia di chiavi,
poi la chiave pubblica generata dovrebbe essere installata
sul client che la utilizzerą per criptare i pacchetti da inviare
al server
Ciao

 ha scritto nel messaggio 
news:dra1v3$o5k$1...@megan.servidellagleba.it...

Si ma in quel caso il tutto resterebbe cmq vulnerabile a MITM. Chi sniffa 
quel pacchetto puņ impiegare direttamente il valore riportato nel payload di 
client per autenticarsi a server. 


Una possibilita' e' di usare la combinazione una sola volta (ogni
combinazione ha un numero di serie -- una volta usata viene gettata e
dovra' essere usata quella successiva).
Per contro dal lato client va protetto bene il file che contiene la sequenza
(i numeri di serie e le relative combinazioni associate).
-- 
AB

 riportato nel payload di client per autenticarsi a server.
No... se nel payload criptato inserisci ad esempio l'indirizzo IP
del client ed un timestamp, a quel punto un eventuale attacco
"copycat" da parte di un mitm dovrebbe essere portato in pochi
secondi e spoofando l'IP del client originale altrimenti il server
scarterebbe il pacchetto come non valido (es. se inviato qualche
minuto dopo sarebbe non valido perchè esterno alla finestra TTL)
Ciao

 e dovra' essere usata quella successiva).
Si, il "one time pad" è un'altro approccio possibile anche se richiede
che periodicamente il "pad" venga rinnovato o cmq "alimentato" in
qualche modo ;-)

Avevo pensato: sequenza di knocking in chiaro terminata la quale server 
potrebbe aprire un socket a cui si collegherà client. Successivamente:
- server manda una stringa casuale variabile
- client la riceve e hasha i valori di [stringa casuale + password] e 
rimanda indietro un pacchetto.
- server genera l'hash di [stringa casuale precedentemente creata + 
password] e se i due valori collimano l'autenticazione va in porto.
Penso che sia l'unica soluzione anche se ovviamente non proprio ortodossa 
dato che un sistema di port knocking non prevede che vi siano connessioni 
attive tra knockd e knock_client... 

 client. Successivamente:
<snip>
hem .. qui però ti contraddici, all'inizio parlavi del fatto che la
comunicazione fosse solo monodirezionale (dal client al
server - ok, escludendo handshacking ecc..) vabbè, no
problem, basta capire di cosa stiamo parlando, detto questo..
non capisco perchè tu voglia far passare in chiaro la stringa
di knocking, basterebbe (come ho già scritto) usare ad es.
un meccanismo basato su PKI per poter crittare le stringhe
oltre a questo, potresti avere qualcosa del tipo
struct knock_request {
    unsigned long    kn_timestamp;
    unsigned long    kn_clientaddr;
    unsigned char    kn_srccount;
    unsigned int        kn_srclist[16];
    unsigned int        kn_dstcount;
    unsigned int        kn_dstlist[16];
};
ora (a parte la struttura tiratà giù al volo), il timestamp verrà
compilato con il dato relativo a data/ora attuale, il clientaddr
con l'indirizzo del client (IPv?) srccount ed srclist contengono
le info relative alla sequenza di knocking, ossia, quali e quante
porte verranno utilizzate per "bussare", dstcount e dstlist invece
specificano a quali e quante porte viene richiesto l'accesso dopo
il knocking; a questo punto, criptando il pacchetto di cui sopra con
la "public key" del server si potrebbe spedire il tutto verso una
porta predeterminata, il server riceverà e decritterà tale pacchetto
e risponderà con un'altro pacchetto (criptato) contenente tra l'altro
il tempo di attesa in  millisecondi per il client prima dell'inizio della
sequenza di knocking oltre alla stringa da usare per il knocking
Il client a sua volta dopo aver atteso per il tempo richiesto creerà
un pacchetto criptato contenente la stringa inviata dal server ed
avvierà la sequenza di knocking, il server controllerà che l'intera
sequenza sia valida (porte, payload) ed a questo punto aprirà le
porte richieste per il SOLO IP del client, quest'ultimo prima di
connettersi attenderà (di nuovo) per il tempo specificato inizialmente
e quindi accederà alle porte richieste... ovviamente quanto sopra è
uno dei possibili approcci, ma potrebbe essere valido.. tutto dipende
da cosa devi proteggere ovviamente :)
Ciao

ObiWan wrote:

Oh certo! Sa va sans dire... :-)
La distribuzione delle chiavi e' sempre un nodo centrale di qualunque
sistema (informatico e non) crittografico e deve sempre avvenire "fuori
banda". Ovvero bisogna usare un canale di distribuzione che non e' lo
stesso che vuoi proteggere -- per esempio i ministeri degli esteri usano
ancora i corrieri (umani) con borsa diplomatica per distribuire chiavi e
one-time-pad alle loro ambasciate e noi *non* dovremmo usare internet per
distribuire chiavi e one-time-pad a client e server...
-- 
AB

 distribuire chiavi e one-time-pad alle loro ambasciate
ehm ... l'uso di OTP ad oggi è diventato secondario :)
ad ogni modo, concordo sul fatto che OTP andrebbe
distribuito "off band" ... a meno che ... non si accetti un
certo grado di rischio e non si usino (alcuni) dati di
ciascuna sessione OTP (criptata) per alimentare i
"pads" in modo da mantenerli in funzione ;-)
Ciao

 problem, basta capire di cosa stiamo parlando, detto questo..
Gia, ma non vedo alternative. Ora che ci penso però anche questo metodo 
rimane sempre vulnerabile a MITM. Non se ne esce! :-(
PS - No, nessun handshaking. Il pknock_client si limita a mandare dei 
singoli pacchetti SYN sulla varie porte per completare la sequenza.

Uhm... posto che io abbia capito bene (non ne sono sicuro) mi pare sempre 
vulnerabile a MITM. Abbi pazienza: spiegami, se puoi, come avviene una 
transazione "sicura" (aka non vulnerabile a MITM) a chiave pubblica 
ipotizzando di avere una connessione TCP stabilita (quindi non come in 
questo caso). Purtroppo le mie nozioni di crittografia sono assai limitate 
:-\ 

 mi pare sempre vulnerabile a MITM.
vedi la mia risposta relativa al timestamp :) la cosa non evita
totalmente il MITM ma lo rende più difficile, inoltre dovresti fare
attenzione al fatto che il knocking secondo me non dovrebbe
essere utilizzato come meccanismo di sicurezza ma soltanto
per mettere "in sicurezza" determinate porte/servizi permettendo
poi l'accesso solo a chi "conosce la bussata", a questo punto
però il servizio posto in ascolto sulla porta dovrebbe ugualmente
gestire un meccanismo di autenticazione

 
si, nel senso che lo si usa raramente. No, nel senso che lo si usa per cose
*molto* sensibili. Per cose *molto* *sensibilissime* :-) (ach, se lo viene
a sapere il mio prof di lettere mi straccia il diploma...) si va ancora
oltre, nel senso che si usa la "low technology" (gli umani).
-- 
AB

> si, nel senso che lo si usa raramente.
No, nel senso che uno dei problemi primari di
OTP è la sicurezza relativa al trasferimento del
"pad" che potrebbe essere "intercettato e
copiato" il che vanificherebbe il tutto in modo
a dir poco disastroso
Per sopperire a quanto sopra ad oggi vengono
utilizzati altri metodi che .. non richiedono l'uso di
un "corriere umano" o cmq di un pad "fisico"
Ciao