cursor rewrite + network checks

This commit is contained in:
carlospolop 2025-05-24 08:29:47 +02:00
parent 604580adbd
commit 1e7a90d29f
73 changed files with 4059 additions and 1018 deletions

View File

@ -35,5 +35,5 @@
print_2title "Environment"
print_info "Any private information inside environment variables?"
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_" | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_" | sed -${E} "s,[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
echo ""

View File

@ -134,4 +134,6 @@ if [ "$(command -v systemd-detect-virt 2>/dev/null || echo -n '')" ]; then
if [ "$hypervisorflag" ]; then printf $RED"Yes ($detectedvirt)"$NC; else printf $GREEN"No"$NC; fi
else
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
fi
fi
echo ""

View File

@ -14,33 +14,40 @@
# * Common vulnerable modules: nf_tables, eBPF, overlayfs, etc.
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_list
# Functions Used: print_2title, print_3title
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
echo ""
print_2title "Kernel Modules Information"
# List loaded kernel modules
print_list "Loaded kernel modules? ........ "$NC
if [ -f "/proc/modules" ]; then
lsmod
else
echo_not_found "/proc/modules"
if [ "$EXTRA_CHECKS" ] || [ "$DEBUG" ]; then
print_3title "Loaded kernel modules"
if [ -f "/proc/modules" ]; then
lsmod
else
echo_not_found "/proc/modules"
fi
fi
# Check for kernel modules with weak permissions
print_list "Kernel modules with weak perms? "$NC
print_3title "Kernel modules with weak perms?"
if [ -d "/lib/modules" ]; then
find /lib/modules -type f -name "*.ko" -ls 2>/dev/null | grep -Ev "root\s+root" | sed -${E} "s,.*,${SED_RED},g"
if [ $? -eq 1 ]; then
echo "No kernel modules with weak permissions found"
fi
else
echo_not_found "/lib/modules"
fi
echo ""
# Check for kernel modules that can be loaded by unprivileged users
print_list "Kernel modules loadable? "$NC
print_3title "Kernel modules loadable? "
if [ -f "/proc/sys/kernel/modules_disabled" ]; then
if [ "$(cat /proc/sys/kernel/modules_disabled)" = "0" ]; then
echo "Modules can be loaded" | sed -${E} "s,.*,${SED_RED},g"

View File

@ -1,75 +0,0 @@
# Title: System Information - Systemd
# ID: SY_Systemd
# Author: Carlos Polop
# Last Update: 07-03-2024
# Description: Check for systemd vulnerabilities and misconfigurations that could lead to privilege escalation:
# - Systemd version vulnerabilities (CVE-2021-4034, CVE-2021-33910, etc.)
# - Services running as root that could be exploited
# - Services with dangerous capabilities that could be abused
# - Services with writable paths that could be used to inject malicious code
# - Exploitation methods:
# * Version exploits: Use known exploits for vulnerable systemd versions
# * Root services: Abuse services running as root to execute commands
# * Capabilities: Abuse services with dangerous capabilities (CAP_SYS_ADMIN, etc.)
# * Writable paths: Replace executables in writable paths to get code execution
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, print_list, warn_exec
# Global Variables: $DEBUG
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Systemd Information"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/systemd-privilege-escalation"
# Check systemd version
print_list "Systemd version? .............. "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
systemctl --version | head -n 1 | sed -${E} "s,([0-9]+(\.[0-9]+)+),${SED_RED},g"
else
echo_not_found "systemctl"
fi
# Check for systemd services running as root
print_list "Services running as root? ..... "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
systemctl list-units --type=service --state=running 2>/dev/null | grep -E "root|0:0" | sed -${E} "s,root|0:0,${SED_RED},g"
else
echo_not_found "systemctl"
fi
# Check for systemd services with capabilities
print_list "Running services with capabilities? ... "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
for service in $(systemctl list-units --type=service --state=running 2>/dev/null | grep -E "\.service" | awk '{print $1}'); do
if [ -f "/etc/systemd/system/$service" ] || [ -f "/lib/systemd/system/$service" ]; then
if grep -q "CapabilityBoundingSet" "/etc/systemd/system/$service" "/lib/systemd/system/$service" 2>/dev/null; then
echo "$service" | sed -${E} "s,.*,${SED_RED},g"
fi
fi
done
else
echo_not_found "systemctl"
fi
# Check for systemd services with writable paths
print_list "Services with writable paths? . "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
for service in $(systemctl list-units --type=service --state=running 2>/dev/null | grep -E "\.service" | awk '{print $1}'); do
if [ -f "/etc/systemd/system/$service" ] || [ -f "/lib/systemd/system/$service" ]; then
if grep -q "ExecStart\|ExecStartPre\|ExecStartPost" "/etc/systemd/system/$service" "/lib/systemd/system/$service" 2>/dev/null; then
for path in $(grep -E "ExecStart|ExecStartPre|ExecStartPost" "/etc/systemd/system/$service" "/lib/systemd/system/$service" 2>/dev/null | awk '{print $2}' | tr -d '"'); do
if [ -w "$path" ]; then
echo "$service: $path" | sed -${E} "s,.*,${SED_RED},g"
fi
done
fi
fi
done
else
echo_not_found "systemctl"
fi
echo ""

View File

