Fuente: HackPlayers
Hoy es el ultimo día del 2012 un año que vino con miles de retos, cambios mejoras para bien o para mal como lo quieran llamar un jodido año para mi la verdad donde aprendi muchas cosas conoci nuevos amigos pero que va porque no mejor hago un balance el cual el 2012 se quedara por siempre recordado en mi memoria el porque por esto:


Un año de un duro aprendizaje malo no fue ni tan bueno si lo veo del otro lado de la  moneda me pregunto que tanto ame, perdone, reí, aprendí  logre ir contra mis peores enemigos el orgullo, egocentrismo, mi tonto organismo, al fracaso.

Vamonos por el primero, que tanto ame segui amando por otro tonto año mas, a la misma persona aun recordandola, y demas pero se que este año aprendi que solo fue un apego emocional que me mantuvo porque no lo se soy humano cometo errores, :) ahora me doy cuenta que te quiero si lo lees sabras que si gracias por ayudarme a mejorar, por ser esa piedrita en el camino que me hizo tropezar  y caer por un momento para ser lo que ahora soy siempre estaras en mis mejores recuerdos. Aprendí a querer, amar aun estando tan lejos a varios km de distancia volviéndose la persona mas importante en mi vida ayudando y guiándome para que no cometa errores, ni metida de pata  xD.

Aquí también entra lo mas importante :) que aprendi a amar lo que me dio la vida a despertar y dar un gracias por estar aqui y estar un dia mas de pie. 

Perdone, pues se diria que si xD casi todo perdone no todo porque sigue lo peor en mi rencoroso espero cambiar en algo este año que llega.

Reí mas de una vez, y cuanto de las mil tonteras que hacia en la Fundacion Jala mis metidas de pata al subir código, al no hacer bien un merge, o bien mi spanglish que las ultimas semanas por que andaba mal hablaba me trababa, con mis amigos del equipo con la familia, reir por que es el sazón de la vida sin darme cuenta aprendi a sonreir por mas triste que me encontraba.

Aprender ?? OMG!! Este proceso que a diario voy haciendolo este año fue un año de duro aprendizaje tanto como en el are profesional, personal no hay dia que no aprenda cosas nuevas el proceso seguira cada dia, espero que todo lo que aprendi en este año comienze a cultivarlo debidamente sin miedo al fracaso.

Mis enemigos

Joder llegamos a lo peor, mi orgullo, egocentrismo que siguen aun ahi presentes en mi vida, espero llegar a mandarlo o desaserme un poco de ellos este año que comienza dentro de pocas horas, y aun mas lo peor de mi ser DESORDENADO!!! no cumplir con las tareas que me pongo :( se que es algo malo pero no imposible de lograr sobrepasar y lograr hoy sin mentirles ya recibi la regañada del 2012 la ultimo se que sera, hace un momento al llegar a la oficina tachin! mail todo porque? me olvide enviar y si tiene razón tengo que organizar mejor mi tiempo.

Para ello este fin de semana estuve leendo este blog el cual se que me ayudar con sus sugerencias y tips, http://thinkwasabi.com.

Miedo al fracaso, este jodido enemigo que anda al lado mio cada dia se que por fuera ando optimista pero por dentro tengo miedo a no lograr mis objetivos falta de control, de valorarme, no se que rayos sera.

Darme cuenta que no tod o fue como lo pensaba, al fin notar que todo lo que vivi hace un tiempo fue  una ilusión tonta que solo yo la cree.


Lo Mejor del año

Epale lo mejor del año haber comenzando, con mi primera experiencia de Coding Dojo que fue en Febrero cuando recibi una invitación para participar de un nuevo proyecto en Fundacion Jala, no se porque fui, ni porque lo hice quizas porque uno de mis sueños, era formar parte de Jalasoft.

La tesis lograr terminarla luego de mi metida de patota! al borrarla y reprogramarla toda logre alcanzar terminandola teniendo mis empastados listos cuando eran necesarios la defenza privada el mejor dia que pude pasar luego de muchos tropiezos en el cual sali con nota de 95/100 :), lo mejor dia del programador y mi defenza yeah!! todo orgulloso de ella aun mas de haber logrado salir usando netamente software libre la tesis hacerla totalmente en LaTeX programar en Python + Perl + Gtk + Bash una mezcla que salio un hibrido todo hermoso si me siento orgulloso, a la vez cuando termino todo el dia que dio un fin a esa pequeña meta de la vida cuando me dieron el titulo de ingeniero de Sistemas. 

A la vez el Hackmeeting 2012 este evento que forme parte del equipo de los chicos de la Scesi el evento de seguridad y hacking mas grande que tuvo mi pais y con orgullo lo digo porque lo es y sera por mucho tiempo aqui hay 2 entradas referentes a ello.

Los 2 proyectos que van saliendo poco a poco mas fuerte, SniferL4bs y Geekscripting como tambien la Biblioteca, el segundo gracias a todos los que apoyan y siguen la cuenta en twitter el fan page en facebook y a un mas a WizardIP y Tonejito

Mi viaje a La Paz :)


Mi primer ponencia en el DESEIN.

Lograr un poco de estabilidad, dar a mi hermano lo que siempre quise tener, apoyar a mi familia estar siempre cuando me necesiten lograr cumplir mis metas:


  • Entrar a Jalasoft - Lo hice mi sueño desde que llegue de La Paz
  • Terminar la carrera - Otro mas que se sumo
  • Framework de Informática Forense - Esto es la tesis aun falta liberarlo
  • Ser mejor....

Que mas puedo pedirle a este año, que se va dejando una gran marca en mi vida me enseño y demostro lo bello de la vida lo principal los amigos que siempre estan y estaran ahi, primero ante todo como dice mi amigo el Jobato (sabes que lo digo con cariño jabali) Angel FAMILIA!, la familia que el destino hace que tengamos.

Primero esta la familia del Silas, Fabian, Daniel, Reynaldo, Kelly, Oscar, Roger 6 chicos de los mejores que estuve compartiendo 9 meses con ellos talvez con algunos menos tiempo pero los aprecio me enseñaron tantas cosas, como tambien me regañaron xDD, al mentor que me enseño y ayudo a madurar cambiar un poco de mi Julio que se volvio como un hermano mayor para todos en especial para mi aunque diga que por mi culpa le operarón sabemos que no XD, al gravetero de JJ que para mi su alegria y firmeza pasión por el trabajo me dan el empujon a seguir. (No se si lo leeran pero que se quede aqui :D guardado en mi rincón. )

Mish, el angel que me ayudo siempre estare agradecido a ti, por todo el apoyo que me  diste me ayudaste a sobre llevar mi error a darme cuenta que podia hacerlo cumplir, me ayudaste tanto que siempre estare agradecido contigo gracias por darme tu amistad, ser mi tutora, mi guia, consejera y amiga te quiero.

Tami, la chicoca que hasta ahora no la conosco xD pero siempre dandome animos, apareciste cuando mas necesitaba un hombro un sosten ahora andas en Chile o en La Paz no se donde estes feliz año gracias por todo.

Liz, que digo de ti xD solo me queda darte un gracias :P

