comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

[Python] Underch4t v1.0 (Parte 1)

  • 2 Respuestas
  • 2446 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado WhiZ

  • *
  • Underc0der
  • Mensajes: 395
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« en: Diciembre 09, 2015, 01:56:48 pm »

UnderCh4t


Este es un pequeño servidor que acabo de crear en Python en respuesta a No tienes permisos para ver links. Registrate o Entra con tu cuenta de @No tienes permisos para ver links. Registrate o Entra con tu cuenta.

Voy a ir explicando, paso a paso, cómo armar el servidor y, finalmente, pongo todo el código completo.

Debido a que mi idea es ir explicando todo el proceso sin dejar cabos sueltos, ésta va a ser el primero de una serie de artículos en los que intentaré guiarlos en este maravilloso mundo de los sockets.

Comencemos!



CREANDO EL SERVIDOR


Lo primero que haremos es una clase llamada Servidor, la cual, en primera instancia, podrá realizar las siguientes tareas:
    - Sockets (vengan No tienes permisos para ver links. Registrate o Entra con tu cuenta los que no saben de qué estamos hablando ;) ):
        · crear un socket (servidor)
        · establecer interfaz de conexión: esto es, adjudicar ip y puerto local a la que se deberán conectar los clientes
        · poner el servidor en escucha
        · atender conexiones entrantes
        . cerrar socket
    - Informar estado del proceso
    - Manejar errores

Veamos cómo quedaría el código:
Código: Python
  1. import socket
  2. import sys
  3.  
  4. class Servidor(object):
  5.     def __init__(self, ip, puerto, max_con=5):
  6.         self.__ip = ip
  7.         self.__puerto = puerto
  8.         self.__max_con = max_con
  9.         self.__clientes = {} # { socket, [ip, puerto]}
  10.  
  11.     ##########
  12.     # SOCKET #
  13.     ##########
  14.     def ejecutar(self):
  15.         try:
  16.             self._crear_socket()
  17.             self._bind()
  18.             self._escuchar()
  19.             self._cerrar_socket()
  20.         except KeyboardInterrupt:
  21.             self._cerrar_socket()
  22.         except Exception as e:
  23.             self._mostrar_error(e, critico=True)
  24.  
  25.     def _crear_socket(self):
  26.         pass
  27.  
  28.     def _bind(self):
  29.         pass
  30.  
  31.     def _escuchar(self):
  32.         pass
  33.  
  34.     def _atender_cliente(self):
  35.         pass
  36.  
  37.     def _cerrar_socket(self):
  38.         pass
  39.  
  40.     ###########
  41.     # PROCESO #
  42.     ###########
  43.     def _mostrar_info(self, msj):
  44.         print " [+] {}".format(msj)
  45.  
  46.     def _mostrar_error(self, error, critico):
  47.         print " [!] Error: {}".format(error)
  48.         if critico:
  49.             self._salir()
  50.  
  51.     def _salir(self):
  52.         sys.exit(" [+] Finalizando aplicación")

Bien. Hasta aquí no hay mucho que decir. Hasta ahora hemos creado una clase 'Servidor' con dos grupos de métodos: los que se encargan de la conexión y los que se encargan de informar proceso y errores.

Vayamos con los métodos de conexión. El primero que vemos es el método 'ejecutar'. Este método constituye la guía de nuestra aplicación. Él se va a encargar de ir llamando, uno a uno, a cada método necesario para establecer nuestras conexiones.

Lo primero que hace es llamar a '_crear_socket'. Al menos que cambiemos un poco su contenido, no creo que pase mucho jeje. Vamos con eso:
Código: Python
  1. def _crear_socket(self):
  2.     self._mostrar_info("Creando socket")
  3.     try:
  4.         self.__servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  5.         self.__servidor.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  6.     except Exception as e:
  7.         self._mostrar_error(e, critico=True)

Voy a intentar explicar, de forma sencilla, qué significa todo esto que acabamos de escribir. Más allá del manejo de errores, los logs y el debugging, lo que realmente queremos es que este método nos cree un socket. La pregunta es: ¿cómo hacemos eso? El módulo No tienes permisos para ver links. Registrate o Entra con tu cuenta de python es quien nos permite realizar esta tarea. Para crear un socket, debemos escribir lo siguiente:
Código: Python
  1. mi_socket = socket.socket()

