
CVE-2021-43287 CVE-2021-43288 CVE-2021-43289 CVE-2021-43290
저자 / Author: Higor Farias — PRIDE Security
⚠️ 법적 고지 / LEGAL DISCLAIMER
[PT] 본 자료는 오직 교육 및 공격적 보안 연구 목적으로 제작되었습니다. 명시적인 허가 하에 통제된 환경에서만 사용하십시오. 오용 시 모든 책임은 전적으로 사용자에게 있습니다.
[EN] 본 자료는 오직 교육 및 승인된 공격적 보안 연구 목적으로 제작되었습니다. 명시적인 서면 허가 하에 통제된 환경에서만 사용하십시오. 오용 시 모든 책임은 전적으로 사용자에게 있습니다.
[PT] GoCD는 ThoughtWorks에서 유지 관리하는 CI/CD 플랫폼입니다. 21.3.0 이전 버전에서 SonarSource 연구진은 인증 없이도 악용 가능한 취약점 사슬을 식별했습니다. 이 저장소의 두 스크립트는 다음을 보여줍니다:
gocd_rce_noauth.py — 자격 증명 없이 전체 사슬을 악용하여 RCE(원격 코드 실행)까지 도달합니다.gocd_urldns.py — URLDNS 가젯 사슬과 DNS 콜백을 통한 Java 직렬화의 외부(OOB) 감지 (등록된 에이전트 목록 조회를 위해 유효한 자격 증명이 필요함).[EN] GoCD는 ThoughtWorks에서 유지 관리하는 CI/CD 플랫폼입니다. 21.3.0 이전 버전에서 SonarSource 연구진은 인증이 전혀 필요 없는 취약점 사슬을 식별했습니다. 이 저장소의 두 스크립트는 다음을 보여줍니다:
gocd_rce_noauth.py — 자격 증명 없이 전체 사슬을 악용하여 RCE(원격 코드 실행)까지 도달합니다.gocd_urldns.py — URLDNS 가젯 사슬과 DNS 콜백을 통한 Java 직렬화의 외부(OOB) 감지 (등록된 에이전트 목록 조회를 위해 유효한 자격 증명이 필요함).[PT] GoCD는 조직의 소프트웨어 제공 사슬에서 핵심적인 위치를 차지합니다: 빌드, 테스트, 아티팩트 생성 및 프로덕션 배포를 조정합니다. gocd_rce_noauth.py에서 시연된 대로 RCE를 통해 GoCD 서버를 침해할 경우, 공격자는 해당 프로세스의 모든 단계에 대한 제어권을 얻게 됩니다. 이를 통해 바이너리에 백도어를 삽입하거나, 아티팩트를 변조하거나, 최종 사용자가 제품을 받기 전에 소스 코드와 자격 증명을 유출할 수 있습니다. 이 시나리오는 2020년 SolarWinds 공격과 유사한데, 빌드 파이프라인 접근 권한이 수천 명의 고객에게 멀웨어를 배포하는 결과로 이어졌습니다.
[EN] GoCD는 조직의 소프트웨어 제공 사슬에서 핵심적인 위치를 차지합니다: 빌드, 테스트, 아티팩트 생성 및 프로덕션 배포를 조정합니다. gocd_rce_noauth.py에서 시연된 대로 RCE를 통해 GoCD 서버를 침해할 경우, 공격자는 해당 프로세스의 모든 단계에 대한 제어권을 얻게 됩니다. 이를 통해 바이너리에 백도어를 삽입하거나, 아티팩트를 변조하거나, 최종 사용자가 제품을 받기 전에 소스 코드와 자격 증명을 유출할 수 있습니다. 이 시나리오는 2020년 SolarWinds 공격과 유사한데, 빌드 파이프라인 접근 권한이 수천 명의 고객에게 멀웨어를 배포하는 결과로 이어졌습니다.
flowchart TD
ATK(["🕵️ Atacante / Attacker\n(não autenticado / unauthenticated)"])
subgraph EXPLOIT ["Exploração / Exploitation"]
E1["CVE-2021-43287\nLeitura do cruise_config\n(tokenGenerationKey + agentAutoRegisterKey)"]
E2["Path Traversal\nLeitura de /etc/go/jetty.xml\ne /proc/self/environ"]
E3["Registro de agente falso\nFake agent registration"]
E4["Desserialização Java\n(AspectJWeaver gadget chains)\nSobrescreve jetty.xml + restart"]
E5["💥 RCE no servidor GoCD\nRCE on GoCD server"]
E1 --> E2 --> E3 --> E4 --> E5
end
subgraph PIPELINE ["Pipeline CI/CD comprometido / Compromised CI/CD Pipeline"]
P1["📦 Build de artefatos\nBinary/artifact build"]
P2["🧪 Execução de testes\nTest execution"]
P3["📤 Publicação de pacotes\nPackage publication\n(npm, PyPI, Docker Hub...)"]
P4["🚀 Deploy em produção\nProduction deployment"]
P1 --> P2 --> P3 --> P4
end
subgraph IMPACT ["Impacto / Impact"]
I1["🔑 Vazamento de credenciais\nCredential leak\n(tokens, SSH keys, API keys)"]
I2["🦠 Backdoor em artefatos\nBackdoor in build artifacts"]
I3["📂 Exfiltração de código-fonte\nSource code exfiltration"]
I4["☠️ Ataque à cadeia de suprimentos\nSupply chain attack\n(usuários finais afetados / end users impacted)"]
I1 & I2 & I3 --> I4
end
ATK --> EXPLOIT
E5 -->|"Controle total do runner\nFull runner control"| PIPELINE
P1 -->|"Artefatos envenenados\nPoisoned artifacts"| I2
P3 -->|"Pacotes maliciosos\nMalicious packages"| I4
P4 -->|"Produção comprometida\nCompromised production"| I4
E5 -->|"Leitura de secrets\nSecrets read"| I1
E5 -->|"Acesso ao repositório\nRepository access"| I3
| CVE | 유형 / Type | CVSS 3.1 | CWE | 인증 |
|---|---|---|---|---|
| CVE-2021-43287 | 정보 노출 | 7.5 HIGH | CWE-200 | ❌ 없음 / None |
| CVE-2021-43288 | 저장형 XSS | 6.1 MEDIUM | CWE-79 | Agent |
| CVE-2021-43289 | 경로 순회 — PUT | 8.1 HIGH | CWE-22 | Agent |
| CVE-2021-43290 | 경로 순회 — GET | 8.1 HIGH | CWE-22 | Agent |
[PT] /go/add-on/business-continuity/api/cruise_config 엔드포인트는 인증을 요구하지 않고 서버의 전체 구성 XML을 반환합니다. 이 XML에는 <server> 요소의 속성이 포함되어 있으며, 여기에는 agentAutoRegisterKey와 tokenGenerationKey가 포함됩니다 — 이 두 키는 에이전트를 등록하고 인증된 요청에 서명하는 데 필요한 키입니다. 또한, 플러그인 엔드포인트의 pluginName 매개변수는 경로 순회 시퀀스(../../../../../../)를 허용하여 /proc/self/environ 및 /etc/go/jetty.xml과 같은 시스템의 임의 파일을 읽을 수 있습니다.
[EN] /go/add-on/business-continuity/api/cruise_config 엔드포인트는 인증을 요구하지 않고 서버의 전체 구성 XML을 반환합니다. 이 XML에는 <server> 요소의 속성이 포함되어 있으며, 여기에는 agentAutoRegisterKey와 tokenGenerationKey가 포함됩니다 — 이 두 키는 에이전트를 등록하고 인증된 요청에 서명하는 데 필요한 키입니다. 또한, 플러그인 엔드포인트의 pluginName 매개변수는 경로 순회 시퀀스(../../../../../../)를 허용하여 /proc/self/environ 및 /etc/go/jetty.xml과 같은 시스템의 임의 파일을 읽을 수 있습니다.
스크립트가 악용하는 엔드포인트 / Endpoints used by the scripts:
GET /go/add-on/business-continuity/api/cruise_config
GET /go/add-on/business-continuity/api/plugin?folderName=&pluginName=../../../../../../proc/self/environ
GET /go/add-on/business-continuity/api/plugin?folderName=&pluginName=../../../../../../etc/go/jetty.xml
remoteBuildRepository[PT] /go/remoting/remoteBuildRepository 엔드포인트는 Authorization: base64(HMAC-SHA256(tokenGenerationKey, agent_uuid)) 헤더만으로 인증된 Java 직렬화 객체(Content-Type: application/x-java-serialized-object)를 허용합니다. tokenGenerationKey는 CVE-2021-43287을 통해 획득되므로, 자격 증명이 없는 공격자가 악성 gadget chain을 전송할 수 있습니다. 스크립트는 AspectJWeaver 기반의 두 가지 커스텀 ysoserial gadget을 사용합니다:
AspectJWeaverFileUpload1 — 서버 파일 시스템에 임의 파일을 작성합니다 (악성 버전으로 /etc/go/jetty.xml을 덮어쓰는 데 사용됨).AspectJWeaverFileRead1 — /dev/random을 읽어 Jetty를 강제로 재시작시키고 수정된 jetty.xml을 로드하게 하여, java.lang.Runtime.exec()를 통해 주입된 명령을 실행시킵니다.[EN] /go/remoting/remoteBuildRepository 엔드포인트는 Authorization: base64(HMAC-SHA256(tokenGenerationKey, agent_uuid)) 헤더만으로 인증된 Java 직렬화 객체(Content-Type: application/x-java-serialized-object)를 허용합니다. tokenGenerationKey는 CVE-2021-43287을 통해 획득되므로, 인증되지 않은 공격자가 악성 gadget chain을 전송할 수 있습니다. 스크립트는 AspectJWeaver 기반의 두 가지 커스텀 ysoserial gadget을 사용합니다:
AspectJWeaverFileUpload1 — 서버 파일 시스템에 임의 파일을 작성합니다 (악성 버전으로 /etc/go/jetty.xml을 덮어쓰는 데 사용됨).AspectJWeaverFileRead1 — /dev/random을 읽어 Jetty를 강제로 재시작시키고 수정된 jetty.xml을 로드하게 하여, java.lang.Runtime.exec()를 통해 주입된 명령을 실행시킵니다.gocd_rce_noauth.py — 인증 없는 전체 체인 / Full unauthenticated chain