sábado, 19 de abril de 2014

[Parte 3] CURL en PHP

Cookies

El medio por el cual los navegadores web hacen "client side state control (control del estado del lado del cliente)" es por medio de cookies. Las cookies solo son nombres asociadas con contenido. Las cookies son enviadas desde el cliente al servidor. El servidor llama al cliente para saber que ruta y hostname quiere el cliente, devolviendoles asi una fecha de expiracion y unas propiedades mas.

Cuando el cliente se comunica con el servidor con el nombre y ruta previamente especificado y recibido en la cookie, el cliente envia de regreso las cookies y su contenido para el servidor, a menos que claro estas hayan expirado. 

Muchas aplicaciones y servidores usan este metodo para conectar una serie de peticiones dentro de una sola sesion. Para ser capaces de usar curl en tales ocasiones, nosotros deberiamos ser capaces de guardar y enviar de regreso las cookies a la aplicacion web.

Esto es muy importante para script en cURL para verificacion de inicios de sesion o paginas con una seccion segura en el sitio web. Estas son 3 cosas que requerimos implementar:

1.- La ruta del archivo para la cookie en tu servidor:


 <?php
 $cookie_file_path = "C:/xampp/htdocs/cookie/cook"; // Este archivo debe tener permisos chmod 777 (leer / escribir)
?>

2.- Las funciones cURL:


 <?php
 curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); // el nombre del archivo contiene los datos de la cookie. La cookie puede ser en formato netscape, o solo texto plano http-style con las cabeceras puestas dentro del archivo
 curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); // el nombre del archivo guarda todas las cookies internas para cuando la conexion cierra.
?>

Por favor realice lo siguiente:

1.- Suba este archivo prueba.php a su servidor con el siguiente codigo:

 <?php
 print realpath('prueba.php');
?>

2.-  Accede al archivo tuhost.com/prueba.php y copia la ruta que arroja, en este ejemplo:

/home/a8131XXX/public_html/prueba.php  

3.- Crea un archivo .txt y ponle de nombre cookie.txt y subelo a tu servidor

4- Dale permisos CHMOD 777. En windows no es necesario realizar esto.

5.- Ahora simplemente formas una cadena con lo que salio en el paso 2 y con el archivo del paso 3, quedando de la siguiente forma:


/home/a8131XXX/public_html/cookie.txt





 <?php
 // ejemplo 8
 $user = "tusuario";
 $pass = "tucontraseña";
 $url = "https://www.facebook.com/login.php";
 $post_fields = 'lsd=AVolpnen&email='.$user.'&pass='.$pass.'&default_persistent=0&timezone=360&lgnrnd=222458_oW23&lgnjs=1397971500&locale=es_LA';
 $referer = "https://www.facebook.com/login.php";
 $agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0";
 $cookie_file_path = "C:/xampp/htdocs/cookie.txt";

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_USERAGENT, $agent);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($ch, CURLOPT_REFERER, $referer);
 curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
 curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);

 $result = curl_exec($ch);
 curl_close($ch);

 echo $result;
?>


CURLOPT_COOKIEFILE - Nombre del fichero que contiene datos de las cookies. El fichero de las cookies puede estar en formato Netscape, o simplemente tipo HTTP plano dentro de un fichero. Si el nombre es una cadena vacia, no se cargaran cookies, aunque el manejo de cookies aun esta habilitado.

CURLOPT_COOKIEJAR - Nombre del fichero donde guardar cookies internas cuando se cierra se cierra, por ejemplo: despues de llamar a curl_close().

HTTPS (SSL)

Hay varias formas de realizar transferencias HTTP seguras. A lo lejos el protocolo mas comun que realiza esto es conocido como HTTPS, HTTP encima de SSL. SSL encripta todos los datos que son enviados y recibidos atraves de la red, asi hace mas dificil que los atacantes espien la informacion sensitiva.

SSL (o TLS como la ultima version del estandar es llamada) ofrece un camino para caracteristicas avanzadas para permitir estas encriptaciones y claves de mecanismos de infraestructura para encriptar HTTP como es requerido.

cURL soporta recuperaciones encriptadas gracias a las librerias OpenSSL.

En el ejemplo anterior de la peticion con cURL a facebook, usamos esto que eran las opciones CURLOPT_SSL_VERIFYPEER y CURLOPT_SSL_VERIFYHOST.

CURLOPT_SSL_VERIFYPEER - FALSE para que cURL no verifique el PEER del certificado. Para usar diferentes certificados para la verificacion se puede especificar con la opcion CURLOPT_CAINFO o se puede especificar el directorio donde se encuentra el certificado con la opcion CURLOPT_CAPATH. TRUE por omision desde cURL 7.10. Paquete instalado por defecto en la version de CURL 7.10.


CURLOPT_SSL_VERIFYHOST - 1 para comprobar que existe un nombre comun en el peer del certificado SSL.  2 para comprobar que existe un nombre comun y tambien para verificar que el hostname coincide con el proporcionado. En entornos de produccion el valor de esta opcion debe de mantenerse en 2 (valor por omision).