@ -1,62 +0,0 @@
# Title: System Information - System Logging
# ID: SY_System_Logging
# Author: Carlos Polop
# Last Update: 07-03-2024
# Description: Check for logging system misconfigurations that could lead to privilege escalation:
# - Syslog/rsyslog configurations that log sensitive information
# - Auditd configurations that could be abused
# - Log files with weak permissions that could be modified
# - Log rotation configurations that could be exploited
# - Exploitation methods:
# * Sensitive info in logs: Extract credentials or sensitive data from logs
# * Weak permissions: Modify log files to inject malicious content
# * Log rotation: Abuse log rotation to execute malicious code
# * Log injection: Inject malicious content into logs that get executed
# * Common targets: /var/log/auth.log, /var/log/syslog, audit logs
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, print_list, warn_exec
# Global Variables: $DEBUG
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
print_2title "System Logging Information"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/logs-privilege-escalation"
# Check syslog configuration
print_list "Syslog configuration? ......... "$NC
if [ -f "/etc/rsyslog.conf" ]; then
grep -v "^#" /etc/rsyslog.conf 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
elif [ -f "/etc/syslog.conf" ]; then
grep -v "^#" /etc/syslog.conf 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
else
echo_not_found "syslog configuration"
fi
# Check auditd configuration
print_list "Auditd configuration? ......... "$NC
if [ -f "/etc/audit/auditd.conf" ]; then
grep -v "^#" /etc/audit/auditd.conf 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
else
echo_not_found "auditd configuration"
fi
# Check for log files with weak permissions
print_list "Log files with weak perms? .... "$NC
find /var/log -type f -ls 2>/dev/null | grep -v "root root" | sed -${E} "s,.*,${SED_RED},g"
# Check for log rotation configurations
print_list "Log rotation configuration? ... "$NC
if [ -d "/etc/logrotate.d" ]; then
for conf in /etc/logrotate.d/*; do
if [ -f "$conf" ]; then
grep -v "^#" "$conf" 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
fi
done
else
echo_not_found "logrotate configuration"
fi
echo ""

View File

@ -1,73 +0,0 @@
# Title: System Information - Container/VM Escape
# ID: SY_Container_VM_Escape
# Author: Carlos Polop
# Last Update: 07-03-2024
# Description: Check for container/VM escape possibilities that could lead to host system compromise:
# - Container runtime detection (Docker, Podman, LXC)
# - Shared resources between container and host
# - Vulnerable container runtime versions
# - Container breakout possibilities through capabilities
# - Exploitation methods:
# * Shared resources: Abuse mounted volumes, sockets, or devices
# * Runtime exploits: Use known exploits for vulnerable container runtimes
# * Capability abuse: Exploit containers with dangerous capabilities
# * Common escape vectors:
# - Mount escape (CVE-2021-21284)
# - Capability escape (CAP_SYS_ADMIN, CAP_DAC_OVERRIDE)
# - Seccomp bypass
# - Kernel exploits from container
# - Shared namespaces abuse
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, print_list, warn_exec
# Global Variables: $DEBUG
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Container/VM Escape Information"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-breakout-privilege-escalation"
# Check if running in container
print_list "Running in container? ......... "$NC
if [ -f "/.dockerenv" ]; then
echo "Yes (Docker)" | sed -${E} "s,.*,${SED_RED},g"
elif [ -f "/run/.containerenv" ]; then
echo "Yes (Podman)" | sed -${E} "s,.*,${SED_RED},g"
elif [ -f "/proc/1/cgroup" ] && grep -q "docker\|lxc" "/proc/1/cgroup" 2>/dev/null; then
echo "Yes (Container)" | sed -${E} "s,.*,${SED_RED},g"
else
echo "No" | sed -${E} "s,.*,${SED_GREEN},g"
fi
# Check for shared resources
print_list "Shared resources with host? ... "$NC
if [ -f "/proc/mounts" ]; then
grep -E "docker|lxc" /proc/mounts 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
else
echo_not_found "/proc/mounts"
fi
# Check for container runtime vulnerabilities
print_list "Container runtime version? .... "$NC
if [ "$(command -v docker 2>/dev/null || echo -n '')" ]; then
docker version 2>/dev/null | grep "Version" | sed -${E} "s,([0-9]+(\.[0-9]+)+),${SED_RED},g"
elif [ "$(command -v podman 2>/dev/null || echo -n '')" ]; then
podman version 2>/dev/null | grep "Version" | sed -${E} "s,([0-9]+(\.[0-9]+)+),${SED_RED},g"
else
echo_not_found "container runtime"
fi
# Check for container breakout possibilities
print_list "Container breakout possibilities? "$NC
if [ -f "/proc/self/status" ]; then
if grep -q "CapEff:\s*0000003fffffffff" "/proc/self/status" 2>/dev/null; then
echo "Container has all capabilities" | sed -${E} "s,.*,${SED_RED},g"
fi
if grep -q "Seccomp:\s*0" "/proc/self/status" 2>/dev/null; then
echo "Seccomp is disabled" | sed -${E} "s,.*,${SED_RED},g"
fi
fi
echo ""

View File

@ -22,7 +22,7 @@
# - Container escape tool usage
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, warn_exec
# Functions Used: print_2title
# Global Variables:
# Initial Functions:
# Generated Global Variables:
@ -32,42 +32,42 @@
print_2title "Container related tools present (if any):"
# Container runtimes
warn_exec command -v docker
warn_exec command -v lxc
warn_exec command -v rkt
warn_exec command -v podman
warn_exec command -v runc
warn_exec command -v ctr
warn_exec command -v containerd
warn_exec command -v crio
warn_exec command -v nerdctl
command -v docker
command -v lxc
command -v rkt
command -v podman
command -v runc
command -v ctr
command -v containerd
command -v crio
command -v nerdctl
# Container management
warn_exec command -v kubectl
warn_exec command -v crictl
warn_exec command -v docker-compose
warn_exec command -v docker-machine
warn_exec command -v minikube
warn_exec command -v kind
command -v kubectl
command -v crictl
command -v docker-compose
command -v docker-machine
command -v minikube
command -v kind
# Container networking
warn_exec command -v docker-proxy
warn_exec command -v cni
warn_exec command -v flanneld
warn_exec command -v calicoctl
command -v docker-proxy
command -v cni
command -v flanneld
command -v calicoctl
# Container security
warn_exec command -v apparmor_parser
warn_exec command -v seccomp
warn_exec command -v gvisor
warn_exec command -v kata-runtime
command -v apparmor_parser
command -v seccomp
command -v gvisor
command -v kata-runtime
# Container debugging
warn_exec command -v nsenter
warn_exec command -v unshare
warn_exec command -v chroot
warn_exec command -v capsh
warn_exec command -v setcap
warn_exec command -v getcap
command -v nsenter
command -v unshare
command -v chroot
command -v capsh
command -v setcap
command -v getcap
echo ""

View File

@ -13,7 +13,7 @@
# Small linpeas: 1
printf "${YELLOW}Learn and practice cloud hacking techniques in ${BLUE}training.hacktricks.xyz\n"$NC
printf "${YELLOW}Learn and practice cloud hacking techniques in ${BLUE}https://training.hacktricks.xyz\n"$NC
echo ""
print_list "GCP Virtual Machine? ................. $is_gcp_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"

View File

@ -0,0 +1,193 @@
# Title: Processes & Cron & Services & Timers - Services and Service Files
# ID: PR_Services
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Services and service files analysis with privilege escalation vectors
# License: GNU GPL
# Version: 1.2
# Functions Used: echo_not_found, print_2title, print_info, print_3title
# Global Variables: $EXTRA_CHECKS, $SEARCH_IN_FOLDER, $IAMROOT, $WRITABLESYSTEMDPATH
# Initial Functions:
# Generated Global Variables: $service_unit, $service_path, $service_content, $finding, $findings, $service_file, $exec_path, $exec_paths, $service, $line, $target_file, $target_exec, $relpath1, $relpath2
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Services and Service Files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#services"
# Function to check service content for privilege escalation vectors
check_service_content() {
local service="$1"
local findings=""
# Check if service runs with elevated privileges
if systemctl show "$service" -p User 2>/dev/null | grep -q "root"; then
findings="${findings}RUNS_AS_ROOT: Service runs as root\n"
fi
# Get the executable path and check it
local exec_path=$(systemctl show "$service" -p ExecStart 2>/dev/null | cut -d= -f2 | cut -d' ' -f1)
if [ -n "$exec_path" ]; then
if [ -w "$exec_path" ]; then
findings="${findings}WRITABLE_EXEC: Executable is writable: $exec_path\n"
fi
# Check for relative paths
#case "$exec_path" in
# /*) : ;; # Absolute path, do nothing
# *) findings="${findings}RELATIVE_PATH: Uses relative path: $exec_path\n" ;;
#esac
# Check for weak permissions
if [ -e "$exec_path" ] && [ "$(stat -c %a "$exec_path" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_PERMS: Executable has 777 permissions\n"
fi
fi
# Check for unsafe configurations
if systemctl show "$service" -p ExecStart 2>/dev/null | grep -qE '(chmod|chown|mount|sudo|su)'; then
findings="${findings}UNSAFE_CMD: Uses potentially dangerous commands\n"
fi
# Check for environment variables with sensitive data
if systemctl show "$service" -p Environment 2>/dev/null | grep -qE '(PASS|SECRET|KEY|TOKEN|CRED)'; then
findings="${findings}SENSITIVE_ENV: Contains sensitive environment variables\n"
fi
# Check for capabilities
if systemctl show "$service" -p CapabilityBoundingSet 2>/dev/null | grep -qE '(CAP_SYS_ADMIN|CAP_DAC_OVERRIDE|CAP_DAC_READ_SEARCH)'; then
findings="${findings}DANGEROUS_CAPS: Has dangerous capabilities\n"
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo " Potential issue in service: $service"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding"
done
fi
}
# Function to check service file for privilege escalation vectors
check_service_file() {
local service_file="$1"
local findings=""
# Check if service file is writable (following symlinks)
if [ -L "$service_file" ]; then
# If it's a symlink, check the target file
local target_file=$(readlink -f "$service_file")
if ! [ "$IAMROOT" ] && [ -w "$target_file" ] && [ -f "$target_file" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
findings="${findings}WRITABLE_FILE: Service target file is writable: $target_file\n"
fi
elif ! [ "$IAMROOT" ] && [ -w "$service_file" ] && [ -f "$service_file" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
findings="${findings}WRITABLE_FILE: Service file is writable\n"
fi
# Check for weak permissions (following symlinks)
if [ "$(stat -L -c %a "$service_file" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_PERMS: Service file has 777 permissions\n"
fi
# Check for relative paths in Exec directives - Original logic
local relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$service_file" 2>/dev/null | grep -Iv "=/")
local relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$service_file" 2>/dev/null)
if [ "$relpath1" ] || [ "$relpath2" ]; then
if [ "$WRITABLESYSTEMDPATH" ]; then
findings="${findings}RELATIVE_PATH: Could be executing some relative path (systemd path is writable)\n"
else
findings="${findings}RELATIVE_PATH: Could be executing some relative path\n"
fi
fi
# Check for writable executables (following symlinks)
local exec_paths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$service_file" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$exec_paths" | while read -r exec_path; do
if [ -n "$exec_path" ]; then
if [ -L "$exec_path" ]; then
local target_exec=$(readlink -f "$exec_path")
if [ -w "$target_exec" ]; then
findings="${findings}WRITABLE_EXEC: Executable target is writable: $target_exec\n"
fi
elif [ -w "$exec_path" ]; then
findings="${findings}WRITABLE_EXEC: Executable is writable: $exec_path\n"
fi
fi
done
# If any findings, print them
if [ -n "$findings" ]; then
echo " Potential issue in service file: $service_file"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding"
done
fi
}
# List all services and check for privilege escalation vectors
echo ""
print_3title "Active services:"
systemctl list-units --type=service --state=active 2>/dev/null | grep -v "UNIT" | while read -r line; do
service_unit=$(echo "$line" | awk '{print $1}')
if [ -n "$service_unit" ]; then
# Print the service line with highlighting
echo "$line" | sed -${E} "s,$service_unit,${SED_GREEN},"
# Get service file path
service_path=$(systemctl show "$service_unit" -p FragmentPath 2>/dev/null | cut -d= -f2)
if [ -n "$service_path" ]; then
check_service_file "$service_path"
fi
# Check service content for privilege escalation vectors
check_service_content "$service_unit"
fi
done || echo_not_found
# Check for disabled but available services
echo ""
print_3title "Disabled services:"
systemctl list-unit-files --type=service --state=disabled 2>/dev/null | grep -v "UNIT FILE" | while read -r line; do
service_unit=$(echo "$line" | awk '{print $1}')
if [ -n "$service_unit" ]; then
# Print the service line with highlighting
echo "$line" | sed -${E} "s,$service_unit,${SED_GREEN},"
# Get service file path
service_path=$(systemctl show "$service_unit" -p FragmentPath 2>/dev/null | cut -d= -f2)
if [ -n "$service_path" ]; then
check_service_file "$service_path"
fi
# Check service content for privilege escalation vectors
check_service_content "$service_unit"
fi
done || echo_not_found
# Check service files from PSTORAGE_SYSTEMD
if [ -n "$PSTORAGE_SYSTEMD" ]; then
echo ""
print_3title "Additional service files:"
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read -r service_file; do
if [ -n "$service_file" ] && [ -e "$service_file" ]; then
check_service_file "$service_file"
fi
done
fi
# Check for outdated services if EXTRA_CHECKS is enabled
if [ "$EXTRA_CHECKS" ]; then
echo ""
print_3title "Service versions and status:"
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
fi
# Check systemd path writability
if [ ! "$WRITABLESYSTEMDPATH" ]; then
echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"
else
echo "You can write on systemd PATH" | sed -${E} "s,.*,${SED_RED},"
echo "If a relative path is used, it's possible to abuse it."
fi
echo ""
fi

View File

@ -1,21 +0,0 @@
# Title: Processes & Cron & Services & Timers - System Timers
# ID: PR_System_timers
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: System Timers
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $SEARCH_IN_FOLDER, $timersG
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "System timers"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#timers"
(systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found
echo ""
fi

View File

@ -0,0 +1,156 @@
# Title: System Information - Systemd
# ID: SY_Systemd
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Check for systemd vulnerabilities and misconfigurations that could lead to privilege escalation:
# - Systemd version vulnerabilities (CVE-2021-4034, CVE-2021-33910, etc.)
# - Services running as root that could be exploited
# - Services with dangerous capabilities that could be abused
# - Services with writable paths that could be used to inject malicious code
# - Exploitation methods:
# * Version exploits: Use known exploits for vulnerable systemd versions
# * Root services: Abuse services running as root to execute commands
# * Capabilities: Abuse services with dangerous capabilities (CAP_SYS_ADMIN, etc.)
# * Writable paths: Replace executables in writable paths to get code execution
# License: GNU GPL
# Version: 1.1
# Functions Used: print_2title, print_list, echo_not_found
# Global Variables: $SEARCH_IN_FOLDER, $Wfolders, $SED_RED, $SED_RED_YELLOW, $NC
# Initial Functions:
# Generated Global Variables: $WRITABLESYSTEMDPATH, $line, $service, $file, $version, $user, $caps, $path, $path_line, $service_file, $exec_line, $cmd
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Systemd Information"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#systemd-path---relative-paths"
# Function to check if systemctl is available
check_systemctl() {
if ! command -v systemctl >/dev/null 2>&1; then
echo_not_found "systemctl"
return 1
fi
return 0
}
# Function to get service file path
get_service_file() {
local service="$1"
local file=""
for path in "/etc/systemd/system/$service" "/lib/systemd/system/$service"; do
if [ -f "$path" ]; then
file="$path"
break
fi
done
echo "$file"
}
# Function to check dangerous capabilities
check_dangerous_caps() {
local caps="$1"
echo "$caps" | grep -qE '(CAP_SYS_ADMIN|CAP_DAC_OVERRIDE|CAP_DAC_READ_SEARCH|CAP_SETUID|CAP_SETGID|CAP_NET_ADMIN)'
return $?
}
# Check systemd version and known vulnerabilities
print_list "Systemd version and vulnerabilities? .............. "$NC
if check_systemctl; then
version=$(systemctl --version | head -n 1 | grep -oE '([0-9]+(\.[0-9]+)+)')
if [ -n "$version" ]; then
echo "$version" | sed -${E} "s,([0-9]+(\.[0-9]+)+),${SED_RED},g"
# Check for known vulnerable versions
case "$version" in
"2.3"[0-4]|"2.3"[0-4]"."*)
echo " └─ Vulnerable to CVE-2021-4034 (Polkit)" | sed -${E} "s,.*,${SED_RED},g"
;;
"2.4"[0-9]|"2.4"[0-9]"."*)
echo " └─ Vulnerable to CVE-2021-33910 (systemd-tmpfiles)" | sed -${E} "s,.*,${SED_RED},g"
;;
esac
fi
fi
# Check for systemd services running as root
print_list "Services running as root? ..... "$NC
if check_systemctl; then
systemctl list-units --type=service --state=running 2>/dev/null |
grep -E "root|0:0" |
while read -r line; do
service=$(echo "$line" | awk '{print $1}')
user=$(systemctl show "$service" -p User 2>/dev/null | cut -d= -f2)
echo "$service (User: $user)" | sed -${E} "s,root|0:0,${SED_RED},g"
done
echo ""
else
echo ""
fi
# Check for systemd services with dangerous capabilities
print_list "Running services with dangerous capabilities? ... "$NC
if check_systemctl; then
systemctl list-units --type=service --state=running 2>/dev/null |
grep -E "\.service" |
while read -r line; do
service=$(echo "$line" | awk '{print $1}')
caps=$(systemctl show "$service" -p CapabilityBoundingSet 2>/dev/null | cut -d= -f2)
if [ -n "$caps" ] && check_dangerous_caps "$caps"; then
echo "$service: $caps" | sed -${E} "s,.*,${SED_RED},g"
fi
done
echo ""
else
echo ""
fi
# Check for systemd services with writable paths
print_list "Services with writable paths? . "$NC
if check_systemctl; then
systemctl list-units --type=service --state=running 2>/dev/null |
grep -E "\.service" |
while read -r line; do
service=$(echo "$line" | awk '{print $1}')
service_file=$(get_service_file "$service")
if [ -n "$service_file" ]; then
# Check ExecStart paths
grep -E "ExecStart|ExecStartPre|ExecStartPost" "$service_file" 2>/dev/null |
while read -r exec_line; do
# Extract the first word after ExecStart* as the command
cmd=$(echo "$exec_line" | awk '{print $2}' | tr -d '"')
# Extract the rest as arguments
args=$(echo "$exec_line" | awk '{$1=$2=""; print $0}' | tr -d '"')
# Only check the command path, not arguments
if [ -n "$cmd" ] && [ -w "$cmd" ]; then
echo "$service: $cmd (from $exec_line)" | sed -${E} "s,.*,${SED_RED},g"
fi
# Check for relative paths only in the command, not arguments
if [ -n "$cmd" ] && [ "${cmd#/}" = "$cmd" ] && ! echo "$cmd" | grep -qE '^-|^--'; then
echo "$service: Uses relative path '$cmd' (from $exec_line)" | sed -${E} "s,.*,${SED_RED},g"
fi
done
fi
done
else
echo ""
fi
echo ""
print_2title "Systemd PATH"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#systemd-path---relative-paths"
if check_systemctl; then
systemctl show-environment 2>/dev/null |
grep "PATH" |
while read -r path_line; do
echo "$path_line" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
# Store writable paths for later use
if echo "$path_line" | grep -qE "$Wfolders"; then
WRITABLESYSTEMDPATH="$path_line"
fi
done
fi
echo ""
fi

View File

@ -1,33 +0,0 @@
# Title: Processes & Cron & Services & Timers - .timer files
# ID: PR_Timer_files
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: .timer files
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $IAMROOT, $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables: $timerbinpaths, $relpath
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Analyzing .timer files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#timers"
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
if ! [ "$IAMROOT" ] && [ -w "$t" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$t" | sed -${E} "s,.*,${SED_RED},g"
fi
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
printf "%s\n" "$timerbinpaths" | while read tb; do
if [ -w "$tb" ]; then
echo "$t timer is calling this writable executable: $tb" | sed "s,writable.*,${SED_RED},g"
fi
done
#relpath="`grep -Po '^Unit=[^/].*' \"$t\" 2>/dev/null`"
#for rp in "$relpath"; do
# echo "$t is calling a relative path: $rp" | sed "s,relative.*,${SED_RED},g"
#done
done
echo ""

View File

@ -1,23 +0,0 @@
# Title: Processes & Cron & Services & Timers - Services
# ID: PR_Services
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Services outdated versions
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $EXTRA_CHECKS, $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$EXTRA_CHECKS" ]; then
print_2title "Services"
print_info "Search for outdated versions"
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
echo ""
fi
fi

View File

@ -0,0 +1,146 @@
# Title: Processes & Cron & Services & Timers - Socket Files Analysis
# ID: PR_Socket_files
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Analyze .socket files for privilege escalation vectors:
# - Writable socket files
# - Socket files executing writable binaries
# - Socket files with writable listeners
# - Socket files with relative paths
# - Socket files with unsafe configurations
# License: GNU GPL
# Version: 1.2
# Functions Used: print_2title, print_info, print_list
# Global Variables: $IAMROOT, $SEARCH_IN_FOLDER, $SED_RED, $SED_RED_YELLOW, $NC
# Initial Functions:
# Generated Global Variables: $exec_path, $listen_path, $path, $exec_paths, $finding, $listen_paths, $socket_file, $findings, $target_file, $target_listen, $target_exec, $lpath
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$IAMROOT" ]; then
print_2title "Analyzing .socket files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sockets"
# Function to check if path is relative
is_relative_path() {
local lpath="$1"
case "$lpath" in
/*) return 1 ;; # Absolute path
*) return 0 ;; # Relative path
esac
}
# Function to check socket file content
check_socket_file() {
local socket_file="$1"
local findings=""
# Check if socket file is writable (following symlinks)
if [ -L "$socket_file" ]; then
# If it's a symlink, check the target file
local target_file=$(readlink -f "$socket_file")
if ! [ "$IAMROOT" ] && [ -w "$target_file" ] && [ -f "$target_file" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
findings="${findings}WRITABLE_FILE: Socket target file is writable: $target_file\n"
fi
elif ! [ "$IAMROOT" ] && [ -w "$socket_file" ] && [ -f "$socket_file" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
findings="${findings}WRITABLE_FILE: Socket file is writable\n"
fi
# Check for weak permissions (following symlinks)
if [ "$(stat -L -c %a "$socket_file" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_PERMS: Socket file has 777 permissions\n"
fi
# Check for executables (following symlinks)
local exec_paths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$socket_file" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$exec_paths" | while read -r exec_path; do
if [ -n "$exec_path" ]; then
# Check if executable is writable (following symlinks)
if [ -L "$exec_path" ]; then
local target_exec=$(readlink -f "$exec_path")
if [ -w "$target_exec" ]; then
findings="${findings}WRITABLE_EXEC: Executable target is writable: $target_exec\n"
fi
# Check for weak permissions on target
if [ -e "$target_exec" ] && [ "$(stat -L -c %a "$target_exec" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_EXEC_PERMS: Executable target has 777 permissions: $target_exec\n"
fi
else
if [ -w "$exec_path" ]; then
findings="${findings}WRITABLE_EXEC: Executable is writable: $exec_path\n"
fi
# Check for weak permissions
if [ -e "$exec_path" ] && [ "$(stat -L -c %a "$exec_path" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_EXEC_PERMS: Executable has 777 permissions: $exec_path\n"
fi
fi
# Check for relative paths
if is_relative_path "$exec_path"; then
findings="${findings}RELATIVE_PATH: Uses relative path: $exec_path\n"
fi
fi
done
# Check for listeners (following symlinks)
local listen_paths=$(grep -Eo '^(Listen).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$socket_file" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$listen_paths" | while read -r listen_path; do
if [ -n "$listen_path" ]; then
# Check if listener path is writable (following symlinks)
if [ -L "$listen_path" ]; then
local target_listen=$(readlink -f "$listen_path")
if [ -w "$target_listen" ]; then
findings="${findings}WRITABLE_LISTENER: Listener target path is writable: $target_listen\n"
fi
# Check for weak permissions on target
if [ -e "$target_listen" ] && [ "$(stat -L -c %a "$target_listen" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_LISTENER_PERMS: Listener target path has 777 permissions: $target_listen\n"
fi
else
if [ -w "$listen_path" ]; then
findings="${findings}WRITABLE_LISTENER: Listener path is writable: $listen_path\n"
fi
# Check for weak permissions
if [ -e "$listen_path" ] && [ "$(stat -L -c %a "$listen_path" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_LISTENER_PERMS: Listener path has 777 permissions: $listen_path\n"
fi
fi
# Check for relative paths
if is_relative_path "$listen_path"; then
findings="${findings}RELATIVE_LISTENER: Uses relative path: $listen_path\n"
fi
fi
done
# Check for unsafe configurations
if grep -qE '^(User|Group)=root' "$socket_file" 2>/dev/null; then
findings="${findings}ROOT_USER: Socket runs as root\n"
fi
if grep -qE '^(CapabilityBoundingSet).*CAP_SYS_ADMIN' "$socket_file" 2>/dev/null; then
findings="${findings}DANGEROUS_CAPS: Has dangerous capabilities\n"
fi
if grep -qE '^(BindIP|BindIPv6Only)=yes' "$socket_file" 2>/dev/null; then
findings="${findings}NETWORK_BIND: Can bind to network interfaces\n"
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo "Potential privilege escalation in socket file: $socket_file"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding" | sed -${E} "s,WRITABLE.*,${SED_RED},g" | sed -${E} "s,RELATIVE.*,${SED_RED_YELLOW},g"
done
fi
}
# Process each socket file
if [ -n "$PSTORAGE_SOCKET" ]; then
printf "%s\n" "$PSTORAGE_SOCKET" | while read -r socket_file; do
if [ -n "$socket_file" ] && [ -e "$socket_file" ]; then
check_socket_file "$socket_file"
fi
done
else
print_list "No socket files found" "$NC"
fi
echo ""
fi

View File

@ -1,42 +0,0 @@
# Title: Processes & Cron & Services & Timers - Analyzing .service files
# ID: PR_Service_files
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Analyze .service files
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $IAMROOT, $SEARCH_IN_FOLDER, $WRITABLESYSTEMDPATH
# Initial Functions:
# Generated Global Variables: $relpath1, $relpath2, $servicebinpaths
# Fat linpeas: 0
# Small linpeas: 0
#TODO: .service files in MACOS are folders
print_2title "Analyzing .service files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#services"
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
if [ ! -O "" ] || [ "$SEARCH_IN_FOLDER" ]; then #Remove services that belongs to the current user or if firmware see everything
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
printf "%s\n" "$servicebinpaths" | while read sp; do
if [ -w "$sp" ]; then
echo "$s is calling this writable executable: $sp" | sed "s,writable.*,${SED_RED_YELLOW},g"
fi
done
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null)
if [ "$relpath1" ] || [ "$relpath2" ]; then
if [ "$WRITABLESYSTEMDPATH" ]; then
echo "$s could be executing some relative path" | sed -${E} "s,.*,${SED_RED},";
else
echo "$s could be executing some relative path"
fi
fi
fi
done
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
echo ""

View File

@ -0,0 +1,151 @@
# Title: Processes & Cron & Services & Timers - Unix Sockets Analysis
# ID: PR_Unix_sockets_listening
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Analyze Unix sockets for privilege escalation vectors:
# - Listening Unix sockets
# - Socket file permissions
# - Socket ownership
# - Socket connectivity
# - Socket protocol analysis
# License: GNU GPL
# Version: 1.1
# Functions Used: print_2title, print_info
# Global Variables: $EXTRA_CHECKS, $groupsB, $groupsVB, $IAMROOT, $idB, $knw_grps, $knw_usrs, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $SED_RED, $SED_GREEN, $NC, $RED
# Initial Functions:
# Generated Global Variables: $unix_scks_list, $unix_scks_list2, $perms, $owner, $owner_info, $response, $socket, $cmd, $mode, $group
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$IAMROOT" ]; then
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Unix Sockets Analysis"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sockets"
# Function to get socket permissions
get_socket_perms() {
local socket="$1"
local perms=""
# Check read permission
if [ -r "$socket" ]; then
perms="Read "
fi
# Check write permission
if [ -w "$socket" ]; then
perms="${perms}Write "
fi
# Check execute permission
if [ -x "$socket" ]; then
perms="${perms}Execute "
fi
# Check socket mode
local mode=$(stat -c "%a" "$socket" 2>/dev/null)
if [ "$mode" = "777" ] || [ "$mode" = "666" ]; then
perms="${perms}(Weak Permissions: $mode) "
fi
echo "$perms"
}
# Function to check socket connectivity
check_socket_connectivity() {
local socket="$1"
local perms="$2"
if [ "$EXTRA_CHECKS" ] && command -v curl >/dev/null 2>&1; then
# Try to connect to the socket
if curl -v --unix-socket "$socket" --max-time 1 http:/linpeas 2>&1 | grep -iq "Permission denied"; then
perms="${perms} - Cannot Connect"
else
perms="${perms} - Can Connect"
fi
fi
echo "$perms"
}
# Function to analyze socket protocol
analyze_socket_protocol() {
local socket="$1"
local owner="$2"
local response=""
# Try to get HTTP response
if command -v curl >/dev/null 2>&1; then
response=$(curl --max-time 2 --unix-socket "$socket" http:/index 2>/dev/null)
if [ $? -eq 0 ]; then
echo " └─ HTTP Socket (owned by $owner):" | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g"
echo " └─ Response to /index (limit 30):"
echo "$response" | head -n 30 | sed 's/^/ /'
fi
fi
}
# Function to get socket owner and group
get_socket_owner() {
local socket="$1"
local owner=""
local group=""
if [ -e "$socket" ]; then
owner=$(ls -l "$socket" 2>/dev/null | awk '{print $3}')
group=$(ls -l "$socket" 2>/dev/null | awk '{print $4}')
echo "$owner:$group"
fi
}
# Collect listening sockets using multiple methods
unix_scks_list=""
for cmd in "ss -xlp -H state listening" "ss -l -p -A 'unix'" "netstat -a -p --unix"; do
if [ -z "$unix_scks_list" ]; then
unix_scks_list=$($cmd 2>/dev/null | grep -Eo "/[a-zA-Z0-9\._/\-]+" | grep -v " " | sort -u)
fi
done
# Get additional socket information
if [ -z "$unix_scks_list" ]; then
unix_scks_list=$(lsof -U 2>/dev/null | awk '{print $9}' | grep "/" | sort -u)
fi
# Find socket files
if ! [ "$SEARCH_IN_FOLDER" ]; then
unix_scks_list2=$(find / -type s 2>/dev/null)
else
unix_scks_list2=$(find "$SEARCH_IN_FOLDER" -type s 2>/dev/null)
fi
# Process all found sockets
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2") | sort -u | while read -r socket; do
if [ -n "$socket" ] && [ -e "$socket" ]; then
# Get socket information
perms=$(get_socket_perms "$socket")
perms=$(check_socket_connectivity "$socket" "$perms")
owner_info=$(get_socket_owner "$socket")
# Print socket information
if [ -z "$perms" ]; then
echo "$socket" | sed -${E} "s,$socket,${SED_GREEN},g"
else
echo "$socket" | sed -${E} "s,$socket,${SED_RED},g"
echo " └─(${RED}${perms}${NC})" | sed -${E} "s,Cannot Connect,${SED_GREEN},g"
# Analyze socket protocol if we can connect
if echo "$perms" | grep -q "Can Connect"; then
analyze_socket_protocol "$socket" "$owner_info"
fi
# Highlight dangerous ownership
if echo "$owner_info" | grep -q "root"; then
echo " └─(${RED}Owned by root${NC})"
fi
fi
fi
done
fi
echo ""
fi

View File

@ -0,0 +1,253 @@
# Title: Processes & Cron & Services & Timers - D-Bus Analysis
# ID: PR_DBus_analysis
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Comprehensive D-Bus analysis for privilege escalation vectors:
# - D-Bus Service Objects enumeration
# - D-Bus Service Object permissions and ownership
# - D-Bus Configuration files analysis
# - D-Bus Policy analysis
# - D-Bus Method and Interface analysis
# - D-Bus Privilege Escalation Vectors
# License: GNU GPL
# Version: 1.3
# Functions Used: print_2title, print_3title, print_info, echo_not_found
# Global Variables: $IAMROOT, $mygroups, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $dbuslistG, $knw_usrs, $rootcommon, $SED_RED, $SED_GREEN, $SED_BLUE, $SED_LIGHT_CYAN, $SED_LIGHT_MAGENTA, $NC
# Initial Functions:
# Generated Global Variables: $dbuslist, $srvc_object, $genpol, $userpol, $grppol, $dangerous_service, $pattern, $dir, $weak_policies, $dangerous_services, $dangerous, $dbussrvc_object, $patterns, $methods, $file, $dbusservice, $session_services, $prop, $dangerous_session_services, $interface, $dangerous_methods, $dbus_file, $dbus_service, $method, $dangerous_patterns, $properties, $interfaces, $dangerous_props, $service, $info, $allow_rules
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "D-Bus Analysis"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#d-bus"
# Function to check for dangerous methods
check_dangerous_methods() {
service="$1"
interface="$2"
dangerous=0
dangerous_methods=""
# Common dangerous method patterns - using space-separated string instead of array
patterns="StartUnit StopUnit RestartUnit EnableUnit DisableUnit SetProperty SetUser SetPassword CreateUser DeleteUser ModifyUser Execute Run Spawn Shell Command Exec Authenticate Login Logout Reboot Shutdown PowerOff Suspend Hibernate Update Install Uninstall Configure Modify Change Delete Remove Add Create Write Read Access Grant Revoke Allow Deny"
# Get methods for the interface
methods=$(busctl introspect "$service" "$interface" 2>/dev/null | grep "method" | awk '{print $2}')
# Check each method against dangerous patterns
for method in $methods; do
for pattern in $patterns; do
if echo "$method" | grep -qi "$pattern"; then
dangerous=1
dangerous_methods="${dangerous_methods}${method} "
fi
done
done
if [ "$dangerous" -eq 1 ]; then
echo " └─(${RED}Potentially dangerous methods found${NC})"
echo " └─ $dangerous_methods" | sed 's/^/ /'
fi
return $dangerous
}
# Function to check for dangerous properties
check_dangerous_properties() {
service="$1"
interface="$2"
dangerous=0
dangerous_props=""
# Common dangerous property patterns - using space-separated string instead of array
patterns="Executable Command Path User Group Permission Access Auth Password Secret Key Token Credential Config Setting Policy Rule Allow Deny Write Read Execute"
# Get properties for the interface
properties=$(busctl introspect "$service" "$interface" 2>/dev/null | grep "property" | awk '{print $2}')
# Check each property against dangerous patterns
for prop in $properties; do
for pattern in $patterns; do
if echo "$prop" | grep -qi "$pattern"; then
dangerous=1
dangerous_props="${dangerous_props}${prop} "
fi
done
done
if [ "$dangerous" -eq 1 ]; then
echo " └─(${RED}Potentially dangerous properties found${NC})"
echo " └─ $dangerous_props" | sed 's/^/ /'
fi
return $dangerous
}
# Function to analyze service object
analyze_service_object() {
dbusservice="$1"
info=""
dangerous=0
# Get service status
info=$(busctl status "$dbusservice" 2>/dev/null)
# Check for root ownership
if echo "$info" | grep -qE "^(UID|EUID|OwnerUID)=0"; then
echo " └─(${RED}Running as root${NC})"
dangerous=1
fi
# Get service interfaces
interfaces=$(busctl tree "$dbusservice" 2>/dev/null)
if [ -n "$interfaces" ]; then
echo " └─ Interfaces:"
echo "$interfaces" | sed 's/^/ /'
# Check each interface for dangerous methods and properties
echo "$interfaces" | while read -r interface; do
if [ -n "$interface" ]; then
if check_dangerous_methods "$dbusservice" "$interface"; then
dangerous=1
fi
if check_dangerous_properties "$dbusservice" "$interface"; then
dangerous=1
fi
fi
done
fi
# Check for known dangerous services - using space-separated string instead of array
dangerous_services="org.freedesktop.systemd1 org.freedesktop.PolicyKit1 org.freedesktop.Accounts org.freedesktop.login1 org.freedesktop.hostname1 org.freedesktop.timedate1 org.freedesktop.locale1 org.freedesktop.machine1 org.freedesktop.portable1 org.freedesktop.resolve1 org.freedesktop.timesync1 org.freedesktop.import1 org.freedesktop.export1 org.gnome.SettingsDaemon org.gnome.Shell org.gnome.SessionManager org.gnome.DisplayManager org.gnome.ScreenSaver"
for dangerous_service in $dangerous_services; do
if echo "$dbusservice" | grep -qi "$dangerous_service"; then
echo " └─(${RED}Known dangerous service: $dangerous_service${NC})"
dangerous=1
fi
done
# If service is dangerous, provide exploitation hints
if [ "$dangerous" -eq 1 ]; then
echo " └─(${RED}Potential privilege escalation vector${NC})"
echo " └─ Try: busctl call $dbusservice / [Interface] [Method] [Arguments]"
echo " └─ Or: dbus-send --session --dest=$dbusservice / [Interface] [Method] [Arguments]"
fi
}
# Function to analyze policy file
analyze_policy_file() {
file="$1"
weak_policies=0
# Check file permissions
if ! [ "$IAMROOT" ] && [ -w "$file" ]; then
echo " └─(${RED}Writable policy file${NC})"
weak_policies=$((weak_policies + 1))
fi
# Check general policy
genpol=$(grep "<policy>" "$file" 2>/dev/null)
if [ -n "$genpol" ]; then
echo " └─(${RED}Weak general policy found${NC})"
echo " └─ $genpol" | sed 's/^/ /'
weak_policies=$((weak_policies + 1))
fi
# Check user policies
userpol=$(grep "<policy user=" "$file" 2>/dev/null | grep -v "root")
if [ -n "$userpol" ]; then
echo " └─(${RED}Weak user policy found${NC})"
echo " └─ $userpol" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g"
weak_policies=$((weak_policies + 1))
fi
# Check group policies
grppol=$(grep "<policy group=" "$file" 2>/dev/null | grep -v "root")
if [ -n "$grppol" ]; then
echo " └─(${RED}Weak group policy found${NC})"
echo " └─ $grppol" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"
weak_policies=$((weak_policies + 1))
fi
# Check for allow rules in default context
allow_rules=$(grep -A 5 "context=\"default\"" "$file" 2>/dev/null | grep "allow")
if [ -n "$allow_rules" ]; then
echo " └─(${RED}Allow rules in default context${NC})"
echo " └─ $allow_rules" | sed 's/^/ /'
weak_policies=$((weak_policies + 1))
fi
# Check for specific dangerous policy patterns - using space-separated string instead of array
dangerous_patterns="allow_any allow_all allow_root allow_user allow_group allow_anonymous allow_any_user allow_any_group allow_any_uid allow_any_gid allow_any_pid allow_any_connection allow_any_method allow_any_property allow_any_signal allow_any_interface allow_any_path allow_any_destination allow_any_sender allow_any_receiver"
for pattern in $dangerous_patterns; do
if grep -qi "$pattern" "$file" 2>/dev/null; then
echo " └─(${RED}Dangerous policy pattern found: $pattern${NC})"
weak_policies=$((weak_policies + 1))
fi
done
return $weak_policies
}
# Analyze D-Bus Service Objects
dbuslist=$(busctl list 2>/dev/null)
if [ -n "$dbuslist" ]; then
echo "$dbuslist" | while read -r dbus_service; do
# Print service name with highlighting
echo "$dbus_service" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
# Analyze service if it's not in the known list
if ! echo "$dbus_service" | grep -qE "$dbuslistG"; then
dbussrvc_object=$(echo "$dbus_service" | cut -d " " -f1)
analyze_service_object "$dbussrvc_object"
fi
done
else
echo_not_found "busctl"
fi
# Analyze D-Bus Configuration Files
if [ "$PSTORAGE_DBUS" ]; then
echo ""
print_2title "D-Bus Configuration Files"
echo "$PSTORAGE_DBUS" | while read -r dir; do
for dbus_file in "$dir"/*; do
if [ -f "$dbus_file" ]; then
echo "Analyzing $dbus_file:"
if analyze_policy_file "$dbus_file"; then
echo " └─(${RED}Multiple weak policies found${NC})"
fi
fi
done
done
fi
# Check for D-Bus session bus
if command -v dbus-send >/dev/null 2>&1; then
echo ""
print_3title "D-Bus Session Bus Analysis"
if dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>/dev/null | grep -q "Error"; then
echo "(${RED}No access to session bus${NC})"
else
echo "(${GREEN}Access to session bus available${NC})"
# List available services on session bus
session_services=$(dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>/dev/null | grep "string" | sed 's/^/ /')
echo "$session_services"
# Check for known dangerous session services - using space-separated string instead of array
dangerous_session_services="org.gnome.SettingsDaemon org.gnome.Shell org.gnome.SessionManager org.gnome.DisplayManager org.gnome.ScreenSaver org.freedesktop.Notifications org.freedesktop.ScreenSaver org.freedesktop.PowerManagement org.freedesktop.UPower org.freedesktop.NetworkManager org.freedesktop.Avahi org.freedesktop.UDisks2 org.freedesktop.ModemManager1 org.freedesktop.PackageKit org.freedesktop.PolicyKit1 org.freedesktop.systemd1 org.freedesktop.Accounts org.freedesktop.login1"
for dangerous_service in $dangerous_session_services; do
if echo "$session_services" | grep -qi "$dangerous_service"; then
echo " └─(${RED}Known dangerous session service: $dangerous_service${NC})"
echo " └─ Try: dbus-send --session --dest=$dangerous_service / [Interface] [Method] [Arguments]"
fi
done
fi
fi
fi
echo ""

View File

@ -1,75 +0,0 @@
# Title: System Information - Systemd
# ID: PR_Systemd
# Author: Carlos Polop
# Last Update: 07-03-2024
# Description: Check for systemd vulnerabilities and misconfigurations that could lead to privilege escalation:
# - Systemd version vulnerabilities (CVE-2021-4034, CVE-2021-33910, etc.)
# - Services running as root that could be exploited
# - Services with dangerous capabilities that could be abused
# - Services with writable paths that could be used to inject malicious code
# - Exploitation methods:
# * Version exploits: Use known exploits for vulnerable systemd versions
# * Root services: Abuse services running as root to execute commands
# * Capabilities: Abuse services with dangerous capabilities (CAP_SYS_ADMIN, etc.)
# * Writable paths: Replace executables in writable paths to get code execution
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, print_list
# Global Variables:
# Initial Functions:
# Generated Global Variables: $sys_service, $exec_path
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Systemd Information"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#services"
# Check systemd version
print_list "Systemd version? .............. "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
systemctl --version | head -n 1 | sed -${E} "s,([0-9]+(\.[0-9]+)+),${SED_RED},g"
else
echo_not_found "systemctl"
fi
# Check for systemd services running as root
print_list "Services running as root? ..... "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
systemctl list-units --type=service --state=running 2>/dev/null | grep -E "root|0:0" | sed -${E} "s,root|0:0,${SED_RED},g"
else
echo_not_found "systemctl"
fi
# Check for systemd services with capabilities
print_list "Running services with capabilities? ... "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
for sys_service in $(systemctl list-units --type=service --state=running 2>/dev/null | grep -E "\.service" | awk '{print $1}'); do
if [ -f "/etc/systemd/system/$sys_service" ] || [ -f "/lib/systemd/system/$sys_service" ]; then
if grep -q "CapabilityBoundingSet" "/etc/systemd/system/$sys_service" "/lib/systemd/system/$sys_service" 2>/dev/null; then
echo "$sys_service" | sed -${E} "s,.*,${SED_RED},g"
fi
fi
done
else
echo_not_found "systemctl"
fi
# Check for systemd services with writable paths
print_list "Running services with writable paths? . "$NC
if [ "$(command -v systemctl 2>/dev/null || echo -n '')" ]; then
for sys_service in $(systemctl list-units --type=service --state=running 2>/dev/null | grep -E "\.service" | awk '{print $1}'); do
if [ -f "/etc/systemd/system/$sys_service" ] || [ -f "/lib/systemd/system/$sys_service" ]; then
if grep -q "ExecStart\|ExecStartPre\|ExecStartPost" "/etc/systemd/system/$sys_service" "/lib/systemd/system/$sys_service" 2>/dev/null; then
for exec_path in $(grep -E "ExecStart|ExecStartPre|ExecStartPost" "/etc/systemd/system/$sys_service" "/lib/systemd/system/$sys_service" 2>/dev/null | awk '{print $2}' | tr -d '"'); do
if [ -w "$exec_path" ]; then
echo "$sys_service: $exec_path" | sed -${E} "s,.*,${SED_RED},g"
fi
done
fi
fi
done
else
echo_not_found "systemctl"
fi
echo ""

View File

@ -1,38 +0,0 @@
# Title: Processes & Cron & Services & Timers - .socket files
# ID: PR_Socket_files
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: .socket files
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $IAMROOT, $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables: $socketsbinpaths, $socketslistpaths
# Fat linpeas: 0
# Small linpeas: 0
#TODO: .socket files in MACOS are folders
if ! [ "$IAMROOT" ]; then
print_2title "Analyzing .socket files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sockets"
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
fi
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketsbinpaths" | while read sb; do
if [ -w "$sb" ]; then
echo "$s is calling this writable executable: $sb" | sed "s,writable.*,${SED_RED},g"
fi
done
socketslistpaths=$(grep -Eo '^(Listen).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketslistpaths" | while read sl; do
if [ -w "$sl" ]; then
echo "$s is calling this writable listener: $sl" | sed "s,writable.*,${SED_RED},g";
fi
done
done
echo ""
fi

View File

@ -1,72 +0,0 @@
# Title: Processes & Cron & Services & Timers - Unix Sockets Listening
# ID: PR_Unix_sockets_listening
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Unix Sockets Listening
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $EXTRA_CHECKS, $groupsB, $groupsVB, $IAMROOT, $idB, $knw_grps, $knw_usrs, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables: $unix_scks_list, $unix_scks_list2, $unix_scks_list3, $perms, $socketcurl, $owner, $CANNOT_CONNECT_TO_SOCKET
# Fat linpeas: 0
# Small linpeas: 0
#TODO: .socket files in MACOS are folders
if ! [ "$IAMROOT" ]; then
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Unix Sockets Listening"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sockets"
# Search sockets using netstat and ss
unix_scks_list=$(ss -xlp -H state listening 2>/dev/null | grep -Eo "/.* " | cut -d " " -f1)
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(ss -l -p -A 'unix' 2>/dev/null | grep -Ei "listen|Proc" | grep -Eo "/[a-zA-Z0-9\._/\-]+")
fi
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
fi
unix_scks_list3=$(lsof -U 2>/dev/null | awk '{print $9}' | grep "/")
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
# But also search socket files
unix_scks_list2=$(find / -type s 2>/dev/null)
else
unix_scks_list2=$(find "SEARCH_IN_FOLDER" -type s 2>/dev/null)
fi
# Detele repeated dockets and check permissions
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2" && printf "%s\n" "$unix_scks_list3") | sort | uniq | while read l; do
perms=""
if [ -r "$l" ]; then
perms="Read "
fi
if [ -w "$l" ];then
perms="${perms}Write"
fi
if [ "$EXTRA_CHECKS" ] && [ "$(command -v curl || echo -n '')" ]; then
CANNOT_CONNECT_TO_SOCKET="$(curl -v --unix-socket "$l" --max-time 1 http:/linpeas 2>&1 | grep -i 'Permission denied')"
if ! [ "$CANNOT_CONNECT_TO_SOCKET" ]; then
perms="${perms} - Can Connect"
else
perms="${perms} - Cannot Connect"
fi
fi
if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g";
else
echo "$l" | sed -${E} "s,$l,${SED_RED},g"
echo " └─(${RED}${perms}${NC})" | sed -${E} "s,Cannot Connect,${SED_GREEN},g"
# Try to contact the socket
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
if [ $? -eq 0 ]; then
owner=$(ls -l "$s" | cut -d ' ' -f 3)
echo "Socket $s owned by $owner uses HTTP. Response to /index: (limt 30)" | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g"
echo "$socketcurl" | head -n 30
fi
fi
done
echo ""
fi

View File

@ -1,33 +0,0 @@
# Title: Processes & Cron & Services & Timers - D-Bus Service Objects list
# ID: PR_DBus_service_objects_list
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Enumerate D-Bus Service Objects list
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $dbuslistG, $knw_usrs, $nosh_usrs, $rootcommon, $SEARCH_IN_FOLDER, $USER
# Initial Functions:
# Generated Global Variables: $dbuslist, $srvc_object, $srvc_object_info
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "D-Bus Service Objects list"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#d-bus"
dbuslist=$(busctl list 2>/dev/null)
if [ "$dbuslist" ]; then
busctl list | while read l; do
echo "$l" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},";
if ! echo "$l" | grep -qE "$dbuslistG"; then
srvc_object=$(echo $l | cut -d " " -f1)
srvc_object_info=$(busctl status "$srvc_object" 2>/dev/null | grep -E "^UID|^EUID|^OwnerUID" | tr '\n' ' ')
if [ "$srvc_object_info" ]; then
echo " -- $srvc_object_info" | sed "s,UID=0,${SED_RED},"
fi
fi
done
else echo_not_found "busctl"
fi
fi

View File

@ -1,40 +0,0 @@
# Title: Processes & Cron & Services & Timers - D-Bus config files
# ID: PR_DBus_config_files
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Enumerate D-Bus config files
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $IAMROOT, $mygroups, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables: $genpol, $userpol, $grppol
# Fat linpeas: 0
# Small linpeas: 0
print_2title "D-Bus config files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#d-bus"
if [ "$PSTORAGE_DBUS" ]; then
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
for f in $d/*; do
if ! [ "$IAMROOT" ] && [ -w "$f" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
fi
genpol=$(grep "<policy>" "$f" 2>/dev/null)
if [ "$genpol" ]; then printf "Weak general policy found on $f ($genpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#if [ "`grep \"<policy user=\\\"$USER\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak user policy found on $f () \n" | sed "s,$USER,${SED_RED},g"; fi
userpol=$(grep "<policy user=" "$f" 2>/dev/null | grep -v "root")
if [ "$userpol" ]; then printf "Possible weak user policy found on $f ($userpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#for g in `groups`; do
# if [ "`grep \"<policy group=\\\"$g\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak group ($g) policy found on $f\n" | sed "s,$g,${SED_RED},g"; fi
#done
grppol=$(grep "<policy group=" "$f" 2>/dev/null | grep -v "root")
if [ "$grppol" ]; then printf "Possible weak user policy found on $f ($grppol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#TODO: identify allows in context="default"
done
done
fi
echo ""

View File

@ -1,37 +1,227 @@
# Title: Processes & Cron & Services & Timers - List proccesses
# Title: Processes & Cron & Services & Timers - List processes
# ID: PR_List_processes
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: List running proccesses removing the ones that aren't interesting
# Last Update: 2024-03-19
# Description: List running processes and check for unusual configurations
# License: GNU GPL
# Version: 1.0
# Version: 1.4
# Functions Used: print_2title, print_info, print_ps
# Global Variables: $capsB, $knw_usrs, $nosh_usrs, $NOUSEPS, $processesB, $processesDump, $processesVB, $rootcommon, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $Wfolders
# Initial Functions:
# Generated Global Variables: $pslist, $cpid, $caphex, $psline
# Generated Global Variables: $pslist, $cpid, $caphex, $psline, $pid, $selinux_ctx, $current_env_vars, $env_findings, $apparmor_profile, $mount, $mount_findings, $fd_findings, $proc_cmd, $proc_user, $mount_point, $current_mounts, $fd_target, $var, $findings, $sec_findings, $proc_env_vars, $fd_count, $proc_mounts, $$escaped_var
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Running processes (cleaned)"
if [ "$NOUSEPS" ]; then
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
fi
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#processes"
print_info "Check weird & unexpected processes run by root: https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#processes"
if [ -f "/etc/fstab" ] && cat /etc/fstab | grep -q "hidepid=2"; then
echo "Looks like /etc/fstab has hidepid=2, so ps will not show processes of other users"
fi
# Get current process environment variables
if [ -r "/proc/self/environ" ]; then
current_env_vars=$(cat /proc/self/environ 2>/dev/null | tr '\0' '\n' | sort)
else
current_env_vars=$(env 2>/dev/null | sort)
fi
# Get current process mounts
if [ -r "/proc/self/mountinfo" ]; then
current_mounts=$(cat /proc/self/mountinfo 2>/dev/null | sort)
else
current_mounts=$(mount 2>/dev/null | sort)
fi
# Function to check for unusual environment variables
check_env_vars() {
local pid="$1"
local proc_user="$2"
local proc_cmd="$3"
local findings=""
# Skip if we can't read the environment
[ ! -r "/proc/$pid/environ" ] && return
# Get process environment variables
proc_env_vars=$(cat "/proc/$pid/environ" 2>/dev/null | tr '\0' '\n' | sort)
[ -z "$proc_env_vars" ] && return
# Find environment variables that the target process has but we don't
if [ -n "$current_env_vars" ]; then
echo "$proc_env_vars" | while read -r var; do
if [ -n "$var" ]; then
# Escape special regex characters in var
escaped_var=$(echo "$var" | sed 's/[][^$.*+?(){}|]/\\&/g')
if ! echo "$current_env_vars" | grep -q "^$escaped_var$"; then
if [ -z "$findings" ]; then
findings="Has additional environment variables:"
fi
findings="$findings\n └─ $var"
fi
fi
done
else
# If we can't get current env vars, just show all process env vars
findings="Has environment variables:"
echo "$proc_env_vars" | while read -r var; do
if [ -n "$var" ]; then
findings="$findings\n └─ $var"
fi
done
fi
# Return findings if any
if [ -n "$findings" ]; then
echo "$findings"
fi
}
# Function to check for unusual security contexts
check_security_context() {
local pid="$1"
local proc_user="$2"
local proc_cmd="$3"
local findings=""
# Check SELinux context
if [ -r "/proc/$pid/attr/current" ]; then
selinux_ctx=$(cat "/proc/$pid/attr/current" 2>/dev/null)
if [ -n "$selinux_ctx" ] && [ "$selinux_ctx" != "unconfined" ]; then
findings="SELinux context: $selinux_ctx"
fi
fi
# Check AppArmor profile
if [ -r "/proc/$pid/attr/apparmor/current" ]; then
apparmor_profile=$(cat "/proc/$pid/attr/apparmor/current" 2>/dev/null)
if [ -n "$apparmor_profile" ] && [ "$apparmor_profile" != "unconfined" ]; then
if [ -n "$findings" ]; then
findings="$findings\n └─ AppArmor profile: $apparmor_profile"
else
findings="AppArmor profile: $apparmor_profile"
fi
fi
fi
# Return findings if any
if [ -n "$findings" ]; then
echo "$findings"
fi
}
# Function to check for unusual mount namespaces
check_mount_namespace() {
local pid="$1"
local proc_user="$2"
local proc_cmd="$3"
local findings=""
# Skip if we can't read the mountinfo
[ ! -r "/proc/$pid/mountinfo" ] && return
# Get process mounts
proc_mounts=$(cat "/proc/$pid/mountinfo" 2>/dev/null | sort)
[ -z "$proc_mounts" ] && return
# Find mounts that the target process has but we don't
if [ -n "$current_mounts" ]; then
echo "$proc_mounts" | while read -r mount; do
if [ -n "$mount" ] && ! echo "$current_mounts" | grep -q "^$mount$"; then
mount_point=$(echo "$mount" | sed "s,.* - \(.*\),\1,")
if [ -z "$findings" ]; then
findings="Has additional mounts:"
fi
findings="$findings\n └─ $mount_point"
fi
done
else
# If we can't get current mounts, just show all process mounts
findings="Has mounts:"
echo "$proc_mounts" | while read -r mount; do
if [ -n "$mount" ]; then
mount_point=$(echo "$mount" | sed "s,.* - \(.*\),\1,")
findings="$findings\n └─ $mount_point"
fi
done
fi
# Return findings if any
if [ -n "$findings" ]; then
echo "$findings"
fi
}
# Function to check for unusual file descriptors
check_file_descriptors() {
local pid="$1"
local proc_user="$2"
local proc_cmd="$3"
local findings=""
# Skip if we can't read the file descriptors
[ ! -r "/proc/$pid/fd" ] && return
# Check for interesting file descriptors
for fd in /proc/$pid/fd/*; do
# Skip if fd doesn't exist or we can't access it
[ ! -e "$fd" ] && continue
# Get fd target
fd_target=$(readlink "$fd" 2>/dev/null)
[ -z "$fd_target" ] && continue
# Skip if target doesn't exist
[ ! -e "$fd_target" ] && continue
# Check if we can access the FD but not the target file
if [ -r "$fd" ] && [ ! -r "$fd_target" ]; then
if [ -z "$findings" ]; then
findings="Readable FD to unreadable file: $fd -> $fd_target"
else
findings="$findings\n └─ Readable FD to unreadable file: $fd -> $fd_target"
fi
fi
if [ -w "$fd" ] && [ ! -w "$fd_target" ]; then
if [ -z "$findings" ]; then
findings="Writable FD to unwritable file: $fd -> $fd_target"
else
findings="$findings\n └─ Writable FD to unwritable file: $fd -> $fd_target"
fi
fi
done
# Check for unusual number of file descriptors
fd_count=$(ls -1 "/proc/$pid/fd" 2>/dev/null | wc -l)
[ -z "$fd_count" ] && return
# If process has more than 100 file descriptors, it might be interesting
if [ "$fd_count" -gt 100 ]; then
if [ -z "$findings" ]; then
findings="Unusual number of FDs: $fd_count"
else
findings="$findings\n └─ Unusual number of FDs: $fd_count"
fi
fi
# Return findings if any
if [ -n "$findings" ]; then
echo "$findings"
fi
}
if [ "$NOUSEPS" ]; then
print_ps | grep -v 'sed-Es' | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
pslist=$(print_ps)
else
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
if [ "$(command -v capsh || echo -n '')" ] && ! echo "$psline" | grep -q root; then
if [ "$(command -v capsh || echo -n '')" ] && ! echo "$psline" | grep -q "root"; then
cpid=$(echo "$psline" | awk '{print $2}')
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
@ -42,5 +232,34 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
pslist=$(ps auxwww)
echo ""
fi
# Additional checks for each process
print_2title "Processes with unusual configurations"
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -d "/proc/$pid" ] && continue
# Get process user and command
proc_user=$(stat -c '%U' "/proc/$pid" 2>/dev/null)
proc_cmd=$(cat "/proc/$pid/cmdline" 2>/dev/null | tr '\0' ' ' | head -c 100)
[ -z "$proc_user" ] || [ -z "$proc_cmd" ] && continue
# Run all checks and collect findings
sec_findings=$(check_security_context "$pid" "$proc_user" "$proc_cmd")
mount_findings=$(check_mount_namespace "$pid" "$proc_user" "$proc_cmd")
fd_findings=$(check_file_descriptors "$pid" "$proc_user" "$proc_cmd")
env_findings=$(check_env_vars "$pid" "$proc_user" "$proc_cmd")
# If any findings exist, print process info and findings
if [ -n "$env_findings" ] || [ -n "$sec_findings" ] || [ -n "$mount_findings" ] || [ -n "$fd_findings" ]; then
echo "Process $pid ($proc_user) - $proc_cmd"
[ -n "$env_findings" ] && echo "$env_findings"
[ -n "$sec_findings" ] && echo "$sec_findings"
[ -n "$mount_findings" ] && echo "$mount_findings"
[ -n "$fd_findings" ] && echo "$fd_findings"
echo ""
fi
done
echo ""
fi

View File

@ -1,26 +1,103 @@
# Title: Processes & Cron & Services & Timers - Processes with credentials inside memory
# ID: PR_Process_cred_in_memory
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Processes with credentials inside memory
# Last Update: 2024-03-19
# Description: Processes with credentials inside memory and memory-mapped files
# License: GNU GPL
# Version: 1.0
# Version: 1.2
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $pslist, $SEARCH_IN_FOLDER
# Global Variables: $pslist, $SEARCH_IN_FOLDER, $processesDump, $nosh_usrs, $processesB, $knw_usrs, $rootcommon, $sh_usrs, $processesVB
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $line, $cred_files, $filename, $fd_target, $found_cred_files, $proc, $proc_cmd, $pid, $proc_user, $cred_processes, $seen_files
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Processes with credentials in memory (root req)"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#credentials-from-process-memory"
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
# Common credential-storing processes
cred_processes="gdm-password gnome-keyring-daemon lightdm vsftpd apache2 sshd: mysql postgres redis-server mongod memcached elasticsearch jenkins tomcat nginx php-fpm supervisord vncserver xrdp teamviewer"
# Check for credential-storing processes
for proc in $cred_processes; do
if echo "$pslist" | grep -q "$proc"; then
echo "$proc process found (dump creds from memory as root)" | sed "s,$proc,${SED_RED},"
else
echo_not_found "$proc"
fi
done
# Check for processes with open handles to credential files
echo ""
print_2title "Opened Files by processes"
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -d "/proc/$pid" ] && continue
[ ! -r "/proc/$pid/fd" ] && continue
# Get process user and command
proc_user=$(stat -c '%U' "/proc/$pid" 2>/dev/null)
proc_cmd=$(cat "/proc/$pid/cmdline" 2>/dev/null | tr '\0' ' ' | head -c 100)
[ -z "$proc_user" ] || [ -z "$proc_cmd" ] && continue
# Skip processes that start with "sed " or contain "linpeas.sh"
echo "$proc_cmd" | grep -q "^sed " && continue
echo "$proc_cmd" | grep -q "linpeas.sh" && continue
# Variable to store unique files for this process
seen_files=""
found_cred_files=""
# Check for open credential files
for fd in /proc/$pid/fd/*; do
[ ! -e "$fd" ] && continue
fd_target=$(readlink "$fd" 2>/dev/null)
[ -z "$fd_target" ] && continue
[ "$fd_target" = "/dev/null" ] && continue
echo "$fd_target" | grep -q "^socket:" && continue
echo "$fd_target" | grep -q "^anon_inode:" && continue
# Only add if not already seen (using case to check)
case " $seen_files " in
*" $fd_target "*) continue ;;
*)
seen_files="$seen_files $fd_target"
if [ -z "$found_cred_files" ]; then
echo "Process $pid ($proc_user) - $proc_cmd"
echo " └─ Has open files:"
found_cred_files="yes"
fi
echo " └─ $fd_target"
;;
esac
done
done | sed -${E} "s,\.(pem|key|cred|db|sqlite|conf|cnf|ini|env|secret|token|auth|passwd|shadow)$,\1${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
# Check for processes with memory-mapped files that might contain credentials
echo ""
print_2title "Processes with memory-mapped credential files"
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -d "/proc/$pid" ] && continue
[ ! -r "/proc/$pid/maps" ] && continue
# Get process user and command
proc_user=$(stat -c '%U' "/proc/$pid" 2>/dev/null)
proc_cmd=$(cat "/proc/$pid/cmdline" 2>/dev/null | tr '\0' ' ' | head -c 100)
[ -z "$proc_user" ] || [ -z "$proc_cmd" ] && continue
# Check for memory-mapped files that might contain credentials
cred_files=$(grep -E '\.(pem|key|cred|db|sqlite|conf|cnf|ini|env|secret|token|auth|passwd|shadow)$' "/proc/$pid/maps" 2>/dev/null)
if [ -n "$cred_files" ]; then
echo "Process $pid ($proc_user) - $proc_cmd"
echo " └─ Has memory-mapped credential files:"
echo "$cred_files" | while read -r line; do
filename=$(echo "$line" | sed "s,.*/\(.*\),\1,")
echo " └─ $filename"
done
fi
done
echo ""
fi

