이미 ISP 단에서 적절한 조치를 취했으리라 생각하고 별달리 언급하진 않았습니다만, 오늘도 해외에서는 계속 업데이트가 올라오고 활발히 논의되는지라 국내에서도 한 번 정리해야 될 것 같다는 생각이 들었습니다.

다들 아시다시피 DNS는 도메인을 IP 주소로 변환하는 책임을 지고 있으며 인터넷이 정상적으로 동작하는데 아주 핵심적인 역할을 맡고 있습니다. DNS 캐시 포이즈닝은 캐싱 네임서버의 캐시에 조작된 DNS 정보를 집어넣는 기법을 말합니다. 별로 새로운 개념도 아닙니다. 오래 전부터 DNS 프로토콜 자체의 취약점을 다루는 문서도 많이 있었고, 널리 사용되는 DNS 구현체의 결함을 다룬 문서도 많이 있었습니다.

제가 예전에 봤던 문서 중 잘 정리된 것으로는 아래 2개가 있었습니다.

그렇지만 당장 전문을 번역하기는 힘들고, 보기에도 만만치 않을테니 간단히 요약을 하자면 아래와 같습니다.

불충분한 쿼리 ID 공간

DNS 프로토콜은 16비트의 쿼리 ID를 포함하고 있습니다. 16비트는 매우 작은 크기라, 프로토콜 명세대로 정확히 구현하고 강력한 난수 생성기를 사용한다고 한들 평균적으로 32768번만 시도해보면 ID를 예측할 수 있습니다. 당연히 제대로 구현하지 않은 경우는 더 적은 수의 시도만으로도 예측이 가능합니다. Amit Klein은 2007년에 아래와 같은 취약점을 조사했습니다.

초기 DNS 서버들은 심지어 쿼리 ID로 순차적으로 증가하는 값을 사용해서 아주 쉽게 예측이 가능했었습니다. 지금은 각 벤더에서 랜덤한 값을 사용하도록 패치되어 있지만 그럼에도 불구하고 ID 공간 자체가 협소하기 때문에 여전히 공격에 취약한 것입니다.

응답을 대기하고 있는 여러 개의 요청

일부 DNS 구현체들은 하나의 리소스 레코드 (RR)를 대상으로 여러 개의 쿼리를 보낼 수 있게 되어있는데, 이렇게 되면 그 RR을 기다리는 여러 개의 쿼리가 생성되게 됩니다. 이런 조건은 성공 확률을 아주 높여주는 결과를 가져오게 됩니다. (birthday attack) 많은 벤더들이 이미 이 이슈를 다루는 패치를 내놓았습니다. 역시 근본적인 해결은 아닙니다.

쿼리 생성에 사용되는 출발지 포트가 고정되어 있음

일부 DNS 구현체들은 시작할 때 임의의 포트를 할당한 다음, 모든 쿼리에 그 포트를 사용합니다. 어떤 구현에서는 아예 53/udp 포트로 고정되어 있기도 합니다. 적어도 출발지 포트를 랜덤하게 해주면 대략 16비트의 공간을 추가하는 셈이기 때문에 확률적으로 공격이 성공하기가 훨씬 어려워집니다. 여전히 공격이 가능하긴 하지만 현실적으로 고정된 포트에 비하면 상당히 보완이 되는 셈입니다.

리소스 레코드를 이용한 공격 시나리오

앞서 언급한 것처럼 지금까지 잘 알려진 DNS 프로토콜 공격은 쿼리 ID를 예측하고 먼저 응답을 보내어서 잘못된 IP를 캐싱하도록 한다는 것이었지만, 이번에 이슈가 된 것은 리소스 레코드(RR)를 이용해서 네임서버를 바꾸는 공격이 쉽게 가능하다는 것입니다.

  1. 공격하려고 하는 사이트의 서브도메인을 조회할 DNS를 선택합니다. 가령 random.example.com 이 될 수 있겠지요. 존재하지 않는 서브도메인을 아무거나 사용하면 됩니다.
  2. 이 서브도메인은 원래 없던 도메인이니 DNS 서버는 IP 주소를 알아내는 과정을 거치게 됩니다. 정상적인 경우에는 ns.example.com이 정확한 쿼리 ID로 존재하지 않는 서브도메인이라고 응답할 것입니다. 이 과정에서 공격자는 여전히 쿼리 ID를 추측해서 ns.example.com보다 더 빨리 답을 제시하려고 시도할 수 있습니다.
  3. 공격자는 2단계를 반복하면서 서브도메인을 랜덤하게 계속 바꿔버립니다. 쿼리 ID 공간 자체가 얼마 안 되다보니 이렇게 계속 쿼리를 시도하게 되면 어느 순간 쿼리 ID를 맞추고 진짜 네임서버보다 먼저 응답할 수 있게 됩니다. 그러면 공격자는 example.com의 DNS 리소스 레코드를 업데이트할 수 있게 되면서 네임서버를 공격자의 서버로 돌릴 수 있게 되는 것입니다.

공개된 익스플로잇

대처 방안

지금 당장 DNS 서버를 패치하시기 바랍니다. 그리고 Securing an Internet Name Server 문서를 참고하셔서 접근 제한 정책을 설정하시기 바랍니다. DNS 쿼리가 UDP로 이루어지기 때문에 공격자가 가짜 출발지 IP를 사용한 패킷을 대량으로 보낼 수 있으므로, 네트워크 필터링이 반드시 필요합니다. 벤더는 Measures for making DNS more resilient against forged answers 페이지를 참고해서 출발지 포트 랜덤화 등을 구현해야 합니다.

참조 문서