OVAL definitions for Fedora
... or to be honest, a start of OVAL definitions for
and CentOS, i.e. work in (very long) progress. I'm just learning
how to use this technology, and if it's of any use at all! :)
In short, OVAL is a XML based specification language for vulnerability assessment. It is already used by different vendors and it will probably see wider adoption as NIST is pushing OVAL as a part of automated solution for vulnerability assessment and management. For example, RedHat publishes vulnerability advisories in OVAL format.
I have to stress that I didn't yet fully learned the idea behind OVAL as well as the technology used so there is a high probability of errors in the following text. If you spot an error please mail me the correction!
What is OVAL and how to use it
As I already said, OVAL is a language that describes checks to be performed on a system in order to determine if any vulnerability is present on it, either to a software bug or to a configuration setting. This is performed via tool in a package called ovaldi, which is available in Fedora's RPM repository. So, you should install it as usual using the yum command. After installation process finishes, you'll have command line tool called, surprisingly, ovaldi! :) The next thing you need in order to use this tool are definitions of vulnerabilities. Unfortunately, there are no vulnerability descriptions for Fedora in OVAL form. I'll try to make few, for Fedora and CentOS. In case I missed some repository, please notify me via e-mail message! While we are at CentOS, it's possible that RedHat's OVAL definitions could be used with a little bit of hacking, but I didn't try it so it could prove false!
Anyway, in order to try ovaldi tool you need OVAL definitions. You can use RedHat's but all the results will be false which is expected as you are not running RedHat on your computer. So, in order for you to try oval, download this definition file I prepared. It is very simple OVAL definition and only checks which version of Fedora is installed on the computer, 8 or 9.
To run ovaldi it has to have schema definitions. Now, this is interesting as those are placed in the /usr/share/ovaldi directory but the tool looks for them in the current directory.
Even more interesting is that I can't seem to identify option
that would allow me to change schema path. To get around this
problem, copy all the content from the /usr/share/ovaldi
directory into current directory. Be carefull to create
separate working directory for this or otherwise you'll have a
mess on your disk!
There are two ways to define where schema files will be searched. The first one is using the option -a. The default value for this option is /usr/share/ovaldi but for some reason this value is not used, i.e. ovaldi tool can not find schema files. The other, and not so good(!), approach is to encode path in the XML file itself. This approach will be described later.
Now, run the ovaldi tool as follows:
$ ovaldi -o fedora.9.oval.xml -m
Note that in real situations is could be possible that you'll have to run ovaldi as root since it could try to access data not accessible to ordinary users. In this case it is not necessary as the tests are very simple.
The output from the command on the Fedora 9 will be:
---------------------------------------------------- OVAL Definition Interpreter Version: 5.4 Build: 2 Build date: Jun 7 2008 15:06:57 Copyright (c) 2002-2008 - The MITRE Corporation ---------------------------------------------------- Tue Jul 8 17:00:52 2008 ** parsing fedora.9.oval.xml file. - validating xml schema. ** checking schema version - Schema version - 5.4 ** skipping Schematron validation ** creating a new OVAL System Charateristics file. ** gathering data for the OVAL definitions. Collecting object: FINISHED ** saving data model to system-characteristics.xml. ** running the OVAL Definition analysis. Analyzing definition: FINISHED ** OVAL definition results. OVAL Id Result ------------------------------------------------------- oval:org.fedoraproject.oval:def:1 true oval:org.fedoraproject.oval:def:2 false ------------------------------------------------------- ** finished evaluating OVAL definitions. ** saving OVAL results to results.xml. ** running OVAL Results xsl: results_to_html.xsl. ----------------------------------------------------
The part that is in bold shows the results of two tests. The one that is true is a test for Fedora 9, while the other one is the test for Fedora 8. Apart from the output on stdout there are few files created along the way, those are:
- results.html is HTML version of the results. I slightly modified this file in order to remove IP addresses, but otherwise it is untouched!
- results.xml is XML version of the previous file.
- system-characteristics.xml is where you'll find some data that the tests run against. It is usefull for debugging purposes!
- ovaldi.log is basically what was seen on the stdout.
What's in the OVAL file
The simple OVAL file I provided checks if Fedora 8 or 9 is running on the computer where ovaldi is started. So, before going further open it in some text or XML editor. Few notes to bare in mind while we step through this file:
- I wrote it based on RedHat's definition so there are some references on RedHat left in the file. I think they are harmless, and also, I don't (yet) know what to place there.
- As an ID for all the stuff in the file I used org.fedoraproject.oval namespace!
General structure of OVAL definition file
The file has the following general structure:
First there is XML PI element that defines it's XML version 1.0 as well as that UTF-8 coding is used.
Top level element is oval_definitions and it has attributes with schemas that I just c/p!
The first element is generator. I didn't changed it, but I suppose it's for metadata about file itself, e.g. who created it, with what tool, etc.
Then there are the following important four parts:
- definitions that define checks to be performed.
- tests defines basic tests to be performed.
- objects are the elements on which tests are performed. For example, if version of some package is checked, then the object is the package.
- states are states that are checked on objects. For example, certain package is an object, version is a state. Probably it could be more complicated than that, but this is enough to get and idea.
Example OVAL definition file
So what we have in the example file? We are determining the exact version of Fedora running on the test computer and this is done by looking what the version (state) of the package fedora-release is present. Thus, the object is the package, and the state is either version 8 or 9.
In the example file, the object is specified in the objects part of the definition file as follows:
<rpminfo_object id="oval:org.fedoraproject.oval:obj:1" version="1" comment="the fedora-release rpm" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"> <name>fedora-release</name> </rpminfo_object>
rpminfo_object element is predefined in OVAL library and it's used to query RPM objects, i.e. packages. In our case, we are querying for package with the name fedora-release. The attribute id is used for referencing this definition in other parts of the file!
The other part of the equation, states, are defined within the states element of the OVAL definition file as follows:
<rpminfo_state id="oval:org.fedoraproject.oval:ste:1" version="1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"> <version operation="pattern match">9<version> <rpminfo_state> <rpminfo_state id="oval:org.fedoraproject.oval:ste:2" version="1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"> <version operation="pattern match">8<version> <rpminfo_state>
The state simply matches the version variable (identified by the version attribute) with number 8 (for Fedora 8) or 9 (for Fedora 9). Also, id attributes are used for referencing those states in other parts of the file.
Now, we have two tests. One that checks for Fedora 8 and another one for Fedora 9. Those go within tests element.
<rpminfo_test id="oval:org.fedoraproject.oval:tst:1" version="1" comment="Fedora 9 is installed" check_existence="at_least_one_exists" check="at least one" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"> <object object_ref="oval:org.fedoraproject.oval:obj:1"/> <state state_ref="oval:org.fedoraproject.oval:ste:1"/> <rpminfo_test> <rpminfo_test id="oval:org.fedoraproject.oval:tst:2" version="1" comment="Fedora 8 is installed" check_existence="at_least_one_exists" check="at least one" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"> <object object_ref="oval:org.fedoraproject.oval:obj:1"/> <state state_ref="oval:org.fedoraproject.oval:ste:2"/> <rpminfo_test>
Note that each of those two tests simply says that object referenced by the object element has to be in the state referenced by the state element. So, what we have here are two tests that check if a single object is in the one state and then in the other.
Finally, beacuse both tests have to be executed, and the results of each one of them has to be printed, there are two definitions. If we are interested in some logical combination of the two tests we could write them in a single definition. So, the definition that checks for Fedora 9 is within definitions element and has the following structure:
<definition id="oval:org.fedoraproject.oval:def:1" version="1" class="inventory"> <metadata> <title>The operating system installed on the system is Fedora 9<title> <affected family="unix"> <platform>Fedora 9<platform> <affected> <reference source="CPE" ref_id="cpe:/o:redhat:enterprise_linux:3::ix86"/> <description>The operating system installed on the system is Fedora 9<description> <oval_repository> <dates> <submitted date="2008-01-12T14:07:00"> <contributor organization="University of Zagreb, FER">Stjepan Groš<contributor> <submitted> <status_change date="2008-07-08T13:56:57.725+02:00">DRAFT<status_change> <dates> <status>DRAFT<status> <oval_repository> <metadata> <criteria> <criterion comment="Fedora 9 is installed" test_ref="oval:org.fedoraproject.oval:tst:1"/> <criteria> <definition>
Esentially, the part in criterion element references tests that have to be performed in order to determine whether vulnerability is present or not.
Implementing sysctl checks in OVAL
On one occasion I had to do a security analysis of a CentOS server. In order to do that as best as I can, I found document Guide to the Secure Configuration of Red Hat Enterprise Linux 5 that I took as a starting point in doing security analysis. Then, I realised that by manually checking what's done isn't going to be enough for two reasons:
- There are another servers that I want also to check and it's going to be too much work so I have to automate somehow this whole process.
- Also, once the things are configured it has to be regularity verified, which is also to be problematic if done manually.
So I decided to write OVAL checks that will be customized for each server and that will be periodically run in order to very if security settings are in place.
Of course, it want' be easy as there is lot to learn in order for me to be able to write OVAL security checks. So, I'm going to write here what and how I did.
Checking sysctl variables
In section 18.104.22.168 of the Guide to the Secure Configuration of Red Hat Enterprise Linux 5 there is recommendation for the following sysctl values:
net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0
It turns out that in the version 5.9 of OVAL there is sysctl test available. So until it is available in Fedora I'll have to wait.