View File

@ -1,29 +1,56 @@
# Title: Processes & Cron & Services & Timers - Process binaries permissions
# ID: PR_Process_binaries_perms
# Author: Carlos Polop
# Last Update: 22-08-2023
# Last Update: 2024-03-19
# Description: Check the permissions of the binaries of the running processes
# License: GNU GPL
# Version: 1.0
# Version: 1.2
# Functions Used: print_2title, print_info
# Global Variables: $knw_usrs, $nosh_usrs, $NOUSEPS, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $Wfolders
# Initial Functions:
# Generated Global Variables: $binW, $bpath
# Generated Global Variables: $binW, $bpath, $pid
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$NOUSEPS" ]; then
print_2title "Binary processes permissions (non 'root root' and not belonging to current user)"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#processes"
binW="IniTialiZZinnggg"
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
# Get list of writable binaries
binW=""
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -r "/proc/$pid/exe" ] && continue
# Get binary path
bpath=$(readlink "/proc/$pid/exe" 2>/dev/null)
[ -z "$bpath" ] && continue
# Check if binary is writable
if [ -w "$bpath" ]; then
binW="$binW|$bpath"
if [ -z "$binW" ]; then
binW="$bpath"
else
binW="$binW|$bpath"
fi
fi
done
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
# Get and display binary permissions
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -r "/proc/$pid/exe" ] && continue
# Get binary path
bpath=$(readlink "/proc/$pid/exe" 2>/dev/null)
[ -z "$bpath" ] && continue
# Display binary permissions if file exists
if [ -e "$bpath" ]; then
ls -la "$bpath" 2>/dev/null
fi
done | grep -Ev "\sroot\s+root" | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
echo ""
fi
fi

View File

@ -1,34 +1,58 @@
# Title: Processes & Cron & Services & Timers - Process opened by other users
# ID: PR_Processes_PPID_different_user
# Author: Carlos Polop
# Last Update: 22-08-2023
# Last Update: 2024-03-19
# Description: Processes whose PPID belongs to a different user (not root)
# License: GNU GPL
# Version: 1.0
# Version: 1.1
# Functions Used: print_2title, print_info
# Global Variables: $nosh_usrs, $NOUSEPS, $SEARCH_IN_FOLDER, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables: $ppid_user, $pid, $ppid, $user
# Generated Global Variables: $ppid_user, $pid, $ppid, $user, $ppid_uid, $user_uid
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$NOUSEPS" ]; then
print_2title "Processes whose PPID belongs to a different user (not root)"
print_info "You will know if a user can somehow spawn processes as a different user"
# Function to get user by PID
# Function to get user by PID using /proc
get_user_by_pid() {
ps -p "$1" -o user | grep -v "USER"
if [ -r "/proc/$1/status" ]; then
grep "^Uid:" "/proc/$1/status" 2>/dev/null | awk '{print $2}'
fi
}
# Function to get username by UID
get_username_by_uid() {
if [ -r "/etc/passwd" ]; then
grep "^[^:]*:[^:]*:$1:" "/etc/passwd" 2>/dev/null | cut -d: -f1
fi
}
# Find processes with PPID and user info, then filter those where PPID's user is different from the process's user
ps -eo pid,ppid,user | grep -v "PPID" | while read -r pid ppid user; do
if [ "$ppid" = "0" ]; then
continue
fi
ppid_user=$(get_user_by_pid "$ppid")
if echo "$ppid_user" | grep -Eqv "$user|root$"; then
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -r "/proc/$pid/status" ] && continue
# Get process user
user_uid=$(get_user_by_pid "$pid")
[ -z "$user_uid" ] && continue
user=$(get_username_by_uid "$user_uid")
[ -z "$user" ] && continue
# Get PPID
ppid=$(grep "^PPid:" "/proc/$pid/status" 2>/dev/null | awk '{print $2}')
[ -z "$ppid" ] || [ "$ppid" = "0" ] && continue
# Get PPID user
ppid_uid=$(get_user_by_pid "$ppid")
[ -z "$ppid_uid" ] && continue
ppid_user=$(get_username_by_uid "$ppid_uid")
[ -z "$ppid_user" ] && continue
# Check if users are different and PPID user is not root
if [ "$user" != "$ppid_user" ] && [ "$ppid_user" != "root" ]; then
echo "Proc $pid with ppid $ppid is run by user $user but the ppid user is $ppid_user" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
fi
done

View File

@ -1,23 +1,64 @@
# Title: Processes & Cron & Services & Timers - Files opened by processes belonging to other users
# ID: PR_Files_open_process_other_user
# Author: Carlos Polop
# Last Update: 22-08-2023
# Last Update: 2024-03-19
# Description: Files opened by processes belonging to other users
# License: GNU GPL
# Version: 1.0
# Version: 1.1
# Functions Used: print_2title, print_info
# Global Variables: $IAMROOT, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $user_uid, $pid, $fd_target, $cmd, $user
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
if ! [ "$IAMROOT" ]; then
print_2title "Files opened by processes belonging to other users"
print_info "This is usually empty because of the lack of privileges to read other user processes information"
lsof 2>/dev/null | grep -v "$USER" | grep -iv "permission denied" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
# Function to get username by UID
get_username_by_uid() {
if [ -r "/etc/passwd" ]; then
grep "^[^:]*:[^:]*:$1:" "/etc/passwd" 2>/dev/null | cut -d: -f1
fi
}
# Check each process
for pid in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+' -printf "%f\n" 2>/dev/null); do
# Skip if process doesn't exist or we can't access it
[ ! -r "/proc/$pid/status" ] && continue
[ ! -r "/proc/$pid/fd" ] && continue
# Get process user
user_uid=$(grep "^Uid:" "/proc/$pid/status" 2>/dev/null | awk '{print $2}')
[ -z "$user_uid" ] && continue
user=$(get_username_by_uid "$user_uid")
[ -z "$user" ] && continue
# Skip if process belongs to current user
[ "$user" = "$USER" ] && continue
# Get process command
cmd=$(cat "/proc/$pid/cmdline" 2>/dev/null | tr '\0' ' ' | head -c 100)
[ -z "$cmd" ] && continue
# Check file descriptors
for fd in /proc/$pid/fd/*; do
[ ! -e "$fd" ] && continue
fd_target=$(readlink "$fd" 2>/dev/null)
[ -z "$fd_target" ] && continue
# Skip if target doesn't exist or is a special file
[ ! -e "$fd_target" ] && continue
case "$fd_target" in
/dev/*|/proc/*|/sys/*) continue ;;
esac
echo "Process $pid ($user) - $cmd"
echo " └─ Has open file: $fd_target" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
done
done
echo ""
fi
fi

View File

@ -0,0 +1,250 @@
# Title: Processes & Cron & Services & Timers - Cron jobs and Wildcards
# ID: PR_Cron_jobs
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Enumerate system cron jobs and check for privilege escalation vectors
# License: GNU GPL
# Version: 1.2
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $cronjobsG, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $Wfolders, $cronjobsB, $PATH
# Initial Functions:
# Generated Global Variables: $cmd, $VAR, $file, $path, $user_crontab, $username, $job_id, $cron_dir, $crontab, $findings, $line, $finding, $bin
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Check for vulnerable cron jobs"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
print_3title "Cron jobs list"
command -v crontab 2>/dev/null || echo_not_found "crontab"
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
command -v incrontab 2>/dev/null || echo_not_found "incrontab"
incrontab -l 2>/dev/null
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g"
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
atq 2>/dev/null
echo ""
print_3title "Checking for specific cron jobs vulnerabilities"
# Function to check if a binary is writable and executable
check_binary_perms() {
local bin="$1"
[ -z "$bin" ] && return
# Skip if binary doesn't exist
[ ! -e "$bin" ] && return
# Check if it's a regular file
[ ! -f "$bin" ] && return
# Check if it's writable and executable
if [ -w "$bin" ]; then
echo "Writable binary: $bin"
ls -l "$bin" 2>/dev/null
fi
}
# Function to extract binary path from command
get_binary_path() {
local cmd="$1"
local bin=""
# Try to get the first word of the command
bin=$(echo "$cmd" | awk '{print $1}')
[ -z "$bin" ] && return
# If it's an absolute path, use it directly
if [ "$(echo "$bin" | cut -c1)" = "/" ]; then
echo "$bin"
return
fi
# If it's a relative path, try to resolve it
if [ -e "$bin" ]; then
echo "$(pwd)/$bin"
return
fi
# Try to find it in PATH
for path in $(echo "$PATH" | tr ':' ' '); do
if [ -x "$path/$bin" ]; then
echo "$path/$bin"
return
fi
done
}
# Function to check for privilege escalation vectors in a command
check_privesc_vectors() {
local cmd="$1"
local file="$2"
local findings=""
local bin=""
# Skip common false positives (mail commands, shell conditionals, variable assignments)
if echo "$cmd" | grep -qE '^(mail|echo|then|else|fi|if|for|while|do|done|case|esac|exit|return|break|continue|:|\[|test|\[\[|\]\]|true|false|source|\.|cd|pwd|export|unset|readonly|local|declare|typeset|alias|unalias|set|unset|shift|wait|trap|umask|ulimit|exec|eval|command|builtin|let|read|printf|^[[:space:]]*[A-Za-z0-9_]+[[:space:]]*[=:])'; then
return
fi
# Get the binary path
bin=$(get_binary_path "$cmd")
if [ -n "$bin" ]; then
check_binary_perms "$bin"
fi
# Check for wildcard injection vectors
# Attack: Using wildcards in tar/chmod/chown to execute arbitrary commands
# Example: tar cf archive.tar * (where * expands to --checkpoint=1 --checkpoint-action=exec=sh)
if echo "$cmd" | grep -qE '\*'; then
findings="${findings}POTENTIAL_WILDCARD_INJECTION: Command uses wildcards with potentially exploitable command\n"
fi
# Check for path hijacking vectors
# Attack: Using relative paths or commands without full path that can be hijacked
# Example: script.sh instead of /usr/bin/script.sh
if echo "$cmd" | grep -qE '^[[:space:]]*[^/][^[:space:]]*[[:space:]]'; then
# Skip common false positives like shell builtins, control structures, and variable assignments
# Also skip test commands ([ ]), logical operators (&& ||), and complex shell constructs
if ! echo "$cmd" | grep -qE '^[[:space:]]*(cd|\.|source|\./|if|then|else|fi|for|while|do|done|case|esac|exit|return|break|continue|:|\[[[:space:]]|test|\[\[|\]\]|true|false|export|unset|readonly|local|declare|typeset|alias|unalias|set|unset|shift|wait|trap|umask|ulimit|exec|eval|command|builtin|let|read|printf|[A-Za-z0-9_]+[[:space:]]*[=:]|&&|\|\||;|\(|\)|\{|\})'; then
findings="${findings}PATH_HIJACKING: Command uses relative path\n"
fi
fi
# Check for command injection vectors
# Attack: Using unquoted variables or command substitution that can be injected
# Example: echo $VAR or echo $(command)
if echo "$cmd" | grep -qE '\$\{?[A-Za-z0-9_]|\$\(|`'; then
findings="${findings}COMMAND_INJECTION: Command uses unquoted variables or command substitution\n"
fi
# Check for overly permissive commands
# Attack: Commands that can be used to escalate privileges
# Example: chmod 777, chown root, etc.
if echo "$cmd" | grep -qE '\b(chmod\s+[0-7]{3,4}|chown\s+root|chgrp\s+root|sudo|su |pkexec)\b'; then
findings="${findings}PERMISSIVE_COMMAND: Command modifies permissions or uses privilege escalation tools\n"
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo "Potential privilege escalation in cron job:"
echo " └─ File: $file"
echo " └─ Command: $cmd"
if [ -n "$bin" ]; then
echo " └─ Binary: $bin"
fi
echo " └─ Findings:"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " * $finding"
done
fi
}
# Check system crontabs
#echo "Checking system crontabs..."
#for crontab in /etc/cron.d/* /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.monthly/* /etc/cron.weekly/* /var/spool/cron/crontabs/* /etc/at* /etc/anacrontab /etc/incron.d/* /var/spool/incron/*; do
# [ ! -f "$crontab" ] && continue
# [ ! -r "$crontab" ] && continue
# # Check if the file is writable
# if [ -w "$crontab" ]; then
# echo "Writable cron file: $crontab"
# fi
# # Check each line for privilege escalation vectors
# while IFS= read -r line || [ -n "$line" ]; do
# # Skip comments and empty lines
# case "$line" in
# \#*|"") continue ;;
# esac
# # Extract the command part (everything after the time specification)
# cmd=$(echo "$line" | sed -E 's/^[^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+ //')
# [ -z "$cmd" ] && continue
# check_privesc_vectors "$cmd" "$crontab"
# done < "$crontab"
#done
# Check user crontabs
#echo "Checking user crontabs..."
#if command -v crontab >/dev/null 2>&1; then
# # Check current user's crontab
# crontab -l 2>/dev/null | while IFS= read -r line || [ -n "$line" ]; do
# case "$line" in
# \#*|"") continue ;;
# esac
# cmd=$(echo "$line" | sed -E 's/^[^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+ //')
# [ -z "$cmd" ] && continue
# check_privesc_vectors "$cmd" "current user crontab"
# done
# # Check other users' crontabs if accessible
# for user_crontab in /var/spool/cron/crontabs/*; do
# [ ! -f "$user_crontab" ] && continue
# [ ! -r "$user_crontab" ] && continue
# username=$(basename "$user_crontab")
# [ "$username" = "$USER" ] && continue
# echo "Found crontab for user: $username"
# while IFS= read -r line || [ -n "$line" ]; do
# case "$line" in
# \#*|"") continue ;;
# esac
# cmd=$(echo "$line" | sed -E 's/^[^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+ //')
# [ -z "$cmd" ] && continue
# check_privesc_vectors "$cmd" "$user_crontab"
# done < "$user_crontab"
# done
#else
# echo_not_found "crontab"
#fi
# Check for writable cron directories
echo "Checking cron directories..."
for cron_dir in /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.monthly /etc/cron.weekly /var/spool/cron/crontabs /usr/lib/cron/tabs /private/var/at/jobs /var/at/tabs /etc/periodic; do
[ ! -d "$cron_dir" ] && continue
if [ -w "$cron_dir" ]; then
echo "Writable cron directory: $cron_dir"
fi
done
# Check for at jobs
#if command -v atq >/dev/null 2>&1; then
# echo "Checking at jobs..."
# atq 2>/dev/null | while IFS= read -r line || [ -n "$line" ]; do
# [ -z "$line" ] && continue
# job_id=$(echo "$line" | awk '{print $1}')
# [ -z "$job_id" ] && continue
# at -c "$job_id" 2>/dev/null | while IFS= read -r cmd || [ -n "$cmd" ]; do
# case "$cmd" in
# \#*|"") continue ;;
# esac
# check_privesc_vectors "$cmd" "at job $job_id"
# done
# done
#fi
# Check for incron jobs
#if command -v incrontab >/dev/null 2>&1; then
# echo "Checking incron jobs..."
# incrontab -l 2>/dev/null | while IFS= read -r line || [ -n "$line" ]; do
# case "$line" in
# \#*|"") continue ;;
# esac
# cmd=$(echo "$line" | awk '{print $3}')
# [ -z "$cmd" ] && continue
# check_privesc_vectors "$cmd" "incron job"
# done
#fi
else
print_2title "Cron jobs"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
find "$SEARCH_IN_FOLDER" '(' -type d -or -type f ')' '(' -name "cron*" -or -name "anacron" -or -name "anacrontab" -or -name "incron.d" -or -name "incron" -or -name "at" -or -name "periodic" ')' -exec echo {} \; -exec ls -lR {} \;
fi
echo ""

View File

@ -1,22 +0,0 @@
# Title: Processes & Cron & Services & Timers - Systemd PATH
# ID: PR_Systemd_path
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Systemd PATH
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $SEARCH_IN_FOLDER, $Wfolders
# Initial Functions:
# Generated Global Variables: $WRITABLESYSTEMDPATH
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Systemd PATH"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#systemd-path---relative-paths"
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
echo ""
fi

View File

@ -1,33 +0,0 @@
# Title: Processes & Cron & Services & Timers - Cron jobs
# ID: PR_Cron_jobs
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Enumerate system cron jobs
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $cronjobsG, $nosh_usrs, $SEARCH_IN_FOLDER, $sh_usrs, $USER, $Wfolders, $cronjobsB
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Cron jobs"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
command -v crontab 2>/dev/null || echo_not_found "crontab"
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
command -v incrontab 2>/dev/null || echo_not_found "incrontab"
incrontab -l 2>/dev/null
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g"
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
atq 2>/dev/null
else
print_2title "Cron jobs"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
find "$SEARCH_IN_FOLDER" '(' -type d -or -type f ')' '(' -name "cron*" -or -name "anacron" -or -name "anacrontab" -or -name "incron.d" -or -name "incron" -or -name "at" -or -name "periodic" ')' -exec echo {} \; -exec ls -lR {} \;
fi
echo ""

View File

@ -0,0 +1,169 @@
# Title: Processes & Cron & Services & Timers - Third party LaunchAgents & LaunchDemons
# ID: PR_Macos_launch_agents_daemons
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: Third party LaunchAgents & LaunchDemons and privilege escalation vectors
# License: GNU GPL
# Version: 1.1
# Functions Used: print_2title, print_info
# Global Variables: $MACPEAS, $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables: $program, $plist_content, $binary_path, $periodic_dir, $workdir, $startup_dir, $line, $emond_script, $startup_item, $finding, $location, $findings, $login_item, $plist, $periodic_script, $plist_dir
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$MACPEAS" ]; then
print_2title "Third party LaunchAgents & LaunchDemons"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#launchd"
print_info "Checking for privilege escalation vectors in LaunchAgents & LaunchDaemons:"
print_info "1. Writable plist files"
print_info "2. Writable program binaries"
print_info "3. Environment variables with sensitive data"
print_info "4. Unsafe program arguments"
print_info "5. RunAtLoad with elevated privileges"
print_info "6. KeepAlive with elevated privileges"
# Function to check plist content for privilege escalation vectors
check_plist_content() {
local plist="$1"
local findings=""
# Check for environment variables
if defaults read "$plist" EnvironmentVariables 2>/dev/null | grep -qE '(PASS|SECRET|KEY|TOKEN|CRED)'; then
findings="${findings}ENV_VARS: Contains sensitive environment variables\n"
fi
# Check for RunAtLoad with elevated privileges
if defaults read "$plist" RunAtLoad 2>/dev/null | grep -q "true"; then
if [ -w "$plist" ]; then
findings="${findings}RUN_AT_LOAD: Runs at load and plist is writable\n"
fi
fi
# Check for KeepAlive with elevated privileges
if defaults read "$plist" KeepAlive 2>/dev/null | grep -q "true"; then
if [ -w "$plist" ]; then
findings="${findings}KEEP_ALIVE: Keeps running and plist is writable\n"
fi
fi
# Check for unsafe program arguments
if defaults read "$plist" ProgramArguments 2>/dev/null | grep -qE '(sudo|su|chmod|chown|chroot|mount)'; then
findings="${findings}UNSAFE_ARGS: Uses potentially dangerous program arguments\n"
fi
# Check for writable working directory
if defaults read "$plist" WorkingDirectory 2>/dev/null | grep -qE '^/'; then
local workdir=$(defaults read "$plist" WorkingDirectory 2>/dev/null)
if [ -w "$workdir" ]; then
findings="${findings}WRITABLE_WORKDIR: Working directory is writable\n"
fi
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo "Potential privilege escalation in: $plist"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding"
done
fi
}
# Check system and user LaunchAgents & LaunchDaemons
for plist_dir in /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/; do
[ ! -d "$plist_dir" ] && continue
echo "Checking $plist_dir..."
find "$plist_dir" -name "*.plist" 2>/dev/null | while read -r plist; do
# Check if plist is writable
if [ -w "$plist" ]; then
echo "Writable plist: $plist" | sed -${E} "s,.*,${SED_RED_YELLOW},"
fi
# Get program path
program=""
program=$(defaults read "$plist" Program 2>/dev/null)
if ! [ "$program" ]; then
program=$(defaults read "$plist" ProgramArguments 2>/dev/null | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
fi
# Check if program is writable
if [ -n "$program" ] && [ -w "$program" ]; then
echo "Writable program: $program" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$program" 2>/dev/null
fi
# Check plist content for privilege escalation vectors
check_plist_content "$plist"
done
done
echo ""
print_2title "StartupItems"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#startup-items"
for startup_dir in /Library/StartupItems/ /System/Library/StartupItems/; do
[ ! -d "$startup_dir" ] && continue
echo "Checking $startup_dir..."
find "$startup_dir" -type f -executable 2>/dev/null | while read -r startup_item; do
if [ -w "$startup_item" ]; then
echo "Writable startup item: $startup_item" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$startup_item" 2>/dev/null
fi
done
done
echo ""
print_2title "Login Items"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#startup-items"
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null | tr ", " "\n" | while read -r login_item; do
if [ -n "$login_item" ]; then
# Try to find the actual binary
binary_path=$(mdfind "kMDItemDisplayName == '$login_item'" 2>/dev/null | head -n 1)
if [ -n "$binary_path" ] && [ -w "$binary_path" ]; then
echo "Writable login item binary: $binary_path" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$binary_path" 2>/dev/null
fi
fi
done
echo ""
print_2title "SPStartupItemDataType"
system_profiler SPStartupItemDataType 2>/dev/null | while read -r line; do
if echo "$line" | grep -q "Location:"; then
location=$(echo "$line" | cut -d: -f2- | xargs)
if [ -w "$location" ]; then
echo "Writable startup item location: $location" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$location" 2>/dev/null
fi
fi
done
echo ""
print_2title "Emond scripts"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#emond"
if [ -d "/private/var/db/emondClients" ]; then
find "/private/var/db/emondClients" -type f 2>/dev/null | while read -r emond_script; do
if [ -w "$emond_script" ]; then
echo "Writable emond script: $emond_script" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$emond_script" 2>/dev/null
fi
done
fi
echo ""
print_2title "Periodic tasks"
print_info "Checking periodic tasks for privilege escalation vectors"
for periodic_dir in /etc/periodic/daily /etc/periodic/weekly /etc/periodic/monthly; do
[ ! -d "$periodic_dir" ] && continue
echo "Checking $periodic_dir..."
find "$periodic_dir" -type f -executable 2>/dev/null | while read -r periodic_script; do
if [ -w "$periodic_script" ]; then
echo "Writable periodic script: $periodic_script" | sed -${E} "s,.*,${SED_RED_YELLOW},"
ls -l "$periodic_script" 2>/dev/null
fi
done
done
echo ""
fi
fi

View File

@ -1,55 +0,0 @@
# Title: Processes & Cron & Services & Timers - Third party LaunchAgents & LaunchDemons
# ID: PR_Macos_launch_agents_daemons
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Third party LaunchAgents & LaunchDemons
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $MACPEAS, $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables: $program
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$MACPEAS" ]; then
print_2title "Third party LaunchAgents & LaunchDemons"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#launchd"
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
echo ""
print_2title "Writable System LaunchAgents & LaunchDemons"
find /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/ /Library/LaunchAgents/ /Library/LaunchDaemons/ | grep ".plist" | while read f; do
program=""
program=$(defaults read "$f" Program 2>/dev/null)
if ! [ "$program" ]; then
program=$(defaults read "$f" ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
fi
if [ -w "$program" ]; then
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
fi
done
echo ""
print_2title "StartupItems"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#startup-items"
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
echo ""
print_2title "Login Items"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#startup-items"
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
echo ""
print_2title "SPStartupItemDataType"
system_profiler SPStartupItemDataType
echo ""
print_2title "Emond scripts"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-auto-start-locations.html#emond"
ls -l /private/var/db/emondClients
echo ""
fi
fi

View File

@ -0,0 +1,156 @@
# Title: Processes & Cron & Services & Timers - System Timers
# ID: PR_System_timers
# Author: Carlos Polop
# Last Update: 2024-03-19
# Description: System Timers and privilege escalation vectors
# License: GNU GPL
# Version: 1.2
# Functions Used: echo_not_found, print_2title, print_info, print_3title
# Global Variables: $SEARCH_IN_FOLDER, $timersG
# Initial Functions:
# Generated Global Variables: $timer_unit, $timer_path, $timer_content, $exec_path, $timer_file, $line, $findings, $unit_path, $finding, $service_unit, $timer, $target_unit, $target_file
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "System timers"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#timers"
# Function to check timer content for privilege escalation vectors
check_timer_content() {
local timer="$1"
local findings=""
# Get the service unit this timer activates
local service_unit=$(systemctl show "$timer" -p Unit 2>/dev/null | cut -d= -f2)
if [ -n "$service_unit" ]; then
# Check if the service runs with elevated privileges
if systemctl show "$service_unit" -p User 2>/dev/null | grep -q "root"; then
findings="${findings}RUNS_AS_ROOT: Service runs as root\n"
fi
# Get the executable path
local exec_path=$(systemctl show "$service_unit" -p ExecStart 2>/dev/null | cut -d= -f2 | cut -d' ' -f1)
if [ -n "$exec_path" ]; then
if [ -w "$exec_path" ]; then
findings="${findings}WRITABLE_EXEC: Executable is writable: $exec_path\n"
fi
# Check for relative paths
case "$exec_path" in
/*) : ;; # Absolute path, do nothing
*) findings="${findings}RELATIVE_PATH: Uses relative path: $exec_path\n" ;;
esac
fi
# Check for unsafe configurations
if systemctl show "$service_unit" -p ExecStart 2>/dev/null | grep -qE '(chmod|chown|mount|sudo|su)'; then
findings="${findings}UNSAFE_CMD: Uses potentially dangerous commands\n"
fi
# Check for weak permissions
if [ -e "$exec_path" ] && [ "$(stat -c %a "$exec_path" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_PERMS: Executable has 777 permissions\n"
fi
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo "Potential privilege escalation in timer: $timer"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding"
done
fi
}
# Function to check timer file for privilege escalation vectors
check_timer_file() {
local timer_file="$1"
local findings=""
# Check if timer file is writable (following symlinks)
if [ -L "$timer_file" ]; then
# If it's a symlink, check the target file
local target_file=$(readlink -f "$timer_file")
if [ -w "$target_file" ]; then
findings="${findings}WRITABLE_FILE: Timer target file is writable: $target_file\n"
fi
elif [ -w "$timer_file" ]; then
findings="${findings}WRITABLE_FILE: Timer file is writable\n"
fi
# Check for weak permissions (following symlinks)
if [ "$(stat -L -c %a "$timer_file" 2>/dev/null)" = "777" ]; then
findings="${findings}WEAK_PERMS: Timer file has 777 permissions\n"
fi
# Check for relative paths in Unit directive
if grep -q "^Unit=[^/]" "$timer_file" 2>/dev/null; then
findings="${findings}RELATIVE_PATH: Uses relative path in Unit directive\n"
fi
# Check for writable executables in Unit directive (following symlinks)
local unit_path=$(grep -Po '^Unit=*(.*?$)' "$timer_file" 2>/dev/null | cut -d '=' -f2)
if [ -n "$unit_path" ]; then
if [ -L "$unit_path" ]; then
local target_unit=$(readlink -f "$unit_path")
if [ -w "$target_unit" ]; then
findings="${findings}WRITABLE_UNIT: Unit target file is writable: $target_unit\n"
fi
elif [ -w "$unit_path" ]; then
findings="${findings}WRITABLE_UNIT: Unit file is writable: $unit_path\n"
fi
fi
# If any findings, print them
if [ -n "$findings" ]; then
echo "Potential privilege escalation in timer file: $timer_file"
echo "$findings" | while read -r finding; do
[ -n "$finding" ] && echo " └─ $finding"
done
fi
}
# List all timers and check for privilege escalation vectors
print_3title "Active timers:"
systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | while read -r line; do
# Extract timer unit name
timer_unit=$(echo "$line" | awk '{print $1}')
if [ -n "$timer_unit" ]; then
# Check if timer file is writable
timer_path=$(systemctl show "$timer_unit" -p FragmentPath 2>/dev/null | cut -d= -f2)
if [ -n "$timer_path" ]; then
check_timer_file "$timer_path"
fi
# Check timer content for privilege escalation vectors
check_timer_content "$timer_unit"
# Print the timer line with highlighting
echo "$line" | sed -${E} "s,$timersG,${SED_GREEN},"
fi
done || echo_not_found
# Check for disabled but available timers
print_3title "Disabled timers:"
systemctl list-unit-files --type=timer --state=disabled 2>/dev/null | grep -v "UNIT FILE" | while read -r line; do
timer_unit=$(echo "$line" | awk '{print $1}')
if [ -n "$timer_unit" ]; then
timer_path=$(systemctl show "$timer_unit" -p FragmentPath 2>/dev/null | cut -d= -f2)
if [ -n "$timer_path" ]; then
check_timer_file "$timer_path"
fi
fi
done || echo_not_found
# Check timer files from PSTORAGE_TIMER
if [ -n "$PSTORAGE_TIMER" ]; then
print_3title "Additional timer files:"
printf "%s\n" "$PSTORAGE_TIMER" | while read -r timer_file; do
if [ -n "$timer_file" ] && [ -e "$timer_file" ]; then
check_timer_file "$timer_file"
fi
done
fi
echo ""
fi

View File

@ -5,20 +5,42 @@
# Description: Check for internet access
# License: GNU GPL
# Version: 1.0
# Functions Used: check_dns, check_icmp, check_tcp_443, check_tcp_80, print_2title
# Global Variables: $FAST, $TIMEOUT
# Functions Used: check_dns, check_icmp, check_tcp_443, check_tcp_443_bin, check_tcp_80, print_2title, check_external_hostname
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pid4, $pid2, $pid1, $pid3, $pid5, $NOT_CHECK_EXTERNAL_HOSTNAME, $TIMEOUT_INTERNET_SECONDS
# Fat linpeas: 0
# Small linpeas: 0
if ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ -f "/bin/bash" ]; then
print_2title "Internet Access?"
check_tcp_80 2>/dev/null &
check_tcp_443 2>/dev/null &
check_icmp 2>/dev/null &
check_dns 2>/dev/null &
wait
echo ""
print_2title "Internet Access?"
TIMEOUT_INTERNET_SECONDS=5
if [ "$SUPERFAST" ]; then
TIMEOUT_INTERNET_SECONDS=2
fi
# Run all checks in background
check_tcp_80 2>/dev/null & pid1=$!
check_tcp_443 2>/dev/null & pid2=$!
check_tcp_443_bin 2>/dev/null & pid3=$!
check_icmp 2>/dev/null & pid4=$!
check_dns 2>/dev/null & pid5=$!
# Kill all after 10 seconds
(sleep $TIMEOUT_INTERNET_SECONDS && kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null) &
# Wait for all to finish
wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
if ! [ "$SUPERFAST" ] && ! [ "$NOT_CHECK_EXTERNAL_HOSTNAME" ]; then
echo ""
print_2title "Is hostname malicious or leaked?"
print_info "This will check the public IP and hostname in known malicious lists and leaks to find any relevant information about the host."
check_external_hostname 2>/dev/null
fi
echo ""

View File

@ -8,12 +8,69 @@
# Functions Used: print_2title
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $iface, $state, $mac, $ip_file, $line
# Fat linpeas: 0
# Small linpeas: 1
# Function to parse network interfaces from /proc/net/dev and other sources
parse_network_interfaces() {
# Try to get interfaces from /proc/net/dev
if [ -f "/proc/net/dev" ]; then
echo "Network Interfaces from /proc/net/dev:"
echo "----------------------------------------"
# Skip header lines and format output
grep -v "^Inter\|^ face" /proc/net/dev | while read -r line; do
iface=$(echo "$line" | awk -F: '{print $1}' | tr -d ' ')
if [ -n "$iface" ]; then
echo "Interface: $iface"
# Try to get IP address from /sys/class/net
if [ -f "/sys/class/net/$iface/address" ]; then
mac=$(cat "/sys/class/net/$iface/address" 2>/dev/null)
echo " MAC: $mac"
fi
# Try to get IP from /sys/class/net
if [ -d "/sys/class/net/$iface/ipv4" ]; then
for ip_file in /sys/class/net/$iface/ipv4/addr_*; do
if [ -f "$ip_file" ]; then
ip=$(cat "$ip_file" 2>/dev/null)
echo " IP: $ip"
fi
done
fi
# Get interface state
if [ -f "/sys/class/net/$iface/operstate" ]; then
state=$(cat "/sys/class/net/$iface/operstate" 2>/dev/null)
echo " State: $state"
fi
echo ""
fi
done
fi
# Try to get additional info from /proc/net/fib_trie
if [ -f "/proc/net/fib_trie" ]; then
echo "Additional IP Information from fib_trie:"
echo "----------------------------------------"
grep -A1 "Main" /proc/net/fib_trie | grep -v "\-\-" | while read -r line; do
if echo "$line" | grep -q "Main"; then
echo "Network: $(echo "$line" | awk '{print $2}')"
elif echo "$line" | grep -q "/"; then
echo " IP: $(echo "$line" | awk '{print $2}')"
fi
done
fi
}
print_2title "Interfaces"
cat /etc/networks 2>/dev/null
(ifconfig || ip a || (cat /proc/net/dev; cat /proc/net/fib_trie; cat /proc/net/fib_trie6)) 2>/dev/null
# Try standard tools first, then fall back to our custom function
if command -v ifconfig >/dev/null 2>&1; then
ifconfig 2>/dev/null
elif command -v ip >/dev/null 2>&1; then
ip a 2>/dev/null
else
parse_network_interfaces
fi
echo ""

View File

@ -8,12 +8,100 @@
# Functions Used: print_2title, warn_exec
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $conf, $line
# Fat linpeas: 0
# Small linpeas: 1
# Function to get hostname using multiple methods
get_hostname_info() {
print_3title "Hostname Information"
# Try multiple methods to get hostname
if command -v hostname >/dev/null 2>&1; then
echo "System hostname: $(hostname 2>/dev/null)"
echo "FQDN: $(hostname -f 2>/dev/null)"
else
# Fallback methods
if [ -f "/proc/sys/kernel/hostname" ]; then
echo "System hostname: $(cat /proc/sys/kernel/hostname 2>/dev/null)"
fi
if [ -f "/etc/hostname" ]; then
echo "Hostname from /etc/hostname: $(cat /etc/hostname 2>/dev/null)"
fi
fi
echo ""
}
# Function to get hosts file information
get_hosts_info() {
print_3title "Hosts File Information"
if [ -f "/etc/hosts" ]; then
echo "Contents of /etc/hosts:"
grep -v "^#" /etc/hosts 2>/dev/null | grep -v "^$" | while read -r line; do
echo " $line"
done
fi
echo ""
}
# Function to get DNS information
get_dns_info() {
print_3title "DNS Configuration"
# Get resolv.conf information
if [ -f "/etc/resolv.conf" ]; then
echo "DNS Servers (resolv.conf):"
grep -v "^#" /etc/resolv.conf 2>/dev/null | grep -v "^$" | while read -r line; do
if echo "$line" | grep -q "nameserver"; then
echo " $(echo "$line" | awk '{print $2}')"
elif echo "$line" | grep -q "search\|domain"; then
echo " $line"
fi
done
fi
# Check for systemd-resolved configuration
if [ -f "/etc/systemd/resolved.conf" ]; then
echo -e "\nSystemd-resolved configuration:"
grep -v "^#" /etc/systemd/resolved.conf 2>/dev/null | grep -v "^$" | while read -r line; do
echo " $line"
done
fi
# Check for NetworkManager DNS settings
if [ -d "/etc/NetworkManager" ]; then
echo -e "\nNetworkManager DNS settings:"
find /etc/NetworkManager -type f -name "*.conf" 2>/dev/null | while read -r conf; do
if grep -q "dns=" "$conf" 2>/dev/null; then
echo " From $conf:"
grep "dns=" "$conf" 2>/dev/null | while read -r line; do
echo " $line"
done
fi
done
fi
# Try to get DNS domain name
echo -e "\nDNS Domain Information:"
if command -v dnsdomainname >/dev/null 2>&1; then
warn_exec dnsdomainname 2>/dev/null
fi
if command -v domainname >/dev/null 2>&1; then
warn_exec domainname 2>/dev/null
fi
# Check for DNS cache status
if command -v systemd-resolve >/dev/null 2>&1; then
echo -e "\nDNS Cache Status (systemd-resolve):"
systemd-resolve --status 2>/dev/null | grep -A5 "DNS Servers" | grep -v "\-\-" | while read -r line; do
echo " $line"
done
fi
echo ""
}
print_2title "Hostname, hosts and DNS"
cat /etc/hostname /etc/hosts /etc/resolv.conf 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null
warn_exec dnsdomainname 2>/dev/null
echo ""
# Execute all information gathering functions
get_hostname_info
get_hosts_info
get_dns_info

View File

@ -5,21 +5,134 @@
# Description: Networks and neighbours
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Functions Used: print_2title, print_3title
# Global Variables: $EXTRA_CHECKS, $MACPEAS
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $hwtype, $flags, $line, $iface, $dest, $ref, $use, $mask, $metric, $device, $hwaddr
# Fat linpeas: 0
# Small linpeas: 0
# Function to parse routing information from /proc/net/route
parse_proc_route() {
print_3title "Routing Table (from /proc/net/route)"
echo "Destination Gateway Genmask Flags Metric Ref Use Iface"
echo "--------------------------------------------------------------------------------"
# Skip header line and process each route
tail -n +2 /proc/net/route 2>/dev/null | while read -r line; do
if [ -n "$line" ]; then
# Extract fields
iface=$(echo "$line" | awk '{print $1}')
dest=$(printf "%d.%d.%d.%d" $(echo "$line" | awk '{printf "0x%s 0x%s 0x%s 0x%s", substr($2,7,2), substr($2,5,2), substr($2,3,2), substr($2,1,2)}'))
gw=$(printf "%d.%d.%d.%d" $(echo "$line" | awk '{printf "0x%s 0x%s 0x%s 0x%s", substr($3,7,2), substr($3,5,2), substr($3,3,2), substr($3,1,2)}'))
mask=$(printf "%d.%d.%d.%d" $(echo "$line" | awk '{printf "0x%s 0x%s 0x%s 0x%s", substr($4,7,2), substr($4,5,2), substr($4,3,2), substr($4,1,2)}'))
flags=$(echo "$line" | awk '{print $5}')
metric=$(echo "$line" | awk '{print $6}')
ref=$(echo "$line" | awk '{print $7}')
use=$(echo "$line" | awk '{print $8}')
# Print formatted output
printf "%-18s %-15s %-15s %-6s %-6s %-6s %-6s %s\n" "$dest" "$gw" "$mask" "$flags" "$metric" "$ref" "$use" "$iface"
fi
done
echo ""
}
# Function to parse ARP information from /proc/net/arp
parse_proc_arp() {
print_3title "ARP Table (from /proc/net/arp)"
echo "IP address HW type Flags HW address Mask Device"
echo "------------------------------------------------------------------------"
# Skip header line and process each ARP entry
tail -n +2 /proc/net/arp 2>/dev/null | while read -r line; do
if [ -n "$line" ]; then
ip=$(echo "$line" | awk '{print $1}')
hwtype=$(echo "$line" | awk '{print $2}')
flags=$(echo "$line" | awk '{print $3}')
hwaddr=$(echo "$line" | awk '{print $4}')
mask=$(echo "$line" | awk '{print $5}')
device=$(echo "$line" | awk '{print $6}')
# Print formatted output
printf "%-15s %-11s %-9s %-18s %-8s %s\n" "$ip" "$hwtype" "$flags" "$hwaddr" "$mask" "$device"
fi
done
echo ""
}
# Function to get network neighbors information
get_network_neighbors() {
print_2title "Networks and neighbours"
# Get routing information
print_3title "Routing Information"
if [ "$MACPEAS" ]; then
# macOS specific
if command -v netstat >/dev/null 2>&1; then
netstat -rn 2>/dev/null
else
echo "No routing information available"
fi
else
# Linux systems
if command -v ip >/dev/null 2>&1; then
ip route 2>/dev/null
echo -e "\nNeighbor table:"
ip neigh 2>/dev/null
elif command -v route >/dev/null 2>&1; then
route -n 2>/dev/null
elif [ -f "/proc/net/route" ]; then
parse_proc_route
else
echo "No routing information available"
fi
fi
# Get ARP information
print_3title "ARP Information"
if command -v arp >/dev/null 2>&1; then
if [ "$MACPEAS" ]; then
arp -a 2>/dev/null
else
arp -e 2>/dev/null || arp -a 2>/dev/null
fi
elif [ -f "/proc/net/arp" ]; then
parse_proc_arp
else
echo "No ARP information available"
fi
# Additional neighbor discovery methods
print_3title "Additional Neighbor Information"
# Check for IPv6 neighbors if available
if [ -f "/proc/net/ipv6_neigh" ]; then
echo "IPv6 Neighbors:"
cat /proc/net/ipv6_neigh 2>/dev/null | grep -v "^IP" | while read -r line; do
if [ -n "$line" ]; then
echo " $line"
fi
done
fi
# Try to get LLDP neighbors if available
if command -v lldpctl >/dev/null 2>&1; then
echo -e "\nLLDP Neighbors:"
lldpctl 2>/dev/null | grep -A2 "Interface:" | while read -r line; do
echo " $line"
done
fi
# Try to get CDP neighbors if available
if command -v cdp >/dev/null 2>&1; then
echo -e "\nCDP Neighbors:"
cdp 2>/dev/null | grep -v "^$" | while read -r line; do
echo " $line"
done
fi
echo ""
}
if [ "$EXTRA_CHECKS" ]; then
print_2title "Networks and neighbours"
if [ "$MACPEAS" ]; then
netstat -rn 2>/dev/null
else
(route || ip n || cat /proc/net/route) 2>/dev/null
fi
(arp -e || arp -a || cat /proc/net/arp) 2>/dev/null
echo ""
get_network_neighbors
fi

View File

@ -5,15 +5,173 @@
# Description: Enumerate open ports
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables:
# Functions Used: print_2title, print_3title, print_info
# Global Variables: $E, $SED_RED
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pid_dir, $tx_queue, $pid, $rem_port, $proc_file, $rem_ip, $local_ip, $rx_queue, $proto, $rem_addr, $program, $state, $header_sep, $proc_info, $inode, $header, $line, $local_addr, $local_port
# Fat linpeas: 0
# Small linpeas: 1
# Function to get process info from inode
get_process_info() {
local inode=$1
local pid=""
local program=""
if [ -n "$inode" ]; then
for pid_dir in /proc/[0-9]*/fd; do
if [ -d "$pid_dir" ]; then
if ls -l "$pid_dir" 2>/dev/null | grep -q "$inode"; then
pid=$(echo "$pid_dir" | awk -F/ '{print $3}')
if [ -f "/proc/$pid/cmdline" ]; then
program=$(tr '\0' ' ' < "/proc/$pid/cmdline" | cut -d' ' -f1)
program=$(basename "$program")
fi
break
fi
fi
done
fi
echo "$pid/$program"
}
print_2title "Active Ports"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#open-ports"
( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
echo ""
# Function to parse /proc/net/tcp and /proc/net/udp files
parse_proc_net_ports() {
local proto=$1
local proc_file="/proc/net/$proto"
local header="Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name"
local header_sep="--------------------------------------------------------------------------------"
if [ -f "$proc_file" ]; then
print_3title "Active $proto Ports (from /proc/net/$proto)"
echo "$header"
echo "$header_sep"
# Process each connection using a pipe
tail -n +2 "$proc_file" 2>/dev/null | while IFS= read -r line; do
[ -z "$line" ] && continue
# Skip header
case "$line" in
*"sl"*) continue ;;
*) : ;;
esac
# Extract fields using awk
sl=$(echo "$line" | awk '{print $1}')
local_addr=$(echo "$line" | awk '{print $2}')
rem_addr=$(echo "$line" | awk '{print $3}')
st=$(echo "$line" | awk '{print $4}')
tx_queue=$(echo "$line" | awk '{print $5}')
rx_queue=$(echo "$line" | awk '{print $6}')
uid=$(echo "$line" | awk '{print $7}')
inode=$(echo "$line" | awk '{print $10}')
# Convert hex IP:port to decimal
local_ip=$(printf "%d.%d.%d.%d" $(echo "$local_addr" | awk -F: '{printf "0x%s 0x%s 0x%s 0x%s", substr($1,7,2), substr($1,5,2), substr($1,3,2), substr($1,1,2)}'))
local_port=$(printf "%d" "0x$(echo "$local_addr" | awk -F: '{print $2}')")
rem_ip=$(printf "%d.%d.%d.%d" $(echo "$rem_addr" | awk -F: '{printf "0x%s 0x%s 0x%s 0x%s", substr($1,7,2), substr($1,5,2), substr($1,3,2), substr($1,1,2)}'))
rem_port=$(printf "%d" "0x$(echo "$rem_addr" | awk -F: '{print $2}')")
# Get process information
proc_info=$(get_process_info "$inode")
# Get state name
case $st in
"01") state="ESTABLISHED" ;;
"02") state="SYN_SENT" ;;
"03") state="SYN_RECV" ;;
"04") state="FIN_WAIT1" ;;
"05") state="FIN_WAIT2" ;;
"06") state="TIME_WAIT" ;;
"07") state="CLOSE" ;;
"08") state="CLOSE_WAIT" ;;
"09") state="LAST_ACK" ;;
"0A") state="LISTEN" ;;
"0B") state="CLOSING" ;;
"0C") state="NEW_SYN_RECV" ;;
*) state="UNKNOWN" ;;
esac
# Only show listening ports
if [ "$state" = "LISTEN" ]; then
# Format the output
printf "%-6s %-8s %-8s %-21s %-21s %-12s %s\n" \
"$proto" "$rx_queue" "$tx_queue" "$local_ip:$local_port" "$rem_ip:$rem_port" "$state" "$proc_info"
fi
done
fi
echo ""
}
# Function to get open ports information
get_open_ports() {
print_2title "Active Ports"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#open-ports"
# Try standard tools first
if command -v netstat >/dev/null 2>&1; then
print_3title "Active Ports (netstat)"
netstat -punta 2>/dev/null | grep -i listen | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
elif command -v ss >/dev/null 2>&1; then
print_3title "Active Ports (ss)"
ss -nltpu 2>/dev/null | grep -i listen | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
else
# Fallback to parsing /proc/net files
parse_proc_net_ports "tcp"
parse_proc_net_ports "udp"
fi
# Additional port information
if [ "$EXTRA_CHECKS" ] || [ "$DEBUG" ]; then
print_3title "Additional Port Information"
# Check for listening ports in /proc/net/unix
if [ -f "/proc/net/unix" ]; then
echo "Unix Domain Sockets:"
# Use awk to process the file in one go, avoiding duplicates and empty paths
awk '$8 != "" && $8 != "@" && $8 != "00000000" {
inode=$7
socket=$8
# Find process using inode
cmd="find /proc/[0-9]*/fd -ls 2>/dev/null | grep " inode " | head -n1 | awk \"{print \\$11}\" | xargs -r readlink"
pid=""
while (cmd | getline pid_dir) {
if (pid_dir != "") {
split(pid_dir, parts, "/")
pid=parts[3]
break
}
}
close(cmd)
if (pid != "") {
cmd="tr \\0 \" \" < /proc/" pid "/cmdline 2>/dev/null | cut -d\" \" -f1 | xargs -r basename"
cmd | getline prog
close(cmd)
if (prog != "") {
print " " socket " (" pid "/" prog ")"
} else {
print " " socket " (" pid ")"
}
} else {
print " " socket
}
}' /proc/net/unix 2>/dev/null | sort -u
fi
# Check for ports in use by systemd
if command -v systemctl >/dev/null 2>&1; then
echo -e "\nSystemd Socket Units:"
systemctl list-sockets 2>/dev/null | while IFS= read -r line; do
[ -z "$line" ] && continue
if ! echo "$line" | grep -q "UNIT\|listed"; then
echo " $line"
fi
done
fi
fi
echo ""
}
get_open_ports

View File

