ghrc.io가 악성 사이트로 의심됨
(bmitch.net)- 단순한 오타인 ghcr.io와 ghrc.io 혼동이 심각한 보안 위협을 야기함
- ghrc.io는 첫눈에는 기본 nginx 서버처럼 보이지만, 내부적으로는 OCI API를 모방하는 행위가 포착됨
- 이 사이트는 www-authenticate 헤더를 통해 컨테이너 클라이언트로 하여금 민감한 인증 정보를 보내도록 유도함
- docker login 등 실수로 인증 정보를 입력하거나 잘못된 레지스트리로 사용하는 경우 자격 증명 유출이 발생할 수 있음
- 잘못된 서버에 로그인했다면 비밀번호 변경, PAT 폐기, GitHub 계정 이상 활동 점검이 필요함
개요
단순한 오타로 인해 자주 발생할 수 있는 ghcr.io와 ghrc.io의 혼동이 매우 위험한 보안 문제를 야기하는 사례임. 많은 개발자와 팀이 사용하는 GitHub Container Registry(ghcr.io) 의 오타 버전인 ghrc.io에서 자격 증명 탈취 시도가 포착되었음.
ghcr.io란 무엇인가
- ghcr.io는 컨테이너 이미지 및 OCI 아티팩트를 위한 OCI 호환 레지스트리임
- GitHub의 일부로, 수많은 오픈소스 프로젝트에서 인기 있는 레지스트리로 쓰임
ghrc.io: 표면상 보이는 모습
- ghrc.io에 접속하면 단순한 nginx 기본 화면이 보임
- 대표적인 404 오류 등 기본 동작은 일반 nginx 서버와 동일함
악의적인 행위의 정체
- 핵심 문제는
/v2/
프리픽스 하위 OCI API 호출 시에 나타남 - 이 경로로 접근할 경우,
www-authenticate
헤더와 401 응답으로 공식 컨테이너 레지스트리와 매우 유사한 동작을 보임 -
www-authenticate: Bearer realm="https://ghrc.io/token"
헤더가 존재함 - 이 헤더 때문에 Docker, containerd, podman, Kubernetes 등의 클라이언트가 사용자 인증 정보를
https://ghrc.io/token
으로 자동 전달 시도함 - nginx 기본 설정에는 해당 헤더가 없으므로, 명백히 의도적으로 구성된 것임
위험성: 자격 증명 탈취 시나리오
- 이 패턴은 타이포스쿼팅(typo-squatting) 기반 자격 증명 탈취 공격으로 판단됨
- 위험은 사용자 클라이언트가 ghrc.io에 저장된 자격 증명을 입력 또는 저장한 경우에만 발생함
- 실제 자격 증명이 노출될 수 있는 상황 예시
-
docker login ghrc.io
를 실행하는 경우 - GitHub Action 내에서
docker/login-action
사용 시, 레지스트리를 ghrc.io로 지정한 경우 - Kubernetes 시크릿에 ghrc.io용 레지스트리 자격 증명을 저장 후 이미지 풀링을 시도한 경우
-
- 단순하게 ghrc.io에 이미지를 push/pull만 시도하면 인증 정보는 노출되지 않음(익명 토큰 시도 후 오류 반환)
대응 방안
- ghrc.io로 실수로 로그인한 적이 있다면, 즉시 비밀번호 변경 및 사용한 PAT(퍼스널 액세스 토큰) 을 폐기해야 함
- GitHub 계정에서 이상 로그인 또는 악성 활동을 반드시 점검해야 함
- 공격자는 이를 이용하여 ghcr.io의 저장소에 악성 이미지 추가 또는 계정 접근권을 획득할 수 있음
결론
- ghcr.io와 유사한 주소를 사용하는 피싱 사이트에 주의 필요함
- 자격 증명, 토큰, 비밀번호 등 보안 정보 관리에 더욱 철저한 방침이 요구됨
Hacker News 의견
-
GitHub Container registry가 세분화된 토큰 대신 기존의 클래식 토큰만 지원하고 있어 심각함을 강조함
관련 문서와 이슈 링크도 첨부함
공식 문서
커뮤니티 토론
로드맵 이슈-
이 문제 때문에 클래식 PAT을 완전히 끌 수 없는 상황임
추가적인 보완책으로는 세션 유효기간을 짧게 두고 엔터프라이즈 SSO로 재인증을 강제하는 방법이 있지만, 실제 필요한 단일 클래식 PAT에는 번거로운 선택임 -
누군가가 선의로 오타 도메인을 전부 사서 Microsoft에 넘기면 좋겠음
Microsoft가 레지스트리 이름을 바꿔야 한다고 생각함
이름이 너무 헷갈려서 나도 오타를 친 적이 많음
-
-
도메인 이슈를 여러 번 읽고 나서야 문제를 파악할 수 있었을 만큼, 꽤 설득력 있는 공격 벡터임
- 나뿐만 아니라 여러 명이 비슷함
몇 번이나 시도하다 실패하고 심지어 컴퓨터를 다시 시작해도 동일 문제가 발생함
참고할 만한 사례로 stackoverflow 답변과 Docker 포럼 토론도 있음
- 나뿐만 아니라 여러 명이 비슷함
-
ghrc.io 관련 코드 검색 결과를 링크로 제시함
-
기사에서 c와 r이 바뀐 것을 직접 지적해주기 전까지 문제를 알아차리지 못했음
-
이런 오타는 하루에 거의 10번도 넘게 내는 유형임
-
여기서 문제는 GitHub의 도메인명이 엉망이라는 것임
컨테이너 레지스트리 이름이 정말로 별로임
-
-
과거 Hacker News 토론 링크를 공유함
-
이 도메인이 dynadot에서 등록된 것을 whois로 확인할 수 있음
따라서 abuse@dynadot.com으로 신고하는 것이 가치 있을 것으로 보임 -
많은 오픈소스 프로젝트에서 이 도메인을 사용하고 있음을 언급하면서 코드 검색 결과도 다시 한번 공유함
-
GitHub 내부적으로 대량으로 자동 수정을 제안하고 배포할 수 있는 도구가 필요함
-
실제로 깃허브 코드 검색 결과가 상당한 규모임을 언급함
-
-
CI 작업에서 오타가 나면 큰 문제를 일으킬 수 있겠다는 우려를 표함
-
보안상 가치가 떨어지는 TLD(최상위 도메인)는 되도록 사용을 지양하자는 조언을 함
귀엽게 보이려는 시도보다는 보안이 우선임
악성 도메인 등록 해제가 .com만큼 신속하지 않을 수 있으므로, 미국 verisign이 관리하는 .com이 더 신뢰감 있다고 생각함
영국령 인도양 지역이나 콜롬비아, 앵귈라 등에 의존하는 건 부적절함- .io TLD는 미국 회사인 Afilias가 관리함을 덧붙임
-
여기서 진짜 위험성이 토큰 재사용 문제인지 질문함
Bearer 토큰은 패스워드를 직접 주지 않는데, RFC와 Mozilla 문서를 인용하면서 실제로는 인증 토큰 자체가 아니라 인증을 위해 다시 토큰을 받는 절차가 문제가 되는 건지 궁금함
도메인 간 OAuth가 토큰을 재사용하지 않는다면, 결국 가짜 도메인에서는 토큰을 받지 못하는 것 아닌지 의문임- 블로그 저자이자 OCI 유지관리자로서 답변함
Bearer 토큰을 받기 위한 요청에서 비밀번호나 PAT를 기본 인증 헤더에 base64로 인코딩해서 보내지만, 사실상 평문으로 전송됨
요청을 받으면 www-authenticate 헤더가 발생하고, 인증 토큰을 받아 레지스트리 접근을 검증하며, 이후 토큰은 만료되지만
공격자가 실제 토큰을 탈취하는 게 아니라, Bearer 토큰을 받기 위한 자격 증명 자체를 요청하게 되는 구조임
- 블로그 저자이자 OCI 유지관리자로서 답변함