Terrordrome: El videojuego de lucha que llevabas años deseando

El otro día a través de los amigos de Zinemaníacos descubría este videojuego. Vi la entrada en el móvil mientras esperaba en un bar así que hasta hoy no me puse a buscarlo (de hecho tuve que preguntarles cómo se llamaba, que ya ni lo recordaba).

Herbert West vs Violent Cop

¿Por qué es El videojuego de lucha que llevabas años deseando? pues porque en él podrás enfrentar a los grandes psicópatas del cine de terror cara a cara. Sí, los grandes entre los grandes: Jason Voorhees (en dos versiones, con machete y con hacha), Freddy Krueger, Leatherface, Micheal Myers, Ashley «Ash» Williams, The Tall man, Chucky, Ghostface, Matt Cordell, Candyman, Herbert West, Pumpkinhead y Pinhead. Menuda pandillita para irse de cañas.

Terrordrome Ash Evil Dead
Ash vs Ash, rememorando El Ejército de las Tinieblas!

El juego ha sido creado por un fan y, como pasaba con el PC Fantacanestro del que hablamos hace tiempo, se pasa por el forro los temas de licencias y nos regala esta experiencia. ¿Los gráficos podrían ser mejores? Por supuesto. ¿La jugabilidad? Para el que se criara con los arcades de los 90 es la habitual. ¿Merece la pena? Si eres aficionado a los juegos de lucha no te engañaré, es un juego indie muy del montón, aquí la gracia radica en los personajes de los que dispones que lo hacen la fantasía de todo buen friki del género. Si te han flipado películas como Posesión Infernal, Pesadilla en Elm Street, Phantasma, Halloween, Muñeco Diabólico o Viernes 13 es un juego que debes probar. A fin de cuentas es gratis así que sólo pierdes el rato en descargarlo si no te acaba de convencer, y si te gustan esas pelis pasarás un rato muy divertido.

Carátulas películas Terrordrome

El juego está creado para Windows XP o superior, pero lo he probado en un Ubuntu 14.04 y en un ElementaryOS y en ambos me ha funcionado con Wine como una seda, así que que el aficionado Linuxero no se quedará sin disfrutarlo. Lo dicho, una frikada más que recomendable para divertiros.

Chucky vs Herbert West

El juego está disponible para ser descargado desde la página del proyecto. Esperemos que no lo tumben por algún tema de derechos para poder seguir disfrutando la frikada. Os dejo un enlace a un vídeo con un gameplay.

Terrordrome: old school vs new school

Clase para prevenir ataques XSS en Java

Buscando información para aumentar la seguridad de una aplicación web basada en Java me encontré con esta clase para filtrar los posibles ataques XSS en la web de un veterano ingeniero llamado Ricardo Zuasti.

Su solución propone dos clases. La primera, que copio de su entrada original a continuación, lo que hace es filtrar las peticiones HTTP para que sean filtradas por la clase especializada creada para eso:

public class XSSFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void destroy() {
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }
 
}

Tras esto propone la siguiente clase para realizar el filtrado. Esta clase sobreescribe los métodos getParameterValues(), getParameter() y getHeader() y utiliza una serie de patrones para evitar la entrada de código malicioso en tu web. El método stripXSS() es el que realiza la labor de filtrado.

import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
public class XSSRequestWrapper extends HttpServletRequestWrapper {
 
    private static Pattern[] patterns = new Pattern[]{
        // Script fragments
        Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
        // src='...'
        Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // lonely script tags
        Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
        Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // eval(...)
        Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // expression(...)
        Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // javascript:...
        Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
        // vbscript:...
        Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
        // onload(...)=...
        Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
    };
 
    public XSSRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }
 
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
 
        if (values == null) {
            return null;
        }
 
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = stripXSS(values[i]);
        }
 
        return encodedValues;
    }
 
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
 
        return stripXSS(value);
    }
 
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return stripXSS(value);
    }
 
    private String stripXSS(String value) {
        if (value != null) {
            // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
            // avoid encoded attacks.
            // value = ESAPI.encoder().canonicalize(value);
 
            // Avoid null characters
            value = value.replaceAll("\0", "");
 
            // Remove all sections that match a pattern
            for (Pattern scriptPattern : patterns){
                value = scriptPattern.matcher(value).replaceAll("");
            }
        }
        return value;
    }
}

Entre las recomendaciones que da en el artículo original está la de configurar este filtro como el primero en tu web.xml y también, en referencia al código que aparece comentado en la segunda clase, echarle un ojo a la librería ESAPI, que nos proporciona diversas soluciones de seguridad.

Desde aquí sólo me queda enviarle mi agradecimiento por su trabajo al señor Zuasti y animarle a recuperar su blog, que tiene material interesante pero hace tiempo que no actualiza.

Comprimiendo en zip desde línea de comandos en Linux (Ubuntu/Debian)

Esta mañana a uno de mis equipos se empezó a ir un poco la pinza. No me digais por qué pero si intentaba comprimir utilizando la utilidad gráfica por defecto de Ubuntu no me lo permitía, se quedaba tirado el programa al hacerlo. Al final se arregló reinstalando, pero el caso es que en aquel momento no tenía conexión a internet para hacerlo y necesitaba crear un zip para pasarle una serie de archivos a una usuaria de Windows. Así que tocó usar la consola de comandos.

¿Cómo hice para comprimir la carpeta? Bueno la sintaxis del comando zip es

zip nombreDeArchivoFinal archivoacomprimir1 archivoacomprimir2…

En el ejemplo os dejo varias posibilidades comentadas:

#para incluir subdirectorios
#hay que añadir la opción -r
zip -r resultado.zip carpeta1

#con el comodín * podemos comprimir
#todos los ficheros dentro de una carpeta
zip resultado.zip *

#zip nos permite proteger el archivo
#con una contraseña, pero hay que
#ver que su algoritmo no es muy seguro
zip --password MI_CONTRASEÑA_ELEGIDA protegido.zip archivo1 archivo2 archivo3

#Una opción para codificar con más seguridad sería usar GPG
#primero comprimimos en zip
#luego codificamos la carpeta
#nos pedirá que insertemos la contraseña tras el comando GPG
zip -r resultado.zip carpeta1
gpg -c resultado.zip

#otra opción es usar openssl para encriptar
#primero comprimimos en zip
#luego codificamos la carpeta
#y nos pedirá password igual que antes
zip -r resultado.zip carpeta1
openssl aes-256-cbc -e -in resultado.zip -out resultado.zip.aes

En los ejemplos hemos usado criptografía de clave simétrica, pero siempre podeis investigar formas de utilizar algoritmos de clave pública/privada, ya que tanto gpg como openssl están pensados para poder hacerlo.

Uniendo documentos pdf en Linux con pdftk

En el anterior artículo hablábamos sobre cortar pdf en distros Linux utilizando la utilidad pdftk. Ahora vamos a ver cómo hacer lo contrario: unir varios pdf en uno solo.

No repetiré los pasos de instalación de pdftk porque están en el artículo anterior. Obviando esto nos metemos en harina: lanzamos un terminal y nos ponemos en la carpeta en la que están los pdf y cuando estemos allí usamos el siguiente comando (en el ejemplo fusionaremos dos archivos que se llaman archivo1.pdf y archivo2.pdf en uno nuevo llamado nuevoArchivo.pdf)

pdftk archivo1.pdf archivo2.pdf cat output nuevoArchivo.pdf

Y luego podemos combinar ambas ideas: cortar y unir en un solo comando. En el ejemplo extraeremos las dos primeras páginas del archivo1, la quinta del archivo2 y la octava del archivo1 y crearemos el archivo3 con estas en ese orden.

pdftk A=archivo1.pdf B=archivo2.pdf cat A1-2 B5 A8 output archivo3.pdf

Como veis nos servimos del comando cat para concatenar archivos y de output para dirigir la salida de cat hacia un nuevo archivo pdf.

Cortando y dividiendo documentos pdf en Linux

No es extraño (que cantaba Tom Jones) el tener que cortar un documento pdf. Hoy mismo me mandaron dos facturas en el mismo documento y las necesitaba separadas porque tenía que enviarlas a dos correos distintos. ¿Cómo se puede solucionar esto?