Todo muy lindo hasta acá pero los que saben y entienden de redes se estarán preguntando: ¿qué características tendrá este socket? ¿sobre qué protocolos se llevará a cabo la comunicación? Bueno, por defecto, el objeto utilizará los protocolos IP y TCP. ¿Y si quisiera utilizar UDP, en vez de TCP? ¿Puedo hacerlo? Absolutamente. Tal como se indica en la No tienes permisos para ver links. Registrate o Entra con tu cuenta, podemos indicar la familia, el tipo y el protocolo que querramos utilizar:
Código: Python
  1. mi_socket = socket.socket(familia, tipo, protocolo)

Para no complicarnos, sólo nos centraremos en la familia y el tipo. Dentro de las familias de direcciones, encontramos las siguientes:

    - AF_INET: le indica al kernel que vamos a utilizar el protocolo IPv4.
    - AF_INET6: le indica al kernel que vamos a utilizar el protocolo IPv6.
    - AF_UNIX: a diferencia de las familias INET que están ligadas a una tupla ip-puerto, las familias UNIX se vinculan a un archivo específico de tu sistema de archivos. Nos sirve, por ejemplo, para comunicación entre procesos de un mismo host.

Dentro de los tipos, los más utilizados son:
    - SOCK_STREAM: le indica al kernel que para transmitir los datos vamos a utilizar un protocolo confiable (TCP, por ejemplo).
    - SOCK_DGRAM: le indica al kernel que para transmitir los datos vamos a utilizar un protocolo no confiable (como es el caso de UDP)

Entonces, si quisiéramos hacer una conexión basada en los protocolos IP y UDP, bastaría con escribir lo siguiente:
Código: Python
  1. familia = socket.AF_INET # IPv4
  2. tipo = socket.SOCK_DGRAM # UDP
  3. mi_socket = socket.socket(familia, tipo)

¿Vamos bien hasta ahí? Si es así, entonces continuemos que queda bastante por delante. Tenemos que saber que, una vez creado nuestro socket, podemos acceder a las opciones del mismo para modificarlas. Para hacerlo, el objeto socket nos brinda un método que nos facilita la tarea: setsockopt().

Tal y como nos indica la No tienes permisos para ver links. Registrate o Entra con tu cuenta, para modificar una opción debemos indicar el nivel del socket (ya lo veremos unos renglones más abajo),  la opción que queremos modificar y el valor:
Código: Python
  1. mi_socket = socket.socket()
  2. mi.socket.setsockopt(nivel, opcion, valor)

Cuando hablamos de nivel, nos referimos, por decirlo de forma sencilla, al protocolo en el que se encuentra la opción que queremos modificar. Cada nivel tiene un valor que lo identifica, por ejemplo:
    - SOL_SOCKET: es el nivel del socket y el valor que lo identifica es 1.
    - SOL_TCP: es el nivel del protocolo TCP, cuyo identificador es el 6.
    - SOL_UDP: nivel del protocolo UDP, identificado por el número 17.

Como a nosotros sólo nos interesa acceder a las opciones del socket, vamos a utilizar SOL_SOCKET para indicar el nivel.

Dentro de las opciones (No tienes permisos para ver links. Registrate o Entra con tu cuenta), a mi me interesa una en particular: SO_REUSEADDR. Esta opción nos permite reutilizar un socket local que se encuentre en estado TIME_WAIT, sin tener que esperar su tiempo natural de expiración (para los que no engancharon nada -> No tienes permisos para ver links. Registrate o Entra con tu cuenta ;) ). La opción sólo acepta valores booleanos, es decir, reutiliza el socket o no lo utiliza (reutilizar: SI/NO).

Bien, ahora que entendemos un poco mejor cómo es esto de las opciones, vamos a modificar esta opción:
Código: Python
  1. mi_socket = socket.socket()
  2. nivel = SOL_SOCKET # Nivel del socket
  3. opcion = SO_REUSADDR # Opción a modificar
  4. valor = True # Sí, queremos reutilizar el socket
  5. mi_socket.setsockopt(nivel, opcion, valor)

