Subdomain Takeover의 기본 전제는 현재 사용되지 않는 특정 서비스를 가리키는 호스트가 존재해야 하며, 공격자는 타사 서비스에 계정을 설정하여 취약한 subdomain을 탈취하여, 콘텐츠를 제공하는 데 사용할 수 있다. ( 요약하자면, subdomain에 매핑된 서버가 제거(삭제) 되었을 경우, 공격자가 해당 IP, 설정 등을 점유하여 인수할 수 있는 공격 방법이다. S3, Github Page, Heroku 등 서비스에서 발생가능성이 높다. )
example.com 이 target 서버일 때, 해커가 example.com에 속한 모든 하위 도메인을 열거하는 과정에서 특정 GitHub 페이지를 가리키는 하위 도메인인 subdomain.example.com을 발견한다. ( 아래에서 subdomain.example.com에 할당된 IP 주소와 whois를 통한 해당 IP 주소 정보를 얻는 것을 볼 수 있다. )
[hackerone report 예시]
$ host subdomain.example.com
subdomain.example.com has address 192.30.xxx.xxx
subdomain.example.com has address 192.30.xxx.xxy
$ whois 192.30.252.153 | grep "OrgName"
OrgName: GitHub, Inc.
현재 상황을 subdomain.example.com 이 whitehat1234.gitgub.io 를 가리키고 있었는데 ( CNAME 설정 ), whitehat1234 계정이 삭제된 상황으로 가정하자. 현재 subdomain.example.com 도메인은 Github page의 소유주가 없기 때문에 404 에러 페이지를 나타낸다. 이때, hacker가 whitehat1234라는 이름의 계정을 새로 생성하여, Github page를 만들게 된다면 subdomain.example.com 도메인을 사용할 수 있게 되는 것이 Subdomain Takeover 취약점이다.
( 유사 내용 : https://abhinav-porwal.medium.com/subdomain-takeover-github-based-bd2cec634c65 )
한 가지 더 예를 들어보도록 한다.
sub.example.domain이라는 도메인은, 다른 도메인 another.com에 대한 CNAME 레코드를 사용한다. ( 즉, sub.domain -----> another.com )
어느 시점에 anoher.com 이 만료되어 누구나 등록 할 수 있게 된다. 그러나 CNAME 레코드는 example.com DNS 영역에서 삭제되지 않았으므로, another.com을 등록하는 사람 누구나 해당 DNS 레코드가 제거될 때까지 sub.example.com에 대한 모든 제어권을 가진다.
Subdomain Takeover 취약점은 제어권을 가지고 끝이 아니라, 이를 통해 합법적인 도메인에서 피싱 이메일을 보내거나, XSS를 수행하거나 도메인과 관련된 브랜드의 평판을 손상 시킬 수 있다. ( 오늘 분석한 https://keep-going99.tistory.com/720 보고서도, 이에 해당된 취약점으로 보인다. )
추가적으로 Subdomain Takeover는 CNAME 레코드에만 국한되지 않는다. NS,MX 및 A 레코드도 영향을 받을 수 있다고 한다.
일반적인 Domain 해석 과정
위 그림 2는 CNAME Record 타입의 도메인 해석과정을 보여준다. 웹 브라우저는 DNS 확인자가 반환하는 모든 것을 암시적으로 신뢰한다. 이러한 신뢰는 공격자가 DNS 레코드에 대한 제어권을 얻을 때 모든 웹 브라우저 보안 측정( SOP )이 우회된다는 것을 의미한다. subdomain 탈취로 인해 공격자가 여러 가지 방법으로 활용할 수 있는 도메인의 신뢰성이 손상되기 때문에 이는 상당한 보안 위협이 된다.
CNAME Subdomain Takeover
CNAME Subdomain Takeover의 주요 유형 중 하나는 canonical domain name ( CNAME domain ) 이 regular internet domain ( 일반 인터넷 도메인 not cloud 공급 업체 소유 도메인 ) 인 경우이다. 일부 source 도메인 이름이 CNAME Subdomain Takeover 에 취약한지 여부를 감지하는 프로세스는 매우 간단하고 아래와 같다. 소스 도메인 이름과 표준 (Canonical) 도메인 이름의 쌍이 주어졌을 때 표준 도메인 이름의 기본 도메인을 등록할 수 있는 경우 소스 도메인 이름은 하위 도메인 탈취에 취약한 것이다.
해당 과정에서 주목할 점은 Canonical ( CNAME ) domain name의 base doamin이라는 점이다. 이는 표준 도메인 네임이 상위 도메인 형태일 수도 있기 때문이다. 기본 ( base ) 도메인을 등록할 수 있는 경우 나중에 DNS 영역에서 상위 도메인 네임을 쉽게 다시 만들 수 있다.
기본 ( base ) 도메인 네임의 사용 가능 여부는 도메인 등록기관을 통해 확인할 수 있다. NXDOMAIN에 대한 DNS 응답 상태를 테스트하는 것으로 도메인 네임을 등록할 수 있다고 생각할 수 있지만, 도메인 네임이 NXDOMAIN으로 응답하긴 하지만 등록될 수 없는 경우가 있다는 점에 유의하도록 한다. ( 제한된 최상위 도메인 혹은 TLD 등록 기관에서 예약한 도메인 이름 )
( 여기까지가 Subdomain Takeover를 간단히 이해할 수 있는 부분이라고 생각합니다. 필자는 https://0xpatrik.com/subdomain-takeover-basics 블로그를 보고, 내용이 좋다 생각이 들어 공부 목적으로 아래 내용을 추가 작성하였습니다. )
Cloud Provider
클라우드 서비스는 사용자의 인프라 설정 부담을 덜어줘 많은 인기를 얻고 있다. ( 온프레미스 환경에서 --> Cloud 환경 )
사용자가 새 클라우드 서비스를 만들면 대부분의 경우 클라우드 제공업체는 생성된 리소스에 액세스하는 데 사용되는 고유한 도메인 이름을 생성한다. 클라우드 서비스 고객이 많기 때문에 TLD 등록기관을 통해 도메인 네임을 등록하는 것은 그리 편리하지 않기 때문에 클라우드 공급업체는 하위 도메인을 사용하기로 선택한다. 고유한 클라우드 리소스를 식별하는 하위 도메인은 종종 name-of-customer.cloudprovider.com 형식으로 제공되며, 여기서 cloudprovider.com은 특정 클라우드 공급업체가 소유한 기본 도메인이다.
만약, 조직에서 등록한 클라우드 서비스가 공개용(예: 전자상거래 스토어)인 경우 특정 조직은 해당 서비스를 도메인의 일부로 표시하고 싶을 수 있다. ( 그 주된 이유는 브랜딩 때문인데, shop.organization.com 이 organization.ecommerceprovider.com보다 더 보기 좋기 때문이다. 이 경우 조직에는 두 가지 선택지가 있다. )
[ HTTP 301/302 리디렉션 ]
301 및 302는 웹 브라우저가 현재 URL을 다른 URL로 리디렉션하도록 트리거하는 HTTP 응답 코드이다. 클라우드 서비스의 경우 조직의 도메인 이름(예: shop.organization.com)으로 첫 번째 요청이 이루어진 다음 클라우드 공급업체의 도메인 이름(예: organization.ecommerceprovider.com)으로 리디렉션이 이루어진다.
[ CNAME 레코드 ]
이 방법을 사용하면 DNS 확인 중에 redirection이 발생한다. 조직이 CNAME 레코드를 설정하면, 모든 트래픽이 자동으로 클라우드 공급 업체에 위임된다. 이 방법 사용 시, 사용자 브라우저의 URL이 동일하게 유지된다.
위 두가지 방법 중, CNAME Record 방법을 사용하는 경우 하위 도메인을 탈취할 가능성이 있다. 클라우드 공급업체가 Canonical 도메인 네임의 base 도메인을 소유하고 있더라도 다음 섹션에서 설명하는 대로 Subdomain Takeover 가 여전히 가능하다.
아래 섹션에서 Amazon Cloud Front를 선택한 이유는 아래와 같다.
Prevalence ( 보급률 ) : CNAME 레코드에 대한 통계를 기반으로 CNAME 레코드에서 가장 많이 사용되는 클라우드 공급업체 도메인을 우선순위로 선정했다.
CNAME 레코드 지원 : 클라우드 공급업체는 CNAME 위임을 지원해야 한다.
Domain ownership verification ( 도메인 소유권 확인 ) : 선택한 클라우드 공급업체는 소스 도메인 이름의 소유권을 확인하지 않는다. 소유자를 증명할 필요가 없으므로 누구나 만료된 클라우드 구성을 사용하여 하위 도메인 인수를 실현할 수 있다.
Amazon CloudFront
Amazon CloudFront는 CDN이다. ( CDN은 웹 콘텐츠의 사본을 서로 다른 지리적 위치(PoP)에 위치한 서버에 배포한다. 사용자가 CDN에 요청하면 방문자 위치에 따라 가장 가까운 지점이 선택되어 지연 시간을 줄인다. CDN은 주로 비디오, 오디오, 이미지 등의 미디어 파일을 배포하기 위해 조직에서 활용한다. CDN의 다른 장점으로는 서비스 거부 공격 보호, 대역폭 감소, 트래픽 급증 시 부하 분산 등이 있다. )
CloudFront는 Amazon S3를 웹 콘텐츠의 주요 소스로 사용한다. Amazon S3는 AWS에서 제공하는 또 다른 서비스이다. 클라우드 스토리지 서비스(S3는 Simple Storage Service의 약자)로, 사용자가 S3 내의 논리 그룹 이름인 소위 버킷에 파일을 업로드할 수 있다.
CloudFront는 배포라는 개념으로 작동한다. 각 배포는 개체(파일)를 서비스할 특정 Amazon S3 버킷에 대한 링크이다. 새 CloudFront 배포가 생성되면 액세스를 제공하기 위해 고유한 하위 도메인이 생성된다. 이 하위 도메인의 형식은 SUBDOMAIN.cloudfront.net이다. 서브도메인 부분은 CloudFront에서 생성하며 사용자가 지정할 수 없다.
무작위로 생성된 하위 도메인 외에도 CloudFront에는 배포에 액세스 하기 위한 대체 도메인 이름 ( CNAME )을 지정할 수 있는 기능이 포함되어 있다. 이는 대체 도메인 이름에서 CloudFront에서 생성된 하위 도메인으로 CNAME 레코드를 생성하는 방식으로 작동한다. Amazon은 내부 CloudFront 개념에 대한 문서를 제공하지 않지만 그 동작에서 높은 수준의 아키텍처를 추론할 수 있다. 지리적 위치에 따라 cloudfront.net의 모든 하위 도메인에 대한 DNS 쿼리는 동일한 A 레코드(동일한 지역)로 연결된다. 이는 CloudFront가 백엔드에서 가상 호스팅 설정을 사용하고 있음을 나타낸다. HTTP 요청이 도착한 후 CloudFront의 엣지 서버 ( https://www.cloudflare.com/ko-kr/learning/cdn/glossary/edge-server/ )는 HTTP 호스트 헤더를 기반으로 올바른 배포를 결정한다. 문서에서도 이 이론을 뒷받침하는 다음과 같은 내용이 명시되어 있다 ( 대체 도메인 이름이 다른 CloudFront 배포에 이미 존재하는 경우, AWS 계정이 다른 배포를 소유하고 있더라도 대체 도메인 이름을 CloudFront 배포에 추가할 수 없다. ) 하나의 배포를 가리키는 여러 개의 대체 도메인이 있는 것은 맞지만, 동일한 대체 도메인 이름이 여러 배포에 존재하는 것은 옳지 않다.
따라서 대체 도메인 이름을 올바르게 처리하려면 CloudFront는 대체 도메인 이름이 어느 배포에 연결되어 있는지 미리 알아야 한다. 즉, CNAME 레코드를 구성하는 것만으로는 충분하지 않으며, 배포 설정에서 대체 도메인 이름을 명시적으로 설정해야 한다.
CloudFront의 대체 도메인 이름의 문제는 일반 도메인 섹션에서 설명한 문제와 유사하다. sub.example.com의 CNAME 레코드가 d1231731281.cloudfront.net으로 설정되어 있다고 가정해 본다. CloudFront 배포에 대체 도메인 네임으로 등록된 sub.example.com 이 없는 경우 하위 도메인을 인수 ( Subdomain Takeover )할 수 있다. 누구나 새 배포를 생성하고 설정에서 sub.example.com을 대체 도메인 이름으로 설정할 수 있다. 그러나 새로 생성된 CloudFront 하위 도메인이 CNAME 레코드(d1231731281.cloudfront.net)에 지정된 도메인과 일치할 필요는 없다. CloudFront는 가상 호스팅 설정을 사용하므로 올바른 배포는 DNS 레코드가 아닌 HTTP 호스트 헤더를 사용하여 결정된다.
아래 그림은 CloudFront에 대한 DNS CNAME 레코드가 있지만 CloudFront 배포에 등록되어 있지 않은 대체 도메인 이름으로 HTTP 요청 후 표시되는 오류 메시지를 보여준다.
이 오류 메시지는 하위 도메인 탈취의 가능성을 확실하게 나타낸다. 그럼에도 불구하고 두 가지 예외를 고려해야 한다
[ HTTP/HTTPS 전용 배포 ]
CloudFront에서는 배포가 HTTP 전용인지 HTTPS 전용인지 지정할 수 있다. HTTP를 HTTPS로 전환하면 일부 배포에 대해 올바른 응답을 제공할 수 있다.
[ 비활성화된 배포 ]
일부 배포는 비활성화될 수 있다. 비활성화된 배포는 설정을 그대로 유지하면서 더 이상 콘텐츠를 적극적으로 제공하지 않는다. 즉, 일부 대체 도메인 네임이 HTTP 요청 후 오류 메시지를 던질 수 있다. 그러나 비활성화된 배포 내부에도 등록되어 있으므로 하위 도메인 탈취에 취약하지 않다. 일부 배포 내에 대체 도메인이 등록되어 있는지 확인하는 올바른 방법은 새 배포를 만들고 대체 도메인 네임을 설정하는 것이다. 등록 프로세스에서 오류가 발생하지 않으면 사용자 정의 도메인은 하위 도메인 탈취에 취약한 것이다. 아래 스크린샷은 사용자가 다른 CloudFront 배포에 이미 있는 대체 도메인 네임을 등록하려고 할 때 표시되는 오류를 보여준다.
https://0xpatrik.com/subdomain-takeover-basics/ 해당 블로그에서, 다른 서비스들의 Subdomain Takeover 가능성을 더 자세히 볼 수 있다.
참고
- https://www.hackerone.com/hackerone-community-blog/guide-subdomain-takeovers
- https://github.com/EdOverflow/can-i-take-over-xyz
- https://0xpatrik.com/subdomain-takeover-basics/
- https://0xpatrik.com/subdomain-takeover/