Script php para obtener los dominios que nos han atacado

Teniendo en funcionamiento iptables, combinado con algún monitor como fail2ban, podemos obtener el listado de IP’s que tenemos bloqueadas en el firewall con un DROP (mejor no deja huella) o REJECT (contesta).

iptables -L > listado-nombres.txt

Esto para que os hagáis una idea produce una salida así:

target     prot opt source               destination         
DROP       all  --  adsl-99-68-7-20.dsl.lsan03.sbcglobal.net  anywhere            
DROP       all  --  adsl-99-63-238-108.dsl.klmzmi.sbcglobal.net  anywhere            
DROP       all  --  adsl-99-59-103-92.dsl.lsan03.sbcglobal.net  anywhere            
DROP       all  --  99-53-244-68.lightspeed.snjsca.sbcglobal.net  anywhere     

Ahora filtro un poco:

cat listado-nombres.txt |tr -s " "|cut -f4 -d" "|grep -v "^[0-9].*[0-9]$"

Excluyo las IP que no se han podido resolver, seguramente pertenecen al abanico DHCP que ofrece algún ISP a nivel doméstico. Esto lo redirecciono a un archivo nombres.txt para usarlo como fuente en el script siguiente y obtener nombres.dat.

Con ayuda de un script en PHP para trabajar a gusto con las cadenas y poder usar funciones como explode:

<?php
$datos='nombres.txt';
$salida='nombres.dat';
$fp = fopen($datos,"r");

if (!$fp2 = fopen($salida, 'a')) {
         echo "No se puede abrir el archivo ($salida)";
         exit;
}

while ($linea= fgets($fp,1024)){
    $linea=trim($linea);
    echo "Churro:$linea"."\n";
    $subdominios=explode(".",$linea);
    $C=count($subdominios);
    echo "N.subdominios:".$C."\n";
    /*
    for ($i=0;$i<$C;$i++){
      echo "Subdominio".$i."/$C=".$subdominios[$i]."\n";
      
    }
    */
        
    if ($C>=2)
      $cadena=$subdominios[$C-2].".".$subdominios[$C-1]."\n";
    else
      $cadena=$linea."\n";
    echo $cadena;

    //Escribir en datos
    if (fwrite($fp2, $cadena) === FALSE) {
        echo "No se puede escribir en el archivo ($salida)";
        exit;
    }
}//while
fclose($fp);
fclose($fp2);

Con ayuda de unos pocos filtros más:

cat nombres.dat |sort|uniq

Evitamos duplicados.

Posibles mejoras

Podríamos ahora usar whois para averiguar los emails de abuse@ de estos dominios.
Podríamos empezar teniendo como objetivo los dominios .com y .net, también otros que soporta el comando whois de Linux, con este filtro:

cat nombres.dat |sort|uniq |egrep "(.com$|.net$)" > abuse.dat

Me quedo con los .com y .net para empezar.
Ahora habría que montar un bucle para iterar y hacer whois sobre todos los dominios del fichero abuse.dat que acabamos de crear.
Pero antes hay que familiarizarse con la salida de whois para saber que tenemos que filtrar luego.

Si tomamos un ejemplo:

whois zsttk.net

Nos interesa un primer filtro que hable de “abuse”

whois zsttk.net|grep abuse

Y ahora para ir al grano usar una expresión regular que case con un email completo, hay muchas, yo usaré esta:

\<[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})\>

Y mi filtro de la salida de whois:

whois zsttk.net|grep abuse|egrep -o "\<[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})\>"

Extraerá esta información:

tld-abuse@nic.ru

Fácil? Pues ahora podemos pensar en un bucle que haga esto:

Para ello este Shell script:

#!/bin/bash
while read dominio
do
  miwhois=`whois $dominio|grep "abuse"|egrep -o "\<[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})\>"`

  if [ ${#miwhois} -gt 1 ];then
    echo "${dominio}:${miwhois}"
  fi
done < abuse.dat

Tras ejecutarlo, vemos una salida como esta:

./whois.sh 
100tb.com
abuse@enom.com
101netlink.com
abuse@enom.com
...

Lo mejor es almacenarla en un fichero para su posterior explotación. Para ello redireccionamos deshaciendonos de los posibles errores.

./whois.sh 2> /dev/null | tee email-abuse.txt

Plan B, tengo IP, necesito dominio, para conseguir el abuse@

Si de lo que disponemos es de un listado de IP’s que hemos obtenido de logs, y a partir de la IP queremos obtener el dominio, para después mediante whois sobre los nombres obtener los emails de abuse, dado un listado de IP’s como este Lista de IP’s que nos atacan, podemos realizar este Shell script:

#!/bin/bash
while read ip
do
  host $ip
done < ips.txt

Si analizamos un poco la salida del comando host, todo lo que responda NXDOMAIN no nos sirve, es alguna IP dinámica, de ADSL o similar.

26.5.38.100.in-addr.arpa domain name pointer static-100-38-5-26.nycmny.fios.verizon.net.
235.112.43.100.in-addr.arpa domain name pointer xplr-100-43-112-235.xplornet.com.
101.85.8.100.in-addr.arpa domain name pointer pool-100-8-85-101.nwrknj.fios.verizon.net.
Host 134.111.9.100.in-addr.arpa. not found: 3(NXDOMAIN)
44.67.0.101.in-addr.arpa domain name pointer vps.compareeducationcosts.com.au.
46.0.102.101.in-addr.arpa domain name pointer ngn3-ppp46.gunma.sannet.ne.jp.

De esa salida podemos deducir que nos interesa la última cadena, de los resultados que no sean NXDOMAIN, quitar el punto final.
Con este filtro ya conseguimos algo:

bash host.sh |egrep -o "[^ ]*$"

La salida es esta:

static-100-38-5-26.nycmny.fios.verizon.net.
xplr-100-43-112-235.xplornet.com.
pool-100-8-85-101.nwrknj.fios.verizon.net.
3(NXDOMAIN)
vps.compareeducationcosts.com.au.
ngn3-ppp46.gunma.sannet.ne.jp.

Con esta mejora la salida ya es:

#!/bin/bash
while read ip
do
  dominio=`host $ip|grep -v "NXDOMAIN"|egrep -o "[^ ]*$"`
  if [ ${#dominio} -gt 1 ];then
    L=${#dominio}
    let L=L-1
    dominio2=`expr substr $dominio 1 $L`
    echo $dominio2
  fi
done < ips.txt

Como esta:

static-100-38-5-26.nycmny.fios.verizon.net
xplr-100-43-112-235.xplornet.com
pool-100-8-85-101.nwrknj.fios.verizon.net
vps.compareeducationcosts.com.au
ngn3-ppp46.gunma.sannet.ne.jp

Que se aproxima a lo que nos proporciona iptables, estaríamos generando un posible fichero nombres.txt del comienzo de este artículo, y estaríamos dispuestos a usar el script php para quedarnos solo con las dos ultimas partes del dominio, por ejemplo verizon.net

Espero que os sirva.

Un comentario

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *