Mostrando entradas con la etiqueta gd. Mostrar todas las entradas
Mostrando entradas con la etiqueta gd. Mostrar todas las entradas

jueves, 21 de mayo de 2015

Creando un catpcha usando PHP GD

Actualmente hay un monton de librerias de captchas en la web, como anteriormente mostre una de google captcha: http://arthusu.blogspot.mx/2014/09/resumen-recaptcha.html

Un desarrollador debe conocer como un captcha es generado. En este tutorial iremos paso a paso como crear un captcha usando PHP GD. El captcha es una cadena generada aleatoria generada automaticamente por numeros/letras, la cadena generada es guardada en algo (como sesiones o base de datos), cuando el usuario envia el formulario, este verifica si el texto introducido por el usuario es igual a la cadena generada y almacenada en la sesion por ejemplo, si coinciden asume que el que ingreso la cadena es un humano y no un bot y el proceso seguiria. En estos dias hay capchas de matematicas tales como 5x_ = 20 y si llenaras el espacio vacio con 4 que seria 5x4 = 20 el formulario es validado. En este tutorial solo nos concentraremos en una imagen de captcha. Para generar un captcha lo que necesitamos nosotros es una cadena aleatoria, para ello utilizaremos la libreria PHP GD, en la mayoria de los casos esta libreria viene instalada por defecto en los servidores. Asi que no discutiremos como instalarla. PHP GD tienen varias funciones para generar imagenes en varios formatos, nosotros comenzaremos con imagecreatetruecolor:

$im = imagecreatetruecolor('150','50');

Lo anterior crea una imagen de 150px de ancho y 50px de alto. Note que $im contiene el recurso de la imagen y no la imagen actual. Nosotros agregaremos componentes a la imagen tal como fondos, cadenas de texto. En este caso requerimos tres colores: primero para el fondo, segundo para la cadena y tercero para hacer unos pixeles de ruido, para que el captcha sea dificultoso para que los bots lo lean. Antes de aplicar estos colores a nuestro recurso de imagen $im primero tenemos que crear los tres colores:

$bg = imagecolorallocate($im, 230, 80, 0); // fondo naranja
$fg = imagecolorallocate($im, 255, 255, 255); // texto blanco
$ns = imagecolorallocate($im, 200, 200, 200); // ruido color gris

Los ultimos tres parametros para imagecolorallocate son el rgb para color. Y el primer parametro es el recurso de la imagen. Entonces ahora tenemos los colores listos, ahora necesitamos llenar la imagen con estos colores, primero agregemos el color de fondo:

imagefill($im, 0, 0, $bg); // el segundo y tercer parametro son las coordenadas x e y para comenzar el llenado de color

Ahora agregamos algunos caracteres a la imagen. Por ahora nosotros agregaremos la palabra 'captcha' pero esta debe ser generada automaticamente en el codigo final.

imagestring($im, 5, 10, 8, 'captcha', $fg);

imagestring dibuja la cadena 'captcha' como quinto parametro. El segundo parametro 5 es el tamaño de la fuente. 10 y 8 son de la esquina arriba a la izquierda las coordenadas x e y para comenzar la cadena desde ese punto. El primer parametro es el recurso de imagen y el ultimo es el color de la cadena. Nosotros agregamos un color de fondo, y una cadena de texto. Esta oficialmente hecho. Pero algunos bots son capaces de leer imagenes. Entonces para defendernos nosotros agregaremos un poco de ruido a la imagen para que solo la puedan leer los humanos y los bots no. 

imagesetpixel($im, 2, 4, $ns);

El codigo de arriba agrega un pixel en la coordenada (2,4) medido desde la esquina arriba izquierda. Obviamente necesitas varios de estos para que la imagen sea mas dificultosa de leer. Ahora es cuando generamos nuestra imagen utilizando imagepng creamos una imagen fuera del recurso $im. Y podemos crear nuestra imagen. 

imagepng($im);

Una buena practica que debemos de tener es destruir la imagen creada, despues de que es mostrada por el navegador ya no la requerimos mas.

imagedestroy($im);

Para que la imagen sea mostrada por el navegador necesitamos enviar algunas cabeceras del tipo de contenido de imagen, en este caso png. El codigo de abajo es llamado antes de que la imagen sea enviada al navegador. Esto es antes de imagepng($im).

header('Cache-Control: no-cache, must-revalidate');
header('Content-type: image/png');

