Cloudflare에서는 새로운 보안 취약점에 대해 알게 되었을 때 빠르게 두 가지의 개별 문제에 대한 답을 마련하기 위해 여러 팀을 불러 모았습니다. 첫 번째 질문은 '고객의 인프라를 보호하기 위해 무엇을 할 수 있는지'이며 두 번째 질문은 '당사의 환경을 안전하게 유지하기 위해 무엇을 할 수 있는지'입니다. 어제인 2021년 12월 9일에 일반적으로 사용되는 Java 기반 로깅 패키지인 Log4j의 심각한 취약점이 공개적으로 드러났을 때, 당사의 보안 팀들은 첫 번째 질문에 대응할 수 있도록 돕고 두 번째 질문에 답하기 위해 즉시 조치를 시작했습니다. 이 포스팅에서는 두 번째 질문을 살펴보고자 합니다.

개별 블로그 포스팅에서 이 취약점이 작동하는 방법에 대한 세부 정보를 다룹니다(Log4j2 취약점 내부(CVE-2021-44228)). 다만 요약하자면 이 취약점을 통해 공격자는 원격 서버에서 코드를 실행할 수 있습니다. 널리 사용되는 Java와 Log4j로 인해 이는 HeartbleedShellShock 이후로 인터넷에서 가장 심각한 취약점이 될 것으로 예상합니다. 취약점은 CVE-2021-44228로 등록되었습니다. CVE 설명에 따르면 이 취약점은 Log4j2 <=2.14.1에 영향을 주며 2.15에 패치되었습니다. 추가적으로 이 취약점은 log4j 1.x의 모든 버전에 영향을 주지만 중단되었으며 수정할 수 없는 다른 보안 취약점을 가지고 있습니다. 2.15로 업데이트하는 것을 권장해 드립니다. 고객을 보호하기 위한 당사의 WAF 규칙 업데이트에 관한 내용은 이 포스팅(CVE-2021-44228 - Log4j RCE 0-day mitigation)에서 확인하실 수 있습니다.

사고 경과

사고에 대응할 때마다 당사에서 맨 먼저 하는 일은 해당 상황의 맥락 내에서 검토하고 이해할 수 있도록 이벤트의 타임라인을 작성하는 것입니다. 해당 상황에서 당사가 작성한 타임라인의 일부는 다음과 같습니다.

  • 2021-12-09 16:57 UTC - Developers.cloudflare.com에서 Log4j RCE에 대한 Hackerone 보고서를 수신함
  • 2021-12-10 09:56 UTC - 첫 번째 WAF 규칙이 Cloudflare Specials 룰셋으로 전송됨
  • 2021-12-10 10:00 UTC - 정식 엔지니어링 사고가 시작되었으며 Log4j 패치가 필요한 영역을 확인하기 위한 작업을 시작함
  • 2021-12-10 10:33 UTC - 취약점을 완화하기 위해 패치와 더불어 Logstash를 배포함.
  • 2021-12-10 10:44 UTC - 두 번째 WAF 규칙이 Cloudflare 관리 규칙의 일부로 활성화됨
  • 2021-12-10 10:50 UTC - 취약점을 완화하기 위한 패치와 더불어 ElasticSearch이 재시작이 시작됨
  • 2021-12-10 11:05 UTC - ElasticSearch 재시작이 완료되었으며 취약점이 더 이상 존재하지 않음
  • 2021-12-10 11:45 UTC - Bitbucket이 패치되었으며 취약점이 더 이상 존재하지 않음
  • 2021-12-10 21:22 UTC - 재현할 수 없었기에 정보 제공용으로 Hackerone 보고서가 종료됨

내부 영향 해결

모든 소프트웨어 취약점을 다룰 때 중요한 질문이 있습니다. 이는 이러한 특정 사례에서 모든 회사가 답해야 하는 디음과 같은 아주 어려운 질문입니다. 취약한 소프트웨어가 실제로 실행되는 모든 위치가 어디에 있나요?