Depuracion

Muchas veces cuando corremos curl en un sitio, tienes un aviso de que el sitio no se muestra, para responder de la misma forma las peticiones curl tu debes hacer como el navegador.

Entonces tu necesitas empezar a crear tus peticiones mas similar a tus peticiones del navegador:

- Estar seguro que checa las cookies cuando son necesarias
- Establecer User-Agent de los navegadores mas actuales y populares
- Establecer el Referer como esta establecido en el navegador
- Si contiene datos POST, debes acomodarlos de la misma manera que lo hace el navegador.

CURLOPT_HEADER - TRUE para incluir el header (encabezado) en la salida
CURLOPT_VERBOSE - TRUE para mostrar informacion verbose. Escribe la salida en STDERR, o el fichero especificado usando CURLOPT_STDERR.




[Parte 2] CURL en PHP

Formularios

Los formularios son generalmente presentados como campos donde el usuario puede meter datos, y al presionar Ok o Submit estos son enviados al servidor para ser procesados. El servidor procesa datos tipicamente como por ejemplo: una busqueda a la base de datos, un inicio de sesion, etc.

GET y POST

En el metodo GET todos los campos se ven mostrados en la URL. Esto generalmente suele ser una ventaja para sistemas de modulacion, pero una desventaja en si, ya que muchos atacantes lo primero que verifican es este tipo de URLs. El protocolo HTTP ofrecere otro metodo que es POST el cual envia los campos ocultos separados de la URL los cuales son enviados por las cabeceras HTTP.

Una buena practica seria enviar en una pagina donde los datos son enviados por el metodo POST y darle nuestros valores... En el metodo post se usa el content-type: application/x-www-form-urlencoded por lo cual es necesario encodear a urlencode nuestros datos que vamos a enviar, por ejemplo: si tiene un espacio pondriamos %20, pero para no hacerlo tan pesado podriamos hacer uso de la funcion urlencode().

Vamos a ver como ejemplo la API de anonscanner que me paso ZanGetsu:


 <?php
    /*
    AnonScanner.com API sample PHP code.
    You must edit the $uid, $api_key and $file variables to make this work.
    */
    
    $url     = "https://anonscanner.com/api.php";
    $uid     = "YOUR_USER_ID"; //Your user id, from the home page.
    $api_key = "YOUR_API_KEY"; //Your API key from the home page.
    $file    = $_FILES['file'];
    
    $ch      = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    $post    = array(
        "uid"     => $uid,
        "api_key" => $api_key,
        "file"    => "@".$_SERVER['DOCUMENT_ROOT']."/".$file,
        "return"  => "link" //"link", "image" or "all". Leave empty for default(all).
        );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $response = curl_exec($ch);
    $response = json_decode($response,true);
    
    print_r($response); //JSON output
?>


En este caso esta pequeña API lo que hace es devolvernos los resultados de los antivirus, para ello envia un archivo por medio de POST, nuestro iud, nuestra api,y el modo en que devolveremos los resultados.


Lo unico nuevo y que voy a explicar aqui es CURLOPT_POST, CURLOPT_POSTFIELDS.

CURLOPT_POST - TRUE para hacer un HTTP POST normal. Este post del tipo application/x-www-form-urlencoded, el mas comun en los formularios HTML.

CURLOPT_POSTFIELDS - Todos los datos para enviar via HTTP "POST". Para enviar un fichero, prefija el nombre de fichero con @ y utiliza la ruta completa. Se puede especificar explicitamente el tipo de fichero añadiendo el tipo al nombre del fichero, en el formato ';type=mimetype'. Se puede enviar una cadena urlencoded como 'para1=val1&para2=val2&...' o tambien como un array con el nombre del campo como key y los datos como value. Si value es un array, el encabezado Content-Type sera definido como multipart/form-data. Apartir de PHP 5.2.0, value debe ser un array si los archivos son pasados a esta con la opcion con el prefijo @. Apartir de PHP 5.5.0, el prefijo @ esta obsoleto, por lo que los ficheros se pueden enviar usando CURLFile.

Nota: Para los campos ocultos de un formulario podemos usar lo mismo, solamente que como estos no se ven nosotros tendriamos que aplicarlos.


Descagar una imagen (Archivo Binario)

Tu puedes descargar archivos como imagenes, pdfs, psd, docs, zip usando curl. Google usa esta tecnica para mostrar sus imagenes.


 <?php
 // Ejemplo 3
 $url = "http://most-security.com/foro/image.php?u=138&dateline=1397283113";
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url); // URL para descargar la imagen
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido
 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0"); // especificamos el navegador que usamos
 curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); // retorna esta transferencia, como contenido binario
 $data = curl_exec($ch); // graba la imagen jpg y lo guarda en la variable $data
 curl_close($ch); // cierra el recurso, y libera memoria del sistema
 header("Content-type: image/jpeg"); // le indicamos en la cabecera lo que se muestra contiene imagenes 
 echo $data; // muestra el contenido
?>


Autentificacion

La autentificacion es capaz de verificar si tienes permiso a acceder a un recurso. La autentificacion basica usada en HTTP es basada en texto plano es decir usuario y contraseña ligeramente ofuscados, pero puede ser leido si te olfatean la red.

Para usar la autenticacion en una caja de dialogo, que nos pide usuario y contraseña:






 <?php
 // Ejemplo 4
 $url = "http://tuhost.com/sinacceso/";
 $post_fields = 'arthusu:test';
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url); // URL para descargar la imagen
 curl_setopt($ch, CURLOPT_USERPWD, $post_fields); // la caja de dialogo
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido
 $results = curl_exec($ch); // graba la imagen jpg y lo guarda en la variable $data
 curl_close($ch); // cierra el recurso, y libera memoria del sistema
 
 echo $results;
?>





CURLOPT_USERPWD - Nombre de usuario y contraseña siguiendo el formato "[username]:[password]" para ser usado en la conexion.


Referer

Muchas paginas chequean desde donde llega el cliente, mas que nada que pagina anterior uso, para llegar a la suya, esto puede ser muy util para muchas cosas, pero esto se puede engañar facilmente modificando la cabecera 'referer'.



 <?php
 // ejemplo 5
 $url = "http://tuhost.com/logsasd/"; // URL
 $referer = "http://www.mirasoyunsitiofalso.com/"; // Sitio referido

 $ch = curl_init(); // inicia una sesion curl
 curl_setopt($ch, CURLOPT_URL, $url); // pasa la url como parametro
 curl_setopt($ch, CURLOPT_REFERER, $referer); // establece el sitio referido
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina

 $result = curl_exec($ch); // graba la url pasada y la mete en la variable result
 curl_close($ch); // cierra la url, y libera recursos del sistema

 echo $result; // muestra el contenido de la pagina
?>








User Agent

La cabecera User-Agent contiene datos importantes como son el navegador que esta usando el cliente y su sistema operativo, tambien indica si esta entrando desde un dispositivo Ipad, Iphone, etc.

Muchas paginas dejan entrar al Bot de google solo por que ven su cabecera, una buena practica que podriamos hacer es intentar entrar a varias paginas con acceso restringido en algunas zonas y ver como con el User-Agent de google tenemos mas privilegios.

O simplemente, si intentas hacer una peticion most-security por medio de cURL te arrojara cloudflare con un error detectando que estas usando cURL por lo cual puedes usar esta cabecera User-Agent evitando que te salga ese error.

 <?php
 // ejemplo 6
 $url = "http://tuhost.com/logsasd/"; // es la url que veremos
 $agent = " Googlebot/2.1 (+http://www.google.com/bot.html)"; // es el navegador que usaremos

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url); // inicia una sesion curl
 curl_setopt($ch, CURLOPT_USERAGENT, $agent); // establece el navegador
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina

 $result = curl_exec($ch); // guarda el contenido de la pagina en $result
 curl_close($ch); // cierra la sesion curl

 echo $result; // muestra la pagina
?>






Redirecciones

Cuando pides una pagina web, muchas veces te envia un mensaje de error 301 el cual dice que el objeto se ha movido, esto pasa que cuando tu lo pides con cURL no sigue el objeto que se movio, entonces para poder retornar o ver la pagina necesitamos seguir ese recurso...
Este tipo de recursos se ven reflejados en la cabecera Location.

Esto nos pasa cuando no seguimos la cabecera Location en el caso de google y si lo activamos.





Siguiendo la cabecera Location.


 <?php
 // ejemplo 7
 $url = "http://www.google.com"; // es la url que veremos

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url); // inicia una sesion curl
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // redirige a la pagina, en caso de un login te redirige a la pagina de entrada
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devuelve el contenido de la pagina

 $result = curl_exec($ch); // guarda el contenido de la pagina en $result
 curl_close($ch); // cierra la sesion curl

 echo $result; // muestra la pagina
?>

Hasta aqui terminamos la parte 2.

viernes, 18 de abril de 2014

[Parte 1] CURL en PHP

Instalacion

Lo primero que debemos hacer para comenzar a utilizar cURL es instarlo, para ello puedes descargarlo desde: http://curl.haxx.se/

La guia para la instalacion de cURL compilandolo esta aqui: http://curl.haxx.se/docs/install.html

En este caso no veremos en detalle esto ya que pues vienen los pasos muy detallados en la pagina de la documentacion de cURL, por lo cual veremos solamente como instarlo en la distribucion de ubuntu usando un solo comando:

Instalar cURL con un solo comando desde la terminal:


sudo apt-get install php5-curl

Reiniciar el servidor apache para que funcione cURL:

sudo /etc/init.d/apache2 restart

Como ves es demasiado facil, y de hecho ya existen muchos paquetes que te incluyen un servidor apache,mysql,php tal como puede ser XAMPP, AppServ... los cuales pueden descagar desde su web oficial y son faciles de instalar y casi siempre ya traen soporte para cURL:

