Cabe mencionar -ya que no lo aclaraste en el post- que con el .htaccess creado lo que hacemos es interpretar los archivos .php como .txt (texto plano) facilitando de ésta manera la lectura de los mismos sin que se ejecuten.
Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.
#82
Back-end / Re:Convertidor Text to Ascii by Cronos
Julio 03, 2012, 02:44:07 PM
Buen script, para iniciar, hace lo que debe de hacer. Mi recomendación es:
Código: php
Primero cambiar el target del formulario a "", para que se procese en el mismo documento puesto que al poner index.php estamos forzando que se envíe a index.php, y ¿qué tal si el script se llama test.php?, pues no se procesara. En segunda almacenar en una variable el valor de cada conversión para al mostrarlo quitarle con la función substr() el último ", " (parámetros: texto, inicio, fin, en éste caso el fin es longitud de variable - 2) quedando así:
Saludos, byeOFF.
<form action="" method="post">
<center>
<h2>Text to Ascii</h2>
<input type="text" name="datos" id="datos" size="30"/>
<input type="submit" value="Convertir" />
</center>
</form>
<center><b><font color="#333333" size="-1">Code by Cronos</font></b></center>
<center>
<?
if($_POST)
{
$datitos = $_POST['datos'];
echo '<br />';
echo '<br />';
for($i=0; $i<strlen($datitos); $i++)
{
$ascii .= ord($datitos[$i]).', ';
}
echo substr($ascii, 0, strlen($ascii) - 2);
}
?>
</center>Primero cambiar el target del formulario a "", para que se procese en el mismo documento puesto que al poner index.php estamos forzando que se envíe a index.php, y ¿qué tal si el script se llama test.php?, pues no se procesara. En segunda almacenar en una variable el valor de cada conversión para al mostrarlo quitarle con la función substr() el último ", " (parámetros: texto, inicio, fin, en éste caso el fin es longitud de variable - 2) quedando así:
88, 116, 51, 109, 80
Saludos, byeOFF.
#83
Dudas y pedidos generales / Re:AYUDA CON HTML Y PHP
Mayo 08, 2012, 10:40:40 PM
Fácil, ocupas sesions o cookies en php, por ejemplo:
Código: php
Y en pagina dos pones:
Código: php
Y te mostraría la sesion de la pagina uno, recordemos que session_start() inicia una sesión si no existe, o la remota si ya existe. Así, cada valor del formulario lo pones en una sesión para al final procesarlos, saludos.
<?php
session_start();
$_SESSION['user'] = $_POST['user'];
?>Y en pagina dos pones:
<?php
session_start();
echo $_SESSION['user'];
?>Y te mostraría la sesion de la pagina uno, recordemos que session_start() inicia una sesión si no existe, o la remota si ya existe. Así, cada valor del formulario lo pones en una sesión para al final procesarlos, saludos.
#84
Back-end / Mostrar últimos comentarios de CuteNews
Abril 28, 2012, 05:02:21 PM
CuteNews es un sistema de gestión de noticias muy fácil de usar y de implementar en la mayoría de los proyectos a nivel web. Sin embargo, a la hora de tratar de mostrar los últimos comentarios se dificulta un poco por lo que he creado un pequeño "hack" para facilitar ésta tarea; claro, como todo script tiene algunos contras:
Pro
Muestra los comentarios a base de un template sumamente editable.
Contra
Se deberan mudar los comentarios manualmente.
Lo primero que debemos hacer es dirigirnos a la línea 95 del archivo show.inc.php de la carpeta inc y sustituír:
Código: php
Por:
Código: php
Después en la línea 342 (contando que ya modificamos lo anterior) agregamos:
Código: php
Con ésto sólo tendríamos el sistema que cada vez que se comente correctamente, abrirá el archivo newComments.txt en la carpeta data y agregará el comentario para posteriormente procesarlo y mostrarlo.
Ahora sólo queda crear el archivo show_comments.php en la raíz del sistema con el siguiente código PHP:
Código: php
Con ésto sólo bastaría tener un iframe de la siguiente forma:
Código: html
La forma de editar el template se basa en la línea 21 del archivo show_comments.php el cual puede ser de varias formas:
Código: php
Inclusive ustedes pueden agregar sus divs como en el último ejemplo. Para mudar los comentarios sólo deben seguir el formato:
Código: html
y guardarlos en el archivo newComments.txt.
Es todo, cualquier duda, comentario o sugerencia comenten.
Pro
Muestra los comentarios a base de un template sumamente editable.
Contra
Se deberan mudar los comentarios manualmente.
Lo primero que debemos hacer es dirigirnos a la línea 95 del archivo show.inc.php de la carpeta inc y sustituír:
$name = trim($name);
$mail = trim($mail);
$id = (int) $id; // Yes it's stupid how I didn't thought about this :/Por:
$name = trim($name);
$namec = trim($name); #Don't edit this (at: Xt3mP)
$mail = trim($mail);
$id = (int) $id; // Yes it's stupid how I didn't thought about this :/
$commentc = $comments; #Don't edit this (at: Xt3mP)Después en la línea 342 (contando que ya modificamos lo anterior) agregamos:
//============================
// Last comments by Xt3mP
//============================
$newComments = @fopen('data/newComments.txt', 'a+');
@fwrite($newComments, $mail.'|'.$namec.'|'.$commentc.'|'.$id.'|'.$time."\r\n");
@fclose($newComments);Con ésto sólo tendríamos el sistema que cada vez que se comente correctamente, abrirá el archivo newComments.txt en la carpeta data y agregará el comentario para posteriormente procesarlo y mostrarlo.
Ahora sólo queda crear el archivo show_comments.php en la raíz del sistema con el siguiente código PHP:
<?php
/*
* Show comments from CuteNews 1.0
* Author: Xt3mP
* Author website: http://xt3mp.mx
* Contact: [email protected]
* Tested on: CuteNews 1.4.6
*/
//============================
// Configuration
//============================
#Where do you've installed cutenews?
$basePath = 'http://localhost/projects/works/Habbostorm/noticias/';
#Where do you've the news show file?
$baseFile = 'show_news2.php';
#The show template
#{url} = News' link
#{comment} = The comment (oh really?)
#{name} = The author
#{date} = Time of the post
$template = '<a href="{url}">{name}</a>:
{comment} - {date}
';
#How many comments wanna show?
$maxComments = 6;
#How length need to be any comment?
$maxLenght = 10;
#The "hack" comment file {don't edit this}
#============================
# Process {don't edit this}
#============================
$dataContent = file_get_contents('data/newComments.txt');
$comments = explode("\r\n", $dataContent);
$from = count($comments) - ($maxComments + 1);
$to = count($comments);
$showComments = array();
for($i = $from; $i < $to; $i++) { $newTemplate = $template; //Stupid fix? $comment = explode('|', $comments[$i]); if(!empty($comment[0])) { $newTemplate = str_replace('{url}', 'show_news2.php?subaction=showcomments&template=&id='.$comment[3].'&archive=&start_from=&ucat=', $newTemplate); if(strlen($comment[2]) > $maxLenght)
$newTemplate = str_replace('{comment}', htmlentities(substr($comment[2], 0, $maxLenght)).'...', $newTemplate);
else
$newTemplate = str_replace('{comment}', htmlentities($comment[2]), $newTemplate);
$newTemplate = str_replace('{name}', htmlentities($comment[1]), $newTemplate);
$newTemplate = str_replace('{date}', date('d M Y h:i a', $comment[4]), $newTemplate);
$showComments[] = $newTemplate;
}
}
#Reverse array way
krsort($showComments);
#Print array
foreach($showComments as $comments)
echo $comments;
?>Con ésto sólo bastaría tener un iframe de la siguiente forma:
<iframe src="show_comments.php" width="200" height"100"></iframe>La forma de editar el template se basa en la línea 21 del archivo show_comments.php el cual puede ser de varias formas:
$template = '<a href="{url}">{name}</a>:<br /> {comment} - {date}<br />';
$template = '<a href="{url}">{comment}</a>:<br /> {date}<br />';
$template = '<a href="{url}">{name}</a>:<br /> {comment}<br />';
$template = '<div id="comment"><div class="name"><a href="{url}">{name}</a>:</div><div class="comment">{comment}</div></div>';Inclusive ustedes pueden agregar sus divs como en el último ejemplo. Para mudar los comentarios sólo deben seguir el formato:
correo|autor|comentario|id_noticia|timestamp(tiempo)y guardarlos en el archivo newComments.txt.
Es todo, cualquier duda, comentario o sugerencia comenten.
#85
Back-end / Crear un login y registro basico con PHP y MySQL
Abril 20, 2012, 02:48:48 AM
Nota: Perdonen la voz pero tuve que fingirla un poco ya que mi voz normal es un tanto grave.
En este tutorial pretendo enseñar como crear un login y un registro básico con tecnología PHP y MySQL; pasando por los puntos más importantes a la hora de creación de un sitio con acceso de usuario.
Recordemos que solo es una base para la creación de un sistema de usuarios con base de datos.
Anotaciones:
Para evitar que se clonen usuarios así:
En este tutorial pretendo enseñar como crear un login y un registro básico con tecnología PHP y MySQL; pasando por los puntos más importantes a la hora de creación de un sitio con acceso de usuario.
Recordemos que solo es una base para la creación de un sistema de usuarios con base de datos.
Anotaciones:
Para evitar que se clonen usuarios así:
- User 1: "Xt3mP"
- User 2: "Xt3mP "
Notemos que al final del segundo usuario tenemos un espacio (" ") en blanco, así que para evitar esto utilizarémos la función trim() la cual elimina los espacios:
También podemos utilizar la función strlen() para contar los carácteres ingresados:
Link de descarga de archivos: You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
#86
Back-end / Descargar imagenes externas con PHP y cURL
Abril 20, 2012, 02:45:22 AM
A veces nos vemos en la necesidad de utilizar imágenes externas pero por x o por y motivos es imposible emplearlas en nuestros sitios web ya que la seguridad o la configuración de donde esta alojada la imagen ha desactivado la accesibilidad mediante el archivo .htaccess (generalmente) o porque el hosting en cuestión a veces no esta en "la nube" haciendo que nuestra página quede con un mal terminado ya que dependemos de imagenes externas (válgame la redundancia).
Entonces, lo más coherente sería descargar las imagenes para no depender de páginas externas que como ya expliqué anteriormente, algún día sin previo aviso pueden dejarnos tirados; y para ello utilizarémos el lenguaje PHP y cURL (librería para trabajar con servidores):
Código: php
Lo que hacemos príncipalmente es iniciar una sesión de cURL y se la asignamos a la variable ch, después agregamos la configuración:
Entonces, lo más coherente sería descargar las imagenes para no depender de páginas externas que como ya expliqué anteriormente, algún día sin previo aviso pueden dejarnos tirados; y para ello utilizarémos el lenguaje PHP y cURL (librería para trabajar con servidores):
<?php
/*
* Descargar imagenes externas con PHP y cURL
* Xt3mP
* [email protected]
*/
function descargarImagen($urlImagen, $target, $directorioBase)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlImagen);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imagen = curl_exec($ch);
curl_close($ch);
$archivo = @fopen($directorioBase.$target, 'w');
if($archivo)
{
echo 'La imagen '.basename($urlImagen).' ha sido descargada a '.$directorioBase.$target;
@fwrite($archivo, $imagen);
@fclose($archivo);
}else{
echo 'La imagen '.basename($urlImagen).' no se ha sido podido descargar';
}
}
descargarImagen('http://xt3mp.mx/wp-content/themes/Polished/images/logo.png', 'miimagen.png', './galeria/');
?>Lo que hacemos príncipalmente es iniciar una sesión de cURL y se la asignamos a la variable ch, después agregamos la configuración:
- CURLOPT_URL: Dirección URL en cuestión.
- CURLOPT_HEADER: Header en cuestión (lo cambiamos a false ya que viene true por default).
- CURLOPT_RETURNTRANSFER: Devolvemos el resultado en string (lo cambiamos a true ya que viene false por default).
Al final, le asignamos a la variable imagen el resultado de la petición cURL para posteriormente abrir la nueva imagen tomando en cuenta los parámetros que le pasamos a la función descargarImagen: - urlImagen: URL de la imagen en cuestión.
- target: Nombre de imagen.
- directorioBase: Directorio donde se guardará la imagen en cuestión.
Luego de esto, el script mostrará un mensaje de success o de failure, según sea el caso. Esta función se deberá hacer manual para cada cada imagen que deseemos descargar por lo que me tome la libertad de hacer una función un poco más compleja que te permite descargar imágenes juntas con el nombre original o el asignado:Código: php <?php
/*
* Descargar imagenes externas con PHP y cURL
* Xt3mP
* [email protected]
*/
function descargarImagen($urlImagenes, $noRepetir = true, $directorioBase, $prefijo = null)
{
foreach($urlImagenes as $id => $urlImagen)
{
$counter = 1;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlImagen);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imagen = curl_exec($ch);
curl_close($ch);
$nombreDearchivo = $prefijo.basename($urlImagen);
if($noRepetir === true && @file_exists($directorioBase.$nombreDearchivo))
{
echo 'La imagen '.basename($urlImagen).' ya existe en '.$directorioBase.$nombreDearchivo.'<br />';
}else{
$infoDearchivo = pathinfo($urlImagen);
while(@file_exists($directorioBase.$nombreDearchivo))
{
$nombreDearchivo = $prefijo.$infoDearchivo['filename'].$counter.'.'.$infoDearchivo['extension'];
$counter++;
}
$archivo = @fopen($directorioBase.$nombreDearchivo, 'w');
if($archivo)
{
echo 'La imagen '.basename($urlImagen).' ha sido descargada a '.$directorioBase.$nombreDearchivo.'<br />';
@fwrite($archivo, $imagen);
@fclose($archivo);
}else{
echo 'La imagen '.basename($urlImagen).' no se ha sido podido descargar.<br />';
}
}
}
}
$urlImagenes = array(
'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png'
);
descargarImagen($urlImagenes, true, './galeria/', 'xt3mp_');
?>
En este caso recibimos 4 (cuatro) parámetros: - urlImagenes: Contiene las direcciones de las imagenes mediante un array.
- noRepetir: Viene en true determinadamente; cambiarlo a false si se requiere que se guarden las imagenes aunque ya existan pero con diferente nombre (ej: foto1.png, foto2.png, foto3.png, fotox.png).
- directorioBase: Directorio donde se guardará la imagen en cuestión.
- prefijo: Prefijo para cada imagen (ej: xt3mp_foto1.png); no es obligatorio (dejarlo vacío si no se requiere).
Y bueno, con esto ya podrían descargar cómodamente sus imágenes externas y guardarlas en la carpeta que mejor lo crean conveniente.
#87
Bugs y Exploits / Las consecuencias de una mala comprobación
Abril 20, 2012, 02:43:35 AM
Es muy común que nos encontremos con sitios webs que tienen un panel de administración junto con un image uploader mal programados haciendo esto que la seguridad del sitio en cuestión quede totalmente en riesgo; por un lado, el no tener buena certificación de las sesiones nos permite navegar por todo el panel administrativo sin restricción alguna y el tener un "image uploader" mal programado nos facilita la tarea a la hora de intentar subir una shell al servidor para tener acceso completo al servidor (o al menos, de la página en cuestión).
Entonces, navegando por Google en busca de un image uploader me encontré con uno de estos paneles en cuestión; al inicio de el directorio nos encontramos con un archivo llamado login.php, el cual, como su nombre lo dice, es el encargado de darnos acceso al panel de administración:

