Red de conocimiento informático - Aprendizaje de código fuente - Al abrir la página web de una computadora, aparece un "desbordamiento de pila". ¿Cuál es el problema y cómo solucionarlo? Por favor dame la respuesta, gracias!

Al abrir la página web de una computadora, aparece un "desbordamiento de pila". ¿Cuál es el problema y cómo solucionarlo? Por favor dame la respuesta, gracias!

Esta es una vulnerabilidad de desbordamiento

Esta entrada carece de una barra de información y una imagen de tarjeta de presentación. Agrega contenido relevante para que la entrada sea más completa y actualízala rápidamente.

Una vulnerabilidad de desbordamiento es un defecto corregible en un programa informático. El nombre completo de la vulnerabilidad de desbordamiento: Vulnerabilidad de desbordamiento del búfer. Debido a que es un código de error ejecutado en el búfer cuando se ejecuta el programa, se denomina vulnerabilidad de desbordamiento del búfer.

Tabla de contenidos

1 Introducción

2 ¿Qué es una vulnerabilidad de desbordamiento? Principio de desbordamiento: desbordamiento local Desbordamiento remoto

3 Información relacionada está en el espacio de direcciones del programa Organice los procedimientos de control de código apropiados que se transferirán al código de ataque en forma de implantación de código integral y control de procesos

1 Introducción a la edición

Generalmente es causado por negligencia del programador.

Específicamente hablando, la vulnerabilidad de desbordamiento es causada por la verificación de límites flexibles de los datos recibidos por parte de una o algunas funciones de entrada (parámetros de entrada del usuario) en el programa.

De acuerdo con el principio de llamada de pila durante la ejecución del programa, si el programa elimina automáticamente la parte más allá del límite sin verificación, entonces la parte más allá del límite sobrescribirá los datos posteriores que almacenan el puntero del programa. Se ejecuta, el programa llamará automáticamente el comando en la dirección señalada por el puntero.

Basándose en este principio, los usuarios malintencionados pueden crear programas de desbordamiento.

2 ¿Qué es la edición de vulnerabilidad de desbordamiento?

Principio de desbordamiento

De hecho, el principio de desbordamiento es muy simple (antes pensaba que era difícil de entender, demasiado novato, o(∩_∩ )o…). Por supuesto, para que sea más fácil de entender para todos, aquí se citarán algunos ejemplos de programas (si no tiene conocimientos básicos de programación, puede omitir el programa, tendrá poco impacto y aún podrá comprenderlo), y La explicación será relativamente popular y simple, no demasiado profunda.

Después de buscar en libros, finalmente encontré un programa adecuado (¡sudor! Es fácil encontrar un programa adecuado, pero no hay muchos programas que un súper novato encuentre particularmente simples, 55~~). Echa un vistazo al siguiente programa:

#include “stdafx.h”

#include “string.h”

#include “stdio.h”

char buf[255], pass[4]; /*Declarar variables y dejar que la computadora asigne la memoria especificada*/

int main (int argc, char* argv[ ] )

