59
Università degli Studi di Trieste Dipartimento di Ingegneria e Architettura Tesi di Laurea Magistrale in INGEGNERIA INFORMATICA A NALISI E REALIZZAZIONE DI UNO STRUMENTO PER LA VERIFICA DI CONFORMITÀ SU SISTEMI REMOTI BASATO SULLO STANDARD XCCDF Laureando: Relatore: Davide Bravin Prof. Alberto Bartoli Correlatore: Alessandro Budai Anno Accademico 2012-2013

Analisi e realizzazione di uno strumento per la verifica di conformità su sistemi remoti basato sullo standard XCCDF - Tesi

Embed Size (px)

Citation preview

Università degli Studi di Trieste

Dipartimento di Ingegneria e Architettura

Tesi di Laurea Magistrale in

INGEGNERIA INFORMATICA

ANALISI E REALIZZAZIONE DIUNO STRUMENTO PER LA

VERIFICA DI CONFORMITÀ SUSISTEMI REMOTI BASATO SULLO

STANDARD XCCDF

Laureando: Relatore:

Davide Bravin Prof. Alberto Bartoli

Correlatore:

Alessandro Budai

Anno Accademico 2012-2013

Indice

Introduzione vi

1 Analisi 1

1.1 Problematiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Descrizione protocolli e linguaggi . . . . . . . . . . . . . . . . . 3

1.2.1 Descrizione linguaggio OVAL . . . . . . . . . . . . . . . 6

1.2.2 Descrizione linguaggio XCCDF . . . . . . . . . . . . . . 10

1.2.3 Relazioni tra gli standard XCCDF e OVAL . . . . . . . . 13

1.3 Obiettivi e vincoli . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.4 Descrizione OVAL engine esistente . . . . . . . . . . . . . . . . 17

2 Progettazione 20

2.1 Elaborazione di una checklist XCCDF . . . . . . . . . . . . . . 20

2.1.1 Fase Loading . . . . . . . . . . . . . . . . . . . . . . . . 20

2.1.2 Fase Traversal . . . . . . . . . . . . . . . . . . . . . . . . 21

2.1.3 Fase Assessment Result . . . . . . . . . . . . . . . . . . . 23

2.2 Refactoring del progetto iniziale . . . . . . . . . . . . . . . . . . 24

2.2.1 Refactoring classe XmlSourceProvider . . . . . . . . . . . 25

2.2.2 Adapter XML . . . . . . . . . . . . . . . . . . . . . . . . 28

2.2.3 Refactoring classe Finder2 . . . . . . . . . . . . . . . . . 29

2.2.4 Implementazione External Variable . . . . . . . . . . . . 30

2.3 Progettazione dell’interprete . . . . . . . . . . . . . . . . . . . . 31

2.3.1 Oggetti in memoria e importazione . . . . . . . . . . . . 31

2.3.2 Elaborazione della checklist e risultati . . . . . . . . . . . 33

2.4 Metodologia di sviluppo . . . . . . . . . . . . . . . . . . . . . . 34

ii

3 Realizzazione 35

3.1 Interfaccia ed esempio di funzionamento . . . . . . . . . . . . . 35

3.1.1 Esempio di scansione completa . . . . . . . . . . . . . . 36

3.2 Implementazione . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3.2.1 Package “xccdfobjects” . . . . . . . . . . . . . . . . . . . 41

3.2.2 Package “xccdfprocess” . . . . . . . . . . . . . . . . . . . 42

3.3 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

4 Conclusioni 48

4.1 Obiettivi e sviluppi futuri . . . . . . . . . . . . . . . . . . . . . 48

4.2 Valutazione del lavoro svolto . . . . . . . . . . . . . . . . . . . . 48

4.3 Valutazioni personali . . . . . . . . . . . . . . . . . . . . . . . . 49

5 Bibliografia 50

iii

Elenco delle figure

1.1 Rappresentazione schematica dell’utilizzo di OVAL . . . . . . . 8

1.2 Struttura del linguaggio OVAL . . . . . . . . . . . . . . . . . . 9

1.3 Relazione tra XCCDF e checking engine . . . . . . . . . . . . . 11

1.4 Struttura del linguaggio XCCDF . . . . . . . . . . . . . . . . . 11

1.5 Rappresentazione schematica dell’utilizzo di XCCDF . . . . . . 13

1.6 Relazione tra XCCDF e OVAL . . . . . . . . . . . . . . . . . . 14

1.7 Relazione tra i documenti XCCDF e OVAL . . . . . . . . . . . 15

1.8 Importazione dei documenti OVAL . . . . . . . . . . . . . . . . 18

1.9 Opzioni dell’engine OVAL . . . . . . . . . . . . . . . . . . . . . 18

1.10 Rappresentazione dell’OVAL engine . . . . . . . . . . . . . . . . 19

2.1 Esempio della procedura extends applicata a un profilo . . . . . 21

2.2 Associazione dei risultati OVAL e XCCDF . . . . . . . . . . . . 23

2.3 Class Diagramm delle classe XmlSourceProvider . . . . . . . . . 26

2.4 Activity Diagram del metodo rebuilddb . . . . . . . . . . . . . . 27

2.5 Sequence Diagram delle interazioni del metodo rebuilddb . . . . 28

2.6 Class Diagram dell’adapter . . . . . . . . . . . . . . . . . . . . . 29

2.7 Activity Diagram dell’adapter . . . . . . . . . . . . . . . . . . . 29

2.8 Elementi figli di external_variable . . . . . . . . . . . . . . . . . 30

2.9 Class diagram degli elementi XCCDF . . . . . . . . . . . . . . . 32

2.10 Class diagram della classe XccdfParser . . . . . . . . . . . . . . 32

2.11 Class diagram delle classi della fase Traversal . . . . . . . . . . . 33

2.12 Class diagram della classe ResultLogger . . . . . . . . . . . . . . 33

3.1 Path dei documenti XCCDF e OVAL . . . . . . . . . . . . . . . 37

3.2 Creazione del Database OVAL . . . . . . . . . . . . . . . . . . . 37

iv

3.3 Verifica della connessione col target . . . . . . . . . . . . . . . . 37

3.4 Comandi della console XCCDF . . . . . . . . . . . . . . . . . . 38

3.5 Schermata della selezione dei profili . . . . . . . . . . . . . . . . 38

3.6 Esempi di scansioni delle definizioni OVAL . . . . . . . . . . . . 39

3.7 Esempi di regole che hanno superato il test . . . . . . . . . . . . 40

3.8 Esempi di regole che non hanno superato il test . . . . . . . . . 40

3.9 Esempi di regole che non sono state valutate . . . . . . . . . . . 40

3.10 Report finale della scansione . . . . . . . . . . . . . . . . . . . . 40

v

Introduzione

La presente tesi illustra il lavoro svolto presso Emaze Networks S.p.A.

L’azienda è interessata ai problemi di Vulnerability Assessment e Manage-

ment. Il tentativo di prevenire le minacce e la sempre maggiore complessità

dei sistemi portano alla volontà di automatizzare il più possibile le procedure

di controllo che permettono di minimizzare l’impatto di possibili vulnerabilità.

L’obiettivo di questo elaborato è quello di realizzare uno strumento auto-

matizzato che permetta, partendo da delle checklist contenenti delle specifiche

di configurazione, di eseguire delle verifiche di conformità su sistemi remoti.

Questi controlli permettono di verificare che il sistema presenti la configura-

zione voluta. Questo strumento deve rispettare lo standard XCCDF1 per la

gestione delle checklist e deve interagire con uno strumento OVAL2 già pre-

sente in azienda. Si è inoltre richiesto di eseguire alcune ristrutturazione dello

strumento OVAL. Il linguaggio di programmazione utilizzato è Python.

Il lavoro è stato sviluppato in tre fasi: la fase di analisi del progetto esistente

e degli standard necessari per la creazione dello strumento, la fase di proget-

tazione e infine quella di realizzazione tramite metodologie “agile” e “TDD3”

che portano a una continua revisione delle ultime due fasi rendendole meno

distinte.

Il documento di tesi è articolato in cinque capitoli, brevemente riassunti di

seguito:

1. analisi del contesto, delle problematiche, degli obiettivi, dei vincoli e degli

standard necessari per lo sviluppo del progetto;1Extensible Configuration Checklist Description Format.2Open Vulnerability and Assessment Language.3Test Driven Development

vi

2. descrizione dell’elaborazione di una checklist, delle modifiche allo stru-

mento OVAL esistente e della progettazione dello strumento XCCDF;

3. descrizione dell’interfaccia e dell’implementazione della logica del siste-

ma;

4. conclusioni del lavoro, possibili sviluppi futuri e valutazione del lavoro

svolto;

5. riferimenti bibliografici.

vii

Capitolo 1

Analisi

1.1 Problematiche

L’azienda è da sempre impegnata nella ricerca di standard e nello sviluppo

di strumenti per il Vulnerability Management1.

Vulnerability Management

Una possibile definizione di VM è data dall’omonimo libro di Park Fore-

man2:

“The cyclical practice of identifying, classifying, remediating, and

mitigating vulnerabilities.”

Inizialmente l’assenza di standard di riferimento rendeva molto difficile poter

utilizzare le informazioni ottenute da diverse fonti (es. Advisory) e confrontare

i risultati ottenuti con diversi prodotti (es. Vulnerability Scanner). Questo

portava alla quasi impossibilità d’automazione e d’interoperabilità tra prodotti

e fonti d’informazioni eterogenei.

Queste problematiche hanno reso necessario la definizione di standards VM

con lo scopo di:

• promuovere l’uniformità e la consistenza dei dati e dei risultati;

• favorire l’interoperabilità tra i prodotti e fonti di informazioni eterogenee;

• standardizzare e automatizzare le operazioni di sicurezza;1In questo documento abbreviato con VM.2Vulnerability Management, Park Foreman, Taylor and Francis (Auerbach Publications),

pag. 1.

1

• favorire la condivisione e il riutilizzo delle informazioni, dei dati o dei

risultati;

• semplificare i processi di correlazione;

• ridurre i margini di errore e la complessità del software;

• rendere la sicurezza misurabile;

• compliance normativa;

• utilizzare standard aperti ed estensibili liberamente.

Alcune delle principali organizzazioni dietro alla definizione e allo sviluppo

di questi standards sono:

• National Institute of Standards and Technology (NIST);

• MIT Research and Engineering (MITRE) Corporation;

• National Security Agency/Central Security Service (NSA/CSS);

• Forum of Incident Response and Security Teams (FIRST).

Queste organizzazioni sono tutte americane ed alcune di esse sono organiz-

zazioni governative o militari.

Problematiche oggetto della tesi

Questi standard permettono di aumentare l’automatizzazione dei processi

di VM, per questo motivo l’Emaze Networks è interessata all’analisi e allo

sviluppo di questi standard per integrarli nei software aziendali in modo da

poter fornire un maggior numero di servizi ai clienti.

Dato l’accesso a un sistema (inteso, in questo documento, come un sistema

remoto, ovvero un calcolatore raggiungibile tramite protocolli di rete dagli

strumenti di analisi e verifica, indicato anche con la parola target), alcune

delle problematiche che hanno motivato il lavoro di tesi sono le seguenti:

• verificare la presenza di una vulnerabilità specifica;

2

• verificare la presenza delle vulnerabilità note tra quelle presenti nel re-

pository aziendale o nei repository di organizzazioni esterne, come ad

esempio il NVD3;

• verificare la presenza di un software;

• verificare la versione di un software installato;

• verificare la presenza di una determinata configurazione di un software;

• verificare la presenza di una determinata configurazione del sistema ope-

rativo.

L’elevato numero di controlli, l’esecuzione di essi su un numero indefinito di

sistemi, i diversi livelli di criticità e l’eterogeneità dei target (ad es. sistemi ope-

rativi differenti) sono alcuni aspetti che portano alla volontà di automatizzare

questi processi e diminuire l’approccio manuale di un operatore.

L’automatizzazione porta anche altri vantaggi, quali:

• azzeramento dell’errore umano;

• ripetizione e schedulazione dei controlli;

• report automatici dei risultati.

Per tutte le motivazioni descritte precedentemente si è deciso di implemen-

tare alcuni di questi strumenti rispettando i protocolli standard. In particolare,

in questo documento verranno trattati gli standard OVAL, XCCDF e SCAP4.

1.2 Descrizione protocolli e linguaggi

Come descritto precedentemente ci sono molti standard, ognuno avente uno

scopo diverso. Il protocollo SCAP è stato concepito con l’obiettivo di stan-

dardizzare il modo in cui le vulnerabilità di sicurezza e le configurazioni del

sistema sono identificate e catalogate. Sviluppato e mantenuto dal NIST, il3National Vulnerability Database, repository del governo degli Stati Uniti che contiene i

dati riguardanti il VM.4Security Content Automation Protocol.

3

protocollo SCAP è formato da sette5 standard aperti, chiamati components.

Questi hanno l’obiettivo di classificare le vulnerabilità, catalogare i nomi dei

prodotti software, identificare le configurazioni che implicano possibili proble-

mi di sicurezza, verificare i sistemi per determinare la presenza di vulnerabilità

e fornire meccanismi per valutare i risultati di queste misurazioni permetten-

do di verificare l’impatto della vulnerabilità. SCAP definisce come utilizzare

questi componenti e come questi comunichino tra loro; da notare che il NIST

non ha il controllo diretto di questi standard.

5Il settimo componente è presente da SCAP 1.1.

4

Acronyms Name Description

CVE Common

Vulnerability

Enumeration

Standard nomenclature and

dictionary of security related

software flaws

CCE Common

Configuration

Enumeration

Standard nomenclature and

dictionary of software

misconfigurations

CPE Common Platform

Enumeration

Standard nomenclature and

dictionary for product naming

XCCDF eXtensible Checklist

Configuration

Description Format

Standard XML for specifying

checklists and for reporting

results of checklist evaluation

OVAL Open Vulnerability

and Assessment

Language

Standard XML for test

procedures

OCIL Open Checklist

Interactive Language

Standard XML for human

interaction

CVSS Common

Vulnerability Scoring

System

Standard for measuring the

impact of vulnerabilities

Tabella 1.1: Elenco componenti del protocollo SCAP

I componenti SCAP elencati nella tabella 1.1 possono essere distinti in tre

gruppi, Enumeration, Language, Metric:

• Enumeration, convenzioni per identificare e nominare:

– CVE: identificatore standard utilizzato per identificare le vulnera-

bilità;

– CCE: identificatore standard utilizzato per identificare le configu-

razioni di sicurezza dei sistemi;

5

– CPE: dizionario standard per descrivere in maniera univoca sistemi

hardware e software;

• Language, forniscono istruzioni e riportano i risultati:

– OVAL: descrizione standard delle componenti del sistema che devo-

no essere collezionate e confrontate con valori predefiniti;

– OCIL: fornisce un framework concettuale per rappresentare gli ar-

gomenti non automatizzabili;

– XCCDF: descrizione in forma machine-readable di un insieme di

configurazioni di sicurezza per qualche sistema;

• Metric, misura del rischio:

– CVSS: framework standard per determinare il livello di rischio as-

sociato a una vulnerabilità.

Per il progetto descritto in questo documento verranno trattati solamente i

componenti OVAL e XCCDF. L’interazione tra questi componenti è descritta

nella specifica del protocollo SCAP.

1.2.1 Descrizione linguaggio OVAL

Lo standard OVAL è gestito dal MITRE ed è sponsorizzato dal U.S De-

partment of Homeland Security6, una breve descrizione presa direttamente dal

sito ufficiale7 è:

“Open Vulnerability and Assessment Language (OVAL) is an in-

ternational, information security, community standard to promote

open and publicly available security content, and to standardize

the transfer of this information across the entire spectrum of se-

curity tools and services. OVAL includes a language used to en-

code system details, and an assortment of content repositories held

throughout the community. The language standardizes the three6DHS.7http://oval.mitre.org/about/

6

main steps of the assessment process: representing configuration

information of systems for testing; analyzing the system for the

presence of the specified machine state (vulnerability, configura-

tion, patch state, etc.); and reporting the results of this assess-

ment. The repositories are collections of publicly available and

open content that utilize the language.”

Lo standard OVAL è composto principalmente da tre componenti, che sono:

• OVAL Language basato su xml, necessario per esprimere lo stato e

permettere di fare delle asserzioni sul sistema;

• OVAL Repository dei contenuti scritti nel linguaggio OVAL grazie al

contributo della community8;

• OVAL Adoption che assicura che un implementazione OVAL coincida

con gli standard.

OVAL Language fornisce una descrizione dettagliata delle informazioni che

devono essere raccolte dal sistema da analizzare. Successivamente le configu-

razioni rilevate vengono confrontate con il valore di riferimento e quindi viene

ritornato un risultato che può essere positivo o negativo. Questo processo è

visibile nella figura 1.1.

8Sono disponibili altri repository come Debian, NIST, Red Hat.

7

Figura 1.1: Rappresentazione schematica dell’utilizzo di OVAL

Struttura OVAL

Come si può notare nella figura 1.2, alla base del linguaggio OVAL ci sono le

definizioni dette OVAL Definitions, queste hanno lo scopo di combinare uno o

più test usando gli operatori logici AND e OR e di contenere metadati utili per

l’utilizzo. Un OVAL Test associa un OVAL Object a un valore di riferimento,

detto OVAL State, con il quale si vuole confrontare. Ogni test necessita di

uno o più “oggetti” da controllare. Gli OVAL Object sono quei componenti del

sistema che devono essere valutati, alcuni esempi sono: un file, un processo,

una chiave di registro. Un OVAL State esprime come deve essere confrontato

il valore dell’oggetto appena estratto per poter valutare il test positivo. Le

OVAL Variable possono essere riferite da OVAL Object, OVAL State e altre