El codigo de abajo es el codigo total. Nota que agregamos todas las funciones y sus parametros discutidos anteriormente. El proposito es agregar nuestro codigo dinamico. Tambien el fondo de ruido con la funcion imagesetpixel es agregado dentro de un loop para ser llamado varias veces. y por ultimo los caracteres del captcha son agregados aleatoriamente. El captcha aleatorio es almacenado en $_SESSION['captcha_code'].

 


 <?php
 
//ancho y alto de la imagen a crear
$width = 90;
$height = 30;
 
//Cantidad de fondo para agregar el ruido a la imagen
$noise_level = 15;
 
//generamos codigo aleatorio en caso de que queramos usar numeros:
//$code=rand(1000,9999);
 
// generamos codigo aleatorio en caso de que queramos usar letras y numeros:
$chars = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
// el tamano del captcha en caracteres ?lenght=5...
$length = (isset($_GET['lenght']) && is_numeric($_GET['lenght'])) ? (int)$_GET['lenght'] : 8;

// Es agregado el captcha aleatorio en la variable $code
$code = "";
for ($i = 1; $i <= $length; $i++)
{
 $code .= $chars[mt_rand(0, strlen($chars)-1)];
}


// guardamos la sesion para la validacion del formulario
session_start();
$_SESSION["captcha_code"]=$code;
 
//creamos el recurso de imagen
$im = imagecreatetruecolor($width, $height);
$bg = imagecolorallocate($im, 230, 80, 0); //color de fondo
$fg = imagecolorallocate($im, 255, 255, 255);//color de texto
$ns = imagecolorallocate($im, 200, 200, 200);//color de ruido
 
//llenamos la imagen del color fondo
imagefill($im, 0, 0, $bg);
 
//Agregamos la cadena aleatoria a la imagen
imagestring($im, 5, 10, 8,  $code, $fg);
 
//Agregamos ruido a la imagen
for ($i = 0; $i < $noise_level; $i++) {
    for($j = 0; $j < $noise_level; $j++) {
        imagesetpixel(
            $im,
            rand(0, $width), 
            rand(0, $height),// nos aseguramos que los pixeles no se salgan de la imagen agregando sus respectivos ancho y alto
            $ns
        );
    }
}
 
//le decimos al navegador el tipo de aimgen
header("Cache-Control: no-cache, must-revalidate");
header('Content-type: image/png');
 
//generamos la imagen
imagepng($im);
 
//destruimos la imagen
imagedestroy($im);
?>


Guardamos el codigo en un archivo php como captcha.php, ahora podemos usar el archivo como recurso de imagen, us uso es simple:

<form method="post" action="">
    <img src="captcha.php">
    <input type="text" name="captcha_code">
    <input type="submit" name="enviar">
</form>



En caso de que queramos agregar menos caracteres (aunque en realidad esta funcion es irrelevante y podria causar problemas futuros), es una buena demostracion:

<form method="post" action="">
    <img src="captcha.php?lenght=4">
    <input type="text" name="captcha_code">
    <input type="submit" name="enviar">
</form>


Ahora para validar el formulario con el captcha por el lado del servidor es como lo siguiente:

    session_start();
    if (isset($_POST['enviar'])) {
        if($_POST["captcha_code"] == $_SESSION["captcha_code"] ){
            //El captcha es correcto, entonces el formulario es procesado.
            echo "Correcto!";
        }
        else{
            //Los caracteres del captcha no coinciden.
            echo "Codigo captcha incorrecto.";
        }
    }



El capcha tambien nos ayuda contra ataques de fuerza bruta como comentamos en el tutorial de seguridad de php numero 7.


Espero que este post les haya sido de utilidad.

Publicacion original: http://perials.com/tutorial-creating-image-captcha-php-using-gd-library/

miércoles, 6 de mayo de 2015

[PHP]Filtros con la libreria GD

Buenas en este caso utilizaremos la libreria PHP GD para aplicar algunos efectos comunes utilizando la funcion imagefilter():

bool imagefilter ( resource $image , int $filtertype [, int $arg1 [, int $arg2 [, int $arg3 [, int $arg4 ]]]] )

Como se describe la sintaxis arriba, necesitamos un recurso de imagen, una constante que aplicara el filtro (varios incluyen opciones y otros no).

Vamos a explicar algunas de las opciones que podremos usar.

IMG_FILTER_NEGATE - Esto lo que hace es negar los colores de la imagen (invertirlos).

IMG_FILTER_GRAYSCALE - Convierte la imagen a escala de grises.

IMG_FILTER_GAUSSIAN_BLUR - Pone la imagen borrosa utilizando el metodo Gaussiano.

IMG_FILTER_EMBOSS - Pone en relieve la imagen.

IMG_FILTER_EDGEDETECT - Detecta los bordes de la imagen para resaltarlos.

