Skip to content

Commit bdcebad

Browse files
author
HackTricks News Bot
committed
Add linpeas privilege escalation checks from: HTB Planning: Grafana CVE-2024-9264 to Container Root, Env-Creds Pivot, Crontab
1 parent 7c7884f commit bdcebad

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

build_lists/sensitive_files.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,3 +3949,24 @@ search:
39493949
type: f
39503950
search_in:
39513951
- common
3952+
3953+
- name: Crontab-UI
3954+
value:
3955+
config:
3956+
auto_check: True
3957+
3958+
files:
3959+
- name: "crontab.db"
3960+
value:
3961+
bad_regex: "-P[[:space:]]+\\S+|--password[[:space:]]+\\S+|[Pp]ass(word)?|[Tt]oken|[Ss]ecret"
3962+
only_bad_lines: True
3963+
type: f
3964+
search_in:
3965+
- common
3966+
3967+
- name: "crontab-ui.service"
3968+
value:
3969+
just_list_file: True
3970+
type: f
3971+
search_in:
3972+
- common
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Title: Processes & Cron & Services & Timers - Crontab UI (root) Misconfiguration
2+
# ID: PR_Crontab_UI_misconfig
3+
# Author: HT Bot
4+
# Last Update: 2025-09-13
5+
# Description: Detect Crontab UI service and risky configurations that can lead to privesc:
6+
# - Root-run Crontab UI exposed on localhost
7+
# - Basic-Auth credentials in systemd Environment= (BASIC_AUTH_USER/PWD)
8+
# - Cron DB path (CRON_DB_PATH) and weak permissions / embedded secrets in jobs
9+
# License: GNU GPL
10+
# Version: 1.0
11+
# Functions Used: print_2title, print_info, print_list, echo_not_found
12+
# Global Variables: $SEARCH_IN_FOLDER, $SED_RED, $SED_RED_YELLOW, $NC
13+
# Initial Functions:
14+
# Generated Global Variables: $svc, $state, $user, $envvals, $port, $dbpath, $dbfile, $candidates, $procs, $perms, $basic_user, $basic_pwd, $uprint, $pprint, $dir, $found
15+
# Fat linpeas: 0
16+
# Small linpeas: 1
17+
18+
if ! [ "$SEARCH_IN_FOLDER" ]; then
19+
print_2title "Crontab UI (root) misconfiguration checks"
20+
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
21+
22+
# Helper: mask secret values (keep first/last 2 chars when length >4)
23+
mask_secret() {
24+
local s="$1"
25+
local l=${#s}
26+
if [ $l -le 4 ]; then
27+
printf "%s" "$s"
28+
else
29+
printf "%s...%s" "${s:0:2}" "${s: -2}"
30+
fi
31+
}
32+
33+
# Collect candidate services referencing crontab-ui
34+
candidates=""
35+
if command -v systemctl >/dev/null 2>&1; then
36+
candidates=$(systemctl list-units --type=service --all 2>/dev/null | awk '{print $1}' | grep -Ei '^crontab-ui\.service$' 2>/dev/null)
37+
fi
38+
39+
# Fallback: grep service files for ExecStart containing crontab-ui
40+
if [ -z "$candidates" ]; then
41+
for dir in /etc/systemd/system /lib/systemd/system; do
42+
[ -d "$dir" ] || continue
43+
found=$(grep -RIl "^Exec(Start|StartPre|StartPost)=.*crontab-ui" "$dir" 2>/dev/null | xargs -r -I{} basename {} 2>/dev/null)
44+
if [ -n "$found" ]; then
45+
candidates=$(printf "%s\n%s" "$candidates" "$found" | sort -u)
46+
fi
47+
done
48+
fi
49+
50+
# Also flag if the binary exists or a process seems to be running
51+
if command -v crontab-ui >/dev/null 2>&1; then
52+
print_list "crontab-ui binary found at: $(command -v crontab-ui)"$NC
53+
else
54+
echo_not_found "crontab-ui"
55+
fi
56+
57+
procs=$(ps aux 2>/dev/null | grep -E "(crontab-ui|node .*crontab-ui)" | grep -v grep)
58+
if [ -n "$procs" ]; then
59+
print_list "Processes matching crontab-ui? ..................... "$NC
60+
printf "%s\n" "$procs"
61+
echo ""
62+
fi
63+
64+
# If no candidates detected, exit quietly
65+
if [ -z "$candidates" ]; then
66+
exit 0
67+
fi
68+
69+
# Iterate candidates and extract interesting data
70+
printf "%s\n" "$candidates" | while read -r svc; do
71+
[ -n "$svc" ] || continue
72+
# Ensure suffix .service if missing
73+
case "$svc" in
74+
*.service) : ;;
75+
*) svc="$svc.service" ;;
76+
esac
77+
78+
state=""
79+
user=""
80+
if command -v systemctl >/dev/null 2>&1; then
81+
state=$(systemctl is-active "$svc" 2>/dev/null)
82+
user=$(systemctl show "$svc" -p User 2>/dev/null | cut -d= -f2)
83+
fi
84+
85+
[ -z "$state" ] && state="unknown"
86+
[ -z "$user" ] && user="unknown"
87+
88+
echo "Service: $svc (state: $state, User: $user)" | sed -${E} "s,root,${SED_RED},g"
89+
90+
# Read Environment from systemd (works even if file unreadable in many setups)
91+
envvals=$(systemctl show "$svc" -p Environment 2>/dev/null | cut -d= -f2-)
92+
if [ -n "$envvals" ]; then
93+
basic_user=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^BASIC_AUTH_USER=' | head -n1 | cut -d= -f2-)
94+
basic_pwd=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^BASIC_AUTH_PWD=' | head -n1 | cut -d= -f2-)
95+
dbpath=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^CRON_DB_PATH=' | head -n1 | cut -d= -f2-)
96+
port=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^PORT=' | head -n1 | cut -d= -f2-)
97+
98+
if [ -n "$basic_user" ] || [ -n "$basic_pwd" ]; then
99+
uprint="$basic_user"
100+
pprint="$basic_pwd"
101+
[ -n "$basic_pwd" ] && pprint=$(mask_secret "$basic_pwd")
102+
echo " └─ Basic-Auth credentials in Environment: user='${uprint}' pwd='${pprint}'" | sed -${E} "s,pwd='[^']*',${SED_RED_YELLOW},g"
103+
fi
104+
105+
if [ -n "$dbpath" ]; then
106+
echo " └─ CRON_DB_PATH: $dbpath"
107+
fi
108+
109+
# Check listener bound to localhost
110+
[ -z "$port" ] && port=8000
111+
if command -v ss >/dev/null 2>&1; then
112+
if ss -ltn 2>/dev/null | grep -qE "127\.0\.0\.1:${port}[[:space:]]"; then
113+
echo " └─ Listener detected on 127.0.0.1:${port} (likely Crontab UI)."
114+
fi
115+
else
116+
if netstat -tnl 2>/dev/null | grep -qE "127\.0\.0\.1:${port}[[:space:]]"; then
117+
echo " └─ Listener detected on 127.0.0.1:${port} (likely Crontab UI)."
118+
fi
119+
fi
120+
121+
# If we know DB path, try to read crontab.db for obvious secrets and check perms
122+
if [ -n "$dbpath" ] && [ -d "$dbpath" ] && [ -r "$dbpath" ]; then
123+
dbfile="$dbpath/crontab.db"
124+
if [ -f "$dbfile" ]; then
125+
perms=$(ls -ld "$dbpath" 2>/dev/null | awk '{print $1, $3, $4}')
126+
echo " └─ DB dir perms: $perms"
127+
if [ -w "$dbpath" ] || [ -w "$dbfile" ]; then
128+
echo " └─ Writable by current user -> potential job injection!" | sed -${E} "s,.*,${SED_RED},g"
129+
fi
130+
echo " └─ Inspecting $dbfile for embedded secrets in commands (zip -P / --password / pass/token/secret)..."
131+
grep -E "-P[[:space:]]+\S+|--password[[:space:]]+\S+|[Pp]ass(word)?|[Tt]oken|[Ss]ecret" "$dbfile" 2>/dev/null | head -n 20 | sed -${E} "s,(${SED_RED_YELLOW}),\1,g"
132+
fi
133+
fi
134+
fi
135+
echo ""
136+
done
137+
fi
138+

0 commit comments

Comments
 (0)