The XCCDF standard provides a vendor neutral way to compose a checklist for assessing computer systems. While the XCCDF specification focuses mainly on the scan, there is also a small module which defines how to put the scanned system into the desired (compliant) state. This blogpost introduces a new feature of OpenSCAP, the remediation, which helps you execute remediation command in the automated way.
Your security policy may contain the remediation commands for each Rule within the XCCDF document. Remediation commands are encapsulated within
<xccdf:fix> elements. Attributes of the fix element define metadata consumed by scanner tool in the time of execution. For more detailed info about XCCDF Remediation please consult NIST-IR-7275, and search for fix and remediation keywords.
The following snippet is an example of a XCCDF Rule with both remediation and scanning (OVAL) definitions. The
@system attribute defines the interpreter of the commands, you can use bash, perl, python, or whatever your scanner supports. Obviously, the fix content tends to be unportable across different operating systems, thus the XCCDF allows you to specify multiple fix elements – each for different OS. These fix elements can be distinguished by diffrerent CPE identifier within the
@platform attribute. The scanner select the one most suitable for the target system. Other attributes like,
@disruption level or flag indicating whether
@reboot is required, can be used by scanner tool to choose the fix element.
<Rule id="xccdf_moc.elpmaxe.www_rule_1"> <title> The telnet-server Package Shall Not Be Installed </title> <rationale> Removing the telnet-server package decreases the risk of the telnet service's accidental (or intentional) activation. </rationale> <fix platform="cpe:/o:redhat:enterprise_linux:6" reboot="false" disruption="low" system="urn:xccdf:fix:script:sh"> if rpm -q telnet-server; then yum -y remove telnet-server fi </fix> <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> <check-content-ref href="test_remediation_simple.oval.xml" name="oval:moc.elpmaxe.www:def:1"/> </check> </Rule>
Remediation Support in Earlier OpenSCAP
Previously, in OpenSCAP we didn’t execute fix elements. We have only allowed export of bash fix scripts to a file. In order to bring your machine to the compliant state, You have need to take the following four steps:
Execute OpenSCAP scan and get
xccdf:TestResultstored to some file like:
$ oscap xccdf eval \ --results ~/my-results-xccdf.xml \ /usr/share/scap/my-policy-xccdf.xml
Generate bash script from the result file:
$ oscap xccdf generate fix \ --output ~/my-bash-remediation.sh \ ~/my-results-xccdf.xml
Review the script by eye and execute it.
Execute OpenSCAP scan again and verify applied fixes:
$ oscap xccdf eval \ --results ~/my-results-xccdf2.xml \ /usr/share/scap/my-policy-xccdf.xml
Shortcomings of That Approach
For the second step, OpenSCAP library used XSLT transformation to generate scripts. However, some of the features of XCCDF (Text Substitution, CPE applicability, and correct XCCDF Processing) were missing and these features seem to be bordeline impossible to implement with pure XSLT language. Further, when the administrator executed the remediation script manually in the third step, the output of the script was not saved back to the XCCDF document and the second scan may not be issued. Thus the chain of evidences was discontinued.
The newer version of OpenSCAP library addresses these problems by integrating these 4 steps together. It introduces two new processess which I named Online and Offline remediation.
oscap’s Online Remediation
The online remediation executes
fix elements in the time of scanning. First of all OpenSCAP evaluates XCCDF as usual, assessing the results by evaluation of OVAL definitions. Next, each Rule which has failed is candidate for remediation. OpenSCAP searches for appropriate fix element, resolves it, prepares the environment and executes the script. Any output of the fix script is captured by OpenSCAP and stored within the result element. The return value of the fix script is stored as well.
Whenever OpenSCAP executes fix script, it immediatelly evaluates the OVAL definition again (to verify that fix script has been applied correctly). In this second run, if the OVAL returns success the result of the Rule is
fixed otherwise it is
error. The online remediation is executed by
--remediate command-line switch.
$ oscap xccdf eval --remediate \ --results ~/my-results-xccdf.xml \ /usr/share/scap/my-policy-xccdf.xml
oscap’s Offline Remediation
The offline remediation on the other hand allows you to postpone fix execution. In first step, you only evaluate system and store the
xccdf:TestResult on your disk:
$ oscap xccdf eval \ --result ~/my-results-xccdf.xml \ /usr/share/scap/my-policy-xccdf.xml
In the second step, oscap executes the fix scripts and verifies the result. It is safe to store results into the input file, no data will be lost. During the offline remediation OpenSCAP creates new
xccdf:TestResult element which is based on the previous one and inherits all the data. The newly created TestResult differs only in the rule-result elements which have had failed in the first place. For those the remediation is executed.
$ oscap xccdf remediate \ --results ~/my-results-xccdf.xml \ ~/my-results-xccdf.xml
Examplary result XCCDF
The following are snippets of the
~/my-results-xccdf.xml. These demostrate what data are exported by OpenSCAP to the result document. In the first example the rule-result failed to remediate, because I had not enough privileges to modify package set on the system.
<rule-result idref="xccdf_moc.elpmaxe.www_rule_1" time="2013-03-22T19:15:11" weight="1.000000"> <result>error</result> <message severity="info">Fix execution comleted and returned: 1</message> <message severity="info">Loaded plugins: auto-update-debuginfo, langpacks, presto, refresh-packagekit You need to be root to perform this command. </message> <message severity="info">Failed to verify applied fix: Checking engine returns: fail</message> <fix xmlns:xhtml="http://www.w3.org/1999/xhtml" platform="cpe:/o:redhat:enterprise_linux:6" reboot="false" disruption="low" system="urn:xccdf:fix:script:sh"> if rpm -q telnet-server; then yum remove -y telnet-server fi </fix> <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> <check-content-ref name="oval:moc.elpmaxe.www:def:1" href="test_remediation_simple.oval.xml"/> </check> </rule-result>
In the second try, I logged in as root user and the remediation succeeded. You can see that OpenSCAP exported full output of the fix script. The output of yum command within the XML file looks clumsy. On the other hand, I believe that in the critical environments the output of remediation command should be properly archieved, especially if the remediation is fully automated.
<rule-result idref="xccdf_moc.elpmaxe.www_rule_1" time="2013-03-22T19:16:03" weight="1.000000"> <result>fixed</result> <message severity="info">Fix execution comleted and returned: 0</message> <message severity="info">Loaded plugins: auto-update-debuginfo, langpacks, presto, refresh-packagekit Resolving Dependencies --> Running transaction check ---> Package telnet-server.x86_64 1:0.17-51.fc16 will be erased --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Removing: telnet-server x86_64 1:0.17-51.fc16 @fedora 53 k Transaction Summary ================================================================================ Remove 1 Package Installed size: 53 k Downloading Packages: Running Transaction Check Running Transaction Test Transaction Test Succeeded Running Transaction Erasing : 1:telnet-server-0.17-51.fc16.x86_64 1/1 Verifying : 1:telnet-server-0.17-51.fc16.x86_64 1/1 Removed: telnet-server.x86_64 1:0.17-51.fc16 Complete! </message> <fix xmlns:xhtml="http://www.w3.org/1999/xhtml" platform="cpe:/o:redhat:enterprise_linux:6" reboot="false" disruption="low" system="urn:xccdf:fix:script:sh"> if rpm -q telnet-server; then yum remove -y telnet-server fi </fix> <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> <check-content-ref name="oval:moc.elpmaxe.www:def:1" href="test_remediation_simple.oval.xml"/> </check> </rule-result>