Underc0de

[In]Seguridad Informática => Bugs y Exploits => Pentesting => Mensaje iniciado por: rollth en Febrero 08, 2016, 09:33:36 PM

Título: upload.php [Vulnerabilidad]
Publicado por: rollth en Febrero 08, 2016, 09:33:36 PM
Muy buenas Underc0ders, en este caso vengo a explicar como se puede explotar una vulnerabilidad en un upload.php. Hay más información sobre esto en el foro, pero lo que he visto o es en video o no está explicado como a mi me gustaría que me lo explicaran.

Lo primero que tenemos que saber es que es un uploader en php.

CitarUn uploader en php es un código que nos va a permitir subir un archivo a una página web.

En este caso nuestro código de prueba vulnerable va a ser el siguiente (El codigo no es propio, es este  (http://www.taringa.net/posts/hazlo-tu-mismo/14680814/Tutorial-Crear-una-Web-para-Subir-Archivos-PHP.html) modificado).

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 
if(isset($_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((true==true)  &&  ($_FILES["archivo"]["size"] < 200000000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>


Este código nos deja subir archivos de cualquier extensión y aquí es donde nosotros nos vamos a aprovechar. En este caso yo voy a subir una shell c99.php (http://www.c99shellphp.com/shell/c99.zip), que es muy intuitiva de manejar.

(https://i.gyazo.com/e07c2dde408bf7e9db10ad6a95b7af2f.png)

Ya solo nos quedaría ir al directorio está el archivo malicios, en este caso: "/archivos/c99.php".

Dejo aquí una foto de la shell. El funcionamiento como digo es muy intuitivo.

(https://i.gyazo.com/55caa069cbb16d4311325581e51068a3.png)

(Ya se que tengo que activar Windows xD)

Ahora voy a mostrar un filtro que NO DEBÉIS USAR y como hacer un bypass, es decir, saltarse el filtro.(Despues mostrare el filtro final).

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 
if(isset($_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((($_FILES["archivo"]["type"] == "image/gif") || 
    (
$_FILES["archivo"]["type"] == "image/jpeg") || 
    (
$_FILES["archivo"]["type"] == "image/pjpeg")) && 
    (
$_FILES["archivo"]["size"] < 20000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>


Si os fijáis en estas lineas:
Código (php) [Seleccionar]
if ((($_FILES["archivo"]["type"] == "image/gif") ||
    ($_FILES["archivo"]["type"] == "image/jpeg") ||
    ($_FILES["archivo"]["type"] == "image/pjpeg")) &&
    ($_FILES["archivo"]["size"] < 20000))


Lo que hace el php es comprobar el content type del archivo y no comprueba la terminación del archivo (si es php, html, etc). Para saltarte este filtro lo que hay que hacer es lo siguiente:

1º Hay que descargarse firefox, ya que vamos a usar una herramienta (https://addons.mozilla.org/es/firefox/addon/tamper-data/) de firefox para esta prueba.

2º Hay que renombrar el archivo c99.php a c99.jpg, ya que es un tipo de los archivos que nos permite subir este uploader.

3º En la web le damos a examinar y ponemos nuestro archivo c99.jpg (NO LE DAMOS A SUBIR TODAVIA). Tiene que quedar asi.

(https://i.gyazo.com/a9f2d1be6ba723e874748e52ca440887.png)

4º Iniciamos Tamper Data. (Está en el menú de arriba en la barra de herramientas).

(https://i.gyazo.com/d40dfe7e417cf101beb13e083c0ebf46.png)

5º Le damos a comenzar modificación.

(https://i.gyazo.com/c5374fa26a8b7cb82516781a06fb0332.png)

6º Ya podemos darle a enviar el archivo, nos saldra una pantallita y le tenemos que dar a modificar.

(https://i.gyazo.com/dcd4a7b10ab6d500563893d412e19bfe.png)

7º Entonces nos saldrá otra pantalla y tenemos que modificar el código de la derecha.

(https://i.gyazo.com/0c9808d2c868f004df2b2e1082ff9bc8.png)

En ese código hay que buscar algo de este estilo.

filename="c99.jpg"\r\nContent-Type: image/jpeg\r\n\r\n

Y cambiar "c99.jpg" por c99.php. Le das a enviar y listo. Esto saltará el filtro ya que aunque estas subiendo el archivo con la terminación .php el content type es de un jpg, y el código del upload comprueba el content type y no la terminación.

Por último una forma de arreglar esto sería añadir estas líneas.

El código ha sido editado porque como decía @seth seguía siendo vulnerable.

Código (php) [Seleccionar]
$blacklist = array(".php", ".phtml", ".php3", ".php4" , ".html", "htaccess");

    foreach ($blacklist as $item) {
      if(preg_match("/$item\$/i", $_FILES['userfile']['name'])) {
         echo "No se permiten archivos PHP";
         exit;
      }
    }


Con lo que el código final quedaría así.

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 

$blacklist 
= array(".php"".phtml"".php3"".php4" ".html""htaccess");
 
    foreach (
$blacklist as $item) {
      if(
preg_match("/$item\$/i"$_FILES['userfile']['name'])) {
         echo 
"No se permiten archivos PHP";
         exit;
     }
}
if(isset(
$_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((($_FILES["archivo"]["type"] == "image/gif") ||  
    (
$_FILES["archivo"]["type"] == "image/jpeg") ||  
    (
$_FILES["archivo"]["type"] == "image/pjpeg")) &&  
    (
$_FILES["archivo"]["size"] < 200000000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>



Espero que esto sea utilidad.

También me pueden seguir en Twitter si les hace ilusión: @RoloMijan (https://twitter.com/RoloMijan)

Saludos.
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rush en Febrero 08, 2016, 10:39:11 PM
Bonito tutorial y a esto se le llama "RFI" Remote File Inclusion :D
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rollth en Febrero 08, 2016, 10:49:36 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Bonito tutorial y a esto se le llama "RFI" Remote File Inclusion :D

Perdon si me equivoco, pero por lo que tengo entendido el RFI es cuando carga contenido a través del metodo GET de forma.

servervictima.com/file.php?file="archivo" y este archivo se puede sustituir por una shell.

Dejo aqui (https://www.owasp.org/index.php/Testing_for_Remote_File_Inclusion) info.

Si me equivoco que se me corrija :D
Título: Re:upload.php [Vulnerabilidad]
Publicado por: arthusu en Febrero 08, 2016, 11:05:12 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Bonito tutorial y a esto se le llama "RFI" Remote File Inclusion :D
Rush deje la marijuana le he dicho que esa cosa hace daño XD :v, No te creas :P, Saludos bro!, Buen tuto!
PD: Burp suite es cool tambien C:
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rush en Febrero 08, 2016, 11:30:33 PM
Jajaj lo siento por la confucion, entonces tengo un mal entendido y no recuerdo, pero segun yo tambien se le llamaba asi al poder subir en un upload una shell o ando marihuano como dice @arthusu (https://underc0de.org/foro/index.php?action=profile;u=2961) jaja confuciones de terminos
Título: Re:upload.php [Vulnerabilidad]
Publicado por: bernatixer en Febrero 09, 2016, 11:07:38 AM
Buen aporte, gracias por compartirlo   :)
Título: Re:upload.php [Vulnerabilidad]
Publicado por: blackdrake en Febrero 09, 2016, 12:06:54 PM
Esa shell me recuerda a una web bastante tentadora ^^ (ya tu sabes), buen aporte @rollth (https://underc0de.org/foro/index.php?action=profile;u=30952), a más de uno le vendrá bien.

Saludos.
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rollth en Febrero 09, 2016, 12:11:59 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Esa shell me recuerda a una web bastante tentadora ^^ (ya tu sabes), buen aporte @rollth (https://underc0de.org/foro/index.php?action=profile;u=30952), a más de uno le vendrá bien.

Saludos.

A mi no me suena esa shell  ::). Gracias por tu comentario @blackdrake (https://underc0de.org/foro/index.php?action=profile;u=24972) :D
Título: Re:upload.php [Vulnerabilidad]
Publicado por: meteor0 en Febrero 09, 2016, 12:13:56 PM
Buena esa @rollth (https://underc0de.org/foro/index.php?action=profile;u=30952), es una vulnerabilidad bastante común, fácil y rapido,
Saludos :)
Título: Re:upload.php [Vulnerabilidad]
Publicado por: EPSILON en Febrero 09, 2016, 03:12:10 PM
En definitiva a esta técnica se la conoce como "bypass upload", @rush (https://underc0de.org/foro/index.php?action=profile;u=37736) nada que ver bro xD, @arthusu (https://underc0de.org/foro/index.php?action=profile;u=2961) tienes razón bro Burpsuite es la onda, @rollth (https://underc0de.org/foro/index.php?action=profile;u=30952) te ha quedado muy bueno el post y usaste un clásico de shell la c99 xD.

Saludos a todos!
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rush en Febrero 09, 2016, 03:52:13 PM
Tienes razon @EPSILON (https://underc0de.org/foro/index.php?action=profile;u=42897), un bypass upload, tiene mucho tiempo esta tecnica jaja tal vez lo confundi por que en el RFI se utilizaba mucho la shell c99
Título: Re:upload.php [Vulnerabilidad]
Publicado por: roadd en Febrero 09, 2016, 04:55:32 PM
Buenisimo Rolo! Excelente forma de mostrar el Upload. Aplausos desde aqui :) Muy util para todos
Título: Re:upload.php [Vulnerabilidad]
Publicado por: EPSILON en Febrero 09, 2016, 09:43:54 PM
Claro @rush (https://underc0de.org/foro/index.php?action=profile;u=37736) probablemente leiste sobre rfi hace 8 años cuando era común ver en foros aportes de  rfi usando la c99 como ejemplo, a mi me toco leer así y lo recuerdo igual jaja
Título: Re:upload.php [Vulnerabilidad]
Publicado por: seth en Febrero 10, 2016, 02:28:26 PM
Ese filtro sigue estando mal

Me deja subir un html que se puede usar para hacer xss
Tambien me deja subir un htaccess que se puede usar para hacer que otra extension se ejecute con php


Lo mejor es que el usuario no controle el nombre del archivo
Si no podes hacer eso, usa una whitelist y funciones que parsean nombres de archivos en lugar de expresiones regulares
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rollth en Febrero 10, 2016, 04:59:02 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Ese filtro sigue estando mal

Me deja subir un html que se puede usar para hacer xss
Tambien me deja subir un htaccess que se puede usar para hacer que otra extension se ejecute con php


Lo mejor es que el usuario no controle el nombre del archivo
Si no podes hacer eso, usa una whitelist y funciones que parsean nombres de archivos en lugar de expresiones regulares

Cierto lo que dices, el ejemplo es algo simple para entender como va, al array se le podría añadir las extension html, para que no pueda subir htaccess y demás extensiones que uno quiera :D
Título: Re:upload.php [Vulnerabilidad]
Publicado por: seth en Febrero 11, 2016, 07:44:11 PM
El tema es que siempre te podes olvidar de alguna, o puede salir una nueva
No sirve una blacklist

Te muestro como lo resolvi yo para un uploader de imagenes con poco trafico
Subo los archivos en /uploads/, carpeta que siempre tira 403 https://github.com/seth--/imgup/blob/master/uploads/.htaccess
Los guardo  con un nombre aleatorio para que no hagan cosas raras como escalar directorios https://github.com/seth--/imgup/blob/master/php/models/upload.php#L48
Con un archivo php leo la imagen y la mando al navegador https://github.com/seth--/imgup/blob/master/php/models/f.php
Los mime types estan limitados con una whitelist https://github.com/seth--/imgup/blob/master/php/models/upload.php#L14
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rollth en Febrero 12, 2016, 10:38:24 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
El tema es que siempre te podes olvidar de alguna, o puede salir una nueva
No sirve una blacklist

Te muestro como lo resolvi yo para un uploader de imagenes con poco trafico
Subo los archivos en /uploads/, carpeta que siempre tira 403 https://github.com/seth--/imgup/blob/master/uploads/.htaccess
Los guardo  con un nombre aleatorio para que no hagan cosas raras como escalar directorios https://github.com/seth--/imgup/blob/master/php/models/upload.php#L48
Con un archivo php leo la imagen y la mando al navegador https://github.com/seth--/imgup/blob/master/php/models/f.php
Los mime types estan limitados con una whitelist https://github.com/seth--/imgup/blob/master/php/models/upload.php#L14

Hay muchas formas de filtrarlo, lo único es que esa me pareció la más rápida y sencilla, de esa forma filtras rapido lo que no quieres que suban, aunque se te pueda olvidar algo. Otra forma similar sería haciendo Whitelist como dijiste, el código sería similar. Igualmente hay miles de formas. Gracias por comentar.

Saludos.
Título: Re:upload.php [Vulnerabilidad]
Publicado por: We are all Phineas Fisher en Abril 27, 2017, 11:31:08 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Muy buenas Underc0ders, en este caso vengo a explicar como se puede explotar una vulnerabilidad en un upload.php. Hay más información sobre esto en el foro, pero lo que he visto o es en video o no está explicado como a mi me gustaría que me lo explicaran.

Lo primero que tenemos que saber es que es un uploader en php.

CitarUn uploader en php es un código que nos va a permitir subir un archivo a una página web.

En este caso nuestro código de prueba vulnerable va a ser el siguiente (El codigo no es propio, es este  (http://www.taringa.net/posts/hazlo-tu-mismo/14680814/Tutorial-Crear-una-Web-para-Subir-Archivos-PHP.html) modificado).

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 
if(isset($_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((true==true)  &&  ($_FILES["archivo"]["size"] < 200000000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>


Este código nos deja subir archivos de cualquier extensión y aquí es donde nosotros nos vamos a aprovechar. En este caso yo voy a subir una shell c99.php (http://www.c99shellphp.com/shell/c99.zip), que es muy intuitiva de manejar.

(https://i.gyazo.com/e07c2dde408bf7e9db10ad6a95b7af2f.png)

Ya solo nos quedaría ir al directorio está el archivo malicios, en este caso: "/archivos/c99.php".

Dejo aquí una foto de la shell. El funcionamiento como digo es muy intuitivo.

(https://i.gyazo.com/55caa069cbb16d4311325581e51068a3.png)

(Ya se que tengo que activar Windows xD)

Ahora voy a mostrar un filtro que NO DEBÉIS USAR y como hacer un bypass, es decir, saltarse el filtro.(Despues mostrare el filtro final).

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 
if(isset($_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((($_FILES["archivo"]["type"] == "image/gif") || 
    (
$_FILES["archivo"]["type"] == "image/jpeg") || 
    (
$_FILES["archivo"]["type"] == "image/pjpeg")) && 
    (
$_FILES["archivo"]["size"] < 20000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>


Si os fijáis en estas lineas:
Código (php) [Seleccionar]
if ((($_FILES["archivo"]["type"] == "image/gif") ||
    ($_FILES["archivo"]["type"] == "image/jpeg") ||
    ($_FILES["archivo"]["type"] == "image/pjpeg")) &&
    ($_FILES["archivo"]["size"] < 20000))


Lo que hace el php es comprobar el content type del archivo y no comprueba la terminación del archivo (si es php, html, etc). Para saltarte este filtro lo que hay que hacer es lo siguiente:

1º Hay que descargarse firefox, ya que vamos a usar una herramienta (https://addons.mozilla.org/es/firefox/addon/tamper-data/) de firefox para esta prueba.

2º Hay que renombrar el archivo c99.php a c99.jpg, ya que es un tipo de los archivos que nos permite subir este uploader.

3º En la web le damos a examinar y ponemos nuestro archivo c99.jpg (NO LE DAMOS A SUBIR TODAVIA). Tiene que quedar asi.

(https://i.gyazo.com/a9f2d1be6ba723e874748e52ca440887.png)

4º Iniciamos Tamper Data. (Está en el menú de arriba en la barra de herramientas).

(https://i.gyazo.com/d40dfe7e417cf101beb13e083c0ebf46.png)

5º Le damos a comenzar modificación.

(https://i.gyazo.com/c5374fa26a8b7cb82516781a06fb0332.png)

6º Ya podemos darle a enviar el archivo, nos saldra una pantallita y le tenemos que dar a modificar.

(https://i.gyazo.com/dcd4a7b10ab6d500563893d412e19bfe.png)

7º Entonces nos saldrá otra pantalla y tenemos que modificar el código de la derecha.

(https://i.gyazo.com/0c9808d2c868f004df2b2e1082ff9bc8.png)

En ese código hay que buscar algo de este estilo.

filename="c99.jpg"\r\nContent-Type: image/jpeg\r\n\r\n

Y cambiar "c99.jpg" por c99.php. Le das a enviar y listo. Esto saltará el filtro ya que aunque estas subiendo el archivo con la terminación .php el content type es de un jpg, y el código del upload comprueba el content type y no la terminación.

Por último una forma de arreglar esto sería añadir estas líneas.

El código ha sido editado porque como decía @seth seguía siendo vulnerable.

Código (php) [Seleccionar]
$blacklist = array(".php", ".phtml", ".php3", ".php4" , ".html", "htaccess");

    foreach ($blacklist as $item) {
      if(preg_match("/$item\$/i", $_FILES['userfile']['name'])) {
         echo "No se permiten archivos PHP";
         exit;
      }
    }


Con lo que el código final quedaría así.

Código (php) [Seleccionar]
<html>
<head>
<style type="text/css">
.upload{
background:#e7e7e7;
box-shadow:0px 0px 10px black;
width:500px;
height:200px;
margin-right:auto;
margin-left:auto;
border-radius:20px;

}
form{
        margin: 126px auto 0;
        width: 225px;
    }
    label{
        display: block;
    }
    input[type="file"]{
        display: block;
        margin: 8px 0;
    }
    div.resultado{
        margin: 25px auto 0;
        width: 225px;
    }
    div.resultado img{
        border: 2px solid #EEEEEE;
        height: auto;
        width: 225px;
    }
</style>
</head>
<body>
<div class="upload">
<form action="" method="post" enctype="multipart/form-data">
    <br><br>Sube un archivo:
    <input type="file" name="archivo" id="archivo" /> <br>
    <input type="submit" name="boton" value="Subir" />
</form>
<div>
<div class="resultado">
<?php 

$blacklist 
= array(".php"".phtml"".php3"".php4" ".html""htaccess");
 
    foreach (
$blacklist as $item) {
      if(
preg_match("/$item\$/i"$_FILES['userfile']['name'])) {
         echo 
"No se permiten archivos PHP";
         exit;
     }
}
if(isset(
$_POST['boton'])){ 
    
// Hacemos una condicion en la que solo permitiremos que se suban imagenes y que sean menores a 20 KB
    
if ((($_FILES["archivo"]["type"] == "image/gif") ||  
    (
$_FILES["archivo"]["type"] == "image/jpeg") ||  
    (
$_FILES["archivo"]["type"] == "image/pjpeg")) &&  
    (
$_FILES["archivo"]["size"] < 200000000)) { 
     
    
//Si es que hubo un error en la subida, mostrarlo, de la variable $_FILES podemos extraer el valor de [error], que almacena un valor booleano (1 o 0).
      
if ($_FILES["archivo"]["error"] > 0) { 
        echo 
$_FILES["archivo"]["error"] . "<br />"
      } else { 
          
// Si no hubo ningun error, hacemos otra condicion para asegurarnos que el archivo no sea repetido
          
if (file_exists("archivos/" $_FILES["archivo"]["name"])) { 
            echo 
$_FILES["archivo"]["name"] . " ya existe. "
          } else { 
           
// Si no es un archivo repetido y no hubo ningun error, procedemos a subir a la carpeta /archivos, seguido de eso mostramos la imagen subida
            
move_uploaded_file($_FILES["archivo"]["tmp_name"], 
            
"archivos/" $_FILES["archivo"]["name"]); 
            echo 
"Archivo Subido <br />"
            echo 
"<img src='archivos/".$_FILES["archivo"]["name"]."' />"
          } 
      } 
    } else { 
        echo 
"Archivo no permitido"
    } 

?>

</div>
</body>
</html>



Espero que esto sea utilidad.

Saludos.

Hola rollth, no tengo ni idea de lo que has dicho, pero creo que lo he pillado, es decir el codigo php que estaba dentro del HTML de la página web estaba mal programado ya que dejaba subir archivos .php y también en el otro ejemplo bypaseabas el content type con una extensión no?, después modificabas el código y le ponias a una variable de lista negra todas las extensiones? creo que lo he pillado pero no muy bien xD
Título: Re:upload.php [Vulnerabilidad]
Publicado por: BrowserNet en Abril 28, 2017, 04:26:40 PM
JAJAJAJA, estos temas hacen recordar mis inicios  ;D ;D ;D ;D
Título: Re:upload.php [Vulnerabilidad]
Publicado por: DevilCry en Junio 11, 2017, 02:30:03 PM
Esto tuto es genial.

Tengo un problema, he instalado tamper data en mi firefox, pero no me sale la opcion de POST_DATA en la parte derecha, me salen un moton de cosas, pero esa en concreto no me sale. He estado investigando pero no consigo encontrar nada, quisiera saber como teneis vosotros configurado tamper data.

Un saludo
Título: Re:upload.php [Vulnerabilidad]
Publicado por: rollth en Junio 11, 2017, 05:56:06 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Esto tuto es genial.

Tengo un problema, he instalado tamper data en mi firefox, pero no me sale la opcion de POST_DATA en la parte derecha, me salen un moton de cosas, pero esa en concreto no me sale. He estado investigando pero no consigo encontrar nada, quisiera saber como teneis vosotros configurado tamper data.

Un saludo

Podrías pasar una imagen de que te aparece?
Título: Re:upload.php [Vulnerabilidad]
Publicado por: pepe1983 en Septiembre 17, 2018, 12:55:56 PM
con que versión de firefox lo has probado?. he probado hasta con la versión 10 y me dice que tamper data no es compatible.
Título: Re:upload.php [Vulnerabilidad]
Publicado por: Drok3r en Septiembre 23, 2018, 03:53:36 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Jajaj lo siento por la confucion, entonces tengo un mal entendido y no recuerdo, pero segun yo tambien se le llamaba asi al poder subir en un upload una shell o ando marihuano como dice @arthusu (https://underc0de.org/foro/index.php?action=profile;u=2961) jaja confuciones de terminos

No estas tan perdido, pues con RFI puedes cargar Shells... sin embargo son cosas distintas RFI y AFU (Arbitrary File Upload - Carga Arbitraria de Archivos)