-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathweaken-kernel-hardening
More file actions
executable file
·120 lines (109 loc) · 5 KB
/
Copy pathweaken-kernel-hardening
File metadata and controls
executable file
·120 lines (109 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/bin/sh
# This file is part of KASLD - https://github.com/bcoles/kasld
#
# Temporarily weaken kernel hardening settings for KASLD testing.
# Saves current values and restores them on exit (or SIGINT/SIGTERM/SIGHUP).
#
# The settings are system-wide: every process on the host runs unrestricted for
# as long as this script holds them down, not just KASLD.
#
# This script is intended for testing on systems you control.
# DO NOT run this on production systems.
#
# Settings modified:
# - kernel.dmesg_restrict -> 0 (allow unprivileged dmesg access)
# - kernel.kptr_restrict -> 0 (expose kernel pointers in /proc/kallsyms etc)
# - kernel.perf_event_paranoid -> 0 (allow unprivileged perf_event_open)
# - kernel.unprivileged_bpf_disabled -> 0 (allow unprivileged bpf())
#
# Note: kernel.unprivileged_bpf_disabled has three states: 0 (allowed), 1
# (disabled and LOCKED until reboot), and 2 (disabled but re-enablable). Writing
# 0 works from state 0 or 2 (state 2 is the common CONFIG_BPF_UNPRIV_DEFAULT_OFF
# default) and re-enables the unprivileged bpf() components. Only the locked
# state 1 refuses the write (EPERM). This script attempts it and reports if the
# kernel rejected it.
#
# Requires: root privileges
#
# References:
# https://www.kernel.org/doc/Documentation/sysctl/kernel.txt
# https://sysctl-explorer.net/kernel/kptr_restrict/
# https://sysctl-explorer.net/kernel/dmesg_restrict/
# https://sysctl-explorer.net/kernel/perf_event_paranoid/
# https://sysctl-explorer.net/kernel/unprivileged_bpf_disabled/
# ---
# <bcoles@gmail.com>
set -e
if [ "$(id -u)" -ne 0 ]; then
echo "[-] This script requires root privileges." >&2
exit 1
fi
echo "========================================"
echo " WARNING: Weakening kernel hardening"
echo "========================================"
echo
echo "This script temporarily weakens kernel hardening settings"
echo "to allow KASLD components to function without restrictions."
echo
echo "Settings will be restored on exit (Ctrl+C or script completion)."
echo
# Save current values
saved_dmesg=$(sysctl -n kernel.dmesg_restrict 2>/dev/null) || saved_dmesg=""
saved_kptr=$(sysctl -n kernel.kptr_restrict 2>/dev/null) || saved_kptr=""
saved_perf=$(sysctl -n kernel.perf_event_paranoid 2>/dev/null) || saved_perf=""
saved_bpf=$(sysctl -n kernel.unprivileged_bpf_disabled 2>/dev/null) || saved_bpf=""
restore() {
# Disarm first: the EXIT trap would otherwise fire again on the exit below and
# restore a second time.
trap - INT TERM HUP EXIT
echo
echo "[*] Restoring kernel settings ..."
[ -n "$saved_dmesg" ] && sysctl -q kernel.dmesg_restrict="$saved_dmesg"
[ -n "$saved_kptr" ] && sysctl -q kernel.kptr_restrict="$saved_kptr"
[ -n "$saved_perf" ] && sysctl -q kernel.perf_event_paranoid="$saved_perf"
# Restoring the original (equal or more restrictive) value is always allowed.
if [ -n "$saved_bpf" ]; then
sysctl -q kernel.unprivileged_bpf_disabled="$saved_bpf" 2>/dev/null || true
fi
echo "[+] Restored."
exit 0
}
trap restore INT TERM HUP EXIT
echo "[*] Current settings:"
[ -n "$saved_dmesg" ] && echo " kernel.dmesg_restrict = $saved_dmesg"
[ -n "$saved_kptr" ] && echo " kernel.kptr_restrict = $saved_kptr"
[ -n "$saved_perf" ] && echo " kernel.perf_event_paranoid = $saved_perf"
[ -n "$saved_bpf" ] && echo " kernel.unprivileged_bpf_disabled = $saved_bpf"
echo
echo "[*] Applying weakened settings ..."
[ -n "$saved_dmesg" ] && sysctl -q kernel.dmesg_restrict=0
[ -n "$saved_kptr" ] && sysctl -q kernel.kptr_restrict=0
[ -n "$saved_perf" ] && sysctl -q kernel.perf_event_paranoid=0
# Writing 0 succeeds from state 2 (re-enables unprivileged bpf); only the locked
# state 1 rejects it. Attempt it, but do not abort the other (successful)
# relaxations if the kernel says no.
if [ -n "$saved_bpf" ] && [ "$saved_bpf" != "0" ]; then
if ! sysctl -q kernel.unprivileged_bpf_disabled=0 2>/dev/null; then
echo " [!] kernel.unprivileged_bpf_disabled is locked (state 1); cannot"
echo " re-enable unprivileged bpf() until reboot."
fi
fi
echo
echo "[*] New settings:"
[ -n "$saved_dmesg" ] && echo " kernel.dmesg_restrict = $(sysctl -n kernel.dmesg_restrict)"
[ -n "$saved_kptr" ] && echo " kernel.kptr_restrict = $(sysctl -n kernel.kptr_restrict)"
[ -n "$saved_perf" ] && echo " kernel.perf_event_paranoid = $(sysctl -n kernel.perf_event_paranoid)"
[ -n "$saved_bpf" ] && echo " kernel.unprivileged_bpf_disabled = $(sysctl -n kernel.unprivileged_bpf_disabled)"
echo
echo "[*] Hardening weakened. Run KASLD in another terminal."
echo "[*] Press Ctrl+C to restore settings and exit."
echo
# Wait until interrupted. The sleep runs in the background with the shell
# blocked in `wait`, because a shell defers a trapped signal until the current
# foreground command finishes: behind a day-long foreground sleep, a signal that
# does not also reach the sleep would leave the settings weakened for the rest
# of the day. `wait` is interrupted by the signal, so restore() runs at once.
while true; do
sleep 86400 &
wait "$!" || true
done