IMG_FILTER_BRIGHTNESS - Cambia el brillo de la imagen. Tiene un argumento el cual puede ir del valor -255 a 255.

IMG_FILTER_COLORIZE - Le da un color a toda la imagen, se usan tres parametros RGB (rojo, verde y azul), tambien puedes usar un cuarto parametro para valores alpha que va desde 0 a 127 lo cual le da transparencia a la imagen.

IMG_FILTER_CONTRAST - Cambia el contraste de la imagen.
Tiene un argumento el cual puede ir del valor -255 a 255.

IMG_FILTER_SMOOTH - Suaviza la imagen. Los valores recomendados son de -8 a 8 para que la diferencia se note pero no exageradamente.

Ahora veremos dos ejemplos en practica:

Codigo:

$image = imagecreatefrompng("ay2bdLJ.png");
imagefilter($image, IMG_FILTER_NEGATE); // negar colores

header("content-type: image/png");
imagepng($image);
imagedestroy($image);

Imagen: http://i.imgur.com/HOINYIr.png
Filtro Aplicado: IMG_FILTER_NEGATE
Resultado: 



Codigo:
$image = imagecreatefrompng("space.png");
imagefilter($image, IMG_FILTER_COLORIZE,255,0,0); // le da color a la imagen, red green blue
header("content-type: image/png");
imagepng($image);
imagedestroy($image);

Imagen: http://i.imgur.com/Nix7KLI.png
Filtro Aplicado: IMG_FILTER_COLORIZE
Resultado:


Y hasta aqui esta pequeña introduccion, es muy facil de usar, pero los efectos son bastante buenos, saludos!

lunes, 4 de mayo de 2015

[PHP] Creando una firma dinamica

Introduccion

Buenas he estado sin tiempo para postear pero en esta ocasion les mostraré como crear una firma dinamica de manera que obtengan algunos datos, muchos ya saben como realizarlo por que no tiene tanta dificultad mas que nada se trata de utilizar la libreria de PHP GD.

Un buen tutorial que recomiendo mucho sobre PHP GD es el siguiente: http://wiki.elhacker.net/programacion/php/libreria-gd el cual esta muy bien explicado.
Tratare de ser breve colocando solo los pasos.

Estructura a realizar

La estructura con la que trabajaremos sera la siguiente:


Explicando un poco que hace cada archivo.

.htaccess - Con este archivo interpretaremos imagenes png (con su extension .png) como archivos php y bloquearemos cualquier intento de acceso al archivo logs.txt

firma.php - Con este archivo generamos la imagen dinamica (pronto le cambiaremos la extension a .png)

KeepCalm-Medium.ttf - Es el tipo de letra que utilizaremos para la firma dinamica.

logs.txt - Aqui guardaremos los logs, en este caso IP, Sistema, Si usa proxy.

rVJgsdx.png - Es la imagen que utilizaremos para la firma dinamica. 

view_logs.php - Este es un archivo para ver los logs online. Con un simple formulario que tiene que ingresar una clave.

Nota importante: Nada de aqui es guardado en una base de datos. Y esto es facilmente explotable haciendo peticiones desde la misma IP un sin fin de veces cargaria todo el archivo logs.txt haciendolo demasiado pesado (Esa idea la hizo un amigo JhonJhon_123) entonces lo unico que podemos realizar en este caso es:

1.- Denegar las ips que realizen demasiadas peticiones
2.- No insertar IPS repetidas en el archivo logs.txt
3.- Cambiar el nombre de la carpeta para que no hagan mas peticiones.

Cualquiera de estos tres puntos no se ven en este tutorial.

Creando la firma