{

printf("Ingrese su contraseña:" /*Especifique los caracteres que se generarán*/

scanf(s, buf) ; / *Ingresa una cadena y guárdala en la variable buf*/

strcpy(pass, buf /*Copia la cadena en la cadena buf a la variable pass*/

if (strcmp(pass, "wlqs") = =0) /*Comparar si la cadena ingresada es una contraseña*/

printf ("¡Entrada correcta!");

else printf ("¡Error de entrada!");

return 0;

}

(Nota: el chino en "/*" es un comentario sobre programa)

Este es un programa de verificación de contraseña. Es el mismo que cuando usualmente ingresamos contraseñas. Primero, dejamos que el usuario ingrese la contraseña y luego obtenga la contraseña real. es 0, la contraseña de salida es correcta; de lo contrario, la contraseña de salida es incorrecta. Muchos programas de inicio de sesión hacen esto y no parece muy razonable. De hecho, tiene un defecto fatal. ¡Esta vulnerabilidad es fácil de detectar!

Es decir, se aplica a 4 bytes de espacio de almacenamiento para datos, pero si el usuario ingresa más de 4 bytes de datos, ¿dónde se almacenan los bytes restantes?

Por ejemplo, hay un trozo de madera de un metro de largo con una nota roja pegada desde la cola hasta la cabeza, con palabras escritas, y luego hay una nota azul con palabras también escritas. En él, debes pegarlo desde la cabeza de la madera hasta la cola, pero después de pegar la nota roja, solo quedan 4 cm de largo. Después de pegarlo, alguien leerá las palabras 96 cm detrás y ejecutará las instrucciones. nota, pero la nota azul tiene ¿Qué debo hacer si la longitud es de 10 cm? Simplemente pegue la parte restante del papel azul sobre el papel rojo. Luego se cubrirán algunas palabras de la nota roja. Pero esa persona seguirá leyendo las palabras 96 cm en la parte posterior, por lo que solo leerá las palabras incorrectamente, y las palabras en el frente son todas las palabras en la nota azul. La ejecución anterior fue el comando 6 cm detrás de la nota azul.

Por supuesto, no todo el mundo entiende muy bien este ejemplo. Vamos a explicarlo a continuación:

Personas——CPU

Las palabras en la nota roja—. —Requisitos de la CPU El comando ejecutado

La longitud de 4 cm: el espacio de memoria solicitado por la computadora para los datos

Las palabras en la nota azul: los datos que se almacenarán

Se puede ver que la nota azul ha cubierto las palabras de la nota roja, pero la persona aún tiene que leer las palabras 96 cm detrás y ejecutarlas. ¡Lo que sigue ya no es un orden prescrito! ¡No puede ejecutarlo en absoluto, no puede leerlo en absoluto! Entonces no podrá ejecutarlo y reportará un error.

Como se muestra en la imagen, el sistema solo asigna 4 bytes de memoria para mi contraseña. Entonces la contraseña que ingresé es "714718366" que se ha repetido 6 veces. No son solo 4 bytes, sino la misma. ¡Los personajes restantes se desbordarán! Los números restantes ocuparán espacio en la memoria, por lo que cuando el sistema ejecute el comando, ejecutará los datos que ocupan la memoria en lugar de ejecutar el comando escrito originalmente. Estos sistemas digitales son simplemente incomprensibles, entonces, ¿cómo se pueden implementar? ¡Entonces no le queda más remedio que informar de un error! Dice que este programa ha encontrado un problema y debe cerrarse. Entonces el programa en la computadora generará un error y no podrá ejecutarse ni cerrarse.

Desbordamiento local

El ordenador local mencionado anteriormente que cierra el programa o no puede ejecutarlo debido a un desbordamiento de datos se denomina desbordamiento local. La introducción de datos extremadamente largos ha sobrescrito el código que ejecutará la computadora. Sin embargo, a la computadora no le importa si las instrucciones se han cambiado o no, y todavía toma los datos en el espacio donde se almacenaron originalmente las instrucciones para ejecutarlos y los obtiene. "¡shujucuole! ¡shujucuole! ¡shujucuole!" "Estos datos de desbordamiento ilegales aún se ejecutarán, pero en la computadora dichas instrucciones son instrucciones ilegales, es decir, instrucciones que no se ajustan a la lógica de la computadora. Cuando el usuario las ejecuta, se producirá un error ocurrirá y el programa se cerrará a la fuerza.

Fuera de tema: (Después de pensarlo mucho, déjame hablar sobre o (∩_∩) o... mi hobby... mi hobby de beneficiarme a mí mismo a expensas de los demás) Usar tal desbordamiento La vulnerabilidad puede cerrar muchos programas, como las salas de computadoras de las escuelas. En esos sistemas de educación a distancia instalados en la computadora, la computadora del estudiante es controlada por la computadora del maestro porque hay un programa del lado del estudiante instalado en la computadora del estudiante. La computadora del maestro puede controlar de forma remota. la computadora del estudiante a través de la computadora del maestro. La computadora del estudiante no tiene una función de salida. El grupo de usuarios no tiene la autoridad para finalizar el proceso por la fuerza. Cuando los estudiantes no quieren ser controlados por el maestro, pueden abrir la mensajería remota. función que viene con el terminal de estudiantes e ingresa datos largos en el mensaje, como cientos o miles de oraciones "¡Atrévete a controlarme"! ¡Veamos si no te mato y luego lo enviaré, lo que provocará que el estudiante! -Programa lateral para cometer un error y ser cerrado por la fuerza por el sistema.

¡Este truco también es útil para el sistema de cobro de algunos cibercafés! ^_^

Desbordamiento remoto

Otro ejemplo:

#include "stdafx.h"

#include winsock .hgt; ;

#pragma comment(lib, "ws2_32")

int main(int argc, char* argv[ ])

{

char buf[255]=” ”, pass[4]=” ”; //Declarar variables y dejar que la computadora asigne memoria

//=========== = ================================================== = ==

//La función del código en esta sección es inicializar la conexión de red

//y escuchar el puerto 1234 para esperar la conexión

//Sin conocimientos de programación, los novatos especiales pueden omitirlo

SOCKET sock1, sock2;

struct sockaddr_in addr1;

struct sockaddr_in addr2;

addr1.sin_addr.s_addr=INADDR_ANY;

addr1 .sin_family=AF_INET;

addr1 .sin_port=htons(1234);

WSADATA * wsadatal =nuevo WSADATA( ) ;

WSAStartup(MAKEWORD(2, 2), wsadatal1;

sock1=socket(AF_INET, SOCK_STREAM, 0

); bind(sock1, (sockaddr *)amp; addr1, sizeof(struct sockaddr)

listen(sock1, 10);

int iSin=sizeof(struct sockaddr_in); /p>

//=========================================== ====== ==================

if(sock2=accept(sock1, (sockaddr *)amp; addr2, amp; iSin )

{//Un usuario se está conectando en

send(sock2, "Por favor ingrese la contraseña. Si la contraseña es correcta, le diré mi qq:", 36, 0);

/ /Enviar solicita al usuario que introduzca la contraseña

if (recv(sock2,buf,255,0))

{// Acepte los datos enviados por el usuario y guárdelos en la variable buf del búfer

strcpy (pass,buf //Copia los datos en la variable buf del búfer a la variable de paso

if(strcmp(pass,"wlqs"= =0)

//Compara si la diferencia entre los datos de la variable de paso y la cadena "wlqs" es 0

{/ /La diferencia es 0, lo que significa que los dos son iguales y la contraseña es correcta

send(sock2, "714718366", 9, 0 //Enviar número QQ al usuario

}

else

{// De lo contrario, significa que la contraseña es incorrecta

send (sock2, "¡La contraseña es incorrecta!" ",10,0);

}

>

}

}

//=================[/ft]Cerrar la conexión de red y salir= = =====================

closesocket(sock2);

closesocket(sock1);

return 0;

}

Este es un programa de servidor Cuando un usuario se conecta, primero enviará una oración para solicitarle que ingrese la contraseña de inicio de sesión. De hecho, es similar al ejemplo de desbordamiento local mencionado anteriormente. El problema radica en el código que copia los datos del caché a la memoria. Si la contraseña ingresada por el usuario remoto es demasiado larga, ocurrirá el mismo fenómeno de desbordamiento. Entonces el programa generará un error y el servidor se cerrará a la fuerza.

Por ejemplo, el programa de servidor de software de mensajería instantánea de Tencent fue atacado constantemente por piratas informáticos, lo que provocó que el servidor fallara y no pudiera proporcionar servicios normales. Como resultado, muchos usuarios no pudieron iniciar sesión. de manera oportuna solo tomaría unos minutos. Se volvió a desconectar al cabo de un mes porque su servidor tenía una vulnerabilidad y fue explotado por otros, lo que causó pérdidas inconmensurables a ellos y a sus clientes.

3 Edición de información relacionada

Métodos de ataque de vulnerabilidad de desbordamiento de búfer

La vulnerabilidad de desbordamiento de búfer puede permitir que cualquier persona con habilidades de hacker obtenga el control de la máquina o incluso es el máxima autoridad. Generalmente, las vulnerabilidades de desbordamiento del búfer se utilizan para atacar programas raíz, y la mayoría de ellos obtienen el shell raíz ejecutando un código de ejecución similar a "exec(sh)". Para lograr sus objetivos, los piratas informáticos generalmente tienen que completar dos tareas: organizar el código apropiado en el espacio de direcciones del programa y hacer que el programa salte al espacio de direcciones organizado para su ejecución a través de registros de inicialización y memorias apropiados.

Colocar el código apropiado en el espacio de direcciones del programa

Colocar el código apropiado en el espacio de direcciones del programa suele ser relativamente sencillo. Si el código a atacar ya existe en el programa atacado, simplemente pase algunos parámetros al código y luego haga que el programa salte al objetivo. El código de ataque requiere la ejecución de "exec('/bin/sh')", mientras que el código en la biblioteca libc ejecuta "exec(arg)", donde "arg" es un parámetro de puntero que apunta a una cadena, siempre que el parámetro pasado Simplemente modifique el puntero para que apunte a "/ bin/sh" y luego salte a la secuencia de instrucciones de respuesta en la biblioteca libc. Eso sí, muchas veces esta posibilidad es muy pequeña, por lo que hay que realizarla mediante un método llamado "método de implantación". Cuando se ingresa una cadena en el programa a atacar, el programa colocará la cadena en el búfer. Los datos contenidos en esta cadena son una secuencia de instrucciones que se pueden ejecutar en la plataforma de hardware del objetivo. El búfer se puede ubicar en cualquier lugar: pila (variables automáticas), montón (asignado dinámicamente), área de datos estáticos (datos inicializados o no inicializados), etc. No es necesario desbordar ningún buffer para lograr esto, solo encontrar suficiente espacio para colocar el código de ataque.

La forma en que el programa de control se transfiere al código de ataque

Los ataques de vulnerabilidad de desbordamiento de búfer buscan cambiar el flujo de ejecución del programa para que salte al código de ataque al máximo. El básico es el desbordamiento. Un búfer sin comprobaciones u otras vulnerabilidades que interrumpe el orden de ejecución normal del programa. Al desbordar un búfer, se puede reescribir el espacio de un programa similar y se puede omitir directamente la verificación de identidad del sistema. En principio, el espacio del programa al que se dirige el desbordamiento del búfer durante el ataque puede ser cualquier espacio. Sin embargo, debido a la diferente ubicación en diferentes lugares, se han introducido una variedad de métodos de transferencia.

(1) Punteros de función (punteros de función)

En el programa, "void (* foo) ( )" declara una variable con un valor de retorno de "void" Punteros de función" foo".

Los punteros de función se pueden usar para ubicar cualquier espacio de direcciones. Al atacar, solo necesita encontrar un búfer que pueda desbordarse cerca de los punteros de función en cualquier espacio y luego usar el desbordamiento para cambiar los punteros de función. Cuando el programa llama a funciones a través de punteros de función, se realizará el flujo del programa.

(2) Registros de activación (Registros de activación)

Cuando se produce una llamada a una función, un Registro de activación permanecerá en la pila, que contiene la dirección del remitente cuando finaliza la función. La ejecución desborda estas variables automáticas para que la dirección de retorno apunte al código de ataque y luego cambia la dirección de retorno del programa. Cuando finalice la llamada a la función, el programa saltará a la dirección preestablecida en lugar de a la dirección original. Este tipo de desbordamiento también es relativamente común.

(3) Búfer Longjmp (búfer de salto largo)

El lenguaje C contiene un sistema simple de verificación/recuperación llamado "setjmp/longjmp", que significa Establecer "setjmp(buffer)" en el punto de control y use longjmp(buffer)" para restaurar el punto de control. Si el ataque puede ingresar al espacio del buffer, se siente como si "longjmp(buffer)" en realidad salta al código de ataque. Al igual que los punteros de función, los buffers longjmp pueden apuntar a cualquier parte, por lo tanto, lo primero que debe hacer es encontrar un búfer para desbordarse.

Integrar código integral y control de flujo

Una clase de ataque de búfer de desbordamiento común combina la implantación de código y los registros de activación en una cadena. localiza una variable automática para el desbordamiento y luego pasa una cadena grande al programa para activar el búfer. El desbordamiento cambia los registros de activación mientras se implanta el código (porque C está acostumbrado a abrir solo un pequeño búfer para los usuarios y los parámetros del código implantado). y el desbordamiento del búfer no es necesario completarlo al mismo tiempo, y se puede colocar en un código de búfer (el búfer no se puede desbordar en este momento) y luego transferir el puntero del programa desbordando otro búfer. el búfer para desbordamiento no puede contener todo el código. Cuando no es necesario implantar el código restante externamente, el código primero debe usarse como parámetro. Los amigos que estén familiarizados con C deben saber que casi todas las conexiones de programas C ahora lo usan. connect. El segmento ejecutará "exec (algo)", donde algo es el parámetro, usará un desbordamiento de búfer para cambiar los parámetros del programa y luego usará otro desbordamiento de búfer para apuntar el puntero del programa a un segmento de código específico en libc.

La inseguridad de la red causada por errores de programación también debe tomarse en serio, porque su inseguridad ha quedado claramente demostrada por los desbordamientos del buffer.