OVAL Variable, esse sono dei contenitori di uno o più valori dello stesso tipo

e si dividono in:

• constant_variable un semplice valore costante;

8

• external_variable il valore della variabile è ottenuto a tempo di ese-

cuzione da una sorgente esterna, es. XCCDF Benchmark Document;

• local_variable il valore della variabile è ottenuto a tempo di esecuzio-

ne manipolando valori recuperati dagli oggetti, da altre variabili o da

literal9.

Figura 1.2: Struttura del linguaggio OVAL

OVAL non fornisce indicazioni su come queste configurazioni vengano “estrat-

te” dal sistema, ma dà le indicazioni necessarie per poter estrarre informazioni

quali la tipologia di configurazione (es. chiave di registro, file di configurazione,

presenza di file su disco), il percorso della configurazione, lo stato che essa deve9http://oval.mitre.org/language/version5.10/ovaldefinition/documentation/

oval-definitions-schema.html#LiteralComponentType.

9

assumere per superare il confronto e la tipologia del confronto (es. se il valore

rilevato deve essere uguale o maggiore, uguale o minore al valore voluto).

1.2.2 Descrizione linguaggio XCCDF

Lo standard XCCDF è guidato dal NSA, pubblicato dal NIST e sviluppato

con il contributo della comunità. Una breve descrizione estratta direttamente

del sito ufficiale del NIST10 è:

“XCCDF is a specification language for writing security checklists,

benchmarks, and related kinds of documents. An XCCDF doc-

ument represents a structured collection of security configuration

rules for some set of target systems. The specification is designed to

support information interchange, document generation, organiza-

tional and situational tailoring, automated compliance testing, and

compliance scoring. The specification also defines a data model and

format for storing results of benchmark compliance testing. The in-

tent of XCCDF is to provide a uniform foundation for expression of

security checklists, benchmarks, and other configuration guidance,

and thereby foster more widespread application of good security

practices.”

XCCDF permette, partendo da bollettini di sicurezza, guide di configura-

zioni o altre direttive, di creare delle checklist in formato machine-readable che

hanno lo scopo di minimizzare l’impatto di possibili vulnerabilità. Infatti mol-

te vulnerabilità possono essere annullate o mitigate se il sistema ha una certa

configurazione. Il NIST fornisce un insieme di checklist che sono disponibili

nel loro repository.

XCCDF non specifica un proprio sistema (platform-specific) per la logica di

controllo delle regole, ma gli elementi Rule/Check contengono le informazioni

per guidare un platform-specific engine. XCCDF è disegnato per supportare

l’integrazione con molteplici checking engine. Tipicamente (e secondo il pro-10http://scap.nist.gov/specifications/xccdf/

10

tocollo SCAP) l’engine di default implementa OVAL, come rappresentato in

figura 1.3.

Figura 1.3: Relazione tra XCCDF e checking engine

Struttura XCCDF

Una checklist XCCDF è un documento XML i cui elementi principali sono

visibili in figura 1.4.

Figura 1.4: Struttura del linguaggio XCCDF

Di seguito viene presentata una breve panoramica di questi elementi:

• Benchmark questo elemento, unico, è la radice del documento e con-

tiene tutti gli altri elementi;

• Item

– Group questo Item contiene altri Item;

11

– Rule questo Item contiene i riferimenti ai controlli (check) e ad altre

informazioni, alcune opzionali, come un identificatore, un punteggio,

informazioni per eventuali correzioni;

– Value questo Item è un valore contraddistinto da un nome che può

essere sostituito in altre proprietà dell’item o dei check;

• Profile rappresenta un insieme di referenze ad oggetti quali Group, Rule,

Value permettendo di modificare il valore di alcuni attributi. L’utilizzo

dei profili facilita il riutilizzo di un benchmark adattandolo alle proprie

esigenze o alle diverse tipologie di configurazioni da verificare. Un Pro-

filo, ad esempio, permette di scegliere quali Rule/Check verificare e/o

scegliere quale valore di un Value si vuole utilizzare.

Workflow scansione XCCDF

Le fasi che compongono l’utilizzo dello standard XCCDF sono visibili in

figura 1.5. Le prime due fasi, utilizzando bollettini di sicurezza, guide di con-

figurazione o altre direttive, portano alla generazione del documento XCCDF.

Successivamente la fase di personalizzazione permette di adattare il documen-

to alle proprie esigenze, creando e/o modificando dei vincoli rendendoli più o

meno restrittivi. La quarta fase consiste nell’utilizzo di strumenti automatiz-

zati per la verifica di conformità del sistema oggetto dell’analisi. L’ultima fase,

denominata assessment results, riporta i risultati dei test eseguiti.

12

Figura 1.5: Rappresentazione schematica dell’utilizzo di XCCDF

1.2.3 Relazioni tra gli standard XCCDF e OVAL

Dopo aver analizzato la struttura di OVAL e XCCDF è possibile capire

come essi siano relazionati. Come si è visto, un engine OVAL è in grado di

verificare una configurazione e ritornare un risultato che può essere o True o

False. Ad esempio è possibile scrivere un test per verificare se un file abbia

determinati permessi e l’esecuzione di questo test ci indicherebbe se i permessi

per quel file sono rispettati. Il problema principale nell’eseguire dei test OVAL

13

è l’impossibilità di interpretare il risultato e quindi l’incapacità di valutare le

implicazioni che questa condizione ha nel processo di assessment.

Per risolvere questa problematica è stato sviluppato un linguaggio, XCC-

DF, che è in grado di relazionarsi con OVAL. Questo linguaggio fornisce indi-

cazioni su quali test effettuare, come interpretare i risultati e come risolvere i

problemi scoperti.

La relazione tra XCCDF e OVAL è ben rappresentata nella figura 1.6

estratta da una slide del MITRE.

Figura 1.6: Relazione tra XCCDF e OVAL

Per chiarire ulteriormente le relazioni tra i due linguaggi, in figura 1.7 si

può vedere un esempio semplificato di una checklist XCCDF per la verifica

della richiesta della combinazione dei tasti CTRL + ALT + CANC al login

del sistema.

14

Figura 1.7: Illustrazione di documento XCCDF, di documento OVAL e dellaloro relazione

Il documento XCCDF è composto da una sola regola identificata da un id.

Questa regola è formata da un titolo, un riferimento a una risorsa dove è pos-

sibile ottenere maggiori informazioni11, una descrizione e un Check contenente

un riferimento a una definizione OVAL. Nel documento OVAL è presente una

definizione contenente dei metadata, un titolo, un riferimento e un elemento

criteria indicante quali sono i test da eseguire. In questo esempio si vuole

verificare che il sistema abbia sistema operativo Windows XP SP2 32bit e che

la chiave di registro indicata sia uguale a zero.

Il riferimento a una definizione OVAL in un check XCCDF non è l’unica

possibile relazione tra i due linguaggi. Infatti un check può contenere anche

un riferimento a una variabile esterna OVAL, la quale deve assumere il valore

definito sul documento XCCDF. Nel frammento di codice 1.1, estratto da una

checklist presente nel repository ufficiale, si può notare che l’elemento check-

export contiene un riferimento sia ad una variabile OVAL sia ad un elemento

Value con il valore da utilizzare.11In questo caso si tratta di un riferimento a un identificatore CCE.

15

Listing 1.1: Frammento fdcc-winxp-xccdf.xml1 <Benchmark >2 <check system="http: //oval.mitre.org/XMLSchema/oval -definitions -5">3 <check -export export -name="oval:gov.nist.fdcc.xp:var:6708" value -id="

Screen -Saver -timeout_var"/>4 <check -content -ref href="fdcc -winxp -oval.xml" name="oval:gov.nist.

fdcc.xp:def:6708"/>5 </check>67 <Value id="Screen -Saver -timeout_var" operator="less than or equal" type

="number">8 <title >Screen Saver timeout </title>9 <description >Specifies how much user idle time must elapse before the

screen saver is launched. When configured , this idle time can be setfrom a minimum of 1 second to a maximum of 86 ,400 seconds , or 24

hours. If set to zero , the screen saver will not be started.</description >

10 <value >900</value >11 </Value>12 </Benchmark >

La possibilità di un documento XCCDF di fare riferimento a delle definizio-

ni e a delle variabili OVAL permette di adattare velocemente una checklist alle

esigenze dell’utilizzatore. Nel codice 1.1 viene riportato il test che verifica il

tempo massimo di inattività prima dell’avvio dello screensaver. Se ad esempio

volessimo aumentare o diminuire questo tempo sarebbe sufficiente sostituire al

valore 900 il valore voluto.

1.3 Obiettivi e vincoli

Le problematiche di Vulnerability Management trattate precedentemente

hanno portato l’azienda a sviluppare un engine OVAL (in questo documento

d’ora in poi con la parola engine si farà riferimento all’OVAL engine sviluppato

dall’azienda).

Gli obiettivi che si vogliono raggiungere sono:

• implementare uno strumento automatizzato che, partendo da una chec-