La loca  familia que tengo U_U, si loca primero a la ingrata escritora colaboradora -_-! Kari, al rooteado de Enrique :( que se olvido de nosotros, y al viejo del mar Seguridad Jabali mas conocido como Angel el indestructible, chicos gracias por estar ahi siempre dandome animos haciendome  reir, llorar disfrutar la vida dar el dulce en la cereza con nuestras discusiones y peleas.

Este año conoci a Jhegs, Walsen, Kasammanor, Betto, Jimmy el troll xD personajes de gran corazón siempre saliendo con alguna ocurrencia buscando pelea o bien mas que uno queriendome romper las piernas un abrazo a todos.

Arquitecta, Tebot, Eliana, Fabiola, chilli, Anita, Sergio 666, Cristina, Sarah, Camel, ChicoViejo, Darvein, Goztilla, thearcherblog, Luweeds, kinomakino, 1gbdeinfo, Angelucho, ns4 vil gusano,  y todos los demas que talvez me olvide de alguno xDDD feliz año nuevo gente!

A los redactores del blog nao, sanko, kari feliz año!!

A los tucanes :3 a todos los pinguinos que andan alli un abrazo....


Lo que se viene



  1. Ser mejor cada dia luchar, no caer.
  2. Darle con todo cada dia para saber que logre dar lo mejor de mi.
  3. El framework :) de forense terminarlo este año sale por que sale.
  4. Dejar mi orgullo a un lado ser mas fuerte.
  5. Continuar haciendo crecer geekscripting y Sniferl4bs.
  6. No caer...


Por ultimo lo que tengo que hacer...

  • No tenerle miedo al sufrimiento ni al fracaso, porque ambos son sólo unas  instancias de aprendizaje que ayudaran a crecer.
  • Entender que la vida es solo prestada aprender a vivirla depende de cada uno de nosotros nuestra fuerza de voluntad para cambiar, tener una mejor idea para cambiar la vida que venga con estrategias y cambios.



Recuerden esto :

“SER FELIZ ES UNA DECISIÓN”

Para mi que siempre tengo que llevarlo .

"Queda prohibido no luchar por lo que quiero, abandonarlo todo por miedo,no convertir en realidad mis sueños"

Este es mi año el que viene es mi sueño, no me rendire..  seguire luchando por mis sueños...



Ahora este verso que me encanto...

"Dicen que las alegrías, cuando se comparten, se agrandan.
Y que en cambio, con las penas pasa al revés: Se achican.
Tal vez lo que sucede, es que AL COMPARTIR, LO QUE SE DILATA ES EL CORAZÓN.
Y un corazón dilatado esta mejor capacitado para gozar de las alegrías y mejor defendido para que las penas no nos lastimen por dentro".


Feliz año nuevo y gracias por leer este cuento :).
Leer Mas
Hoy es el ultimo día del año y creo que se viene con mas hace un momento me desperte y walla ya salio el numero especial de las guerrilleras :3 que lean esto y me matan xD pero que va desde que salio el primer numero en el blog andamos difundiendo esta revista Hackers Developers y hoy cerramos el año con broche de oro  con esta entrega una edición especial acabo de terminar de leerla :3, y si ven aparece Richard Stallman con una entrevista, un priv8 asi que a bajar la revista y leer el ultimo día del año.




Por si quieren ver las anteriores entradas:


Hackers&Developers @HackDevMagazine #1



31.12.2012   Descargar PDF de Hackers & Developers Magazine Nº 2  03.12.2012   Descargar PDF de Hackers & Developers Magazine Nº 1  05.11.2012   Descargar PDF de Hackers & Developers Magazine Nº 0  

Leer Mas
Ya la penúltima entrada del año :) y la cual viene con una idea que andaba rondando por mi cabeza  mucho tiempo ya pero nunca salia correctamente talvez porque estuve esta dos ultimas semanas mal sin tiempo para poder reaccionar debidamente caminando como un vagundo entre mi mente, pero que va hoy es Domingo y como saben mañana es la noche que se va todo lo malo y se viene lo bueno o bueno al menos eso es lo que pienso hoy les traigo un pequeño proyecto el cual es LABORATORIOS DE SEGURIDAD yo ando armando el mio bueno eso luego viene :). 

La mejor forma para poder aprender es practicando, para dicho objetivo se crearon, armaron y posteriormente se liberarón entornos  de practica los cuales nos sirven para poder montarlos y practicar con ellos, yo los llamo laboratorios de prueba pero que tal si se tiene una referencia de todos estos entornos ya sean de Seguridad Hacking, Pentesting, Forensic, Maquinas Virtuales configuradas debidamente seteadas y poder acceder a ellas a eso se viene el proyecto que se inicia en SniferL4bs lo cual seria gratificante recibir un feedback de todos en este mismo post en el cual poder incrementar las referencias ahora ando subiendo de apoco las referencias y los links pero la pequeña muestra de lo que andara por esa pestaña es la siguiente:
Pentesting

  • Proyecto Sauron
  • Web Security Dojo
  • Metasploitable
  • Damn Vulnerable Web
  • OWASPBWA
  • Game Over
  • HOLYNIX
  • WackoPicko
  • Lampsecurity
  • y mas.. 

Lo mismo procederé con lo que es referente a Forense, Redes  y demás ira creciendo segun el transcurso de los días cabe destacar  que es un proyecto abierto y con tiempo espero que sea una fuente de referencia en lo posible tratare de hacer una entrada semanal o mensual con alguna de estas distro y a la vez teniendo en ella referencia a mas información con ello.

Pero a esto el link donde esta Laboratorios de Seguridad
Leer Mas
El movil que tendre cuando sea grande :) es el Nokia N900 y lo digo enserio sueño con este móvil el porque y para que en este post se darán cuenta el cual vuelve al móvil en toda una herramienta de Pentesting.

PwnieExpress una de la mejor suite de Pentesting para el Nokia N900, la cual nos ayuda a llenarlo de hormonas y tener todo un monstruo en el lo cual lo vemos a continuacion teniendo a metasploit

Metasploit
Una vista mas sexy del mismo que nos permites configurar La pantalla es totalmente personalizada para el Pentesting con accesos directos a Macchanger, incorporado en la tarjeta inalámbrica compatible con la inyección de paquetes, el modo monitor y el modo promiscuo también está disponible.

El escritorio como se llega a ver ;)




1. Conky - Para ver el uso del sistema y stats
2. Promiscuous_on_off - Script para activar el modo promiscuo de manera intermitente durante wlan0
3. xterm RootShell - el acceso de root shell en el directorio /home/usuario/MyDocs/pwnphone
4. Macchanger - Rolls dirección MAC de la tarjeta inalámbrica wlan0 y los cambios de nombre de host a "DellPC"
5. Nmap - Versión de línea de Comando de Nmap
6. Zenmap - Versión GUI de Nmap
7. InjectionON - Carga los controladores necesarios para la inyección de paquetes inalámbrico
8. InjectionOFF - Descarga los controladores de la inyección de paquetes y vuelve a cargar los controladores normales wifi
9. Airodump-ng - Rápido acceso a la tecnología inalámbrica sniffer, ejecutando: airodump-ng wlan0
10. Kismet - Wireless Sniffer / herramienta de mapeo
11. Wifite - Herramienta de ataque Wirelles automatizado
12. Wifizoo - Herramienta inalámbrica para olfatear las sesiones activas en el wifi
13. Grimwepa - Hherramienta en GUI que se utilizan con la suite aircrack-ng - WEP / WPA cracking
14. Wepbuster - Automáticamente rompe las redes inalámbricas de WEP en el rango (¡cuidado!)
15. El modo promiscuo en el botón de off - Activa el modo promiscuo en wlan0
16. Wireshark - acceso directo del escritorio - analizador de paquetes / sniffer
17. Tshark - La versión CMD línea de Wireshark - Se ejecuta en wlan0
18. Tcpdump - Ejecutar tcpdump en wlan0 (tcpdump-s0-n-i wlan0)
19. Sslstrip - Herramienta utilizada para despojar a los sitios web de SSL y oler las credenciales
20. Scapy - Interfaz Scapy - la manipulación de paquetes interactivos
21. Nikto - Herramienta Web de exploración de vulnerabilidades
22. SET - Kit de herramientas de Ingeniería Social
23. Metasploit - la versión del CMD msf3 (msfconsole)
24. Metasploit-GUI - versión GUI de msf3
25. Fasttrack - Herramienta automatizada pentesting
26. EttercapNG-Curses - Version Curses de EttercapNG
27. EttercapNG-GUI - versión GUI de EttercapNG

