Como ya sabréis todos, soy un enamorado del Metasploit Framework, pero no por los exploits que incluye, sino por otras funcionalidades incluidas en el framework que me resultan muy útiles y cómodas de utilizar.
Una de las funcionalidades que uso con mucha frecuencia es la del módulo fakedns, que te permite configurar un servidor DNS en cuestión de segundos, que resolverá cualquier nombre con la IP que le digamos, salvo una lista concreta de nombres para los que se resolverán sus IPs reales.
Veamos como funciona:
# ./msfconsole
msf > use auxiliary/server/fakedns
msf auxiliary(fakedns) > show options
Module options (auxiliary/server/fakedns):
Name Current Setting Required Description
---- --------------- -------- -----------
DOMAINBYPASS www.google.com yes The list of domain names we want to fully resolve
SRVHOST 0.0.0.0 yes The local host to listen on.
SRVPORT 53 yes The local port to listen on.
TARGETHOST no The address that all names should resolve to
msf auxiliary(fakedns) > set DOMAINBYPASS www.pentester.es
msf auxiliary(fakedns) > set TARGETHOST 192.168.1.100
msf auxiliary(fakedns) > run
[*] Auxiliary module execution completed
[*] DNS server initializing
[*] DNS server started
Ahora, si probamos a hacer algunos "dig" (os enseño la salida recortada), veremos como resuelve todos los nombres con la dirección 192.168.1.100, salvo el nombre www.pentester.es (o los que hubiéramos pasado separados por espacios):
$ dig @127.0.0.1 www.google.com
www.google.com. 60 IN A 192.168.1.100
$ dig @127.0.0.1 www.yahoo.com
www.yahoo.com. 60 IN A 192.168.1.100
$ dig @127.0.0.1 www.pentester.es
www.pentester.es. 60 IN A 173.194.66.121
Este funcionamiento... a mi nunca me ha terminado de convencer, lo veo demasiado "de botón gordo", ya que yo por lo general suelo querer interceptar solo una o un grupo de conexiones, y dejar que todas las demás sigan su funcionamiento normal.
Por suerte estamos trabajando con software OpenSource y tenemos la oportunidad de poder acceder al código y modificarlo según nos convenga, así que vamos a pegarle un vistazo al código (modules/auxiliary/server/fakedns.rb):
Como podemos ver, hay un punto en el código en el que se recorre la lista y se compara con la petición DNS que acaba de entrar. Si son iguales, entonces se hace una resolución "normal", mientras que si tras recorrer la lista no ha encontrado ninguno se entiende que al no estar en la lista de "bypass", se envia la respuesta "fake".
Si pensamos en una solución rápida y práctica, podemos sencillamente cambiar la condición:
[...]
if (name.to_s <=> ex) != 0
[...]
Con esto, siempre y cuando solo pongamos un elemento en la lista, vamos a tener más que suficiente, ya que va a funcionar de la forma completamente contraria: Cuando el nombre solicitado esté en la lista resolverá con fake, y cuando no lo esté funcionará normal.
Esta aproximación tan sencilla es la que he usado muchas veces cuando he querido interceptar las conexiones de algún software para analizarlas y dejar que el resto de elementos del sistema funcionen sin pasar por mis otras herramientas. Sin embargo, en algunas situaciones...
msf auxiliary(fakedns_single) > [-] fakedns: Resolv::ResolvError DNS result has no information for foo.pentester.es /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/resolv.rb:363:in `getaddress'/opt/msf/modules/auxiliary/server/fakedns.rb:143:in `run'/opt/msf/modules/auxiliary/server/fakedns.rb:140:in `each'/opt/msf/modules/auxiliary/server/fakedns.rb:140:in `run'/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/resolv.rb:1183:in `each_question'/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/resolv.rb:1182:in `each'/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/resolv.rb:1182:in `each_question'/opt/msf/modules/auxiliary/server/fakedns.rb:115:in `run'/opt/msf/lib/msf/base/simple/auxiliary.rb:102:in `job_run_proc'/opt/msf/lib/msf/base/simple/auxiliary.rb:74:in `run_simple'/opt/msf/lib/rex/job_container.rb:36:in `call'/opt/msf/lib/rex/job_container.rb:36:in `start'/opt/msf/lib/rex/thread_factory.rb:21:in `call'/opt/msf/lib/rex/thread_factory.rb:21:in `spawn'/opt/msf/lib/msf/core/thread_manager.rb:64:in `call'/opt/msf/lib/msf/core/thread_manager.rb:64:in `spawn'/opt/msf/lib/msf/core/thread_manager.rb:57:in `initialize'/opt/msf/lib/msf/core/thread_manager.rb:57:in `new'/opt/msf/lib/msf/core/thread_manager.rb:57:in `spawn'/opt/msf/lib/rex/thread_factory.rb:21:in `spawn'/opt/msf/lib/rex/job_container.rb:31:in `start'/opt/msf/lib/rex/job_container.rb:155:in `start_bg_job'/opt/msf/lib/msf/base/simple/auxiliary.rb:71:in `run_simple'/opt/msf/lib/msf/base/simple/auxiliary.rb:89:in `run_simple'/opt/msf/lib/msf/ui/console/command_dispatcher/auxiliary.rb:103:in `cmd_run'/opt/msf/lib/rex/ui/text/dispatcher_shell.rb:380:in `send'/opt/msf/lib/rex/ui/text/dispatcher_shell.rb:380:in `run_command'/opt/msf/lib/rex/ui/text/dispatcher_shell.rb:342:in `run_single'/opt/msf/lib/rex/ui/text/dispatcher_shell.rb:336:in `each'/opt/msf/lib/rex/ui/text/dispatcher_shell.rb:336:in `run_single'/opt/msf/lib/rex/ui/text/shell.rb:199:in `run'./msfconsole:134
Ops! Cascazo! Y además la ejecución del módulo se ha ido al garete, así que como tenga en una red o host peticiones como esta... voy a estar teniendolo que rearrancar cada dos por tres. Imposible trabajar así, vamos.
En
el próximo post veremos porque pasa esto y como evitarlo, y seguiremos mejorando el fakedns.