Skip to main content

TestWeb, un queso gruyer de vulnerabilidades

Esta idea viene de un_post_en_HackXCrack en el que se buscaba el codigo de una pagina web con vulnerabilidades para hacer pruebas y a falta de una ya escrita, programe una web pequeña.

Tiene un poco de todo: SQL inyection, XSS y todo lo que se me ocurrio =)

Aqui teneis el zip (TestWeb.zip)

Usa una base de datos MySQL, los datos se pueden configurar en el archivo dbdata.php

ps: como ya comente en el post de HackXCrack, si vas a permitir a cualquiera entrar, mejor que pongas la variable $allowUpload en False, ( $allowUpload=False; ) (esta en el archivo _change_avatar.php ) sino se podria causar un DoS..., y de paso asegurate que los archivos estén en un chroot (las distros basadas en Debian lo hacen por defecto)... yo aviso

Hasta otra!

ps2: La tercera parte de Introduccion a la criptografia esta en camino ;)

Bajando OGG's de Jamendo

[Actualizacion]

Para quien no lo sepa, Jamendo ofrece la opcion de descargar musica en OGG, pero solo por Bittorrent, y... seamos sinceros, el 90% de las descargas  no tienen ya seeds, asi que hay que recurrir a la descarga directa y al MP3.

Como esta no es forma de ayudar a la musica libre, con formatos no libres, escribi un pequeño (muuuy pequeño) script de Greasemonkey que permite hacer la descarga directa en OGG, si quereis descargarlo, esta [aqui]... o el codigo:

// ==UserScript== // @name           Jamendo OGG Redirector // @namespace      www.jamendo.com // @description    Redirects Jamendo MP3 download to OGG ones // @include        http://www.jamendo.com/*/download/ // ==/UserScript==

// http://www.jamendo.com/LANGUAGE/download/album/ALBUM_NUMBER/do //   | //   |  to //   v // http://www.jamendo.com/get/album/id/album/archiverestricted/redirect/ ALBUM_NUMBER/?p2pnet=bittorrent&are=ogg3

var url=location.href;

var slices=url.split('/');

if (slices[slices.length-1]=="do"){

var newUrl="http://www.jamendo.com/get/album/id/album/archiverestricted/ redirect/"+slices[slices.length-2]+"/?p2pnet=bittorrent&are=ogg3";

location.href=newUrl; }

Y ya esta, vais a la pagina de las descargas, hasta donde pone que esperemos mientras se prepara la descarga (si, tambien esta la opcion de usar la descarga en MP3), se descargara el ZIP con el album en OGG.

Hasta otra!

Música en HTML5

Actualmente si alguien va a hacer un reproductor de audio o de video, en lo unico que se piensa es en Flash, pero HTML5 tambien permite hacerlo... sin necesidad de un formato que consume muchos recursos y que suele funcionar mal si no se visualiza con software privativo.

HTML5, la nueva version (aun experimental, pero soportada por la mayoria de los navegadores) del lenguaje HTML, añade tags como "audio" o "video", de esta forma, como antes se hacian presentaciones de imagenes mezclando Javascript y HTML, ahora se puede hacer un reproductor completo.

Nota: al menos Firefox no soporta MP3, dado que esta patentado, la mejor alternativa (incluso mejor que MP3) es OGG, totalmente libre.

Nota[2]: ningun musico fue "pirateado"  en el proceso de escritura de este post, podeis encontrar musica libre en sitios como Jamendo

Ahora si, HTML5...

La etiqueta que se usa es:

(Lo que esta entre '[' y ']' es opcional) El texto solo se muestra si no se soporta la etiqueta audio ,seria algo asi como la etiqueta noscript

El significado de los atributos es: src: ruta al archivo (como con la etiqueta img) controls: se mostraran los controles: boton de reproducir, una barra de progreso.. autoplay: empezara a reproducirse tan pronto como pueda preload: se empezara a cargar el audio cuando se carge la pagina (se ignora si se utiliza autoplay)

Entonces, con un codigo minimo:

Reproductor HTML5

Obtenemos esto:

No esta mal, eh? y eso usando solo HTML, el navegador hace todo el trabajo,añadiendo algo de Javascript se pueden hacer cosas como listas de reproduccion...

Reproductor HTML5