klist XCCDF, esegua una verifica di conformità di un sistema remoto.

Questo strumento deve essere in grado d’interagire con l’engine esistente,

indicandogli quali test devono essere eseguiti;

• ristrutturare alcune componenti dell’engine. Questa richiesta è motiva-

ta dalla volontà di aumentare la mantenibilità del codice, di sostitui-

re l’utilizzo di librerie deprecate e non più supportate, di permettere

l’interazione con lo strumento XCCDF da implementare.

16

Per la realizzazione del progetto è stato necessario rispettare alcuni vincoli

imposti da politiche aziendali. I vincoli derivano principalmente della volon-

tà di riutilizzare l’engine già sviluppato. Si è quindi utilizzato Python come

linguaggio di programmazione e l’IDE utilizzato è stato PyCharm.

1.4 Descrizione OVAL engine esistente

L’engine esistente è sviluppato in Python 2.4.1, il linguaggio e la versione

sono dovuti alla volontà di mantenere la compatibilità con altri componenti

aziendali. Per non interrompere o compromettere la funzionalità dell’engine, le

fasi di analisi, implementazione e test sono state fatte su un ambiente virtuale

di test. Questo ambiente è una macchina virtuale basata su una distribuzione

CentOS release 5.9. L’utilizzo dell’engine avviene tramite terminale.

Prima di poter utilizzare l’engine è necessario importare i documenti XML

contenenti gli elementi OVAL in un database creato tramite l’utilizzo della

libreria SQLite. Terminata l’importazione il database contiene tutti gli ele-

menti OVAL, i loro attributi e il frammento XML corrispondente. La scelta

di importare i documenti XML in un database è motivata da una maggiore

efficenza a tempo d’esecuzione a scapito di un tempo d’attesa maggiore al mo-

mento dell’importazione che però viene eseguita solo nel caso si aggiungessero

nuove definizioni. Durante l’analisi di una definizione è necessario ricercare ed

analizzare gli elementi necessari per l’esecuzione dei test. La fase di ricerca

può essere velocizzata utilizzando il database ed evitando il parsing dell’intero

documento ad ogni esecuzione. Un’altro vantaggio dell’utilizzo di una base di

dati è data dalla possibilità di eseguire query che sarebbero onerose da fare

sull’XML, ad esempio ottenere l’elenco di tutte le definizioni compatibili con

il sistema operativo (Windows, *NIX) del target. Lo schema di questa fase è

illustrato in figura 1.8.

17

Figura 1.8: Rappresentazione schematizzata del processo di importazione deidocumenti OVAL

L’avvio dell’engine avviene da console e accetta diversi parametri alcuni dei

quali sono obbligatori, mentre altri sono facoltativi. Nel caso si volesse ricreare

il database analizzando i documenti OVAL presenti in determinate directory

del progetto sarebbe sufficiente aggiungere il parametro --rebuilddb. Se in-

vece si vuole eseguire una scansione è necessario specificare l’indirizzo IP e le

credenziali di amministratore del target. In questo caso l’engine esegue tutte

le definizioni OVAL compatibili con il target oppure solo quelle specificate dai

parametri -x o -e.

Figura 1.9: Opzioni disponibile all’avvio dell’OVAL engine

In figura 1.10 è visibile una rappresentazione semplificata dell’engine. Nel

caso si voglia eseguire una scansione l’engine tenta di connettersi al target

utilizzando le connessioni supportate dall’engine, se la connessione è avvenuta

con successo vengono estratte dal target alcune informazioni quali la “famiglia”

(Windows, *NIX) e la lingua del sistema. Estratte queste informazioni viene

interrogato il database, la query cambia a seconda che si sia scelto di esegui-

re solo delle determinate definizioni o di verificare tutte le definizioni OVAL

18

compatibili. Nel primo caso vengono estratte solo le definizione dichiarate

esplicitamente, nel secondo caso vengono estratte tutte quelle con una “fami-

ly” compatibile. Una volta ottenuto l’elenco delle definizioni da verificare, per

ognuna vengono “risolte”, cioè viene analizzato il loro contenuto e vengono ri-

cercati tutti gli elementi necessari per eseguire la verifica. Al termine della fase

precedente vengono eseguiti i test sul target e successivamente il risultato dei

test viene riportato sia su schermo che su file.

Figura 1.10: Rappresentazione semplificata dell’OVAL engine

19

Capitolo 2

Progettazione

In questa fase vengono definiti i passi necessari per l’elaborazione di una

checklist XCCDF, le modifiche da eseguire all’engine esistente e le scelte ri-

guardanti la progettazione dell’interprete XCCDF (in questo documento d’ora

in poi con la parola interprete farà riferimento all’interprete XCCDF che si sta

sviluppando).

2.1 Elaborazione di una checklist XCCDF

Il processo di elaborazione di una checklist per la verifica di conformità su

un sistema è suddivisa in due fasi sequenziali, la prima è denominata Loading

Process e la seconda Traversal Process. A queste due fasi, in questo documento,

è stata aggiunta una terza denominata Assessment Result. Nella prima fase

avviene la lettura del documento XML, la creazione degli oggetti in memoria e

la loro modifica sulla base dei valori di alcuni attributi. La seconda fase consiste

in una visita in-order e depth-first di tutti gli elementi che compongono il

benchmark. L’ultima fase si occupa di riportare i risultati ottenuti dal processo

di elaborazione e dalla verifica del sistema.

2.1.1 Fase Loading

Come prima cosa, questa fase si occupa di eseguire il parsing del documento

XML e di creare una rappresentazione interna all’interprete che corrisponda

agli elementi e agli attributi della checklist. Una volta creata questa rappre-

sentazione si esegue la sottofase Resolve al fine di modificare alcuni elementi

e/o attributi della checklist. Gli attributi del benchmark che devono essere

20

risolti, prima di poter procedere con l’analisi del sistema, sono extends, resol-

ved e abstract. Ad esempio se un profilo B ha l’attributo extends=“profileA”

allora è necessario aggiungere tutte le proprietà del profilo A nel profilo B,

come riportato nella figura 2.1.

Figura 2.1: Esempio della procedura extends applicata a un profilo

L’attributo resolved dell’elemento Benchmark determina se questa fase de-

ve essere eseguita o no. Nel caso che il valore di questo attributo sia false sarà

necessario, per ogni punto della lista, eseguire una visita di tutti gli elementi

del benchmark per verificare la presenza di:

1. elementi di tipo Item che hanno l’attributo extends ;

2. elementi di tipo Profile che hanno l’attributo extends ;

3. elementi di tipo Tailoring che hanno l’attributo extends ;

4. elementi di tipo Item che hanno l’attributo abstract.

Terminata questa fase l’interprete avrà una rappresentazione interna del

documento completa di ogni elemento, priva degli attributi extends, abstract e

con il valore true per l’attributo Resolved.

2.1.2 Fase Traversal

Terminata la fase di Loading, il processo di valutazione procede con la

fase Traversal. Come prima operazione viene verificato se è stato specifica-

to l’utilizzo di un profilo, in caso affermativo sarà necessario applicare alla

rappresentazione interna la configurazione specificata.

21

Dopo aver applicato il profilo, si può proseguire con l’analisi degli elementi

che compongono il benchmark. Questa analisi avviene eseguendo una visita in-

order e depth-first di tutti gli elementi in cerca di quelli di tipo Item. Per ogni

elemento Item viene avviato il processo denominato Item processing. Questo

processo si occupa di:

1. verificare se l’elemento corrente ha come figli gli elementi requires e con-

flicts1, in caso affermativo verifica se questi vincoli sono rispettati, se

non lo sono l’analisi dell’elemento viene interrotta;

2. interrompere l’analisi dell’elemento nel caso che questo abbia attributo

selected=‘false’ o se l’elemento è una Rule con attributo role=‘unchecked’ ;

3. verificare la tipologia di Item, se questo è un Group allora itera il pro-

cesso, se è una Rule avvia il processo Check Processing.

Il processo Check Processing viene applicato agli elementi di tipo Rule, i

quali contengono uno o più elementi di tipo check. Questi elementi a loro

volta contengono i riferimenti ai test da eseguire sul sistema per verificare se

la regola è soddisfatta. Questo processo ha lo scopo di trovare e processare un

elemento check compatibile con l’engine ed è composto dalle seguenti fasi:

1. identificare i possibili check candidati per l’analisi;

2. verificare quali dei possibili check sono supportati dall’engine utilizzato

ed eventualmente selezionare il primo compatibile;

3. iterare tra gli elementi check-content-ref del check selezionato e verificare

se il riferimento alla definizione OVAL può essere risolto;

4. verificare la presenza di elementi check-export contenti riferimenti a valori

di variabili da comunicare all’engine.

Al termine della fase Check Processing, se non si sono verificati errori ed

è presente almeno un check compatibile, saranno disponibili i parametri da1Specifiche XCCDF 1.2 sezione: 7.2.3.3.2.

22

fornire all’engine per permettergli di eseguire la verifica sul sistema. Nel caso

