knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Definición de la pregunta

¿Qué porcentaje de acierto en phising se puede conseguir al analizar una url?

Introducción

Por todos es sabido la cantidad de phising que se puede llegar a localizar en cualquier web en la que se esta navengando. Es por ello, que nos hemos querido focalizar en este tema, ya que es un ataque continuo para el usuario que esta interactuando continuamente en sitios web.

El objetivo de esta investigación es poder encontrar un porcentaje aproximado del contenido de una URL que contenga phising. Para realizarlo, utilizaremos un dataset de phising y un dataset de webs legítimas para aplicar phising y a través del algoritmo de "Naive Bayes" hacer una comparativa entre ellos para obtener un porcentaje aproximado.

Fuente de datos

Para realizar el análisis hemos utilizado la siguiente información:

Datos elegantes

Kaggle

Para extraer los datos de phishing, nos hemos descargado un fichero .csv donde indicaba una serie de campos para la realización de nuestro análisis. Mediante este fichero hemos seleccionado los campos que utilizaremos para que haga la comparación de si una url es phising o no. Se ha realizado una limpieza del fichero de dataset y los campos en los que nos hemos centrado han sido:

Alexa

Para la extracción de webs legítimas, hemos utilizado Alexa (para extraer el top 500 de páginas web), se ha estructurado la información, se han extraído los parámetros en R i se han guardado en un fichero .csv, para posteriormente, realizar la comparativa con el dataset de phising y poder obtener el resultado training y test set.

A continuación, mostramos como pasamos el link de url a un dataset a través de los campos que hemos seleccionado del dataset de phising y lo guardamos en un fichero, para posteriormente, realizar el siguiente paso de análisis de exploración de datos.

library(stringr)
library(httr)

datos <- readLines("Desktop/new_legitimate.csv");

df <- data.frame(index=integer(), having_IPhaving_IP_Address=integer(), URLURL_Length=integer(), Shortining_Service=integer(), having_At_Symbol=integer(), double_slash_redirecting=integer(), Prefix_Suffix=integer(), having_Sub_Domain=integer(), HTTPS_token=integer())
de <- list()


#df = rbind(df,de, stringsAsFactors=FALSE)

write.csv(df, "Desktop/legitimate_links.csv")

#names(df)<-c("caca", "tua", "gosa", "pusa")


for(i in datos){
  de <- list()
  i2 <- toString(i)
  print(i2)
  mida <- nchar(i2)
  #mida <- 3
  url_lenght <- 1
  if(mida >= 54 && mida <= 75){
    url_lenght <- 0
  }
  else if(mida > 75){
    url_lenght <- -1
  }
  else {
    url_lenght <- 1
  }

  de <- c(de, URLURL_Length=url_lenght)
  #insertar el valor en la columna que toque del csv

  having_at <- str_detect(i, "@")
  having_aR <- 0
  if(having_at == TRUE){
    having_aR <- -1
  }
  else{
    having_aR <- 1
  }

  de <- c(de, having_At_Symbol=having_aR)

  #introducir having_aR en csv de resultados

  clean <- strsplit(i, "://")
  clean2 <- clean[[1]]
  double_slashB <- str_detect(clean2[2], "//")
  #print(clean2[2])
  double_slash <- 0
  if(double_slashB == TRUE){
    double_slash <- -1
  }
  else{
    double_slash <- 1
  }

  de <- c(de, double_slash_redirecting=double_slash)

  #introducir valor de double_slash en csv de resultados

  https_t <- str_detect(i, "https://")
  https <- -1
  if(https_t == TRUE){
    https <- 1
  }
  else{
    https <- -1
  }
  de <- c(de, HTTPS_token=https)
  #introducir https en csv de resultados

  main_domain <- strsplit(i, "/")
  print(main_domain)
  domain <- main_domain[[1]]
  #print(domain[3])
  prefixB <- str_detect(domain[3], "-")
  prefix <- 0
  if(prefixB == TRUE){
    prefix <- -1
  }
  else{
    prefix <- 1
  }

  de <- c(de, Prefix_Suffix=prefix)
  #introducir https en prefix de resultados

  subdomain <- strsplit(domain[3], "[.]")
  n_subdomains <- lengths(subdomain[1])-2
  having_sub_domain <- 1
  if(n_subdomains < 2) {
    having_sub_domain <- 1
  }
  else if (n_subdomains == 2){
    having_sub_domain <- 0
  }
  else {
    having_sub_domain <- -1
  }

  de <- c(de, having_Sub_Domain=having_sub_domain)
  #introducir having_sub_domain en csv de resultados

  having_ip_address <- 1
  if(n_subdomains > 5){
    having_ip_address <- 0
  }
  de <- c(de, having_IPhaving_IP_Address=having_ip_address)

  #introducir having_ip_address en csv de resultados

  flag <- 0
  if(str_detect(domain[3], "bit.ly")){flag <-1}
  if(str_detect(domain[3], "tinyurl")){flag <-1}
  if(str_detect(domain[3], "tiny.cc")){flag <-1}
  if(str_detect(domain[3], "lc.chat")){flag <-1}
  if(str_detect(domain[3], "is.gd")){flag <-1}
  if(str_detect(domain[3], "soo.gd")){flag <-1}
  if(str_detect(domain[3], "s2r.co")){flag <-1}
  if(str_detect(domain[3], "clicky.me")){flag <-1}
  if(str_detect(domain[3], "budurl.com")){flag <-1}
  if(str_detect(domain[3], "t.co")){flag <-1}
  if(str_detect(domain[3], "bit.ly")){flag <-1}

  shortened <- 1
  if (flag == 1){shortened <- -1}

  de <- c(de, Shortining_Service=shortened)
  #introducir shortened en csv de resultados

  df[nrow(df) + 1,] = de

}