[Referencias] Audio_-MDC Media_formats_supported_by_the_audio_and_video_elements-MDC Using_audio_and_video_in_Firefox-_MDC Introduction_to_the_HTML5_audio_tag_javascript_manipulation

Probando el Go de Google

Pues leyendo la linux_magazine de este mes (donde me también di por primera vez con scratch) me encontré con un articulo sobre el lenguaje Go_de_Google y me entraron ganas de probarlo, la experiencia es bastante curiosa.

En cuanto a la instalación, usar el binario del proyecto no es especialmente difícil para lo que podría ser, lo bajas del repo, y lanzas un script que lo compila, aquí_están_las_instrucciones. Pero si piensas usar el frontend_de gcc (no veo para que) te auguro un par de dolores de cabeza...

Con este lenguaje de programación, el obligado "hola mundo" quedaría así:

===============================================================================

package main

import "fmt"

func main(){     fmt.Println("Hola, mundo!") }

===============================================================================

Antes ejecutarlo hay que compilarlo y enlazarlo (para 386, 8g ; 8l ).

De primeras se puede ver que los archivos se clasifican en paquetes (para facilitar la importación, supongo), que en vez de #incluir cosas, se importan como lo haría python (siempre y cuando sea solo un módulo, después veremos como hacer con varios), y que no hace falta poner ';' cuando se presuponen (si se sigue el estilo de programación de Go ).

El hola mundo ocupa un mega (frente a los 7 Kb de C), lanzar un "strip -s" no ayuda, hace que su tamaño aumente 200Kb más y provoca que dé un fallo de segmentación ¿?.

Como prueba para ver como es un programa algo más grande, aquí hay un código que descarga un archivo de un servidor FTP [ftp.go], el uso es:

===============================================================================

Uso: ./8.out [[:]@][:]/

===============================================================================

Lo de 8.out es el nombre que le da por defecto el enlazador de Go.

Pero me estoy desviando del tema... esto es lo más destacable con lo que me encotré:

Para importar varias cosas, se hace

===============================================================================

import(     "fmt" / Entrada / Salida /     "net" / Sockets /     "os" / Archivos, errores ... /     "strings" / Manejo de strings /     "strconv" / Conversiones de strings / )

===============================================================================

Que es ciertamente más claro que un bloque de #includes en C.

La cabecera de las funciones recuerda ligeramente a Pascal, empezando la línea con "func", después el nombre de la funcion, los argumentos (variable y tipo en el mismo orden que pascal y inverso a C), y después el tipo que se devolverá , si hay alguno (pueden ser varios)

===============================================================================