취약점이 전 세계를 대상으로 하나의 회사에서 허가를 받은 등록 상표가 붙어 있는 하나의 소프트웨어에서 발생했다면 답은 쉽습니다. 해당 소프트웨어만 찾으면 됩니다. 하지만 이 사례에서는 훨씬 더 어려웠습니다. Log4j는 널리 사용되는 소프트웨어지만 Java 개발자가 아닌 사람에게는 익숙한 소프트웨어가 아닙니다. 당사의 첫 번째 조치는 어떤 소프트웨어 구성 요소가 이러한 문제에 있어서 취약한지 판단하기 위해 JVM에서 실행하고 있는 소프트웨어의 모든 인프라 위치를 다시 확인하는 것이었습니다.

중앙화된 코드 저장소를 통해 JVM에서 실행하고 있는 모든 소프트웨어의 인벤토리를 작성할 수 있었습니다. 우리는 이 정보를 사용하여 우리가 가지고 있는 각각의 개별 Java 응용 프로그램, 그 응용 프로그램이 Log4j를 포함하는지 여부, 어떤 버전의 Log4j가 여기에 컴파일되었는지 등을 조사하고 판단했습니다.

우리는 ElasticSearch, LogStash, Bitbucket에 2.0~2.14.1 버전의 취약한 Log4j 패키지의 인스턴스가 포함되어 있음을 발견했습니다. 이 문제를 해결하기 위해 공식 Log4j 보안 문서에서 설명하는 완화 전략을 사용할 수 있었습니다. Log4j의 각 인스턴스에 대해 다음과 같은 클래스패스에서 JndiLookup 클래스를 제거했습니다.

zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

또는 완화 시스템 속성을 다음 log4j 구성에 설정했습니다.

log4j2.formatMsgNoLookups

패키지의 새로운 버전이 출시되기를 기다리는 동안 이러한 전략을 통해 패키지의 문제를 빠르게 완화할 수 있었습니다.

외부 보고서 검토

취약한 소프트웨어가 실행되는 내부 위치 목록을 작성하기도 전에 당사의 버그 바운티 프로그램인 HackerOne에서 작성한 외부 보고서와 당사가 위험한 상태에 있을지도 모른다고 알린 GitHub의 공개 포스팅을 확인하기 시작했습니다.

Cloudflare가 취약하고 손상되었음을 나타내는 보고서를 최소 두 개 찾았습니다. 다음 스크린샷은 이러한 보고서 중 하나의 내용입니다.

이 예시에서는 https://developer.cloudflare.com에서 호스팅하고 있는 당사의 개발자 문서를 대상으로 합니다. 오른편에서는 공격자가 당사의 서버로 전송한 페이로드에 대해 수신한 DNS 쿼리를 보여줍니다. 하지만 여기에 표시된 IP 주소는 173.194.95.134입니다. 이는 Google에서 소유하는 IPv4 서브넷(173.194.94.0/23)의 일부입니다.

Cloudflare의 개발자 문서는 Cloudflare Worker로 호스팅하고 있으며 정적 자산만 다룹니다. 저장소는 공개됩니다. Worker는 여기에서 보이는 것처럼 Google의 분석 라이브러리에 의존합니다. 따라서 공격자가 Cloudflare에서가 아닌 Google 서버에서 요청을 수신한 것으로 추측합니다.

당사의 백엔드 서버는 Workers에서 로깅을 수신하지만 인터넷 호출을 방지하는 강력한 쿠버네티스 출구 정책을 사용하므로 취약점 공격은 이러한 인스턴스에서 가능하지 않습니다. 유일하게 허용되는 통신은 큐레이션 된 내부 서비스 집합으로 보내는 것입니다.

추가 정보를 수집하는 과정에서 당사의 취약점 공개 프로그램에서 비슷한 보고서를 수신했을 때 리서치 도구에서는 문제를 재현할 수 없었습니다. 이로 인해 타사 서버임을 의심하는 가설을 확실시할 수 있었으며 이들이 문제를 해결했을 수도 있습니다.

