Analisi statistica per IP dello spam.

Tutto ciò che ha a che fare con le reti

Moderatore: Federico.Lagni

Rispondi
Avatar utente
k4mik4ze
Cisco pathologically enlightened user
Messaggi: 196
Iscritto il: mar 20 mag , 2008 1:24 am

Visto e considerato che su Exchange, l'IMF non fornisce statistiche sulla provenienza [IP] delle email di spam, ho provveduto "a mano" a tirare giù questo scriptino che, data la path della cartella da analizzare dove sono i file .EML, ne scorre il testo e fornisce da quali IP sono partite piu' di N [Passato per argomento] email di spam.

Se qualcuno intende fornire approcci diversi/migliori o segnalare problemi sintattico-logici è ben accetto.


*************************

Imports - sono stati fatti col ctrl+o di eclipse, quindi magari c'è qualcosa di troppo, di preciso non so a dire il vero.

Codice: Seleziona tutto

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;

Main -> compito del main sarà solamente quello di sequenzializzare i filtri che progressivamente si occuperanno di pulire l'input stream e quello
di settare il threeshold level per la stampa a schermo [o eventualmente su file] dell'output. A breve pensavo di impotarlo come argomento da linea di comando di modo da poter scegliere se andare a file o a schermo. Ad ogni modo per il momento ho "appoggiato" tutto su di un batchetto ">".

Codice: Seleziona tutto

public class MyIParser {
     static String _path = "PATH";

     public static void main(String[] args) {
          File path = new File(_path);
          File [] lista = path.listFiles();
          int AlarmLevel = 0;
	
          if(args.length < 1) AlarmLevel = 3;
          else AlarmLevel = Integer.parseInt(args[0]);

          int fileNum = lista.length;     
          System.out.println(fileNum + " email di spam");
	
          LinkedList<String> stageone = ipChecker(lista);
          LinkedList<String> stagetwo = StringCleaner(stageone);
          LinkedList<String> cleanOne = ListCleaner(stagetwo)
          LinkedList<Couple> result = OccurrenceCalculator(stagetwo, cleanOne);
		
          for(Couple l: result)
		{
			if(l.counter > AlarmLevel) System.out.println(l);
		}
		
	}

Prende come input la lista dei file presenti nella cartella "PATH". Per ognuno di essi estrae unicamente la prima riga contenentente le parole
"Received: from" [che, salvo headers aggiunti a mano/script, contiene l'ip dell'ultimo host attraversato] e la da in pasto allo script successivo.

Codice: Seleziona tutto

public static LinkedList<String> ipChecker(File[] lista)
{
     LinkedList<String> stageone = new LinkedList<String>();
     for (int i=0; i<lista.length; i++) {
          if ( !lista[i].isDirectory() ) {
               try {
                    File m = lista[i];
                    String filename = m.getAbsolutePath();
                    BufferedReader in = new BufferedReader(new FileReader(filename));
                    String str;
                    boolean checker = false;
     	        		 
                    while ((str = in.readLine()) != null) {
                         if(checker == false)
                         {
                              if (str.contains("Received: from"))
                              {
                                   stageone.add(str);
                                   checker = true;
                              }
                         }
                         else
                         {
                               break;
                         }
                    }
               in.close();
               } 
          catch (IOException e) {}
          }
     }

     return stageone;
}

Da ogni stringa che gli viene passata attraverso la lista stageone, estrae gli ip che sono contenuti tra parentesi quadre. Se ci fossi riuscito avrei utilizzato una regex. Purtroppo pero' nonostante diversi tentativi ho sempre ottenuto "FALSE" in risposta, e quindi ho approfittato della particolare formattazione dei file EML ai fini di un algoritmo maggiormente primitivo e meno "generico".

Codice: Seleziona tutto

public static LinkedList<String> StringCleaner(LinkedList<String> stageone)
{
     Iterator it = stageone.iterator();
     LinkedList<String> stagetwo = new LinkedList<String>();
     while(it.hasNext())
     {
          String t = (String)it.next();
          int start = t.indexOf("[");
          int stop = t.indexOf("]");
          String subst = t.substring(start+1, stop);
          stagetwo.add(subst);
     }     
     return stagetwo;
}

Prende in input la lista contenente (presumibilmente) tutti gli ip da cui sono partite email di spam. Dopo averla ordinata crea una nuova lista dove vengono copiate le voci univoche.

Codice: Seleziona tutto

public static LinkedList<String> ListCleaner(LinkedList<String> stagetwo)
{
     Collections.sort(stagetwo);
     LinkedList<String> ListaPulita = new LinkedList<String>();
     Iterator it = stagetwo.iterator();
		     
     while(it.hasNext())
     {
          String temp = (String)it.next();
          if(!(ListaPulita.contains(temp)))
          {     
               ListaPulita.add(temp);
          }
     }     
     return ListaPulita;
}
Prende come input la lista "sporca" e quella pulita. Calcola, per ogni elemento presente nella lista "pulita" [cleanOne] le occorrenze nella lista
"sporca" [StageTwo] dopodichè, dopo aver piazzato il risultato in una <Couple> [Semplice classe composta da un attributo string e uno int, che
conterranno rispettivamente l'ip e quante volte è stato individuato] la associa come elemento al resultset, che verrà poi restituito al main per
essere stampato.

Codice: Seleziona tutto

public static LinkedList<Couple> OccurrenceCalculator(LinkedList<String> stagetwo, LinkedList<String> cleanOne)
{
     LinkedList<Couple> resultset = new LinkedList<Couple>();
     Iterator itClean = cleanOne.iterator();
     Iterator itStage = stagetwo.iterator();
     int counter = 0;
     
     while(itClean.hasNext())
     {
          counter = 0;
          String temp = (String)itClean.next();
          while(stagetwo.contains(temp))
          {
               counter++;
               stagetwo.removeLastOccurrence(temp);
          }     
     resultset.add(new Couple(temp, counter));
     }
     return resultset;
}
*************************

PS: avrei tendenzialmente usato altro, qualcosa di più "low level", ma essendo java il linguaggio in cui mi muovo meglio...
Rispondi