Artifacts definition

Artifacts define parameters for a collector to gather data.

UAC reads the YAML files dynamically and, based on their contents, uses one of the five available collectors (command, file, find, hash and stat) to collect the relevant artifacts.

The example below contains two sets of rules: the first set uses the hash collector, and the second set uses the command collector to gather the artifacts.

version: 1.0
artifacts:
  -
    description: Hash running processes.
    supported_os: [aix]
    collector: hash
    path: /proc/[0-9]*/object/a.out
    output_directory: /live_response/process
    output_file: hash_running_processes
  -
    description: Report a snapshot of the current processes.
    supported_os: [aix, freebsd, linux, macos, netbsd, openbsd, solaris]
    collector: command
    command: ps auxwww
    output_directory: /live_response/process
    output_file: ps_auxwww.txt

It is common practice to group all artifacts related to the same topic within a single YAML file. This approach allows for more granular artifact collection based on the specific case you are working on.

An artifact has one required field at the top of the file version, followed by a set of rules that will be used by one of the collectors to collect the desired data.

artifacts

Required

Set of rules (sequence of mappings) that define what data will be collected.

An artifact rule must include three mandatory fields: description, supported_os, and collector, along with additional properties depending on the chosen collector.

version: 1.0
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    ... # additional options depending on the collector
  -
    description: Hash files that contain at least +x flag set for owner.
    supported_os: [all]
    collector: hash
    ... # additional options depending on the collector
  -
    description: Collect /var/log logs.
    supported_os: [all]
    collector: file
    ... # additional options depending on the collector

collector

Required

UAC uses collectors to gather data, with each collector serving a specific function and requiring its options.

command

Use this collector to run commands and store the output into an output file. In a nutshell, UAC will use eval to run the command and redirect the stdout to the output file. The stderr will be captured and added to uac.log file as a log record.

Required fields:

Optional fields:

find based collectors

These collectors use the find tool to search for files and directories before collecting or processing any data.

As an example, the artifact below...

version: 1.0
artifacts:
  -
    description: Collect nginx logs.
    supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris]
    collector: file
    path: /var/log
    exclude_path_pattern: ["/sys", "/proc"]
    name_pattern: ["*access_log*", "*access.log*", "*error_log*", "*error.log*"]
    max_depth: 5
    max_file_size: 1073741824 # 1GB

...will become this:

find /var/log -maxdepth 5 \( -path "/sys" -o -path "/proc" \) -prune -o -size -1073741824c  \( -name "*access_log*" -o -name "*access.log*" -o -name "*error_log*" -o -name "*error.log*" \) -print

Since the find tool varies between operating systems, UAC will determine which options are supported by the find tool on the target system to build the correct find command at runtime. UAC can also use a Perl-based implementation of the find command provided in the tools/find_pl directory.

For example, if the artifact above is executed on a system where the find tool does not support the -maxdepth and -path options, and perl is also not available, the find command will be:

find /var/log -size -1073741824c  \( -name "*access_log*" -o -name "*access.log*" -o -name "*error_log*" -o -name "*error.log*" \) -print

Since the Perl-based implementation of the find command supports most known options, the same example will result in the following command:

find_pl /var/log -maxdepth 5 \( -path "/sys" -o -path "/proc" \) -prune -o -size -1073741824c  \( -name "*access_log*" -o -name "*access.log*" -o -name "*error_log*" -o -name "*error.log*" \) -print

This is done to prevent the find command from failing during the collection due to an invalid option.

find

Use this collector to find files and directories and store the output into a text file.

Required fields:

Optional fields:

hash

Use this collector to hash files and store the output into a text file. The algorithms are defined in the uac.conf file.

Required fields:

Optional fields:

stat

Use this collector to extract information from files and directories to create a body file.

Some systems do not have the stat tool available, but do have Perl (e.g., AIX). In this case, UAC will use a Perl-based version (stat_pl) to extract information from files and directories.

Required fields:

Optional fields:

file

Use this collector to collect files and directories (in their raw format). Collected files will be stored in the [root] directory within the output file.

screenshot

Required fields:

Optional fields:

command

Required by: command