@ -5,16 +5,84 @@
# Description: MacOS network Capabilities
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, warn_exec
# Global Variables: $MACPEAS
# Functions Used: print_2title, print_3title, warn_exec
# Global Variables: $MACPEAS, $EXTRA_CHECKS
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $net_service
# Fat linpeas: 0
# Small linpeas: 0
# Function to get network capabilities information
get_macos_network_capabilities() {
print_2title "Network Capabilities"
# Basic network information
echo ""
print_3title "Network Interfaces and Configuration"
warn_exec system_profiler SPNetworkDataType
# Network locations
echo ""
print_3title "Network Locations"
warn_exec system_profiler SPNetworkLocationDataType
# Network extensions
echo ""
print_3title "Network Extensions"
if [ -d "/Library/SystemExtensions" ]; then
warn_exec systemextensionsctl list
fi
# Network security
echo ""
print_3title "Network Security"
if command -v networksetup >/dev/null 2>&1; then
echo "Firewall Status:"
warn_exec networksetup -getglobalstate
echo -e "\nFirewall Rules:"
warn_exec networksetup -listallnetworkservices | while read -r net_service; do
if [ -n "$net_service" ]; then
echo "Service: $net_service"
warn_exec networksetup -getwebproxy "$net_service"
warn_exec networksetup -getsecurewebproxy "$net_service"
warn_exec networksetup -getproxybypassdomains "$net_service"
fi
done
fi
# Additional network information if EXTRA_CHECKS is enabled
if [ "$EXTRA_CHECKS" ]; then
# Network preferences
echo ""
print_3title "Network Preferences"
if [ -f "/Library/Preferences/SystemConfiguration/preferences.plist" ]; then
warn_exec plutil -p /Library/Preferences/SystemConfiguration/preferences.plist | grep -A 5 "NetworkServices"
fi
# Network statistics
echo ""
print_3title "Network Statistics"
warn_exec netstat -s
# Network routes
echo ""
print_3title "Network Routes"
warn_exec netstat -rn
# Network interfaces details
echo ""
print_3title "Network Interfaces Details"
warn_exec ifconfig -a
# Network kernel extensions
echo ""
print_3title "Network Kernel Extensions"
warn_exec kextstat | grep -i network
fi
echo ""
}
if [ "$MACPEAS" ]; then
print_2title "Network Capabilities"
warn_exec system_profiler SPNetworkDataType
echo ""
get_macos_network_capabilities
fi

View File

@ -5,42 +5,160 @@
# Description: Enumerate macos network services
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, warn_exec
# Global Variables: $EXTRA_CHECKS, $MACPEAS
# Functions Used: print_2title, print_3title, warn_exec
# Global Variables: $EXTRA_CHECKS, $MACPEAS, $E, $SED_RED
# Initial Functions:
# Generated Global Variables: $rmMgmt, $scrShrng, $flShrng, $rLgn, $rAE, $bmM
# Generated Global Variables: $sharing_service, $profile, $port3, $service_count, $port1, $port, $services, $total, $port_list, $count, $ports, $active_ports, $port2
# Fat linpeas: 0
# Small linpeas: 0
# Function to check if a port is listening
check_listening_port() {
local port=$1
local service=$2
local count=0
# Check both IPv4 and IPv6
count=$(netstat -na 2>/dev/null | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.${port}" | wc -l)
echo "$count"
}
# Function to get sharing services status
get_sharing_services_status() {
print_2title "MacOS Sharing Services Status"
# Define services and their ports using parallel arrays
services="Screen Sharing File Sharing Remote Login Remote Management Remote Apple Events Back to My Mac AirPlay Receiver AirDrop Bonjour Printer Sharing Internet Sharing"
ports="5900 88,445,548 22 3283 3031 4488 7000 5353 5353 515,631 67,68"
# Check each service
echo "Service Status (0=OFF, >0=ON):"
echo "--------------------------------"
# Get number of services
service_count=$(echo "$services" | wc -w)
# Loop through services using index
i=1
while [ $i -le $service_count ]; do
sharing_service=$(echo "$services" | cut -d' ' -f$i)
port_list=$(echo "$ports" | cut -d' ' -f$i)
total=0
active_ports=""
# Check each port for the service
port1=$(echo "$port_list" | cut -d',' -f1)
port2=$(echo "$port_list" | cut -d',' -f2)
port3=$(echo "$port_list" | cut -d',' -f3)
for port in $port1 $port2 $port3; do
if [ -n "$port" ]; then
count=$(check_listening_port "$port" "$sharing_service")
if [ "$count" -gt 0 ]; then
total=$((total + count))
if [ -n "$active_ports" ]; then
active_ports="${active_ports},"
fi
active_ports="${active_ports}${port}"
fi
fi
done
# Print service status
if [ "$total" -gt 0 ]; then
printf "%-20s: ON (Ports: %s)\n" "$sharing_service" "$active_ports" | sed -${E} "s,ON.*,${SED_RED},g"
else
printf "%-20s: OFF\n" "$sharing_service"
fi
i=$((i + 1))
done
echo ""
}
# Function to get VPN information
get_vpn_info() {
print_3title "VPN Information"
# Get VPN configurations
warn_exec system_profiler SPNetworkLocationDataType | grep -A 5 -B 7 ": Password" | sed -${E} "s,Password|Authorization Name.*,${SED_RED},g"
# Check for VPN profiles
if [ -d "/Library/Preferences/SystemConfiguration" ]; then
echo -e "\nVPN Profiles:"
find /Library/Preferences/SystemConfiguration -name "*.plist" -exec grep -l "VPN" {} \; 2>/dev/null | while read -r profile; do
echo "Profile: $profile"
warn_exec plutil -p "$profile" | grep -A 5 "VPN"
done
fi
echo ""
}
# Function to get firewall information
get_firewall_info() {
print_3title "Firewall Information"
# Get firewall status
warn_exec system_profiler SPFirewallDataType
# Get application firewall rules
if command -v /usr/libexec/ApplicationFirewall/socketfilterfw >/dev/null 2>&1; then
echo -e "\nApplication Firewall Rules:"
warn_exec /usr/libexec/ApplicationFirewall/socketfilterfw --listapps
fi
# Get pf firewall rules if available
if command -v pfctl >/dev/null 2>&1; then
echo -e "\nPF Firewall Rules:"
warn_exec pfctl -s rules 2>/dev/null
fi
echo ""
}
# Function to get additional network information
get_additional_network_info() {
if [ "$EXTRA_CHECKS" ]; then
print_3title "Additional Network Information"
# Bluetooth information
echo "Bluetooth Status:"
warn_exec system_profiler SPBluetoothDataType
# Ethernet information
echo -e "\nEthernet Status:"
warn_exec system_profiler SPEthernetDataType
# USB network adapters
echo -e "\nUSB Network Adapters:"
warn_exec system_profiler SPUSBDataType
# Network kernel extensions
echo -e "\nNetwork Kernel Extensions:"
warn_exec kextstat | grep -i "network\|ethernet\|wifi\|bluetooth"
# Network daemons
echo -e "\nNetwork Daemons:"
warn_exec launchctl list | grep -i "network\|vpn\|firewall\|sharing"
fi
echo ""
}
# Main function to get all network services information
get_macos_network_services() {
if [ "$MACPEAS" ]; then
# Get sharing services status
get_sharing_services_status
# Get VPN information
get_vpn_info
# Get firewall information
get_firewall_info
# Get additional network information if EXTRA_CHECKS is enabled
get_additional_network_info
fi
}
if [ "$MACPEAS" ]; then
print_2title "Any MacOS Sharing Service Enabled?"
rmMgmt=$(netstat -na | grep LISTEN | grep tcp46 | grep "*.3283" | wc -l);
scrShrng=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.5900" | wc -l);
flShrng=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep -E "\*.88|\*.445|\*.548" | wc -l);
rLgn=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.22" | wc -l);
rAE=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.3031" | wc -l);
bmM=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.4488" | wc -l);
printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharing: %s\nFile Sharing: %s\nRemote Login: %s\nRemote Mgmt: %s\nRemote Apple Events: %s\nBack to My Mac: %s\n\n" "$scrShrng" "$flShrng" "$rLgn" "$rmMgmt" "$rAE" "$bmM";
echo ""
print_2title "VPN Creds"
system_profiler SPNetworkLocationDataType | grep -A 5 -B 7 ": Password" | sed -${E} "s,Password|Authorization Name.*,${SED_RED},"
echo ""
print_2title "Firewall status"
warn_exec system_profiler SPFirewallDataType
echo ""
if [ "$EXTRA_CHECKS" ]; then
print_2title "Bluetooth Info"
warn_exec system_profiler SPBluetoothDataType
echo ""
print_2title "Ethernet Info"
warn_exec system_profiler SPEthernetDataType
echo ""
print_2title "USB Info"
warn_exec system_profiler SPUSBDataType
echo ""
fi
get_macos_network_services
fi

View File

@ -1,23 +1,168 @@
# Title: Network Information - Tcpdump
# Title: Network Information - Network Traffic Analysis
# ID: NT_Tcpdump
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Can I sniff with tcpdump?
# Description: Check network traffic analysis capabilities and tools
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_no, print_2title, print_info
# Global Variables:
# Functions Used: print_2title, print_3title, print_info, warn_exec
# Global Variables: $EXTRA_CHECKS, $E, $SED_RED, $SED_GREEN
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $tools_found, $tool, $interfaces, $interfaces_found, $iface, $cmd, $pattern, $patterns
# Fat linpeas: 0
# Small linpeas: 1
# Function to check if a command exists and is executable
check_command() {
local cmd=$1
if command -v "$cmd" >/dev/null 2>&1; then
if [ -x "$(command -v "$cmd")" ]; then
return 0
fi
fi
return 1
}
print_2title "Can I sniff with tcpdump?"
timeout 1 tcpdump >/dev/null 2>&1
if [ $? -eq 124 ]; then #If 124, then timed out == It worked
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#sniffing"
echo "You can sniff with tcpdump!" | sed -${E} "s,.*,${SED_RED},"
else echo_no
fi
echo ""
# Function to check if we can sniff on an interface
check_interface_sniffable() {
local iface=$1
if timeout 1 tcpdump -i "$iface" -c 1 >/dev/null 2>&1; then
return 0
fi
return 1
}
# Function to check for promiscuous mode
check_promiscuous_mode() {
local iface=$1
if ip link show "$iface" 2>/dev/null | grep -q "PROMISC"; then
return 0
fi
return 1
}
# Main function to check network traffic analysis capabilities
check_network_traffic_analysis() {
print_2title "Network Traffic Analysis Capabilities"
# Check for sniffing tools
echo ""
print_3title "Available Sniffing Tools"
tools_found=0
if check_command tcpdump; then
echo "tcpdump is available" | sed -${E} "s,.*,${SED_GREEN},g"
tools_found=1
# Check tcpdump version and capabilities
warn_exec tcpdump --version 2>/dev/null | head -n 1
fi
if check_command tshark; then
echo "tshark is available" | sed -${E} "s,.*,${SED_GREEN},g"
tools_found=1
# Check tshark version
warn_exec tshark --version 2>/dev/null | head -n 1
fi
if check_command wireshark; then
echo "wireshark is available" | sed -${E} "s,.*,${SED_GREEN},g"
tools_found=1
fi
if [ $tools_found -eq 0 ]; then
echo "No sniffing tools found" | sed -${E} "s,.*,${SED_RED},g"
fi
# Check network interfaces
echo ""
print_3title "Network Interfaces Sniffing Capabilities"
interfaces_found=0
# Get list of network interfaces
if command -v ip >/dev/null 2>&1; then
interfaces=$(ip -o link show | awk -F': ' '{print $2}')
elif command -v ifconfig >/dev/null 2>&1; then
interfaces=$(ifconfig -a | grep -o '^[^ ]*:' | tr -d ':')
else
interfaces=$(ls /sys/class/net/ 2>/dev/null)
fi
for iface in $interfaces; do
if [ "$iface" != "lo" ]; then # Skip loopback
echo -n "Interface $iface: "
if check_interface_sniffable "$iface"; then
echo "Sniffable" | sed -${E} "s,.*,${SED_GREEN},g"
interfaces_found=1
# Check promiscuous mode
if check_promiscuous_mode "$iface"; then
echo " - Promiscuous mode enabled" | sed -${E} "s,.*,${SED_RED},g"
fi
# Get interface details
if [ "$EXTRA_CHECKS" ]; then
echo " - Interface details:"
warn_exec ip addr show "$iface" 2>/dev/null || ifconfig "$iface" 2>/dev/null
fi
else
echo "Not sniffable" | sed -${E} "s,.*,${SED_RED},g"
fi
fi
done
if [ $interfaces_found -eq 0 ]; then
echo "No sniffable interfaces found" | sed -${E} "s,.*,${SED_RED},g"
fi
# Check for sensitive traffic patterns if we have sniffing capabilities
if [ $tools_found -eq 1 ] && [ $interfaces_found -eq 1 ]; then
echo ""
print_3title "Sensitive Traffic Detection"
print_info "Checking for common sensitive traffic patterns..."
# List of sensitive traffic patterns to check
patterns="
- HTTP Basic Auth
- FTP credentials
- SMTP credentials
- MySQL/MariaDB traffic
- PostgreSQL traffic
- Redis traffic
- MongoDB traffic
- LDAP traffic
- SMB traffic
- DNS queries
- SNMP traffic
- Many more...
"
echo "$patterns" | while read -r pattern; do
if [ -n "$pattern" ]; then
echo "$pattern"
fi
done
print_info "To capture sensitive traffic, you can use:"
echo "tcpdump -i <interface> -w capture.pcap" | sed -${E} "s,.*,${SED_GREEN},g"
echo "tshark -i <interface> -w capture.pcap" | sed -${E} "s,.*,${SED_GREEN},g"
fi
# Additional information
if [ "$EXTRA_CHECKS" ]; then
echo ""
print_3title "Additional Network Analysis Information"
# Check for network monitoring tools
echo "Checking for network monitoring tools..."
for tool in nethogs iftop iotop nload bmon; do
if check_command "$tool"; then
echo "$tool is available" | sed -${E} "s,.*,${SED_GREEN},g"
fi
done
fi
echo ""
}
# Run the main function
check_network_traffic_analysis

View File

@ -1,20 +1,210 @@
# Title: Network Information - Iptables
# Title: Network Information - Firewall Rules Analysis
# ID: NT_Iptables
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Enumerate iptables rules
# Description: Analyze firewall rules and configurations
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title
# Global Variables: $EXTRA_CHECKS
# Functions Used: print_2title, print_3title, warn_exec, echo_not_found
# Global Variables: $EXTRA_CHECKS, $E, $SED_RED, $SED_GREEN, $SED_YELLOW
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $rules_file, $cmd, $tool, $config_file
# Fat linpeas: 0
# Small linpeas: 1
# Function to check if a command exists and is executable
check_command() {
local cmd=$1
if command -v "$cmd" >/dev/null 2>&1; then
if [ -x "$(command -v "$cmd")" ]; then
return 0
fi
fi
return 1
}
if [ "$EXTRA_CHECKS" ]; then
print_2title "Iptables rules"
(timeout 1 iptables -L 2>/dev/null; cat /etc/iptables/* | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null) 2>/dev/null || echo_not_found "iptables rules"
echo ""
fi
# Function to analyze iptables rules
analyze_iptables() {
echo ""
print_3title "Iptables Rules"
# Check if iptables is available
if ! check_command iptables; then
echo_not_found "iptables"
return
fi
# Check if we have permission to list rules
if ! timeout 1 iptables -L >/dev/null 2>&1; then
echo "No permission to list iptables rules" | sed -${E} "s,.*,${SED_RED},g"
return
fi
# Get iptables version
warn_exec iptables --version 2>/dev/null
# List all chains and rules
echo -e "\nFilter Table Rules:"
warn_exec iptables -L -v -n 2>/dev/null
echo -e "\nNAT Table Rules:"
warn_exec iptables -t nat -L -v -n 2>/dev/null
echo -e "\nMangle Table Rules:"
warn_exec iptables -t mangle -L -v -n 2>/dev/null
# Check for custom chains
echo -e "\nCustom Chains:"
warn_exec iptables -L -v -n | grep -E "^Chain [A-Za-z]" | grep -v "INPUT\|OUTPUT\|FORWARD\|PREROUTING\|POSTROUTING" 2>/dev/null
# Check for saved rules
echo -e "\nSaved Rules:"
for rules_file in /etc/iptables/* /etc/iptables/rules.v4 /etc/iptables/rules.v6 /etc/iptables-save /etc/iptables.save; do
if [ -f "$rules_file" ]; then
echo "Found rules in $rules_file:"
warn_exec cat "$rules_file" | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null
fi
done
}
# Function to analyze nftables rules
analyze_nftables() {
echo ""
print_3title "Nftables Rules"
# Check if nft is available
if ! check_command nft; then
echo_not_found "nftables"
return
fi
# Check if we have permission to list rules
if ! timeout 1 nft list ruleset >/dev/null 2>&1; then
echo "No permission to list nftables rules" | sed -${E} "s,.*,${SED_RED},g"
return
fi
# Get nftables version
warn_exec nft --version 2>/dev/null
# List all rules
echo -e "\nNftables Ruleset:"
warn_exec nft list ruleset 2>/dev/null
# Check for saved rules
echo -e "\nSaved Rules:"
for rules_file in /etc/nftables.conf /etc/sysconfig/nftables.conf; do
if [ -f "$rules_file" ]; then
echo "Found rules in $rules_file:"
warn_exec cat "$rules_file" | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null
fi
done
}
# Function to analyze firewalld rules
analyze_firewalld() {
echo ""
print_3title "Firewalld Rules"
# Check if firewall-cmd is available
if ! check_command firewall-cmd; then
echo_not_found "firewalld"
return
fi
# Check if firewalld is running
if ! systemctl is-active firewalld >/dev/null 2>&1; then
echo "Firewalld is not running" | sed -${E} "s,.*,${SED_YELLOW},g"
return
fi
# Get firewalld version
warn_exec firewall-cmd --version 2>/dev/null
# List all zones
echo -e "\nFirewalld Zones:"
warn_exec firewall-cmd --list-all-zones 2>/dev/null
# List active zones
echo -e "\nActive Zones:"
warn_exec firewall-cmd --get-active-zones 2>/dev/null
# List services
echo -e "\nAvailable Services:"
warn_exec firewall-cmd --list-services 2>/dev/null
# List ports
echo -e "\nOpen Ports:"
warn_exec firewall-cmd --list-ports 2>/dev/null
# List rich rules
echo -e "\nRich Rules:"
warn_exec firewall-cmd --list-rich-rules 2>/dev/null
}
# Function to analyze UFW rules
analyze_ufw() {
echo ""
print_3title "UFW Rules"
# Check if ufw is available
if ! check_command ufw; then
echo_not_found "ufw"
return
fi
# Check if UFW is running
if ! ufw status >/dev/null 2>&1; then
echo "UFW is not running" | sed -${E} "s,.*,${SED_YELLOW},g"
return
fi
# Get UFW version
warn_exec ufw version 2>/dev/null
# List rules
echo -e "\nUFW Rules:"
warn_exec ufw status verbose 2>/dev/null
# List numbered rules
echo -e "\nNumbered Rules:"
warn_exec ufw status numbered 2>/dev/null
}
# Main function to analyze firewall rules
analyze_firewall_rules() {
print_2title "Firewall Rules Analysis"
# Analyze different firewall systems
analyze_iptables
analyze_nftables
analyze_firewalld
analyze_ufw
# Additional checks if EXTRA_CHECKS is enabled
if [ "$EXTRA_CHECKS" ]; then
echo ""
print_3title "Additional Firewall Information"
# Check for common firewall configuration files
echo "Checking for firewall configuration files..."
for config_file in /etc/sysconfig/iptables /etc/sysconfig/ip6tables /etc/iptables/rules.v4 /etc/iptables/rules.v6 /etc/nftables.conf /etc/ufw/user.rules /etc/ufw/user6.rules; do
if [ -f "$config_file" ]; then
echo "Found configuration file: $config_file" | sed -${E} "s,.*,${SED_GREEN},g"
fi
done
# Check for firewall management tools
echo -e "\nChecking for firewall management tools..."
for tool in shorewall shorewall6 ferm; do
if check_command "$tool"; then
echo "$tool is available" | sed -${E} "s,.*,${SED_GREEN},g"
fi
done
fi
echo ""
}
# Run the main function
analyze_firewall_rules

View File

@ -1,20 +1,192 @@
# Title: Network Information - Inetconf
# Title: Network Information - Inetd/Xinetd Services Analysis
# ID: NT_Inetdconf
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Check content of /etc/inetd.conf & /etc/xinetd.conf
# Description: Analyze inetd and xinetd services and configurations
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title
# Global Variables: $EXTRA_CHECKS
# Functions Used: print_2title, print_3title, warn_exec, echo_not_found
# Global Variables: $EXTRA_CHECKS, $E, $SED_RED, $SED_GREEN, $SED_YELLOW
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $inetd_service, $log_file, $cmd, $service_name, $conf_file, $service_dir, $service_file, $inetd_file
# Fat linpeas: 0
# Small linpeas: 0
# Function to check if a command exists and is executable
check_command() {
local cmd=$1
if command -v "$cmd" >/dev/null 2>&1; then
if [ -x "$(command -v "$cmd")" ]; then
return 0
fi
fi
return 1
}
if [ "$EXTRA_CHECKS" ]; then
print_2title "Content of /etc/inetd.conf & /etc/xinetd.conf"
(cat /etc/inetd.conf /etc/xinetd.conf 2>/dev/null | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null) || echo_not_found "/etc/inetd.conf"
echo ""
fi
# Function to analyze inetd services
analyze_inetd() {
echo ""
print_3title "Inetd Services"
# Check if inetd is installed
if ! check_command inetd; then
echo_not_found "inetd"
return
fi
# Check if inetd is running
if ! pgrep -x inetd >/dev/null 2>&1; then
echo "inetd is not running" | sed -${E} "s,.*,${SED_YELLOW},g"
fi
# Get inetd version
warn_exec inetd -v 2>/dev/null
# Check main configuration file
if [ -f "/etc/inetd.conf" ]; then
echo -e "\nInetd Configuration (/etc/inetd.conf):"
warn_exec cat /etc/inetd.conf | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null
# Check for potentially dangerous services
echo -e "\nPotentially Dangerous Services:"
warn_exec cat /etc/inetd.conf | grep -v "^$" | grep -Ev "\W+\#|^#" | grep -iE "shell|login|exec|rsh|rlogin|rexec|finger|telnet|ftp|tftp" 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
else
echo_not_found "/etc/inetd.conf"
fi
# Check for additional configuration files
echo -e "\nAdditional Inetd Configuration Files:"
for conf_file in /etc/inetd.d/* /etc/inet/*.conf; do
if [ -f "$conf_file" ]; then
echo "Found configuration in $conf_file:"
warn_exec cat "$conf_file" | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null
fi
done
}
# Function to analyze xinetd services
analyze_xinetd() {
echo ""
print_3title "Xinetd Services"
# Check if xinetd is installed
if ! check_command xinetd; then
echo_not_found "xinetd"
return
fi
# Check if xinetd is running
if ! pgrep -x xinetd >/dev/null 2>&1; then
echo "xinetd is not running" | sed -${E} "s,.*,${SED_YELLOW},g"
fi
# Get xinetd version
warn_exec xinetd -version 2>/dev/null
# Check main configuration file
if [ -f "/etc/xinetd.conf" ]; then
echo -e "\nXinetd Configuration (/etc/xinetd.conf):"
warn_exec cat /etc/xinetd.conf | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null
# Check for included configurations
echo -e "\nIncluded Configurations:"
warn_exec grep -r "includedir" /etc/xinetd.conf 2>/dev/null
else
echo_not_found "/etc/xinetd.conf"
fi
# Check for service-specific configurations
echo -e "\nService Configurations:"
for service_dir in /etc/xinetd.d/ /etc/xinetd/; do
if [ -d "$service_dir" ]; then
echo "Services in $service_dir:"
for service_file in "$service_dir"/*; do
if [ -f "$service_file" ]; then
service_name=$(basename "$service_file")
echo -e "\nService: $service_name"
# Check if service is enabled
if grep -q "disable.*=.*no" "$service_file" 2>/dev/null; then
echo "Status: Enabled" | sed -${E} "s,.*,${SED_RED},g"
else
echo "Status: Disabled"
fi
# Show service configuration
warn_exec cat "$service_file" | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null
# Check for potentially dangerous configurations
if grep -qiE "server.*=.*/bin/|server.*=.*/sbin/|server.*=.*/usr/bin/|server.*=.*/usr/sbin/" "$service_file" 2>/dev/null; then
echo "Warning: Service uses system binaries" | sed -${E} "s,.*,${SED_RED},g"
fi
if grep -qiE "user.*=.*root|user.*=.*0" "$service_file" 2>/dev/null; then
echo "Warning: Service runs as root" | sed -${E} "s,.*,${SED_RED},g"
fi
fi
done
fi
done
}
# Function to check for running inetd/xinetd services
check_running_services() {
echo ""
print_3title "Running Inetd/Xinetd Services"
# Check netstat for services
if check_command netstat; then
echo "Active Services (from netstat):"
warn_exec netstat -tulpn 2>/dev/null | grep -E "inetd|xinetd" | sed -${E} "s,.*,${SED_RED},g"
fi
# Check ss for services
if check_command ss; then
echo -e "\nActive Services (from ss):"
warn_exec ss -tulpn 2>/dev/null | grep -E "inetd|xinetd" | sed -${E} "s,.*,${SED_RED},g"
fi
# Check for service processes
echo -e "\nRunning Service Processes:"
for inetd_service in $(pgrep -l inetd 2>/dev/null; pgrep -l xinetd 2>/dev/null); do
echo "$inetd_service" | sed -${E} "s,.*,${SED_RED},g"
done
}
# Main function to analyze inetd/xinetd services
analyze_inetd_services() {
print_2title "Inetd/Xinetd Services Analysis"
# Analyze inetd and xinetd services
analyze_inetd
analyze_xinetd
# Check for running services
check_running_services
# Additional checks if EXTRA_CHECKS is enabled
if [ "$EXTRA_CHECKS" ]; then
echo ""
print_3title "Additional Inetd/Xinetd Information"
# Check for inetd/xinetd logs
echo "Checking for service logs..."
for log_file in /var/log/inetd.log /var/log/xinetd.log /var/log/messages /var/log/syslog; do
if [ -f "$log_file" ]; then
echo "Found log file: $log_file" | sed -${E} "s,.*,${SED_GREEN},g"
warn_exec tail -n 20 "$log_file" | grep -iE "inetd|xinetd" 2>/dev/null
fi
done
# Check for inetd/xinetd related files
echo -e "\nChecking for related files..."
for file in /etc/init.d/inetd /etc/init.d/xinetd /etc/default/inetd /etc/default/xinetd; do
if [ -f "$inetd_file" ]; then
echo "Found file: $inetd_file" | sed -${E} "s,.*,${SED_GREEN},g"
warn_exec cat "$inetd_file" | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null
fi
done
fi
echo ""
}
# Run the main function
analyze_inetd_services

