diff --git a/CHANGELOG.md b/CHANGELOG.md index 879fa73f..53146d31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,40 @@ # Changelog -## 2.7.0 (2023-09-20) +## 2.8.0 (2024-01-22) + +### Features + +- --debug option now does not remove the uac-data.tmp directory created in the destination directory. This is the location where temporary and debugging data is stored during execution. ### Artifacts -- files/applications/findmy.yaml: Added the collection of the list of user's items/devices and items/devices info registered within the Find My application [macos]. -- files/applications/rclone.yaml: Added the collection of rclone application configuration and log files [freebsd, linux, macos, netbsd, openbsd, solaris]. -- files/applications/rustdesk.yaml: Added the collection of RustDesk application access logs and screen recording files [linux, macos]. -- files/applications/splashtop.yaml: Added the collection of Splashtop application artifacts [linux, macos]. -- files/applications/steam.yaml: Added the collection of Steam browser artifacts, avatar pictures, configuration and log files [linux, macos]. -- files/applications/teamviewer.yaml: Added the collection of TeamViewer application artifacts [linux, macos]. -- files/applications/thinlinc.yaml: Added the collection of ThinLinc application configuration files, connections and post-session logs [linux, macos]. -- files/package/installed_applications: Added the collection of Info.plist from installed applications [macos]. -- files/system/netscaler.yaml: Added the collection of '/var/vpn', '/var/netscaler/logon', and '/netscaler/ns_gui' system files and directories [netscaler]. -- files/system/nsconfig.yaml: Deprecated. All artifacts were moved to 'files/system/netscaler.yaml' [netscaler]. -- live_response/storage/mdadm.yaml: Added the collection of information on Linux software RAID [linux]. -- live_response/storage/zpool.yaml: Added the collection of the command history of all pools [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris]. +- files/applications/box_drive.yaml: Renamed to box.yaml. +- files/applications/box.yaml: Added collection support for Box log files [macos]. +- files/applications/wget.yaml: Added collection support for wget hsts file. This file is used to store the HSTS cache for the wget utility [aix, esxi, freebsd, linux, macos, netbsd, openbsd, solaris] (by [firexfly](https://github.com/firexfly)). +- files/browsers/brave.yaml: Updated collection support for Flatpak version [linux]. +- files/browsers/chrome.yaml: Updated collection support for Flatpak version [linux]. +- files/browsers/edge.yaml: Updated collection support for Flatpak version [linux]. +- files/browsers/opera.yaml: Updated collection support for Flatpak version [linux]. +- files/browsers/vivaldi.yaml: Updated collection support for Flatpak version [linux]. +- files/packages/pkg_contents.yaml: Added collection support for package table of contents files [openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- files/system/desktop.yaml: Added collection support for GUI shortcut files (.desktop) of users [freebsd, linux, netbsd, openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- files/system/etc.yaml: Added "master.passwd" and "spwd.db" to the exclude_name_pattern list as they contain the hashed passwords of local users [freebsd, netbsd, netscaler, openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- files/system/etc.yaml: Added exclusion for the group shadow files 'gshadow' and 'gshadow-'. Those files contain password hashes for groups [linux] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- files/system/xsession_errors.yaml: Updated collection support for OpenBSD systems [openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- live_response/network/ndp.yaml: Added collection support for kernel's IPv6 network neighbor cache [freebsd, netbsd, openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). +- live_response/network/nft.yaml: Added collection support for complete nftables ruleset [linux] (by [sanderu](https://github.com/sanderu)). +- live_response/network/ss.yaml: Updated collection support for processes listening on UDP ports/sockets [android, linux]. +- live_response/vms/vmctl.yaml: Added collection support for information about running virtual machines on the OpenBSD using the native virtualization system [openbsd] (by [Herbert-Karl](https://github.com/Herbert-Karl)). + +### Fixes + +- Offline disk image mount point path was part of the file structure in [root] (by [maxspl](https://github.com/maxspl)). +- Collected data was not being properly archived by tar in AIX systems. + +### Profiles + +- profiles/offline.yaml: New 'offline' profile that can be used during offline collections (by [randomaccess3](https://github.com/randomaccess3)). ### Tools -- AVML updated to v0.12.0. \ No newline at end of file +- statx source code was moved to a dedicated repository at https://github.com/tclahr/statx diff --git a/LICENSES.md b/LICENSES.md new file mode 100644 index 00000000..89879f52 --- /dev/null +++ b/LICENSES.md @@ -0,0 +1,7 @@ +Use of the following Third-Party Software is subject to the license agreements at the URLs listed in the table below. + +|Product|Copyright|URL| +|---|---|---| +|AVML|Use rights in accordance with the information displayed at: https://github.com/microsoft/avml/blob/main/LICENSE|https://github.com/microsoft/avml| +|linux_procmemdump.sh|Use rights in accordance with the information displayed at: https://creativecommons.org/licenses/by-sa/4.0|| +|statx|Use rights in accordance with the information displayed at: https://github.com/tclahr/statx/blob/main/LICENSE|https://github.com/tclahr/statx| diff --git a/README.md b/README.md index ab448bd9..531d2dd5 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,15 @@ Project documentation page: [https://tclahr.github.io/uac-docs](https://tclahr.g ## 🌟 Main Features -- Runs everywhere with no dependencies (no installation required). +- Run everywhere with no dependencies (no installation required). - Customizable and extensible collections and artifacts. -- Respects the order of volatility during artifacts collection. -- Collects information from processes running without a binary on disk. -- Hashes running processes and executable files. -- Extracts information from files and directories to create a bodyfile (including enhanced file attributes for ext4). -- Collects user and system configuration files and logs. -- Collects artifacts from applications. -- Acquires volatile memory from Linux systems using different methods and tools. +- Respect the order of volatility during artifact collection. +- Collect information from processes running without a binary on disk. +- Hash running processes and executable files. +- Extract information from files and directories to create a bodyfile (including enhanced file attributes for ext4). +- Collect user and system configuration files and logs. +- Collect artifacts from applications. +- Acquire volatile memory from Linux systems using different methods and tools. *** @@ -80,7 +80,7 @@ Common usage scenarios may include the following: ./uac -a live_response/\*,bodyfile/bodyfile.yaml . ``` -**Collect all artifacts based on the ```full``` profile, but excludes the ```bodyfile/bodyfile.yaml``` artifact, and create the output file in ```/tmp```.** +**Collect all artifacts based on the ```full``` profile, but exclude the ```bodyfile/bodyfile.yaml``` artifact, and create the output file in ```/tmp```.** ```shell ./uac -p full -a \!bodyfile/bodyfile.yaml /tmp diff --git a/artifacts/files/applications/box.yaml b/artifacts/files/applications/box.yaml new file mode 100644 index 00000000..bcd3b29e --- /dev/null +++ b/artifacts/files/applications/box.yaml @@ -0,0 +1,26 @@ +version: 2.0 +artifacts: + - + description: Collect Box configuration and sqlite database files. + supported_os: [macos] + collector: file + path: /Library/"Application Support"/Box/Box/data + exclude_nologin_users: true + - + description: Collect Box configuration and sqlite database files. + supported_os: [macos] + collector: file + path: /%user_home%/Library/"Application Support"/Box/Box/data + exclude_nologin_users: true + - + description: Collect Box log files. + supported_os: [macos] + collector: file + path: /Library/Logs/Box/Box + - + description: Collect Box log files. + supported_os: [macos] + collector: file + path: /%user_home%/Library/Logs/Box/Box + exclude_nologin_users: true + \ No newline at end of file diff --git a/artifacts/files/applications/box_drive.yaml b/artifacts/files/applications/box_drive.yaml deleted file mode 100644 index 63cb7d4f..00000000 --- a/artifacts/files/applications/box_drive.yaml +++ /dev/null @@ -1,9 +0,0 @@ -version: 1.0 -artifacts: - - - description: Collect Box Drive configuration and sqlite database files. - supported_os: [macos] - collector: file - path: /%user_home%/Library/"Application Support"/Box/Box/data - exclude_nologin_users: true - \ No newline at end of file diff --git a/artifacts/files/applications/wget.yaml b/artifacts/files/applications/wget.yaml new file mode 100644 index 00000000..18447a80 --- /dev/null +++ b/artifacts/files/applications/wget.yaml @@ -0,0 +1,8 @@ +version: 1.0 +artifacts: + - + description: Collect wget hsts file. This file is used to store the HSTS cache for the wget utility. + supported_os: [aix, esxi, freebsd, linux, macos, netbsd, openbsd, solaris] + collector: file + path: /%user_home%/.wget-hsts + exclude_nologin_users: true diff --git a/artifacts/files/browsers/brave.yaml b/artifacts/files/browsers/brave.yaml index a252ab67..de88a52b 100644 --- a/artifacts/files/browsers/brave.yaml +++ b/artifacts/files/browsers/brave.yaml @@ -1,4 +1,4 @@ -version: 2.0 +version: 3.0 artifacts: - description: Collect Brave browser files. @@ -17,6 +17,23 @@ artifacts: file_type: d ignore_date_range: true exclude_nologin_users: true + - + description: Collect Brave browser files (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.brave.Browser + name_pattern: ["Bookmarks*", "Cookies*", "DownloadMetadata", "Extension Cookies*", "Favicons*", "History*", "Login Data*", "Media History*", "Network Action Predictor*", "Network Persistent State", "Preferences", "QuotaManager*", "Reporting and NEL*", "SecurePreferences", "Shortcuts*", "SyncData.sqlite3", "Top Sites*", "Trust Tokens*", "Visited Links", "Web Data*"] + ignore_date_range: true + exclude_nologin_users: true + - + description: Collect Brave browser directories (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.brave.Browser + name_pattern: ["Extensions", "File System", "Sessions"] + file_type: d + ignore_date_range: true + exclude_nologin_users: true - description: Collect Brave browser files (Snap version). supported_os: [linux] diff --git a/artifacts/files/browsers/chrome.yaml b/artifacts/files/browsers/chrome.yaml index dafe0741..e4db2ce2 100644 --- a/artifacts/files/browsers/chrome.yaml +++ b/artifacts/files/browsers/chrome.yaml @@ -1,4 +1,4 @@ -version: 2.0 +version: 3.0 artifacts: - description: Collect Chrome browser files. @@ -17,6 +17,23 @@ artifacts: file_type: d ignore_date_range: true exclude_nologin_users: true + - + description: Collect Chrome browser files (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.google.Chrome + name_pattern: ["Bookmarks*", "Cookies*", "DownloadMetadata", "Extension Cookies*", "Favicons*", "History*", "Login Data*", "Media History*", "Network Action Predictor*", "Network Persistent State", "Preferences", "QuotaManager*", "Reporting and NEL*", "SecurePreferences", "Shortcuts*", "SyncData.sqlite3", "Top Sites*", "Trust Tokens*", "Visited Links", "Web Data*"] + ignore_date_range: true + exclude_nologin_users: true + - + description: Collect Chrome browser directories (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.google.Chrome + name_pattern: ["Extensions", "File System", "Sessions"] + file_type: d + ignore_date_range: true + exclude_nologin_users: true - description: Collect Chrome browser files. supported_os: [macos] diff --git a/artifacts/files/browsers/edge.yaml b/artifacts/files/browsers/edge.yaml index 5e734227..0c7f9719 100644 --- a/artifacts/files/browsers/edge.yaml +++ b/artifacts/files/browsers/edge.yaml @@ -1,4 +1,4 @@ -version: 2.0 +version: 3.0 artifacts: - description: Collect Edge browser files. @@ -17,6 +17,23 @@ artifacts: file_type: d ignore_date_range: true exclude_nologin_users: true + - + description: Collect Edge browser files (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.microsoft.Edge + name_pattern: ["Bookmarks*", "Cookies*", "DownloadMetadata", "Extension Cookies*", "Favicons*", "History*", "Login Data*", "Media History*", "Network Action Predictor*", "Network Persistent State", "Preferences", "QuotaManager*", "Reporting and NEL*", "SecurePreferences", "Shortcuts*", "SyncData.sqlite3", "Top Sites*", "Trust Tokens*", "Visited Links", "Web Data*"] + ignore_date_range: true + exclude_nologin_users: true + - + description: Collect Edge browser directories (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.microsoft.Edge + name_pattern: ["Extensions", "File System", "Sessions"] + file_type: d + ignore_date_range: true + exclude_nologin_users: true - description: Collect Edge browser files. supported_os: [macos] diff --git a/artifacts/files/browsers/opera.yaml b/artifacts/files/browsers/opera.yaml index 5a288fd7..c46abdc4 100644 --- a/artifacts/files/browsers/opera.yaml +++ b/artifacts/files/browsers/opera.yaml @@ -1,4 +1,4 @@ -version: 2.0 +version: 3.0 artifacts: - description: Collect Opera browser files. @@ -17,6 +17,23 @@ artifacts: file_type: d ignore_date_range: true exclude_nologin_users: true + - + description: Collect Opera browser files (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.opera.Opera + name_pattern: ["Bookmarks*", "Cookies*", "DownloadMetadata", "Extension Cookies*", "Favicons*", "History*", "Login Data*", "Media History*", "Network Action Predictor*", "Network Persistent State", "Preferences", "QuotaManager*", "Reporting and NEL*", "SecurePreferences", "Shortcuts*", "SyncData.sqlite3", "Top Sites*", "Trust Tokens*", "Visited Links", "Web Data*"] + ignore_date_range: true + exclude_nologin_users: true + - + description: Collect Opera browser directories (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.opera.Opera + name_pattern: ["Extensions", "File System", "Sessions"] + file_type: d + ignore_date_range: true + exclude_nologin_users: true - description: Collect Opera browser files (Snap version). supported_os: [linux] diff --git a/artifacts/files/browsers/vivaldi.yaml b/artifacts/files/browsers/vivaldi.yaml index a35aafe9..a5ad0a24 100644 --- a/artifacts/files/browsers/vivaldi.yaml +++ b/artifacts/files/browsers/vivaldi.yaml @@ -1,4 +1,4 @@ -version: 2.0 +version: 3.0 artifacts: - description: Collect Vivaldi browser files. @@ -17,6 +17,23 @@ artifacts: file_type: d ignore_date_range: true exclude_nologin_users: true + - + description: Collect Vivaldi browser files (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.vivaldi.Vivaldi + name_pattern: ["Bookmarks*", "Cookies*", "DownloadMetadata", "Extension Cookies*", "Favicons*", "History*", "Login Data*", "Media History*", "Network Action Predictor*", "Network Persistent State", "Preferences", "QuotaManager*", "Reporting and NEL*", "SecurePreferences", "Shortcuts*", "SyncData.sqlite3", "Top Sites*", "Trust Tokens*", "Visited Links", "Web Data*"] + ignore_date_range: true + exclude_nologin_users: true + - + description: Collect Vivaldi browser directories (Flatpak version). + supported_os: [linux] + collector: file + path: /%user_home%/.var/app/com.vivaldi.Vivaldi + name_pattern: ["Extensions", "File System", "Sessions"] + file_type: d + ignore_date_range: true + exclude_nologin_users: true - description: Collect Vivaldi browser files. supported_os: [macos] diff --git a/artifacts/files/logs/apache.yaml b/artifacts/files/logs/apache.yaml new file mode 100644 index 00000000..0d12b434 --- /dev/null +++ b/artifacts/files/logs/apache.yaml @@ -0,0 +1,27 @@ +version: 1.0 +artifacts: + - + description: Collect Apache logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log + name_pattern: ["access_log*", "access.log*", "error_log*", "error.log*"] + max_file_size: 1073741824 # 1GB + - + description: Collect Apache logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log/apache + max_file_size: 1073741824 # 1GB + - + description: Collect Apache logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log/apache2 + max_file_size: 1073741824 # 1GB + - + description: Collect Apache logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log/httpd + max_file_size: 1073741824 # 1GB diff --git a/artifacts/files/logs/nginx.yaml b/artifacts/files/logs/nginx.yaml new file mode 100644 index 00000000..899ec22c --- /dev/null +++ b/artifacts/files/logs/nginx.yaml @@ -0,0 +1,16 @@ +version: 1.0 +artifacts: + - + description: Collect nginx logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log + name_pattern: ["*access_log*", "*access.log*", "*error_log*", "*error.log*"] + max_file_size: 1073741824 # 1GB + - + description: Collect nginx logs. + supported_os: [aix, freebsd, linux, macos, netbsd, netscaler, openbsd, solaris] + collector: file + path: /var/log/nginx + max_file_size: 1073741824 # 1GB + diff --git a/artifacts/files/packages/pkg_contents.yaml b/artifacts/files/packages/pkg_contents.yaml new file mode 100644 index 00000000..7ac6cbaa --- /dev/null +++ b/artifacts/files/packages/pkg_contents.yaml @@ -0,0 +1,8 @@ +version: 1.0 +artifacts: + - + description: Collect package table of contents files. + supported_os: [openbsd] + collector: file + path: /var/db/pkg + path_pattern: ["*/+CONTENTS"] diff --git a/artifacts/files/system/desktop.yaml b/artifacts/files/system/desktop.yaml new file mode 100644 index 00000000..47999c78 --- /dev/null +++ b/artifacts/files/system/desktop.yaml @@ -0,0 +1,11 @@ +version: 1.0 +artifacts: + - + description: Collect GUI shortcut files of users. + supported_os: [freebsd, linux, netbsd, openbsd] + collector: file + path: /%user_home% + max_depth: 6 + name_pattern: ["*.desktop"] + ignore_date_range: true + exclude_nologin_users: true diff --git a/artifacts/files/system/etc.yaml b/artifacts/files/system/etc.yaml index 8eed0499..f55e1caf 100644 --- a/artifacts/files/system/etc.yaml +++ b/artifacts/files/system/etc.yaml @@ -5,7 +5,7 @@ artifacts: supported_os: [aix, android, esxi, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: file path: /etc - exclude_name_pattern: ["shadow", "shadow-"] + exclude_name_pattern: ["shadow", "shadow-", "master.passwd", "spwd.db", "gshadow", "gshadow-"] ignore_date_range: true - description: Collect system configuration files. diff --git a/artifacts/files/system/xsession_errors.yaml b/artifacts/files/system/xsession_errors.yaml index 02d6504f..07d36f27 100644 --- a/artifacts/files/system/xsession_errors.yaml +++ b/artifacts/files/system/xsession_errors.yaml @@ -2,8 +2,8 @@ version: 1.0 artifacts: - description: Collect xsession errors file. This is the error log produced by X window system. - supported_os: [linux] + supported_os: [linux, openbsd] collector: file path: /%user_home%/.xsession-errors exclude_nologin_users: true - \ No newline at end of file + diff --git a/artifacts/live_response/network/ndp.yaml b/artifacts/live_response/network/ndp.yaml new file mode 100644 index 00000000..d7378459 --- /dev/null +++ b/artifacts/live_response/network/ndp.yaml @@ -0,0 +1,8 @@ +version: 1.0 +artifacts: + - + description: Collect the kernel's IPv6 network neighbour cache. + supported_os: [freebsd, netbsd, openbsd] + collector: command + command: ndp -a + output_file: ndp_-a.txt diff --git a/artifacts/live_response/network/netstat.yaml b/artifacts/live_response/network/netstat.yaml index 66d7760e..f70fc35e 100644 --- a/artifacts/live_response/network/netstat.yaml +++ b/artifacts/live_response/network/netstat.yaml @@ -2,31 +2,31 @@ version: 2.0 artifacts: - description: Collect both listening and non-listening (for TCP this means established connections) sockets. - supported_os: [android, aix, freebsd, linux, openbsd, netbsd, netscaler, openbsd, solaris] + supported_os: [android, aix, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: command command: netstat -a output_file: netstat_-a.txt - description: Collect both listening and non-listening (for TCP this means established connections) sockets with numerical addresses instead of trying to determine symbolic host, port or user names. - supported_os: [android, aix, freebsd, linux, openbsd, netbsd, netscaler, openbsd, solaris] + supported_os: [android, aix, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: command command: netstat -an output_file: netstat_-an.txt - description: Collect a table of all network interfaces. - supported_os: [android, aix, freebsd, linux, openbsd, netbsd, netscaler, openbsd, solaris] + supported_os: [android, aix, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: command command: netstat -i output_file: netstat_-i.txt - description: Collect the kernel routing tables. - supported_os: [android, aix, freebsd, linux, openbsd, netbsd, netscaler, openbsd, solaris] + supported_os: [android, aix, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: command command: netstat -r output_file: netstat_-r.txt - description: Collect the kernel routing tables with numerical addresses instead of trying to determine symbolic host, port or user names. - supported_os: [android, aix, freebsd, linux, openbsd, netbsd, netscaler, openbsd, solaris] + supported_os: [android, aix, freebsd, linux, netbsd, netscaler, openbsd, solaris] collector: command command: netstat -rn output_file: netstat_-rn.txt @@ -59,4 +59,4 @@ artifacts: supported_os: [android, linux] collector: command command: netstat -lpeanut - output_file: netstat_-lpeanut.txt \ No newline at end of file + output_file: netstat_-lpeanut.txt diff --git a/artifacts/live_response/network/nft.yaml b/artifacts/live_response/network/nft.yaml new file mode 100644 index 00000000..31fe1c0b --- /dev/null +++ b/artifacts/live_response/network/nft.yaml @@ -0,0 +1,8 @@ +version: 1.0 +artifacts: + - + description: Collect complete nftables ruleset. + supported_os: [linux] + collector: command + command: nft list ruleset + output_file: nft_list_ruleset.txt diff --git a/artifacts/live_response/network/ss.yaml b/artifacts/live_response/network/ss.yaml index c78d1002..40297214 100644 --- a/artifacts/live_response/network/ss.yaml +++ b/artifacts/live_response/network/ss.yaml @@ -1,4 +1,4 @@ -version: 1.0 +version: 2.0 artifacts: - description: Display both listening and non-listening (for TCP this means established connections) sockets with numerical addresses instead of trying to determine symbolic host, port or user names, and show the PID and name of the program to which each socket belongs. @@ -12,6 +12,12 @@ artifacts: collector: command command: ss -ap output_file: ss_-ap.txt + - + description: Display both listening and non-listening TCP sockets only with numerical addresses instead of trying to determine symbolic host, and show the PID of the program to which socket belongs. + supported_os: [android, linux] + collector: command + command: ss -tanp + output_file: ss_-tanp.txt - description: Display both listening and non-listening TCP sockets only, and show the PID of the program to which socket belongs. supported_os: [android, linux] @@ -19,11 +25,17 @@ artifacts: command: ss -tap output_file: ss_-tap.txt - - description: Display both listening and non-listening TCP sockets only with numerical addresses instead of trying to determine symbolic host, and show the PID of the program to which socket belongs. + description: Display both listening and non-listening UDP sockets only with numerical addresses instead of trying to determine symbolic host, and show the PID of the program to which socket belongs. supported_os: [android, linux] collector: command - command: ss -tanp - output_file: ss_-tanp.txt + command: ss -uanp + output_file: ss_-uanp.txt + - + description: Display both listening and non-listening UDP sockets only, and show the PID of the program to which socket belongs. + supported_os: [android, linux] + collector: command + command: ss -uap + output_file: ss_-uap.txt - description: Display listening TCP sockets only, and show the PID of the program to which socket belongs. supported_os: [android, linux] @@ -35,4 +47,16 @@ artifacts: supported_os: [android, linux] collector: command command: ss -tlnp - output_file: ss_-tlnp.txt \ No newline at end of file + output_file: ss_-tlnp.txt + - + description: Display listening UDP sockets only, and show the PID of the program to which socket belongs. + supported_os: [android, linux] + collector: command + command: ss -ulp + output_file: ss_-ulp.txt + - + description: Display listening UDP sockets only with numerical addresses instead of trying to determine symbolic host, and show the PID of the program to which socket belongs. + supported_os: [android, linux] + collector: command + command: ss -ulnp + output_file: ss_-ulnp.txt \ No newline at end of file diff --git a/artifacts/live_response/process/hash_running_processes.yaml b/artifacts/live_response/process/hash_running_processes.yaml index 5381f37a..dc7622e7 100644 --- a/artifacts/live_response/process/hash_running_processes.yaml +++ b/artifacts/live_response/process/hash_running_processes.yaml @@ -32,7 +32,7 @@ artifacts: output_file: hash_running_processes_full_paths.txt - description: Collect running processes executable path. - supported_os: [exsi] + supported_os: [esxi] collector: command command: ps -c | awk '{print $4}' | sort -u | grep "^/" output_file: hash_running_processes_full_paths.txt diff --git a/artifacts/live_response/vms/vmctl.yaml b/artifacts/live_response/vms/vmctl.yaml new file mode 100644 index 00000000..e8548101 --- /dev/null +++ b/artifacts/live_response/vms/vmctl.yaml @@ -0,0 +1,9 @@ +version: 1.0 +artifacts: + - + description: List running virtual machines on this system. + supported_os: [openbsd] + collector: command + command: vmctl status + output_file: vmctl_status.txt + diff --git a/lib/check_available_system_tools.sh b/lib/check_available_system_tools.sh index bd673308..0b0e0047 100644 --- a/lib/check_available_system_tools.sh +++ b/lib/check_available_system_tools.sh @@ -10,11 +10,12 @@ # OPERATING_SYSTEM # UAC_DIR # Requires: -# None +# command_exists # Arguments: # None # Outputs: # Set the value for the following global vars: +# CURL_TOOL_AVAILABLE # FIND_ATIME_SUPPORT # FIND_CTIME_SUPPORT # FIND_MAXDEPTH_SUPPORT @@ -32,14 +33,14 @@ # STATX_TOOL_AVAILABLE # STAT_BTIME_SUPPORT # STAT_TOOL_AVAILABLE -# TAR_TOOL_AVAILABLE # XARGS_REPLACE_STRING_SUPPORT +# ZIP_TOOL_AVAILABLE # Exit Status: # Last command exit status code. ############################################################################### check_available_system_tools() { - + CURL_TOOL_AVAILABLE=false FIND_ATIME_SUPPORT=false FIND_CTIME_SUPPORT=false FIND_MAXDEPTH_SUPPORT=false @@ -58,29 +59,56 @@ check_available_system_tools() STATX_TOOL_AVAILABLE=false STAT_BTIME_SUPPORT=false STAT_TOOL_AVAILABLE=false - TAR_TOOL_AVAILABLE=false XARGS_REPLACE_STRING_SUPPORT=false - - # each command needs to be tested individually as some systems do not have - # 'type' or 'which' tool + ZIP_TOOL_AVAILABLE=false # check if 'gzip' tool is available - if eval "echo \"uac\" | gzip"; then + if command_exists "gzip"; then GZIP_TOOL_AVAILABLE=true fi # check if 'perl' is available - if eval "perl -e 'print \"uac\"'"; then + if command_exists "perl"; then PERL_TOOL_AVAILABLE=true fi # check if 'procstat' is available - if eval "procstat $$"; then + if command_exists "procstat"; then PROCSTAT_TOOL_AVAILABLE=true fi + # check if 'curl' is available + if command_exists "curl"; then + CURL_TOOL_AVAILABLE=true + fi + + # check if 'zip' is available + if command_exists "zip"; then + ZIP_TOOL_AVAILABLE=true + elif [ "${OPERATING_SYSTEM}" = "esxi" ] \ + || [ "${OPERATING_SYSTEM}" = "linux" ]; then + for ca_directory in "${UAC_DIR}"/tools/zip/linux/*; do + if "${ca_directory}/zip" - "${UAC_DIR}/uac" >/dev/null 2>/dev/null; then + PATH="${ca_directory}:${PATH}" + export PATH + ZIP_TOOL_AVAILABLE=true + break + fi + done + elif [ "${OPERATING_SYSTEM}" = "freebsd" ] \ + || [ "${OPERATING_SYSTEM}" = "netscaler" ]; then + for ca_directory in "${UAC_DIR}"/tools/zip/freebsd/*; do + if "${ca_directory}/zip" - "${UAC_DIR}/uac" >/dev/null 2>/dev/null; then + PATH="${ca_directory}:${PATH}" + export PATH + ZIP_TOOL_AVAILABLE=true + break + fi + done + fi + # check if 'stat' is available - if eval "stat \"${MOUNT_POINT}\""; then + if command_exists "stat"; then STAT_TOOL_AVAILABLE=true # check if birth time is collected by 'stat' case "${OPERATING_SYSTEM}" in @@ -99,59 +127,57 @@ check_available_system_tools() esac fi - # check if 'statx' is available for the current system architecture - if [ "${OPERATING_SYSTEM}" = "esxi" ] \ - || [ "${OPERATING_SYSTEM}" = "linux" ]; then - ca_arch="" - case "${SYSTEM_ARCH}" in - armv5*|armv6*|armv7*) - ca_arch="arm" - ;; - aarch64*|armv8*) - ca_arch="arm64" - ;; - "i386"|"i686") - ca_arch="i686" - ;; - "mips") - ca_arch="mips" - ;; - "mips64") - ca_arch="mips64" - ;; - "ppc") - ca_arch="ppc" - ;; - "ppc64") - ca_arch="ppc64" - ;; - "ppc64le") - ca_arch="ppc64le" - ;; - s390*) - ca_arch="s390" - ;; - sparc*) - ca_arch="sparc" - ;; - "x86_64") - ca_arch="x86_64" - ;; - esac - if [ -n "${ca_arch}" ] \ - && eval "\"${UAC_DIR}/tools/statx/bin/linux/${ca_arch}/statx\" \ - \"${MOUNT_POINT}\""; then - PATH="${UAC_DIR}/tools/statx/bin/linux/${ca_arch}:${PATH}" + if ${STAT_BTIME_SUPPORT}; then + true + else + # check if 'statx' is available for the current system architecture + if [ "${OPERATING_SYSTEM}" = "esxi" ] \ + || [ "${OPERATING_SYSTEM}" = "linux" ]; then + ca_arch="" + case "${SYSTEM_ARCH}" in + armv[34567]*) + ca_arch="arm" + ;; + aarch64*|armv[89]*) + ca_arch="arm64" + ;; + "i486"|"i586"|"i686"|pentium*|athlon*) + ca_arch="i386" + ;; + "mips") + ca_arch="mips" + ;; + "mips64") + ca_arch="mips64" + ;; + "ppc") + ca_arch="ppc" + ;; + "ppc64") + ca_arch="ppc64" + ;; + "ppc64le") + ca_arch="ppc64le" + ;; + s390*) + ca_arch="s390" + ;; + sparc*) + ca_arch="sparc64" + ;; + *) + ca_arch="x86_64" + ;; + esac + if [ -n "${ca_arch}" ] \ + && eval "\"${UAC_DIR}/tools/statx/linux/${ca_arch}/statx\" \"${MOUNT_POINT}\""; then + PATH="${UAC_DIR}/tools/statx/linux/${ca_arch}:${PATH}" export PATH STATX_TOOL_AVAILABLE=true + fi fi fi - # check if 'tar' tool is available - if eval "tar -cf - \"${UAC_DIR}/uac\""; then - TAR_TOOL_AVAILABLE=true - fi - # check if 'xargs' supports -I{} parameter if eval "echo \"uac\" | xargs -I{}"; then # check if 'xargs' removes the backslash character from escaped quotes @@ -198,9 +224,9 @@ check_available_system_tools() fi # check for available MD5 hashing tools - if eval "echo \"uac\" | md5sum"; then + if command_exists "md5sum"; then MD5_HASHING_TOOL="md5sum" - elif eval "echo \"uac\" | md5"; then + elif command_exists "md5"; then MD5_HASHING_TOOL="md5" elif eval "echo \"uac\" | digest -v -a md5"; then MD5_HASHING_TOOL="digest -v -a md5" @@ -211,11 +237,11 @@ check_available_system_tools() fi # check for available SHA1 hashing tools - if eval "echo \"uac\" | sha1sum"; then + if command_exists "sha1sum"; then SHA1_HASHING_TOOL="sha1sum" elif eval "echo \"uac\" | shasum -a 1"; then SHA1_HASHING_TOOL="shasum -a 1" - elif eval "echo \"uac\" | sha1"; then + elif command_exists "sha1"; then SHA1_HASHING_TOOL="sha1" elif eval "echo \"uac\" | digest -v -a sha1"; then SHA1_HASHING_TOOL="digest -v -a sha1" @@ -226,11 +252,11 @@ check_available_system_tools() fi # check for available SHA256 hashing tools - if eval "echo \"uac\" | sha256sum"; then + if command_exists "sha256sum"; then SHA256_HASHING_TOOL="sha256sum" elif eval "echo \"uac\" | shasum -a 256"; then SHA256_HASHING_TOOL="shasum -a 256" - elif eval "echo \"uac\" | sha256"; then + elif command_exists "sha256"; then SHA256_HASHING_TOOL="sha256" elif eval "echo \"uac\" | digest -v -a sha256"; then SHA256_HASHING_TOOL="digest -v -a sha256" diff --git a/lib/command_exists.sh b/lib/command_exists.sh new file mode 100755 index 00000000..d25c3dc5 --- /dev/null +++ b/lib/command_exists.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 + +# Check if command exists. +# Arguments: +# string command: command +# Returns: +# boolean: true on success +# false on fail +command_exists() +{ + co_command="${1:-}" + + if [ -z "${co_command}" ]; then + return 1 + fi + + if eval type type >/dev/null 2>/dev/null; then + eval type "${co_command}" >/dev/null 2>/dev/null + elif command >/dev/null 2>/dev/null; then + command -v "${co_command}" >/dev/null 2>/dev/null + else + which "${co_command}" >/dev/null 2>/dev/null + fi + +} \ No newline at end of file diff --git a/lib/load_lib_files.sh b/lib/load_lib_files.sh index 520d84e3..345b13f2 100644 --- a/lib/load_lib_files.sh +++ b/lib/load_lib_files.sh @@ -10,6 +10,7 @@ . "${UAC_DIR}/lib/azure_storage_sas_url_transfer.sh" . "${UAC_DIR}/lib/check_available_system_tools.sh" . "${UAC_DIR}/lib/command_collector.sh" +. "${UAC_DIR}/lib/command_exists.sh" . "${UAC_DIR}/lib/copy_data.sh" . "${UAC_DIR}/lib/create_acquisition_log.sh" . "${UAC_DIR}/lib/create_artifact_list.sh" @@ -38,6 +39,7 @@ . "${UAC_DIR}/lib/list_profiles.sh" . "${UAC_DIR}/lib/load_config_file.sh" . "${UAC_DIR}/lib/log_message.sh" +. "${UAC_DIR}/lib/output_file_exists.sh" . "${UAC_DIR}/lib/lrstrip.sh" . "${UAC_DIR}/lib/parse_artifacts_file.sh" . "${UAC_DIR}/lib/profile_file_to_artifact_list.sh" diff --git a/lib/output_file_exists.sh b/lib/output_file_exists.sh new file mode 100644 index 00000000..4159c925 --- /dev/null +++ b/lib/output_file_exists.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# shellcheck disable=SC2006 + +# Check whether output file exists. +# Arguments: +# string output_file: full path to output file +# Returns: +# boolean: true on success +# false on fail +output_file_exists() +{ + __of_output_file="${1:-}" + + if [ -d "${__of_output_file}" ]; then + printf %b "uac: can't create directory '${__of_output_file}': Directory exists" >&2 + return 0 + elif [ -f "${__of_output_file}.tar.gz" ]; then + printf %b "uac: can't create output file '${__of_output_file}.tar.gz': File exists" >&2 + return 0 + elif [ -f "${__of_output_file}.tar" ]; then + printf %b "uac: can't create output file '${__of_output_file}.tar': File exists" >&2 + return 0 + fi + return 1 + +} diff --git a/lib/usage.sh b/lib/usage.sh index f914ae57..597428b1 100644 --- a/lib/usage.sh +++ b/lib/usage.sh @@ -18,18 +18,7 @@ usage() { - printf %b "Usage: $0 [-h] [-V] [--debug] {-p PROFILE | -a ARTIFACTS} DESTINATION - [-m MOUNT_POINT] [-s OPERATING_SYSTEM] [-u] [--temp_dir PATH] - [--date-range-start YYYY-MM-DD] [--date-range-start YYYY-MM-DD] - [--case-number CASE_NUMBER] [--description DESCRIPTION] - [--evidence-number EVIDENCE_NUMBER] [--examiner EXAMINER] - [--notes NOTES] [--hostname HOSTNAME] [--stfp SERVER] - [--sftp-port PORT] [--sftp-identity-file FILE] - [--s3-presigned-url URL] [--s3-presigned-url-log-file URL] - [--azure-storage-sas-url URL] [--azure-storage-sas-url-log-file URL] - [--ibm-cos-url URL] [--ibm-cos-url-log-file URL] - [--ibm-cloud-api-key KEY] - [--delete-local-on-successful-transfer] [--debug] + printf %b "Usage: $0 {-p PROFILE | -a ARTIFACTS} DESTINATION [OPTIONS] or: $0 --validate-artifacts-file FILE Optional Arguments: diff --git a/profiles/offline.yaml b/profiles/offline.yaml new file mode 100644 index 00000000..710323f1 --- /dev/null +++ b/profiles/offline.yaml @@ -0,0 +1,7 @@ +name: offline +description: Offline artifacts collection. +artifacts: + - bodyfile/bodyfile.yaml + - chkrootkit/chkrootkit.yaml + - hash_executables/hash_executables.yaml + - files/* diff --git a/tools/avml/LICENSE b/tools/avml/LICENSE deleted file mode 100644 index 21071075..00000000 --- a/tools/avml/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/tools/avml/bin/linux/x86_64/avml b/tools/avml/linux/avml similarity index 100% rename from tools/avml/bin/linux/x86_64/avml rename to tools/avml/linux/avml diff --git a/tools/statx/bin/linux/arm/statx b/tools/statx/linux/arm/statx similarity index 80% rename from tools/statx/bin/linux/arm/statx rename to tools/statx/linux/arm/statx index 5ae6f60f..22491b8f 100755 Binary files a/tools/statx/bin/linux/arm/statx and b/tools/statx/linux/arm/statx differ diff --git a/tools/statx/bin/linux/arm64/statx b/tools/statx/linux/arm64/statx similarity index 69% rename from tools/statx/bin/linux/arm64/statx rename to tools/statx/linux/arm64/statx index 51701529..f4be347b 100755 Binary files a/tools/statx/bin/linux/arm64/statx and b/tools/statx/linux/arm64/statx differ diff --git a/tools/statx/bin/linux/i686/statx b/tools/statx/linux/i386/statx similarity index 99% rename from tools/statx/bin/linux/i686/statx rename to tools/statx/linux/i386/statx index 516204d6..387e3509 100755 Binary files a/tools/statx/bin/linux/i686/statx and b/tools/statx/linux/i386/statx differ diff --git a/tools/statx/bin/linux/mips/statx b/tools/statx/linux/mips/statx similarity index 99% rename from tools/statx/bin/linux/mips/statx rename to tools/statx/linux/mips/statx index a95bbf40..4aab919c 100755 Binary files a/tools/statx/bin/linux/mips/statx and b/tools/statx/linux/mips/statx differ diff --git a/tools/statx/bin/linux/mips64/statx b/tools/statx/linux/mips64/statx similarity index 99% rename from tools/statx/bin/linux/mips64/statx rename to tools/statx/linux/mips64/statx index 6ef67338..6d0de9ed 100755 Binary files a/tools/statx/bin/linux/mips64/statx and b/tools/statx/linux/mips64/statx differ diff --git a/tools/statx/bin/linux/ppc/statx b/tools/statx/linux/ppc/statx similarity index 99% rename from tools/statx/bin/linux/ppc/statx rename to tools/statx/linux/ppc/statx index 9c400944..72cc3efb 100755 Binary files a/tools/statx/bin/linux/ppc/statx and b/tools/statx/linux/ppc/statx differ diff --git a/tools/statx/bin/linux/ppc64/statx b/tools/statx/linux/ppc64/statx similarity index 99% rename from tools/statx/bin/linux/ppc64/statx rename to tools/statx/linux/ppc64/statx index ede2fc13..3604edf6 100755 Binary files a/tools/statx/bin/linux/ppc64/statx and b/tools/statx/linux/ppc64/statx differ diff --git a/tools/statx/bin/linux/ppc64le/statx b/tools/statx/linux/ppc64le/statx similarity index 99% rename from tools/statx/bin/linux/ppc64le/statx rename to tools/statx/linux/ppc64le/statx index 1e3eb365..6a9dd1f3 100755 Binary files a/tools/statx/bin/linux/ppc64le/statx and b/tools/statx/linux/ppc64le/statx differ diff --git a/tools/statx/bin/linux/s390/statx b/tools/statx/linux/s390/statx similarity index 99% rename from tools/statx/bin/linux/s390/statx rename to tools/statx/linux/s390/statx index 0c352d5d..0741d0f0 100755 Binary files a/tools/statx/bin/linux/s390/statx and b/tools/statx/linux/s390/statx differ diff --git a/tools/statx/bin/linux/sparc/statx b/tools/statx/linux/sparc64/statx similarity index 80% rename from tools/statx/bin/linux/sparc/statx rename to tools/statx/linux/sparc64/statx index 4d6078b8..e2c8b8f0 100755 Binary files a/tools/statx/bin/linux/sparc/statx and b/tools/statx/linux/sparc64/statx differ diff --git a/tools/statx/bin/linux/x86_64/statx b/tools/statx/linux/x86_64/statx similarity index 50% rename from tools/statx/bin/linux/x86_64/statx rename to tools/statx/linux/x86_64/statx index 5d58d4a2..72d0315c 100755 Binary files a/tools/statx/bin/linux/x86_64/statx and b/tools/statx/linux/x86_64/statx differ diff --git a/tools/statx/src/Makefile b/tools/statx/src/Makefile deleted file mode 100644 index 53261152..00000000 --- a/tools/statx/src/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -CFLAGS=-static -O2 -BIN_DIR=../bin/linux - -all: arm arm64 i686 x86_64 mips mips64 ppc ppc64 ppc64le s390 sparc - -arm: statx.c - mkdir -p $(BIN_DIR)/$@ - arm-linux-gnueabi-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -arm64: statx.c - mkdir -p $(BIN_DIR)/$@ - aarch64-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -i686: statx.c - mkdir -p $(BIN_DIR)/$@ - i686-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -x86_64: statx.c - mkdir -p $(BIN_DIR)/$@ - x86_64-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -mips: statx.c - mkdir -p $(BIN_DIR)/$@ - mips-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -mips64: statx.c - mkdir -p $(BIN_DIR)/$@ - mips64-linux-gnuabi64-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -ppc: statx.c - mkdir -p $(BIN_DIR)/$@ - powerpc-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -ppc64: statx.c - mkdir -p $(BIN_DIR)/$@ - powerpc64-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -ppc64le: statx.c - mkdir -p $(BIN_DIR)/$@ - powerpc64le-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -s390: statx.c - mkdir -p $(BIN_DIR)/$@ - s390x-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -sparc: statx.c - mkdir -p $(BIN_DIR)/$@ - sparc64-linux-gnu-gcc $(CFLAGS) -o $(BIN_DIR)/$@/statx statx.c - -clean: - rm -rf $(BIN_DIR)/arm $(BIN_DIR)/arm64 $(BIN_DIR)/i686 $(BIN_DIR)/x86_64 $(BIN_DIR)/mips $(BIN_DIR)/mips64 $(BIN_DIR)/ppc $(BIN_DIR)/ppc64 $(BIN_DIR)/ppc64le $(BIN_DIR)/s390 $(BIN_DIR)/sparc \ No newline at end of file diff --git a/tools/statx/src/statx.c b/tools/statx/src/statx.c deleted file mode 100644 index e298c12a..00000000 --- a/tools/statx/src/statx.c +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/* - * based on https://github.com/torvalds/linux/blob/master/samples/vfs/test-statx.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __NR_statx -#define __NR_statx -1 -#endif - -ssize_t statx(int dfd, const char *filename, unsigned flags, - unsigned int mask, struct statx *buffer) -{ - return syscall(__NR_statx, dfd, filename, flags, mask, buffer); -} - -int main(int argc, char **argv) -{ - int ret; - char file_type = '?'; - char symlink[1024]; - int atflag = AT_SYMLINK_NOFOLLOW; - unsigned int mask = STATX_ALL; - struct statx stx; - - if (argc < 2) - { - printf("%s: missing operand\n", argv[0]); - return EXIT_FAILURE; - } - - memset(&stx, 0xbf, sizeof(stx)); - ret = statx(AT_FDCWD, argv[1], atflag, mask, &stx); - - if (ret < 0) - { - perror(*argv); - return EXIT_FAILURE; - } - - // MD5 - printf("0"); - - // name - ret = readlink(argv[1], symlink, sizeof(symlink)); - if (ret > 0) - printf("|%s -> %s", argv[1], symlink); - else - printf("|%s", argv[1]); - - // inode - if (stx.stx_mask & STATX_INO) - printf("|%llu", (unsigned long long)stx.stx_ino); - else - printf("|0"); - - // type - if (stx.stx_mask & STATX_TYPE) - { - switch (stx.stx_mode & S_IFMT) - { - case S_IFIFO: - file_type = 'p'; - break; - case S_IFCHR: - file_type = 'c'; - break; - case S_IFDIR: - file_type = 'd'; - break; - case S_IFBLK: - file_type = 'b'; - break; - case S_IFREG: - file_type = '-'; - break; - case S_IFLNK: - file_type = 'l'; - break; - case S_IFSOCK: - file_type = 's'; - break; - } - } - printf("|%c", file_type); - - // mode as string - if (stx.stx_mask & STATX_MODE) - printf("%c%c%c%c%c%c%c%c%c", - stx.stx_mode & S_IRUSR ? 'r' : '-', - stx.stx_mode & S_IWUSR ? 'w' : '-', - stx.stx_mode & S_IXUSR ? 'x' : '-', - stx.stx_mode & S_IRGRP ? 'r' : '-', - stx.stx_mode & S_IWGRP ? 'w' : '-', - stx.stx_mode & S_IXGRP ? 'x' : '-', - stx.stx_mode & S_IROTH ? 'r' : '-', - stx.stx_mode & S_IWOTH ? 'w' : '-', - stx.stx_mode & S_IXOTH ? 'x' : '-'); - else - printf("?????????"); - - // uid - if (stx.stx_mask & STATX_UID) - printf("|%d", stx.stx_uid); - else - printf("|0"); - - // gid - if (stx.stx_mask & STATX_GID) - printf("|%d", stx.stx_gid); - else - printf("|0"); - - // size - if (stx.stx_mask & STATX_SIZE) - printf("|%llu", (unsigned long long)stx.stx_size); - else - printf("|0"); - - // atime - if (stx.stx_mask & STATX_ATIME) - printf("|%llu", stx.stx_atime.tv_sec); - else - printf("|0"); - - // mtime - if (stx.stx_mask & STATX_MTIME) - printf("|%llu", stx.stx_mtime.tv_sec); - else - printf("|0"); - - // ctime - if (stx.stx_mask & STATX_CTIME) - printf("|%llu", stx.stx_ctime.tv_sec); - else - printf("|0"); - - // btime - if (stx.stx_mask & STATX_BTIME) - printf("|%llu", stx.stx_btime.tv_sec); - else - printf("|0"); - - printf("\n"); - - return EXIT_SUCCESS; -} diff --git a/uac b/uac index 1be5097f..1f93438e 100755 --- a/uac +++ b/uac @@ -6,7 +6,7 @@ unalias -a # use a safe umask for created files -umask 027 +umask 022 # set locale LANG=C @@ -40,7 +40,7 @@ export PATH . "${UAC_DIR}/lib/load_lib_files.sh" # global vars -UAC_VERSION="2.7.0" +UAC_VERSION="2.8.0" MOUNT_POINT="/" OPERATING_SYSTEM="" SYSTEM_ARCH="" @@ -63,6 +63,8 @@ ua_artifacts="" ua_destination_dir="" ua_run_as_non_root=false ua_temp_dir="" +ua_output_base_filename="" +ua_output_filename="" ua_case_number="" ua_evidence_number="" ua_evidence_description="" @@ -195,7 +197,7 @@ Try 'uac --help' for more information.\n" >&2 fi ;; # filter arguments - "--date-range-start") + "--start-date"|"--date-range-start") if [ -n "${2}" ]; then START_DATE="${2}" shift @@ -205,7 +207,7 @@ Try 'uac --help' for more information.\n" >&2 exit 1 fi ;; - "--date-range-end") + "--end-date"|"--date-range-end") if [ -n "${2}" ]; then END_DATE="${2}" shift @@ -498,6 +500,23 @@ if [ -z "${ua_hostname}" ]; then ua_hostname=`get_hostname 2>/dev/null` fi +# get current date and time string +ua_current_date_time=`date "+%Y%m%d%H%M%S"` +if [ -n "${ua_output_base_filename}" ]; then + ua_output_base_filename=`echo "${ua_output_base_filename}" \ + | sed -e "s|%hostname%|${ua_hostname}|g" \ + -e "s|%os%|${OPERATING_SYSTEM}|g" \ + -e "s|%timestamp%|${ua_current_date_time}|g"` + if [ -z "${ua_output_base_filename}" ]; then + printf %b "uac: invalid empty output filename\n" >&2 + exit 1 + fi +else + ua_output_base_filename="uac-${ua_hostname}-${OPERATING_SYSTEM}-${ua_current_date_time}" +fi + +output_file_exists "${ua_destination_dir}/${ua_output_base_filename}" && exit 1 + # check if destination directory's file system supports symlink creation if [ -n "${ua_temp_dir}" ]; then file_system_symlink_support "${ua_temp_dir}" >/dev/null 2>/dev/null \ @@ -509,6 +528,9 @@ else TEMP_DATA_DIR="${ua_destination_dir}/uac-data.tmp" fi +# check available system tools +check_available_system_tools >/dev/null 2>/dev/null + # test the connectivity to remote sftp server if [ -n "${ua_sftp_destination}" ]; then if sftp_transfer_test "${ua_sftp_destination}" "${ua_sftp_port}" \ @@ -521,14 +543,14 @@ fi # test the connectivity to S3 presigned url if [ -n "${ua_s3_presigned_url}" ]; then - if eval "curl --version" >/dev/null 2>/dev/null; then + if ${CURL_TOOL_AVAILABLE}; then if s3_presigned_url_transfer_test "${ua_s3_presigned_url}"; then true else exit 1 fi else - printf %b "uac: cannot transfer to S3 presigned URL because 'curl' \ + printf %b "uac: cannot transfer to S3 presigned URL as 'curl' \ tool was not found.\n" exit 1 fi @@ -536,14 +558,14 @@ fi # test the connectivity to Azure Blob Storage SAS url if [ -n "${ua_azure_storage_sas_url}" ]; then - if eval "curl --version" >/dev/null 2>/dev/null; then + if ${CURL_TOOL_AVAILABLE}; then if azure_storage_sas_url_transfer_test "${ua_azure_storage_sas_url}"; then true else exit 1 fi else - printf %b "uac: cannot transfer to Azure Blob Storage SAS URL because 'curl' \ + printf %b "uac: cannot transfer to Azure Blob Storage SAS URL as 'curl' \ tool was not found.\n" exit 1 fi @@ -552,14 +574,14 @@ fi # test the connectivity to IBM Cloud Object Storage url if [ -n "${ua_ibm_cos_url}" ]; then if [ -n "${ua_ibm_cloud_api_key}" ]; then - if eval "curl --version" >/dev/null 2>/dev/null; then + if ${CURL_TOOL_AVAILABLE}; then if ibm_cos_transfer_test "${ua_ibm_cos_url}" "${ua_ibm_cloud_api_key}"; then true else exit 1 fi else - printf %b "uac: cannot transfer to IBM Cloud Object Storage because 'curl' \ + printf %b "uac: cannot transfer to IBM Cloud Object Storage as 'curl' \ tool was not found.\n" exit 1 fi @@ -604,7 +626,9 @@ SYSTEM_ARCH=`get_system_arch 2>>"${UAC_STDERR_LOG_FILE}"` # add local 'bin' directory to path PATH="${UAC_DIR}/bin/${OPERATING_SYSTEM}/${SYSTEM_ARCH}:${PATH}" # add 'avml' tool directory to path -PATH="${UAC_DIR}/tools/avml/bin/${OPERATING_SYSTEM}/${SYSTEM_ARCH}:${PATH}" +if [ "${OPERATING_SYSTEM}" = "esxi" ] || [ "${OPERATING_SYSTEM}" = "linux" ]; then + PATH="${UAC_DIR}/tools/avml/linux:${PATH}" +fi # add 'linux_procmemdump.sh' tool directory to path PATH="${UAC_DIR}/tools/linux_procmemdump.sh:${PATH}" export PATH @@ -659,11 +683,6 @@ log_message INFO "Hash algorithm: ${HASH_ALGORITHM}" log_message INFO "Enable find mtime: ${ENABLE_FIND_MTIME}" log_message INFO "Enable find atime: ${ENABLE_FIND_ATIME}" log_message INFO "Enable find ctime: ${ENABLE_FIND_CTIME}" - -# check available system tools -log_message INFO "Checking available system tools" -check_available_system_tools >/dev/null 2>>"${UAC_STDERR_LOG_FILE}" - log_message INFO "'find' opperators support: ${FIND_OPERATORS_SUPPORT}" log_message INFO "'find -path' support: ${FIND_PATH_SUPPORT}" log_message INFO "'find -type' support: ${FIND_TYPE_SUPPORT}" @@ -678,7 +697,6 @@ log_message INFO "SHA1 hashing tool: ${SHA1_HASHING_TOOL}" log_message INFO "SHA256 hashing tool: ${SHA256_HASHING_TOOL}" log_message INFO "'gzip' tool available: ${GZIP_TOOL_AVAILABLE}" log_message INFO "'perl' tool available: ${PERL_TOOL_AVAILABLE}" -log_message INFO "'tar' tool available: ${TAR_TOOL_AVAILABLE}" log_message INFO "'stat' tool available: ${STAT_TOOL_AVAILABLE}" log_message INFO "'stat' btime support: ${STAT_BTIME_SUPPORT}" log_message INFO "'statx' tool available: ${STATX_TOOL_AVAILABLE}" @@ -729,7 +747,8 @@ while read ua_artifact_file || [ -n "${ua_artifact_file}" ]; do ua_artifacts_root_output_directory=`dirname "${ua_artifact_file}"` parse_artifacts_file "${UAC_DIR}/artifacts/${ua_artifact_file}" \ "${ua_artifacts_root_output_directory}" - echo "${ua_artifacts_root_output_directory}" >>"${TEMP_DATA_DIR}/.output_file.tmp" + find "${TEMP_DATA_DIR}/${ua_artifacts_root_output_directory}" -type f -print \ + | sed -e "s|^${TEMP_DATA_DIR}/||" >>"${TEMP_DATA_DIR}/.output_file.tmp" done <"${TEMP_DATA_DIR}/.artifacts.tmp" 2>>"${UAC_STDERR_LOG_FILE}" # disable debug mode @@ -739,8 +758,6 @@ ${ua_debug_mode} && set +x ua_acq_end_date=`date "+%a %b %d %H:%M:%S %Y %z" 2>>"${UAC_STDERR_LOG_FILE}"` # acquisition end epoch date ua_acq_end_date_epoch=`get_epoch_date 2>>"${UAC_STDERR_LOG_FILE}"` -# get current date and time string (it will be part of the output file name) -ua_current_date_time=`date "+%Y%m%d%H%M%S"` # calculate running time # shellcheck disable=SC2003 @@ -753,12 +770,8 @@ Total execution time: ${ua_total_running_time} seconds" printf %b "Artifacts collection complete. \ Total execution time: ${ua_total_running_time} seconds\n" -# output file/directory name -ua_output_base_name="uac-${ua_hostname}-${OPERATING_SYSTEM}-${ua_current_date_time}" -# output file/directory name -ua_output_name="${ua_output_base_name}" # acquisition log file name -ua_acquisition_log="${ua_output_base_name}.log" +ua_acquisition_log="${ua_output_base_filename}.log" # output file hash ua_output_file_hash="-" @@ -769,14 +782,14 @@ echo "uac.log" >>"${TEMP_DATA_DIR}/.output_file.tmp" # add uac.log.stderr to the list of files to be archived/copied within the output file echo "uac.log.stderr" >>"${TEMP_DATA_DIR}/.output_file.tmp" -if ${TAR_TOOL_AVAILABLE}; then - +# create output file +if command_exists "tar"; then if [ -f "${TEMP_DATA_DIR}/.files.tmp" ]; then # sort and uniq sort_uniq_file "${TEMP_DATA_DIR}/.files.tmp" 2>>"${UAC_STDERR_LOG_FILE}" if ${ua_temp_data_dir_symlink_support}; then # create symbolic link to / - ln -s "/" "${TEMP_DATA_DIR}/[root]" 2>>"${UAC_STDERR_LOG_FILE}" + ln -s "${MOUNT_POINT}" "${TEMP_DATA_DIR}/[root]" 2>>"${UAC_STDERR_LOG_FILE}" else # copy files to uac-data.tmp/[root] printf %b "Copying files to ${TEMP_DATA_DIR}/[root]. Please wait...\n" @@ -785,7 +798,7 @@ if ${TAR_TOOL_AVAILABLE}; then fi # add [root] string to the beginning of each entry in .files.tmp # and add them to the list of files to be archived within the output file - sed -e 's:^/:\[root\]/:' "${TEMP_DATA_DIR}/.files.tmp" \ + sed -e "s:^${MOUNT_POINT}:\[root\]/:" -e 's://*:/:g' "${TEMP_DATA_DIR}/.files.tmp" \ >>"${TEMP_DATA_DIR}/.output_file.tmp" fi @@ -794,17 +807,17 @@ if ${TAR_TOOL_AVAILABLE}; then cd "${TEMP_DATA_DIR}" || exit 1 if ${GZIP_TOOL_AVAILABLE}; then - ua_output_name="${ua_output_base_name}.tar.gz" + ua_output_filename="${ua_output_base_filename}.tar.gz" archive_compress_data ".output_file.tmp" \ - "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null else - ua_output_name="${ua_output_base_name}.tar" + ua_output_filename="${ua_output_base_filename}.tar" archive_data ".output_file.tmp" \ - "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null fi - if [ -f "${ua_destination_dir}/${ua_output_name}" ]; then - printf %b "Output file created '${ua_destination_dir}/${ua_output_name}'\n" + if [ -f "${ua_destination_dir}/${ua_output_filename}" ]; then + printf %b "Output file created '${ua_destination_dir}/${ua_output_filename}'\n" cd "${UAC_DIR}" || exit 1 if ${ua_debug_mode}; then printf %b "Temporary directory not removed '${TEMP_DATA_DIR}'\n" @@ -817,7 +830,7 @@ if ${TAR_TOOL_AVAILABLE}; then # hash output file printf %b "Hashing output file. Please wait...\n" cd "${ua_destination_dir}" || exit 1 - ua_output_file_hash=`${MD5_HASHING_TOOL} "${ua_output_name}"` + ua_output_file_hash=`${MD5_HASHING_TOOL} "${ua_output_filename}"` cd "${UAC_DIR}" || exit 1 else printf %b "Cannot create output file\n" @@ -825,20 +838,21 @@ if ${TAR_TOOL_AVAILABLE}; then cd "${UAC_DIR}" && exit 1 fi else - printf %b "'tar' not found. Copying collected artifacts to '${ua_destination_dir}/${ua_output_name}'. Please wait...\n" + ua_output_filename="${ua_output_base_filename}" + printf %b "'tar' not found. Copying collected artifacts to '${ua_destination_dir}/${ua_output_filename}'. Please wait...\n" if [ -f "${TEMP_DATA_DIR}/.files.tmp" ]; then # sort and uniq sort_uniq_file "${TEMP_DATA_DIR}/.files.tmp" 2>>"${UAC_STDERR_LOG_FILE}" - copy_data "${TEMP_DATA_DIR}/.files.tmp" "${ua_destination_dir}/${ua_output_name}/[root]" \ + copy_data "${TEMP_DATA_DIR}/.files.tmp" "${ua_destination_dir}/${ua_output_filename}/[root]" \ 2>>"${UAC_STDERR_LOG_FILE}" fi cd "${TEMP_DATA_DIR}" || exit 1 - copy_data "${TEMP_DATA_DIR}/.output_file.tmp" "${ua_destination_dir}/${ua_output_name}" \ + copy_data "${TEMP_DATA_DIR}/.output_file.tmp" "${ua_destination_dir}/${ua_output_filename}" \ 2>>"${UAC_STDERR_LOG_FILE}" - ua_file_count=`find "${ua_destination_dir}/${ua_output_name}" -print | wc -l` + ua_file_count=`find "${ua_destination_dir}/${ua_output_filename}" -print | wc -l` if [ "${ua_file_count}" -gt 2 ]; then - printf %b "Please check collected artifacts in '${ua_destination_dir}/${ua_output_name}'\n" + printf %b "Please check collected artifacts in '${ua_destination_dir}/${ua_output_filename}'\n" cd "${UAC_DIR}" || exit 1 if ${ua_debug_mode}; then printf %b "Temporary directory not removed '${TEMP_DATA_DIR}'\n" @@ -875,15 +889,15 @@ fi # transfer output and log file to remote sftp server if [ -n "${ua_sftp_destination}" ]; then - if [ -f "${ua_destination_dir}/${ua_output_name}" ] \ - || [ -d "${ua_destination_dir}/${ua_output_name}" ]; then + if [ -f "${ua_destination_dir}/${ua_output_filename}" ] \ + || [ -d "${ua_destination_dir}/${ua_output_filename}" ]; then printf %b "Transferring output file to remote SFTP server. Please wait...\n" - if sftp_transfer "${ua_destination_dir}/${ua_output_name}" \ + if sftp_transfer "${ua_destination_dir}/${ua_output_filename}" \ "${ua_sftp_destination}" "${ua_sftp_port}" "${ua_sftp_identity_file}"; then printf %b "File transferred successfully\n" # delete output file on success transfer ${ua_delete_local_on_successful_transfer} \ - && rm -f "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + && rm -f "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null printf %b "Transferring log file to remote SFTP server. Please wait...\n" if sftp_transfer "${ua_destination_dir}/${ua_acquisition_log}" \ "${ua_sftp_destination}" "${ua_sftp_port}" "${ua_sftp_identity_file}"; then @@ -904,14 +918,14 @@ fi # transfer output and log file to S3 presigned url if [ -n "${ua_s3_presigned_url}" ]; then - if [ -f "${ua_destination_dir}/${ua_output_name}" ]; then + if [ -f "${ua_destination_dir}/${ua_output_filename}" ]; then printf %b "Transferring output file to S3 presigned URL. Please wait...\n" - if s3_presigned_url_transfer "${ua_destination_dir}/${ua_output_name}" \ + if s3_presigned_url_transfer "${ua_destination_dir}/${ua_output_filename}" \ "${ua_s3_presigned_url}"; then printf %b "File transferred successfully\n" # delete output file on success transfer ${ua_delete_local_on_successful_transfer} \ - && rm -f "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + && rm -f "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null else printf %b "Could not transfer output file to S3 presigned URL\n" exit 1 @@ -934,14 +948,14 @@ fi # transfer output and log file to Azure Storage SAS url if [ -n "${ua_azure_storage_sas_url}" ]; then - if [ -f "${ua_destination_dir}/${ua_output_name}" ]; then + if [ -f "${ua_destination_dir}/${ua_output_filename}" ]; then printf %b "Transferring output file to Azure Storage SAS URL. Please wait...\n" - if azure_storage_sas_url_transfer "${ua_destination_dir}/${ua_output_name}" \ + if azure_storage_sas_url_transfer "${ua_destination_dir}/${ua_output_filename}" \ "${ua_azure_storage_sas_url}"; then printf %b "File transferred successfully\n" # delete output file on success transfer ${ua_delete_local_on_successful_transfer} \ - && rm -f "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + && rm -f "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null else printf %b "Could not transfer output file to Azure Storage SAS URL\n" exit 1 @@ -964,14 +978,14 @@ fi # transfer output and log file to IBM Cloud Object Storage if [ -n "${ua_ibm_cos_url}" ]; then - if [ -f "${ua_destination_dir}/${ua_output_name}" ]; then + if [ -f "${ua_destination_dir}/${ua_output_filename}" ]; then printf %b "Transferring output file to IBM Cloud Object Storage. Please wait...\n" - if ibm_cos_transfer "${ua_destination_dir}/${ua_output_name}" \ + if ibm_cos_transfer "${ua_destination_dir}/${ua_output_filename}" \ "${ua_ibm_cos_url}" "${ua_ibm_cloud_api_key}"; then printf %b "File transferred successfully\n" # delete output file on success transfer ${ua_delete_local_on_successful_transfer} \ - && rm -f "${ua_destination_dir}/${ua_output_name}" 2>/dev/null + && rm -f "${ua_destination_dir}/${ua_output_filename}" 2>/dev/null else printf %b "Could not transfer output file to IBM Cloud Object Storage\n" exit 1