di un engine OVAL si dovrà fornire l’identificatore di una definizione OVAL

ed eventualmente le informazioni necessarie per risolvere le variabili esterne. I

parametri necessari per gestire le variabili esterne sono:

• un identificatore della variabile esterna;

• un valore che deve assumere la variabile esterna;

• una tipologia del valore esportato, ad esempio number o boolean;

• un’operazione da utilizzare per il confronto del valore, ad esempio equals

o greater than.

2.1.3 Fase Assessment Result

Al termine dell’analisi del sistema si vuole avere un risultato che indichi

l’esito della scansione. Il risultato di una Rule è determinato dal valore ot-

tenuto dall’esecuzione della definizione OVAL e dalla classe della stessa che

può essere Vulnerability, Patch, Inventory e Compliance. Nella tabella 2.2 è

visibile l’associazione fornita nelle specifiche del protocollo SCAP2.

Figura 2.2: Associazione dei risultati OVAL e XCCDF2Specifiche SCAP 1.2 sezione: 4.5.2.

23

Nel caso in cui una definizione OVAL di classe compliance ritorni il risultato

“True” allora vuol dire che il sistema risulta conforme con il check eseguito e

quindi l’interprete ritornerà il risultato “Pass”. Similmente se una definizione

per una condizione di vulnerabilità ritorna il risultato “False” allora quella

vulnerabilità non è stata trovata nel sistema analizzato e il risultato per il

check sarà sempre “Pass”.

2.2 Refactoring del progetto iniziale

Il progetto iniziale ha subito varie modifiche, alcune delle quali sono state

apportate in seguito a richieste specifiche dell’azienda, altre per permettere

l’integrazione tra l’interprete e l’engine.

Le modifiche richieste dall’azienda sono dovute alla volontà di cambiare il

parser XML utilizzato nell’engine. Il parser XML preesistente è una libreria

chiamata 4Suite-XML, la quale non è più supportata dagli sviluppatori dal

2006 e non garantisce la compatibilità con le versioni più recenti di Python. Si

è così deciso di sostituire questa libreria con una più aggiornata e supportata

dal nome lxml che verrà utilizzata anche nell’interprete da realizzare.

La sostituzione del parser XML ha portato alla necessità di modificare le

seguenti parti del progetto:

• refactoring della classe XmlSourceProvider adattandola al nuovo parser

XML ed estraendo alcuni componenti rendendola più mantenibile;

• creazione di una nuova classe adibita alla comunicazione con il database;

• creazione di una nuova classe adibita ad eseguire il parsing dei documenti

XML;

• creazione di un Adapter tra la vecchia e la nuova libreria XML.

Le modifiche rese necessarie per permettere la corretta interazione tra

l’interprete e l’engine sono:

• refactoring della classe Finder2 per permettere all’interprete XCCDF di

eseguire una scansione OVAL;

24

• implementazione delle variabili esterne OVAL;

• matching delle definizioni OVAL con emazeId3 momentaneamente igno-

rata.

2.2.1 Refactoring classe XmlSourceProvider

La classe XmlSourceProvider si occupa di gestire il parsing dei documenti

XML, d’importare le informazioni e di eseguire le query nel database. Le query

utilizzate sono:

• dato l’ID di un componente OVAL ottenere namespace e frammento

XML relativo;

• dato l’ID di una definizione OVAL ottenere l’emazeID;

• dato una Family ottenere tutti gli ID delle definizioni OVAL appartenenti

a quella famiglia.

Come si può vedere nel digramma in figura 2.3 questa classe presenta sette

metodi oltre a quelli ereditati dalla classe IXmlSourceProvider i quali hanno

principalmente la funzione di configurare alcuni path.3Un identificatore delle vulnerabilità interno all’azienda.

25

Figura 2.3: Class Diagramm delle classe XmlSourceProvider

Il metodo che ha subito un maggior numero di modifiche è il metodo

rebuilddb. Questo metodo presenta una struttura complessa e si occupa di

importare i documenti XML e creare il database. Viene eseguito quando non

è presente un database oppure se viene richiesto esplicitamente nella fase di

avvio dell’engine. Il processo di importazione è visibile nel diagramma 2.4.

26

Figura 2.4: Activity Diagram del metodo rebuilddb

Tutta questa fase viene eseguita all’interno del metodo rebuilddb, renden-

do più complessa ogni modifica che si vuole apportare. Per questo motivo e

approfittando della necessità di adattarla alla nuova libreria si è reso questo

metodo più modulare. La strategia utilizzata è stata quella di creare una nuova

classe, chiamata NewXmlSourceProvider, da sostituire alla precedente. Questa

nuova classe continua ad ereditare i metodi dalla classe IXmlSourceProvider

e presenta gli stessi metodi della classe che andrà a sostituire. L’implementa-

zione del metodo rebuilddb utilizza due nuovi classi chiamate XmlExtractor

e SqliteRepository. Queste classi si occupano, rispettivamente, di eseguire

il parsing XML del documento estraendo le informazioni necessarie e di inte-

ragire col database per inserire record ed eseguire query. La scelta di creare

queste classi è motivata dalla volontà di rendere più mantenibile il codice. In-

fatti, nel caso si voglia sostituire il parser XML o il database, sarà sufficiente

modificare solamente le classi corrispondenti senza che sia necessario effettuare

cambiamenti alla classe NewXmlSourceProvider.

In figura 2.5 è possibile vedere meglio le relazioni tra le 3 classi.

27

Figura 2.5: Sequence Diagram delle interazioni tra NewXmlSourceProvider,XmlExtractor e SqliteRepository nel metodo rebuilddb

2.2.2 Adapter XML

L’utilizzo del parser 4Suite-XML è molto ricorrente nel progetto; per evi-

tare di eseguire un refactoring di molte parti di esso si è deciso di creare un

Adapter che permettesse di interfacciare la nuova libreria in modo trasparente

per l’engine. Dopo aver analizzato le differenze tra i due parser e aver valutato

quali sono i metodi della libreria utilizzati nel progetto si è deciso di ricreare

la struttura degli elementi 4Suite-XML.

La struttura della libreria 4Suite-XML è composta dagli elementi:

• Node classe madre contenente attributi comuni alle classi figlie;

• Element rappresenta un elemento del documento XML;

• Text rappresenta il contenuto di un nodo di testo;

• Comment rappresenta il contenuto di un commento.

28

Nel diagramma delle classi in figura 2.6 si possono notare le classi che ricreano

la struttura della libreria da sostituire. Queste classi contengono i metodi e gli

attributi presenti nei corrispettivi elementi della libreria 4Suite-XML.

Figura 2.6: Class Diagram dell’adapter

Utilizzare questa struttura ha permesso di non dover modificare l’engine in

nessuna parte se non nel metodo getDomNodeNode della classe NewXmlSourceProvider

dove, invece di ritornare un oggetto Element della libreria 4Suite-XML, viene

ritornato un oggetto ElementNode.

2.2.3 Refactoring classe Finder2

La classe Finder2 è una classe fondamentale per l’intero engine, le sue fun-

zionalità sono molte e in questo documento vedremo solo quelle strettamente

collegate col progetto.

Nel diagramma in figura 2.7 vi è una rappresentazione semplificata del

metodo startScan che si occupa di gestire una gran parte del processo di

scansione.

Figura 2.7: Activity Diagram dell’adapter

29

Per permettere di utilizzare questa classe anche dall’interprete sono neces-

sari dei cambiamenti. Questa classe infatti non è in grado di gestire le variabili

esterne e non fornisce un valore di ritorno adatto all’interprete XCCDF.

2.2.4 Implementazione External Variable

L’OVAL engine esistente era in grado di gestire due delle tre tipologie di

variabili OVAL, in particolare era in grado di gestire correttamente le Constant

Variable e le Local Variable ma non le External Variable. Per l’utilizzo con

l’interprete XCCDF è necessario implementare questa tipologia di variabile in

quanto è una componente utilizzata nella comunicazione tra i due strumenti.

Un elemento external_variable in un documento OVAL contiene degli attri-

buti, alcuni dei quali obbligatori, come id, version, datatype, comment ed altri

facoltativi come deprecated e signature. Oltre a questi attributi può contenere

anche degli elementi figli. Questi figli possono essere di due tipi, possible_value

oppure possible_restriction, entrambi con cardinalità (0, . . . , n).

Figura 2.8: Elementi figli di external_variable

L’elemento possible_restriction contiene almeno un elemento restriction.

La descrizione di questi elementi è riportata di seguito:

1. PossibleValue fornisce un modo per dichiarare esplicitamente un valore

accettabile per una variabile esterna;

2. PossibleRestriction fornisce un modo per elencare esplicitamente un

intervallo di valori accettabili per una variabile esterna;

3. Restriction definisce un’operazione e un valore per fornire un intervallo

per l’elemento PossibleRestriction.

30

Questi elementi permettono di specificare delle restrizioni ai valori delle

variabili esterne. La specifica OVAL descrive dettagliatamente come il risultato