Lo primero es instalar pdftk:

#si lo hacemos en una distro Ubuntu/Debian
sudo apt-get install pdftk

#Si lo hacemos en Fedora/RedHat
sudo yum install pdftk

Una vez instalado la forma más simple de cortar el pdf es usan burst, que lo que hará será generar una página independiente por cada una de las páginas del pdf original.

pdftk archivo.pdf burst

Esto generará varios archivos llamados pg_001.pdf, pg_002.pdf… en mi caso me bastaba con esto porque eran dos páginas pero ¿qué pasa si manejas un pdf de 600? Es probable que no quieras 600 archivos nuevos. Por suerte pdftk es una herramienta potente que nos da gran flexibilidad a la hora de trabajar, y disponemos de un comando que nos permite extraer una serie de páginas concretas de un documento hacia un nuevo archivo. Vamos con el ejemplo, donde sacaremos las páginas de la 30 a la 45 de un archivo y generaremos uno nuevo con ellas:

$ pdftk A=archivo.pdf cat A30-45 output archivofinal.pdf

Y es más, podemos extraer páginas de dos pdf distintos y sacarlas todas en un mismo documento. En el ejemplo sacaremos las páginas del 10 al 15 del documento 1 y las 15-18 del documento 2:

$ pdftk A=archivo.pdf B=archivo.pdf cat A10-15 B15-18 output archivofinal2.pdf

Y próximamente veremos cómo fusionar archivos.

Configurando un sistema Debian para que monte en el inicio las carpetas compartidas NFS

Recordarás que hace un par de días hablamos sobre cómo configurar y montar una carpeta en red usando NFS en un sistema Debian. Ese artículo nos servirá de ejemplo para el presente ¿cómo hacemos que los clientes monten la carpeta desde el inicio?.

Vamos con un resumen rápido del artículo anterior (por si estás vago para leerlo): la ip del servidor es 192.168.1.2, la carpeta se llama /compartida y el punto de montaje es /mnt/nfs/compartida.

Bueno, basándonos en nuestro conocimiento de Linux sabemos que los discos y particiones montados en el arranque se configuran en el archivo /etc/fstab (abreviatura de File Systems Table) así que lo abrimos con un editor de texto (nano, gedit, vi, emacs… el que más o guste) y añadimos una nueva línea para montar. Cada una de estas líneas se compone de la siguiente forma:

  1. Primero la dirección de la unidad compartida, en este caso 192.168.1.2:/compartida
  2. Después va el punto de montaje, para el ejemplo /mnt/nfs/compartida
  3. El sistema de archivos, que en este caso es nfs.
  4. Las opciones son varias, y las puedes ver en la página oficial de Ubuntu. Para el ejemplo serán auto,noatime,nolock,bg,nfsvers=3,intr,tcp,actimeo=1200.
  5. La frecuencia con la que se usará dump para respaldar el sistema de archivos. Si se pone a 0 no se hará copia (más velocidad, menos seguridad).
  6. La frecuencia con la que fsck revisará el volumen en busca de errores. Si se deja a 0 no lo hará (más velocidad, menos seguridad)

Así que al final la línea que meteríamos, siguiendo el ejemplo del artículo anterior, sería tal cual esta:

192.168.1.2:/compartida /mnt/nfs/compartida nfs auto,noatime,nolock,bg,nfsvers=3,intr,tcp,actimeo=1200 0 0

Una vez guardados los cambios bastará reiniciar para comprobar que han surtido efecto

Metal Captcha: Parando los pies a los bots estilo moshpit

Una simpática idea de la gente de Heavygifts, una web húngara de merchandising metalero, que he visto en MetalSucks hoy: LOS METAL CAPTCHA.

Captcha es la abreviatura de Completely Automated Public Turing test to tell Computers and Humans Apart y se trata de un sistema para evitar que bots automatizados hagan login en tu sistema. Los has visto mil veces al intentar enviar un formulario en alguna web, cuando te ponen unas letras deformadas o una imagen con una palabra o número y te mandan escribir qué lees para confirmar que eres humano.

Pues la idea de estos Metal Captcha es hacer lo propio con logotipos de bandas de metal. Todavía no lo he probado, pero si queréis echarle un ojo os dejo por aquí la página de este simpático proyecto, que nació inspirado por una broma viral en las redes sociales.

Metal Captcha

Carpetas compartidas en red en Ubuntu: Instalando y configurando una con NFS

Vamos a ver cómo compartir una carpeta utilizando una distribución de linux de la familia Debian (Ubuntu, Debian, Linux Mint). Y vamos a ver cómo hacerla mediante línea de comandos para que sea universal para todas las distribuciones (en las distros «no Debian» no cambiaría mucho la cosa, exceptuando la parte de instalar los paquetes el resto iría más o menos igual, creo)

El primer paso es instalar los paquetes nfs-kernel-server,nfs-common y rpcbind en el equipo que servirá la carpeta. Para ello usamos el siguiente comando:

sudo apt-get install nfs-kernel-server nfs-common rpcbind

Tras esto reiniciamos el equipo.En los equipos clientes, que se van a conectar con la carpeta, tenemos que instalar sólo los dos últimos paquetes, no es necesario el del servidor:

sudo apt-get install nfs-common rpcbind

Lo siguiente es crear la carpeta a compartir, en este caso se llamará compartida, y configurar los permisos para no tener problemas al acceder a ella. En este caso daremos a los usuarios permisos totales sobre la carpeta y no habrá grupo propietario, para que puedan hacer lo que les plazca.

sudo mkdir /compartida
sudo chown nobody:nogroup /compartida
sudo chmod -R 777 /compartida

Ahora tenemos que decirle al sistema qué carpetas vamos a compartir editando el archivo /etc/exports. La sintaxis es rutaCarpeta cliente_A(opciones) cliente_B(opciones). Tenemos múltiples opciones a la hora de definir a los clientes: una dirección ip o un rango de ellas, el nombre DNS del equipo o caracteres comodín (para dar acceso a cualquier equipo basta poner el comodín *).

En cuanto a las opciones son las siguientes:

  • ro(read-only): La carpeta compartida será de sólo lectura. Si no se define, es la opción por defecto.
  • rw (read-write): El usuario tiene permisos para escribir en la carpeta y hacer cambios en ella.
  • wdelay: El servidor NFS no escribe en el disco si espera otra solicitud inminentemente. Esto reduce los accesos a disco mejorando el rendimiento. Sólo funciona cuando usamos la opción sync.
  • no_wdelay: Desactiva wdelay.
  • sync: No permite responder peticiones antes de escribir los cambios pendientes. Se trata de la opción predeterminada.
  • async: Deshabilita sync. Esto mejora el rendimiento pero provoca que exista el riesgo de corrupción en los archivos si se produjese un corte de luz o una caída de la red.
  • subtree_check: Si el directorio compartido es un subdirectorio de un sistema de archivos mayor NFS comprobará los directorios por encima de éste, verificando sus permisos. Se trata de la opción predeterminada.
  • no_subtree_check: Deshabilita la característica anterior. Así se consigue agilizar el envío de la lista de archivos, pero reduciendo la seguridad del sistema.
  • root_squash: Evita que los usuarios con privilegios mantengan los permisos administrativos sobre la carpeta compartida, cuando se conectan remotamente.Es la opción activada por defecto
  • no_root_squash: Deshabilita root_squash.

Así que en nuestro archivo /etc/exports toca añadir la siguiente línea, con la que daremos permisos de lectura/escritura, activaremos la opción de sync y la de no comprobar todo el árbol superior a todos los clientes que se conecten:

#recordamos: primero la ruta
#después el cliente, en este caso * para todos
#y finalmente las opciones
/compartida *(rw,sync,no_subtree_check)

Y tras eso, toca reiniciar el servidor nfs:

sudo /etc/init.d/nfs-kernel-server restart

Lo siguiente será crear un punto de montaje para la carpeta compartida en los equipos cliente (vamos a suponer que la IP del servidor es 192.168.1.2):

sudo mkdir -p /mnt/nfs/compartida
#aunque ya dimos permisos a la carpeta
#también se los damos al punto
#de montaje
sudo chmod -R 777 /mnt/nfs
#y montamos la carpeta
sudo mount 192.168.1.2:/compartida /mnt/nfs/compartida