Cloudflare가 손상되었나요?

위에서 설명한 소프트웨어 버전을 실행하는 동안 당사의 대응 속도와 심층 방어 접근법으로 인해 Cloudflare가 손상되지 않았다고 생각합니다. 이를 검증하기 위해 큰 노력을 기울였으며 해당 취약점에 대한 모든 것을 파악할 때까지 계속해서 노력하겠습니다. 다음은 그러한 당사 노력의 일부입니다.

취약한 소프트웨어가 실행되고 있는 모든 맥락을 평가 및 분리하고 이를 수습하기 위해 이러한 인스턴스 중 어느 것이라도 취약점 공격을 당했는지 분석하기 위해 별도의 업무 흐름을 시작했습니다.  당사의 감지와 대응 방법은 산업 표준 사고 대응 관례에 따르며 자산의 손상 여부를 확인하기 위해 철저하게 배포되었습니다. 다음에서 설명하는 동시다발적인 접근법을 사용했습니다.

내부 데이터 검토

당사의 자산 인벤토리 및 코드 스캐닝 도구를 통해 Apache Log4j에 의존하는 모든 응용 프로그램 및 서비스를 확인할 수 있었습니다. 이러한 응용 프로그램을 검토하고 필요할 경우 업데이트하는 동안 이러한 서비스와 호스트를 꼼꼼하게 스캔했습니다. 특히 CVE-2021-44228에 대한 취약점 공격은 로그 메시지와 매개변수의 특정 패턴을 기반으로 합니다( 예: \$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+ ). 영향을 받았을지도 모르는 각 서비스에 대해 모든 취약점 공격 시도를 밝히기 위해 로그 분석을 실행했습니다.

네트워크 분석 검토

네트워크 분석을 통해 의심스러운 네트워크 행동을 식별할 수 있습니다. 이러한 행동은 당사의 인프라를 대상으로 한 취약점 공격 시도 및 실제 취약점 공격을 나타낼 수 있습니다. 다음을 식별하기 위해 당사의 네트워크 데이터를 면밀히 조사했습니다.

  1. 의심스러운 인바운드 및 아웃바운드 활동
    의심스러운 인바운드 및 아웃바운드 연결을 분석하여 당사의 환경을 모두 살펴보고 활성 상태인 손상 징후를 나타내는 시스템의 존재 여부를 식별할 수 있었습니다.
  2. 목표 시스템 및 서비스
    네트워크 데이터를 대상으로 패턴 분석을 사용하여 위협 액터의 대상이 된 시스템과 서비스를 발견했습니다. 이를 통해 자산 인벤토리에 대해 상관관계가 있는 검색을 수행할 수 있었습니다. 또한 이러한 컴퓨터가 취약점에 노출되었거나 현재 취약점 공격을 당하고 있는지를 결정할 수 있도록 각 호스트를 세부적으로 검토했습니다.
  3. 네트워크 표시기
    이전에 언급한 분석을 통해 다양한 위협 액터의 인프라에 대한 인사이트를 얻었으며 이 취약점에 대한 공격 시도에 사용된 네트워크 표시기를 찾았습니다. 이러한 표시기에 대한 아웃바운드 활동은 Cloudflare Gateway에서 차단되었습니다.

엔드포인트 검토

로그 분석과 네트워크 분석 작업 흐름을 상호 연관시켜 엔드포인트 분석을 보완할 수 있었습니다. 이러한 두 가지 분석에서 얻은 결과를 활용해서 잠재적으로 영향을 받을 수 있는 추가 시스템을 식별하고 활성 상태인 손상의 징후에 대해 개별 엔드포인트를 분석하기 위한 엔드포인트 스캐닝 기준을 만들 수 있었습니다. 사용한 기술은 다음과 같습니다.

시그니처 기반 스캐닝