Algunas Imagenes de las Herramientas:

Wifi Free
Terminal
El sexy Conky








Ahora si que viene lo malo como se diria bueno no pa todo lo malo es de pago :( y si lo queremos en el movil es necesario ingresar a la pagina oficial del proyecto Pwnphone y comprar dicho archivo, la cual el precio es de $960.00 USD








Pero si ya tenes el Nokia N900 en tus manos, te facilitare las aplicaciones totalmente gratis !! solo tenes que dirigirte a este link para descargar la aplicación:

Fuente de todo esto Caleb

(430 MB)

Ahora si para poder instalar y demas viene dentro del file, se los dejos de tarea :D

Acceso SHH:
Username: root
Password: pwnphone
Ruta: /home/user/MyDocs/pwnphone
Leer Mas
Buenas a todos el post de ayer fue una inocentada, si en parte ando un poco delicado de salud pero eso no va para que deje este proyecto ni el resto que llevo en popa, ya que se vienen varias sorpresas y proyectos que se acercan entre ellos un adelanto una revista, que tendra a varios participes de la red.

Aun mas desde mañana espero volver con los post diarios como estuvimos mas de 1 mes.. :)

Se viene:

-  Fin de Semana con LaTeX
-  Laboratorio de Informatica Forense
-  Entradas de MITM
-  Jugando con Backtrack
-  Retos y mas... 

Gracias a todos por el apoyo sin querer me ayudaron, a subir la moral ya que andaba un poco caida 
Saludos
Leer Mas
Buenas a todos últimamente ando pasando malos momentos los cuales no me permiten seguir adelante con el Blog, es un año y mas que ando con este proyecto el cual creció con las visitas comentarios feedback por medio de facebook, twitter, a travez del mail gracias a todos por el apoyo enserio, pero hoy es un punto que todo  termina al ir al medico y enterarme que las cosas cambiaran me llevan a realizar este entrada, ando un poco cansado de escribir, no podre dar post de interes o bien llevar algo para los demas hoy el pinguino me aplasta tal vez siga en twitter compartiendo pero ando cansado acabado moralmente, no tengo las fuerzas para seguir adelante y luchar, el blog seguira abierto para que algunos lo tengan como referencia  y siga el pequeño aporte que realize..

GRACIAS A TODOS..

@SeguridadJabali @Kari_243 @enriquegmv @1gbInfo @Kinomakino  @WizardIP @Tonejito...


Leer Mas
Que sucede si nos cambian de equipo de trabajo, renunciamos o bien nos realizaran un cambio de ordenador en cualquiera de los casos ya nombrados tenemos que tener en cuenta que al hacer uso del equipo llegamos  a ingresar nuestros credenciales y  gran parte del tiempo tenemos el error de no verificar si  en el browser, msn, skype damos click en recordar contraseña se que lo hacemos por comodidad para no volver a escribir o aun mas porque somos los únicos que tenemos acceso al pc, ahora que sucede si nos olvidamos eliminar los datos privados del equipo y cualquier persona tiene acceso a ellos? 

Se pusieron a pensar ? ese detalle lo iremos viendo que primero lo común es eliminar todos los datos temporales y demas el proceso contra esta medida es vialmente viable de la siguiente forma pero antes tenemos a un nemesis Chrome


Chrome  nuestro primer enemigo 

Primero Chrome es mi browser por defecto lo prefiero, sera porque ando casado ya con google pero me agrada este browser primero si alguien tiene acceso a tu navegador si le das en guardar o almacenar las contraseñas, se tiene acceso totalmente libre en texto plano, si basta de muestra un boton.



Texto plano
Cuando note este error comenze a indigar y buscar información sobre ello, pero ya lleva bastante tiempo con ello no fui el primero en darme cuenta era de suponerse obviamente, segun las respuestas de Google indican que solo se tiene acceso  a las cuentas por el usuario cuando da en recordar contraseña como también cuando se realiza la sincronización, pero que sucede si algún curioso revisa y tenemos almacenadas la cuenta del banco, transacciones y demás tachin tenemos problemas evidentemente ahora vamonos, que hacemos para ello primero para borrar la información de Chrome procedemos a ir a setting y  desconectamos la cuenta si es que nos sincronizamos con la cuenta de Gmail.





Desconectando la cuenta.. :)


Ahora lo siguiente es eliminar las paginas que visitamos, es decir el historial el shortcut es Ctrl+h.


Asi que tendremos acceso a la siguiente ventanita y borramos todos nuestros datos.. 

Esto seria en el caso de Chrome pero tenemos que hacer lo mismo con Firefox, IE, sea cual fuese el browser que usemos debemos de proceder de la misma forma, a la vez tenemos que tener en cuenta con las cuentas de msn que si le dimos en guardar los logs de las conversaciones que tengamos, skype  y el resto...

A tener en cuenta, de no dejar información suelta por dejar, no sea que estemos siendo vulnerados por nuestros propios errores :).


Leer Mas
Ahora es Navidad si  una vez al año donde nos reunimos en familia para compartir y demás SniferL4bs el blog les desea una bonita noche a todos que la pasen bien en compañía de sus seres queridos, pasen un excelente dia.. 





Mish, Noe, Uremix los chicos de la SCESI a todas las personas que conosco y no lo mismo va feliz dia.
Tami espero que leas esto :) feliz dia pa ti tambien amiga...
Kari Angel Enrique, feliz día chicos....

Y si quieren mas fondos y demás cosas linuxeras.. aqui...

Wallpapers Navideños Linuxeros

Leer Mas
Descubriendo y aprendiendo el dia de hoy venimos con esta entrada de manos de @Yoya el cual nos brinda una excelente entrada, para analizar y poder ver como trabaja Joomla.. sin  mas que decir  a leer.

Buscando un ejemplo de la estructura de los hash que genera joomla para agregarlo a la lista de hash que detecta la herramienta IHash. Opte por descargarme joomla y instalarlo (la versión 2.5.8 que es la que recomiendan) para verlo con mis propios ojos. Luego de instalarlo, cree un usuario directamente desde el panel de administración, llamado example con el password "example" para luego no olvidarme.

Ahora toca ver todas las tablas que contiene la base de datos donde instale joomla.

