Artifact Hashing Tool

From CMMC Toolkit Wiki
Jump to navigation Jump to search

Source of Reference: The official Artifact Hashing Tool User Guide from the Office of the Under Secretary of Defense for Acquisition & Sustainment.

For inquiries and reporting errors on this wiki, please contact us. Thank you.

Scope and Purpose

During the performance of a CMMC assessment, the assessment team will collect objective evidence using a combination of three assessment methods:

  • examination of artifacts,
  • affirmations through interviews, and
  • observations of actions.

Because these organizational artifacts are proprietary, the assessment team will not take organizational artifacts offsite at the conclusion of the assessment. For the protection of all stakeholders, the OSC must retain the artifacts.

Because the artifacts will remain with the OSC, a tool has been developed to provide a cryptographic reference (or hash) for each artifact used in the assessment. If needed, the integrity of the assessment artifacts may be checked by verifying the hash generated during the assessment. If an artifact has not been modified, the hash will remain the same.

The Artifact Hashing Tool is a PowerShell script that uses the SHA-256 algorithm to generate a hash of each artifact. Next, it generates a list of artifact filenames and associated hashes, then completes the process by generating a hash of the list. At the conclusion of the assessment, the OSC and the assessor will each have the list of artifact hashes, and a hash of the list.

System Requirements

A computer capable of running Microsoft PowerShell is required for this tool. PowerShell is available for Windows, Linux, and macOS. Please refer to Microsoft PowerShell instructions for installation, if the software is not already on your system. The execution of PowerShell scripts may be restricted by your organization. Microsoft's instructions explain how to temporarily bypass such restrictions to use the tool. Please speak to your administrator if you do not have the necessary permissions to execute PowerShell scripts. You can find additional details in the Supplemental Information section.

This tool was tested on Windows 10 (version 1904), Linux (Ubuntu 20.04) and macOS (10.15.7).

Process Overview

During the assessment planning and preparation, the OSC and assessment team should decide jointly how they will store artifact files during the assessment. The agreed-upon location should be secure and accessible only to those with a need-to-know, because the artifacts may contain sensitive or proprietary information.

During the course of the assessment, the team collects information through three assessment methods: interviews, artifact examination, and observation. This collection may include such activities as interviewing organization staff, examining the documents or the configuration of a device, and observing organization staff performing actions (Figure 1). It is important to collect objective evidence while performing these actions, to substantiate pass or fail decisions for each CMMC practice.

The central location where you store collected assessment artifacts may be a single root directory (Figure 2, Scenario 1) where all documents are stored. Optionally, the root directory may have subdirectories within it (Figure 2, Scenario 2). The Artifact Hashing Tool can operate in either scenario.

Clearly naming artifacts will aid in the event of an audit or retrospective reviews of assessment data in the government-managed database. Artifact filenames should follow a standardized naming pattern or be grouped by CMMC practice.

After all artifacts reviewed by the assessment team are consolidated into the central location, the OSC may run the artifact hashing tool. Both the OSC and Certified Assessor should retain a copy of the hash files. The following section details the process for generating hashes for all collected assessment artifacts.

Tool Usage Process

Use the commands listed in the instructions below to execute the Artifact Hashing Tool on a computer running Microsoft Windows. If you are using the tool on a computer running Linux or macOS, you will need to make minor command modifications (e.g., in Linux and macos, use mv instead of ren).

Preparation

Execution of Tool

Supplemental Information

  • For parameters that include spaces in the paths, surround the entire path name in single quotes. During testing, double quotes produced an error.
  • If the script file is not placed in the root assessment artifact directory, you will need to specify the path of the script, for example, Z:\Files\Tool ArtifactHash.ps1.
  • In certain instances, the organization may restrict the execution of PowerShell scripts. The By Pass value of the Execution Policy cmdlet within the command should temporarily bypass these restrictions. In addition, it is possible to manually verify and modify the PowerShell script execution policy of the current user as follows.
Note: The content following the # (hashtag) symbol represents a comment in the script.

1. Verify the policy that is set.

2. Set the execution policy for the user to bypass, and verify that "Bypass" is reflected.

3. After completion of the hashing process, change the execution policy back to the default state.

