Port Knocking & Encrypted Login
Presentazione
clicca qui se la presentazione non è visibile
Chuck Norris approva quest'applicazione :)
Codice lato server
/** * @PkServer * * * @author - Michele Nacucchi e Francesco Sportelli */ import java.io.IOException; import java.net.*; import java.util.Hashtable; public class Server { static Hashtable<String, String > userTable=new Hashtable<String, String>(); public static void main (String args[]) throws IOException { caricaUserTable(); PackageSelector filtro = new PackageSelector(); filtro.start(); ServerSocket serversocket = new ServerSocket(2009); Socket s = null; while (true) { s = serversocket.accept(); try { if (filtro.getIPTable().get(s.getInetAddress().toString().substring(1))!=3) { s.close(); System.out.println("Connessione in ingresso nn autorizzata"); } else{ System.out.println("Connessione in ingresso autorizzata"); new ConnectionManager(s,filtro.getIPTable(),userTable).start(); } } catch (NullPointerException e) { s.close(); System.out.println("Connessione in ingresso non riuscita"); } } } private static void caricaUserTable() { userTable.put("ciccio", "pass1"); userTable.put("miki", "pass2"); userTable.put("ndm", "pass3"); } } //Classe PackageSelector import java.io.IOException; import java.util.Hashtable; import java.util.Scanner; import jpcap.*; import jpcap.packet.Packet; public class PackageSelector extends Thread{ private static Hashtable<String, Integer> IPTable; private JpcapCaptor captor = null; public Hashtable<String, Integer> getIPTable() { return IPTable; } public PackageSelector() throws IOException { IPTable=new Hashtable<String, Integer>(); NetworkInterface[] devices = JpcapCaptor.getDeviceList(); //per ogni interfaccia for (int i = 0; i < devices.length; i++) { //stampa la descrizione System.out.println(i+": "+devices[i].name + "(" + devices[i].description+")"); //descrizione datalink System.out.println(" datalink: "+devices[i].datalink_name + "(" + devices[i].datalink_description+")"); //stampa mac address System.out.print(" MAC address:"); for (byte b : devices[i].mac_address) System.out.print(Integer.toHexString(b&0xff) + ":"); System.out.println(); //stampa IP,subnet mask,address for (NetworkInterfaceAddress a : devices[i].addresses) System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast); } Scanner in = new Scanner(System.in); System.out.println("Seleziona interfaccia di rete"); int index= in.nextInt(); captor=JpcapCaptor.openDevice(devices[index], 65535, false, 20); System.out.println("Hai scelto di usare l'interfaccia:"); System.out.println(devices[index].name); captor.setFilter("tcp dst port 3100 or 3500 or 3900", true); } public void run() { captor.loopPacket(-1, new PacketPrinter(this)); } } //Classe PacketPrinter import java.util.Hashtable; import jpcap.PacketReceiver; import jpcap.packet.Packet; public class PacketPrinter implements PacketReceiver { Hashtable<String,Integer> IPTable=null; public PacketPrinter(PackageSelector obj){ this.IPTable=obj.getIPTable(); } public void receivePacket(Packet pk) { int port = getPort(pk.toString()); String IP = getIP(pk.toString()); System.out.println(IP+"ha bussato sulla porta:"+port); try { switch (port) { case 3100: IPTable.put(IP,1); break; case 3500: if(IPTable.get(IP)==1) IPTable.put(IP,2);//prime due porte "bussate" in sequenza break; case 3900: if(IPTable.get(IP)==2) IPTable.put(IP,3);//sequenza corretta! break; default: IPTable.remove(IP); break; } System.out.println("val: "+IPTable.get(IP)); } catch (NullPointerException e) { } } static String getIP(String packet){ String IP = packet; IP = IP.substring(IP.indexOf('/')+1); IP = IP.substring(0,IP.indexOf('-')); return IP; } static int getPort(String packet){ String port = packet; port = port.substring(port.indexOf('>')+1); port = port.substring(port.indexOf('>')+2); port = port.substring(0,port.indexOf(' ')); return Integer.parseInt(port); } } //Classe ConnectionManager import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Date; import java.util.Hashtable; public class ConnectionManager extends Thread{ private Socket s = null; private BufferedReader fromSocket = null; private PrintWriter toSocket = null; private Hashtable<String, Integer> IPTable = null; private Hashtable<String, String> userTable = null; private String userConnected; private String userPassword; public ConnectionManager(Socket s,Hashtable<String, Integer> IPTable, Hashtable<String, String> userTable) throws IOException{ this.s=s; this.IPTable=IPTable; this.userTable=userTable; } public void run(){ //Avviare la procedura di login per i client correttamente autenticati try { fromSocket = new BufferedReader(new InputStreamReader(s.getInputStream())); toSocket = new PrintWriter(s.getOutputStream(),true); send("Connessione avvenuta con successo"); int i=0; String user; String pass; do{ String key=keyTemp(); send(key); send("Inserire USER:"); user = Codifica.decripta(waitAndReceive(), key); System.out.println(user); key=keyTemp(); send(key); send("Inserire PASSWORD:"); pass = Codifica.decripta(waitAndReceive(), key); System.out.println(pass); if (pass.equals(userTable.get(user))){ send("Utente AUTENTICATO"); i=4; } else{ i++; send("Autenticazione FALLITA! Tentativi rimasti:"+(3-i)); } }while(i<3); if(i<4){ send("Tentativi esauriti rieffettuare la procedura di autenticazione"); IPTable.remove(s.getInetAddress().toString().substring(1)); s.close(); return; } //Il client ha effettuato con successo sia la procedura di PortKnocking, sia il LogIn. send("Benvenuto "+user+". Sei stato autenticato con successo!"); userConnected=user; userPassword=pass; IPTable.remove(s.getInetAddress().toString().substring(1)); //Comunicazione tra Client e Server post autenticazione... } catch (IOException e) { try { send("Tentativi esauriti rieffettuare la procedura di autenticazione"); IPTable.remove(s.getInetAddress().toString().substring(1)); s.close(); return; } catch (IOException e1) { e1.printStackTrace(); } } } private String keyTemp() { Date d=new Date(); return new Integer((int)(d.getTime()*Math.random()%100*1024)).toString(); } private String waitAndReceive() throws IOException { String str; while ((str=fromSocket.readLine())==null); return str; } private void send(String str) { toSocket.println(str); toSocket.flush(); } } //Classe Codifica public class Codifica { private Codifica() { } public static String cripta(String str,String chiave) { StringBuffer s = new StringBuffer(str); int len = s.length(); int i,uni; int key = Integer.parseInt(chiave)/1024; for (i=0;i<len;i++) { char c = s.charAt(i); //Il char i-esimo uni = (int)c; //Estrae il codice unicode c = (char)((len + uni)+ key+i); // Lo codifica s.setCharAt(i, c); //L'i-esimo carattere convertito } return s.toString(); } public static String decripta(String str,String chiave) { StringBuffer s = new StringBuffer(str); int len = s.length(); int i; int uni; int key = Integer.parseInt(chiave)/1024; for (i=0;i<len;i++) { char c = s.charAt(i); //Il char i-esimo uni = (int)c; //Estrae il carattere unicode c = (char)((uni-len)- key-i); // Lo codifica s.setCharAt(i, c); //L'i-esimo carattere convertito } return s.toString(); } }
Codice lato client
/** * @PkClient * * * @author - Michele Nacucchi e Francesco Sportelli */ import java.io.BufferedInputStream; import java.util.Scanner; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class Client { private static BufferedReader fromSocket=null; private static PrintWriter toSocket=null; public static void main(String[] args){ Socket s=null; Scanner in = new Scanner(System.in); System.out.println("Inserisci l'indirizzo IP del Server:"); String dest = in.nextLine(); int port; do{ System.out.println("Inserisci un numero di porta"); port = in.nextInt(); if(port==2009)break;//porta aperta per accedere al servizio try { s=new Socket(dest,port); } catch (UnknownHostException e) {} catch (IOException e) {} }while(port!=2009); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace();} try { s=new Socket(dest,2009); String str; fromSocket=new BufferedReader(new InputStreamReader(s.getInputStream())); toSocket=new PrintWriter(s.getOutputStream(),true); BufferedReader userIn=new BufferedReader(new InputStreamReader(System.in)); System.out.println(waitAndReceive()); do{ //Trasmissione criptata dell'user String key=waitAndReceive(); //System.out.println(key); System.out.println(waitAndReceive()); str=userIn.readLine(); send(Codifica.cripta(str, key)); //Trasmissione criptata della password key=waitAndReceive(); //System.out.println(key); System.out.println(waitAndReceive()); str=userIn.readLine(); send(Codifica.cripta(str, key)); //Esito da Server str=waitAndReceive(); System.out.println(str); }while(!str.equals("Utente AUTENTICATO")||!str.equals("Tentativi esauriti rieffettuare la procedura di autenticazione")); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static String waitAndReceive() throws IOException { String str; while ((str=fromSocket.readLine())==null); return str; } private static void send(String str) { toSocket.println(str); toSocket.flush(); } } //Classe Codifica public class Codifica { private Codifica() { } public static String cripta(String str,String chiave) { StringBuffer s = new StringBuffer(str); int len = s.length(); int i,uni; int key = Integer.parseInt(chiave)/1024; for (i=0;i<len;i++) { char c = s.charAt(i); //Il char i-esimo uni = (int)c; //Estrae il codice unicode c = (char)((len + uni)+ key+i); // Lo codifica s.setCharAt(i, c); //L'i-esimo carattere convertito } return s.toString(); } public static String decripta(String str,String chiave) { StringBuffer s = new StringBuffer(str); int len = s.length(); int i; int uni; int key = Integer.parseInt(chiave)/1024; for (i=0;i<len;i++) { char c = s.charAt(i); //Il char i-esimo uni = (int)c; //Estrae il carattere unicode c = (char)((uni-len)- key-i); // Lo codifica s.setCharAt(i, c); //L'i-esimo carattere convertito } return s.toString(); } }