diff --git a/.gitignore b/.gitignore index 8d12fbb76..9e7a262f7 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ Temporary Items book book/* hacktricks-preprocessor.log +hacktricks-preprocessor-error.log diff --git a/hacktricks-preprocessor.py b/hacktricks-preprocessor.py index 0077da80f..af5949449 100644 --- a/hacktricks-preprocessor.py +++ b/hacktricks-preprocessor.py @@ -7,7 +7,14 @@ from os import path from urllib.request import urlopen, Request logger = logging.getLogger(__name__) -logging.basicConfig(filename='hacktricks-preprocessor.log', filemode='w', encoding='utf-8', level=logging.DEBUG) +logger.setLevel(logging.DEBUG) +handler = logging.FileHandler(filename='hacktricks-preprocessor.log', mode='w', encoding='utf-8') +handler.setLevel(logging.DEBUG) +logger.addHandler(handler) + +handler2 = logging.FileHandler(filename='hacktricks-preprocessor-error.log', mode='w', encoding='utf-8') +handler2.setLevel(logging.ERROR) +logger.addHandler(handler2) def findtitle(search ,obj, key, path=(),): @@ -45,19 +52,29 @@ def ref(matchobj): try: if href.endswith("/"): href = href+"README.md" # Fix if ref points to a folder - chapter, _path = findtitle(href, book, "source_path") - logger.debug(f'Recursive title search result: {chapter["name"]}') - title = chapter['name'] + if "#" in href: + chapter, _path = findtitle(href.split("#")[0], book, "source_path") + title = " ".join(href.split("#")[1].split("-")).title() + logger.debug(f'Ref has # using title: {title}') + else: + chapter, _path = findtitle(href, book, "source_path") + logger.debug(f'Recursive title search result: {chapter["name"]}') + title = chapter['name'] except Exception as e: try: dir = path.dirname(current_chapter['source_path']) logger.debug(f'Error getting chapter title: {href} trying with relative path {path.normpath(path.join(dir,href))}') - chapter, _path = findtitle(path.normpath(path.join(dir,href)), book, "source_path") - logger.debug(f'Recursive title search result: {chapter["name"]}') - title = chapter['name'] + if "#" in href: + chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path") + title = " ".join(href.split("#")[1].split("-")).title() + logger.debug(f'Ref has # using title: {title}') + else: + chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path") + title = chapter["name"] + logger.debug(f'Recursive title search result: {chapter["name"]}') except Exception as e: - logger.debug(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') - print(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') + logger.debug(e) + logger.error(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') sys.exit(1) @@ -85,13 +102,11 @@ def files(matchobj): except Exception as e: logger.debug(e) - logger.debug(f'Error searching file: {href}') - print(f'Error searching file: {href}') + logger.error(f'Error searching file: {href}') sys.exit(1) if title=="": - logger.debug(f'Error searching file: {href}') - print(f'Error searching file: {href}') + logger.error(f'Error searching file: {href}') sys.exit(1) template = f"""{title}""" @@ -134,10 +149,11 @@ if __name__ == '__main__': for chapter in iterate_chapters(book['sections']): logger.debug(f"Chapter: {chapter['path']}") current_chapter = chapter - regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}' + # regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}' + regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n#]*(?:#(.*))?)(?:\n)?{{[\s]*#endref[\s]*}}' new_content = re.sub(regex, ref, chapter['content']) regex = r'{{[\s]*#file[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endfile[\s]*}}' - new_content = re.sub(regex, files, chapter['content']) + new_content = re.sub(regex, files, new_content) new_content = add_read_time(new_content) chapter['content'] = new_content diff --git a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md index 1ecef7949..94266b32d 100644 --- a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md +++ b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md @@ -34,7 +34,7 @@ ] } ``` -그리고 하이재킹은 **템플릿이 버킷에 업로드되는 순간부터** **템플릿이 배포되는 순간까지의 작은 시간 창** 때문에 가능합니다. 공격자는 자신의 계정에 **lambda function**을 생성하여 **버킷 알림이 전송될 때 트리거**되도록 하고, **버킷**의 **내용**을 **하이재킹**할 수 있습니다. +그리고 하이재킹이 가능한 이유는 **템플릿이 버킷에 업로드되는 순간부터** **템플릿이 배포되는 순간까지의 작은 시간 창**이 있기 때문입니다. 공격자는 자신의 계정에 **lambda function**을 생성하여 **버킷 알림이 전송될 때 트리거**되도록 할 수 있으며, **버킷**의 **내용**을 **하이재킹**할 수 있습니다. ![](<../../../images/image (174).png>) @@ -54,17 +54,17 @@ Pacu 모듈 [`cfn__resouce_injection`](https://github.com/RhinoSecurityLabs/pacu [terraform](https://cloud.hacktricks.wiki/en/pentesting-ci-cd/terraform-security.html) 상태 파일이 클라우드 제공자의 블롭 스토리지에 저장되는 것은 매우 일반적입니다. 예를 들어 AWS S3. 상태 파일의 파일 접미사는 `.tfstate`이며, 버킷 이름은 종종 terraform 상태 파일을 포함하고 있음을 나타냅니다. 일반적으로 모든 AWS 계정에는 상태 파일을 저장하는 하나의 버킷이 있습니다. 이 상태 파일은 계정의 상태를 보여줍니다. 또한 실제 계정에서는 거의 모든 개발자가 `s3:*` 권한을 가지고 있으며, 때로는 비즈니스 사용자도 `s3:Put*` 권한을 가집니다. -따라서 이러한 파일에 대해 나열된 권한이 있는 경우, `terraform`의 권한으로 파이프라인에서 RCE를 얻을 수 있는 공격 벡터가 있습니다. 대부분의 경우 `AdministratorAccess`가 되어 클라우드 계정의 관리자가 됩니다. 또한 이 벡터를 사용하여 `terraform`이 합법적인 리소스를 삭제하도록 하여 서비스 거부 공격을 수행할 수 있습니다. +따라서 이러한 파일에 대해 나열된 권한이 있는 경우, `terraform`의 권한으로 파이프라인에서 RCE를 얻을 수 있는 공격 벡터가 있습니다. 대부분의 경우 `AdministratorAccess`로 클라우드 계정의 관리자가 됩니다. 또한 이 벡터를 사용하여 `terraform`이 합법적인 리소스를 삭제하도록 하여 서비스 거부 공격을 수행할 수 있습니다. -직접 사용할 수 있는 익스플로잇 코드는 *Terraform Security* 페이지의 *Abusing Terraform State Files* 섹션의 설명을 따르세요: +*Terraform Security* 페이지의 *Abusing Terraform State Files* 섹션에 있는 설명을 따라 직접 사용할 수 있는 익스플로잇 코드를 확인하세요: {{#ref}} -terraform-security.md#abusing-terraform-state-files +pentesting-ci-cd/terraform-security.md#abusing-terraform-state-files {{#endref}} ### `s3:PutBucketPolicy` -공격자는 **같은 계정에서** 있어야 하며, 그렇지 않으면 `The specified method is not allowed` 오류가 발생합니다. 이 권한을 가진 공격자는 자신에게 버킷에 대한 더 많은 권한을 부여하여 읽기, 쓰기, 수정, 삭제 및 버킷을 노출할 수 있습니다. +공격자는 **같은 계정에서** 있어야 하며, 그렇지 않으면 `The specified method is not allowed` 오류가 발생합니다. 이 권한을 가진 공격자는 자신에게 더 많은 권한을 부여하여 버킷에 대한 읽기, 쓰기, 수정, 삭제 및 노출을 허용할 수 있습니다. ```bash # Update Bucket policy aws s3api put-bucket-policy --policy file:///root/policy.json --bucket diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md index 47acda317..68ef6a895 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md @@ -7,7 +7,7 @@ Azure App 서비스에 대한 자세한 정보는 다음을 확인하세요: {{#ref}} -../az-services/az-app-service.md +../az-services/az-app-services.md {{#endref}} ### Microsoft.Web/sites/publish/Action, Microsoft.Web/sites/basicPublishingCredentialsPolicies/read, Microsoft.Web/sites/config/read, Microsoft.Web/sites/read @@ -35,9 +35,9 @@ ssh root@127.0.0.1 -p 39895 - **애플리케이션 디버깅**: 1. VScode에 Azure 확장을 설치합니다. 2. Azure 계정으로 확장에 로그인합니다. -3. 구독 내 모든 앱 서비스를 나열합니다. -4. 디버깅할 앱 서비스를 선택하고 마우스 오른쪽 버튼을 클릭한 후 "디버깅 시작"을 선택합니다. -5. 앱에 디버깅이 활성화되어 있지 않으면, 확장이 이를 활성화하려고 시도하지만, 귀하의 계정은 이를 수행하기 위해 `Microsoft.Web/sites/config/write` 권한이 필요합니다. +3. 구독 내 모든 App 서비스를 나열합니다. +4. 디버깅할 App 서비스를 선택하고, 마우스 오른쪽 버튼을 클릭한 후 "디버깅 시작"을 선택합니다. +5. 앱에 디버깅이 활성화되어 있지 않으면, 확장이 이를 활성화하려고 시도하지만, 귀하의 계정은 `Microsoft.Web/sites/config/write` 권한이 필요합니다. ### SCM 자격 증명 얻기 및 기본 인증 활성화 @@ -94,11 +94,11 @@ az webapp deployment list-publishing-profiles --name --resource-group } ] ``` -사용자 이름은 항상 동일하다는 점에 유의하세요(FTP에서는 앱 이름이 앞에 추가됨). 그러나 모든 경우에 대해 비밀번호는 동일합니다. +**사용자 이름은 항상 동일합니다** (FTP에서는 앱 이름이 앞에 추가됨) 하지만 **비밀번호는 모두 동일합니다**. -또한, SCM URL은 `.scm.azurewebsites.net`입니다. +또한, **SCM URL은 `.scm.azurewebsites.net`**입니다. -- 권한 **`Microsoft.Web/sites/config/list/action`**은 다음을 호출할 수 있습니다: +- 권한 **`Microsoft.Web/sites/config/list/action`**은 호출할 수 있습니다: ```bash az webapp deployment list-publishing-credentials --name --resource-group # Example output @@ -131,8 +131,7 @@ az webapp deployment user set \ > [!WARNING] > 모든 사용자가 이전 명령을 호출하여 자신의 자격 증명을 구성할 수 있지만, 사용자가 SCM 또는 FTP에 액세스할 수 있는 충분한 권한이 없으면 자격 증명이 작동하지 않습니다. - -- 이러한 자격 증명이 **REDACTED**로 표시되면, 이는 **SCM 기본 인증 옵션을 활성화해야 하기 때문이며**, 이를 위해 두 번째 권한(`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write`)이 필요합니다: +- 자격 증명이 **REDACTED**로 표시되면, 이는 **SCM 기본 인증 옵션을 활성화해야 하기 때문이며**, 이를 위해 두 번째 권한(`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write`)이 필요합니다: ```bash # Enable basic authentication for SCM az rest --method PUT \ @@ -206,7 +205,7 @@ curl -X PUT \ ``` ### Microsoft.Web/sites/write, Microsoft.Web/sites/read, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action -이 권한은 **관리되는 ID**를 App 서비스에 할당할 수 있게 하므로, 이전에 App 서비스가 손상된 경우 공격자가 App 서비스에 새로운 관리되는 ID를 할당하고 **권한을 상승**시킬 수 있습니다. +이 권한은 **관리형 ID**를 App 서비스에 할당할 수 있게 하므로, 이전에 App 서비스가 침해된 경우 공격자가 App 서비스에 새로운 관리형 ID를 할당하고 **권한을 상승**시킬 수 있습니다. ```bash az webapp identity assign --name --resource-group --identities /subscriptions//resourceGroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/ ``` @@ -226,7 +225,7 @@ az rest --method GET \ ``` 이 명령은 Github, Bitbucket, Dropbox 및 OneDrive에 대한 토큰을 반환합니다. -여기 토큰을 확인하기 위한 몇 가지 명령 예가 있습니다: +여기 토큰을 확인하기 위한 몇 가지 명령 예제가 있습니다: ```bash # GitHub – List Repositories curl -H "Authorization: token " \ @@ -249,29 +248,29 @@ curl -H "Authorization: Bearer " \ -H "Accept: application/json" \ https://graph.microsoft.com/v1.0/me/drive/root/children ``` -### Update App Code from the source +### 소스에서 앱 코드 업데이트 -- If the configured source is a third-party provider like Github, BitBucket or an Azure Repository, you can **update the code** of the App service by compromising the source code in the repository. -- If the app is configured using a **remote git repository** (with username and password), it's possible to get the **URL and basic auth credentials** to clone and push changes with: -- Using the permission **`Microsoft.Web/sites/sourcecontrols/read`**: `az webapp deployment source show --name --resource-group ` -- Using the permission **`Microsoft.Web/sites/config/list/action`**: +- 구성된 소스가 Github, BitBucket 또는 Azure Repository와 같은 제3자 제공자인 경우, 리포지토리의 소스 코드를 손상시켜 **앱 서비스의 코드를 업데이트**할 수 있습니다. +- 앱이 **원격 git 리포지토리**(사용자 이름 및 비밀번호 포함)를 사용하도록 구성된 경우, 다음을 통해 **URL 및 기본 인증 자격 증명**을 얻어 클론하고 변경 사항을 푸시할 수 있습니다: +- 권한 **`Microsoft.Web/sites/sourcecontrols/read`** 사용: `az webapp deployment source show --name --resource-group ` +- 권한 **`Microsoft.Web/sites/config/list/action`** 사용: - `az webapp deployment list-publishing-credentials --name --resource-group ` - `az rest --method POST --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/sites//config/metadata/list?api-version=2022-03-01" --resource "https://management.azure.com"` -- If the app is configured to use a **local git repository**, it's possible to **clone the repository** and **push changes** to it: -- Using the permission **`Microsoft.Web/sites/sourcecontrols/read`**: You can get the URL of the git repo with `az webapp deployment source show --name --resource-group `, but it's going to be the same as the the SCM URL of the app with the path `/.git` (e.g. `https://pythonwebapp-audeh9f5fzeyhhed.scm.canadacentral-01.azurewebsites.net:443/pythonwebapp.git`). -- To get the SCM credential you need the permission: -- **`Microsoft.Web/sites/publishxml/action`**: Then run `az webapp deployment list-publishing-profiles --resource-group -n `. -- **`Microsoft.Web/sites/config/list/action`**: Then run `az webapp deployment list-publishing-credentials --name --resource-group ` +- 앱이 **로컬 git 리포지토리**를 사용하도록 구성된 경우, **리포지토리를 클론하고 변경 사항을 푸시**할 수 있습니다: +- 권한 **`Microsoft.Web/sites/sourcecontrols/read`** 사용: `az webapp deployment source show --name --resource-group `로 git 리포지토리의 URL을 얻을 수 있지만, 이는 앱의 SCM URL과 동일하며 경로는 `/.git`입니다 (예: `https://pythonwebapp-audeh9f5fzeyhhed.scm.canadacentral-01.azurewebsites.net:443/pythonwebapp.git`). +- SCM 자격 증명을 얻으려면 다음 권한이 필요합니다: +- **`Microsoft.Web/sites/publishxml/action`**: 그런 다음 `az webapp deployment list-publishing-profiles --resource-group -n `을 실행합니다. +- **`Microsoft.Web/sites/config/list/action`**: 그런 다음 `az webapp deployment list-publishing-credentials --name --resource-group `을 실행합니다. > [!WARNING] -> Note that having the permission `Microsoft.Web/sites/config/list/action` and the SCM credentials it's always possible to deploy into a webapp (even if it was configured to use a third-party provider) as mentioned in a previous section. +> 권한 `Microsoft.Web/sites/config/list/action`과 SCM 자격 증명을 보유하면, 이전 섹션에서 언급한 바와 같이 웹앱에 배포하는 것이 항상 가능합니다 (제3자 제공자를 사용하도록 구성된 경우에도). > [!WARNING] -> Note that having the permissions below it's also **possible to execute an arbitrary container** even if the webapp was configured differently. +> 아래 권한을 보유하면 웹앱이 다르게 구성되었더라도 **임의의 컨테이너를 실행하는 것도 가능합니다**. ### `Microsoft.Web/sites/config/Write`, `Microsoft.Web/sites/config/Read`, `Microsoft.Web/sites/config/list/Action`, `Microsoft.Web/sites/Read` -이것은 웹앱에서 사용되는 **컨테이너를 수정할 수 있는** 권한 세트입니다. 공격자는 이를 악용하여 웹앱이 악성 컨테이너를 실행하도록 만들 수 있습니다. +이 권한 세트는 웹앱에서 사용되는 **컨테이너를 수정**할 수 있게 해줍니다. 공격자는 이를 악용하여 웹앱이 악성 컨테이너를 실행하도록 만들 수 있습니다. ```bash az webapp config container set \ --name \ diff --git a/src/pentesting-cloud/azure-security/az-services/az-function-apps.md b/src/pentesting-cloud/azure-security/az-services/az-function-apps.md index 68cd49db6..4ddccde1c 100644 --- a/src/pentesting-cloud/azure-security/az-services/az-function-apps.md +++ b/src/pentesting-cloud/azure-security/az-services/az-function-apps.md @@ -2,79 +2,79 @@ {{#include ../../../banners/hacktricks-training.md}} -## 기본 정보 +## Basic Information **Azure Function Apps**는 **서버리스 컴퓨트 서비스**로, 기본 인프라를 관리하지 않고도 **함수**라고 불리는 작은 코드 조각을 실행할 수 있게 해줍니다. 이들은 **HTTP 요청, 타이머 또는 Blob Storage나 Event Hubs와 같은 다른 Azure 서비스의 이벤트**와 같은 다양한 트리거에 응답하여 코드를 실행하도록 설계되었습니다. Function Apps는 C#, Python, JavaScript, Java 등 여러 프로그래밍 언어를 지원하여 **이벤트 기반 애플리케이션**, 워크플로 자동화 또는 서비스 통합을 구축하는 데 유용합니다. 일반적으로 코드가 실행될 때 사용된 컴퓨트 시간에 대해서만 비용을 지불하므로 비용 효율적입니다. > [!NOTE] > **Functions는 App Services의 하위 집합**이므로, 여기서 논의된 많은 기능은 Azure Apps(`webapp` in cli)로 생성된 애플리케이션에서도 사용됩니다. -### 다양한 요금제 +### Different Plans - **Flex Consumption Plan**: 수요에 따라 함수 인스턴스를 추가하거나 제거하는 **동적 이벤트 기반 스케일링**을 제공하며, 사용한 만큼만 지불하는 요금제를 제공합니다. **가상 네트워킹** 및 **사전 프로비저닝된 인스턴스**를 지원하여 콜드 스타트를 줄여주며, 컨테이너 지원이 필요하지 않은 **변동 작업 부하**에 적합합니다. - **Traditional Consumption Plan**: 기본 서버리스 옵션으로, **함수가 실행될 때만 컴퓨트 리소스에 대해 지불**합니다. 수신 이벤트에 따라 자동으로 스케일링되며 **콜드 스타트 최적화**가 포함되어 있지만, 컨테이너 배포는 지원하지 않습니다. 자동 스케일링이 필요한 **간헐적 작업 부하**에 이상적입니다. - **Premium Plan**: **일관된 성능**을 위해 설계되었으며, 콜드 스타트를 없애기 위해 **사전 예열된 작업자**를 제공합니다. **연장된 실행 시간, 가상 네트워킹**을 제공하며, **사용자 정의 Linux 이미지**를 지원하여 높은 성능과 고급 기능이 필요한 **미션 크리티컬 애플리케이션**에 적합합니다. -- **Dedicated Plan**: 예측 가능한 청구가 가능한 전용 가상 머신에서 실행되며, 수동 또는 자동 스케일링을 지원합니다. 동일한 요금제에서 여러 앱을 실행할 수 있으며, **컴퓨트 격리**를 제공하고 App Service Environments를 통해 **안전한 네트워크 액세스**를 보장하여 일관된 리소스 할당이 필요한 **장기 실행 애플리케이션**에 이상적입니다. +- **Dedicated Plan**: 예측 가능한 청구가 가능한 전용 가상 머신에서 실행되며, 수동 또는 자동 스케일링을 지원합니다. 동일한 계획에서 여러 앱을 실행할 수 있으며, **컴퓨트 격리**를 제공하고 App Service Environments를 통해 **안전한 네트워크 액세스**를 보장하여 일관된 리소스 할당이 필요한 **장기 실행 애플리케이션**에 이상적입니다. - **Container Apps**: 관리되는 환경에서 **컨테이너화된 함수 앱**을 배포할 수 있으며, 마이크로서비스 및 API와 함께 사용할 수 있습니다. 사용자 정의 라이브러리, 레거시 앱 마이그레이션 및 **GPU 처리**를 지원하여 Kubernetes 클러스터 관리를 없애줍니다. **이벤트 기반, 확장 가능한 컨테이너화된 애플리케이션**에 적합합니다. -### **스토리지 버킷** +### **Storage Buckets** -컨테이너화되지 않은 새로운 Function App을 생성할 때, **코드 및 기타 Function 관련 데이터는 스토리지 계정에 저장됩니다**. 기본적으로 웹 콘솔은 코드를 저장하기 위해 함수당 새 스토리지 계정을 생성합니다. +컨테이너화되지 않은 새로운 Function App을 생성할 때 (코드를 실행할 수 있도록 제공하는 경우), **코드 및 기타 Function 관련 데이터는 Storage 계정에 저장됩니다**. 기본적으로 웹 콘솔은 코드를 저장하기 위해 함수당 새 Storage 계정을 생성합니다. -또한, 버킷 내의 코드를 수정하면 (저장될 수 있는 다양한 형식에서) **앱의 코드가 새 코드로 수정되어 다음에 함수가 호출될 때 실행됩니다**. +또한, 버킷 내의 코드를 수정하면 (저장될 수 있는 다양한 형식에서), **앱의 코드는 새로운 코드로 수정되어 다음에 함수가 호출될 때 실행됩니다**. > [!CAUTION] -> 공격자의 관점에서 매우 흥미로운 점은 **이 버킷에 대한 쓰기 권한**이 공격자가 **코드를 손상시키고 Function App 내의 관리되는 ID에 대한 권한을 상승시킬 수 있게 해준다는 것입니다.** +> 공격자의 관점에서 매우 흥미로운 점은 **이 버킷에 대한 쓰기 권한**이 있으면 공격자가 **코드를 손상시키고 Function App 내의 관리되는 ID에 대한 권한을 상승시킬 수 있다는 점입니다**. > -> 이에 대한 자세한 내용은 **권한 상승 섹션**에서 다룹니다. +> 이에 대한 자세한 내용은 **권한 상승 섹션**에서 확인할 수 있습니다. -또한, **`azure-webjobs-secrets`** 컨테이너 내의 스토리지 계정에서 **마스터 및 함수 키**를 찾는 것도 가능합니다. 이 키는 **``** 폴더 내의 JSON 파일에서 찾을 수 있습니다. +또한, **`azure-webjobs-secrets`** 컨테이너 내의 Storage 계정에서 **마스터 및 함수 키**를 찾는 것도 가능합니다. 이 키는 **``** 폴더 내의 JSON 파일에서 찾을 수 있습니다. Functions는 또한 코드를 원격 위치에 저장할 수 있으며, 그 URL을 지정하기만 하면 됩니다. -### 네트워킹 +### Networking -HTTP 트리거를 사용하여: +HTTP 트리거를 사용할 때: - **인터넷의 모든 사용자에게 함수에 대한 액세스를 제공**하거나 IAM 기반으로 액세스를 제공할 수 있습니다. 이 액세스를 제한하는 것도 가능합니다. - **내부 네트워크(VPC)**에서 Function App에 대한 액세스를 **제공하거나 제한**할 수 있습니다. > [!CAUTION] -> 공격자의 관점에서 매우 흥미로운 점은 취약한 Function이 인터넷에 노출된 경우 **내부 네트워크로 피벗할 수 있는 가능성이 있다는 것입니다.** +> 공격자의 관점에서 매우 흥미로운 점은 취약한 Function이 인터넷에 노출된 경우 **내부 네트워크로 피벗할 수 있는 가능성이 있다는 점입니다**. -### **Function App 설정 및 환경 변수** +### **Function App Settings & Environment Variables** -앱 내에서 환경 변수를 구성할 수 있으며, 이 변수는 민감한 정보를 포함할 수 있습니다. 또한 기본적으로 **`AzureWebJobsStorage`** 및 **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`**(기타 포함)과 같은 env 변수가 생성됩니다. 이들은 **애플리케이션 데이터가 포함된 스토리지 계정을 완전 권한으로 제어할 수 있는 계정 키를 포함**하고 있어 특히 흥미롭습니다. 이러한 설정은 스토리지 계정에서 코드를 실행하는 데에도 필요합니다. +앱 내에서 환경 변수를 구성할 수 있으며, 이 변수는 민감한 정보를 포함할 수 있습니다. 또한 기본적으로 **`AzureWebJobsStorage`** 및 **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`** (기타 포함)과 같은 env 변수가 생성됩니다. 이들은 **애플리케이션 데이터가 포함된 Storage 계정을 완전한 권한으로 제어하는 계정 키를 포함하고 있기 때문에 특별히 흥미롭습니다**. 이러한 설정은 Storage 계정에서 코드를 실행하는 데에도 필요합니다. -이러한 env 변수 또는 구성 매개변수는 Function이 코드를 실행하는 방식을 제어합니다. 예를 들어 **`WEBSITE_RUN_FROM_PACKAGE`**가 존재하면 애플리케이션 코드가 위치한 URL을 나타냅니다. +이러한 env 변수 또는 구성 매개변수는 함수가 코드를 실행하는 방식을 제어합니다. 예를 들어 **`WEBSITE_RUN_FROM_PACKAGE`**가 존재하면 애플리케이션 코드가 위치한 URL을 나타냅니다. ### **Function Sandbox** -리눅스 샌드박스 내에서 소스 코드는 **`/home/site/wwwroot`**의 **`function_app.py`**(Python 사용 시)에 위치하며, 코드를 실행하는 사용자는 **`app`**(sudo 권한 없음)입니다. +리눅스 샌드박스 내에서 소스 코드는 **`/home/site/wwwroot`**의 **`function_app.py`** 파일에 위치하며 (Python을 사용하는 경우), 코드를 실행하는 사용자는 **`app`**입니다 (sudo 권한 없음). -**Windows** 함수에서 NodeJS를 사용하는 경우 코드는 **`C:\home\site\wwwroot\HttpTrigger1\index.js`**에 위치하며, 사용자 이름은 **`mawsFnPlaceholder8_f_v4_node_20_x86`**이고, **그룹**은 `Mandatory Label\High Mandatory Level Label`, `Everyone`, `BUILTIN\Users`, `NT AUTHORITY\INTERACTIVE`, `CONSOLE LOGON`, `NT AUTHORITY\Authenticated Users`, `NT AUTHORITY\This Organization`, `BUILTIN\IIS_IUSRS`, `LOCAL`, `10-30-4-99\Dwas Site Users`의 일부입니다. +**Windows** 함수에서 NodeJS를 사용하는 경우 코드는 **`C:\home\site\wwwroot\HttpTrigger1\index.js`**에 위치하며, 사용자 이름은 **`mawsFnPlaceholder8_f_v4_node_20_x86`**이고 **그룹**의 일부입니다: `Mandatory Label\High Mandatory Level Label`, `Everyone`, `BUILTIN\Users`, `NT AUTHORITY\INTERACTIVE`, `CONSOLE LOGON`, `NT AUTHORITY\Authenticated Users`, `NT AUTHORITY\This Organization`, `BUILTIN\IIS_IUSRS`, `LOCAL`, `10-30-4-99\Dwas Site Users`. -### **관리되는 ID 및 메타데이터** +### **Managed Identities & Metadata** -[**VMs**](vms/)와 마찬가지로 Functions는 **시스템 할당** 및 **사용자 할당**의 2가지 유형의 **Managed Identities**를 가질 수 있습니다. +[**VMs**](vms/index.html)와 마찬가지로, Functions는 **시스템 할당** 및 **사용자 할당**의 두 가지 유형의 **Managed Identities**를 가질 수 있습니다. -**시스템 할당**된 ID는 **해당 함수**만 사용할 수 있는 관리되는 ID이며, **사용자 할당**된 관리되는 ID는 **다른 Azure 서비스가 사용할 수 있는 관리되는 ID**입니다. +**시스템 할당**된 것은 **해당 함수**만 사용할 수 있는 관리되는 ID이며, **사용자 할당**된 관리되는 ID는 **다른 Azure 서비스가 사용할 수 있는 관리되는 ID**입니다. > [!NOTE] -> [**VMs**](vms/)와 마찬가지로 Functions는 **1개의 시스템 할당** 관리되는 ID와 **여러 사용자 할당** 관리되는 ID를 가질 수 있으므로, 함수를 손상시키면 모든 ID를 찾는 것이 항상 중요합니다. 하나의 Function에서 여러 관리되는 ID로 권한을 상승시킬 수 있습니다. +> [**VMs**](vms/index.html)와 마찬가지로, Functions는 **1개의 시스템 할당** 관리되는 ID와 **여러 사용자 할당** 관리되는 ID를 가질 수 있으므로, 함수를 손상시키면 모든 관리되는 ID를 찾는 것이 항상 중요합니다. 하나의 Function에서 여러 관리되는 ID로 권한을 상승시킬 수 있습니다. > -> 시스템 관리 ID가 사용되지 않고 하나 이상의 사용자 관리 ID가 함수에 연결된 경우 기본적으로 토큰을 얻을 수 없습니다. +> 시스템 관리 ID가 사용되지 않고 하나 이상의 사용자 관리 ID가 함수에 연결된 경우, 기본적으로 토큰을 얻을 수 없습니다. -[**PEASS 스크립트**](https://github.com/peass-ng/PEASS-ng)를 사용하여 메타데이터 엔드포인트에서 기본 관리 ID의 토큰을 얻을 수 있습니다. 또는 다음과 같이 **수동으로** 얻을 수 있습니다: +[**PEASS scripts**](https://github.com/peass-ng/PEASS-ng)를 사용하여 메타데이터 엔드포인트에서 기본 관리 ID의 토큰을 얻을 수 있습니다. 또는 다음과 같이 **수동으로** 얻을 수 있습니다: {% embed url="https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf#azure-vm" %} -함수가 연결된 **모든 관리 ID를 확인하는 방법**을 찾아야 합니다. 그렇지 않으면 메타데이터 엔드포인트는 **기본 ID만 사용**합니다(자세한 내용은 이전 링크를 참조). +함수가 연결된 모든 Managed Identities를 **확인하는 방법을 찾아야 합니다**. 그렇지 않으면 메타데이터 엔드포인트는 **기본 ID만 사용합니다** (자세한 내용은 이전 링크를 확인하세요). -## 액세스 키 +## Access Keys > [!NOTE] -> 함수 호출에 대한 사용자 액세스를 부여하는 RBAC 권한이 없음을 유의하십시오. **함수 호출은 생성 시 선택된 트리거에 따라 달라지며, HTTP 트리거가 선택된 경우 **액세스 키**를 사용해야 할 수 있습니다.** +> 함수 호출에 대한 사용자 액세스를 부여하는 RBAC 권한이 없음을 유의하세요. **함수 호출은 생성 시 선택된 트리거에 따라 달라지며, HTTP 트리거가 선택된 경우 **액세스 키**를 사용해야 할 수 있습니다**. HTTP 트리거를 사용하여 함수 내에서 엔드포인트를 생성할 때, 함수 트리거에 필요한 **액세스 키 권한 수준**을 지정할 수 있습니다. 세 가지 옵션이 있습니다: @@ -84,27 +84,27 @@ HTTP 트리거를 사용하여 함수 내에서 엔드포인트를 생성할 때 **키 유형:** -- **Function Keys:** 함수 키는 기본 또는 사용자 정의일 수 있으며, Function App 내의 **특정 함수 엔드포인트**에 대한 액세스를 독점적으로 부여하도록 설계되었습니다. -- **Host Keys:** 호스트 키는 기본 또는 사용자 정의일 수 있으며, FUNCTION 액세스 수준으로 Function App 내의 **모든 함수 엔드포인트**에 대한 액세스를 제공합니다. -- **Master Key:** 마스터 키(`_master`)는 모든 함수 엔드포인트에 대한 액세스를 포함하여 권한이 상승된 액세스를 제공하는 관리 키입니다. 이 **키는 취소할 수 없습니다.** -- **System Keys:** 시스템 키는 **특정 확장에 의해 관리**되며, 내부 구성 요소에서 사용하는 웹훅 엔드포인트에 접근하는 데 필요합니다. 예를 들어, Event Grid 트리거 및 Durable Functions는 시스템 키를 사용하여 해당 API와 안전하게 상호작용합니다. +- **Function Keys:** 함수 키는 기본 또는 사용자 정의일 수 있으며, Function App 내의 **특정 함수 엔드포인트**에만 접근을 허용하도록 설계되었습니다. 이를 통해 엔드포인트에 대한 보다 세밀한 접근 제어가 가능합니다. +- **Host Keys:** 호스트 키는 기본 또는 사용자 정의일 수 있으며, **FUNCTION 접근 수준**으로 Function App 내의 **모든 함수 엔드포인트**에 접근을 제공합니다. +- **Master Key:** 마스터 키(`_master`)는 모든 함수 엔드포인트에 대한 접근을 포함하여 **승격된 권한**을 제공하는 관리 키입니다. 이 **키는 취소할 수 없습니다.** +- **System Keys:** 시스템 키는 **특정 확장에 의해 관리되며**, 내부 구성 요소에서 사용하는 웹훅 엔드포인트에 접근하는 데 필요합니다. 예를 들어, Event Grid 트리거 및 Durable Functions는 시스템 키를 사용하여 해당 API와 안전하게 상호작용합니다. > [!TIP] > 키를 사용하여 함수 API 엔드포인트에 접근하는 예: > > `https://.azurewebsites.net/api/?code=` -### 기본 인증 +### Basic Authentication -App Services와 마찬가지로 Functions는 **SCM** 및 **FTP**에 연결하여 코드를 배포하기 위해 Azure에서 제공하는 **사용자 이름과 비밀번호가 포함된 URL**을 사용하여 기본 인증을 지원합니다. 이에 대한 자세한 내용은: +App Services와 마찬가지로, Functions는 **SCM** 및 **FTP**에 연결하여 코드를 배포하기 위해 Azure에서 제공하는 **URL의 사용자 이름과 비밀번호**를 사용한 기본 인증을 지원합니다. 이에 대한 자세한 내용은: {{#ref}} -az-app-service.md +az-app-services.md {{#endref}} -### Github 기반 배포 +### Github Based Deployments -함수가 Github 리포지토리에서 생성될 때 Azure 웹 콘솔은 **특정 리포지토리에서 자동으로 Github Workflow를 생성**할 수 있게 해주며, 이 리포지토리가 업데이트될 때마다 함수의 코드가 업데이트됩니다. 실제로 Python 함수에 대한 Github Action yaml은 다음과 같습니다: +함수가 Github 리포지토리에서 생성될 때 Azure 웹 콘솔은 **특정 리포지토리에서 자동으로 Github Workflow를 생성**할 수 있도록 하여 이 리포지토리가 업데이트될 때마다 함수의 코드가 업데이트됩니다. 실제로 Python 함수에 대한 Github Action yaml은 다음과 같습니다:
@@ -192,10 +192,10 @@ package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} ```
-또한, **Managed Identity**가 생성되어 리포지토리의 Github Action이 이를 사용하여 Azure에 로그인할 수 있습니다. 이는 **Managed Identity**에 대해 Federated credential을 생성하여 **Issuer** `https://token.actions.githubusercontent.com`와 **Subject Identifier** `repo:/:ref:refs/heads/`를 허용함으로써 이루어집니다. +또한, **Managed Identity**가 생성되어 리포지토리의 Github Action이 이를 사용하여 Azure에 로그인할 수 있습니다. 이는 **Managed Identity**에 대해 **Issuer** `https://token.actions.githubusercontent.com`와 **Subject Identifier** `repo:/:ref:refs/heads/`를 허용하는 Federated credential을 생성함으로써 이루어집니다. > [!CAUTION] -> 따라서 해당 리포지토리를 손상시키는 사람은 기능과 이에 연결된 Managed Identities를 손상시킬 수 있습니다. +> 따라서, 해당 리포지토리를 손상시키는 사람은 기능과 이에 연결된 Managed Identities를 손상시킬 수 있습니다. ### Container Based Deployments