mysql> use joomla;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> show tables;
+-----------------------------+
| Tables_in_joomla            |
+-----------------------------+
| jom_assets                  |
| jom_associations            |
| jom_banner_clients          |
| jom_banner_tracks           |
| jom_banners                 |
| jom_categories              |
| jom_contact_details         |
| jom_content                 |
| jom_content_frontpage       |
| jom_content_rating          |
| jom_core_log_searches       |
| jom_extensions              |
| jom_finder_filters          |
| jom_finder_links            |
| jom_finder_links_terms0     |
| jom_finder_links_terms1     |
| jom_finder_links_terms2     |
| jom_finder_links_terms3     |
| jom_finder_links_terms4     |
| jom_finder_links_terms5     |
| jom_finder_links_terms6     |
| jom_finder_links_terms7     |
| jom_finder_links_terms8     |
| jom_finder_links_terms9     |
| jom_finder_links_termsa     |
| jom_finder_links_termsb     |
| jom_finder_links_termsc     |
| jom_finder_links_termsd     |
| jom_finder_links_termse     |
| jom_finder_links_termsf     |
| jom_finder_taxonomy         |
| jom_finder_taxonomy_map     |
| jom_finder_terms            |
| jom_finder_terms_common     |
| jom_finder_tokens           |
| jom_finder_tokens_aggregate |
| jom_finder_types            |
| jom_languages               |
| jom_menu                    |
| jom_menu_types              |
| jom_messages                |
| jom_messages_cfg            |
| jom_modules                 |
| jom_modules_menu            |
| jom_newsfeeds               |
| jom_overrider               |
| jom_redirect_links          |
| jom_schemas                 |
| jom_session                 |
| jom_template_styles         |
| jom_update_categories       |
| jom_update_sites            |
| jom_update_sites_extensions |
| jom_updates                 |
| jom_user_notes              |
| jom_user_profiles           |
| jom_user_usergroup_map      |
| jom_usergroups              |
| jom_users                   |
| jom_viewlevels              |
| jom_weblinks                |
+-----------------------------+
61 rows in set (0.00 sec)

Directamente me fije en la tabla jom_users. Supuse que hay es donde se guardan los datos que tienen que ver con el nombre de usuario y password. Ahora toca ver la estructura de la tabla jom_users para verificar los campos que tiene para realizar la próxima consulta SQL.

| id            | int(11)      | NO   | PRI | NULL                | auto_increment |
| name          | varchar(255) | NO   | MUL |                     |                |
| username      | varchar(150) | NO   | MUL |                     |                |
| email         | varchar(100) | NO   | MUL |                     |                |
| password      | varchar(100) | NO   |     |                     |                |
| usertype      | varchar(25)  | NO   | MUL |                     |                |
| block         | tinyint(4)   | NO   | MUL | 0                   |                |
| sendEmail     | tinyint(4)   | YES  |     | 0                   |                |
| registerDate  | datetime     | NO   |     | 0000-00-00 00:00:00 |                |
| lastvisitDate | datetime     | NO   |     | 0000-00-00 00:00:00 |                |
| activation    | varchar(100) | NO   |     |                     |                |
| params        | text         | NO   |     | NULL                |                |
| lastResetTime | datetime     | NO   |     | 0000-00-00 00:00:00 |                |
| resetCount    | int(11)      | NO   |     | 0                   |                |
+---------------+--------------+------+-----+---------------------+----------------+
14 rows in set (0.00 sec)

Directamente vi que los campos que me interesaban, era id, username (contiene el nombre de usuario para loguearse) y password (el campo mas importante, contiene el hash que genera joomla).


mysql> select id, username, password from jom_users;
+----+----------+-------------------------------------------------------------------+
| id | username | password                                                          |
+----+----------+-------------------------------------------------------------------+
| 73 | admin    | 07ac4817e34b93ee42e88ea0f0705e9a:3uQaeUYsbQf2F7aeehj75gYiuHARWpdJ |
| 74 | example  | edbea885d26f0557e748605c5a5707cd:NXhARsuArVRSZcs4U0lSDrpCDs0Le1Ch |
+----+----------+-------------------------------------------------------------------+
2 rows in set (0.00 sec)

Hay muestra los 2 usuarios, el primero que se crea cuando se instala joomla y el segundo usuario que cree directamente desde el panel de administración.

Hasta hay todo bien, había hecho todo lo que necesitaba pero me dio un poco de curiosidad ver como joomla genera los hash y también me servia para asegurarme de todo. Lo primero que hice fue buscar en google, ya que no quería leer el código de joomla para poder entender como generaba los hash joomla, mejor ver algún post de alguien que ya lo había leído .

Me encontré con este hilo: Using php to create a joomla user password

Pero vi que fue hace 2 años y no estaba seguro si joomla utilizaba el mismo método, así que me puse a revisar el source.

Indagando un poco, el método que generaba los hash era bind() que pertenecía a la clase JUser del archivo user.php que se encontraba en el directorio libraries/joomla/user.

user.php - metodo bind
public function bind(&$array)
        {
                // Let's check to see if the user is new or not
                if (empty($this->id))
                {
                        // Check the password and create the crypted password
                        if (empty($array['password']))
                        {
                                $array['password'] = JUserHelper::genRandomPassword();
                                $array['password2'] = $array['password'];
                        }
 
                        // TODO: Backend controller checks the password, frontend doesn't but should.
                        // Hence this code is required:
                        if (isset($array['password2']) && $array['password'] != $array['password2'])
                        {
                                $this->setError(JText::_('JLIB_USER_ERROR_PASSWORD_NOT_MATCH'));
                                return false;
                        }
 
                        $this->password_clear = JArrayHelper::getValue($array, 'password', '', 'string');
 
                        $salt = JUserHelper::genRandomPassword(32);
                        $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
                        $array['password'] = $crypt . ':' . $salt;
 
                        // Set the registration timestamp
 
                        $this->set('registerDate', JFactory::getDate()->toSql());
 
                        // Check that username is not greater than 150 characters
                        $username = $this->get('username');
                        if (strlen($username) > 150)
                        {
                                $username = substr($username, 0, 150);
                                $this->set('username', $username);
                        }
 
                        // Check that password is not greater than 100 characters
                        $password = $this->get('password');
                        if (strlen($password) > 100)
                        {
                                $password = substr($password, 0, 100);
                                $this->set('password', $password);
                        }
                }
                else
                {
                        // Updating an existing user
                        if (!empty($array['password']))
                        {
                                if ($array['password'] != $array['password2'])
                                {
                                        $this->setError(JText::_('JLIB_USER_ERROR_PASSWORD_NOT_MATCH'));
                                        return false;
                                }
 
                                $this->password_clear = JArrayHelper::getValue($array, 'password', '', 'string');
 
                                $salt = JUserHelper::genRandomPassword(32);
                                $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
                                $array['password'] = $crypt . ':' . $salt;
                        }
                        else
                        {
                                $array['password'] = $this->password;
                        }
                }
 
                // TODO: this will be deprecated as of the ACL implementation
                //              $db = JFactory::getDbo();
 
                if (array_key_exists('params', $array))
                {
                        $params = '';
 
                        $this->_params->loadArray($array['params']);
 
                        if (is_array($array['params']))
                        {
                                $params = (string) $this->_params;
                        }
                        else
                        {
                                $params = $array['params'];
                        }
 
                        $this->params = $params;
                }
 
                // Bind the array
                if (!$this->setProperties($array))
                {
                        $this->setError(JText::_('JLIB_USER_ERROR_BIND_ARRAY'));
                        return false;
                }
 
                // Make sure its an integer
                $this->id = (int) $this->id;
 
                return true;
        }