XAMPP: https://www.apachefriends.org/es/index.html
AppServ: http://www.appservnetwork.com/?newlang=spanish

Para saber si nuestro servidor soporta cURL solamente creamos un archivo como el siguiente info.php:

 <?php phpinfo(); ?>

Entramos al archivo y veremos algo como lo siguiente:


¿Que es cURL?

cURL es una herramienta para usar en un interprete de comandos para transferir archivos con sintaxis URL, soporta FTP, FTPS, HTTP, HTTPS, TFTP, SCP, Telnet, DICT, FILE, y LDAP. cURL soporta certificados HTTPS,HTTP POST, HTTP PUT,Subidas FTP, Kerberos, Subidas mediante formulario HTTP, proxies, cookies, autenticacion mediante usuario+contraseña (Basic, Digest, NTLM y Negotiate para HTTP y Kerberos4 para FTP), continuacion de transferencia de archivos, tunneling de proxy http y muchas otras prestaciones. cURL es opensource/software libre distribuido bajo la licencia MIT. El proposito y uso para cURL es automatizar transferencia de archivos o secuencia de operaciones no supervisadas. Es por ejemplo una buena herramienta para simular las acciones de un usuario en un navegador web. Libcurl es la biblioteca/API correspondiente que los usuarios pueden incorporar en sus programas, cURL actua como un envoltorio (wrapper) aislado para la biblioteca libcurl. libcurl se usa para proveer capacidades de transferencia de URL a numerosas aplicaciones, tanto libres y open source como asi tambien privativas. La biblioteca "libcurl" se puede usar desde mas de 30 lenguajes distintos.


HTTP

Hypertext transfer protocol o http (en español protocolo de transferencia de hipertexto) es el protocolo usado en cada transaccion de la world wide web. Es un protocolo orientado a transacciones y sigue el esquema peticion-respuesta entre cliente y un servidor. Al cliente que efectua la peticion (un navegador o un spider) se conoce como "user-agent" (agente del usuario). A la informacion transmitida se le llama recurso y se la identifica mediante un localizador uniforme de recursos (URL). Los recursos pueden ser archivos, el resultado de la ejecucion de un programa, una consulta a una base de datos,la traduccion automatica de un documento, etc. HTTP es un protocolo sin estado, es decir, no guarda ninguna informacion sobre conexiones anteriores. El desarrollo de aplicaciones web necesita frecuentemente mantener el estado. Para eso se usan las cookies, que es informacion que un servidor puede almacenar en el sistema cliente. Esto permite a las aplicaciones web instruir la nocion de "sesion", y tambien permite rastrear usuarios ya que las cookies pueden guardarse en el cliente por tiempo indeterminado.


Uso simple de cURL

La operacion mas comun es obtener una URL. Podriamos hacer referencia a una pagina, imagen o archivo. El cliente hace una peticion GET y recibe el documento que pidio.

curl_init() - esta funcion inicializa una sesion cURL y retorna un manejador cURL.

curl_exec($ch) -  esta funcion deberia ser llamada despues de inicializar una sesion cURL y todas las opciones establecidas en la sesion. Su proposito es simple, ejecutar la sesion CURL predefinida, dada por $ch.

curl_setopt($ch, opcion, valor) - establece una opcion para la sesion de CURL identificada por el parametro $ch, opcion especifica la opcion que se desea establecer, y valor especifica el valor dada la opcion.

curl_setopt($ch,CURLOPT_RETURNTRANSFER,1) - Retorna el contenido de la pagina. Si se establece en 0 no se retornara ninguna salida.


curl_setopt($ch,CURLOPT_URL, $url) - Pasa la url como parametro. Este el el sitio objetivo la direccion url. Esta es la url que vas a obtener desde internet.


curl_exec($ch) - Graba la url y la pasa para la variable a mostrar.

curl_close($ch) -  cierra un recurso curl, libera los recursos del sistema.


 <?php
 // Ejemplo 1
 // Obtener una pagina simple

 $url = "http://arthusu.com.mx/";
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  // Retorna el contenido de la pagina
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // sigue las redirecciones
 curl_setopt($ch, CURLOPT_URL, $url); // Pasa la url como parametro
 $resultado = curl_exec($ch); // graba la url y la pasa para una variable
 curl_close($ch); // cierra el recurso y libera recursos para el sistema

 echo $resultado; // Imprime el contenido de la pagina
?>




jueves, 17 de abril de 2014

[Parte 11] Seguridad en PHP

Criptografia

Literalmente <<escritura oculta>> tradicionalmente se ha definido como parte de la criptologia que se ocupa de las tecnicas, bien sea aplicadas al arte o la ciencia, que alteran las representaciones lingüisticas de mensajes, mediante tecnicas de cifrado o codificado, para hacerlos ininteligibles a intrusos (lectores no autorizados) que interceptan esos mensajes. Por tanto el unico objetivo de la criptografia era conseguir la confidencialidad de los mensajes. Para ello se diseñaban sistemas de cifrado y codigos. 