Y tras esto ya deberías poder crear y leer archivos en la carpeta compartida desde los clientes conectados en la red. Más adelante veremos algunas cosas sobre carpetas compartidas.

Reglas de grupo para proteger un servidor Windows del troyano Cryptolocker

Estos días la enésima mutación de Cryptolocker está generando problemas a muchos usuarios y administradores. Como siempre el tener una buena política de copias de seguridad, el sistema actualizado, una política de contraseñas fuerte y un control adecuado sobre los permisos de los usuarios serán los cimientos de nuestra defensa. En caso de sufrir un ataque que este afecte al menor número de archivos posible y que estos sean recuperables. Pero al final la desinfección y recuperación de datos lleva un rato de trabajo ¿hay una manera de protegerse? Bueno, con algunas versiones de Cryptolocker, no con todas, es posible evitar su impacto generando una regla de grupo que no permita ejecutar archivos desde las ubicaciones en las que este habitualmente se aloja.

En la configuración de seguridad local te vas crear una nueva Directiva de restricción de Software. Alguno pensará en que se podría hacer con una directiva basada en el hash del virus pero hay dos problemas: a) Que para eso tendríamos que tener el exe del virus (aunque esto es conseguible) b)Que nos lo solucionaría para esta versión de Cryptolocker, pero la próxima mutación con algún cambio en el código ya tendría un hash distinto. ¿Cual es la idea? Pues crear una directiva basada en el bloqueo de rutas, que funciona contra varias versiones del virus.

Como ya decíamos, el primer paso es crear una nueva directiva de bloqueo de software:

directiva de bloqueo de software

Una vez creada la directiva la cosa es ir creando una serie de Reglas de Nueva Ruta para cada una de estas excepciones, marcándolas como No Permitidas (Disallowed si tienes el servidor en inglés):

%AppData%\
%AppData%\*\
%localappdata%\
%localappdata%\*\
%localappdata%\Microsoft\Windows\Temporary Internet Files\
%localappdata%\Microsoft\Windows\Temporary Internet Files\Content.Outlook\
%localappdata%\Microsoft\Windows\Temporary Internet Files\Content.Outlook\*\
%localappdata%\Microsoft\Windows\Temporary Internet Files\Content.Outlook\*\*\
%Temp%\
%Temp%\$*\
%Temp%\*.zip\
%userprofile%\
%AppData%\*.scr
%AppData%\*\*.scr
%UserProfile%\Local Settings\Temp\rar*\*.scr
%UserProfile%\Local Settings\Temp\7z*\*.scr
%UserProfile%\Local Settings\Temp\wz*\*.scr
%UserProfile%\Local Settings\Temp\*.zip\*.scr
%UserProfile%\Local Settings\Temp\*.cab\*.scr
%UserProfile%\Local Settings\Temp\*.scr
%UserProfile%\Local Settings\Temp\*\*.scr

Es posible que estas reglas bloqueen algún software que quieras utilizar, en ese caso puedes crear excepciones para esas aplicaciones creando un nueva regla y dándole un perfil con más permisos. Esto no garantiza protección total, ya que desde hace un par de años cada X meses aparece una nueva variante del malware más puñetera que la anterior, pero al menos sí te ayudará a minimizar el efecto de algunas de las versiones hasta ahora conocidas.

Dar formato a un float para mostrar sólo dos decimales en Python

A la hora de trabajar con números decimales en cualquier lenguaje nos topamos con la necesidad de darles un formato adecuado en muchas ocasiones (por ejemplo si trabajamos con valores monetarios, con estaturas, etc) para presentar un resultado en pantalla. El más habitual es recortar o redondear los decimales para mostrar sólo dos. ¿Cómo podemos hacer esto en Python? Con la función format() y los operadores de formateo de cadenas es muy simple:

#Formateamos 5.1234554321
print "{0:.2f}".format(5.1234554321)
#El resultado sería
>>5.12
#¿Y si queremos tres?
print "{0:.3f}".format(5.1234554321)
#El resultado sería
>>5.123