Accepted values: one or multiple shell commands

The command will be executed on the target system, and the output will be collected.

You do not need to specify the path to the executable as it is expected to be in the PATH; only the executable's name and parameters are required.

UAC can also run executables located in the bin directory. In this case, the path to the executable is still not required, as the bin directory is automatically added to PATH when UAC runs. For more information, refer to the bin/README.md file.

The example below demonstrates how to collect the output from the ps -ef command:

version: 1.0
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps -ef
    output_directory: /live_response/process
    output_file: ps_-ef.txt

compress_output_file

Optional for: command

Accepted values: true or false

If this option is set to true, the output file will be compressed using gzip (when gzip is available).

The example below will result in a compressed ps_-ef.txt.gz file.

version: 1.0
output_directory: /live_response/process
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps -ef
    output_file: ps_-ef.txt
    compress_output_file: true

Note that compress_output_file only applies to files specified in the output_file key-value pair.

condition

Optional for: command, file, find, hash and stat

Accepted values: one or multiple shell commands

The collection will only run if the condition returns true. This feature is very useful for preventing UAC from executing numerous commands if a specific condition does not apply to the target system.

In the example below, the command will only be executed if the condition ls /proc/$$ returns true.

version: 1.0
output_directory: /live_response/process
artifacts:
  -
    description: Collect running processes executable path.
    supported_os: [freebsd]
    condition: ls /proc/$$
    collector: command
    command: ls -l /proc/[0-9]*/file
    output_file: running_processes_full_paths.txt

You can prefix the command with an exclamation mark (!) to perform an 'if not' condition.

In the example below, the command will only be executed if the condition ls /proc/$$ returns false.

version: 1.0
output_directory: /live_response/process
artifacts:
  -
    description: Collect running processes executable path.
    supported_os: [freebsd]
    condition: ! ls /proc/$$
    collector: command
    command: ps -eo args | grep ^/ | awk '{print $1}' | sort -u
    output_file: running_processes_full_paths.txt

The condition key-pair value can also be used as a global option, placed before the artifacts mapping. In this case, the collection will only proceed if the global condition returns true.

In the example below, the data will only be collected if the global condition returns true.

version: 1.0
output_directory: /live_response/process
condition: ls /proc/$$
artifacts:
  -
    description: Hash running processes.
    supported_os: [linux, netbsd]
    collector: hash
    path: /proc/[0-9]*/exe
    output_file: hash_running_processes
  -
    description: Hash running processes.
    supported_os: [freebsd]
    collector: hash
    path: /proc/[0-9]*/file
    output_file: hash_running_processes

description

Required

Description of what will be collected. No line breaks are supported.

exclude_file_system

Optional for: file, find, hash and stat

Accepted values: array of file systems

Use this option to exclude file systems from the collection. UAC will retrieve the list of existing mountpoints (paths) at runtime and exclude them from the collection.

The file system types that are supported depend on the target computer's running kernel. Note that exclude_file_system will be ignored when path_pattern is used.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all files excluding any files located in procfs, nfs and devfs file systems.
    supported_os: [all]
    collector: find
    path: /
    exclude_file_system: [procfs, nfs, devfs]
    output_file: exclude_procfs_nfs_devfs.txt

exclude_name_pattern

Optional for: file, find, hash and stat

Accepted values: array of paths

Use this option to exclude files from the collection. This option works the same way as find's -name -prune option.

Since the leading directories are removed, the file names considered for a match with name_pattern will never include a slash, so "a/b" will never match anything.

Don't forget to enclose the pattern in double quotes. Use a backslash (\) to escape double quotes and commas.

As UAC uses find tool to search for artifacts, wildcards and regex patterns are also supported here.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search /etc excluding passwd and shadow* files.
    supported_os: [all]
    collector: find
    path: /etc
    exclude_name_pattern: ["passwd", "shadow*"]
    output_file: etc_excluding_passwd_shadow.txt

exclude_nologin_users

Optional for: command, file, find, hash and stat

Accepted values: true or false

Use this option to search for artifacts only from users with a valid shell. Any user with no shell will be skipped from the collection.