Los tipos fundamentales de criptografia que un desarrollador en PHP debe conocer son los siguientes:

- La criptografia simetrica
- La criptografia asimetrica (clave publica)
- Funciones hash criptograficos (resumenes de mensajes)
- Los codigos de autenticacion de mensajes (MAC)

La mayoria del tiempo en esta parte nos basaremos en la criptografia simetrica usando la funcion mcrypt.

Almacenar contraseñas 

Nunca debemos almacenar nuestras contraseñas en texto plano, ya que puede contener un grave riesgo de seguridad, es por ello que podemos usar funciones hash seguidas de un salto, por ejemplo:



 <?php
/* $contra contiene la contraseña. */
$salto = 'xsW3#|-AsWGB';
$contra_hash = md5($salto . md5($contra . $salto));
/* almacena el hash contra. */
?>


Si los valores del hash son identicos entonces las contraseñas tambien lo son. Con este tipo de codigo no podemos recuperar las contraseñas, por lo que lo unico que hay que hacer es enviarle una nueva contraseña y actualizar la base de datos.


Usando mcrypt

La funcion estandar para la criptografia en PHP es mcrypt, y tiene un gran listado de compatibilidad con algoritmos, para verlos solo necesitamos usar la funcion mcrypt_list_algorithms():



 <?php
echo '<pre>' . print_r(mcrypt_list_algorithms(), TRUE) . '</pre>';
?>

Para cifrar y descifrar datos usamos las funciones mcrypt_encrypt() y mcrypt_decrypt(), cada una de ellas acepta 5 argumentos:


 <?php
 mcrypt_encrypt($algorithm,
 $key,
 $cleartext,
 $mode,
 $iv);
 mcrypt_decrypt($algorithm,
 $key,
 $ciphertext,
 $mode,
 $iv);
?>


La clave ($key) el segundo argumento es extremadamente sensible, debes tenerlo siempre en algun lugar seguro. Podriamos usar la tecnica que usamos en la parte 8 de seguridad en php, donde aplicabamos la clave de la base de datos. Un key hardware (clave de hardware) es mucho mas seguro, pero mucho mas costoso.

Se pueden utilizar numerosos modos, puedes usar la funcion  mcrypt_list_modes() para ver los modos disponibles:


 <?php
echo '<pre>' . print_r(mcrypt_list_modes(), TRUE) . '</pre>';
?>







El 5to argumento $iv es el vector de inicializacion, y es creado con la funcion mcrypt_create_iv():


 class crypt
{
 private $algorithm;
 private $mode;
 private $random_source;
 public $cleartext;
 public $ciphertext;
 public $iv;
 public function __construct($algorithm = MCRYPT_BLOWFISH,
  $mode = MCRYPT_MODE_CBC,
  $random_source = MCRYPT_DEV_URANDOM)
 {
  $this->algorithm = $algorithm;
  $this->mode = $mode;
  $this->random_source = $random_source;
 }
 public function generate_iv()
 {
  $this->iv = mcrypt_create_iv(mcrypt_get_iv_size($this->algorithm,
  $this->mode), $this->random_source);
 }
 public function encrypt()
 {
  $this->ciphertext = mcrypt_encrypt($this->algorithm,
  $_SERVER['CRYPT_KEY'], $this->cleartext, $this->mode, $this->iv);
 }
 public function decrypt()
 {
  $this->cleartext = mcrypt_decrypt($this->algorithm,
  $_SERVER['CRYPT_KEY'], $this->ciphertext, $this->mode, $this->iv);
 }
}


Esta clase se hace referencia en otros ejemplos, este es su uso:




 <?php
 $crypt = new crypt();
 $crypt->cleartext = 'This is a string';
 $crypt->generate_iv();
 $crypt->encrypt();
 $ciphertext = base64_encode($crypt->ciphertext);
 $iv = base64_encode($crypt->iv);
 unset($crypt);
 /* Almacena $ciphertext y $iv (incializa el vector). */
 $ciphertext = base64_decode($ciphertext);
 $iv = base64_decode($iv);
 $crypt = new crypt();
 $crypt->iv = $iv;
 $crypt->ciphertext = $ciphertext;
 $crypt->decrypt();
 $cleartext = $crypt->cleartext;
?>





 

Almacenamiento de numero de tarjetas de credito

Siempre que se almacenen tarjetas de credito se debe ser cuidadoso, existen unas reglas para mantener seguras nuestras tarjetas de credito, en wikipedia podemos ver al final en la seccion Security: http://en.wikipedia.org/wiki/Bank_card_number

 
En este caso veremos como almacenar una tarjeta de credito encriptando nuestros datos, para ello tambien usaremos la funcion base64_encode() ya que la cadena es binaria:

 <?php
 $crypt = new crypt();
 $crypt->cleartext = '1234567890123456';
 $crypt->generate_iv();
 $crypt->encrypt();
 $ciphertext = $crypt->ciphertext;
 $iv = $crypt->iv;
 $string = base64_encode($iv . $ciphertext);