View File

@ -2,18 +2,59 @@
# ID: UG_Pkexec
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Check Pkexec policy
# Description: Check Pkexec policy and related files for privilege escalation
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $Groups, $groupsB, $groupsVB,$nosh_usrs, $sh_usrs, $USER
# Functions Used: print_2title, print_info
# Global Variables: $Groups, $groupsB, $groupsVB, $nosh_usrs, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pkexec_bin, $policy_dir, $policy_file
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Checking Pkexec policy"
print_2title "Checking Pkexec and Polkit"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/interesting-groups-linux-pe/index.html#pe---method-2"
(cat /etc/polkit-1/localauthority.conf.d/* 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED}," | sed -${E} "s,$groupsVB,${SED_RED}," | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,$USER,${SED_RED_YELLOW}," | sed -${E} "s,$Groups,${SED_RED_YELLOW},") || echo_not_found "/etc/polkit-1/localauthority.conf.d"
echo ""
print_3title "Polkit Binary"
# Check pkexec binary
pkexec_bin=$(command -v pkexec 2>/dev/null)
if [ -n "$pkexec_bin" ]; then
echo "Pkexec binary found at: $pkexec_bin" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
if [ -u "$pkexec_bin" ]; then
echo "Pkexec binary has SUID bit set!" | sed -${E} "s,.*,${SED_RED},g"
fi
ls -l "$pkexec_bin" 2>/dev/null
# Check polkit version for known vulnerabilities
if command -v pkexec >/dev/null 2>&1; then
pkexec --version 2>/dev/null
fi
fi
# Check polkit policies
echo ""
print_3title "Polkit Policies"
for policy_dir in "/etc/polkit-1/localauthority.conf.d/" "/etc/polkit-1/rules.d/" "/usr/share/polkit-1/rules.d/"; do
if [ -d "$policy_dir" ]; then
echo "Checking $policy_dir:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
if [ -w "$policy_dir" ]; then
echo "WARNING: $policy_dir is writable!" | sed -${E} "s,.*,${SED_RED},g"
fi
for policy_file in "$policy_dir"/*; do
if [ -f "$policy_file" ]; then
if [ -w "$policy_file" ]; then
echo "WARNING: $policy_file is writable!" | sed -${E} "s,.*,${SED_RED},g"
fi
cat "$policy_file" 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$Groups,${SED_RED},g"
fi
done
fi
done
# Check for polkit authentication agent
echo ""
print_3title "Polkit Authentication Agent"
ps aux 2>/dev/null | grep -i "polkit" | grep -v "grep"
echo ""

View File

@ -2,17 +2,36 @@
# ID: UG_Superusers
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Superusers
# Description: Check for superusers and users with UID 0
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Global Variables:$knw_usrs ,$nosh_usrs,$sh_usrs, $USER
# Functions Used: print_2title, print_info
# Global Variables: $knw_usrs, $nosh_usrs, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $group
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Superusers"
awk -F: '($3 == "0") {print}' /etc/passwd 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED_YELLOW}," | sed "s,root,${SED_RED},"
print_2title "Superusers and UID 0 Users"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/interesting-groups-linux-pe/index.html"
# Check /etc/passwd for UID 0 users
echo ""
print_3title "Users with UID 0 in /etc/passwd"
awk -F: '($3 == "0") {print}' /etc/passwd 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_RED_YELLOW},g" | sed "s,root,${SED_RED},g"
if [ command -v getent >/dev/null 2>&1 ]; then
for group in sudo wheel adm docker lxd lxc root shadow disk video; do
if getent group "$group" >/dev/null 2>&1; then
echo "- Users in group '$group':"
getent group "$group" 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_RED},g" | sed "s,root,${SED_RED},g"
fi
done
fi
# Check for users with sudo privileges in sudoers
echo ""
print_3title "Users with sudo privileges in sudoers"
grep -v "^#" /etc/sudoers 2>/dev/null | grep -v "^$" | grep -v "^Defaults" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_RED_YELLOW},g" | sed "s,root,${SED_RED},g"
echo ""

View File

@ -2,7 +2,7 @@
# ID: UG_Login_now
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Login now
# Description: Check currently logged in users and their sessions
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
@ -13,6 +13,45 @@
# Small linpeas: 1
print_2title "Login now"
(w || who || finger || users) 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
print_2title "Currently Logged in Users"
# Check basic user information
echo ""
print_3title "Basic user information"
(w || who || finger || users) 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
# Check for active sessions
echo ""
print_3title "Active sessions"
if command -v w >/dev/null 2>&1; then
w 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check for logged in users via utmp
echo ""
print_3title "Logged in users (utmp)"
if [ -f "/var/run/utmp" ]; then
who -a 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check for SSH sessions
echo ""
print_3title "SSH sessions"
if command -v ss >/dev/null 2>&1; then
ss -tnp | grep ":22" 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check for screen sessions
echo ""
print_3title "Screen sessions"
if command -v screen >/dev/null 2>&1; then
screen -ls 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check for tmux sessions
echo ""
print_3title "Tmux sessions"
if command -v tmux >/dev/null 2>&1; then
tmux list-sessions 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
echo ""

View File

@ -2,17 +2,54 @@
# ID: UG_Last_logons
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Last logons
# Description: Check last logons and login history
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Global Variables: $knw_usrs, $nosh_usrs, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $EXISTS_FINGER, $ushell
# Fat linpeas: 0
# Small linpeas: 0
# Small linpeas: 1
print_2title "Last Logons and Login History"
print_2title "Last logons"
(last -Faiw || last) 2>/dev/null | tail | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_RED}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
# Check last logins
echo ""
print_3title "Last logins"
if command -v last >/dev/null 2>&1; then
last -n 20 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check failed login attempts
echo ""
print_3title "Failed login attempts"
if command -v lastb >/dev/null 2>&1; then
lastb -n 20 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Check auth logs for recent logins
echo ""
print_3title "Recent logins from auth.log (limit 20)"
if [ -f "/var/log/auth.log" ]; then
grep -i "login\|authentication\|accepted" /var/log/auth.log 2>/dev/null | tail -n 20 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${SED_RED},g"
fi
# Last time logon each user
echo ""
if command -v lastlog >/dev/null 2>&1; then
print_3title "Last time logon each user"
lastlog 2>/dev/null | grep -v "Never" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
fi
EXISTS_FINGER="$(command -v finger 2>/dev/null || echo -n '')"
if [ "$MACPEAS" ] && [ "$EXISTS_FINGER" ]; then
dscl . list /Users | while read un; do
ushell=$(dscl . -read "/Users/$un" UserShell | cut -d " " -f2)
if grep -q "$ushell" /etc/shells; then #Shell user
finger "$un" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
echo ""
fi
done
fi
echo ""

View File

@ -1,29 +0,0 @@
# Title: Users Information - Login info
# ID: UG_Login_info
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Last time logon each user
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Global Variables: $knw_usrs, $MACPEAS, $nosh_usrs, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables: EXISTS_FINGER, ushell
# Fat linpeas: 0
# Small linpeas: 0
print_2title "Last time logon each user"
lastlog 2>/dev/null | grep -v "Never" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
EXISTS_FINGER="$(command -v finger 2>/dev/null || echo -n '')"
if [ "$MACPEAS" ] && [ "$EXISTS_FINGER" ]; then
dscl . list /Users | while read un; do
ushell=$(dscl . -read "/Users/$un" UserShell | cut -d " " -f2)
if grep -q "$ushell" /etc/shells; then #Shell user
finger "$un" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
echo ""
fi
done
fi
echo ""

View File

@ -8,15 +8,18 @@
# Functions Used: print_2title
# Global Variables: $MACPEAS
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $user_home
# Fat linpeas: 0
# Small linpeas: 0
if [ "$MACPEAS" ];then
print_2title "All Login and Logout hooks"
defaults read /Users/*/Library/Preferences/com.apple.loginwindow.plist 2>/dev/null | grep -e "Hook"
defaults read /private/var/root/Library/Preferences/com.apple.loginwindow.plist
for user_home in /Users/*/ /private/var/root/; do
if [ -f "${user_home}Library/Preferences/com.apple.loginwindow.plist" ]; then
echo "User: $(basename "$user_home")" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
defaults read "${user_home}Library/Preferences/com.apple.loginwindow.plist" 2>/dev/null | grep -e "Hook" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
done
echo ""
fi

View File

@ -1,14 +1,14 @@
# Title: Users Information - Macos systemKey
# Title: Users Information - MacOS Keychains
# ID: UG_Macos_keychains
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Get macOS systemKey
# Description: Get macOS keychains information
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
# Functions Used: print_2title, print_info
# Global Variables: $MACPEAS
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $user_home
# Fat linpeas: 0
# Small linpeas: 0
@ -16,6 +16,14 @@
if [ "$MACPEAS" ];then
print_2title "Keychains"
print_info "https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/macos-sensitive-locations.html#chainbreaker"
security list-keychains
echo "System Keychains:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
security list-keychains 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
echo -e "\nUser Keychains:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
for user_home in /Users/*/; do
if [ -d "${user_home}Library/Keychains" ]; then
echo "- User: $(basename "$user_home")" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
ls -la "${user_home}Library/Keychains/" 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
fi
done
echo ""
fi

View File

@ -1,8 +1,8 @@
# Title: Users Information - Macos systemKey
# Title: Users Information - MacOS SystemKey
# ID: UG_Macos_systemkey
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Get macOS systemKey
# Description: Get macOS SystemKey information (used for FileVault encryption)
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title
@ -15,10 +15,14 @@
if [ "$MACPEAS" ];then
print_2title "SystemKey"
ls -l /var/db/SystemKey
echo "The SystemKey is used by FileVault to encrypt/decrypt the volume. If you can read it, you might be able to decrypt the disk."
echo -e "\nSystemKey file permissions:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
ls -l /var/db/SystemKey 2>/dev/null | sed -${E} "s,.*,${SED_RED_YELLOW},g"
if [ -r "/var/db/SystemKey" ]; then
echo "You can read /var/db/SystemKey" | sed -${E} "s,.*,${SED_RED_YELLOW},";
hexdump -s 8 -n 24 -e '1/1 "%.2x"' /var/db/SystemKey | sed -${E} "s,.*,${SED_RED_YELLOW},";
echo -e "\nWARNING: You can read /var/db/SystemKey!" | sed -${E} "s,.*,${SED_RED},g"
echo "SystemKey content (first 24 bytes after header):" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
hexdump -s 8 -n 24 -e '1/1 "%.2x"' /var/db/SystemKey | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
echo ""
fi

View File

@ -2,21 +2,48 @@
# ID: UG_Pgp_keys
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: PGP keys
# Description: Check for PGP keys and related files that might contain sensitive information
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title
# Global Variables:
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $HOME
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pgp_file
# Fat linpeas: 0
# Small linpeas: 1
print_2title "Do I have PGP keys?"
command -v gpg 2>/dev/null || echo_not_found "gpg"
gpg --list-keys 2>/dev/null
command -v netpgpkeys 2>/dev/null || echo_not_found "netpgpkeys"
netpgpkeys --list-keys 2>/dev/null
command -v netpgp 2>/dev/null || echo_not_found "netpgp"
print_2title "PGP Keys and Related Files"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#pgp-keys"
# Check for GPG
echo "GPG:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
if command -v gpg >/dev/null 2>&1; then
echo "GPG is installed, listing keys:"
gpg --list-keys 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
# Check for private keys
gpg --list-secret-keys 2>/dev/null | sed -${E} "s,.*,${SED_RED_YELLOW},g"
else
echo_not_found "gpg"
fi
# Check for NetPGP
echo -e "\nNetPGP:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
if command -v netpgpkeys >/dev/null 2>&1; then
echo "NetPGP is installed" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
netpgpkeys --list-keys 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
else
echo_not_found "netpgpkeys"
fi
# Check for common PGP files
echo -e "\nPGP Related Files:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
for pgp_file in "$HOME/.gnupg" "$HOME/.pgp" "$HOME/.openpgp" "$HOME/.ssh/gpg-agent.conf" "$HOME/.config/gpg"; do
if [ -e "$pgp_file" ]; then
echo "Found: $pgp_file"
if [ -d "$pgp_file" ]; then
ls -la "$pgp_file" 2>/dev/null
fi
fi
done
echo ""

View File

@ -2,28 +2,52 @@
# ID: UG_Clipboard_highlighted_text
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Clipboard and highlighted text
# Description: Check clipboard and highlighted text for sensitive information
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $DEBUG, $pwd_inside_history
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $content
# Fat linpeas: 0
# Small linpeas: 1
if [ "$(command -v xclip 2>/dev/null || echo -n '')" ] || [ "$(command -v xsel 2>/dev/null || echo -n '')" ] || [ "$(command -v pbpaste 2>/dev/null || echo -n '')" ] || [ "$DEBUG" ]; then
print_2title "Clipboard or highlighted text?"
if [ "$(command -v xclip 2>/dev/null || echo -n '')" ] || [ "$(command -v xsel 2>/dev/null || echo -n '')" ] || [ "$(command -v pbpaste 2>/dev/null || echo -n '')" ] || [ "$(command -v wl-paste 2>/dev/null || echo -n '')" ] || [ "$DEBUG" ]; then
print_2title "Clipboard and Highlighted Text"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#clipboard"
# Function to check clipboard content
check_clipboard() {
local content="$1"
if [ -n "$content" ]; then
echo "$content" | sed -${E} "s,$pwd_inside_history,${SED_RED},g" | sed -${E} "s,(password|passwd|pwd).*=.*,${SED_RED},g" | sed -${E} "s,(token|key|secret).*=.*,${SED_RED},g"
fi
}
# Check different clipboard tools
if [ "$(command -v xclip 2>/dev/null || echo -n '')" ]; then
echo "Clipboard: "$(xclip -o -selection clipboard 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
echo "Highlighted text: "$(xclip -o 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
echo "Using xclip:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
echo "Clipboard:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(xclip -o -selection clipboard 2>/dev/null)"
echo "Highlighted text:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(xclip -o 2>/dev/null)"
elif [ "$(command -v xsel 2>/dev/null || echo -n '')" ]; then
echo "Clipboard: "$(xsel -ob 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
echo "Highlighted text: "$(xsel -o 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
echo "Using xsel:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
echo "Clipboard:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(xsel -ob 2>/dev/null)"
echo "Highlighted text:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(xsel -o 2>/dev/null)"
elif [ "$(command -v pbpaste 2>/dev/null || echo -n '')" ]; then
echo "Clipboard: "$(pbpaste) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
else echo_not_found "xsel and xclip"
echo "Using pbpaste:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
echo "Clipboard:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(pbpaste 2>/dev/null)"
elif [ "$(command -v wl-paste 2>/dev/null || echo -n '')" ]; then
echo "Using wl-paste:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
echo "Clipboard:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
check_clipboard "$(wl-paste 2>/dev/null)"
else
echo_not_found "clipboard tools (xclip, xsel, pbpaste, wl-paste)"
fi
echo ""
fi

View File

@ -2,23 +2,54 @@
# ID: UG_Doas
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Checking doas.conf
# Description: Check doas configuration and permissions for privilege escalation
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title
# Global Variables: $DEBUG, $nosh_usrs, $sh_usrs, $USER
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $DEBUG, $nosh_usrs, $sh_usrs, $USER
# Initial Functions:
# Generated Global Variables: $doas_dir_name
# Generated Global Variables: $doas_dir_name, $doas_bin, $conf_file
# Fat linpeas: 0
# Small linpeas: 1
if [ -f "/etc/doas.conf" ] || [ "$DEBUG" ]; then
print_2title "Checking doas.conf"
doas_dir_name=$(dirname "$(command -v doas || echo -n '')" 2>/dev/null)
if [ "$(cat /etc/doas.conf $doas_dir_name/doas.conf $doas_dir_name/../etc/doas.conf $doas_dir_name/etc/doas.conf 2>/dev/null)" ]; then
cat /etc/doas.conf "$doas_dir_name/doas.conf" "$doas_dir_name/../etc/doas.conf" "$doas_dir_name/etc/doas.conf" 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_RED}," | sed "s,root,${SED_RED}," | sed "s,nopass,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,$USER,${SED_RED_YELLOW},"
else echo_not_found "doas.conf"
if [ -f "/etc/doas.conf" ] || [ -f "/usr/local/etc/doas.conf" ] || [ "$DEBUG" ]; then
print_2title "Doas Configuration"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#doas"
# Find doas binary and its config locations
doas_bin=$(command -v doas 2>/dev/null)
if [ -n "$doas_bin" ]; then
doas_dir_name=$(dirname "$doas_bin")
echo "Doas binary found at: $doas_bin" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
# Check doas binary permissions
if [ -u "$doas_bin" ]; then
echo "Doas binary has SUID bit set!" | sed -${E} "s,.*,${SED_RED},g"
fi
ls -l "$doas_bin" 2>/dev/null | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
echo ""
fi
# Check all possible doas.conf locations
echo -e "\nChecking doas.conf files:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
for conf_file in "/etc/doas.conf" "$doas_dir_name/doas.conf" "$doas_dir_name/../etc/doas.conf" "$doas_dir_name/etc/doas.conf" "/usr/local/etc/doas.conf"; do
if [ -f "$conf_file" ]; then
echo "Found: $conf_file" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
if [ -w "$conf_file" ]; then
echo "WARNING: $conf_file is writable!" | sed -${E} "s,.*,${SED_RED},g"
fi
cat "$conf_file" 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_RED},g" | sed "s,root,${SED_RED},g" | sed "s,nopass,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed "s,$USER,${SED_RED_YELLOW},g"
fi
done
# Check if doas is working
if [ -n "$doas_bin" ]; then
echo -e "\nTesting doas:" | sed -${E} "s,.*,${SED_LIGHT_CYAN},g"
if $doas_bin -l 2>/dev/null; then
echo "doas -l command works!" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
fi
else
echo_not_found "doas.conf"
fi
echo ""

View File

@ -26,13 +26,13 @@ check_az_vm(){
else
# 3. Try querying the Azure Metadata Service for more wide support (e.g. Azure Container Registry tasks need this)
if command -v curl &> /dev/null; then
if type curl >/dev/null 2>&1; then
meta_response=$(curl -s --max-time 2 \
"http://169.254.169.254/metadata/identity/oauth2/token")
if echo "$meta_response" | grep -q "Missing"; then
is_az_vm="Yes"
fi
elif command -v wget &> /dev/null; then
elif type wget >/dev/null 2>&1; then
meta_response=$(wget -qO- --timeout=2 \
"http://169.254.169.254/metadata/identity/oauth2/token")
if echo "$meta_response" | grep -q "Missing"; then

View File

@ -8,11 +8,25 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pid, $pids
# Fat linpeas: 0
# Small linpeas: 1
check_dns(){
(timeout 20 /bin/bash -c '(( echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 | xxd -p -r >&3; dd bs=9000 count=1 <&3 2>/dev/null | xxd ) 3>/dev/udp/1.1.1.1/53 && echo "DNS available" || echo "DNS not available") 2>/dev/null | grep "available"' ) 2>/dev/null || echo "DNS not available"
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8 ; do
(( echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 | xxd -p -r >&3; dd bs=9000 count=1 <&3 2>/dev/null | xxd ) 3>/dev/udp/$ip/53 && echo "DNS available" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "DNS not available"
' 2>/dev/null | grep "available" || echo "DNS not available"
}

View File

@ -0,0 +1,26 @@
# Title: LinPeasBase - check_external_hostname
# ID: check_external_hostname
# Author: Carlos Polop
# Last Update: 23-05-2025
# Description: This will check the public IP and hostname in known malicious lists and leaks to find any relevant information about the host.
# License: GNU GPL
# Version: 1.0
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables: $$INTERNET_SEARCH_TIMEOUT
# Fat linpeas: 0
# Small linpeas: 1
check_external_hostname(){
INTERNET_SEARCH_TIMEOUT=15
# wget or curl?
if command -v curl >/dev/null 2>&1; then
curl "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" -H "User-Agent: linpeas" -d "{\"hostname\":\"$(hostname)\"}" -H "Content-Type: application/json" --max-time "$INTERNET_SEARCH_TIMEOUT"
elif command -v wget >/dev/null 2>&1; then
wget -q -O - "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" --header "User-Agent: linpeas" --post-data "{\"hostname\":\"$(hostname)\"}" -H "Content-Type: application/json" --timeout "$INTERNET_SEARCH_TIMEOUT"
else
echo "wget or curl not found"
fi
}

View File

@ -1,4 +1,4 @@
# Title: LinPeasBase - check_tcp_443
# Title: LinPeasBase - check_icmp
# ID: check_icmp
# Author: Carlos Polop
# Last Update: 22-08-2023
@ -14,5 +14,5 @@
check_icmp(){
(timeout -s KILL 20 /bin/bash -c '(ping -c 1 1.1.1.1 | grep "1 received" && echo "Ping is available" || echo "Ping is not available") 2>/dev/null | grep "available"') 2>/dev/null || echo "Ping is not available"
(ping -c 1 1.1.1.1 | grep -E "1 received|1 packets received" && echo "Ping is available" || echo "Ping is not available" 2>/dev/null) | grep -i "available"
}

View File

@ -8,11 +8,30 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pid, $pids
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_443(){
(timeout -s KILL 20 /bin/bash -c '(echo >/dev/tcp/1.1.1.1/443 && echo "Port 443 is accessible" || echo "Port 443 is not accessible") 2>/dev/null | grep "accessible"') 2>/dev/null || echo "Port 443 is not accessible"
}
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8; do
(echo >/dev/tcp/$ip/443 && echo "Port 443 is accessible" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "Port 80 is not accessible"
' 2>/dev/null | grep "accessible" || echo "Port 80 is not accessible"
}

View File

@ -0,0 +1,23 @@
# Title: LinPeasBase - check_tcp_443_bin
# ID: check_tcp_443_bin
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Check if TCP Internet conns are available (via port 443) using curl or wget
# License: GNU GPL
# Version: 1.0
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_443_bin(){
if command -v curl >/dev/null 2>&1; then
curl -s "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" -H "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1 && echo "Port 443 is accessible with curl" || echo "Port 443 is not accessible with curl"
elif command -v wget >/dev/null 2>&1; then
wget -q -O - "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/" --header "User-Agent: linpeas" -H "Content-Type: application/json" >/dev/null 2>&1 && echo "Port 443 is accessible with wget" || echo "Port 443 is not accessible with wget"
fi
}

View File

@ -8,11 +8,25 @@
# Functions Used:
# Global Variables:
# Initial Functions:
# Generated Global Variables:
# Generated Global Variables: $pid, $pids
# Fat linpeas: 0
# Small linpeas: 1
check_tcp_80(){
(timeout -s KILL 20 /bin/bash -c '( echo >/dev/tcp/1.1.1.1/80 && echo "Port 80 is accessible" || echo "Port 80 is not accessible") 2>/dev/null | grep "accessible"') 2>/dev/null || echo "Port 80 is not accessible"
if ! [ -f "/bin/bash" ]; then
echo " /bin/bash not found"
return
fi
/bin/bash -c '
for ip in 1.1.1.1 8.8.8.8; do
(echo >/dev/tcp/$ip/80 && echo "Port 80 is accessible" && exit 0) &
pids+=($!)
done
for pid in ${pids[@]}; do
wait $pid && exit 0
done
echo "Port 80 is not accessible"
' 2>/dev/null | grep "accessible"
}

View File

@ -6,9 +6,9 @@
# License: GNU GPL
# Version: 1.0
# Functions Used:
# Global Variables:
# Global Variables: $SED_RED_YELLOW
# Initial Functions:
# Generated Global Variables: $BFUSER, $PASSWORDTRY, $trysu, $SED_RED_YELLOW
# Generated Global Variables: $BFUSER, $PASSWORDTRY, $trysu
# Fat linpeas: 0
# Small linpeas: 1

View File

@ -83,6 +83,7 @@ AUTO_NETWORK_SCAN=""
EXTRA_CHECKS=""
REGEXES=""
PORT_FORWARD=""
NOT_CHECK_EXTERNAL_HOSTNAME=""
THREADS="$( ( (grep -c processor /proc/cpuinfo 2>/dev/null) || ( (command -v lscpu >/dev/null 2>&1) && (lscpu | grep '^CPU(s):' | awk '{print $2}')) || echo -n 2) | tr -d "\n")"
[ -z "$THREADS" ] && THREADS="2" #If THREADS is empty, put number 2
[ -n "$THREADS" ] && THREADS="2" #If THREADS is null, put number 2
@ -96,6 +97,7 @@ ${NC}This tool enum and search possible misconfigurations$DG (known vulns, user,
${YELLOW} -e${BLUE} Perform extra enumeration
${YELLOW} -r${BLUE} Enable Regexes (this can take from some mins to hours)
${YELLOW} -P${BLUE} Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
${YELLOW} -n${BLUE} Do not check hostname & IP in known malicious lists and leaks
${YELLOW} -D${BLUE} Debug mode
${GREEN} Network recon:
@ -128,6 +130,7 @@ while getopts "h?asd:p:i:P:qo:LMwNDterf:F:" opt; do
p) PORTS=$OPTARG;;
i) IP=$OPTARG;;
P) PASSWORD=$OPTARG;;
n) NOT_CHECK_EXTERNAL_HOSTNAME="1";;
q) QUIET=1;;
o) CHECKS=$OPTARG;;
L) MACPEAS="";;

