cursor rewrite + network checks
This commit is contained in:
parent
604580adbd
commit
1e7a90d29f
@ -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 ""
|
@ -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 ""
|
@ -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"
|
||||
|
@ -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 ""
|
@ -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 ""
|
@ -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 ""
|
@ -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 ""
|
@ -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},"
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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 ""
|
@ -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
|
@ -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
|
@ -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 ""
|
@ -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
|
@ -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 ""
|
@ -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 ""
|
@ -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
|
@ -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
|
@ -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
|
@ -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 ""
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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 ""
|
@ -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
|
@ -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 ""
|
@ -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
|
@ -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
|
@ -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
|
@ -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 ""
|
||||
|
@ -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 ""
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
@ -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 ""
|
@ -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 ""
|
@ -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
|
@ -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
|
@ -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
|
@ -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 ""
|
@ -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
|
||||
|
@ -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 ""
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
@ -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
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
23
linPEAS/builder/linpeas_parts/functions/check_tcp_443_bin.sh
Normal file
23
linPEAS/builder/linpeas_parts/functions/check_tcp_443_bin.sh
Normal 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
|
||||
}
|
@ -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"
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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="";;
|
||||
|
@ -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'
|
@ -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"
|
||||
|
@ -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
|
@ -411,4 +411,6 @@ class LinpeasBuilder:
|
||||
|
||||
with open(path, "w") as f:
|
||||
f.write(self.linpeas_sh)
|
||||
|
||||
print(f"[+] Linpeas written on {path}")
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user