A simples intentos no tenía Blind SQLi ni otras vulnerabilidades parecidas; pero... ¿válida la sesión de los demás archivos correspondiente a la de un administrador?, en este caso: ¡no!, continuando la búsqueda en Google nos encontramos con un archivo .php del panel de administrador indexado que al entrar simplemente nos daba acceso total sin sacarnos por no tener la sesión adecuada:

Código: php
Acá tenemos dos opciones: o alguien accedió antes que yo al servidor y quito la comprobación de sesión (muy, muy dudable) o simplemente el administrador del sitio creeyó que al tener el script en varios paths no se indexaría en los buscadores pensando así que no correría ningún riesgo; opto más por la segunda opción.
Siguiendo con el script, podemos notar que se trata de un image uploader el cual, como todo curioso, procedemos a subir desde el primer intento nuestra shell.php y ¿qué obtenemos?, que efectivamente la subió correctamente puesto que la validación del tipo de archivo en cuestión es incorrecta o simplemente, no fue programada de una manera adecuada.
Despúes entra otra cuestión: ¿en dónde se subió la shell?, revisamos por Live Headers y no se mira hacia donde hace referencia, entonces recurrimos a subir otra imagen en el mismo image uploader y al mostrarnos la información (segunda imagen) damos click derecho en la imagen y ver imagen quedandonos de la siguiente manera:
Al intentar acceder al directorio para revisar si efectivamente esta ahí nos encontramos con que tiene seguridad para no mostrar los "Index Of" al no tener un index la carpeta, por lo que a cuestión de suerte (y con dedos cruzados) cambiamos imagen.jpg (nombre de la imagen en cuestión) por shell.php y bingo, tenemos acceso total al hosting (ya después, se puede proceder a escalar privilegios pero esa es otra historia):

¿Qué quiero decir con esto?, que a veces siendo "curiosos" nos encontramos con scripts mal programados que nos facilitan la tarea a la hora de intentar acceder a un sitio.
P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: Se parchó (se descomentó) la sesión por lo que si no tienes sesión activa, no te permite navegar en el panel de administración.
Entonces, navegando por Google en busca de un image uploader me encontré con uno de estos paneles en cuestión; al inicio de el directorio nos encontramos con un archivo llamado login.php, el cual, como su nombre lo dice, es el encargado de darnos acceso al panel de administración:

A simples intentos no tenía Blind SQLi ni otras vulnerabilidades parecidas; pero... ¿válida la sesión de los demás archivos correspondiente a la de un administrador?, en este caso: ¡no!, continuando la búsqueda en Google nos encontramos con un archivo .php del panel de administrador indexado que al entrar simplemente nos daba acceso total sin sacarnos por no tener la sesión adecuada:

<?php /*?><?php
session_start();
if ($_SESSION['k_admin']<>1) {
echo '<SCRIPT LANGUAGE="javascript">
location.href = "index.php";
</SCRIPT>';
}
?><?php */?>Acá tenemos dos opciones: o alguien accedió antes que yo al servidor y quito la comprobación de sesión (muy, muy dudable) o simplemente el administrador del sitio creeyó que al tener el script en varios paths no se indexaría en los buscadores pensando así que no correría ningún riesgo; opto más por la segunda opción.
Siguiendo con el script, podemos notar que se trata de un image uploader el cual, como todo curioso, procedemos a subir desde el primer intento nuestra shell.php y ¿qué obtenemos?, que efectivamente la subió correctamente puesto que la validación del tipo de archivo en cuestión es incorrecta o simplemente, no fue programada de una manera adecuada.
Despúes entra otra cuestión: ¿en dónde se subió la shell?, revisamos por Live Headers y no se mira hacia donde hace referencia, entonces recurrimos a subir otra imagen en el mismo image uploader y al mostrarnos la información (segunda imagen) damos click derecho en la imagen y ver imagen quedandonos de la siguiente manera:
Citarhttp://web/path/path/imagen.jpg
Al intentar acceder al directorio para revisar si efectivamente esta ahí nos encontramos con que tiene seguridad para no mostrar los "Index Of" al no tener un index la carpeta, por lo que a cuestión de suerte (y con dedos cruzados) cambiamos imagen.jpg (nombre de la imagen en cuestión) por shell.php y bingo, tenemos acceso total al hosting (ya después, se puede proceder a escalar privilegios pero esa es otra historia):

¿Qué quiero decir con esto?, que a veces siendo "curiosos" nos encontramos con scripts mal programados que nos facilitan la tarea a la hora de intentar acceder a un sitio.
P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: Se parchó (se descomentó) la sesión por lo que si no tienes sesión activa, no te permite navegar en el panel de administración.
#88
Bugs y Exploits / Otra forma de bypassear un uploader
Abril 20, 2012, 02:42:01 AM
Nota: Algunas líneas del código de la página en cuestión fueron editadas para poder hacer esta prueba de concepto.
Como expliqué en la entrada pasada (You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login), es muy común encontrarnos con sitios mal válidados pero en esta ocasión nos enfocaremos exclusivamente en nuestro image uploader sin necesitar de una sesión de administrador para poder explotarla.
Generalmente un uploader comprueba que el archivo en cuestión sea una imagen, pero por el otro lado, algunos uploaders comprueban que no se traten de extensiones en específico; aunque desde PHP 5+ ya no se puede fácilmente subir shell utilizando nombres como shell.jpg.txt.php puesto que con la función pathinfo() te regresa solamente la extensión, es decir, aunque tu archivo sea shell.jpg.txt.php.png.php, utilizando la función anteriormente mencionada te regresará php (en este caso).
Un bypass común consiste en modificar las cabeceras (comúnmente el content-type) mediante plugins, scripts o programas que hacen creer al servidor que se trata de una imagen cuando en realidad es una aplicación PHP; pero este tipo de bypass al ser tan conocido y con la función anterior (pathinfo()), ha sido parchado y es más difícil de bypassear por lo que recurriremos a otra técnica que seguro más de uno ya la conoce: shell.jpg con directivas de .htaccess.
En esta ocasión nos encontramos con una página que tiene como fin una comunicación entre alumno y profesor en donde el alumno sube tareas y el profesor las revisa, o el profesor sube trabajos y el alumno los descarga (quiero creer que por eso la validación de archivos es prácticamente nula):

Testeando en primera instancia al intentar subir shell.php nos encontramos con que filtra las variables regresandonos el siguiente error:

Intentamos a ver si de casualidad con Live Headers nos permite subir la shell y nos regresa el mismo error:
Continuamos a buscar donde alojó la shell.jpg y nos encontramos con el mensaje que es obvio:
Acá es donde entra el .htaccess; nosotros sabemos de antemano que shell.jpg es una aplicación PHP bajo la extensión de una imagen y que con .htaccess podemos agregar directivas para que la extensión .jpg la interprete como .php quedando así (recuerda guardarlo como .htaccess):
Código: .htacces
Procedemos a subirlo (y cruzamos dedos para que nos lo permita):

Ahora nos dirigímos a donde se subió la shell.jpg anteriormente y:

P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: En algunos servidores será más difícil decirle las directivas .htaccess puesto que pueden estar desactivadas (como en este caso, en la página uno no permitía por lo que se siguió con el PoC en una segunda página para explicar el concepto), así que no se desesperen.
Como expliqué en la entrada pasada (You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login), es muy común encontrarnos con sitios mal válidados pero en esta ocasión nos enfocaremos exclusivamente en nuestro image uploader sin necesitar de una sesión de administrador para poder explotarla.
Generalmente un uploader comprueba que el archivo en cuestión sea una imagen, pero por el otro lado, algunos uploaders comprueban que no se traten de extensiones en específico; aunque desde PHP 5+ ya no se puede fácilmente subir shell utilizando nombres como shell.jpg.txt.php puesto que con la función pathinfo() te regresa solamente la extensión, es decir, aunque tu archivo sea shell.jpg.txt.php.png.php, utilizando la función anteriormente mencionada te regresará php (en este caso).
Un bypass común consiste en modificar las cabeceras (comúnmente el content-type) mediante plugins, scripts o programas que hacen creer al servidor que se trata de una imagen cuando en realidad es una aplicación PHP; pero este tipo de bypass al ser tan conocido y con la función anterior (pathinfo()), ha sido parchado y es más difícil de bypassear por lo que recurriremos a otra técnica que seguro más de uno ya la conoce: shell.jpg con directivas de .htaccess.
En esta ocasión nos encontramos con una página que tiene como fin una comunicación entre alumno y profesor en donde el alumno sube tareas y el profesor las revisa, o el profesor sube trabajos y el alumno los descarga (quiero creer que por eso la validación de archivos es prácticamente nula):

Testeando en primera instancia al intentar subir shell.php nos encontramos con que filtra las variables regresandonos el siguiente error:
CitarExtensión php no permitida.Por lo tanto procedemos a subir shell.jpg y notamos que la sube sin ningún problema:

Intentamos a ver si de casualidad con Live Headers nos permite subir la shell y nos regresa el mismo error:
CitarExtensión php no permitida.
Continuamos a buscar donde alojó la shell.jpg y nos encontramos con el mensaje que es obvio:
CitarNo se puede mostrar la imagen "http://web/path/path/shell.jpg" porque contiene errores.
Acá es donde entra el .htaccess; nosotros sabemos de antemano que shell.jpg es una aplicación PHP bajo la extensión de una imagen y que con .htaccess podemos agregar directivas para que la extensión .jpg la interprete como .php quedando así (recuerda guardarlo como .htaccess):
RemoveHandler .jpg
AddHandler application/x-httpd-php .jpg
AddType application/x-httpd-php .jpgProcedemos a subirlo (y cruzamos dedos para que nos lo permita):

Ahora nos dirigímos a donde se subió la shell.jpg anteriormente y:

P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: En algunos servidores será más difícil decirle las directivas .htaccess puesto que pueden estar desactivadas (como en este caso, en la página uno no permitía por lo que se siguió con el PoC en una segunda página para explicar el concepto), así que no se desesperen.
#89
Bugs y Exploits / Bypassear uploader con validacion en JavaScript
Abril 20, 2012, 02:39:49 AM
Estamos en una época en donde utilizar tecnología dinámica (refiriendome a programación; como lo es JavaScript, entre otros) hace que un sitio se posicione entre los favoritos por la interacción en tiempo real entre cliente > servidor < cliente. Algo de lo más notorio de lo anterior mencionado es que trae consigo mismo un enfoque en la seguridad a nivel cliente dejando de lado la seguridad a nivel servidor (cosa que es terriblemente riesgoso). Esta ocasión me encontré con un uploader de imagenes que no permitía subir ningún archivo; y no porque validará la extensión, si no que utiliza funciones natas de PHP que hacen que la operación de cargar el archivo sea incorrecta:


A primera instancia notamos (como ya mencione) que no valida la extensión del archivo por lo que si no existieran esas funciones tendríamos desde ya nuestra shell arriba; por otro lado, notamos que hace referencia al archivo upload_.php que en realidad no nos sirve de nada por lo que procedemos buscando algo que nos sea útil. Generalmente, estos uploaders no tienen un .htaccess o un index que restringa el listado de archivos, es decir, quedan al descubierto los demás archivos encontrandonos así con el resto de los archivos del servidor (al menos los de la carpeta en cuestión); navegando por dichos archivos notamos que existe otro uploader más pero este es para archivos .mp3:


Intentando subir la shell en extensión .php (como lo hemos estado intentando hasta ahorita) notamos que nos regresa en tiempo real un error de la siguiente manera ya que valida la extensión del archivo:

A simple vista nos damos cuenta que se trata de algún lenguaje dinámico, como lo es JavaScript por lo que procedí a revisar el código fuente y nos encontramos con la siguiente función:
Código: javascript
Notamos que nos valida la extensión tomando de referencia el último punto (.) por lo que si intentamos subir shell.mp3.php sería inútil, revisando el resto del código fuente notamos que hace referencia a otro archivo .php que es el encargado de procesar el archivo en cuestión, y esto era de esperarse, ya que en el uploader anterior también hacia referencia a otro archivo.
Es aquí donde entra el ingenio para saltarse la protección en JavaScript, aclaro que todavía no estaba seguro si subiría la shell porque creí que tenía también comprobación en PHP.
Lo que hicimos fue abrir un documento de texto (en cualquier editor) y simular el formulario original quedándonos de esta manera:

Código: html
Después, cargamos la shell como archivo (al dar click en el file loader) y presionamos Enviar; como en este caso no existe ninguna función validar() que al dar click al ítem submit nos regresa true porque no hay nada que impida que el formulario se envíe a el target indicado, y ¿qué resultado obtenemos?, que en este caso no valida la extensión por PHP haciendo que esto sea posible:


Por lo tanto, mi recomendación es que si quieren ser parte de estos sitios bonitos, no solo comprueben la seguridad a nivel cliente, si no también a nivel servidor.
Nota: Para hacer esto más sencillo también basta con enviar cabeceras (y el archivo en ellas) o desactivar JavaScript directamente:

P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).


A primera instancia notamos (como ya mencione) que no valida la extensión del archivo por lo que si no existieran esas funciones tendríamos desde ya nuestra shell arriba; por otro lado, notamos que hace referencia al archivo upload_.php que en realidad no nos sirve de nada por lo que procedemos buscando algo que nos sea útil. Generalmente, estos uploaders no tienen un .htaccess o un index que restringa el listado de archivos, es decir, quedan al descubierto los demás archivos encontrandonos así con el resto de los archivos del servidor (al menos los de la carpeta en cuestión); navegando por dichos archivos notamos que existe otro uploader más pero este es para archivos .mp3:


Intentando subir la shell en extensión .php (como lo hemos estado intentando hasta ahorita) notamos que nos regresa en tiempo real un error de la siguiente manera ya que valida la extensión del archivo:

A simple vista nos damos cuenta que se trata de algún lenguaje dinámico, como lo es JavaScript por lo que procedí a revisar el código fuente y nos encontramos con la siguiente función:
function validar() {
var archivo = document.SubirMp3.mp3.value;
extensiones_permitidas = new Array(".mp3", ".wma");
mierror = "";
if (!archivo) {
//Si no tengo archivo, es que no se ha seleccionado un archivo en el formulario
mierror = "No has seleccionado ningún archivo";
}else{
//recupero la extensión de este nombre de archivo
extension = (archivo.substring(archivo.lastIndexOf("."))).toLowerCase();
//alert (extension);
//compruebo si la extensión está entre las permitidas
permitida = false;
for (var i = 0; i < extensiones_permitidas.length; i++) {
if (extensiones_permitidas[i] == extension) {
permitida = true;
break;
}
}
if (!permitida) {
mierror = "Compruebe la extensión del archivo de sonido seleccionado. \nSólo se pueden subir archivos con extension: " + extensiones_permitidas.join();
}else{
//submito!
SubirMp3.submit();
return true;
}
}
//si estoy aqui es que no se ha podido submitir
alert (mierror);
return false;
}Notamos que nos valida la extensión tomando de referencia el último punto (.) por lo que si intentamos subir shell.mp3.php sería inútil, revisando el resto del código fuente notamos que hace referencia a otro archivo .php que es el encargado de procesar el archivo en cuestión, y esto era de esperarse, ya que en el uploader anterior también hacia referencia a otro archivo.
Es aquí donde entra el ingenio para saltarse la protección en JavaScript, aclaro que todavía no estaba seguro si subiría la shell porque creí que tenía también comprobación en PHP.
Lo que hicimos fue abrir un documento de texto (en cualquier editor) y simular el formulario original quedándonos de esta manera:

<form action="http://web/path/path/uploadmp3_.php" method="POST" ENCTYPE="multipart/form-data" onSubmit="return validar()">
<input name="mp3" type="file"><input name="submit" type="submit" value="Enviar"></FORM>Después, cargamos la shell como archivo (al dar click en el file loader) y presionamos Enviar; como en este caso no existe ninguna función validar() que al dar click al ítem submit nos regresa true porque no hay nada que impida que el formulario se envíe a el target indicado, y ¿qué resultado obtenemos?, que en este caso no valida la extensión por PHP haciendo que esto sea posible:


Por lo tanto, mi recomendación es que si quieren ser parte de estos sitios bonitos, no solo comprueben la seguridad a nivel cliente, si no también a nivel servidor.
Nota: Para hacer esto más sencillo también basta con enviar cabeceras (y el archivo en ellas) o desactivar JavaScript directamente:

P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
#90
Front-end / [JQuery][BASICO] Permitir solo numeros
Abril 20, 2012, 02:35:13 AM
A veces por cuestiones de la vida nos vemos en la situación de validar que caracter es ingresado permitiendo sólo así el ingreso de caracteres numéricos. Existen muchas maneras de lograrlo pero en mi caso, lo necesario era que en cuanto el visitante presione una tecla, validarla en tiempo real para solo permitir los caracteres que queremos; en éste caso, numéricos.
Haremos uso del evento keydown tomando como evento el caracter presionado pero antes, por cuestiones de eficacia y porque seguramente necesitamos usarlo en varios input/textarea, le asignaremos una clase de esta manera:
Código: html5
Ahora agregaremos el evento de la siguiente manera:
Código: javascript
Con esto nos bastaría para solo permitir números aunque con IE8 tuve problemas. Y respecto a qué hacemos, pues fácil. Mandamos mediante "event" la tecla pulsada y la comparamos con su "char key code". Los podemos encontrar en You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Hay otras formas de hacer lo mismo, por ejemplo, utilizando isNaN (is not a number). Todo varia dependiendo la experiencia de cada programador aunque sinceramente a esto no le veo mucha ciencia así que espero que haya sido de utilidad aunque sea un poco, ya que estoy seguro que al menos una vez en la vida necesitaremos validar caracteres numéricos dejando de lado PHP, ASP, etc.
Haremos uso del evento keydown tomando como evento el caracter presionado pero antes, por cuestiones de eficacia y porque seguramente necesitamos usarlo en varios input/textarea, le asignaremos una clase de esta manera:
<input class="validar" type="text" name="casilla_1" />
<input class="validar" type="text" name="casilla_2" />Ahora agregaremos el evento de la siguiente manera:
$(function(){
$(".validar").keydown(function(event){
if(event.keyCode < 48 || event.keyCode > 57){
return false;
}
});
});Con esto nos bastaría para solo permitir números aunque con IE8 tuve problemas. Y respecto a qué hacemos, pues fácil. Mandamos mediante "event" la tecla pulsada y la comparamos con su "char key code". Los podemos encontrar en You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login
Hay otras formas de hacer lo mismo, por ejemplo, utilizando isNaN (is not a number). Todo varia dependiendo la experiencia de cada programador aunque sinceramente a esto no le veo mucha ciencia así que espero que haya sido de utilidad aunque sea un poco, ya que estoy seguro que al menos una vez en la vida necesitaremos validar caracteres numéricos dejando de lado PHP, ASP, etc.
#91
Back-end / Re:Empesando Con el PHP By OKOL [echo br comentarios y algo de variables]
Abril 18, 2012, 02:14:23 PMYou are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or LoginVaya, me da gusto leerte por acá y pues bueno, en realidad la clase es sólo para él, no sabía que postearía acá.
no sabia que @Xt3mP daba clase jejeje y mucho menos hace tiempo xD, un dia de esto te pido que me des alguna clase xD.
Saludos y bien hecho.
Reitero: me da gusto verte online de nuevo.
#92
Back-end / Re:Empesando Con el PHP By OKOL [echo br comentarios y algo de variables]
Abril 18, 2012, 12:32:06 AM
Aclararte algunas cosas:
- echo es un constructor que te imprime un valor en pantalla.
- Para pasar de línea en lenguaje semántico (HTML) puede ser <br /> o <br>.
- No es necesario hacer 3 echos cuando puedes hacer echo 'Texto <br />Text</br >Text<br />Text';
- Los comentarios, como en cualquier lenguaje, sirven como anotaciones para facilitar el entendimiento del código en cuestión.
- Recordarte que si ponemos un string con variable en comillas simples '' es interpretado literalmente, de lo contrario, al poner comillas dobles "", se procesa como variable como tal.
- Punto une variables y textos, no sólo variables.
Saludos.
#93
Bugs y Exploits / Re:PROXYgetter
Abril 16, 2012, 07:40:02 PM
Fue en python, me equivoqué; y sobre las páginas, en una oportunidad las actualizo. Gracias.
#94
Bugs y Exploits / Re:PROXYgetter
Abril 16, 2012, 05:52:22 PM
Acá está el de Dedalo:
Código: perl
Sólo que los lista sin comprobarlos, saludos.
from urllib2 import Request, urlopen, URLError, HTTPError
import urllib2, string, re
def test(ip, puerto):
proxy = urllib2.ProxyHandler({"http" : ip+":"+puerto})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
try:
web=urllib2.urlopen("http://whatismyip.org/", timeout=3)
print web.read()
f=open("ip.txt", "a")
f.write(ip+":"+puerto+"\n")
except Exception as e:
print str(e)
def extractor():
a=urllib2.urlopen("http://www.cybersyndrome.net/pla5.html")
list= a.readlines()
cad=list[106]
cadena=cad.split("</li>")
for i in cadena:
inicio=i.find('">')
fin=i.find('</a>')
proxypuerto=i[inicio+2:fin]
if proxypuerto!='/ol>':
proxy=proxypuerto.split(":")
ip=str(proxy[0])
puerto=str(proxy[1])
print "ip/url: "+str(ip)+"\n"
print "puerto: "+str(puerto)+"\n"
print "resultado: "
test(ip, puerto)
print "------------------------"
if __name__ == "__main__":
print "PROXY FINDER By Dr.Neox And Dedalo for Backroot.org"
extractor()
anon()Sólo que los lista sin comprobarlos, saludos.
#95
Bugs y Exploits / PROXYgetter
Abril 16, 2012, 04:02:31 AM
PROXYgetter es una herramienta en PHP la cual fue inspirada en la herramienta de Dedalo en python, es decir, el mecanismo es diferente pero la idea principal fue tomada de dicho script.

