Analisi e realizzazione di uno strumento per la verifica di conformità su sistemi remoti basato...
-
Upload
davide-bravin -
Category
Documents
-
view
174 -
download
5
Transcript of Analisi e realizzazione di uno strumento per la verifica di conformità su sistemi remoti basato...
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