GCP - Network Docker Escape

Support HackTricks

Initial State

이 기술이 명시된 두 개의 보고서에서 공격자는 GCP에서 관리하는 Docker 컨테이너 내에서 root 접근 권한을 얻었으며, 호스트 네트워크에 접근할 수 있었습니다 (및 CAP_NET_ADMINCAP_NET_RAW 권한).

Attack Explanation

Google Compute Engine 인스턴스에서 네트워크 트래픽을 정기적으로 검사하면 메타데이터 인스턴스에 대한 수많은 일반 HTTP 요청169.254.169.254로 전송되는 것을 확인할 수 있습니다. Google Guest Agent는 이러한 요청을 자주 수행하는 오픈 소스 서비스입니다.

이 에이전트는 메타데이터의 변경 사항을 모니터링하도록 설계되었습니다. 특히, 메타데이터에는 SSH 공개 키 필드가 포함되어 있습니다. 새로운 공개 SSH 키가 메타데이터에 추가되면, 에이전트는 자동으로 .authorized_key 파일에서 이를 승인합니다. 필요할 경우 새 사용자를 생성하고 sudoers에 추가할 수도 있습니다.

에이전트는 모든 메타데이터 값을 재귀적으로 검색하기 위해 요청을 전송하여 변경 사항을 모니터링합니다 (GET /computeMetadata/v1/?recursive=true). 이 요청은 마지막 검색 이후 메타데이터에 변경 사항이 있을 경우에만 메타데이터 서버가 응답하도록 유도합니다. 이는 Etag(wait_for_change=true&last_etag=)로 식별됩니다. 또한 타임아웃 매개변수(timeout_sec=)가 포함됩니다. 지정된 타임아웃 내에 변경 사항이 발생하지 않으면 서버는 변경되지 않은 값으로 응답합니다.

이 프로세스는 IMDS (Instance Metadata Service)가 구성 변경이 발생하지 않은 경우 60초 후에 응답할 수 있도록 하여, 게스트 에이전트에 대한 가짜 구성 응답을 주입할 수 있는 잠재적인 을 생성합니다.

공격자는 이를 이용하여 Man-in-the-Middle (MitM) 공격을 수행하고 IMDS 서버의 응답을 스푸핑하여 새 공개 키를 삽입할 수 있습니다. 이는 호스트에 대한 무단 SSH 접근을 가능하게 할 수 있습니다.

Escape Technique

ARP 스푸핑은 Google Compute Engine 네트워크에서 효과적이지 않지만, Ezequiel에서 개발한 수정된 rshijack 버전을 사용하여 SSH 사용자를 주입하기 위한 패킷 주입을 수행할 수 있습니다.

이 rshijack 버전은 ACK 및 SEQ 번호를 명령줄 인수로 입력할 수 있어, 실제 메타데이터 서버 응답 전에 응답을 스푸핑할 수 있습니다. 또한, 작은 Shell 스크립트를 사용하여 특별히 제작된 페이로드를 반환합니다. 이 페이로드는 Google Guest Agent가 .authorized_keys 파일에 지정된 공개 키로 wouter 사용자를 생성하도록 유도합니다.

스크립트는 같은 ETag를 사용하여 메타데이터 서버가 Google Guest Agent에 다른 메타데이터 값을 즉시 알리지 않도록 하여 응답을 지연시킵니다.

스푸핑을 실행하기 위해서는 다음 단계가 필요합니다:

  1. tcpdump를 사용하여 메타데이터 서버에 대한 요청을 모니터링합니다:

tcpdump -S -i eth0 'host 169.254.169.254 and port 80' &

유사한 줄을 찾아보세요:

<TIME> IP <LOCAL_IP>.<PORT> > 169.254.169.254.80: Flags [P.], seq <NUM>:<TARGET_ACK>, ack <TARGET_SEQ>, win <NUM>, length <NUM>: HTTP: GET /computeMetadata/v1/?timeout_sec=<SECONDS>&last_etag=<ETAG>&alt=json&recursive=True&wait_for_change=True HTTP/1.1
  1. 올바른 ETAG와 함께 가짜 메타데이터를 rshijack에 전송합니다:

fakeData.sh <ETAG> | rshijack -q eth0 169.254.169.254:80 <LOCAL_IP>:<PORT> <TARGET_SEQ> <TARGET_ACK>; ssh -i id_rsa -o StrictHostKeyChecking=no wouter@localhost

이 단계는 공개 키를 인증하여 해당 개인 키로 SSH 연결을 가능하게 합니다.

References

Support HackTricks

Last updated