Bien. Con esto queda concluido nuestro método para crear sockets. Con todo lo visto, ya son capaces de adaptar el método a sus necesidades. De hecho, podríamos modificar un poco el método para que sea más flexible:

Código: Python
  1. def _crear_socket(self, familia, tipo, opciones):
  2.     self._mostrar_info("Creando socket")
  3.     try:
  4.         self.__servidor = socket.socket(familia, tipo)
  5.         for opcion in opciones:
  6.             nivel, opcion, valor = opcion[:]
  7.         self.__servidor.setsockopt(nivel, opcion, valor)
  8.     except Exception as e:
  9.         self._mostrar_error(e, critico=True)



Con esto doy por concluida esta primera parte. En los próximos días iré desarrollando los demás métodos que tenemos pendientes y más ;)

Saludos!
WhiZ

P.D.: muchas gracias @po6xsecpo por la correción.
« Última modificación: Diciembre 19, 2015, 05:22:49 pm por WhiZ »


Desconectado po6xsecpo

  • *
  • Underc0der
  • Mensajes: 45
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
    • Email
  • Skype: po6xsecpo@gmail.com
« Respuesta #1 en: Diciembre 09, 2015, 02:24:02 pm »
Gracias por el aporte.
En la línea 7 del primer script tenemos un error, la asignación del parámetro al atributo puerto está como:
Código: Python
  1. self.__port = port
Y el parámetro es "puerto". Por ende dará error.


Duda. En la línea 4 del método _crear_socket(self)
Código: Python
  1. self.__servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Al usar self.__servidor, estás declarando e inicializando el objeto self.__servidor ó este debía existir previamente entre los atributos de la clase Socket(object) ?


Gracias por el aporte. Estaré al tanto de la serie
« Última modificación: Diciembre 09, 2015, 10:24:13 pm por WhiZ »

Desconectado WhiZ

  • *
  • Underc0der
  • Mensajes: 395
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #2 en: Diciembre 09, 2015, 04:14:14 pm »
No tienes permisos para ver links. Registrate o Entra con tu cuenta
En la línea 7 del primer script tenemos un error, la asignación del parámetro al atributo puerto está como:
Código: Python
  1. self.__port = port
Y el parámetro es "puerto". Por ende dará error.

Sí, es cierto. Pasa que a la aplicación la hice en inglés y la estoy traduciendo para el tuto jeje. Voy a tener más cuidado. Gracias por el aviso ;)

No tienes permisos para ver links. Registrate o Entra con tu cuenta
En la línea 4 del método _crear_socket(self)
Código: Python
  1. self.__servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Al usar self.__servidor, estás declarando e inicializando el objeto self.__servidor ó este debía existir previamente entre los atributos de la clase Socket(object) ?

__servidor es una instancia de socket() que pertenece a la clase Servidor. Es decir, estoy declarando e inicializando el objeto.

No tienes permisos para ver links. Registrate o Entra con tu cuenta
Gracias por el aporte. Estaré al tanto de la serie
No, gracias a vos por tu interés :)

Saludos!
WhiZ
« Última modificación: Diciembre 09, 2015, 10:25:13 pm por WhiZ »


 

¿Te gustó el post? COMPARTILO!



[Código] Yardas a metros - Metros a yardas [Python]

Iniciado por LucaSthefano

Respuestas: 0
Vistas: 1346
Último mensaje Mayo 29, 2011, 01:27:34 am
por LucaSthefano
[Código] Entero / No Entero [Ejercicio - Python]

Iniciado por LucaSthefano

Respuestas: 0
Vistas: 1301
Último mensaje Mayo 29, 2011, 01:24:09 am
por LucaSthefano
Python phpmyadmin "BruteForce"

Iniciado por linkgl

Respuestas: 2
Vistas: 2443
Último mensaje Agosto 19, 2011, 12:14:37 pm
por linkgl
Python Trojan - By "bLiNdFiR3"

Iniciado por d33k40

Respuestas: 1
Vistas: 1979
Último mensaje Abril 03, 2010, 11:01:59 pm
por Dharok
Python keylogger - by "bLiNdFiR3"

Iniciado por d33k40

Respuestas: 0
Vistas: 1969
Último mensaje Abril 07, 2010, 03:30:22 am
por d33k40