?>


Esto lo guardamos en la base de datos y lo recuperamos de la siguiente manera:

 <?php
 $string = base64_decode($string);
 $iv_size = mcrypt_get_iv_size($algorithm, $mode);
 $ciphertext = substr($string, $iv_size);
 $iv = substr($string, 0, $iv_size);
 $crypt = new crypt();
 $crypt->iv = $iv;
 $crypt->ciphertext = $ciphertext;
 $crypt->decrypt();
 $cleartext = $crypt->cleartext;
?>
 
Esta implementacion asume un algoritmo y modo consistente. Si estos datos no son encodeados, usted debe almacenarlos para desencriptar los datos. La clave ($key) es la unica que se debe mantener en secreto.


Cifrar datos de sesion

Si piensas que los datos son particularmente sensibles si llegasen a ver los datos de tu base de datos, es posible cifrar los datos de sesion. Esto no es absolutamente necesario pero si piensas que es necesario puedes implementarlo. En la parte 8 de seguridad en php vimos como almacenar los datos de sesion en la base de datos utilizando la funcion session_set_save_handler(), veamos una pequeña modificacion en la forma en que inserta y recupera los datos:


 <?php
function _read($id)
{
 global $_sess_db;
 $algorithm = MCRYPT_BLOWFISH;
 $mode = MCRYPT_MODE_CBC;
 $id = mysql_real_escape_string($id);
 $sql = "SELECT data
 FROM sessions
 WHERE id = '$id'";
 if ($result = mysql_query($sql, $_sess_db))
 {
 $record = mysql_fetch_assoc($result);
 $data = base64_decode($record['data']);
 $iv_size = mcrypt_get_iv_size($algorithm, $mode);
 $ciphertext = substr($data, $iv_size);
 $iv = substr($data, 0, $iv_size);
 $crypt = new crypt();
 $crypt->iv = $iv;
 $crypt->ciphertext = $ciphertext;
 $crypt->decrypt();
 return $crypt->cleartext;
 }
 return '';
}
function _write($id, $data)
{
 global $_sess_db;
 $access = time();
 $crypt = new crypt();
 $crypt->cleartext = $data;
 $crypt->generate_iv();
 $crypt->encrypt();
 $ciphertext = $crypt->ciphertext;
 $iv = $crypt->iv;
 $data = base64_encode($iv . $ciphertext);
 $id = mysql_real_escape_string($id);
 $access = mysql_real_escape_string($access);
 $data = mysql_real_escape_string($data);
 $sql = "REPLACE
 INTO sessions
 VALUES ('$id', '$access', '$data')";
 return mysql_query($sql, $_sess_db);
}
?>


Con esto nuestros datos serian almacenados y leidos de forma segura. Hasta aqui se terminan las partes de seguridad en PHP espero que hayan disfrutado leyendo todo este tiempo.


Referencias:

* Essential PHP Security
* Wikipedia
* PHP documentacion oficial



[Parte 10] Seguridad en PHP

Funciones

Muchas funciones que se utilizan en PHP si no se usan de manera correcta pueden provocar errores de seguridad, es por eso que en este apartado veremos como usarlas de manera adecuada.

eval()

La funcion eval() lo que hace es evaluar una cadena como codigo PHP, por ejemplo:

 <?php
 $nombre= 'arthusu';
 $cadena = 'echo "Hola, $nombre";';
 eval($cadena);?>



Esto lo que hace es ejecutar la variable $cadena como si se tratara de codigo PHP, lo cual es equivalente al siguiente codigo:

 <?php
 $nombre = 'arthusu';
 echo "Hola, $nombre";?>

Mientras es util utilizar la funcion eval(), puede ser peligroso en caso de usarlo en campos de entrada, tal como un variable $_GET, por ejemplo:

 <?php
 $nombre = $_GET['nombre'];
 eval($nombre);?>

Se recomienda evitar el uso de eval(), ya que puede llegar a ejecutar comandos, este tipo de ataque es buen candidato para auditorias web.




exec()

Tal como describiamos en la parte 6 de seguridad en php, la ejecucion de comandos shell es una operacion muy peligrosa, y el uso de un payload puede llegar a crear una vulnerabilidad llamada inyeccion de comandos. Hay que tratar de evitar los comandos de shell, pero cuando sea necesario, escapelos!

 <?php
$limpiar = array();
$shell = array();
/* Filtrar entrada ($comando, $argumento) */
$shell['comando'] = escapeshellcmd($limpiar['comando']);
$shell['argumento'] = escapeshellarg($limpiar['argumento']);
$ultima = exec("{$shell['comando']} {$shell['argumento']}", $salida, $devolver);
?>



file()