del confronto tra questi elementi e il valore della variabile esterna deve essere

combinato4.

Per sviluppare la gestione delle variabili esterne è necessario:

• creare una classe ExternalVariable simile nella struttura alle Con-

stantVariable e LocalVariable;

• aggiungere il riferimento della nuova classe nella classe OvalVariable-

sFactory per permettere di istanziarla;

• creare le classi PossibleValue, PossibleRestriction e Restriction

che rappresentano i rispettivi elementi OVAL;

• aggiungere i riferimenti alla classi PossibleValue, PossibleRestric-

tion e Restriction nella classe ComponentsFactory per permettere di

istanziarle;

• implementare i controlli necessari per validare i valori esterni.

2.3 Progettazione dell’interprete

Come si è visto precedentemente l’elaborazione di una checklist ai fini della

verifica di conformità su un sistema è divisa in tre fasi. Si è deciso di progettare

le classi seguendo queste fasi.

2.3.1 Oggetti in memoria e importazione

La necessità di avere una rappresentazione interna della checklist XCCDF

ha portato alla creazione di classi che rappresentassero gli elementi del docu-

mento. Il linguaggio XCCDF presenta un gran numero di elementi, questo ha

portato alla scelta di creare degli oggetti specifici solo per gli elementi prin-

cipali e la creazione di un oggetto “generico” per gli altri elementi. In figura

2.9 è rappresentata la struttura delle classi degli oggetti creati. Come si può4Specifiche OVAL 5.10.1 sezione: 5.3.5.2 - External Variable.

31

notare queste classi sono molto semplici e non contengono nessun metodo ma

soltanto le informazioni dell’elemento che rappresentano.

Figura 2.9: Class diagram degli elementi XCCDF

L’importazione della checklist viene effettuata da una classe denominata

XccdfParser. Questa classe esegue il parsing XML del documento iniziale

utilizzando la libreria lxml. Il parsing del documento e la creazione degli

oggetti è affidata al metodo importBenchmark visibile nel diagramma delle

classe in figura 2.10.

Figura 2.10: Class diagram della classe XccdfParser

32

2.3.2 Elaborazione della checklist e risultati

La fase di progettazione della fase Traversal ha portato alla creazione di

tre classi. Queste classi sono:

• Traversal si occupa di applicare un profilo ed eseguire l’analisi della

checklist rispettando l’ordine descritto precedentemente;

• ItemProcess si occupa di eseguire la fase Item processing ;

• RuleCheckProcess si occupa di eseguire la fase Check Processing.

Il diagramma delle classi è visibile in figura 2.11.

Figura 2.11: Class diagram delle classi della fase Traversal

Al termine della fase Traversal i risultati vengono gestiti dalla classe Re-

sultLogger che si occupa di ottenere il risultato corretto e di visualizzarli a

schermo. Il diagramma della classe è rappresentato in figura 2.12

Figura 2.12: Class diagram della classe ResultLogger

33

2.4 Metodologia di sviluppo

Tra le tecniche utilizzate dall’azienda ci sono lo sviluppo agile e Test Driven

Development5. Si è scelto di utilizzare queste tecniche anche per lo sviluppo

del progetto.

Lo sviluppo agile prevede la divisione del progetto in parti più piccole e di

continue interazioni su brevi periodi con i committenti del progetto e con gli

altri membri del progetto. Questa metodologia porta a una continua revisione

delle fasi di progettazione e sviluppo rendendo meno distinte queste fasi.

La tecnica di TDD è una tecnica che fa affidamento sui test automatici,

in particolare la creazione di questi test precede lo sviluppo del software. An-

che questa tecnica prevede brevi cicli di sviluppo e di verifica. Utilizzando

queste tecniche ogni classe scritta avrà i suoi test d’unità, d’integrazione e

d’accettazione che garantiscono il corretto funzionamento della stessa.

A supporto di queste tecniche è stato utilizzato Mercurial come sistema di

version control.

5TDD.

34

Capitolo 3

Realizzazione

3.1 Interfaccia ed esempio di funzionamento

La progettazione e la realizzazione dell’interprete XCCDF è finalizzata al-

l’uso dello strumento internamente all’azienda, questo ha eliminato la necessi-

tà di sviluppare una interfaccia grafica per l’utilizzo. L’assenza dell’interfaccia

grafica non pregiudica il funzionamento dell’interprete che può essere avviato

tramite console.

Prima di poter utilizzare l’interprete è necessario posizionare gli XML

necessari per il corretto funzionamento, questi documenti sono:

• checklist XCCDF per il sistema che si vuole analizzare;

• documento OVAL uno o più documenti contenti le definizioni riferite

dalle checklist.

Questi documenti possono essere estratti dai pacchetti SCAP che tra i suoi

componenti contiene anche la checklist e i documenti OVAL.

Per permettere l’avvio da terminale è stato creato un file Python dal nome

cmdlinexccdf.py che contiene un singolo metodo denominato main(). Questo

metodo ha il compito di gestire i parametri passati da console e avviare la

scansione. Come per l’engine OVAL anche in questo caso alcuni parametri

sono obbligatori, altri invece sono facoltativi. Le opzioni disponibili all’avvio

sono le seguenti:

• targethost obbligatorio, corrisponde all’indirizzo IP del target;

• sshcredentials obligatorio, credenziali ssh;

35

• smbcredentials obbligatorio, credenziali smb;

• checklist obbligatorio, nome del documento XCCDF da utilizzare;

• smbdomain facoltativo, nome del dominio da usare al login;

• rebuilddb facoltativo, ricrea il database degli elementi OVAL.

Dopo aver avviato l’interprete con i parametri necessari il metodo main

prosegue eseguendo il parsing della checklist e se sono presenti viene proposto

quale profilo applicare. Successivamente continuerà il workflow dell’interprete.

3.1.1 Esempio di scansione completa

In questa sezione verranno ripercorsi tutti i passaggi che formano una ve-

rifica di conformità tramite un esempio completo. Il sistema target è una

macchina virtuale con sistema operativo Microsoft Windows 2003 Server SP2.

La checklist XCCDF e le definizioni OVAL sono state prelevate dal repository

del NIST, in particolare è stato utilizzato il pacchetto SCAP, con ID 353, re-

dato dal DISA1 per il sistema operativo target. Nell’archivio scaricato saranno

di nostro interesse i file:

• U_Windows_2003_DC_V6R1.29_STIG_Benchmark-xccdf.xml contenente

la checklist XCCDF;

• U_Windows_2003_DC_V6R1.29_STIG_Benchmark-oval.xml contenente gli

oggetti OVAL necessari durante l’esecuzione della checklist.

Inizializzazione

Prima di poter utilizzare l’interprete e l’engine bisogna posizionare i docu-

menti XML relativi alla checklist e alle componenti OVAL nei path corretti.

Nella figura 3.1 si può vedere come la checklist e il documento OVAL so-

no stati posizionati nei rispettivi path /root/job-finder/src/xmls/xccdf e

/root/job-finder/src/xmls/oval_for_xccd.1Defense Information Systems Agency.

36

Figura 3.1: Path dei documenti XCCDF e OVAL

Successivamente si può procedere con la creazione del database contenente

le definizioni OVAL. Per far questo viene eseguito il file cmdlinexccdf.py, che

si trova nel path /root/job-finder/src/, con il parametro --rebuilddb. In

questa fase l’engine OVAL procede con l’importazione di tutte le definizioni, i

test, gli oggetti, gli stati e le variabili OVAL nel database.

Figura 3.2: Creazione del Database OVAL

Prima di procedere con l’avvio dell’interprete si verifica che il target sia

raggiungibile. Viene quindi eseguito il comando PING all’host 10.4.12.2,

che è l’indirizzo IP della macchina virtuale raggiungibile solo dalla intranet

aziendale.

Figura 3.3: Verifica della connessione col target

37

Avvio scansione

Terminata la fase di inizializzazione si può procedere con l’avvio dell’inter-

prete XCCDF, anche in questo caso è necessario eseguire il file cmdlinexccdf.py.

Nella figura 3.4 si può vedere l’elenco dei parametri, quelli utilizzati sono: -t

10.4.12.2 con l’ip del target, –ssh=User%Pass e –smb=User%Pass con le cre-

denziali, -c U_Windows_2003_DC_V6R1.29_STIG_Benchmark-xccdf.xml con

il nome della checklist.

Figura 3.4: Comandi della console XCCDF

Avviato l’interprete questo procede con il parsing della checklist e la fase

di Loading. Terminata questa fase vengono visualizzati a schermo i profili

disponibili permettendo la scelta di quale applicare. In questo caso viene scelto

arbitrariamente un profilo nominato MAC-2_Sensitive2.

Figura 3.5: Schermata della selezione dei profili

I passi successivi alla selezione del profilo sono del tutto automatici, l’o-

peratore deve solo attendere la fine delle operazioni. L’interprete XCCDF2Mission Assurance Category.

38

come prima cosa applica il profilo selezionato, successivamente inizia la fase

