• Nome:Ricardo L0gan
  • Especialidade:Network Security and Security Researcher Enthusiast
  • E-mail:ricardologanbrøgmail·com·br
  • Contato:About-me | Github: Loganbr | Twitter:l0ganbr | Localização:::1
Análise Estática de Malware com o PEV

Sempre que precisamos fazer uma rápida analise em um binário (PE), logo pensamos em Unpackers / Disassemblers / Debuggers e etc. Neste breve artigo, o foco será o PEV [1], ferramenta open source criada pelo brasileiro Fernando Merces que auxilia na analise estática de binário PE.

O artefato analisado está renomeado como malware.exe, inicialmente iremos procurar por evidencias que comprovem que ele é um binário malicioso.
A curiosidade é o unico pré-requisito exigido, então vamos a brincadeira:

File: malware.exe[2]Password: malwar
Plataforma Utilizada: Slackware 14
Ferramentas Utilizadas:
- file
- UPX
- PEV (pepack / pesec / pestr / pescan / pedis / readpe / pehash)

O Primeiro passo é verificar para qual plataforma este binario foi compilado, neste caso ainda extraímos outra informação bem relevante (packer UPX)
* O comando file junto com o UPX serão as únicas ferramentas que não fazem parte do projeto PEV utilizado nesta analise
$ file malware.exe
malware.exe: PE32 executable (GUI) Intel 80386, for MS Windows, UPX compressed

Sabendo que possui packer só para testar o PEV
$ pepack malware.exe
packer: UPX 2.90 [LZMA] -> Markus Oberhumer, Laszlo Molnar & John Reiser

E podemos também fazer da seguinte forma:
$ pestr malware.exe | grep UPX
UPX0
UPX1
UPX!

Ainda via pestr conseguimos identificar qual compilador foi utilizado para criar este binário
$ pestr malware.exe | grep VB
VBRUN
VBA6.DLL
MSVBVM60.DLL
C:\Program Files\Microsoft Visual Studio\VB98\VB6.OLB
MSVBVM60.DLL

Neste momento, verificamos as features de segurança utilizadas no binário.
$ pesec malware_upx.exe
ASLR: no
DEP/NX: no
SEH: yes
Stack cookies (EXPERIMENTAL): yes

Sabendo que o malware possui ofuscação (UPX), iremos salvar uma copia[3] do resultado gerado pelo pestr
$ pestr malware.exe > malware_pestr_upx.txt
$ wc -l malware_pestr.txt
429 malware_pestr.txt *Veja a quantidade de Linhas !!!

Ainda com o UPX vamos rodar o PEV (pescan) atrás de informações relevantes sobre o binário
$ pescan malware.exe
file entropy: packed (7.260721)
entrypoint: fake
DOS stub: normal
TLS directory: not found
section count: 3
UPX0: suspicious name, zero length, self-modifying
UPX1: suspicious name, self-modifying
.rsrc: normal
imagebase: normal
timestamp: normal

Neste momento, resolvi deixar separada uma copia do binario com UPX (malware_upx.exe)
$ cp malware.exe malware_upx.exe

E, enfim vamos remover o packer (UPX)
$ upx -d malware.exe
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2013
UPX 3.09 Markus Oberhumer, Laszlo Molnar & John Reiser Feb 18th 2013

File size Ratio Format Name
-------------------- ------ ----------- -----------
86016 <- 35840 41.67% win32/pe malware.exe

Unpacked 1 file.

Voltando a usar o pestr vemos que agora existem mais informações[4] disponíveis no binário
$ pestr malware.exe > malware_pestr_noupx.txt
$ wc -l malware_pestr_noupx.txt
583 malware_pestr_noupx.txt *Quantidade de linhas após o unpacker !!!

E finalmente rodando o pescan novamente sem o UPX
$ pescan malware.exe
file entropy: normal (5.212606)
entrypoint: normal
DOS stub: normal
TLS directory: not found
section count: 3
.text: normal
.data: normal
.rsrc: normal
imagebase: normal
timestamp: normal

Localizando o Offset (EntryPoint+ImageBase)
$ readpe malware.exe | grep -iA3 Entry
Entrypoint: 0x22c8
Address of .text section: 0x1000
Address of .data section: 0x12000
ImageBase: 0x400000

Também podemos rodar o readpe sem filtros e temos praticamente todas as informações já coletadas anteriormente
$ readpe malware.exe

DOS Header
Magic number: 0x5a4d (MZ) *Magic Number (Identifica como DOS(4d5a))
Bytes in last page: 144
Pages in file: 3
Relocations: 0
Size of header in paragraphs: 4
Minimum extra paragraphs: 0
Maximum extra paragraphs: 65535
Initial (relative) SS value: 0
Initial SP value: 0xb8
Initial IP value: 0
Initial (relative) CS value: 0
Address of relocation table: 0x40
Overlay number: 0
OEM identifier: 0
OEM information: 0
PE header offset: 0xc0

