Test Case Generation

Introduction

This article is a review of using AI tools to generate cybersecurity compliance test cases that create evidence of compliance to a cybersecurity standard (the US Department of War (DoW) Cybersecurity Maturity Model Certification (CMMC) standards used in these scenarios).  This is the third blog article in a series of applied AI technology as aids to develop a cybersecurity compliance program.  An overview document providing the background for this blog series can be found here:

 

(https://www.complianceautomationenineeirng.com/blogoverview)

 

That article provides the scenario that is the basis for this blog series and information about the environment used for this use case.

Disclaimer:  All materials created in this blog series were developed solely by, are the opinions of the author and are provided with no express or implied warranty.  Other than outputs generated by the AI models used in this exercise, no AI was used to prepare this blog series (in case you were wondering).  The author accepts no liability for the use of any of these materials by the reader.  We strongly encourage engaging appropriate professionals for developing materials for use within your own organization.

Cybersecurity Compliance Test Cases

Test cases can be used as a means to generate and collect evidence of compliance to a cybersecurity standard.  Compliance to many cybersecurity requirements can be demonstrated through computer device configuration settings and tests to collect information about cybersecurity related systems.  Although test cases per se are not an explicit cybersecurity requirement of the CMMC standards, programs in the form of scripts can be easily prepared that read and report device settings which can satisfy a given requirement.  Further, once written these scripts can be reused to monitor the state of the system under review providing a form of continuous cybersecurity monitoring, an acknowledged best practice.

 

An example:

CMMC Account Control (AC) requirement AC.L2-3.1.8 – Unsuccessful Logon Attempts states “Limit unsuccessful logon attempts” (ref. CMMC Assessment Guide Level 2, Version 2.13, September 2024 (ZRIN 0790-ZA19). 

 

To further clarify the requirement, the associated assessment objectives consist of:

 

Determine if:

 

[a] the means of limiting unsuccessful logon attempts is defined; and

[b] the defined means of limiting unsuccessful logon attempts is implemented.

 

This first objective [a] is a documentation related requirement, meaning that somewhere in the organization’s technical documentation (policy / procedure, System Security Plan (SSP), internal standards / guidelines, etc.) there should be a statement on how the organization implements control of unsuccessful logon attempts. 

 

Most likely this will refer to a configuration setting that controls the maximum of unsuccessful logon attempts.  In the case of Microsoft Windows 11, the following registry setting controls that parameter:

 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Parameters\AccountLockout

 

In organizations systems documentation, a value would be specified, perhaps set to 5 maximum unsuccessful attempts.  To meet objective [a], the documentation would specify where this setting is documented and its required setting.

 

The second objective [b] is a natural candidate for an automated test case.  It is a typical example of an objective that can be easily satisfied with a script.

 

This test case would read the registry setting and provide it as evidence that the requirement is met, assuming it is set to 5 per the organizations documented specification.  The following Windows powershell command reports the current setting of the logon attempts registry setting:

 

net accounts

 

Here is an example result of that command showing that the Lockout threshold amount is set to 10 which would fail the requirement and need to be set to 5 to meet the organizations standard:

Using the above command as its basis, an automated script can extract the Lockout Threshold value from the generated output and report the result.  This provides the raw data (the current value of the Lockout threshold setting in this case) for addressing the control objective. This serves as a data point for a compliance assessment.

 

A second step can be to compare the retrieved value to the required setting and declare whether the objective is met or not.  This assumes that the required value setting is available in electronic form and not embedded in a document (see the discussion “A few words about ODP’s” following). 

 

By their nature, test cases are operating system environment (OS) and version specific.  Most organizations have a mixture of operating systems for their devices (some may be firmware based).  Commands to provide test case results need to be generated for the correct OS, version and device type.  Some devices may be networking appliances (e.g., CISCO), some may be office workstations (e,g,, Microsoft Windows or Apple Macintosh OS) while others may be system servers (possibly Linux based).

 

Each of these environments require expertise to know what commands to use and how to use them for test cases.  This expertise most likely resides in different individuals or groups within an organization, or may reply upon vendors to provide.  Using AI tools to generate test cases can help compliance analysts, who may not be experts in all systems environments, by providing start points to create test cases and identify parameter settings for specific systems related data.  This can greatly expedite their development.  When needed, experts on specific environments can be consulted to validate meaning of specific parameter settings.  This is much more efficient than having valuable resources tied up with creating test cases and leverages their expertise.

A few words about ODP’s (Organizational Defined Parameters):  This blog series was developed using the current in effect version of the CMMC standards, Version 2 by the US Department of War (DoW).  These standards are based on the NIST SP800-171, Version 2 control standards.  The standards have been updated and replaced by the Version 3 standard by NIST.  One of the improvements of the Version 3 standard is the formal introduction of Organizational Defined Parameters (ODP’s) (ref. NIST SP800-171A, Rev.3 ).  87 ODP’s have been defined in the NIST SP800-171 Version 3 standards.

 

One of the ODP’s is defined as: 

 

A.03.01.08.ODP[01]: the number of consecutive Invalid logon attempts by a user allowed during a time period is defined.

 

If the organization has developed the assigned settings for its ODP’s they can be used directly in test cases like the one above.  Parameterized ODP values can be used in test cases to make evaluation of objectives easier, more precise and facilitate automating compliance reporting.  Even though the current in effect CMMC (based on NIST SP800-171Rev.2) standard does not include ODP’s, they can be used now to expedite test case development and compliance assessments and should be considered a best practice.  Kudos to NIST for these types of improvements.

Inputs

The following input files were used to provide contextual information to ChatGPT V5 for test case generation.

 

  • ACObjectives.csv – the list of control objectives for generating test cases. Note that this list of control objectives is for the Access Control (AC) family only, and does not include the objectives for the rest of the CMMC control objectives.

Prompt

Following is the initial ChatGPT prompt used for the test case generation scenario.  The full chat sequence is lengthy and can be seen here.

The initial response from the above prompt failed to produce a usable result.  ChatGPT attempted to generate one script per objective (in the AC control family there were a total of 70 objectives) one each for the 45 cyber assets.   That would result in 2,760 total scripts scripts).

 

ChatGPT gave up and stopped after generating 684 scripts presumably because of AI model token limitations.  This behavior of simply stopping a generation task (be it code generation or document generation, etc.) is typical of Large Language AI Models (LLMs).  When they run out of memory space to process tokens needed, they tend to just give up and stop.

 

In addition, when reviewing the generated scripts the vast majority appeared to be generic Linux style bash scripts and not specific to the target operating environments of the device asset list.  Lesson learned, be careful what you ask for (or more specifically, this is a case of a need for further prompt engineering).

 

To remedy the large volume generation issue, I added this next prompt in the ChatGPT dialog:

Please make the following changes to the tests and the test generation:

 

  1. Please generate tests on a per operating system environment basis.  This means that there should be one test per operating system (OS) and version (OSVer) for each control objective.  Note that one test may address multiple objectives in which case one test should be generated and marked as addressing the multiple objectives.  If it is easier to manage, please generate the actual individual test code for each test (per OS environment) instead of using the test code generator approach.  
  1. For each generated test case, please record the Operating system, the Operating system version, the control objective number met, the control number met and include the description associated with the control objective so that auditing of test runs can associate the test results with the corresponding control objective.

The result was a set of scripts organized by operating system and objective.  The generated scripts were now OS appropriate and very much closer to the intended result.  There were some anomalies in the Macintosh and CISCO OS versions of the scripts.  In addition, as an enhancement, I added a request to generate explanations on how a given script addresses the control objective.  These changes were added were addressed with the dialog prompt:

The generated scripts for MacOS appear to use an older version that uses outdated commands.  For example, the generated MACOS test for AC.L2-3.1.21, uses the lastlog command, but the current, correct command is “log” and requires different command parameters.  Second example, test AC.L2-3.1.19 generated for MACOS uses the lsblk command that is not available on MacOS (lsblk is generic linux) – macos uses the diskutil command. Third example, the MACOS test for AC.L2-3.1.17 uses the nmcli command that is not a current MACOS command.  Is it possible to generate commands that use the current supported MACOS commands?

 

The generated scripts that are for CISCO ASA appear to be generic linux commands, not specific CISCO ASA operating system commands.  As such, they will not work on cisco operating systems.  Please correct to use CISCO ASA specific commands.  Refer to the CISCO command reference for list of valid CISCO ASA operating system commands:

 

https://www.cisco.com/c/en/us/td/docs/security/asa/asa-cli-reference/A-H/asa-command-ref-A-H/m_da-dg.html

 

Please add comments to the generated test cases that explains how the test achieves the objective(s).  For example, if the objective states “Determine if the execution of privileged functions is captured in audit logs”, the explanation should be something like: “audit logging is configured to capture privileged functions because <explain>” and indicate that the test was passed successfully.  The explanation should be included as comments in the generated test scripts.   In the case where an objective is not met indicate the test failed.

ChatGPT responded with:

Response

Absolutely — here’s a clean regeneration of test cases that:

 

  • Adds HowTestMeetsObjective (and tightens SuccessCriteria) explaining how each test proves/doesn’t prove the objective.
  • Writes the same explanation into each generated script’s comments and also prints PASS/FAIL + explanation into results.txt.
  • Modernizes macOS commands (no lsblk, nmcli, lastlog misuse; uses fdesetup, log, networksetup, systemsetup, auditconfig, etc.).
  • Introduces Cisco ASA targeting: if an asset’s OS contains ASA or Cisco ASA, it generates an ASA command pack (to be executed from a jump host via SSH or your agent’s Netmiko runner). These are ASA-native show/more system:running-config queries (not GNU/Linux commands). You can flip between “raw CLI file” or a ready-to-run Python/Netmiko wrapper by a flag.

The results from this prompt were very good and addressed the issues noted above.

 

Review of Results

 

In total 171 test cases were generated organized by CMMC standard and OS.  Each script includes as comments the following:

  • Control: The CMMC requirement control ID for the script (e.g., AC.L1-3.1.1
  • OS: The OS target for the script
  • OSVer: The OS version for the sript
  • TestKey: The parameter that forms the test key for the sctipt
  • Objective: The CMMC objective for  the script
  • HowThisTestMeetsObjective: A description of how the script meets the objective being tested
  • SuccessCriteria: The criteria that is used to determine if the test was a success or not (objective met or not met)

 

The comments are followed by the executable script code.

 

Here is the generated Windows 11 script for the above requirement objective [b]: the defined means of limiting unsuccessful logon attempts is implemented for CMMC control requirement AC.L2-3.1.8: Unsuccessful Logon Attempts:

# Control: AC.L2-3.1.8

# OS: Windows

# OSVer: 23

# TestKey: lockout_policy

# Requirement: AC.L2-3.1.8

# HowThisTestMeetsObjective: Unsuccessful login lockout is enforced. Windows via ‘net accounts’ & security policy; Linux via pam_faillock; macOS via ‘pwpolicy’ global policy.

# SuccessCriteria: results.txt must show lockout thresholds/durations configured to organization policy.

# Objective Descriptions:

#  – 3.1.8[a] – the means of limiting unsuccessful logon attempts is defined

#  – 3.1.8[b] – the defined means of limiting unsuccessful logon attempts is implemented

# How: Unsuccessful login lockout is enforced. Windows via ‘net accounts’ & security policy; Linux via pam_faillock; macOS via ‘pwpolicy’ global policy.

# Criteria: results.txt must show lockout thresholds/durations configured to organization policy.

“net accounts” | Out-File results.txt

secedit /export /cfg sepolicy.inf | Out-Null

Select-String -Path sepolicy.inf -Pattern “LockoutBadCount|ResetLockoutCount|LockoutDuration” | Out-File -Append results.txt

$cfg = Get-Content sepolicy.inf

$bad = $cfg -match “LockoutBadCount\s*=\s*(\d+)”

$passed = $bad -and ($matches[1] -as [int]) -ge 3

$explain = “Unsuccessful login lockout is enforced. Windows via ‘net accounts’ & security policy; Linux via pam_faillock; macOS via ‘pwpolicy’ global policy. “ + ($(if ($passed) {“Test passed—account lockout thresholds present.”} else {“Objective not met—no lockout thresholds found.”}))

$stat = @{Status=($(if($passed){“success”}else{“error”})); Explanation=$explain}

$stat | ConvertTo-Json | Out-File status.json

Executing this script (as a Windows Powershell script) produces the following output:

(from file results.txt)

net accounts

sepolicy.inf:9:LockoutBadCount = 10

sepolicy.inf:10:ResetLockoutCount = 10

sepolicy.inf:11:LockoutDuration = 10

(from file status.json)

{

    “Explanation”:  “Unsuccessful login lockout is enforced. Windows via \u0027net accounts\u0027 \u0026 security policy; Linux via pam_faillock; macOS via \u0027pwpolicy\u0027 global policy. Test passed-account lockout thresholds present.”,

    “Status”:  “success”

}

Observations

The process of using AI to generate compliance test cases is an iterative exercise in gaining the desired results.  AI tools such as ChatGPT are effective at generation tasks generally, however due to the more complex nature of cybersecurity compliance, a simple prompt such as “Please generate a humorous story about three bears and a little blond girl” is not enough to create the desired outcome.  It takes several iterations of dialog with the AI engine to understand how it responds and what it needs in order to accomplish the task.

Context is critical to the process.  Sufficient quantity of contextual information must be made available to the AI tool so that it can create the correct output.  It is valuable to remember that the AI engine has no prior information about the problem to be solved, or environment in which to operate.  Identifying the perquisite information goes hand in hand with the iterative process wherein when you see the results of a given prompt, it becomes evident what additional or modified information is needed.

As previously stated, Organizational Defined Parameters (ODP’s) provide key parameters that the organization sets for control objectives.  The example here is ODP 01 of requirement A.03.01.08:

A.03.01.08.ODP[01]: the number of consecutive invalid logon attempts by a user allowed during a time period is defined.

ODP’s were added to the NIST SP800-171 standard with version 3.  The current enforced standard is Version 2.  In this code generation exercise, the list of ODP’s were added as input to ChatGPT.  In the version 2 standard for this example, there is no mention of “during a time period”.  ChatGPT picked up this detail for the version 3 code generation test case and added it to the results. 

Conclusions

Effective results can be obtained through the application of AI technology to the task of generating compliance test cases.  Given that there is potentially a large number of test cases required to generate the evidence needed for a thorough assessment, generating test cases provides an effective means to reduce the time and effort required to create them.  Generating test cases has high value for cybersecurity compliance assessments and can substantially reduce the time and cost to conduct them.

Appendix A - Samples of Generated Test Cases

TestCasesGenerated

Standard Requirement Environment Test Command(s) Test Script Result
ACL2-3.1.1   Windows 11 Get-LocalUser | Select Name,Enabled,LastLogon | Sort Name | Format-Table -AutoSize > results.txt net user guest >> results.txt 2>&1 (Get-ItemProperty ‘HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp’).UserAuthentication | Out-File -Append results.txt Name                                           Enabled     LastLogon ----                                                 -------           --------- Administrator                           False DefaultAccount                       False Guest                                           False Michael Davidson                  True               11/5/2025 7:57:58 AM WDAGUtilityAccount           False   1
ACL2-3.1.1   CISCO ASA # Execute these commands on ASA and capture output: show running-config show logging show ssh show http show telnet show aaa-server show aaa authentication show vpn-sessiondb anyconnect more system:running-config | inc privilege|username|aaa|ssh|telnet|http Unable to test
ACL2-3.1.5 Employ the principle of least privilege, including for specific security functions and privileged accounts. Linux set -euo pipefail id > results.txt echo ‘{{“Status”:”success”,”Explanation”:”Administrative group membership is constrained; privilege escalation requires auth. Test enumerates admin groups/sudo NOPASSWD exceptions. Generic evidence captured.”}}’ > status.json uid=1000(mdavidson) gid=1000(mdavidson) groups=1000(mdavidson),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),1 00(users),116(lpadmin)
ACL2-3.1.5   Windows 11 REM ACL2-3.1.5-least_privilege-Windows.bat net localgroup administrators > results.txt whoami /groups >> results.txt Alias name     administrators Comment        Administrators have complete and unrestricted access to the computer/domain   Members   Administrator Michael Davidson The command completed successfully.     GROUP INFORMATION   Group Name                                                    Type             SID          Attributes                                          ============================================================= ================ ============ =============================================================== Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Mandatory group, Enabled by default, Enabled group  BUILTIN\Administrators                                        Alias            S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\INTERACTIVE                                      Well-known group S-1-5-4      Mandatory group, Enabled by default, Enabled group  CONSOLE LOGON                                                 Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group  LOCAL                                                         Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group  NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group  Mandatory Label\High Mandatory Level                          Label            S-1-16-12288                                                    
xcACL2-3.1.5   CISCO ASA # OS: Cisco ASA # TestKey: least_privilege # HowThisTestMeetsObjective: Administrative group membership is constrained; privilege escalation requires auth. Test enumerates admin groups/sudo NOPASSWD exceptions. # SuccessCriteria: results.txt must show minimal admin members and absence of broad NOPASSWD grants.   # Execute these commands on ASA and capture output: show running-config | include username|privilege show privilege utt
ACL2-3.1.7 Non-priviledged account use Windows 11 reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA > results.txt   reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin >> results.txt HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System EnableLUA    REG_DWORD    0x0   HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System ConsentPromptBehaviorAdmin    REG_DWORD    0x5
ACL2-3.1.7 Non-priviledged account use Linux #!/usr/bin/env bash # How: Audit logging is configured to capture privileged function execution (e.g., sudo/privileged exec). The test checks platform audit settings (Windows: Advanced Audit Policy Privilege Use; Linux: auditd execve rules for euid=0; macOS: auditd policy argv/arge). # Criteria: results.txt must contain audit settings capturing privileged-use/exec and rule lines or policy indicating capture. set -euo pipefail : > results.txt echo "== audit rules ==" >> results.txt auditctl -l >> results.txt 2>/dev/null || true grep -R "execve" /etc/audit/rules.d 2>/dev/null >> results.txt || true echo "== sudo logging ==" >> results.txt grep -R "logfile" /etc/sudoers /etc/sudoers.d 2>/dev/null >> results.txt || true   blob=$(tr '[:upper:]' '[:lower:]' < results.txt) if echo "$blob" | grep -E -q 'execve|always,exit.*euid=0|sudo.*logfile'; then   echo "PASS: privileged exec is audited or sudo is logging" >> results.txt   echo '{{"Status":"success","Explanation":"Audit logging is configured to capture privileged function execution (e.g., sudo/privileged exec). The test checks platform audit settings (Windows: Advanced Audit Policy Privilege Use; Linux: auditd execve rules for euid=0; macOS: auditd policy argv/arge). Test passed—auditd execve (root) and/or sudo logging present."}}' > status.json else   echo "FAIL: no privileged exec audit or sudo logging found" >> results.txt   echo '{{"Status":"error","Explanation":"Objective not met—no audit rules or sudo logging for privileged exec."}}' > status.json fi == audit rules == == sudo logging == FAIL: no privileged exec audit or sudo logging found
ACL2-3.1.7 Non-priviledged account use Cisco ASA # Execute these commands on ASA and capture output: show logging show aaa accounting more system:running-config | include logging  
ACL2-3.1.21   Windows 11 Get-LocalUser | Select Name,Enabled,LastLogon | Sort Name | Out-File results.txt "net accounts" | Out-File -Append results.txt try {   Get-ADUser -Filter 'enabled -eq $false' -Properties whenChanged,LastLogonDate |   Select SamAccountName,Enabled,whenChanged,LastLogonDtate | Out-File -Append results.tx } catch { "AD module not available" | Out-File -Append results.txt } Name        Enabled LastLogon ----               -------      --------- Administrator        False DefaultAccount    False Guest                         False Michael Davidson True 11/5/2025 7:57:58 AM WDAGUtilityAccount False     net accounts
ACL2-3.1.21   Cisco ASA # OS: Cisco ASA # TestKey: account_management # HowThisTestMeetsObjective: Accounts are managed with appropriate lifecycles. Test lists disabled/stale accounts and password aging settings. # SuccessCriteria: results.txt must contain disabled accounts, lastlog insights, and aging configuration.   # Execute these commands on ASA and capture output: show running-config show logging show ssh show http show telnet show aaa-server show aaa authentication show vpn-sessiondb anyconnect more system:running-config | inc privilege|username|aaa|ssh|telnet|http Unable to test

Discover more from Compliance Automation Engineering LLC

Subscribe now to keep reading and get access to the full archive.

Continue reading