Traversal dove viene analizzata la checklist. Questa fase si occupa di:

• inizializzare l’engine OVAL fornendogli le informazioni di configurazione

e i parametri necessari per la connessione al target;

• Interrogare l’engine per richiedere di eseguire delle scansioni ed ottenerne

il risultato.

Alcuni esempi di una scansione OVAL sono in figura 3.6

Figura 3.6: Esempi di scansioni delle definizioni OVAL

Interpretazione risultati

Al termine della scansione vengono mostrati i risultati della scansione. Per

motivazioni di debug e di test si è scelto di visualizzare il log a schermo. I

risultati sono divisi in tre parti: test con esito positivo, test con esito negativo

e test di cui non si è potuto verificare lo stato. Ogni risultato include le seguenti

informazioni:

• il nome della regola XCCDF analizzata;

39

• la definizione OVAL corrispondente;

• la classe OVAL;

• il risultato OVAL, che può differire dal risultato XCCDF.

I test che non sono stati verificati non presentano la classe ed il risultato

ma viene visualizzato l’errore che ha causato l’impossibilità di eseguire il test.

Di seguito sono mostrati alcuni screen di come si presentano i risultati.

Figura 3.7: Esempi di regole che hanno superato il test

Figura 3.8: Esempi di regole che non hanno superato il test

Figura 3.9: Esempi di regole che non sono state valutate

Figura 3.10: Report finale della scansione

Nella figura 3.10 è visibile un riepilogo con il numero di successi, falli-

menti ed errori. Si può notare che il sistema target soddisfa solamente una

piccola parte dei test eseguiti. Questo è dovuto all’assenza di una configu-

razione adeguata del target. Gli errori sono causati dalla necessità di usare

oggetti OVAL non implementati dall’engine. La motivazione di questa man-

canza è data dall’assenza di questi elementi nei documenti OVAL utilizzati

precedentemente.

40

3.2 Implementazione

L’integrazione con l’OVAL engine ha portato alla scelta di integrare l’inter-

prete XCCDF nello stesso package dell’engine. Sono stati creati due package

che compongono l’interprete XCCDF che sono:

• xccdfobjects contenente le classi degli elementi XCCDF;

• xccdfprocess contenente le classi necessarie per il processo di analisi.

3.2.1 Package “xccdfobjects”

Il package xccdfobjects contiene tutte le classi che compongono gli ele-

menti XCCDF e delle classi di supporto per la creazione di queste.

La struttura delle classi che rappresentano gli oggetti sono molto sempli-

ci come è visibile nella sezione 2.3.1. Le classi di supporto sono delle classi

identificate dal suffisso Builder. Le classi rappresentative degli elementi si

differenziano tra di loro per i loro attributi. Per rendere queste differenze

trasparenti nel momento della creazione degli oggetti si sono create le classi

Builder. Di seguito è riportato il codice di una di queste classi.

Listing 3.1: classe XccdfCheckBuilder1 class XccdfCheckBuilder(object):23 def __init__(self):4 self.object = XccdfCheck ()56 def addAttribute(self , key , value):7 if key == ’id’:8 self.object.id = value9 elif key == ’system ’:

10 self.object.system = value11 elif key == ’selector ’:12 self.object.selector = value13 elif key == ’negate ’:14 self.object.negate = value15 else:16 self.object.attributes[key] = value1718 def addValue(self , value):19 self.object.value = value202122 def addChild(self , child):23 self.object.children.append(child)2425 def addNamespace(self , namespace):26 self.object.namespace = namespace

I metodi visibili nella classe 3.1 sono comuni anche agli altri builder. Que-

sto permette di poter creare gli oggetti in memoria ignorando la loro tipologia.

41

L’unica operazione richiesta dalla classe che si occupa di eseguire il parsing del

documento è istanziare il corretto builder. In questo modo una volta ottenuto

il corretto builder si può invocare, ad esempio, il metodo addAttribute senza

la preoccupazione della tipologia dell’elemento. La ricerca del corretto builder

è svolta dal metodo findCorrectBuilder della classe XccdfParser. Questo

metodo verifica la presenza del nome dell’elemento tra le chiavi di una mappa

e ritorna un builder. La mappa ha nome ELEMENTS ed è composta come:

{‘nome_elemento’ : ‘nome_classe_builder’}. Il builder ritornato sarà

quello corrispondente all’elemento se la verifica ha avuto successo, quello ge-

nerico altrimenti.

Le classi builder sono attualmente dodici, ma una è utilizzata solamente

come classe madre e non fa riferimento a nessun elemento XCCDF. Nel caso

si volesse aggiungere una nuova classe per un nuovo elemento sarà sufficien-

te effettuare tre operazioni: creare una classe rappresentativa dell’elemento,

creare una classe builder contenenti i metodi comuni agli altri builder e infine

aggiungere il riferimento al builder nella mappa ELEMENTS.

Un’altra classe presente in questo package è ExportVariable, questa classe

come visibile nel codice 3.2 contiene le informazioni necessarie per permettere

all’engine di ottenere il valore di una variabile esterna.

Listing 3.2: classe ExportVariable1 class ExportVariable(object):2 def __init__(self):3 self.ovalVarId = None4 self.value = None5 self.type = None6 self.operator = ’’

3.2.2 Package “xccdfprocess”

Il package xccdfprocess contiene le classi che si occupano di gestire l’intero

processo per la verifica di conformità del sistema. Le classi che compongono

questo package sono:

• XccdfParser(object);

• Loading(object);

42

• Traversal(object);

• ItemProcess(object);

• RuleCheckProcess(object);

• FinderEngineHandler(object);

• SourceProviderHandler(object);

• ResultLogger(object).

Le classi presenti nel package si dividono in classi che forniscono l’im-

plementazione per il processo di analisi e classi di supporto per la connes-

sione con l’engine. Le classi di supporto sono SourceProviderHandler e

FinderEngineHandler.

La classe SourceProviderHandler si occupa di inizializzare e configura-

re la classe NewXmlSourceProvider. Come visibile nel codice 3.3 il metodo

_initializeXmlSourceProvider svolge questa funzione, impostanto i path

corretti per il database e i documenti OVAL.

Listing 3.3: classe SourceProviderHandler1 class SourceProviderHandler(object):23 def __init__(self):4 self._xmlSourceProvider = None5 self._initializeXmlSourceProvider ()67 def _initializeXmlSourceProvider(self):8 if self._xmlSourceProvider == None:9 xmlSourceProv = newxmlsourceprovider.NewXmlSourceProvider ()

10 xmlSourceProv.setRepositoryDirs(settings.DATA_DEFINITIONS_FOR_XCCDF)

11 xmlSourceProv.setDatabaseFilePath(settings.CACHE_DATABASE_FOR_XCCDF)

12 xmlSourceProv.initialize ()13 self._xmlSourceProvider = xmlSourceProv1415 def getXmlSourceProvider(self):16 return self._xmlSourceProvider

La classe FinderEngineHandler invece si occupa delle comunicazioni tra l’in-

terprete XCCDF e l’OVAL engine.

43

Listing 3.4: classe FinderEngineHandler1 class FinderEngineHandler(object):234 def initializedConnections(self , preferences , sourceProvider):5 self.finderEngine = finder2.Finder2LocalAssessment ()6 self.finderEngine.initializedConnectionsForXccdf(preferences ,

sourceProvider)78 def starScan(self , rule):9 return self.finderEngine.startScanFromXccdf(rule)

1011 def finalize(self):12 self.finderEngine.finalizeProviders ()

I metodi della classe corrispondono alle fasi della comunicazione tra gli stru-

menti XCCDF e OVAL, in particolare:

• initializedConnections(self, preferences, sourceProvider) ini-

zializza l’engine OVAL;

• starScan(self, rule) richiede scansione di una definizione OVAL e

ritorna il risultato della scansione;

• finalize(self) termina le connessioni con l’engine.

Le altri classi del package compongono le varie fasi del processo di veri-

fica. Le classi XccdfParser e Loading si occupano della fase Loading. La

fase Traversal è invece implementata dalle classi Traversal, ItemProcess e

RuleCheckProcess.

3.3 Test

L’utilizzo di metodologie “Agile” e TTD hanno comportato la realizzazione

di molte classi di test. Questi test sono un componente fondamentale per lo

sviluppo del progetto perché permettono di verificare la correttezza del codice

scritto. Sono stati realizzati dei test per ogni classe e per ogni metodo im-

plementato. Per la scrittura dei test è stato utilizzato il framework unittest

incluso nella Python Standard Library. I test scritti possono essere distinti in

due tipologie, i test d’unità e i test d’integrazione. I test d’unità rappresentano

il test al più piccolo componente di un programma dotato di funzionamento

autonomo. Questi test devono essere i più semplici possibili, essere di facile

44

lettura e dovrebbero usare solamente funzioni già testate in modo da limitare

la possibilità di errori nelle classi di test. Un test si può suddividere in tre fasi:

1. precondizioni;

2. operazioni;

3. asserzioni.