El método recibe como parámetro un array, pero si se fijan ponen al inicio el símbolo &. Eso indica que el array $array se pasa por referencia y por lo tanto los cambios que se hagan a la variable $array, dentro del metodo bind, afectara directamente al array que se le pase como parámetro al metodo bind(). El método bind retorna un booleano, si el usuario existe entonce retornaba un false, si era nuevo entonce un true (despues de haber generado el hash).

Nota: Argumentos de funciones, ejemplo #2

Bueno aquí las 3 lineas que mas me interesa del metodo bind(), van desde linea 660 hasta la 662:

$salt = JUserHelper::genRandomPassword(32);
                                $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
                                $array['password'] = $crypt . ':' . $salt;

Al final el array guardaba el hash de esta forma crypt:salt

En la primera linea, llama el método estático genRandomPassword() de la clase abstracta JUserHelper que pertenece al archivo helper.php en el directorio libraries/joomla/user. Al método se le pasa como parámetro el numero 32.

Aquí las primeras 3 lineas del método genRandomPassword(), que basta con las 3 primera mas el nombre de la función para darse cuenta cual es el propósito.

public static function genRandomPassword($length = 8)
        {
                $salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

El metodo retorna por defecto 8 caracteres al azar (a-z-A-Z0-9). Pero como se le pasa un 32 como parámetro, retornara 32 caracteres al alzar.

Eso quiere decir que la variable $salt contendrá 32 caracteres al azar. Ahora vamos a la segunda linea:


$salt = JUserHelper::genRandomPassword(32);
                                $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
                                $array['password'] = $crypt . ':' . $salt;

La variable $crypt almacena el valoro del resultado del método getCryptedPassword de la clase abstracta JUserHelper; se les pasa 2 parámetros al método getCryptedPassword que es el password (en texto plano) y los 32 caracteres generados de forma aleatoria. Aquí el método getCryptedPassword:

public static function getCryptedPassword($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)
        {
                // Get the salt to use.
                $salt = JUserHelper::getSalt($encryption, $salt, $plaintext);
 
                // Encrypt the password.
                switch ($encryption)
                {
                        case 'plain':
                                return $plaintext;
 
                        case 'sha':
                                $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext));
                                return ($show_encrypt) ? '{SHA}' . $encrypted : $encrypted;
 
                        case 'crypt':
                        case 'crypt-des':
                        case 'crypt-md5':
                        case 'crypt-blowfish':
                                return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt);
 
                        case 'md5-base64':
                                $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext));
                                return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
 
                        case 'ssha':
                                $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext . $salt) . $salt);
                                return ($show_encrypt) ? '{SSHA}' . $encrypted : $encrypted;
 
                        case 'smd5':
                                $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext . $salt) . $salt);
                                return ($show_encrypt) ? '{SMD5}' . $encrypted : $encrypted;
 
                        case 'aprmd5':
                                $length = strlen($plaintext);
                                $context = $plaintext . '$apr1$' . $salt;
                                $binary = JUserHelper::_bin(md5($plaintext . $salt . $plaintext));
 
                                for ($i = $length; $i > 0; $i -= 16)
                                {
                                        $context .= substr($binary, 0, ($i > 16 ? 16 : $i));
                                }
                                for ($i = $length; $i > 0; $i >>= 1)
                                {
                                        $context .= ($i & 1) ? chr(0) : $plaintext[0];
                                }
 
                                $binary = JUserHelper::_bin(md5($context));
 
                                for ($i = 0; $i < 1000; $i++)
                                {
                                        $new = ($i & 1) ? $plaintext : substr($binary, 0, 16);
                                        if ($i % 3)
                                        {
                                                $new .= $salt;
                                        }
                                        if ($i % 7)
                                        {
                                                $new .= $plaintext;
                                        }
                                        $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext;
                                        $binary = JUserHelper::_bin(md5($new));
                                }
 
                                $p = array();
                                for ($i = 0; $i < 5; $i++)
                                {
                                        $k = $i + 6;
                                        $j = $i + 12;
                                        if ($j == 16)
                                        {
                                                $j = 5;
                                        }
                                        $p[] = JUserHelper::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5);
                                }
 
                                return '$apr1$' . $salt . '$' . implode('', $p) . JUserHelper::_toAPRMD5(ord($binary[11]), 3);
 
                        case 'md5-hex':
                        default:
                                $encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext);
                                return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
                }
        }

Observando los parametros:

getCryptedPassword($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)

el primer parámetro, corresponde al password (en texto plano), el salt que por defecto esta vació pero recordar que se envían 32 caracteres aleatorio, por lo tanto en este caso la variable $salt contendrá los 32 caracteres aleatorios. El tercer parámetro por defecto contiene el valor de md5-hex y el cuarto un booleano establecido como false. Una linea importante es esta (la cuarta linea):

$salt = JUserHelper::getSalt($encryption, $salt, $plaintext);

Ya que le esta dando un nuevo valor a la variable $salt. Aquí el método getSalt():

public static function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '')
        {
                // Encrypt the password.
                switch ($encryption)
                {
                        case 'crypt':
                        case 'crypt-des':
                                if ($seed)
                                {
                                        return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2);
                                }
                                else
                                {
                                        return substr(md5(mt_rand()), 0, 2);
                                }
                                break;
 
                        case 'crypt-md5':
                                if ($seed)
                                {
                                        return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12);
                                }
                                else
                                {
                                        return '$1$' . substr(md5(mt_rand()), 0, 8) . '$';
                                }
                                break;
 
                        case 'crypt-blowfish':
                                if ($seed)
                                {
                                        return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16);
                                }
                                else
                                {
                                        return '$2$' . substr(md5(mt_rand()), 0, 12) . '$';
                                }
                                break;
 
                        case 'ssha':
                                if ($seed)
                                {
                                        return substr(preg_replace('|^{SSHA}|', '', $seed), -20);
                                }
                                else
                                {
                                        return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
                                }
                                break;
 
                        case 'smd5':
                                if ($seed)
                                {
                                        return substr(preg_replace('|^{SMD5}|', '', $seed), -16);
                                }
                                else
                                {
                                        return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
                                }
                                break;
 
                        case 'aprmd5': /* 64 characters that are valid for APRMD5 passwords. */
                                $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 
                                if ($seed)
                                {
                                        return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8);
                                }
                                else
                                {
                                        $salt = '';
                                        for ($i = 0; $i < 8; $i++)
                                        {
                                                $salt .= $APRMD5{rand(0, 63)};
                                        }
                                        return $salt;
                                }
                                break;
 
                        default:
                                $salt = '';
                                if ($seed)
                                {
                                        $salt = $seed;
                                }
                                return $salt;
                                break;
                }
        }

Al parámetro getSalt() se le pasa como parámetro la variable $encryption que por defecto contiene el valor de md5-hex. De ese primer parámetro depende el comportamiento del método getSalt(). Ya que en el método getSalt() utiliza un switch y dependiendo del valor que contenga $encryption se comportara de forma diferente. Por defecto como $encryption contiene md5-hex, se ejecutara el default: del swtich. Que simplemente retorna el salt sin ningún tipo de cambio. Por lo tanto en la linea:

$salt = JUserHelper::getSalt($encryption, $salt, $plaintext);

La variable $salt contendrá el mismo valor que antes. Bueno volviendo al metodo getCryptedPassword(), vemos que luego sigue un switch que evalúa la variable $encryption que dependiendo de esta se puede comportar de manera diferente. Recordando que la variable $encryption por defecto contiene el valor de md5-hex entonce vamos directamente a ese case