En este caso crearemos el archivo PHP para realizar la firma dinamica, no entrare en detalles de explicaciones ya que comente el codigo lo mas posible para que se entendiera, de todas maneras si no entienden algo, arriba deje una buena documentacion con la que pueden guiarse.

 <?php
 // no reportamos errores
 error_reporting(0);
 // el nombre de la imagen a poner como firma
 $im_name = "rVJgsdx.png";
 // los datos de la imagen
 $data_im = getimagesize($im_name);
 // el tipo de imagen
 header("Content-type: {$data_im['mime']}");
 // creamos la imagen en este caso png 
 $im = imagecreatefrompng($im_name);
 // creamos un color para usarlo en el texto
 $color = imagecolorallocate($im, 45, 196, 236);
 // obtenemos la IP
 $ip = $_SERVER['REMOTE_ADDR'];
 // obtenemos los datos del navegador
 $user_agent = $_SERVER['HTTP_USER_AGENT'];
 // vemos si existe algun proxy (no es 100% fiable), y lo agregamos a la variable ip
 $proxy_headers = array(
        'HTTP_VIA',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_FORWARDED',
        'HTTP_CLIENT_IP',
        'HTTP_FORWARDED_FOR_IP',
        'VIA',
        'X_FORWARDED_FOR',
        'FORWARDED_FOR',
        'X_FORWARDED',
        'FORWARDED',
        'CLIENT_IP',
        'FORWARDED_FOR_IP',
        'HTTP_PROXY_CONNECTION'
    );
    foreach($proxy_headers as $x){
        if (isset($_SERVER[$x])) {
         $ip .= "/Estas usando proxy!";
         break;
        }
    }

    // reemplazamos los datos del navegador en caso de que sea firefox por firefox o chrome por chrome, la lista es corta se pueden agregar mas
 $navegador = preg_replace('/.*(firefox|chrome).*/i', '$1', $user_agent);
 // lo mismo que arriba en este caso con el sistema, igual podemos hacer la lista personalizable
 $sistema = preg_replace('/.*(windows|mac|linux).*/i', '$1', $user_agent);
 // guardamos los datos en una variable para usarla en el texto
 $string = " Tu IP: $ip \n Tu navegador: $navegador \n Tu sistema: $sistema \n Te estoy vigilando!\n";
 // asignamos una variable con la fuente para usarla en el texto
 $fuente = "KeepCalm-Medium.ttf";
 // en caso de que no se haya detectado nada mostramos el navegador, aunque nos trolleen xD :P
 if($navegador == ''){
  $navegador = $_SERVER['HTTP_USER_AGENT'];
 }
 // what? :3, Guardamos logs
 $manejador = fopen("logs.txt", 'a+');
 fwrite($manejador, "$string\n\n\n");
 fclose($manejador);
 // magia is here! Mostramos el texto en las coordenadas dadas
 imagettftext($im, 10, 0, 300, 10, $color, $fuente, $string);
 // png transparency, para la transparencia en la imagen sino se veria desfigurada
 imagealphablending($im, true);
 imagesavealpha($im, true);
 imagepng($im);
 // destroy image, liberamos la memoria
 imagedestroy($im);
?>



Asignar formato a la imagen y denegar acceso a los logs

En este apartado crearemos el archivo .htaccess el cual denegara acceso a los logs y interpretara nuestro archivo png como php.

AddType application/x-httpd-php .png
<FilesMatch "\.(txt)$">
  Order Deny,Allow
  Deny from all
</FilesMatch>

Creando archivo para ver los logs

Por ultimo creamos nuestro archivo view_logs.php con el cual veremos los logs. 

 <?php
 if (isset($_POST['pass']) && !empty($_POST['pass']) && $_POST['pass'] == 'tucontraseñae.e') {
  $gestor = fopen('logs.txt', 'r');
  $contenido = fread($gestor, filesize('logs.txt'));
  fclose($gestor);
  echo "<pre>" . $contenido . "</pre>";
 }
?>
<form method="post" action="">
 <p><input type="text" name="pass" /></p>
 <p><input type="submit" name="enviar" /></p>
</form>

En este caso solo hay que cambiar tucontraseñae.e por la contraseña que le quieras asignar a la entrada.

Finalizando

Le cambiamos la extension al archivo firma.php y le ponemos el nombre que queramos en mi caso firma.png
Lo abrimos en el navegador para ver los resultados.


En este caso mi ip es ::1 ya que es una ip local.

Les dejo por ultimo los archivos por si quieren probarlo, igual pueden realizar el suyo propio cambiando algunas funciones como dependiendo del tipo de imagen que sea JPEG, PNG, etc. el tipo de letra, sus datos, etc. De igual manera con esto podrian crearse hasta generadores de firmas, saludos!

Archivos: http://www.mediafire.com/download/wr4yeydjyoyc397/firma_dinamica.rar
 

lunes, 10 de junio de 2013

Entendiendo las coordenadas en una grafica con PHP+GD



Bueno amigos hoy estaba algo aburrido asi que me puse hacer algo que a muchos puede que se les dificulte me incluyo, asi que para que entiendan un poco mejor esto de como interpretar las coordenadas les dejo este tutorial que no pensaba publicar sino que lo habia hecho para entendimiento propio, pero como un amigo dijo: "El conocimiento es libre" asi que espero que ayude a mas de 1 :D

Ver Tutorial: http://www.mediafire.com/view/abzydzvalnwizlr/Entendiendo+las+coordenadas+en+una+grafica+con+PHP+mas+GD.pdf