Transfiere un fichero completo a un array. Devuelve el fichero a un array. Cada elemento del array se corresponde con una linea del fichero, con el caracter nueva linea aun adjunto. Si falla, file() devuelve FALSE.
El uso de la funcion file() en si, no es particularmente un riesgo, sino que se vuelve un riesgo cuando esta habilitada la directiva allow_url_fopen con la cual puedes hacer referencias a archivos remotos como si fueran archivos locales...


 <?php
$entrada_contaminada = file($_POST['archivo']);
?>


En este caso, nuestra variable estaria contaminada por lo cual seria peligroso, lo recomendable es la utilizacion correcta de la funcion file(), para ello lo unico que debemos hacer es filtrar la entrada como vimos en la parte 1 de seguridad en php y parte 2 de seguridad en php.


file_get_contents()

Transmite un fichero entero a una cadena.Esta funcion devuelve los datos leidos o FALSE en caso de error.
Para esta funcion puede aplicar lo mismo que la funcion file().

fopen()

Abre un fichero o una URL. Devuelve un recurso de puntero a fichero si tiene exito, o FALSE si se produjo error.
Para esta funcion puede aplicar lo mismo que la funcion file().

include()

Tal como describimos en la parte 5 de seguridad en php include() es una funcion que nos ayuda mucho en proyectos grandes y para organizar nuestra aplicacion y modularla. Pero el uso inadecuado de ella puede causar una grave vulnerabilidad, para ello se recomienda filtrar los datos, este tipo de funciones puede ser bueno para escanear en una auditoria web.

passthru()

Ejecuta un programa externo y muestra la salida en bruto.   
Para mas informacion sobre como evitar este tipo de vulnerabilidades ver la funcion exec().

phpinfo()

Muestra informacion sobre la configuracion de PHP. Esto pueden ser datos como la version, las configuraciones, y si esta utilizando la tecnica que usamos en la parte 8 de seguridad en php, puede exponer la variable superglobal $_SERVER, es por eso que se recomienda restringir el acceso a todos los archivos que contengan la funcion phpinfo().

popen()

Abre un proceso de un puntero a un archivo. Devuelve un puntero al archivo identico al devuelto por fopen(), excepto que es uni-direccional (solo se puede usar para lectura o escritura) y debe ser cerrado con pclose(). Este puntero se puede usar con fgets(), fgetss() y fwrite(). Cuando el modo es 'r', el puntero al archivo devuelto iguala al STDOUT del comando, cuando el modo es 'w', el puntero al archivo devuelto iguala a STDIN del comando. Si se produjo un error, devuelve FALSE.
Para evitar este tipo de vulnerabilidades consulte la funcion exec().

preg_replace()

Realiza una busqueda y sustitucion de una expresion regular. Preg_replace() devuelve una matriz si el parametro subject (La cadena o matriz de cadenas a buscar y sustituir) es una matriz, o, por el contrario, una cadena. Si se encuentran coincidencias, el nuevo subject sera devuelto, de otro modo subject sera devuelto sin cambios o NULL si se produjo error. En este caso Pattern que es el patron de busqueda. Puede ser una cadena como una matriz de cadenas. Tambien estan disponibles varios modificadores PCRE, incluyendo el obsoleto 'e' (PREG_REPLACE_EVAL), que es especifico de esta funcion. 


   



 





Esto seria como usar una funcion eval() entonces se desaconseja utilizar esta funcion con el modificador e.

proc_open()

Ejecuta un comando y abre un puntero de fichero para entrada/salida. Devuelve un recurso representando el proceso, cuando se haya terminado con el, debera ser liberado usando proc_close(). En caso de error devuelve FALSE.
Para evitar los riesgos de esta funcion vea la funcion exec().

readfile()

Realizar la salida de un fichero. Devuelve el numero de bytes leidos del fichero. Si se produjo un error, devuelve FALSE y, a menos que la funcion fuese llamada como @readfile(), se imprime un mensaje de error. Para ver las vulnerabilidades que puede causar vea la funcion file().

require()

require es identico a include excepto que en caso de fallo producira un error fatal de nivel E_COMPILE_ERROR. En otras palabras, este detiene el script mientras que include solo emitira una advertencia (E_WARNING) lo cual permite continuar el script. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion include().

shell_exec()

Ejecutar un comando mediante el interprete de comandos y devolver la salida completa como una cadena. Devuelve la salida del comando ejecutado o NULL si ocurre un error o el comando no produce ninguna salida. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion exec().

system()

Ejecutar un programa externo y mostrar su salida. Devuelve la ultima linea de la salida del comando en caso de tener exito, y FALSE si ocurre un error. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion exec().


Referencias:

* Essential PHP Security
* PHP documentacion oficial
* SLA.CKERS
* Wikipedia


lunes, 14 de abril de 2014

Solucion install PECL ZipArchive or `unzip` & 'php_exif.dll' - No se puede encontrar el modulo especificado