La prima fase consiste nel preparare le condizioni necessarie per l’esecuzione

del test. Alcune operazioni tipiche sono istanziare le classi necessarie, riempire

liste e mappe. Se necessario questa fase può essere anche portata fuori dalla

classe di test, permettendo una maggiore leggibilità del codice.

Dopo aver concluso la prima fase si procede con la fase di esecuzione delle

operazioni da testare.

La terza fase si confronta il risultato ottenuto dalla fase precedente con

il risultato atteso e si riporta il risultato del test. In questa fase non si può

effettuare solo un confronto tra il valore atteso e il valore ricevuto, ma si può

verificare anche la corretta gestione delle eccezioni o il valore di ritorno di una

funzione.

Dopo aver verificato il corretto funzionamento dei singoli metodi e/o classi

si vuole verificare la corretta interazione tra loro, questi test sono detti test

d’integrazione. Questi test come quelli unitari sono fondamentali per verificare

il comportamento del progetto e garantire il corretto funzionamento.

Le classi di test sono riunite in un package distinto da quelle del pro-

getto, il package che racchiude tutti i test per l’interprete XCCDF ha nome

testunit_xccdf. Ogni classe di test può contenere più test, si è scelto di crea-

re una classe di test per ogni classe del progetto e all’interno di questa inserire

tutti i test riguardanti le operazioni di quella classe. Sono state scritte anche

classi di supporto alle classi di test, queste classi permettono di istanziare le

classi necessarie rendendo il codice più leggibile e diminuendo la ridondanza

del codice.

Nel frammento di codice 3.5 è possibile vedere alcuni dei test per verificare

il corretto funzionamento della classe ProfileBuilder. Questa classe contiene

45

altri test che non sono stati riportati. In dettaglio il primo test verifica che il

builder istanzi l’oggetto XccdfProfile, il secondo e il terzo test verificano la

corretta gestioni degli attributi namespace e id.

Listing 3.5: Frammento classe TestProfileBuilder1 class TestProfileBuilder(unittest.TestCase):23 def testProfileType(self):4 expectedType = ’Profile ’5 builder = xccdfprofilebuilder.XccdfProfileBuilder ()6 profile = builder.object7 resultType = profile.type8 self.assertEquals(expectedType , resultType)9

10 def testProfileNamespace(self):11 expectedNamespace = ’TestNs ’12 builder = xccdfprofilebuilder.XccdfProfileBuilder ()13 builder.addNamespace(expectedNamespace)14 profile = builder.object15 resultNamespace = profile.namespace16 self.assertEquals(expectedNamespace , resultNamespace)1718 def testProfileId(self):19 expectedId = ’testId ’20 builder = xccdfprofilebuilder.XccdfProfileBuilder ()21 builder.addAttribute(’id’, expectedId)22 profile = builder.object23 resultId = profile.id24 self.assertEquals(expectedId , resultId)25 self.assertEquals ({}, profile.attributes)2627 if __name__ == ’__main__ ’: unittest.main()

Nel codice 3.6 è possibile notare alcuni test della classe Traversal. Il me-

todo setUp viene invocato prima dell’esecuzione dei test ed istanzia la clas-

se TraversalTestMother che si occupa di creare gli oggetti necessari per

eseguire il test. Il metodo testProfileSelectResolveId testa il metodo

profileSelectResolve. Questo metodo viene eseguito quando viene incon-

trato un elemento XCCDF del tipo <select idref=“someID” selected=“true”>

e sovrascrive all’elemento definito dall’attributo idRef il valore dell’attributo

selected. Il metodo testApplyProfile verifica il corretto funzionamento del

metodo applyProfile che si occupa di applicare un profilo. Questo test non

è definibile come test unitario perché non verifica la componente più piccola

autonoma ma verifica il corretto funzionamento dei metodi necessari per risol-

vere un profilo.

46

Listing 3.6: Frammento classe TestTraversalProcess1 class TestTraversalProcess(unittest.TestCase):23 def setUp(self):4 self.mother = TraversalTestMother ()567 def testProfileSelectResolveId(self):8 expectedResults , benchmarks = self.mother.

benchmarkGroupsAndRulesSelectedId ()9 for expected , benchmark in zip(expectedResults , benchmarks):

10 expectedElement , expectedSelected = expected11 traversal = Traversal(benchmark [0], None , None)12 traversal.profileSelectResolve (* benchmark)13 self.assertEquals(expectedSelected , expectedElement.selected)141516 def testApplyProfile(self):17 expectedResults , benchmarks = self.mother.

benchmarkWithProfileGroupAndRule ()18 for expected , benchmark in zip(expectedResults , benchmarks):19 expectedElements , expectedSelected = expected20 benchmarkRoot , profileElement = benchmark21 traversal = Traversal(benchmarkRoot , None , None)22 traversal.applyProfile(profileElement)23 for expectedElement in expectedElements:24 self.assertEquals(expectedSelected , expectedElement.selected)2526 if __name__ == ’__main__ ’: unittest.main()

47

Capitolo 4

Conclusioni

4.1 Obiettivi e sviluppi futuri

L’obiettivo prefissato di creare uno strumento automatico capace di elabo-

rare una checklist XCCDF e di eseguire i test su un sistema remoto è stato

raggiunto. Al momento il sistema è utilizzabile anche se la messa in produzione

non è ancora completata. Alcuni possibili sviluppi futuri sono:

• creazione di un’interfaccia grafica per agevolare l’avvio della scansione;

• creazione di uno strumento per permettere la personalizzazione di una

checklist già esistente;

• creazione di uno strumento per permettere la creazione di nuovi profili;

• supporto a nuovi oggetti OVAL per permettere di eseguire un maggior

numero di test;

• aggiornamento di entrambi gli strumenti a una versione più recente di

Python;

• miglioramento della gestione dei log.

4.2 Valutazione del lavoro svolto

Per la realizzazione del progetto sono state scritte un totale di 74 classi e

oltre 6200 righe di codice, suddivise nel seguente modo:

• 20 classi e 1100 linee di codice per il refactoring dell’OVAL Engine;

48

• 32 classi e 1000 linee di codice per la realizzazione dell’interprete XCCDF;

• 22 classi e 4100 linee di codice per i test.

La scrittura di queste classi ha portato a oltre 220 commit nel repository

aziendale.

4.3 Valutazioni personali

Personalmente sono soddisfatto del lavoro svolto, lo studio degli stan-

dard necessari mi ha permesso di acquisire dimestichezza nel confrontarmi

con documenti tecnici quali sono le specifiche.

Lo sviluppo del progetto è stato un’occasione per conoscere e imparare un

linguaggio di programmazione che non avevo mai visto precedentemente e per

capire alcune delle problematiche tipiche della realizzazione di un progetto.

Questa esperienza mi ha permesso di entrare in contatto con un ambiente

lavorativo diverso da quello accademico.

49

Capitolo 5

Bibliografia

• Core PYTHON Programming, Wesley J. Chun, Prentice Hall

• Vulnerability Management, Park Foreman, Taylor and Francis

(Auerbach Publications)

• Documentazione OVAL

– Sito ufficiale

http://oval.mitre.org/about/

– Specifiche 5.10

https://oval.mitre.org/language/version5.10.1/OVAL_

Language_Specification_01-20-2012.pdf

– Repository ufficiale

http://oval.mitre.org/repository/index.html

– Altri repository

http://oval.mitre.org/repository/about/other_

repositories.html

• Documentazione XCCDF

– Sito ufficiale

http://scap.nist.gov/specifications/xccdf/

– Specifiche 1.2

http://csrc.nist.gov/publications/PubsNISTIRs.html#

NIST-IR-7275-r4

50

• Documentazione protocollo SCAP

– Sito ufficiale

http://scap.nist.gov/

– Specifiche 1.2

http://csrc.nist.gov/publications/PubsSPs.html#

SP-800-126-Rev.%202

• Libreria 4Suite-XML

https://pypi.python.org/pypi/4Suite-XML

• Libreria lxml

http://lxml.de/

• Pacchetto SCAP checklist id 353

http://web.nvd.nist.gov/view/ncp/repository/

checklistDetail?id=353

• National Vulnerability Database

http://web.nvd.nist.gov

• Slide MITRE

– http:

//nvd.nist.gov/scap/docs/conference%20presentations/

workshops/OVAL%20Tutorial%201%20-%20Overview.pdf

– http://nvd.nist.gov/scap/docs/2008-conf-presentations/

scapTutorial/4-languages.pdf

– http://energy.gov/sites/prod/files/cioprod/documents/

Technical_Introduction_to_SCAP_-_Charles_Schmidt.pdf

51

Ringraziamenti

Il ringraziamento più grande va ai miei genitori e alle mie sorelle per essermi

sempre stati vicini durante tutti questi anni.

Un doveroso ringraziamento va a tutti i vecchi amici/amiche e a quelli

nuovi conosciuti durante il periodo universitario che hanno avuto la pazienza

di sopportarmi, incoraggiarmi ed aiutarmi.

52