By default, UAC will always search for artifacts from all users.

version: 1.0
artifacts:
  -
    description: Run 'ls -lRa' on all home directories for users that have a valid shell only.
    supported_os: [all]
    collector: command
    command: ls -lRa /%user_home%/
    exclude_nologin_users: true
    output_directory: /live_response/%user%
    output_file: ls_-lRa_%user%.txt

exclude_path_pattern

Optional for: file, find, hash and stat

Accepted values: array of paths

Use this option to exclude paths from the collection. This option works the same way as find's -path -prune option.

Don't forget to enclose the pattern in double quotes. Use a backslash (\) to escape double quotes and commas.

As UAC uses find tool to search for artifacts, wildcards and regex patterns are also supported here.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all excluding /etc and /var.
    supported_os: [all]
    collector: find
    path: /
    exclude_path_pattern: ["/dev", "/var"]
    output_file: all_excluding_etc_var.txt

file_type

Optional for: file, find, hash and stat

Accepted values: array of file types

Use this option to specify the type of file to search for, such as directories (d), regular files (f), symbolic links (l), and other file types. This option works the same way as find's -type option.

File is of type:

Value Description
f regular file
d directory
l symbolic link
p named pipe (FIFO)
s socket
b block special
c character special
version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search files only.
    supported_os: [all]
    collector: find
    path: /
    file_type: [f]
    output_file: files_only.txt
  -
    description: Search directories only.
    supported_os: [all]
    collector: find
    path: /
    file_type: [f, d, l]
    output_file: directories_only.txt

foreach

Optional for: command

Accepted values: one or multiple shell commands

The command will be executed, and its output lines will be used as input by the command key-value pair.

The logic behind it is:

for (each line returned by foreach); do
  command
done

The %line% variable has to be used and will be replaced by each line returned by the execution of the foreach command at runtime. The %line% variable can also be used on output_directory and output_file key-value pairs.

Let's suppose you need to collect container logs, and you don't know the container IDs. First, you need to retrieve all the IDs: docker container ps -all | sed 1d | awk '{print $1}'

The %line% variable will be replaced by each output line generated by the command (which are container IDs in the example above).

This implies that if you have 10 containers, the command docker container logs %line% will be executed 10 times, once for each container ID.

Example:

version: 1.0
artifacts:
  -
    description: Fetch the logs of all containers.
    supported_os: [linux]
    collector: command
    foreach: docker container ps -all | sed 1d | awk '{print $1}'
    command: docker container logs %line%
    output_directory: /live_response/containers/%line%
    output_file: docker_container_logs_%line%.txt

ignore_date_range

Optional for: file, find, hash and stat

Accepted values: true or false

Use this option to collect files ignoring the date set using both --start-date and --end-date command line options.

This is useful when you want to set a date range for your collection, but want to collect some files regardless of their last accessed, modified and changed dates.

For example, search for all files and subdirectories from /etc regardless of their last accessed, modified and changed dates, even if a date range was set using --start-date and --end-date command line options.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search /etc regardless date range set by --start-date and --end-date.
    supported_os: [all]
    collector: find
    path: /etc
    ignore_date_range: true
    output_file: ignore_date_range.txt

is_file_list

Optional for: file, hash and stat

Accepted values: true or false

If set to true, the path option will refer to a file list containing one path per line. This is useful when you need to hash/stat/collect files based on a file list.

artifacts:
  -
    description: Hash files based on a file list located in /%uac_directory%/my_file_list.txt.
    supported_os: [all]
    collector: hash
    path: /%uac_directory%/my_file_list.txt
    is_file_list: true
    output_file: hash_my_file_list.txt

max_depth

Optional for: file, find, hash and stat

Accepted values: non-negative integer

Descend at most levels (a non-negative integer) levels of directories below the starting-point. Using 0 means only applying the tests and actions to the starting-points themselves. This option works the same way as find's -maxdepth option.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Descend at most 5 levels of directories below /.
    supported_os: [all]
    collector: find
    path: /
    max_depth: 5
    output_file: max_5_levels.txt

max_file_size

Optional for: file, find, hash and stat

Accepted values: non-negative integer

