Skip to content

Commit f06567c

Browse files
committed
feat: find collectors may include a command to use with xargs
"find" type collectors may now include an optional "command:". The full command line is appended to the constructed command as "... | xargs <commandline>". This allows piping the xargs output into other programs (see artifacts/system/immutable_files.yaml). Refactored artifacts/system/{getcap,immutable_files}.yaml to take advantage of this feature and benefit from the path and name filtering normally applied to other "find" type collectors.
1 parent d8704d2 commit f06567c

File tree

5 files changed

+41
-33
lines changed

5 files changed

+41
-33
lines changed

artifacts/system/getcap.yaml

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
version: 2.1
2-
condition: command_exists "getcap"
1+
version: 3.0
32
output_directory: /system
4-
# abuse process capabilities
5-
# ref: https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms
63
artifacts:
74
-
8-
description: List files that have process capabilities (no recursion, parent top-level directories only).
5+
description: List all files with Linux capabilities
96
supported_os: [linux]
10-
collector: command
11-
foreach: dirwalk.sh parents "%mount_point%" "/proc|/sys|%non_local_mount_points%"
12-
command: getcap "%line%"/*
13-
output_file: getcap.txt
14-
-
15-
description: List files that have process capabilities (recursion, children directories only).
16-
supported_os: [linux]
17-
collector: command
18-
foreach: dirwalk.sh children "%mount_point%" "/proc|/sys|%non_local_mount_points%"
19-
command: getcap -r "%line%"/*
7+
collector: find
8+
path: /
9+
file_type: [f]
10+
command: getcap
11+
exclude_file_system: [proc, procfs]
2012
output_file: getcap.txt
13+
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
version: 2.1
2-
condition: command_exists "lsattr"
1+
version: 3.0
32
output_directory: /system
43
artifacts:
54
-
6-
description: List immutable files (no recursion, parent top-level directories only).
5+
description: List all immutable files
76
supported_os: [linux]
8-
collector: command
9-
foreach: dirwalk.sh parents "%mount_point%" "/dev|/proc|/run|/sys|%non_local_mount_points%"
10-
command: lsattr "%line%" | awk '{if ($1 ~ /i/ && $1 !~ /^\\//) print $0}'
11-
output_file: immutable_files.txt
12-
-
13-
description: List immutable files (recursion, children directories only).
14-
supported_os: [linux]
15-
collector: command
16-
foreach: dirwalk.sh children "%mount_point%" "/dev|/proc|/run|/sys|%non_local_mount_points%"
17-
command: lsattr -R "%line%" | awk '{if ($1 ~ /i/ && $1 !~ /^\\//) print $0}'
7+
collector: find
8+
path: /
9+
file_type: [f]
10+
command: lsattr | awk '$1 ~ /i/ && $1 !~ /^\\//'
11+
exclude_file_system: [proc, procfs, squashfs]
1812
output_file: immutable_files.txt
13+

lib/find_based_collector.sh

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# boolean no_group: no group corresponds to file's numeric group ID (optional)
2222
# boolean no_user: No user corresponds to file's numeric user ID (optional)
2323
# boolean ignore_date_range: ignore date range (optional) (default: false)
24+
# string command: command passed to xargs to execute on find output
2425
# string output_directory: full path to the output directory
2526
# string output_file: output file name
2627
# Returns:
@@ -62,6 +63,8 @@ _find_based_collector()
6263
shift
6364
__fc_ignore_date_range="${1:-false}"
6465
shift
66+
__fc_command_xargs_pipe="${1:-}"
67+
shift
6568
__fc_output_directory="${1:-}"
6669
shift
6770
__fc_output_file="${1:-}"
@@ -149,6 +152,8 @@ _find_based_collector()
149152
if ${__fc_is_file_list}; then
150153
__fc_find_command="cat \"${__fc_path}\""
151154
else
155+
[ -n "${__fc_command_xargs_pipe}" ] && __fc_print0="true" || __fc_print0="false"
156+
152157
__fc_find_command=`_build_find_command \
153158
"${__fc_path}" \
154159
"${__fc_path_pattern}" \
@@ -162,13 +167,20 @@ _find_based_collector()
162167
"${__fc_permissions}" \
163168
"${__fc_no_group}" \
164169
"${__fc_no_user}" \
165-
"" \
170+
"${__fc_print0}" \
166171
"${__fc_start_date_days}" \
167172
"${__fc_end_date_days}"`
168173
fi
174+
if [ "${__fc_collector}" = "find" ] && [ -n "${__fc_command_xargs_pipe}" ]; then
175+
if ${__UAC_TOOL_FIND_PRINT0_SUPPORT} && ${__UAC_TOOL_XARGS_NULL_DELIMITER_SUPPORT}; then
176+
__fc_find_command="${__fc_find_command} | xargs -0 ${__fc_command_xargs_pipe}"
177+
else
178+
__fc_find_command="${__fc_find_command} | xargs ${__fc_command_xargs_pipe}"
179+
fi
180+
fi
169181
_verbose_msg "${__UAC_VERBOSE_CMD_PREFIX}${__fc_find_command}"
170182
_run_command "${__fc_find_command}" \
171-
>>"${__fc_output_directory}/${__fc_output_file}"
183+
>>"${__fc_output_directory}/${__fc_output_file}"
172184
;;
173185
"hash")
174186
for __fc_algorithm in `echo "${__UAC_CONF_HASH_ALGORITHM}" | sed -e 's:|: :g'`; do

lib/parse_artifact.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ _parse_artifact()
362362
"${__pa_no_group}" \
363363
"${__pa_no_user}" \
364364
"${__pa_ignore_date_range}" \
365+
"" \
365366
"${__UAC_TEMP_DATA_DIR}" \
366367
"file_collector.tmp"
367368
elif [ "${__pa_collector}" = "find" ]; then
@@ -382,6 +383,7 @@ _parse_artifact()
382383
"${__pa_no_group}" \
383384
"${__pa_no_user}" \
384385
"${__pa_ignore_date_range}" \
386+
"${__pa_command}" \
385387
"${__pa_new_output_directory}" \
386388
"${__pa_new_output_file}"
387389
elif [ "${__pa_collector}" = "hash" ]; then
@@ -402,6 +404,7 @@ _parse_artifact()
402404
"${__pa_no_group}" \
403405
"${__pa_no_user}" \
404406
"${__pa_ignore_date_range}" \
407+
"" \
405408
"${__pa_new_output_directory}" \
406409
"${__pa_new_output_file}"
407410
elif [ "${__pa_collector}" = "stat" ]; then
@@ -422,6 +425,7 @@ _parse_artifact()
422425
"${__pa_no_group}" \
423426
"${__pa_no_user}" \
424427
"${__pa_ignore_date_range}" \
428+
"" \
425429
"${__pa_new_output_directory}" \
426430
"${__pa_new_output_file}"
427431
fi
@@ -453,6 +457,7 @@ _parse_artifact()
453457
"${__pa_no_group}" \
454458
"${__pa_no_user}" \
455459
"${__pa_ignore_date_range}" \
460+
"" \
456461
"${__UAC_TEMP_DATA_DIR}" \
457462
"file_collector.tmp"
458463
elif [ "${__pa_collector}" = "find" ]; then
@@ -473,6 +478,7 @@ _parse_artifact()
473478
"${__pa_no_group}" \
474479
"${__pa_no_user}" \
475480
"${__pa_ignore_date_range}" \
481+
"${__pa_command}" \
476482
"${__pa_output_directory}" \
477483
"${__pa_output_file}"
478484
elif [ "${__pa_collector}" = "hash" ]; then
@@ -493,6 +499,7 @@ _parse_artifact()
493499
"${__pa_no_group}" \
494500
"${__pa_no_user}" \
495501
"${__pa_ignore_date_range}" \
502+
"" \
496503
"${__pa_output_directory}" \
497504
"${__pa_output_file}"
498505
elif [ "${__pa_collector}" = "stat" ]; then
@@ -513,6 +520,7 @@ _parse_artifact()
513520
"${__pa_no_group}" \
514521
"${__pa_no_user}" \
515522
"${__pa_ignore_date_range}" \
523+
"" \
516524
"${__pa_output_directory}" \
517525
"${__pa_output_file}"
518526
fi
@@ -523,4 +531,4 @@ _parse_artifact()
523531
esac
524532
done
525533

526-
}
534+
}

lib/validate_artifact.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ _validate_artifact()
503503
_error_msg "Missing required field: 'path' is not set for '${__va_collector}' collector."
504504
return 1
505505
fi
506-
if [ -n "${__va_command}" ]; then
506+
if [ -n "${__va_command}" ] && [ "${__va_collector}" != "find" ]; then
507507
_error_msg "Invalid field: 'command' is not applicable for the '${__va_collector}' collector."
508508
return 1
509509
fi
@@ -566,4 +566,4 @@ _validate_artifact()
566566
esac
567567

568568
done
569-
}
569+
}

0 commit comments

Comments
 (0)