Come potete vedere nei precedenti articoli riguardanti il Brute Force in Java e i vari metodi di attacco per le password, la sicurezza informatica è uno degli aspetti dell’informatica che preferisco, soprattutto per quanto riguarda la sicurezza in Internet. Vi sembrerà strano, ma non potete immaginare quanta gente dia per scontato il fattore sicurezza mentre naviga in rete, crea account e soprattutto quanto sceglie la password.

Proprio sulla scelta della password vorrei soffermarmi un attimo con una piccola considerazione, basata su dati statistici. Infatti, secondo alcuni studi, la password usata più spesso dagli utenti è la stringa “123456″. Questo dato mi è sembrato sconvolgente, ma posso assicurarvi che è molto realistico. Su questo argomento credo di fare a breve un articolo più approfondito, quindi per ora consideriamo semplicemente l’aspetto che riguarda Java, ed in particolare come fare una richiesta http usando il metodo POST, sfruttando i Socket.

I due argomenti sopra citati sono strettamente collegati, in quanto le applicazioni web sono costruite essenzialmente sfruttando il metodo GET per le varie richieste. Il metodo POST viene usato per elementari requisiti di sicurezza per la trasmissione di dati sensibili, quali appunto username e password al momento del login su un servizio web. Il metodo che vi mostro quindi, può essere appositamente adattato per effettuare un login su un’applicazione web usando Java. Un esempio concreto di ciò, potrebbe essere la creazione di un’applicazione Java che effettua una connessione all’applicazione web per effettuare determinate operazioni.

Solitamente una applicazione web che richiede il login, ha una porzione della pagina che effettua una richiesta POST verso una specifica pagina che si occupa di verificare la correttezza dei dati forniti:

1
2
3
4
5
<form action="login.php" method="post" target="_top">
    <input type="text" name="username" size="30" maxlength="20" />
    <input type="password" name="password" size="30" maxlength="20" />
    <input type="submit" name="login" value="Login" />
</form>

Per realizzare il nostro scopo, dobbiamo analizzare la pagina specifica, ed annotare la struttura del messaggio inviato tramite POST, e la pagina che riceve i dati, che è specificata nel parametro action dell’elemento form.

Per quanto riguarda la parte Java, questo è un esempio di come realizzare la richiesta POST usando solo le Socket.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URLEncoder;

public class SocketPost {  
    public static void main (String args[]) {
        String host         = "HOST-WEB-APP";
        int port            = 80;
        String form_action  = "PAGINA-DI-LOGIN";
       
        String username     = "TUO-USERNAME";
        String password     = "TUA-PASSWORD";
       
        boolean result = login(host, port, form_action, username, password);
    }

    private static boolean login (String host, int port, String form_action, String username, String password) throws Exception {
        // Dati da inviare tramite POST
        // Copmosizione tipica:    username=TUOUSER&password=TUAPASSWORD
        String data =   URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8") + "&" +
                        URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8");
       
        // Creo il Socket per la connessione all'host
        InetAddress addr = InetAddress.getByName(host);
        Socket socket = new Socket(addr, port);

        BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
       
        wr.write("POST " + form_action + " HTTP/1.0\r\n");
        wr.write("Host: " + host + "\r\n");
        wr.write("Content-Length: " + data.length() + "\r\n");
        wr.write("\r\n");

        // Invio i dati tramite POST
        wr.write(data);
        wr.flush();    
       
        // Leggo la risposta dall'host
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // Solitamente, in caso di pagine di login,
        // il codice di risposta per un login valido è 302
        if (br.readLine().equals("HTTP/1.1 302 Found")) return true;
        else return false;
       
        wr.close();
        br.close();
    }
}

Prima di poter essere in grado di riempire il codice Java, bisogna analizzare il sito presso il quale si vuole effettuare il login, per estrapolare tutti i dati necessari. Questa operazione non richiede un particolare sforzo, ma un minimo di esperienza è sempre d’obbligo. Se avete bisogno di una mano, potete chiedere tranquillamente. Il metodo su illustrato è stato realizzato solo a scopo illustrativo e deve essere utilizzato solo in possesso delle credenziali di accesso, e non per scopi malevoli.