당사에서는 현재 취약점에 대한 공격이 발생하면 알리는 맞춤형 Yara 감지 규칙을 배포하고 있습니다. 이러한 규칙은 당사의 모든 인프라에서 실행되고 있는 엔드포인트 감지 및 응대 에이전트와 SIEM(Security Information and Events Management) 도구에 배포될 예정입니다.

변칙 프로세스 실행 및 지속성 분석

Cloudflare에서는 계속해서 엔드포인트 프로세스 이벤트를 당사의 인프라에서 수집하고 분석합니다. 당사에서는 두 번째 스테이지 취약점 공격 다운로드, 변칙 자식 프로세스 등과 같은 취약점 공격 사후 기술에 대한 탐색을 위해 이러한 이벤트를 사용했습니다.

이러한 모든 방식을 사용했지만 손상의 흔적을 찾을 수 없었습니다.

타사 위험

위 분석에서는 당사에서 생성한 코드와 데이터 검토를 중점적으로 다뤘습니다. 대부분의 회사와 같이 우리도 타사에서 허가를 받은 소프트웨어에 의존합니다. 이러한 문제에 대해 자체적인 조사를 시작했을 때 영향을 받았는지를 알아보기 위해 사내 정보 기술 팀과 협업하여 모든 주요 타사 공급자와 모든 서브 프로세서의 목록을 만들었습니다. 공급자의 응답을 수신하여 현재 검토하고 있습니다. 이러한 취약점으로부터 영향을 받는, 중요하다고 판단되는 모든 공급자는 완전히 복구될 때까지 비활성화되고 차단될 예정입니다.

당사의 심층 방어 접근법이 효과를 발휘했다는 확인

이 사고에 대해 대응하면서 심층 방어 접근법이 효과를 발휘한 여러 위치를 찾을 수 있었습니다.

  1. 아웃바운드 트래픽 제한

콜홈 능력을 제한하는 것은 취약점 공격을 훨씬 더 어렵게 만드는 킬 체인의 필수적인 부분입니다. 앞서 언급한 것처럼 우리는 쿠버네티스 네트워크 정책을 사용하여 당사의 배포에서 인터넷으로의 출구를 제한하고자 합니다. 이와 관련해서, 이러한 제한은 공격의 다음 스테이지를 방지하고 공격자가 제어하는 리소스와의 네트워크 연결을 끊습니다.

외부와 접촉하는 당사의 모든 서비스는 Cloudflare에서 보호합니다. 이러한 서비스의 오리진 서버는 인증된 오리진 풀을 통해 설정되었습니다. 이는 인터넷에 직접 노출된 서버가 없음을 뜻합니다.

2.   Cloudflare 보호를 위한 Cloudflare 사용

당사의 내부 서비스는 모두 Zero Trust 제품인 Cloudflare Access를 통해 보호됩니다. 따라서 당사에서 확인한 제한된 공격 표면을 패치한 후에는 Cloudflare 시스템 및 Access를 이용하는 고객에 대한 모든 취약점 공격 시도는 공격자에게 인증을 요구합니다.

Cloudflare WAF 제품 배포는 Cloudflare를 사용하여 Cloudflare를 보호하기 위한 노력의 일환이므로 당사는 고객을 보호하기 위해 진행했던 모든 작업으로부터 혜택을 받았습니다. 이러한 취약점으로부터 보호하기 위해 작성된 모든 새로운 WAF 규칙은 기본 조치인 차단으로 업데이트되었습니다. WAF이 배포된 모든 고객과 같이 당사는 이제 자체적으로 어떠한 추가 작업을 하지 않고도 보호를 받고 있습니다.

결론

이 어려운 상황에 대한 당사의 대응이 계속되는 동안 우리의 노력으로 작성된 이 개요가 다른 사람들에게도 도움이 되었으면 좋겠습니다. Cloudflare 안팎에서 보내주신 모든 지원에 감사드립니다.

이 블로그에 기여해 주신 Evan Johnson, Anjum Ahuja, Sourov Zaman, David Haynes, Jackie Keith에게도 감사의 마음을 전합니다.