func readline (sock *net.TCPConn) (s string){

===============================================================================

Llama la atención que se pueda predefinir una variable a devolver, que no se tendrá que especificar en el return (aquí sería "s")

Otra cosa curiosa tiene que ver con la declaración de variables y su asignación, las variables se pueden declarar a la vez que se crean, sin necesidad de especificar su tipo, esto se hace con el operador := (que también recuerda a la asignación de Pascal), pero al definir el valor de una variable ya declarada se usaría = (el símbolo de asignación de C)

===============================================================================

line := "" for {     line = readline(sock)

===============================================================================

Ya que no lo encontré mencionado en ninguna parte aviso, si una funcion devuelve varias variables y no quieres recojer una, subtituye lo que habría en esa posición por un "_"

===============================================================================

_, e := sock.Read(readData)

===============================================================================

El while ya no existe, su lugar lo toma for ¡!.

En las funciones predefinidas, la primera letra es mayúscula, esto es porque lo que comienza por mayúsculas es exportado por defecto.

===============================================================================

fmt.Println("Hecho")

===============================================================================

El puesto del NULL de C lo ocupa el nil de Pascal.

===============================================================================

if (e != nil){

===============================================================================

La lectura de un Stream (un chan en Go), es muy sencilla

===============================================================================

<-quit

===============================================================================

La escritura también, por supuesto

===============================================================================

quit <- 1

===============================================================================

La concurrecia sigue el mismo camíno, solo hay que añadir "go" antes de la función que sera ejecutada en paralelo

===============================================================================

go download_file(sock, filepath, naddr, quit)

===============================================================================

Y no se me ocurre nada más. En resumen, aunque al principio el lenguaje pareciera que tenía caprichos de diseño y que algunas cosas se hicieron como se hicieron por hacerlo diferente, al final todo encaja dando lugar a un lenguaje fácil de leer y de programar en cuanto se comprende.

No puedo acabar esto sin decir que me temo que al menos hasta hace poco, Go no era del todo estable como lenguaje, me encontré con cosas escritas no hace mucho (unos meses) que ya no compilaban por cambios en el lenguaje.

Nos vemos. [Referencias] http://golang.org/ http://golang.org/doc/effective_go.html http://swehack.se/0417/goroutines-och-tcp-programmering-i-golang https://groups.google.com/group/golang-nuts/

Portando LOIC a Gnu/Linux

Empezando por el principio, Anonymous_está_atacando_a_los_lobbies_del copyright, la noticia no es nueva, ya_llevan_un_rato_así, y me entero de que aún_estan_portando_LOIC (el_DOSer_que_utiliza_esta_comunidad) a Gnu/Linux. Portarlo es trivial, usaré MonoDevelop porque lo hace más facil y apenas ocupa 20 Megas, sino solo hay que editar el código a mano, cosa más que fácil.

Una descargado y descomprimido el_código_fuente, se abre el proyecto (el .sln) y se intenta "construir" (F8), el error que salta es este:

Obviamente, lo que pasa es que la ruta está escrita para Windows, usa \ como separador, y el nombre de la imágen está en minúsculas (en realidad es WTF.jpg) y Gnu/Linux es case-sensitive:

Se arregla...

Se construye, y ya está =)

My 2 cents.

Script para saber etiqueta de un dispositivo FAT

El aburrimiento de pasar unas horas en el tren sin conexión hace estragos, y para muestra un botón script, indícale al script un dispositivo FAT (vas a necesitar permisos de root) y dirá el nombre: ===============================================================================

!/usr/bin/env python

-- coding: utf-8 --

import sys try:     f = open(sys.argv[1], "rb") except:     print >>sys.stderr, "Uso:", sys.argv[0]," "     exit(1) f.seek(38) # Indica el tipo de particion FAT (12/16/32) sig = ord(f.read(1)) if (sig == 0x28) or (sig == 0x29) :     init = 43 else:     init = 71 f.seek(init) # Posicion del nombre FAT print f.read(11).strip() # Tamaño del nombre en FAT                         

El strip es porque se rellena con espacios

=============================================================================== Esos es todo, hasta otra

Eso pasa por no leer

La historia viene de atrás, intentando programar el módulo de la siguiente parte de Introducción a la criptografía, me di de frente con una parte del algoritmo en cuestion  (DSA), que dice así
Toma un primo p de una longitud dada (muy grande, para entendernos),
y otro q, de 160 que sea divisor de p-1 Y ahí se armó el follon. Dejando a un script que buscase al tan ansiado q durante un tiempo no produjo resultados, ya es pesado de por si buscar primos de 160 bits cuanto más comprobar si son divisibles por, otro de como mínimo 512 bits... y no, 2 no vale, porque el otro divisor sería de 511 bits ;).

Siendo la epoca en la que fue, con poco tiempo, no me preocupe mucho de esto, pero puse un script a buscar ese número y que de paso hiciera una lista de todos los números primos que se fuera encontrando. El script, después de 3 dias funcionando y más de millon y medio de números primos no dio con q , pero resulta que el propio FIPS 186 (la "especificación" de DSA) dice en el Apéndice 2 como obtener este par de números (p y q), tanto tiempo de CPU en vano... ¿o no?

La lista de primos en forma de módulo de python (está en la variable dumplist) se puede descargar aquí [dumped.py], no se que uso se le puede dar pero al fin y al cabo son millon y medio de primos a partir de 2^159 y hay gente con mucha imaginación :)

ps: La primera vez tarda un poco en importar, pero en cuanto hace el .pyc funciona relativamente rápido ps2: Ahora que lo pienso... ¿este será el módulo de python más pesado?

Y eso es todo por hoy... [Referencias] FIPS_186

Números pseudo-aleatorios con Pascal

La generación de números pseudo-aleatorios es una característica que la mayoría de lenguajes de programación implementa por defecto, pero Pascal estándar extendido es una excepción (el FreePascal no, ojo).

Esta historia viene porque hace tiempo necesitaba generar estos números para un programa en Pascal, y al no encontrar nada (aunque bueno... tampoco busqué mucho :P ) programé  algo. No es gran cosa, si se conocen los dos números anteriores y el momento en el que se inició el generador (con una precisión de microsegundos) se puede intentar descubrir cual será el siguiente, pero sirve para algo básico.