View File

@ -13,4 +13,4 @@
# Small linpeas: 1
processesVB='jdwp|tmux |screen | inspect |--inspect[= ]|--inspect$|--inpect-brk|--remote-debugging-port'
processesVB='jdwp|tmux |screen | inspect |--inspect=|--inspect |--inspect$|--inpect-brk|--remote-debugging-port'

View File

@ -13,4 +13,4 @@
# Small linpeas: 1
timersG="anacron.timer|apt-daily.timer|apt-daily-upgrade.timer|dpkg-db-backup.timer|e2scrub_all.timer|fstrim.timer|fwupd-refresh.timer|geoipupdate.timer|io.netplan.Netplan|logrotate.timer|man-db.timer|mlocate.timer|motd-news.timer|phpsessionclean.timer|plocate-updatedb.timer|snapd.refresh.timer|snapd.snap-repair.timer|systemd-tmpfiles-clean.timer|systemd-readahead-done.timer|ua-license-check.timer|ua-messaging.timer|ua-timer.timer|ureadahead-stop.timer"
timersG="anacron.timer|apt-daily.timer|apt-daily-upgrade.timer|dpkg-db-backup.timer|e2scrub_all.timer|exim4-base.timer|fstrim.timer|fwupd-refresh.timer|geoipupdate.timer|io.netplan.Netplan|logrotate.timer|man-db.timer|mlocate.timer|motd-news.timer|phpsessionclean.timer|plocate-updatedb.timer|snapd.refresh.timer|snapd.snap-repair.timer|systemd-tmpfiles-clean.timer|systemd-readahead-done.timer|ua-license-check.timer|ua-messaging.timer|ua-timer.timer|ureadahead-stop.timer"

View File

@ -21,6 +21,6 @@ if [ "$MACPEAS" ]; then
if grep -q \"$ushell\" /etc/shells; then sh_usrs="$sh_usrs|$uname"; else nosh_usrs="$nosh_usrs|$uname"; fi
done
else
sh_usrs=$(cat /etc/passwd 2>/dev/null | grep -v "^root:" | grep -i "sh$" | cut -d ":" -f 1 | tr '\n' '|' | sed 's/|bin|/|bin[\\\s:]|^bin$|/' | sed 's/|sys|/|sys[\\\s:]|^sys$|/' | sed 's/|daemon|/|daemon[\\\s:]|^daemon$|/')"ImPoSSssSiBlEee" #Modified bin, sys and daemon so they are not colored everywhere
nosh_usrs=$(cat /etc/passwd 2>/dev/null | grep -i -v "sh$" | sort | cut -d ":" -f 1 | tr '\n' '|' | sed 's/|bin|/|bin[\\\s:]|^bin$|/')"ImPoSSssSiBlEee"
sh_usrs=$(cat /etc/passwd 2>/dev/null | grep -v "^root:" | grep -i "sh$" | cut -d ":" -f 1 | tr '\n' '|' | sed 's/|bin|/|bin[[:space:]:]|^bin$|/' | sed 's/|sys|/|sys[[:space:]:]|^sys$|/' | sed 's/|daemon|/|daemon[[:space:]:]|^daemon$|/')"ImPoSSssSiBlEee" #Modified bin, sys and daemon so they are not colored everywhere
nosh_usrs=$(cat /etc/passwd 2>/dev/null | grep -i -v "sh$" | sort | cut -d ":" -f 1 | tr '\n' '|' | sed 's/|bin|/|bin[[:space:]:]|^bin$|/')"ImPoSSssSiBlEee"
fi

View File

@ -411,4 +411,6 @@ class LinpeasBuilder:
with open(path, "w") as f:
f.write(self.linpeas_sh)
print(f"[+] Linpeas written on {path}")

View File

@ -209,11 +209,15 @@ class LinpeasModule:
if self.id != "BS_variables_base":
main_base = LinpeasModule(os.path.join(os.path.dirname(__file__), "..", "linpeas_parts", "linpeas_base", "0_variables_base.sh"))
not_defined_global_vars = []
for var in self.extract_variables(self.sh_code):
if len(var) > 2 and not var in linux_global_vars and var not in self.global_variables and var not in self.generated_global_variables:
if not var.startswith("PSTORAGE_"):
if not main_base or var not in main_base.generated_global_variables:
raise Exception(f"Global Variable '{var}' in module {path} is not defined inside the 'Generated Global Variables' metadata")
not_defined_global_vars.append("$"+var)
if not_defined_global_vars:
raise Exception(f"Global Variables '{', '.join(not_defined_global_vars)}' in module {path} are not defined inside the 'Generated Global Variables' metadata")
def __eq__(self, other):

View File

@ -19,6 +19,7 @@ namespace winPEAS.Checks
{
public static bool IsDomainEnumeration = false;
public static bool IsNoColor = false;
public static bool DontCheckHostname = false;
public static bool Banner = true;
public static bool IsDebug = false;
public static bool IsLinpeas = false;
@ -162,6 +163,11 @@ namespace winPEAS.Checks
IsNoColor = true;
}
if (string.Equals(arg, "dont-check-hostname", StringComparison.CurrentCultureIgnoreCase))
{
DontCheckHostname = true;
}
if (string.Equals(arg, "quiet", StringComparison.CurrentCultureIgnoreCase))
{
Banner = false;

View File

@ -9,6 +9,7 @@ using winPEAS.Helpers.Extensions;
using winPEAS.Info.NetworkInfo;
using winPEAS.Info.NetworkInfo.Enums;
using winPEAS.Info.NetworkInfo.InternetSettings;
using winPEAS.Info.NetworkInfo.NetworkScanner;
namespace winPEAS.Checks
{
@ -26,9 +27,9 @@ namespace winPEAS.Checks
public void PrintInfo(bool isDebug)
{
Beaprint.GreatPrint("Network Information");
new List<Action>
Beaprint.GreatPrint("Network Information");
var baseChecks = new List<Action>
{
PrintNetShares,
PrintMappedDrivesWMI,
@ -38,7 +39,15 @@ namespace winPEAS.Checks
PrintFirewallRules,
PrintDNSCache,
PrintInternetSettings,
}.ForEach(action => CheckRunner.Run(action, isDebug));
PrintInternetConnectivity,
};
// Only create hostnameCheck list if we want to run it
var allChecks = !Checks.DontCheckHostname
? baseChecks.Concat(new List<Action> { () => PrintHostnameResolution().GetAwaiter().GetResult() })
: baseChecks;
allChecks.ForEach(action => CheckRunner.Run(action, isDebug));
}
private void PrintNetShares()
@ -224,9 +233,9 @@ namespace winPEAS.Checks
foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv4, processesByPid))
{
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
}
Beaprint.AnsiPrint(
@ -260,9 +269,9 @@ namespace winPEAS.Checks
foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv6, processesByPid))
{
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
}
Beaprint.AnsiPrint(
@ -389,8 +398,8 @@ namespace winPEAS.Checks
var info = InternetSettings.GetInternetSettingsInfo();
Beaprint.ColorPrint(" General Settings", Beaprint.LBLUE);
Beaprint.NoColorPrint($" {"Hive",-10} {"Key",-40} {"Value"}");
Beaprint.NoColorPrint($" {"Hive",-10} {"Key",-40} {"Value"}");
foreach (var i in info.GeneralSettings)
{
Beaprint.NoColorPrint($" {i.Hive,-10} {i.ValueName,-40} {i.Value}");
@ -410,9 +419,9 @@ namespace winPEAS.Checks
{
Beaprint.NoColorPrint($" {i.Hive,-10} {i.ValueName,-40} {i.Interpretation}");
}
}
Beaprint.ColorPrint("\n Zone Auth Settings", Beaprint.LBLUE);
}
Beaprint.ColorPrint("\n Zone Auth Settings", Beaprint.LBLUE);
if (info.ZoneAuthSettings.Count == 0)
{
Beaprint.NoColorPrint(" No Zone Auth Settings");
@ -423,11 +432,96 @@ namespace winPEAS.Checks
{
Beaprint.NoColorPrint($" {i.Interpretation}");
}
}
}
}
catch (Exception ex)
{
}
}
private void PrintInternetConnectivity()
{
try
{
Beaprint.MainPrint("Internet Connectivity");
Beaprint.LinkPrint("", "Checking if internet access is possible via different methods");
var connectivityInfo = InternetConnectivity.CheckConnectivity();
// HTTP Access
Beaprint.AnsiPrint($" HTTP (80) Access: {(connectivityInfo.HttpAccess ? Beaprint.ansi_color_good + "Yes" + Beaprint.NOCOLOR : Beaprint.ansi_color_bad + "No" + Beaprint.NOCOLOR)}");
if (connectivityInfo.HttpAccess)
{
Beaprint.AnsiPrint($" Successful IP: {connectivityInfo.SuccessfulHttpIp}");
}
else if (!string.IsNullOrEmpty(connectivityInfo.HttpError))
{
Beaprint.AnsiPrint($" Error: {connectivityInfo.HttpError}");
}
// HTTPS Access
Beaprint.AnsiPrint($" HTTPS (443) Access: {(connectivityInfo.HttpsAccess ? Beaprint.ansi_color_good + "Yes" + Beaprint.NOCOLOR : Beaprint.ansi_color_bad + "No" + Beaprint.NOCOLOR)}");
if (connectivityInfo.HttpsAccess)
{
Beaprint.AnsiPrint($" Successful IP: {connectivityInfo.SuccessfulHttpsIp}");
}
else if (!string.IsNullOrEmpty(connectivityInfo.HttpsError))
{
Beaprint.AnsiPrint($" Error: {connectivityInfo.HttpsError}");
}
// DNS Access
Beaprint.AnsiPrint($" DNS (53) Access: {(connectivityInfo.DnsAccess ? Beaprint.ansi_color_good + "Yes" + Beaprint.NOCOLOR : Beaprint.ansi_color_bad + "No" + Beaprint.NOCOLOR)}");
if (connectivityInfo.DnsAccess)
{
Beaprint.AnsiPrint($" Successful IP: {connectivityInfo.SuccessfulDnsIp}");
}
else if (!string.IsNullOrEmpty(connectivityInfo.DnsError))
{
Beaprint.AnsiPrint($" Error: {connectivityInfo.DnsError}");
}
// ICMP Access
Beaprint.AnsiPrint($" ICMP (ping) Access: {(connectivityInfo.IcmpAccess ? Beaprint.ansi_color_good + "Yes" + Beaprint.NOCOLOR : Beaprint.ansi_color_bad + "No" + Beaprint.NOCOLOR)}");
if (connectivityInfo.IcmpAccess)
{
Beaprint.AnsiPrint($" Successful IP: {connectivityInfo.SuccessfulIcmpIp}");
}
else if (!string.IsNullOrEmpty(connectivityInfo.IcmpError))
{
Beaprint.AnsiPrint($" Error: {connectivityInfo.IcmpError}");
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
private async Task PrintHostnameResolution()
{
try
{
Beaprint.MainPrint("Hostname Resolution");
Beaprint.LinkPrint("", "Checking if the hostname can be resolved externally");
var resolutionInfo = await HostnameResolution.CheckResolution();
Beaprint.AnsiPrint($" Hostname: {resolutionInfo.Hostname}");
if (!string.IsNullOrEmpty(resolutionInfo.ExternalCheckResult))
{
Beaprint.AnsiPrint($" External Check Result: {resolutionInfo.ExternalCheckResult}");
}
else if (!string.IsNullOrEmpty(resolutionInfo.Error))
{
Beaprint.AnsiPrint($" {Beaprint.ansi_color_bad}{resolutionInfo.Error}{Beaprint.NOCOLOR}");
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
}
}

View File

@ -142,6 +142,7 @@ namespace winPEAS.Helpers
Console.WriteLine(LCYAN + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR);
Console.WriteLine(LCYAN + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
Console.WriteLine(LCYAN + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
Console.WriteLine(LCYAN + " dont-check-hostname" + GRAY + " Don't check the hostname externally" + NOCOLOR);
Console.WriteLine(LCYAN + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
Console.WriteLine(LCYAN + " max-regex-file-size=1000000" + GRAY + $" Max file size (in Bytes) to search regex in. Default: {Checks.Checks.MaxRegexFileSize}B" + NOCOLOR);

View File

@ -0,0 +1,69 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
using System.Text;
namespace winPEAS.Info.NetworkInfo.NetworkScanner
{
public class HostnameResolutionInfo
{
public string Hostname { get; set; }
public string ExternalCheckResult { get; set; }
public string Error { get; set; }
}
public static class HostnameResolution
{
private const int INTERNET_SEARCH_TIMEOUT = 15;
private static readonly HttpClient httpClient = new HttpClient();
public static async Task<HostnameResolutionInfo> CheckResolution()
{
var result = new HostnameResolutionInfo();
try
{
// Get the current hostname
result.Hostname = Dns.GetHostName();
// Environment.MachineName if hostname empty
if (string.IsNullOrEmpty(result.Hostname))
{
result.Hostname = Environment.MachineName;
}
// Prepare the request
var content = new StringContent(
JsonSerializer.Serialize(new { hostname = result.Hostname }),
Encoding.UTF8,
"application/json"
);
httpClient.DefaultRequestHeaders.Add("User-Agent", "winpeas");
httpClient.Timeout = TimeSpan.FromSeconds(INTERNET_SEARCH_TIMEOUT);
// Make the request to the same endpoint as Linux version
var response = await httpClient.PostAsync(
"https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/",
content
);
if (response.IsSuccessStatusCode)
{
result.ExternalCheckResult = await response.Content.ReadAsStringAsync();
}
else
{
result.ExternalCheckResult = $"External check failed with status code: {response.StatusCode}";
}
}
catch (Exception ex)
{
result.Error = $"Error during hostname check: {ex.Message}";
}
return result;
}
}
}

View File

@ -0,0 +1,257 @@
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
namespace winPEAS.Info.NetworkInfo.NetworkScanner
{
public class InternetConnectivityInfo
{
public bool HttpAccess { get; set; }
public bool HttpsAccess { get; set; }
public bool LambdaAccess { get; set; }
public bool DnsAccess { get; set; }
public bool IcmpAccess { get; set; }
public string HttpError { get; set; }
public string HttpsError { get; set; }
public string LambdaError { get; set; }
public string DnsError { get; set; }
public string IcmpError { get; set; }
public string SuccessfulHttpIp { get; set; }
public string SuccessfulHttpsIp { get; set; }
public string SuccessfulDnsIp { get; set; }
public string SuccessfulIcmpIp { get; set; }
}
public static class InternetConnectivity
{
private const int HTTP_TIMEOUT = 5000; // 5 seconds
private const int ICMP_TIMEOUT = 2000; // 2 seconds
private static readonly string[] TEST_IPS = new[] { "1.1.1.1", "8.8.8.8" }; // Cloudflare DNS, Google DNS
private const string LAMBDA_URL = "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/";
private static bool TryHttpAccess(string ip, out string error)
{
try
{
using (var client = new WebClient())
{
client.Timeout = HTTP_TIMEOUT;
client.DownloadString($"http://{ip}");
error = null;
return true;
}
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private static bool TryHttpsAccess(string ip, out string error)
{
try
{
using (var client = new WebClient())
{
client.Timeout = HTTP_TIMEOUT;
client.DownloadString($"https://{ip}");
error = null;
return true;
}
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private static bool TryLambdaAccess(out string error)
{
try
{
using (var client = new WebClient())
{
client.Timeout = HTTP_TIMEOUT;
client.Headers.Add("User-Agent", "winpeas");
client.Headers.Add("Content-Type", "application/json");
client.DownloadString(LAMBDA_URL);
error = null;
return true;
}
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private static bool TryDnsAccess(string ip, out string error)
{
try
{
using (var udpClient = new UdpClient())
{
// Set a timeout for the connection attempt
udpClient.Client.ReceiveTimeout = HTTP_TIMEOUT;
udpClient.Client.SendTimeout = HTTP_TIMEOUT;
// Create DNS server endpoint
var dnsServer = new IPEndPoint(IPAddress.Parse(ip), 53);
// Create a simple DNS query for google.com (type A record)
byte[] dnsQuery = new byte[] {
0x00, 0x01, // Transaction ID
0x01, 0x00, // Flags (Standard query)
0x00, 0x01, // Questions: 1
0x00, 0x00, // Answer RRs: 0
0x00, 0x00, // Authority RRs: 0
0x00, 0x00, // Additional RRs: 0
// google.com
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x01, // Type: A
0x00, 0x01 // Class: IN
};
// Send the DNS query
udpClient.Send(dnsQuery, dnsQuery.Length, dnsServer);
// Try to receive a response
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] response = udpClient.Receive(ref remoteEP);
// If we got a response, the DNS server is reachable
if (response != null && response.Length > 0)
{
error = null;
return true;
}
error = "No response received from DNS server";
return false;
}
}
catch (SocketException ex)
{
error = $"Socket error: {ex.Message}";
return false;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private static bool TryIcmpAccess(string ip, out string error)
{
try
{
using (var ping = new Ping())
{
var reply = ping.Send(ip, ICMP_TIMEOUT);
if (reply?.Status == IPStatus.Success)
{
error = null;
return true;
}
error = $"Ping failed with status: {reply?.Status}";
return false;
}
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
public static InternetConnectivityInfo CheckConnectivity()
{
var result = new InternetConnectivityInfo();
// Test HTTP (port 80) on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryHttpAccess(ip, out string error))
{
result.HttpAccess = true;
result.SuccessfulHttpIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.HttpAccess = false;
result.HttpError = error;
}
}
// Test HTTPS (port 443) on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryHttpsAccess(ip, out string error))
{
result.HttpsAccess = true;
result.SuccessfulHttpsIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.HttpsAccess = false;
result.HttpsError = error;
}
}
// Test Lambda URL
result.LambdaAccess = TryLambdaAccess(out string lambdaError);
if (!result.LambdaAccess)
{
result.LambdaError = lambdaError;
}
else
{
result.HttpsAccess = true;
}
// Test DNS on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryDnsAccess(ip, out string error))
{
result.DnsAccess = true;
result.SuccessfulDnsIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.DnsAccess = false;
result.DnsError = error;
}
}
// Test ICMP (ping) on each IP until success
foreach (var ip in TEST_IPS)
{
if (TryIcmpAccess(ip, out string error))
{
result.IcmpAccess = true;
result.SuccessfulIcmpIp = ip;
break;
}
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
{
result.IcmpAccess = false;
result.IcmpError = error;
}
}
return result;
}
}
}