The maximum size of a file to search (in bytes). Any files bigger than this will be ignored. This option works the same way as find's -size option.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all files smaller than 1048576 bytes.
    supported_os: [all]
    collector: find
    path: /
    file_type: f
    max_file_size: 1048576
    output_file: smaller_than.txt

min_file_size

Optional for: file, find, hash and stat

Accepted values: non-negative integer

The minimum size of a file to search (in bytes). Any files smaller than this will be ignored. This option works the same way as find's -size option.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all files bigger than 1048576 bytes.
    supported_os: [all]
    collector: find
    path: /
    file_type: f
    min_file_size: 1048576
    output_file: bigger_than.txt

modifier

Optional

Accepted values: true or false

The collection will only execute if the value is set to true and the --enable-modifiers switch is included in the command line. This feature helps identify artifacts that modify the current system state after execution.

Please note that this is a global property that must be set before defining the artifacts mapping.

In the example below, the artifact will only be executed if --enable-modifiers switch is included in the command line.

version: 1.0
modifier: true
output_directory: /live_response/modifiers
artifacts:
  -
    description: List all PIDs with a directory in /proc but hidden for ps command.
    supported_os: [linux]
    collector: command
    foreach: for pid in /proc/[0-9]*; do echo ${pid} | sed -e 's:/proc/::'; done
    command: if ps ax | awk '{print $1}' | grep -q %line%; then true; else echo %line%; fi
    output_file: hidden_pids_for_ps_command.txt
  -
    description: Umount all bind mounted directories to /proc/PID.
    supported_os: [linux]
    collector: command
    foreach: mount | awk 'BEGIN { FS=" on "; } { print $2; }' | grep "/proc/[0-9]" | awk '{print $1}'
    command: umount "%line%"
    output_file: umount_%line%.txt

name_pattern

Optional for: file, find, hash and stat

Accepted values: array of paths

Return the full file path if one of the name_pattern values matches the file name. This option works the same way as find's -name option.

Since the leading directories are removed, the file names considered for a match with name_pattern will never include a slash, so "a/b" will never match anything.

Don't forget to enclose the pattern in double quotes. Use a backslash (\) to escape double quotes and commas.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all wtmp and utmp files.
    supported_os: [all]
    collector: find
    path: /var
    name_pattern: ["wtmp", "btmp"]
    output_file: wtmp_btmp.txt

As UAC uses find tool to search for artifacts, wildcards and regex patterns are also supported here.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all HTML and TXT files.
    supported_os: [all]
    collector: find
    path: /
    name_pattern: ["*.html", "*.txt"]
    output_file: all_html_txt.txt
version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all .log and .Log (capital L) files.
    supported_os: [all]
    collector: find
    path: /var/log
    name_pattern: ["*.[Ll]og"]
    output_file: all_log_files.txt

output_directory

Required by: command, find, hash and stat

Accepted values: path

Specify the directory within the output file where the collected data will be stored.

In the example below, ls_tmp.txt will stored in my_custom_artifacts directory within the output file.

version: 1.0
artifacts:
  -
    description: My first artifact.
    supported_os: [all]
    collector: command
    command: ls /tmp
    output_directory: /my_custom_artifacts
    output_file: ls_tmp.txt

Output file contents:

screenshot

The output_directory key-pair value can also be used as a global option, placed before the artifacts mapping. In this case, any rules that do not have a specified output_directory will use the global setting.

In the example below, ps.txt will be stored in live_response/process directory, but ps_auxwww.txt will be stored in my_global_dir directory.

version: 1.0
output_directory: /my_global_dir
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps
    output_directory: /live_response/process
    output_file: ps.txt
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps auxwww
    output_file: ps_auxwww.txt

output_file

Optional for: command, find, hash and stat

Accepted values: file name

Specify the output file name where the collected data will be stored.

version: 1.0
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps
    output_directory: /live_response/process
    output_file: ps.txt

If no output_file is specified, all data in the output_directory will be archived into the output file.

In the example below, avml.raw will be placed in the memory_dump directory.

version: 1.0
output_directory: /memory_dump
artifacts:
  -
    description: Capture a memory image.
    supported_os: [linux]
    collector: command
    command: avml avml.raw