write.csv(df, "Desktop/legitimate_links.csv")

Análisis de exploración de datos

Una vez hemos realizado toda la parte de datos elegantes (extrayendo toda la información que deseamos), empezaremos la parte de análisis de exploración de datos.

Para ello, lo que se ha hecho para realizar esta explotación de datos ha sido seguir el algoritmo de "Naive Bayes". Este algoritmo, consiste en un "Data Mining", donde la presencia o ausencia de una característica particular no está relacionada con la presencia o ausencia de cualquier otra característica, dada la clase variable. Este algoritmo, ha sido útil también ya que solo requiere de una pequeña cantidad de datos de entrenamiento para estimar los parámetros que queremos.

Junto con el algoritmo "Naive Bayes" también hemos utilizado el "Principal Component Analysis (PCA)" que nos permite describir un conjunto de datos en términos de nuevas variables no correlacionadas y por lo tanto, nos es útil para reducir la dimensionalidad de los datos que tenemos.

A continuación mostramos el código que hemos utilizado para hacer phishing, siguiendo el algoritmo de "Naive Bayes + PCA".

library(caret)
library(caTools)
library(e1071)
library(ElemStatLearn)

any(is.na(mixed_links))

mixed_links$index <- factor(mixed_links$index, levels = c(0, 1))
typeof(mixed_links$index)

mixed_links_defined <- mixed_links[,c(2,3,4,5,7,8,9)]
head(mixed_links_defined)

head(mixed_links)

set.seed(123)
split = sample.split(mixed_links_defined$index, SplitRatio = 0.70)
training_set = subset(mixed_links_defined, split == TRUE)
test_set = subset(mixed_links_defined, split == FALSE)

head(training_set)

pca = preProcess(x = training_set[-8], method = 'pca', pcaComp = 2)
training_set_pca = predict(pca, training_set)
training_set_pca = training_set_pca[c(2, 3, 1)]
test_set_pca = predict(pca, test_set)
test_set_pca = test_set_pca[c(2, 3, 1)]
head(test_set_pca)

classifier = naiveBayes(x = training_set_pca[-3], y = training_set_pca$index)

y_pred = predict(classifier, newdata = test_set_pca[-3])

confusionMatrix(table(test_set_pca[, 3], y_pred))

set = test_set_pca

X1 = seq(min(set[, 1]) - 1, max(set[, 1]) + 1, by = 0.01)
X2 = seq(min(set[, 2]) - 1, max(set[, 2]) + 1, by = 0.01)
grid_set = expand.grid(X1, X2)
colnames(grid_set) = c('PC1', 'PC2')

y_grid = predict(classifier, newdata = grid_set)

Resultados

A continuación, se muestra un gráfico donde se puede observar, que mediante el algoritmo de "Naive Bayes + PCA", al realizar la comparativa de ambos datasets hemos obtenido una aproximación del 75% de exactitud de que existe phishing.

plot(set[, -3], main = 'Naive Bayes',
     xlab = 'PC1', ylab = 'PC2',
     xlim = range(X1), ylim = range(X2))
contour(X1, X2, matrix(as.numeric(y_grid), length(X1), length(X2)), add = TRUE)
points(grid_set, pch = '.', col = ifelse(y_grid == 1, 'tomato', 'springgreen3'))
points(set, pch = 21, bg = ifelse(set[, 3] == 1, 'red3','green4'))

![Accuracy 75%](C:/Users/Victor/Desktop/Data Driven/group-assignment-team-03/grafica_accuracy.jpg)

Conclusiones

Utilizando el algoritmo de "Naive Bayes" junto con el "Principal Component Analysis (PCA)" para reducir la dimensionalidad de los datos, al hacer una comparativa del dataset de phishing junto con el de webs legítimas extraído de "Alexa", hemos obtenido unos resultados del 75% de exactitud. Es un porcentaje bastante alto de exactitud, mejor del que habíamos imaginado, seguramente, si hubieramos obtenido herramientas más avanzadas, ese porcentaje lo hubieramos podido aumentar.

Para un siguiente "aproach", podríamos mejorar ese porcentaje de exactitud y también aplicarlo para hacer un análisis de países, para de esta manera, poder determinar donde hay más enfoque de phising.



DDS-MCSM/group-assignment-team-03 documentation built on June 1, 2019, 4 a.m.