case 'md5-hex':
                        default:
                                $encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext);
                                return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;

Vemos que se utiliza el operador ternario para darle un nuevo valor a la variable $encrypted. Bueno si la variable salt contiene algún valor, entonce la variable $encrypted contendrá el valor del password+salt (32 caracteres alertorios) cifrado a MD5, sino la variable encrypted tendrá el valor del password cifrado en MD5. Luego, en la linea siguiente hay se retorna la variable $encrypted pero se utiliza el operador ternario para indicar 2 posibles casos. Si la variable $show_encrypt es verdadera, entonce retorna $encrypted pero le agrega al inicio la cadena {MD5} sino retorna simplemente el valor de $encrypted. Recordar que en el método getCryptedPassword() la variable $show_encrypt por defecto es false, por lo tanto en este caso retornara simplemente el valor de $encrypted. Ahora vamos a la ultima linea:

$salt = JUserHelper::genRandomPassword(32);
                                $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
                                $array['password'] = $crypt . ':' . $salt;

Que simplemente contiene el valor de la variable $crypt el signo de : y luego el salt. Que es la estructura en que joomla guarda los hash que genera.

mysql> select id, username, password from jom_users;
+----+----------+-------------------------------------------------------------------+
| id | username | password                                                          |
+----+----------+-------------------------------------------------------------------+
| 73 | admin    | 07ac4817e34b93ee42e88ea0f0705e9a:3uQaeUYsbQf2F7aeehj75gYiuHARWpdJ |
| 74 | example  | edbea885d26f0557e748605c5a5707cd:NXhARsuArVRSZcs4U0lSDrpCDs0Le1Ch |
+----+----------+-------------------------------------------------------------------+
2 rows in set (0.00 sec)

Ahora por lo tanto, es simple hacer un pequeño PoC (prueba de concepto).

 ".$hash."\n\n";
echo "Salt                    -> ".$salt."\n";
echo "password encriptado     -> ".$estructura[0]."\n";
echo "[*]md5(password+salt)   -> ".md5($password.$salt)."\n";
 
?>
yoya@OpenSUSE:~/www/public$ php a.php
[+]Hash                    -> edbea885d26f0557e748605c5a5707cd:NXhARsuArVRSZcs4U0lSDrpCDs0Le1Ch
 
Salt                    -> NXhARsuArVRSZcs4U0lSDrpCDs0Le1Ch
password encryptado     -> edbea885d26f0557e748605c5a5707cd
[*]md5(password+salt)   -> edbea885d26f0557e748605c5a5707cd
yoya@OpenSUSE:~/www/public$ 


Autor del Documento Yoya
Blog
Leer Mas

Buenas esta semana que paso anduve un poco ocupado llegando a casa directo a dormir cansancio, y a la vez sin tiempo por el trabajo que esta semana ya comenze :) para lo cual  ando aprendiendo bastantes cosas tal vez algunas las vaya  posteando especificamente algunos detalles especiales o que me llamen la atención, el martes instale en la pc del trabajo Sabayon X.

Esta semana conocí dos nuevas gemas de ruby pero las cuales me obligaban a que tenga instalado la ultima versión :(  asi que pedi ayuda a Sergio para que me pueda indicar alguna solución a ello así que el me presento a RVM.

¿RVM que es?

RVM o Ruby Version Manager, es un sistema de gestión de versiones para Ruby. 

Es decir una gema de ruby como la imagen que lleva dentro otras versiones mas, xD daa yo y mis explicaciones si que no van me voy a lo correcto con RVM podremos tener varias versiones de ruby instaladas en el sistema pudiendo swichear entre ellas.

Instalación de  RVM

Primero para instalarlo hacemos lo siguiente

Instalar RVM:

$ \curl -L https://get.rvm.io | bash -s stable --ruby

Instalar una versión de ruby:

$ rvm install 1.9.3


Para saber mas sobre RVM accede aquí

Instalando Ruby

Podemos instalar cualquier versión de Ruby mediante RVM, para ver las opciones que nos brinda escribimos:

$ rvm list known

Una vez decidida la version que queremos instalar usamos rvm install 1.9.3, en este caso para instalar Ruby 1.9.3.

Instalando gemas

Ahora si este es el motivo principal por el cual tuve que hacer uso de RVM ya que algunas gemas no pueden correctamente entre una versión y otra de ruby, para este proposito RVM nos permite crear gemset  que son ???

Bueno al crear un gemset lo que hacemos es crear una virtual, por así decirlo de un conjunto de gemas especificamente para una versión de Ruby

Para crear un gemset escribimos

$ rvm gemset create [NombreGemas]

 indicamos a RVM que queremos usar ese conjunto con:

rvm gemset use nombreGema

Ahora ya podemos instalar gemas que quedarán recogidas enjaulados en esta virtual conjunto como lo llamemos.

rvm gemset create compass
rvm gemset use compass
gem install compass

Ahora si aqui viene algo que recien me di cuenta el dia de ayer al instalar rails y note algunas gemas que andaban siendo compartidas revisando el dia ayer sabado encontre con este tip por asi decirlo el cual nos dice que podemos crear un gemset llamado global cuyas gemas serán incluidas cuando uses cualquier otro conjunto de los mismos, seria como compartirlas.

rvm gemset create global
rvm gemset use global
gem install rails

Ahora que sucede si cargamos a montones gemsets como enfermos o ya no nos sirve para ello tenemos lo siguiente.

rvm delete mygemset #para borrar el gemset
rvm clean mygemset #para borrar las gemas del gemset

Ahora no quiero ya usar ningun Ruby que instale si no trabajar con el del sistema hacemos lo siguiente.

$ rvm system

Si notan es un forma ordenada de trabajar con ruby y asi poder meter lo que queramos para nuestras pruebas locas que seguro tenemos mas de una ;).
Leer Mas
Bueno , no hace mucho publiqué una introducción sobre MongoDB con sus características , primeros pasos y demas.
Bien , pues hoy trataré sobre un tema que a muchos Pythoneros como yo les interesa.