UAC never overwrites output files; data is always appended.

In the example below, both ps and ps auxwww outputs will be stored in the same same_file.txt file.

version: 1.0
output_directory: /live_response/process
artifacts:
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps
    output_file: same_file.txt
  -
    description: Report a snapshot of the current processes.
    supported_os: [all]
    collector: command
    command: ps auxwww
    output_file: same_file.txt

path

Required by: find, file, hash and stat

Accepted values: path

The starting point from where the artifact will be searched for. UAC will recurse into subdirectories unless otherwise prevented by max_depth option.

As UAC uses find tool to search for artifacts, wildcards and regex patterns are also supported here.

Every artifact should be treated as if it originates from the / (root) mount point. The root mount point will be replaced by UAC at runtime if a mount point is defined with the --mount-point command-line option.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search all cmdline files within /proc/*/
    supported_os: [all]
    collector: find
    path: /proc/*/cmdline
    output_file: list_of_cmdline_files.txt

Remember to use quotation marks when specifying paths with spaces or special characters.

version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search for TCC.db file.
    supported_os: [all]
    collector: find
    path: /Library/"Application Support"/com.apple.TCC/TCC.db
    output_file: path_with_spaces.txt

path_pattern

Optional for: find, file, hash and stat

Accepted values: array of paths

Return the full file path if one of the path_pattern values matches the file path. This option works the same way as find's -path option.

Don't forget to enclose the pattern in double quotes. Use a backslash (\) to escape double quotes and commas.

As UAC uses find tool to search for artifacts, wildcards and regex patterns are also supported here.

The example below searches for Discord's Cache directory anywhere within the user's home directory. Hits would be as follows:

  • /home/user/.config/discord/Cache/00bcecbd2455cb22_0
  • /home/user/.var/app/com.discordapp.Discord/config/discord/Cache/index
  • /home/user/snap/discord/current/.config/discord/Cache/ac0fa118bdaaa62e_0
version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Find Discord cache files.
    supported_os: [all]
    collector: find
    path: /%user_home%
    path_pattern: ["*/discord/Cache/*"]
    output_file: discord_cache.txt

permissions

Optional for: find, file, hash and stat

Accepted values: array of permissions

Use this option to search for files and directories based on their permissions. This option works the same way as find's -perm option.

Please note that symbolic mode is not supported (e.g: -g=w).

Permissions can be used as follows:

  • File's permission bits are exactly mode (octal).
version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search files that have permissions set to 755 or 644.
    supported_os: [all]
    collector: find
    path: /
    file_type: f
    permissions: [755, 644]
    output_file: all_755_and_644_permissions.txt
  • All of the permission bits mode (octal) are set for the file.
version: 1.0
output_directory: /live_response/system
artifacts:
  -
    description: Search for files that have SUID bit set.
    supported_os: [all]
    collector: find
    path: /
    file_type: f
    permissions: [-4000]
    output_file: suid_files.txt

supported_os

Required

Accepted values: array of operating systems

List of operating systems that the artifact applies to. Use all whether the artifact applies to all operating systems.

The currently supported operating systems are (case sensitive):

Value Description
aix Artifact applies to AIX systems.
esxi Artifact applies to ESXi systems.
freebsd Artifact applies to FreeBSD systems.
linux Artifact applies to Linux systems.
macos Artifact applies to macOS systems.
netbsd Artifact applies to NetBSD systems.
netscaler Artifact applies to NetScaler systems.
openbsd Artifact applies to OpenBSD systems.
solaris Artifact applies to Solaris systems.

Examples:

Artifact applies to all supported operating systems:

version: 1.0
artifacts:
  -
    description: Artifact description.
    supported_os: [all]
    collector: hash
    ... # additional options depending on the collector

Artifact applies to Aix, FreeBSD and Solaris systems only:

version: 1.0
artifacts:
  -
    description: Artifact description.
    supported_os: [aix, freebsd, solaris]
    collector: stat
    ... # additional options depending on the collector

version

Required

The artifact file version. It needs to be updated every time the YAML file is changed.