
간단한 DNS 리바인딩 서비스
간단한 DNS 리바인딩 서비스
rbndr은 DNS 리바인딩 취약점에 대해 소프트웨어를 테스트하기 위한 매우 간단하고, 비표준적인 이름 서버입니다. 이 서버는 호스트명에 지정된 주소 중 하나를 무작위로 선택하여 매우 낮은 TTL로 응답으로 반환합니다.
https://en.wikipedia.org/wiki/DNS_rebinding
DNS 리바인딩은 TOCTOU(time of check, time of use) 취약점의 한 형태입니다. 이는 보안 속성을 수정하기 위해 "사전 점검(preflight)" 확인을 잘못 사용하는 서비스가 있을 때 사용합니다. 예를 들어, 다음과 같은 API를 가진 (가상의) 브라우저 플러그인을 생각해 보세요:
AllowUntrustedAccess("foobar.com");
SendArbitraryRequests("foobar.com");
그리고 AllowUntrustedAccess()는 단순히 호스트에 사전 점검 HTTP 요청을 보냅니다:
GET /CanIDisableSecurity HTTP/1.1
서비스가 200을 반환하면, 플러그인은 호스트 페이지가 해당 호스트명에 대한 완전한 접근 권한을 가지도록 허용합니다. 이는 보안 취약점이 될 수 있습니다. 왜냐하면 사용자가 제어하는 호스트와 그렇지 않은 호스트 간에 전환되는 rbndr 호스트명을 지정할 수 있기 때문입니다. 플러그인은 해당 서비스가 일반적으로 사전 점검을 허용하지 않더라도 임의의 IP 주소(예: 내부 서비스 또는 localhost)에 대한 완전한 접근을 허용할 수 있습니다.
이것이 비현실적으로 들릴 수 있지만, 과거 Adobe Flash, Oracle Java 및 많은 다른 제품들이 정확히 이렇게 작동했으며, 여전히 많은 다른 제품들이 그렇게 작동하고 있습니다.
Adobe가 Flash에서 이 문제를 해결하기 위해 시도한 방법은 여기에서 확인할 수 있습니다. https://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html
이러한 공격에 취약한 소프트웨어의 경우, rbndr은 /etc/hosts를 수정하거나 자체 네임서버를 설정할 필요 없이 테스트할 수 있는 쉬운 방법입니다. 소프트웨어가 결과를 호스트명과 IP 주소가 아닌 호스트명에만 연결한다면, 모든 IP 주소에 대한 접근 권한을 부여받을 수 있습니다.
호스트명 형식은 간단합니다:
<16진수 IPv4>.<16진수 IPv4>.rbndr.us
하지만 원한다면 다음 웹사이트를 사용하여 점으로 구분된 쿼드(dotted quad) 형식에서 변환할 수 있습니다:
https://lock.cmpxchg8b.com/rebinder.html
예를 들어, 127.0.0.1과 192.168.0.1 사이를 전환하려면 각각을 더블워드로 인코딩한 후 다음과 같이 사용합니다:
7f000001.c0a80001.rbndr.us
테스트해 봅시다:
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 192.168.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 192.168.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 192.168.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 127.0.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 127.0.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 192.168.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 127.0.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 127.0.0.1
$ host 7f000001.c0a80001.rbndr.us
7f000001.c0a80001.rbndr.us has address 192.168.0.1
보시다시피, 서버는 주소 중 하나를 무작위로 반환합니다. 다음과 같은 작업을 수행할 수 있습니다 (의사 코드):
// 내가 제어하는 주소로 확인될 때까지 계속 호출하여 접근 권한을 얻음
while (AllowUntrustedAccesss("7f000001.c0a80001.rbndr.us") != true)
;
// 접근 권한 획득, 이제 리바인딩될 때까지 대기
while (ConnectToPort("7f000001.c0a80001.rbndr.us", 123) != true)
;
// 이제 localhost가 보안 축소에 동의하지 않았음에도 localhost:123에 접근 가능
SomethingEvil();