COFF/File header
Machine: 0x14c Intel 386 and compatible (32-bits)
Number of sections: 3
Date/time stamp: 1357759828 (Wed, 09 Jan 2013 19:30:28 UTC) *Data de Compilação
Symbol Table offset: 0
Number of symbols: 0
Size of optional header: 0xe0
Characteristics: 0x10f
base relocations stripped
executable image
line numbers removed (deprecated)
local symbols removed (deprecated)
32-bit machine

Optional/Image header
Magic number: 0x10b (PE32)
Linker major version: 6
Linker minor version: 0
Size of .text section: 0x11000
Size of .data section: 0x4000
Size of .bss section: 0
Entrypoint: 0x22c8
Address of .text section: 0x1000
Address of .data section: 0x12000
ImageBase: 0x400000
Alignment of sections: 0x1000
Alignment factor: 0x1000
Major version of required OS: 4
Minor version of required OS: 0
Major version of image: 9
Minor version of image: 30
Major version of subsystem: 4
Minor version of subsystem: 0
Size of image: 0x16000
Size of headers: 0x1000
Checksum: 0
Subsystem required: 0x2 (Windows GUI)
DLL characteristics: 0
Size of stack to reserve: 0x100000
Size of stack to commit: 0x1000
Size of heap space to reserve: 0x100000
Size of heap space to commit: 0x1000

Data directories
Import Table: 0x113d4 (40 bytes)
Resource Table: 0x14000 (8120 bytes)

Imported functions
export directory not found

Sections
Name: .text
Virtual Address: 0x1000
Physical Address: 0x10c64
Size: 0x11000 (69632 bytes)
Pointer To Data: 0x1000
Relocations: 0
Characteristics: 0x60000020
contains executable code
is executable
is readable
Name: .data
Virtual Address: 0x12000
Physical Address: 0x109c
Size: 0x1000 (4096 bytes)
Pointer To Data: 0x12000
Relocations: 0
Characteristics: 0xc0000040
contains initialized data
is readable
is writable
Name: .rsrc
Virtual Address: 0x14000
Physical Address: 0x1fb8
Size: 0x2000 (8192 bytes)
Pointer To Data: 0x13000
Relocations: 0
Characteristics: 0x40000040
contains initialized data
is readable

Agora podemos usar o pedis para chegar no entrypoint fazendo um disassembler do binário e salvando em um arquivo texto [5].
$ pedis -e malware.exe > malware_pedis.txt

Parte do Resultado:
$ pedis -e malware.exe
22c8: 68 58 24 40 00 push dword 0x402458
22cd: e8 f0 ff ff ff call 0x4022c2
22d2: 00 00 add [eax], al
22d4: 00 00 add [eax], al
22d6: 00 00 add [eax], al
22d8: 30 00 xor [eax], al
22da: 00 00 add [eax], al
22dc: 38 00 cmp [eax], al
22de: 00 00 add [eax], al
22e0: 00 00 add [eax], al
22e2: 00 00 add [eax], al
22e4: fb sti
22e5: b1 2e mov cl, 0x2e
22e7: 8e 42 ee mov es, [edx-0x12]
22ea: 72 49 jb 0x402335


Verificando o Hash do binário (Isto pode ser feito antes de se remover o UPX), apenas para sabermos se o mesmo foi alterado.
$ pehash malware.exe
md5: 43f51ae8093ec5be35e5a8bcf9f7b010
sha-1: eb475d40e3bb0cf0741bf1bbd1395a0567aa67ad
sha-256: 3ee63029d3ced827deb1ec009b8e084020a96b0683138999b852c60675a6bac6

Bom, até o momento conseguimos examinar algumas evidencias que apontariam o binário como malicioso, como por exemplo o uso de packer, mas não realmente evidenciado como malicioso. Como de praxe também averiguei a taxa de detecção 27/46 via Virustotal [6] só para vermos como ele era classificado.
Basicamente na analise estatica extraímos informações que servirão como base para uma analise dinamica em um ambiente Windows e executando / debugando o malware afim de encontrar gatilhos e comportamentos mais específicos. Porem, com o conteúdo apresentado rapidamente ja conseguimos responder algumas duvidas que possam surgir.

Agradecimentos
Gostaria de agradecer ao amigo Fernando Mercês que me incentiva a escrever [7] sobre malware e ao brother Assuero que abriu espaço para escrever no blog [8]

Links:
[1] Sourceforge ou Github
[2] malware.zip
[3] malware_pestr_upx.txt
[4] malware_pestr_noupx.txt
[5] malware_pedis.txt
[6] Virustotal
[7] Mentebinaria
[8] Malwar.org