Actualmente consta de dos páginas donde obtengo los proxys:

Actualmente consta de dos páginas donde obtengo los proxys:
- You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
- You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Funcionamiento
El mecanismo es sumamente fácil; mediante expresiones regulares obtengo una lista de proxys a los cuales mediante sockets compruebo el tiempo de conexión para solo mostrar los que el usuario requiera ya que tiene un sistema de personalización. - Max. pages (1-5): Se puede ingresar un número del 1 al 5 tomando de referencia que la página You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login solo tiene 5 páginas.
- Timeout: El tiempo máximo de espera.
- Show all results: Sirve para mostrar resultados tanto positivos como negativos.
- Stop processing if there's X positive matches: Indicamos cuantos proxys correctos debe haber para detener la carga del script; 0 significa todos.
Código: php <?php
/*
* Name: PROXYgetter
* Author: Xt3mP
* Contact: xt3mp[at]null[dot]net
* Bugs: xt3mp[at]null[dot]net
* Personal website: http://xt3mp.mx
* Website: http://backroot.org
* Version: 1.0 BETA
*/
ob_implicit_flush();
set_time_limit(0);
?>
<!DOCTYPE html>
<html>
<head>
<title>PROXYgetter v1.0 [Xt3mP]</title>
<style type="text/css">body{background-color:#000;color:#FFF;font-family:"Courier New";font-size:14px}div#container{background-color:#151515;border:1px dashed #FFF;margin:0 auto;padding:5px;text-align:center;width:800px}input{font-family:"Courier New";text-align:center}h1{border-bottom:1px dashed #FFF;border-top:1px dashed #FFF;margin:0 0 5px;padding:0}p{border-top:1px dashed #FFF;margin:5px 0 0;padding:0}a{color:lime;text-decoration:none}a:hover{color:#FFF}.result{border-top:1px dashed #FFF}</style>
</head>
<body>
<div id="container">
<pre>
______ ______ _______ ___ ___ ___ ___ __ __PROXYgetter v1.0
| __ \| __ \| || | || | |.-----..-----.| |_ | |_ .-----..----.
| __/| <| - ||- -| \ / | _ || -__|| _|| _|| -__|| _|
|___| |___|__||_______||___|___| |___| |___ ||_____||____||____||_____||__|
|_____| Powered By Xt3mP
xt3mp[at]null[dot]net
</pre>
<h1>Free proxys for you</h1>
<form action="" method="POST">
For each page, the script tries to verify the connection of 50 proxys.<br />
Max. pages (1-5): <input type="text" name="pages" value="5" size="1" maxlength="1"> -
Timeout: <input type="text" name="timeout" value="1" size="1" maxlength="1"><br />
Show all results: <select name="show"><option value="no">No</option><option value="yes">Yes</option></select><br />
Stop processing if there's <input type="text" name="stop" value="0" size="2" maxlength="2"> positive matches<br />
<font color="red">[0: All]</font><br />
<input type="submit" name="get" value="Give me proxys for free!">
</form>
<?php
if(isset($_POST['get']))
{
echo '<div class="result">';
$proxyList = array();
$pages = (!is_numeric($_POST['pages']) or $_POST['pages'] < 1 or $_POST['pages'] > 5) ? 5 : abs($_POST['pages']);
$timeOut = (!is_numeric($_POST['timeout'])) ? 5 : abs($_POST['timeout']);
$show = ($_POST['show'] != 'no' && $_POST['show'] != 'yes') ? 'yes' : $_POST['show'];
$stop = ($_POST['stop'] == 0 or !is_numeric($_POST['stop']) or $_POST['stop'] > 50) ? 'all' : abs($_POST['stop']);
$counter = 0;
$quit = false;
#This section of the code
#is for proxys.com.ar
for($i = 0; $i <= $pages; $i++)
{
if($quit)
{
break;
}else{
$web = ($i == 0) ? 'http://www.proxys.com.ar/' : 'http://www.proxys.com.ar/index.php?act=list&port=&type=&country=&page='.$i;
$webContent = @file_get_contents($web);
$_pattern1 = "/<tr class=\"cells\" onmouseover=\"this\.className='cells2'\" onmouseout=\"this\.className='cells'\">(.*?)<\/tr>/is";
$pregMatch = @preg_match_all($_pattern1, $webContent, $proxyData, PREG_SET_ORDER);
for($x = 0; $x<count($proxyData); $x++)
{
$_pattern2 = "/<td>(.*)<\/td>/i";
$pregMatch = @preg_match_all($_pattern2, $proxyData[$x][1], $proxyConnect, PREG_SET_ORDER);
$proxyIp = $proxyConnect[0][1];
$proxyPort = $proxyConnect[1][1];
$proxyCountry = $proxyConnect[3][1];
$proxyTarget = $proxyIp.':'.$proxyPort;
$fp = @fsockopen($proxyIp, $proxyPort, $errno, $errstr, $timeOut);
if($fp)
{
if(!in_array($proxyTarget, $proxyList))
{
$counter++;
array_push($proxyList, $proxyTarget);
echo '<font color="lime">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';
if($counter == $stop)
{
$quit = true;
break;
}
}
}elseif(!$fp && $show == 'yes'){
echo '<font color="red">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';
}
}
}
}
#This section of the code
#is for xroxy.com
if(!$quit)
{
$latency = $timeOut * 1000;
$web = 'http://www.xroxy.com/proxylist.php?port=&type=&ssl=&country=&latency='.$latency.'&reliability=#table';
$webContent = @file_get_contents($web);
$_pattern1 = "/<tr class='row[(1|0){1}]'>(.*?)<\/tr>/is";
$pregMatch = @preg_match_all($_pattern1, $webContent, $proxyData, PREG_SET_ORDER);
for($i=0; $i<count($proxyData); $i++)
{
$_pattern2 = "/<td[( nowrap='nowrap'>|>)?](.*?)<\/td>/s";
$pregMatch = @preg_match_all($_pattern2, $proxyData[$i][1], $proxyConnect, PREG_SET_ORDER);
$proxyIp = @preg_replace("/\s/", '', $proxyConnect[1][1]);
$proxyPort = $proxyConnect[2][1];
$proxyCountry = str_replace("nowrap='nowrap'>", "", $proxyConnect[5][1]);
$proxyTarget = $proxyIp.':'.$proxyPort;
echo '<font color="lime">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';
}
}
//echo count($proxyList).' matches.';
echo '</div>';
}
?>
<p>Coded by <a href="http://xt3mp.mx">Xt3mP</a> for <a href="http://backroot.org">backroot.org</a></p>
</div>
</body>
</html>
Proof:
Nota: Los proxys devueltos fueron testeados en Mozilla, además, el script es un poco simple.
Saludos.
#96
Bugs y Exploits / HASHorator [MD5 cracker]
Abril 16, 2012, 03:58:23 AM
HASHorator es una aplicación que programé ya hace un tiempo en PHP la cual tiene como fin tratar de decifrar por manera inversa a base de otras páginas con base de datos de hash anteriormente creados para tratar de encontrar un match.
Por el momento cuenta con 13 páginas sin dejar a un lado la opción de meter un diccionario, a continuación explico un poco más las características de este pequeño pero útil script:

Select cipher type/Seleccionar tipo de cifrado:
Por el momento cuenta con 13 páginas sin dejar a un lado la opción de meter un diccionario, a continuación explico un poco más las características de este pequeño pero útil script:

Select cipher type/Seleccionar tipo de cifrado:
- MD5 ($pass)
- SHA1 ($pass)
- SMF ($salt.$pass)
Put HASH/Ingresar HASH: - Mediante expresiones regulares se puede tratar de comprobar que el hash ingresado sea el correcto ([a-f0-9]{long}).
Put SALT/Ingresar SALT: - Opción solo disponible para SMF
Dictionary/Diccionario:
Opción disponible para los 3 tipos de cifrados, en la variable $max se especifica el máximo de palabras por diccionario. - Stop processing if there's a positive match/Parar el procesamiento al primer resultado positivo:
Opción para detener el script al primer resultado positivo; esto puede acelerar el tiempo de ejecución del script (recomendable).
Tengo una página que rompe MD5 pero no se como agregarla al script:
El script tiene como motor el array multidimensional $data el cual contiene 4 arrays importantes:
pages: Contiene la página a donde se enviará la petición POST o GET por cURL.
parameters: Los parámetros del formulario o de la URL.
sustitution: Las expresiones regulares para sacar exclusivamente el resultado (en caso de ser positivo).
security: Para eliminar etiquetas repetidas.
Tomaremos de ejemplo la página You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login, al nosotros ingresar un hash para desencriptar nos regresará:Citar<b>Md5 Hash:</b> dc02aab0ea69aab5be23c7d966bd04a1<br/><br/><img src="line.gif"/><br/><br/><b><font size="2">Decrypted Text: </font></b><font size="2">[email protected]</font>
Por lo tanto, nuestro array multidimensional debe constar de: - pages: La página a donde hace referencia; si es por GET en vez por URL se pone la url You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login o You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login según sea el caso y los parámetros se ponen como null.
- parameters: Parámetros del formulario; si es por GET la petición se pone null.
- sustitution: La expresión regular
- security: Generalmente null si no se repiten tags
Código con ejemplo POST y GET:Código: php <?php
$data = array(
'pages' => array(
0 => 'http://md5decryption.com/'
1 => 'http://md5.rednoize.com/?q='.$hash
),
'parameters' => array(
0 => 'hash='.$hash.'&submit=Decrypt It!'
1 => null
),
'sustitution' => array(
0 => "/Decrypted Text: <\/b>(.*)<\/font>/"
1 => "/<div id=\"result\" >(.*)<\/div>/"
),
'security' => array(
0 => null
1 => null
)
);
?>
Recordemos que el 0 y 1 debe ser el número siguiente, en este caso, si tratamos de añadir una página más sería el 2 =>.Código: php <?php
/*
* Name: Hashorator
* Author: Xt3mP
* Contact: xt3mp[at]null[dot]net
* Bugs: xt3mp[at]null[dot]net
* Personal website: http://xt3mp.mx
* Website: http://backroot.org
* Version: 1.0 BETA
*/
set_time_limit(0); //30 seconds default
$max = 100000; //Max words per dictionary
?>
<title>Hashorator v1.0 [Xt3mP]</title>
<style type="text/css">body{font-family:Courier;background-color:#000;color:#FFF;font-size:13px}div#container{width:690px;height:auto;border:1px dashed #FFF;margin:0 auto}div#container a{text-decoration:none;color:#FF5B5B}div#container a:hover{color:#FFF}div#menu{width:100%;height:auto;border-top:1px dashed #FFF;border-bottom:1px dashed #FFF;text-align:center}div.border{border-top:1px dashed #FFF;text-align:center;color:red}div#container input{background-color:#FFF;color:#000;border:1px solid #FFF;font-family:Courier;cursor:pointer;text-align:center;padding:5px}pre.none{width:auto;margin:0;padding:0}div#result{width:100%;height:auto;font-size:12px}div#container textarea{border:1px solid #FFF}</style>
<script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<script>$(function(){$("#salt").css("background-color","#999").attr("disabled",true);$("#dic").css("background-color","#999").attr("disabled",true);$("#usedic").click(function(){if($("#dic").attr("disabled")==true){$("#dic").attr("disabled",false).css("background-color","#FFF").css("color","#000");$("#dictionary").val("yes")}else{$("#dic").attr("disabled",true).val("").css("background-color","#999");$("#dictionary").val("no")}});$("#type").change(function(){var a=$("select#type option:selected").val();if(a=="mysql"){$("#salt").css("background-color","#999").val("").attr("disabled",true);$("#dic").css("background-color","#999").val("").attr("disabled",true);$("#usedic").attr("disabled",true).attr("checked",false);$("#dictionary").val("no")}else if(a=="smf"){$("#salt").css("background-color","#FFF").css("color","#000").attr("disabled",false);$("#dic").css("background-color","#FFF").val("").attr("disabled",false);$("#usedic").attr("disabled",true).attr("checked",true);$("#dictionary").val("yes")}else{$("#salt").css("background-color","#999").val("").attr("disabled",true);$("#dic").css("background-color","#999").attr("disabled",true);$("#usedic").attr("disabled",false).attr("checked",false);$("#dictionary").val("no")}})})</script>
<div id="container">
<pre>
___ ___ __ __ Hashorator v1.0
| Y |.---.-..-----.| |--..-----..----..---.-.| |_ .-----..----.
|. 1 || _ ||__ --|| || _ || _|| _ || _|| _ || _|
|. _ ||___._||_____||__|__||_____||__| |___._||____||_____||__|
|: | |
|::.|:. | Powered By Xt3mP
`--- ---' xt3mp[at]null[dot]net
</pre>
<div id="menu">
<form action="" method="POST">
Select cipher type:
<select name="type" id="type">
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<!-- <option value="mysql">MySQL</option> -->
<option value="smf">SMF</option>
</select><br />
Put HASH: <br />
<input type="text" name="hash" value="" maxlength="40" size="41"/><br />
Put SALT <a href="#">(?)</a>: <br />
<input type="text" name="salt" id="salt" value="" maxlength="40" size="41"/><br />
Dictionary: <input type="checkbox" id="usedic" name="usedic" value="yes"><br />
<input type="hidden" value="no" id="dictionary" name="dictionary" />
<textarea name="dic" id="dic" rows="5" cols="50"></textarea><br />
Stop processing if there's a positive match: <input type="checkbox" name="stop" value="yes"><br />
<input type="submit" name="submit" value="Decipher"/>
</form>
</div>
<div id="result">
<?php
$start = microtime(true);
function checkHash($hash, $long)
{
return preg_match('/^[a-f0-9]{'.$long.'}$/', $hash);
}
if(isset($_POST['submit'])):
$hash = htmlentities($_POST['hash']);
$salt = htmlentities($_POST['salt']);
$type = $_POST['type'];
$usedic = $_POST['dictionary'];
$dic = $_POST['dic'];
$stop = $_POST['stop'];
$counter = 0;
if($type == 'md5'):
if(!checkHash($hash, 32)):
echo '<div class="border">The entered hash doesn\'t look like MD5</div>';
exit();
else:
$data = array(
'pages' => array(
0 => 'http://md5decryption.com/',
1 => 'http://md5-decrypter.com/',
2 => 'http://md5.rednoize.com/?q='.$hash,
3 => 'http://md5.hashcracking.com/search.php?md5='.$hash,
4 => 'http://www.md5rainbow.com/'.$hash,
5 => 'http://md5crack.com/crackmd5.php',
6 => 'http://md5pass.info/',
7 => 'http://md5.unidadlocal.com/'.$hash,
8 => 'http://www.hashhack.com/index.php',
9 => 'http://www.md5this.com/crackit.php',
10 => 'http://md5hack.com/md5_cracker.php',
11 => 'http://www.md5.net/cracker.php',
12 => 'http://crackstation.net/index.php'
),
'parameters' => array(
0 => 'hash='.$hash.'&submit=Decrypt It!',
1 => 'data[Row][cripted]='.$hash,
2 => null,
3 => null,
4 => null,
5 => 'term='.$hash.'&submit=Crack that hash baby!',
6 => 'hash='.$hash.'&get_pass=Get Pass',
7 => null,
8 => 'hash='.$hash.'&antispam=7',
9 => 'h='.$hash.'&s=Crack it!',
10 => 'dico=dicos/1.txt&hash='.$hash.'&ok= Crack ',
11 => 'hash='.$hash,
12 => 'hashes='.$hash.'&crack=Crack Hashes'
),
'sustitution' => array(
0 => "/Decrypted Text: <\/b>(.*)<\/font>/",
1 => "/<b class=\"res\">(.*)<\/b>/",
2 => "/<div id=\"result\" >(.*)<\/div>/",
3 => "/Cleartext of ".$hash." is (.*)/",
4 => "/(.*)<br\/><p style=\"font-size: 9pt; line-height: 48px;\">/",
5 => "/Found: md5\(\"(.*)\"\) = ".$hash."/",
6 => "/Password - <b>(.*)<\/b>/",
7 => "/Se encontro <strong>\"(.*)\"<\/strong> MD5:/",
8 => "/<center>".$hash." : : <b><font color=green>(.*)<\/font><\/b>/",
9 => "/The value of <b>".$hash."<\/b> resolves to -> <b>(.*)<\/b>/",
10 => "/<h3>".$hash." <\/br><font color=white>Cracking Successful Password =<\/font><font color=red size=20> (.*)/",
11 => "/<input type=\"text\" id=\"hash\" size=\"32\" value=\"(.*)\"\/> /",
12 => "/<td>".$hash."<br \/><\/td><td>md5<\/td><td>(.*)<\/td>/"
),
'security' => array(
0 => null,
1 => "<b class=\"res\">".$hash."</b>",
2 => null,
3 => null,
4 => null,
5 => null,
6 => null,
7 => null,
8 => null,
9 => null,
10 => null,
11 => null,
12 => null
)
);
endif;
elseif($type == 'sha1'):
if(!checkHash($hash, 40)):
echo '<div class="border">The entered hash doesn\'t look like SHA1</div>';
exit(1);
else:
$data = array(
'pages' => array(
0 => 'http://sha1.unidadlocal.com/'.$hash
),
'parameters' => array(
0 => null,
1 => 'datafromuser='.$hash
),
'sustitution' => array(
0 => "/Se encontro <strong>\"(.*)\"<\/strong> SHA1:/"
),
'security' => array(
0 => null
)
);
endif;
/*
passcracking.com isn't works anymore, so... is deprecated.
elseif($type == 'mysql'):
if(!checkHash($hash, 16)):
echo '<div class="border">The entered hash doesn\'t look like MySQL</div>';
exit(1);
else:
$data = array(
'pages' => array(
0 => 'http://passcracking.com/'
),
'parameters' => array(
0 => 'datafromuser='.$hash
),
'sustitution' => array(
0 => "/<td bgcolor=#FF0000>(.*)<\/td><td>/",
),
'security' => array(
0 => null
)
);
endif;*/
elseif($type == 'smf'):
if(!checkHash($hash, 40)):
echo '<div class="border">The entered hash doesn\'t look like SMF</div>';
exit(1);
endif;
endif;
$title = 'Cipher type: <font color="#00FF00">'.strtoupper($type).'</font><br />- - - - - - - - - - -<br />';
if($usedic != 'yes'):
echo $title;
for($i = 0; $i<count($data['pages']); $i++):
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $data['pages'][$i]);
if(!empty($data['parameters'][$i]))
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data['parameters'][$i]);
}
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_REFERER, $data['pages'][$i]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec ($ch);
curl_close ($ch);
if(!empty($data['sustitution'][$i]))
{
$test = preg_match($data['sustitution'][$i], str_replace($data['security'][$i], "", $return), $result);
$result = $result[1];
}
$result = ($result == 'Entry not found.' or empty($result)) ? '' : $result;
if(!empty($result)):
$counter++;
$hash_dec = $result;
echo 'Hash::['.$hash.']<br />
[+]Page::<font color="#00FF00">'.$data['pages'][$i].'</font><br />
[+]Status::<font color="#00FF00">Found</font><br />
[+]Result::<font color="#00FF00">'.$hash_dec.'</font><br />';
if($stop == 'yes'):
break;
endif;
elseif($stop != 'yes'):
echo 'Hash::['.$hash.']<br />
[+]Page::<font color="red">'.$data['pages'][$i].'</font><br />
[+]Status::<font color="red">Not Found</font><br />
[+]Result::<font color="red">none</font><br />';
endif;
endfor;
$min = ($stop == 'yes') ? '[Min] '.$counter.' of '.count($data['pages']): $counter.'/'.count($data['pages']);
if($counter >= 1):
echo '- - - - - - - - - - -<br />Positive matches: <font color="#00FF00">'.$min.'</font>';
echo '<br />Deciphered hash: <font color="#00FF00">'.$hash_dec.'</font>';
else:
echo '- - - - - - - - - - -<br />Positive matches: <font color="red">[None] '.$counter.'/'.count($data['pages']).'</font>';
echo '<br />Deciphered hash: <font color="red">Not Found</font>';
endif;
else:
$palabra = explode("\r\n", $dic);
if((count($palabra) > $max) or (count($palabra) == 1)):
echo '<div class="border">Only allows <font color="red">1-'.$max.'</font> word per dictionary.</div>';
exit(1);
else:
echo $title;
for($i = 0; $i<count($palabra); $i++):
if($type == 'md5' or $type == 'sha1'):
$new_hash = ($type == 'md5') ? md5($palabra[$i]) : sha1($palabra[$i]);
elseif($type == 'smf'):
$new_hash = sha1($salt.$palabra[$i]);
$add = $salt;
endif;
if(!empty($palabra[$i])):
if($new_hash == $hash):
$counter++;
$hash_dec = htmlspecialchars($palabra[$i], ENT_QUOTES);
echo 'Hash::['.$hash.']<br />';
echo (!empty($salt)) ? ' [+]Salt::<font color="#00FF00">'.$salt.'</font><br />' : '';
echo ' [+]Word::<font color="#00FF00">'.$hash_dec.'</font><br />
[+]Status::<font color="#00FF00">Found</font><br />
[+]Result::<font color="#00FF00">'.$add.$hash_dec.'</font><br />';
if($stop == 'yes'):
break;
endif;
elseif($stop != 'yes'):
echo 'Hash::['.$hash.']<br />';
echo (!empty($salt)) ? ' [+]Salt::<font color="red">'.$salt.'</font><br />' : '';
echo ' [+]Word::<font color="red">'.$palabra[$i].'</font><br />
[+]Status::<font color="red">Not Found</font><br />
[+]Result::<font color="red">none</font><br />';
endif;
$total++;
endif;
endfor;
if($counter == 0):
echo 'Hash::['.$hash.']<br />';
echo (!empty($salt)) ? ' [+]Salt::<font color="red">'.$salt.'</font><br />' : '';
echo ' [+]Word::<font color="red">'.$palabra[$i].'</font><br />
[+]Status::<font color="red">Not Found</font><br />
[+]Result::<font color="red">none</font><br />';
endif;
$min = ($stop == 'yes') ? '[Mínimo] '.$counter.' de '.count($palabra): $counter.'/'.count($palabra);
if($counter >= 1):
echo '- - - - - - - - - - -<br />Positive matches: <font color="#00FF00">'.$min.'</font>';
echo '<br />Deciphered hash: <font color="#00FF00">'.$add.$hash_dec.'</font>';
else:
echo '- - - - - - - - - - -<br />Positive matches: <font color="red">'.$counter.'/'.count($palabra).'</font>';
echo '<br />Deciphered hash: <font color="red">Not Found</font>';
endif;
endif;
endif;
$end = microtime(true); //Obtenemos tiempo final
echo '<br />Execution time: <font color="#00FF00">'.str_replace('-', '', round($start - $end, 2)).' sec</font>';
endif;
?>
</div>
</div>
Nota: Es probable que tenga fallos o que alguno de los sitios no funcionen, por lo que no me hago responsable de los fallos en cuestión. Además, el script lo que hace es mandar petición a una lista de páginas que hacen todo el trabajo; éste script, sólo sirve de intermediario.
Nota: El script es viejo por lo que se puede optimizar bastante.
Saludos.
#97
Bugs y Exploits / Dorks links Grabber (Bing Version)
Abril 13, 2012, 06:04:13 PM
Este es un script que ya tenía guardado, el cual tiene como fin obtener páginas del motor de Bing para comprobarlas y checar el archivo en cuestión (ingresado) existe. La idea la tenía ya hace un tiempo pero en realidad la idea príncipal le corresponde a ar3sw0rmed ya que el me lo comentó y me gustó la idea.

La utilidad consta de lo siguiente:
Código: php
Nota: Es probable que pueda generar falsos positivos porque la manera de comprobar el archivo no es tan eficaz, por lo que algunos servidores al entrar a You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login lo regresa como 200 en éste caso ya que es encontrada y no quize comprobar la página por cURL.
Cualquier cosa comenten, porque como he dicho, puede que tenga errores.
Saludos.

La utilidad consta de lo siguiente:
- Insert DORK: Dork de bing.
- Search Engine: Por el momento Bing; Google se maneja diferente y está un poco más complicado.
- Output file: Nombre de archivo donde se guardara el resultado.
- Check file: Nombre de archivo a comprobar.
- Raw links: Todos los enláces encontrados.
- Correct links: Todos los enláces correctos.
- Bad links: Todos los enláces incorrectos.
- Output file: Ruta del archivo creado.
- Estadísticas.
<?php
/*
* Author: Xt3mP
* Name: Dorks link grabber
* Version: 1.0 Bing
* Contact: xt3mp[at]null[dot]net
* Website: http://xt3mp.mx | http://backroot.org
*/
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dorks links Grabber (Bing version) | Xt3mP</title>
<style type="text/css">body{background-color:#2b2b2b;color:#777;font-family:Courier,"Courier New",monospace,sans-serif;font-size:12px}div#container{height:auto;margin:0 auto;width:600px}fieldset{background-color:#222;border:1px dashed #777;float:left;margin:5px;padding:5px;width:100%}legend{background-color:#555;border:1px dashed #777;color:#FFF;font-weight:700;margin:5px;padding:5px}label{float:left;margin-right:5px;padding-top:5px;text-align:right;width:100px}input,select{background-color:#E7E7E7;border:1px dashed #777;float:left;font-family:Courier,"Courier New",monospace,sans-serif;font-size:12px;margin-bottom:5px;padding:3px;width:490px}input[type=submit]{width:600px}h1{margin:0;padding:0}a{color:#CCC;font-weight:700}a:hover{color:#FFF;text-decoration:underline}</style>
</head>
<body>
<?php
set_time_limit(0);
class dorkGrabber
{
private $bing;
private $checkfile;
public function __construct()
{
$this->bing = 'http://www.bing.com/search?q=';
}
private function getSource($target)
{
$target = @file_get_contents($target);
return $target;
}
private function remakeUrl($url)
{
$url = explode("/", $url);
for($z = 0; $z < count($url) - 1; $z++)
{
$new .= $url[$z].'/';
}
return $new;
}
private function checkUrl($url)
{
if(@fopen($this->remakeUrl($url).$this->checkfile, 'r'))
return true;
else
return false;
}
private function parseLinks($target)
{
$data['rawlinks'] = array();
$data['correctlinks'] = array();
$data['badlinks'] = array();
for($i = 0; $i < 21; $i++)
{
$first = ($i == 0) ? 0 : ($i * 10) + 1;
$source = $this->getSource($target.'&first='.$first);
$pattern = "/<h3><a href=\"(.*?)\" onmousedown=/";
$preg = preg_match_all($pattern, $source, $output, PREG_PATTERN_ORDER);
if(count($output[1]) != 0)
{
for($x = 0; $x<count($output[1]); $x++)
{
if(!in_array($this->remakeUrl($output[1][$x]), $data['correctlinks']))
{
if($this->checkUrl($output[1][$x]))
{
$data['rawlinks'][] = $output[1][$x];
$data['correctlinks'][] = $this->remakeUrl($output[1][$x]);
}else{
$data['rawlinks'][] = $output[1][$x];
$data['badlinks'][] = $output[1][$x];
}
}
}
}else{
break;
}
}
return $data;
}
private function getLinks($target)
{
$newTarget = $this->getSource($target);
$check = "/<h1>No se han encontrado resultados para <strong>/";
if(@preg_match($check, $newTarget))
return false;
else
return $this->parseLinks($target);
}
private function makeData($type, $links, $output = null)
{
switch($type)
{
case 'raw':
$title = '<h1>Raw links</h1>';
foreach($links['rawlinks'] as $link)
{
$linkdir .= $link."\r\n";
}
$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
break;
case 'correct':
$title = '<h1>Correct links</h1>';
foreach($links['correctlinks'] as $link)
{
$linkdir .= $link."$this->checkfile\r\n";
}
$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
break;
case 'bad':
$title = '<h1>Bad links</h1>';
if(empty($links['badlinks']))
{
$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">None</textarea>';
}else{
foreach($links['badlinks'] as $link)
{
$linkdir .= $link."\r\n";
}
$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
}
break;
case 'txt':
$title = '<h1>Output file</h1>';
foreach($links['correctlinks'] as $link)
{
$linkdir .= $link.$this->checkfile;
}
$tot = count($links['correctlinks']) + count($links['badlinks']);
$statistics = '
[Total links: <b>'.$tot.'</b>]
[Correct links: <b>'.count($links['correctlinks']).'</b>]
[Bad links: <b>'.count($links['badlinks']).'</b>]';
$file = fopen($output, 'w+');
if($file)
{
fwrite($file, $linkdir);
fclose($file);
$filedir = $output.' > http:/'.dirname($_SERVER["PHP_SELF"]).'/'.$output;
$data = $title.'<textarea rows="5" style="width:600px;font-size:11px;margin-bottom:5px;">'.$filedir.'</textarea>';
$data .= $statistics.' <a href="./'.$output.'" target="_blank">[View output file]</a>';
}else{
$data = $title.$statistics.' [Can\'t make output file]';
}
break;
}
return $data;
}
public function makeDirective($dork, $output, $checkfile = null)
{
$dork = urlencode($dork);
$target = $this->bing.$dork;
$this->checkfile = $checkfile;
$grabber = $this->getLinks($target);
$result = '<fieldset style="text-align: justify"><legend>Result</legend>';
if($grabber === false)
{
$result .= 'The DORK (<b>'.urldecode($dork).'</b>) doesn\'t return any results.';
}else{
$result .= $this->makeData('raw', $grabber);
$result .= $this->makeData('correct', $grabber);
$result .= $this->makeData('bad', $grabber);
$result .= $this->makeData('txt', $grabber, $output);
}
$result .= '</fieldset>';
return $result;
}
}
?>
<div id="container">
<fieldset>
<legend>Dorks links Grabber (Bing version) | <a href="http://xt3mp.mx" target="_blank">Xt3mP</a></legend>
<form action="" method="POST">
<label>Insert DORK:</label><input type="text" name="dork"/><br />
<label>Search eng.:</label><input type="text" name="engine" value="Bing" disabled="disabled"><br />
<label>Output file:</label><input type="text" name="output" /><br />
<label>Check file:</label><input type="text" name="check"/><br />
<input type="submit" name="get" value="Get Links!" />
</form>
</fieldset>
<?php
if(isset($_POST['get']))
{
if(empty($_POST['dork']) or empty($_POST['output']))
{
echo '<script>alert("Some fields are empty!.");</script>';
}else{
$mtime = microtime();
$mtime = explode(' ',$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
$dorkGrabber = new dorkGrabber();
echo $dorkGrabber->makeDirective($_POST['dork'], $_POST['output'], $_POST['check']);
$mtime = microtime();
$mtime = explode(' ',$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo 'This page took '.round($totaltime).' seconds to load.';
}
}
?>
</div>
</body>
</html>
Nota: Es probable que pueda generar falsos positivos porque la manera de comprobar el archivo no es tan eficaz, por lo que algunos servidores al entrar a You are not allowed to view links. You are not allowed to view links. Register or Login or You are not allowed to view links. Register or Login lo regresa como 200 en éste caso ya que es encontrada y no quize comprobar la página por cURL.
Cualquier cosa comenten, porque como he dicho, puede que tenga errores.
Saludos.
#98
Galería / Re:Wallpaper Underc0de [Gray & blue] by Xt3mP
Abril 13, 2012, 05:20:31 PM
Gracias a todos, recuerden que si quieren otras dimensiones me comenten para adaptarlo.
#99
Galería / Re:Wallpaper Underc0de [Gray & blue] by Xt3mP
Abril 13, 2012, 01:10:52 AM
Cronos, un gusto re-encontrartem, gracias.
[Q]3rVo[0], en realidad no gaste muchísimo tiempo en el wallpaper, a lo mucho una hora, por eso te digo que no fue tanta dedicación pero gracias.
REC, gracias.
[Q]3rVo[0], en realidad no gaste muchísimo tiempo en el wallpaper, a lo mucho una hora, por eso te digo que no fue tanta dedicación pero gracias.
REC, gracias.
#100
Galería / Re:Wallpaper Underc0de [Gray & blue] by Xt3mP
Abril 12, 2012, 09:54:19 PM
Como te he dicho; humildad ante todo, y que va, el chiste de ésto es aprender todos. Entre más diseños hagas y compartas, más críticas tendrás que te permitiran mejorar y sentirte bien.
Saludos.
Saludos.

