오늘은 Subdomain Takeover 취약점에 대한 이야기를 할까 합니다. 어느정도 자동화가 가능하면서도 버그바운티에서도 결과가 좋은 공격 방법이라 알아두시면 두고두고 도움될거라고 생각합니다.
그럼 시작합니다.
DNS
우선 취약점에 대한 설명 전 간략하게 CNAME, A레코드에 대해 알고가면 좋습니다. 직접 도메인 구매해서 사용하시는 분이라면 아주 익숙한 용어이겠네요.
CNAME
우선 CNAME(Canonical Name)은 하나의 도메인에 다른 이름을 부여하는 방식으로 대체로 별칭이란 표현으로 많이 사용합니다. 예를들면..
- abcd.hahwul.com => hahwul.github.io
이런식으로 CNAME을 지정하였을 경우 abcd.hahwul.com 에 접근 시 hahwul.github.io에 접근한 것과 동일하게 됩니다.
A Record
A Record 는 도메인에 각각 개별의 IP가 매핑된걸 의미합니다.
- www.hahwul.com => 216.58.197.179
- vaha.hahwul.com => 183.111.174.31
간단하죵?
참고로 IPv4는 A Record, IPv6는 AAAA Record를 사용합니다.
Subdomain Takeover?
Subdomain takeover 취약점은 하위 도메인(CNAME)이 삭제된 서비스를 가리키고 있는 경우 공격자가 해당 주소를 재 선점해서 정상 도메인에 공격자의 서비스로 넘어가지도록 변조할 수 있습니다.
예를들어 test.takeover_test.domain
이란 주소가 호스팅 업체의 서비스를 받는 abcd.this_is_hosting_domain.com
을 가리키고 있다고 가정합시다.
이 때 서비스 계정은 abcd
만약 dns는 유지하되 abcd
가 호스팅에서 탈퇴한 경우 test.takeover_test.domain
주소는 없는 도메인을 가리키게 되고, 요청 시 응답을 받지 못하는 상황이 발생합니다.
이때 공격자는 호스팅 업체의 탈퇴되었던 abcd 계정으로 신규 가입하여 abcd.this_is_hosting_domain.com
로 할당받으면 동시에 test.takeover_test.domain
도메인의 제어권도 가지게됩니다.
호스팅 서비스 이외에도 github 페이지나, heroku 등 개별 유저의 권한으로 도메인을 생성할 수 있는 경우 대체로 공격에 사용될 수 있습니다.
아무튼, 취약한 domain을 찾고 이와 매핑되는 서비스의 제어권을 가진다면 쉽게 타겟 도메인의 주소를 단 악의적인 사이트를 만들어낼 수 있게 됩니다.
How to test?
Subdomain Enum
우선 subdomain에 대한 Enum이 필요합니다. 도메인 리스트를 안다면 바로 다음 단계로 넘어가도 되겠지만 아닌 경우 서브 도메인에 대한 수집이 필요해집니다. 보편적으론 subdomain에 대한 enumerate 툴, BruteForce 툴을 기반으로 리스트를 만들어가게 됩니다.
대표적으로 subover(https://github.com/Ice3man543/SubOver), subjack(https://github.com/haccer/subjack) 같은 툴들이 있으며 Metasploit의 모듈이나 직접 코드를 짜서 확보하셔도 좋습니다.
Check Response
해당 도메인이 Github page나 S3 Bucket 등으로 만들어진 사이트와 연결된 도메인일 수 있습니다. 이러한 경우 원본 계정 등이 삭제된 경우 별도의 에러 메시지가 나타나게 됩니다.
에러 메시지에 대한 정보는 Can I take over XYZ?를 참고해주세요!
만약 도메인에 매핑된 CNAME등을 직접 확인하려면 host 명령 등으로 도메인에 대한 정보를 체크할 수 있습니다.
host vaha.hahwul.com
# vaha.hahwul.com is an alias for hahwul.com.
보시면 vaha.hahwul.com
은 hahwul.com
과 같다고 이야기됩니다. 예시로는 동일 도메인이지만 만약 다른 서비스의 주소로 별칭이 지정된 경우엔 해당 서비스 제어만으로 원본 주소의 제어권도 같이 얻어낼 수 있죠.
대체로 위에 subover 관련 툴들은 이 과정까지 대체로 포함되어 있습니다.
python takeover.py -d google.com -w subdomains-10000.txt -t 10
# mail.google.com. CNAME: googlemail.l.google.com.
# m.google.com. CNAME: mobile.l.google.com.
# CNAME: www.blogger.com.g : forum.google.com
# news.google.com. CNAME: news.l.google.com.Scanning : mysql.google.com
# www3.l.google.com.. CNAME: Scanning : mobile.google.com
# CNAME: mobile.l.google.com.sql.google.com
# calendar.google.com. CNAME: www3.l.google.com.
# web.google.com. CNAME: www3.l.google.com.
# images.google.com. CNAME: images.l.google.com.
# email.google.com. CNAME: gmail.google.com.
# CNAME: video.l.google.com.cdn.google.com
이런식으로 매핑된 주소를 확인하면 됩니다.
다른 방법으로는 스크린샷을 이용해서도 체크할 수 있습니다. ruby나 python 모듈중에 스크린 캡쳐가 가능한 모듈이 있는데, 확인된 서브도메인에 요청하면서 페이지의 상태를 캡쳐로 남겨 404같이 에러 발생 페이지를 우선으로 체크하는 방법이 있습니다. 개인적으론 CNAME 체크가 빠르고 좋은 것 같네요.
매핑된 사이트 선점
가장 중요한 부분인데요, 매핑된 사이트에 대해 주소를 재 선점할 수 있거나 해당 서버의 취약점을 이용해 도메인 세팅 권한을 얻어낼 수 있다면 Subdomain takeover가 완성됩니다.
Solution
대응은 간단합니다. 안쓰는 도메인이나 서비스 제거 시 CNAME 쪽도 제거 처리를 같이 해주시면 됩니다.