Para usarlo solo hay que importarlo y llamar a la función random usando el número "tope" como parámetro, por ejemplo, para generar un número del 0 al 100 (ambos incluidos):

=============================================================================== aleatorio := random(100); ===============================================================================

El código es este, se basa en el cifrado ARC4 (a.k.a RC4), y para descargar [random.pas]

=============================================================================== module mod_random;

{ Copyright (C) Kenkeiras 2010

This program is free software: you can redistribute it and/or modify     it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or     (at your option) any later version.

This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the     GNU General Public License for more details.

You should have received a copy of the GNU General Public License     along with this program. If not, see http://www.gnu.org/licenses/.

Modulo de numeros aleatorios

Contiene las funciones para generar numeros aleatorios

- random

}

export mod_random=(random);

function random(top:integer):integer; type     tbyte=0..255;

var     S: array [0..255] of tbyte;     i,j: integer;

end;

{ procedure swap (var c1:tbyte;var c2:tbyte);     Intercambia dos bytes } procedure swap (var a,b:tbyte);

var      temp:tbyte;     begin      temp:=b;      b:=a;      a:=temp;     end;

{ procedure random_seed;

Inicia la caja para generar los numeros pseudo-aleatorios

} procedure random_seed;     var         t:timeStamp;         str:string(255);         n:integer;

begin         getTimeStamp(t);         str:=time(t);

for n:=0 to 255 do             S[n]:=n;

j:=0;         for n:=0 to 255 do begin             j:=(j+S[n]+ord(str[(n mod length(str))+1]))mod 256;             swap(S[n],S[j]);         end;

i:=0;         j:=0; end;

{ function random_byte:tbyte;

Precondicion: La caja esta iniciada     Devuelve un byte pseudo-aleatorio

} function random_byte:tbyte;     begin         i:=(i+1)mod 256;         j:=(j+S[i])mod 256;

swap(S[i],S[j]);         random_byte:= S[(S[i]+S[j])mod 256];     end;

{ function random(top:integer):integer;

Precondicion: La caja esta iniciada     Devuelve un numero (integer) pseudo-aleatorio con un valor maximo de 'top'

}

function random;     var         n,k:integer value 0;

begin         for n:=((top div 256)+1) downto 0 do             k:=k+random_byte;

random:=(k mod top)+1;     end;

to begin do     { Al iniciar el programa inicia la caja para poder generar numeros aleatorios }     random_seed;

end.

Y eso es todo... hasta otra.

Introduccion a la criptografia, con Python: ARC4 (I)

La idea es hacer una serie de posts que cubran algunos de los algoritmos de criptografia mas usados, por lo menos uno decifrado simetrico (como ARC4) , otro de cifrado asimetrico (como RSA) y uno de hash (como MD5), vamos alla....

ARC4 (a.k.a. RC4 ) es el algoritmo de cifrado que se usa en WEP, en WPA y en SSL, entre otras cosas, y destaca por que es extremadamente sencillo y rapido... pero si no se usa correctamente no es seguro :P

Mas concretamente, es un cifrado de flujo, es decir que cifra el mensaje haciendo XOR de el byte de entrada y el byte que se obtiene del algoritmo (del keystream), y que la forma de cifrar y descifrar es exactamente la misma.

El cifrado se maneja con las siguientes estructuras: - Dos enteros (aqui seran 'i' y 'j') que solo tendran valores del 0 al 255 - Un array de 256 bytes (aqui sera 'S' )

La primera parte del cifrado ( el "seeding" ), tiene dos partes, la primera es llenar el array 'S' con valores del 0 al 255 (ambos incluidos), algo como: s=range(0,256)

Y despues se mezcla un poco todo... k=0

for n in range(0,256):

k=(k+self.s[n]+ord(clave[n % len(clave)]))%256

swap(n,k)

Swap intercambia los valores de S con los indices que se le dan... def swap(n,k):

   t=s[n]

   s[n]=s[k]

   s[k]=t

La primera parte ya esta (este es el codigo todo junto): class arc4:

# Intercambia dos valores del array 's'

def swap(self,n,k):

   t=self.s[n]

   self.s[n]=self.s[k]

   self.s[k]=t