MongoDB cuenta con unos drivers que soportan una gran variedad de lenguajes :
  • C
  • C++
  • Erlang
  • Haskell
  • Java (and other JVM languages)
  • Javascript
  • .NET (C#, F#, PowerShell, ...)
  • Node.js
  • Perl
  • PHP
  • Python
  • Ruby
  • Scala
Para más información sobre los drivers : MongoDB Drivers

Uno de los más recomendados a la hora de tratar con MongoDB desde python es "Pymongo".

Primero debemos instalar la libreria pymongo , en mi caso uso mint asi que :
sudo apt-get install pymongo

Jugaremos con  los mismos comandos con pymongo que realizamos en la introducción a MongoDB :

- Conectaremos con la BD
- Veremos las BD's que tenemos creadas
- Veremos las colecciones que tenemos ya creadas
- Crearemos una nueva BD
- Crearemos  una nueva colección
- Insertaremos nuevos documentos
- Actualizaremos documentos
- Buscaremos documentos
- Borraremos documentos con remove y con drop

Y como petición especial (me enviarón la duda por MP) y ya que al parecer no puede esperar al próximo tutorial de MongoDB :

- Borraremos bases de datos

Bueno comenzemos importando pymongo :
from pymongo import Connection

Creamos la conexión con la BD :
conex = Connection('localhost') 

Ahí veís puse localhost por defecto porque la BD esta en nuestra PC y pymongo nos conecta con ella si le indicamos local pero ahi deberían de indicar el sitio de la BD y el puerto al que se conecta.

Bueno veamos las BD's que ya hay creadas :
conex.database_names()

Ahora creemos una BD nueva :
db = conex.nombredb

Creamos una nueva colección :
collect = db.coleccionnueva

Veamos que colecciones tenemos creadas :
db.collection_names()

Insertemos un documento :
collect.insert({"name":"sanko","twitter":"sankoSK"})

Actualizamos documentos con update():
collect.update()

Vamos a realizar una busqueda de documentos :
collect.find()

Borremos documentos con remove():
collect.remove()

Vaciamos la colección (borramos todos los documentos) con drop():
collect.drop()

Y ahora la petición especial , borrar bases de datos...

Aquí me explicaré un poquito más puesto que este comando es nuevo(No lo dimos en el post introductorio a MongoDB).

En MongoDB borrariamos la BD de la siguiente manera:
-Accedemos a la database
-Nos borramos
use nuestrabd
db.dropDatabase()

Una vez aclarado esto , veamos como borrariamos la bd en pymongo:
conex.drop_database('nombredatabase')

Bueno , ahora pongamos esto en práctica creando un código SIMPLE, no nos vamos a matar creando un super manager para un tutorial... xd

Algo así :

# Probaremos los codes , asi que los pondremos todos
# Coded by Sanko
# Haremos lo siguiente :
#  -Conectaremos con la BD
#  -Veremos las BD's que tenemos creadas
#  -Veremos las colecciones que ya tenemos creadas
#  -Crearemos una nueva BD
#  -Crearemos una nueva coleccion
#  -Insertaremos nuevos documentos
#  -Actualizaremos documentos
#  -Borraremos documentos con remove y drop

# Simple MongoDB-Manager using pymongo - Sanko

from pymongo import Connection

def mongomanager():

 conex = Connection('localhost')

 def databases():
  print "Control de BD's , Que deseas hacer?"
  entrada = raw_input("- [1]Visualizar BD's | [2]Crear BD's | [3]Borrar BD's | [4]Home -> ")
  if entrada == '1':
   var = conex.database_names()
   print var
   databases()
  elif entrada == '2':
   name = raw_input("Nombre de la BD que quieres crear -> ")
   global db 
   db = conex.name
   databases()
  elif entrada == '3':
   delname = raw_input("Nombre de la BD que quieres eliminar -> ")
   conex.drop_database(delname)
   databases()
  elif entrada == '4':
   mongomanager()
  else:
   print "Error\n"
   mongomanager()

 def collections():
  print "Control de Colecciones , que deseas hacer?"
  entrada = raw_input("- [1]Visualizar colecciones | [2]Crear coleccion | [3]Home -> ")
  if entrada == '1':
   var = db.collection_names()
   print var
   collections()
  elif entrada == '2':
   global collectname 
   collectname = raw_input("Nombre de la coleccion que quieres crear -> ")
   collect = db.collectname
   collections()
  elif entrada == '3':
   mongomanager()
  else:
   print "error\n"
   mongomanager()

 def documents():
  print "Control de Documentos , que deseas hacer?"
  entrada = raw_input("[1]Crear documento | [2]Busqueda de documentos | [3]Eliminar documento | [4]Home -> ")
  if entrada == '1':
   #Escriba el contenido de esta manera "name":"sanko" por ejemplo.
   document = raw_input("Escriba el contenido del doc => ")
   collectname.insert({"name":"sankito"})
   documents()
  elif entrada == '2':
   content = raw_input("Parametros del contenido -> ")
   var = collectname.find(content)
   print var
   documents()
  elif entrada == '3':
   choosedel = raw_input("Desea vaciar el documento(1) o borrar algo especifico(2) -> ")
   if choosedel == '1':
    collectname.drop()
    documents()
   elif choosedel == '2':
    delcontent = raw_input("Parametros del borrado -> ")
    collectname.remove(delcontent)
    documents()
   else:
    print "error\n"
    documents()
  else:
   print "error\n"
   mongomanager()

 entrada = raw_input("PyMongo Manager => Exit(0) | Control BD's(1) | Control Colecciones(2) | Control de Documentos(3) -> ")
 if entrada == '0':
  exit
 elif entrada == '1':
  databases()
 elif entrada == '2':
  collections()
 elif entrada == '3':
  documents()
 else:
  print "Error\n"
  mongomanager()

mongomanager() 

Una imagen del rápido testeo :



Para los vagos aca les dejo el code en Pastebin

El code esta creado muy rápidamente por eso tiene unos patrones muy rígidos a vuestra imaginación queda quitar lla necesidad de definir unas variables antes de crear el documento y demas cosas , eso ya se tiene que hacer pensando como sería más cómodo y dedicandole un buen rato.

Espero os sirviera este articulo , como siempre UN ABRAZO.
Saludos , Sanko
Leer Mas
Buenas! , en esta ocasión vengo a traerles una presentación.odp sobre Analisis de Metadatos con FOCA y como burlar FOCA.

Me toco realizar una charla sobre Analisis de Metadatos y use esta presentación como guia para realizar una demostración en directo sobre "Ataque y Defensa".

La presentación esta hecha a prueba de Kiddies por lo qué cualquiera pueda aprender.
Esta se hizo con la intención de hacerme de GUIA mientras iva explicando y haciendo las cosas por lo que su explicación sobre el uso de FOCA no es muy extensa pero servirá para aprender lo básico o para aquel que quiera realizar una charla sobre lo mismo pueda tomarla como guia para la suya.





Espero que os sirva , un abrazo.
Sanko.
Leer Mas
Buenas , no hace mucho me hicierón una propuesta para trabajar como backend y requerian de conocimientos en bases de datos NoSQL, así que como buen autodidacta me puse a googlear y me encontre con la MySQL de las bases de datos no relacionales.

Esta se llamaba MongoDB y con tan solo leer sus características me dejo totalmente enamorado.

Índice :

    {1} Introducción:
        1-¿Qué es MongoDB?
        2-Características
        3-Instalando MongoDB y Primeros pasos

{1}.1 : ¿Qué es MongoDB?


A estas alturas y con esa introducción todos los que desconoceís de MongoDB os estareís preguntando

-¿Qué es MongoDB?- , ahora aclararé todo.

MongoDB es una base de datos relativamente "nueva", esta se orienta a documentos...

-¿Como a documentos?- , para poder trabajar cómodamente sobre mongoDB debemos de olvidarnos de la lógica relacional que MySQL nos implemento , así que realizaré una comparativa para que os quedeís con los términos básicos.

Términos SQL - Términos MongoDB  :


  • Database - Database
  • Tabla - Colección
  • Fila - Documento(BSON)
  • columna - campo
  • index - index


Con esto ya tendremos una comparativa bastante clara y podemos proseguir con "¿Qué es MongoDB?".
MongoDB fue programada en C++ de código abierto y fué pensada para ser rápida , escalable y sencilla.
Es muy importante destacar que MongoDB ofrece un mayor rendimiento que CouchDB(otra BD NoSQL) e incluso que MySQL.


¿Para qué podemos usar MongoDB?

Puesto que MongoDB no usa digamos los "estándares" de bases de datos no es muy recomendable usarla para aplicaciones bancarias pero cuando tienes que almacenar grandes cantidades de datos como por ejemplo un blog si sería ideal. 

Tambien mucha gente recomienda crear híbridos en los que uses una BD Relacional para las transacciones y una no relacional como MongoDB para guardar datos,documentos.

{1}.2 : Características de MongoDB :
   
Bueno vamos a ver un poco por encima las características de MongoDB :


  • Ausencia de transacciones
  • Utiliza Almacenamiento Orientado a documentos (BSON)
  • Soporte a Querys dinámicas
  • Indexación de Documentos
  • Indices Geoespaciales
  • Analisis de Rendimiento de Queries
  • Actualización de la información “in-Place”
  • GridFS
  • Replicación de Datos
  • Implementación de Auto Sharding
  • Utilización de Funciones  Map/reduce


Ausencia de transacciones

Se tiene en cuenta como desventaja pero es por esto por lo que MongoDB puede ser más rápida y escalable.

Utiliza Almacenamiento Orientado a documentos (BSON) 

BSON(Binary-JSON) es una excelente forma de intercambio de información y de almacenaje. MongoDB almacena todo en un mismo documento y gracias a json el cual describe el contenido del documento no existe la necesidad de crear estructuras ni de esquematizar.

Aparte de las funcionalidades que posee JSON agrega otras como la habilidad de manejar datos binarios, permitiendoles ser sumamente rápida en la búsqueda, indexación, almacenamiento y recuperación de la información, ya que BSON es fácil y rápidamente transformable en cualquier tipo de dato nativo de cualquier lenguaje de programación.

Soporte a Querys dinámicas

MongoDB acepta la ejecución de queries dinámicas, es decir , se pueden ejecutar consultas sin haberlas definido antes como pasa en CouchDB.

Indexación de Documentos

A la hora de insertar documentos a una colección se indexan con una clave/prefijo (_id) que proporciona al documento la capacidad de ser único, esta _id se puede definir a la hroa de insertar pero si no se define el propio mongo te pondrá una por defecto.

Indices Geoespaciales


Esto permite por indexar información basandonos en geo/localización lo que es muy útil a la hora de elaborar aplicaciones para este area.

Analisis de Rendimiento de Queries

MongoDB nos acerca una herramienta para analizar consultas, desde luego muy útil para analizar defectos o mejorarlas.

Actualización de la información “in-Place”

MongoDB puede actualizarse donde quiera que sucedan los cambios ya que realiza la escritura de la información en la memoría y retrasa la escritura en disco lo más posible (esto puede ser una desventaja) pero esto le proporciona su velocidad.

GridFS

Como ya comentamos mongo utiliza BSON para el almacenaje de datos binarios y su limite esta en 4MB de datos binarios en un mismo documento.

Para eso si necesitamos espacios adicionales para audios , videos , imagenes mongoDB nos acerca un sistema de almacenaje de metadatos, GridFS.

Este permite almacenar información del archivo en una coleccion de archivos.
Esto se divide en minimas partes(chunks) que se almacenan en una coleccion de chunks y permite que sea mas sencillo manejar y escalar.

Replicación de Datos

MongoDB tiene un mecanísmo llamado "replicación maestro-esclavo".
Este mecanismo es sencillo de entender , todas las peticiones de escritura se realizan en la BD maestra quien las "copia" en su réplica(esclavo) y así tenemos alternativa si la maestro falla porque la esclava ocupa su sitio.

Implementación de Auto Sharding

Esta es la característica más útilizada porque esta busca que se encarga del manejo de la data y de que esta vaya al servidor correcto para que las queries se ejecuten de la forma más eficiente.

Funciones  Map/reduce


  • Son las funciones más poderosas en cuanto a consultoría de data se refiere.
  • Estan en JS(JavaScript) y se ejecutan en el servidor.
  • Hay que dejar claro que mongoDB tiene una shell js para el manejo de BD's y en ella podemos trabajar con código js que nos permite explotar todo su potencial.
  • (Bucles para insertar documentos etc etc...)


La función MAP se encarga de encontrar documentos que cumplen X condición/criterio , despues la funcion REDUCE se encarga de procesar esa información y nos retorna un documento con la información "peticionada"/"encargada".


{1}.3 : Instalando MongoDB

Es de lógica que si vamos a ver como instalar MongoDB primero habrá que descargarlo ¿No?.

Para esto acudimos a su website oficial ->Mongodb.org

Ahí podeís elejir para que OS y estas cositas , en mi caso Linux 32-bit


O tambien podemos hacerlo desde nuestra terminal :

sudo apt-get install mongodb



Para comprobar si todo quedo bien abrimos nuestra terminal y escribimos :


Se nos conecta a una bd por defecto "test" , vamos a crear nuestra propia database:
use nombredb




Podemos ver que databases tenemos creadas con :
show dbs


Aclaración : 

La base de datos no se guardará hasta que no guardemos algo dentro...
esto quiere decir que si la creo "use namedb" y luego me salgo de la shell la db no aparecera como creada.

Ok , creemos una colección para nuestra database e insertaremos un documento :

db.nombrecoleccion #asi creamos la coleccion
db.nombrecoleccion.insert({"name":"sanko","twitter":"sankoSK"})


Podemos ver que colecciones tenemos creadas con :

show collections


Ahora usaremos .find() para comprobar que se creo el documento :

db.nombrecoleccion.find()




ahí vemos que nos creo el documento y lo pudimos buscar con .find() que daría un busqueda a todos entre los () podemos dar argumentos

Vamos a crear otro documento con una estructura totalmente diferente para probar la eficiencie de find() para pedirle una busqueda más especifica:

db.nombrecoleccion.insert({"color":"azul","material":"metal"})

db.nombrecoleccion.find({"color":"azul"})



Ahi comprobamos que nos muestra solo lo que nosotros queremos buscar , es decir , datos que contengan "color":"azul" , si no , no muestra nada.

Existe otro método , para mi un poco inútil la verdad pero es otro , xd , este muestra solo la primera fila del doc.

db.nombrecoleccion.findOne()


Bueno pasemos a el método count() , este si es más útil ya que nos dice el número de los que tenemos almacenados :

db.nombrecoleccion.count()




supongamos que queremos actualizar datos y para esto tenemos a nuestro querido update()
db.nombrecoleccion.update({"name":"sanko"}, {$set:{"other":"fuckthishit"}})




Como podeís observar en la imagen gracias a $set actualizamos el documento COLOCANDO "other":"fuckthishit" despues de "name":"sanko"

Ahora tocaremos sobre los métodos remove y drop  , es de suponer que algo tiene que ver con eliminar... xd, el método remove nos servira para eliminar filas en los documentos , aqui un ejemplo :

db.nombrecoleccion.remove()


Esto lo que hará será borrar todas las filas del documento dejando este vacío:


pero tambien podemos usar a remove() con parametros para borrar algo de manera concreta :
db.nombrecoleccion.insert({"name":"sanko"})

db.nombrecoleccion.insert({"color":"rojo"})

db.nombrecoleccion.remove({"color":"rojo"})



ahí podeís ver que nos borro lo que le pedimos.

Bueno y por último en esta "introducción" a mongoDB daremos el método drop qué es como el remove PERO drop no tiene la opción de poder borrar datos especificos , si no que te vacia el documento y ya.

db.nombrecoleccion.drop()


Espero que vuestra opinión acerca de esta database sea buena y qué más que decir que el próximo articulo sobre mongodb será algo más "profundo" , veremos más métodos , de autentificación, y demas

Saludos , Sanko.

Leer Mas