Con questo articolo voglio riassumere alcuni dettagli che ho trovato durante l’analisi del software McAfee Virus Scan, storicamente parlando, si tratta di uno dei primi antivirus commerciali. Studiarne i dettagli e il funzionamento potrebbe rivelare alcune scelte di progettazione che mostrano come i primi antivirus funzionarono. In particolar modo siamo interessati a capire come avveniva la detection dei malware, nonché alle particolari caratteristiche che il prodotto McAfee offriva.
Il prodotto McAfee Virus Scan è stato uno dei primi antivirus sviluppato dall’omonimo fondatore dell’azienda John McAfee ed è divenuto successivamente il prodotto della McAfee Corporation. Seppur il prodotto venne commercializzato prestissimo (parliamo del 1988 come primo anno di rilascio), è possibile ancora trovarne alcune copie online. Per recuperare uno dei primi binari, sono andato su web.archive.org che dispone di una vasta gamma di archivi di materiali tra cui software, ma anche libri, documenti, film e molto altro.
Il binario a cui siamo interessati si chiama “McAfee Virus Scan” ed è l’installer del prodotto di antivirus, versione pubblicata il 10 ottobre 2002. Dal momento che siamo interessati ad ispezionarne il contenuto, scarichiamo il binario in locale e incominciamo l’analisi del software. Il binario scaricato VSHENU702D30.exe
è un archivio autoestraente chiamato “InstallShield self-extracting archive”.
InstallShield è una piattaforma per la creazione di programmi di installazione e distribuzione di software. Sviluppato da Flexera Software, viene utilizzato dalle aziende per creare programmi di installazione per prodotti software. Comunemente parlando, un installer è composto da due principali sezioni. La prima sezione è la serie di informazioni che serve al binario per estrarre il contenuto (e quindi effettivamente installare il software), mentre la seconda sezione è dato dal contenuto stesso (i file che il programma deve installare). In questo caso siamo interessati ad estrarre dal programma il contenuto della suite McAfee.
Un binario PE (Portable Executable) creato con InstallShield consta di vari elementi:
InstallShield
che segue l’ultima sezione del file PE;IS_HEADER
(InstallShield Header) che consente di recuperare la firma del file, il numero di file, il tipo di instestazione;IS_FILE_ATTRIBUTES
che specifica una serie di attributi file secondari (come il nome del file originale, alcune flag - principalmente i permessi);Esempi di strutture dati che possiamo trovare all’interno del binario di InstallShield:
typedef struct IS_HEADER {
char signature[14];
uint16_t num_files;
uint32_t type; // used by "ISSetupStream" format
uint8_t unknown[26];
} IS_HEADER;
dove:
\0
)0
per produzione, 1
per testing e 2
per sviluppo)Un’altra struttura importante è rappresentata dagli attributi del file.
typedef struct IS_FILE_ATTRIBUTES {
char file_name[_MAX_PATH]; // _MAX_PATH è definito come
uint32_t encoded_flags; // flag come i permessi del file
uint32_t x3;
uint32_t file_len;
uint8_t unknown_2[8];
} IS_FILE_ATTRIBUTES;
dove:
Il contenuto di ogni file è compresso utilizzando l’algoritmo LZMA, Lempel Ziv Markov, un algoritmo utilizzato per la compressione dei dati. L’algoritmo LZMA utilizza una codifica tramite un dizionario per memorizzare le occorrenze e i riferimenti ad un pattern di stringhe comuni. L’idea è quella di avere un dizionario che rappresenti le coppie <Stringa, NumeroDiOccorrenze>
. Una serie di strutture dati ausiliarie vengono utilizzate per memorizzare l’offset dell’occorrenza. Per saperne di più sulla specifica dell’algoritmo vi consiglio la lettura “LZMA specification”.
L’estrazione dei file viene effettuata tramite questo semplice algoritmo (ricavato tramite IDA Free ❤️ ):
GetTempFileNameA(lpPathName, PrefixString, 0, TempFileName);
v3 = (void *)sub_401756(TempFileName, 33025);
result = -1;
if ( v3 != NULL ){
sub_40182F(v3, lpBuffer, nNumberOfBytesToWrite);
sub_401851(v3);
v5 = LZOpenFileA(TempFileName, &ReOpenBuf, 0);
v6 = LZOpenFileA(lpFileName, &v9, 0x1001u);
v7 = LZCopy(v5, v6);
LZClose(v5);
LZClose(v6);
DeleteFileA(TempFileName);
return v7;
}
I passi dell’algoritmo sono i seguenti:
TempFileName
e la routine sub_401756
sub_40182F
È ovviamente possibile estrarre il contenuto del file semplicemente avviando un qualsiasi debugger e impostando diversi breakpoint sulle funzioni di interesse (in questo caso LZOpenFileA
e LZCopy
).
Dal momento che stiamo lavorando su un installer creato molti anni fa (quasi 21!) le strutture dati dell’installer potrebbero non essere le stesse utilizzate nell’ultima versione di InstallShield. Per estrarre il contenuto del binario non è necessario fare nulla di straordinariamente difficile. È sufficiente eseguire il comando 7z x nome-binario
che utilizza il software 7zip: in questo modo possiamo ricavare i binari che andrebbero installati all’interno della cartella C:\Programmi (x86)\McAfee Virus Scan
. Il contenuto del binario è il seguente:
[5]SummaryInformation' Binary.EpocDetect.dll Icon.VsMain.exe
'!ActionText' Binary.Exclaim '!IniFile'
'!AdminExecuteSequence' Binary.McAfeeCA.dll '!InstallExecuteSequence'
'!AdminUISequence' Binary.McAfeeCA.Dll.03723396_538B_11D4_B355_00B0D04BB45E '!InstallShield'
'!AdvtExecuteSequence' Binary.McAfeeCA.Dll.E2288E6B_6CA7_11D4_B37B_00B0D04BB45E '!InstallUISequence'
'!AppSearch' Binary.NAILogo_Top.bmp '!LaunchCondition'
'!Binary' Binary.SetAllUsers.dll '!Media'
Binary.ACCEPTLICENSE Binary.side16 '!ModuleComponents'
Binary.AxdistEXE Binary.VSCLogo_Left.bmp '!ModuleDependency'
Binary.Binary20 Binary.VSCTop_NoLogo.bmp '!ModuleSignature'
Binary.Binary21 '!CheckBox' '!MoveFile'
Binary.Binary22 '!Class' '!ProgId'
Binary.Binary23 '!_Columns' '!Property'
Binary.Binary24 '!Component' '!RadioButton'
Binary.Binary25 '!Condition' '!Registry'
Binary.Binary26 '!Control' '!RegLocator'
Binary.Binary27 '!ControlCondition' '!RemoveFile'
Binary.Binary28 '!ControlEvent' '!RemoveRegistry'
Binary.Binary29 '!CreateFolder' '!SelfReg'
Binary.Binary30 '!CustomAction' '!ServiceControl'
Binary.Binary31 Data.Cab '!ServiceInstall'
Binary.Binary32 '!Dialog' '!Shortcut'
Binary.Binary33 '!Directory' '!Signature'
Binary.Binary34 '!DrLocator' '!_StringData'
Binary.Callca_vsc '!Error' '!_StringPool'
Binary.Callca_vsc_nt '!EventMapping' '!_Tables'
Binary.Callimmediate '!Feature' '!TextStyle'
Binary.Callmsi_inst '!FeatureComponents' '!TypeLib'
Binary.Callritual '!File' '!UIText'
Binary.Callwiseapi '!Icon' '!Upgrade'
Binary.DELETE.EXE Icon._B291A24037AB_11D7_BAF5_00B0D0C6893B.exe '!_Validation'
Binary.Dll_.ini Icon._C050255A3944_11D7_99DE_00605B102CFB.exe VSC.msi
Binary.DLLWRAP.DLL Icon.Icon63CB76201.exe
Binary.DontInstall.ico Icon.Icon63CB7620.exe
Come è possibile notare, 7zip ha estratto tutto il contenuto del file binario, comprese alcune informazioni secondarie che specificano alcune impostazioni all’installer. Queste impostazioni sono codificate in una serie di file a cui non siamo interessati (ad esempio '!Dialog
o !File
). Questi file sono denotati dall’iniziale del nome del file '!
: possiamo quindi procedere a spostare/cancellare tali file. Per cancellarli possiamo utilizzare il comando rm \!*
. Tutto ciò invece che è possibile ricavare sono i file che rappresentano il programma McAfee Virus Scan.
Successivamente possiamo filtrare i binari per tipo: non vogliamo che la nostra analisi si concentri su file che consentono grafica (icone, immagini). Possiamo quindi eseguire file nome_file
per capire meglio la natura del file. I file eseguibili, le librerie e il codice nativo su Windows di solito sono contenuti all’interno del formato file PE e presentano una dicitura molto simile a:
PE32 executable (DLL|GUI) Intel 80386, for MS Windows
Nel prossimo articolo ci focalizzeremo sull’effettuare un primo reverse engineering del motore interno di McAfee per la scansione dei file e delle directory F324_SCAN.EXE
. Se avete qualche commento, curiosità o critica, potete scrivermi una e-mail.