def init(self,key):

   # Generamos el array 's', normalmente se utilizaria un bucle para

llenarlo

   # con los valores de 0 a 255, pero python lo hace mas facil



   self.s=range(0,256)

   k=0

   for n in range(0,256):

       k=(k+self.s[n]+ord(key[n % len(key)]))%256

       self.swap(n,k)



   self.i=0

   self.j=0

Ahora para cifrar se extrae un byte (al flujo de bytes que se extrae se le llama keystream) por cada byte de entrada y se les hace XOR... Para extraerlo a la variable "nuevobyte" se hace esto:
i=(i+ 1)% 256

   j=(j+ s[i])% 256

   swap(i,j)

   nuevobyte= s[(s[i]+ s[j])% 256]

Asi que para cifrar una string completa: def nextbyte(self):

   self.i=(self.i+ 1)% 256

   self.j=(self.j+ self.s[self.i])% 256

   self.swap(self.i,self.j)

   return self.s[(self.s[self.i]+ self.s[self.j])% 256]

def cipherbyte(self,byte):

   return byte^self.nextbyte()

# Aunque se usa para cifrar y descifrar...

def cipher(self,text):

   a=""

   for c in text:

       a+=chr(self.cipherbyte(ord(c)))

   return a

Se utilizaria la ultima funcion (cipher) para cifrar y descifrar Y el codigo ya esta... si lo probamos [ codigo completo: arc4.py ] :

===============================================================================

cifrador=arc4("password") text="Hola, mundo!" cifrado=cifrador.cipher(text) print cifrado

descifrador=arc4("password") descifrado=descifrador.cipher(cifrado) print descifrado Hola, mundo!

===============================================================================

Como se puede ver funciona bien :)}

Como usarlo (y como no usarlo):

Como ya se dijo antes, el algoritmo funciona bien dentro de lo que cabe, pero hay que tener en cuenta unas cosas cuando se use: Es recomendable descartar por lo menos los primeros 256 (un valor con cierto margen seria 3072 ) bytes del keystream, en el ejemplo se haria con for n in range(0,256):

cifrador.nextbyte()

antes de empezar a cifrar y for n in range(0,256):

descifrador.nextbyte()

antes de  descifrar.

Esto es por que de los primeros bytes del keystream se puede extraer informacion sobre la contraseña, otra posibilidad es utilizar claves temporales, una forma de hacerlo seria enviando un texto en plano, que se añade a la contraseña, y al resultante pasarle una funcion de hash (como MD5), con esto se conseguiria que aun crackeando la clave temporal y el texto en plano añadido no se pudiera recuperar la clave original (habria que hacer un ataque de fuerza bruta sobre el hash, ya que no se pueden usar Rainbow tables por el texto añadido, que funcionaria de salt)

Por supuesto seria recomendable utilizar las dos medidas, ya que usar varias veces la misma clave (especialmente en un cifrado de flujo) es una MALA IDEA y descartar los primeros bytes supone un esfuerzo computacional muy pequeño y aumenta la seguridad.

Por ultimo, volver a recordar, NO es buena idea usar dos veces la misma clave.

Y eso es todo, hasta otra!!

Ah! y el codigo esta coloreado con pygments

El codigo fuente en Python del cifrador arc4.py

[Referencias] RC4_en_la_Wikipedia

Como permitir que firefox se conecte a otros puertos

Hoy vengo con algo corto, que me pillo desprevenido, y supongo que a alguien le ayudara

Hace ya tiempo que firefox no permite conectarse a algunos puertos no estandar, como el 87, esto esta bien para evitar el HTML Form Protocol Attack [ http:// www.remote.org/jochen/sec/hfpa/index.html ]

Pero esto puede resultar molesto en sitios que utilizan estos puertos para la navegacion web (como smashthestack.org ), para permitir utilizar estos puertos, entramos a about:config ( le damos a "Tendre cuidado, lo prometo" ), y buscamos "network.security.ports.banned.override", si no existe lo creamos: boton secundario>Nuevo>Cadena Nombre: network.security.ports.banned.override Valor:

Si ya existe, hacemos doble click, y añadimos los puertos (separados por comas) [http://1.bp.blogspot.com/_26RJWnubh-w/S6fSp73oPDI/AAAAAAAAAFU/hreZjd-MxWc/ s640/puertos.png]

Y ya esta!, hasta otra!