Appendix A: ArtifactHash.txt File Content

The blue courier text below is the powershell script needed for this task. Use cut and paste to copy all of the blue courier content into your favorite text editor and store the file with the name: ArtifactHash.txt.

<#
.SYNOPSIS
    Hash artifacts for a CMMC Assessment to maintain integrity in the event any files are needed in the future
.DESCRIPTION
    This script will recursively evaluate all files in a local or UNC path.  Each file will be hashed and written to a text file.  Additionally,  the record is hashed to preserve the integrity of the output
.PARAMETER ArtifactRootDirectory
    Specifies the root path of the CMMC assessment artifacts.  This location can be represented by a traditional Windows file path, a  UNC path, or even .\
.PARAMETER ArtifactOutputDirectory
    Specifies the directory where the script will write two log files.  The first log is the listing of all files within the ArtifactRootDirectory  as well as the corresponding hash. The second log, is a hashed value of the first log.  This is a simple way to help preserve the  integrity of the artifact listing without requiring the maintenance of a public/private key pair or a password for an HMAC
#>
#VERSION 1.11
param
(
    [Parameter(mandatory=$false)][string]$ArtifactRootDirectory = ".\",
    [Parameter(mandatory=$false)][string]$ArtifactOutputDirectory = ".\"
)
function GetFileHashes ([string] $rootLocation, [boolean] $isDirectory)
{
    if ($isDirectory)
    {
        $hashList = Get-ChildItem -path $rootLocation -Recurse -Force -File | Get-FileHash
    }
    else
    {
        $hashList = Get-FileHash $rootLocation
    }
    return $hashList
}
function WriteASCIIFile ([string] $filePath, [object] $fileContent)
{
    Out-File -FilePath $filePath -Force -Encoding ASCII -InputObject $fileContent -Width 1024
}
function VerifyLocationExist ([string] $location)
{
    try
    {   $doesExist = Test-Path $location
        if (-Not $doesExist)
        {
            ECHO "Location $location does not exist"
            throw
        }
    }
    catch
    {
        ECHO "The program failed to evaluate the path.  Perhaps you specified an incorrectly formatted command line parameter?"
        EXIT
    }
}
function IsDirectory ([string] $location)
{
    $isDirectory = (get-item $location) -is [System.IO.DirectoryInfo]
    return $isDirectory
}
$version = "1.11"
ECHO "Artifact Hashing Script Version $version"
#Just making sure locations are legit
ECHO "Verifying existence of $ArtifactRootDirectory"
VerifyLocationExist $ArtifactRootDirectory
ECHO "Verifying existence of $ArtifactOutputDirectory"
VerifyLocationExist $ArtifactOutputDirectory
#determine if the input provided is for a single file or for a directory of files
$artifactLocationIsDir = IsDirectory($ArtifactRootDirectory)
$logFileLocationIsDir = IsDirectory($ArtifactOutputDirectory)
if($logFileLocationIsDir)
{
    $logFileLocation = $ArtifactOutputDirectory + "\CMMCAssessmentArtifacts.log"
    $hashedLogFileLocation = $ArtifactOutputDirectory + "\CMMCAssessmentLogHash.log"
}
else
{
    $endOfString = $ArtifactOutputDirectory.LastIndexOf("\")
    $logFileLocation = $ArtifactOutputDirectory.Substring(0,$endOfString) + "\CMMCAssessmentArtifacts.log"
    $hashedLogFileLocation = $ArtifactOutputDirectory.Substring(0,$endOfString) + "\CMMCAssessmentLogHash.log"
}
#return the list of artifacts with their hashed values
$hashedFiles = GetFileHashes $ArtifactRootDirectory $artifactLocationIsDir
ECHO "Writing artifact file listing to $logFileLocation"
WriteASCIIFile $logFileLocation $hashedFiles
#Now, I'm going to create a second file hashing the artifacts file
$hashTheHash = GetFileHashes $logFileLocation $false
ECHO "Writing hashed value of artifact file listing to $hashedLogFileLocation"
WriteASCIIFile $hashedLogFileLocation $hashTheHash
ECHO "SCRIPT COMPLETE"