Este error ocurre cuando intentas instalar sparks en codeigniter, la solucion en este caso la pondre cuando estamos utilizando appserv, primero que nada, localizamos el archivo php.ini que es la configuracion para php, para ello podemos crear un codigo que contenga la funcion phpinfo() y ver donde se encuentra nuestro archivo de configuracion php.ini lo abrimos y editamos lo siguiente:

para el error install PECL ZipArchive or `unzip`, solamente debemos descomentar: 

;extension=php_zip.dll 

quedando de la siguiente manera: 

extension=php_zip.dll

y para el error 'php_exif.dll' - No se puede encontrar el modulo especificado, solamente debemos invertir el orden de las dlls...
estan de la siguiente manera:

extension=php_exif.dll

extension=php_mbstring.dll
 
y quedan asi:

extension=php_mbstring.dll
extension=php_exif.dll  


Estas son extensiones. Se que esto es algo muy basico pero a mas de alguno le puede servir.


viernes, 11 de abril de 2014


Eliminar cuenta iCloud iPhone 4 [Tutorial]



Ignoren el golpe en la pantalla del touch.

Antes que nada quiero dar las gracias a Arthusu, por dejarme colaborar en su BLOG.



Esta ves les traigo como quitar la cuenta iCloud del iPhone 4.Tratare de explicarlo lo mas posible que pueda para que puedan entenderlo y no se les complique tanto.






ATENCIÓN 

A) Este Procedimiento solo funciona para el iPhone 4, no 4S/5/5C/5S, Solo para iPhone 4.
B) Este Procedimiento no es permanente, ya que la cuenta solo es eliminada del equipo para poder acceder a las aplicaciones.

C) 
La cuenta iCloud sigue activa en el servidor de iTunes,así que si restauran el equipo de fabrica o lo actualizan les volverá aparecer la cuenta iCloud.




Lo primero que necesitamos es tener los drivers, para eso descargamos el iTunes.
Lo podemos descargar desde su pagina principal,les dejo el link de descarga.






iTunes: https://www.apple.com/mx/itunes/download/

Ya que tengamos el iTunes instalado en nuestra pc.

Necesitamos el Software con el que vamos a eliminar la cuenta del equipo.
Link: https://www.mediafire.com/?nvhpgbim97l8zzm

ATENCIÓN 

Antes de instalar el Software, desactiven temporalmente el antivirus,en algunos casos
me comentaron que los detecto como virus en el momento de la instalación.
El Software ya esta probado que funciona correctamente.

Igual en el momento del uso del mismo software, mantengan desactivado el antivirus, por que al momento de enviar los exploits al equipo el antivirus los detecta y no deja enviarlos correctamente.

Ya descargado el Software, lo instalamos en la pc,lo abrimos y nos aparecerá esta ventana.



Ahora procedemos a dar click en la opción "iPhone 4 Hacktivate  Tool"




Se nos abrirá una ventana nueva.



Ya que tengamos esta ventana, procedemos a poner el iPhone en modo DFU.
Muchos ya saben como ponerlo, pero para los que no, les dejo el procedimiento.

  • Apaga tu dispositivo.
  • Pulsa a la vez los botones Home+Power  durante 10 segundos.
  • Pasados los 10 segundos mantén pulsado el botón Inicio y suelta el botón Power.
  • Pasados los 10 segundos iTunes te notificará que el dispositivo esta en modo de recuperación o DFU.




Ya después hecho esto, cerramos iTunes y seguimos con la ventana de nuestro software abierto.





Seleccionamos la primera opción "1) Run SSH_RD Tool"




Se nos abrirá otra ventana, no la cerremos hasta que acabe el proceso.





Esperemos que acabe el proceso.
Nos daremos cuenta que ya acabo cuando les aparezca estas letras al final.

  1. "login: root".
  2. "password: alpine".




No cerremos la ventana, la dejamos abierta y proseguimos con los demás pasos.
Ahora seleccionamos la segunda opción "2) Run SSH Connect"



Se nos abrirá una ventana en ms-dos y no tardara mucho el proceso, cuando termine nos quedara así como muestra en la imagen.





Ahora seleccionamos la tercera opción "3) Run Hacktivate Tool" Esto sin cerrar las dos ventanas anteriores.





Y se nos abrira una Ventana negra en ms-dos y se cerrara en automatico, a esta no logre tomarle captura.
Después de este proceso el iPhone se quedara en modo recovery, les muestro una imagen de como quedara su iPhone.
(
Ignoren el golpe en la pantalla del touch.)


Después de esto seleccionamos la ultima opción "4) Exit Recovery Mode"


Y el iPhone solo se reiniciara y prenderá en la pantalla de activación.
Lo conectamos a nuestra red Wi-Fi y lo empezamos a configurar desde el menú.


Una vez conectado en la red Wi-Fi le damos en "Siguiente"


Y se darán cuenta que ya no les pide la cuenta iCloud.


Ahora solo configuran su iPhone. ( De preferencia desactiven la localización)






Eso es todo amigos, espero les sirva este tutorial.
Cualquier duda o donde se traben, me pueden decir y con mucho gusto respondere sus dudas.

Saludos.