예시: Log4Shell 보안 악용 감지

보안 취약점 CVE-2021-44228CVE-2021-45046Apache Log4j 라이브러리 버전 2.0~2.15에서 공개되었습니다. Apache Log4j 유틸리티는 요청 로깅에 흔히 사용되는 구성요소입니다. Log4Shell이라고도 부르는 이 취약점은 Apache Log4j 버전 2.0~2.15을 실행하는 시스템을 손상시켜서 공격자가 임의로 코드를 실행할 수 있게 해줍니다.

이 취약점은 Cloud Logging 또는 타사 애플리케이션의 로그를 수집하기 위해 Cloud Logging에서 제공되는 에이전트에 영향을 주지 않습니다. 하지만 Log4j 2를 사용하는 경우 서비스에 영향을 줄 수 있습니다.

Cloud Logging을 사용해서 가능한 공격을 식별할 수 있습니다. 이 문서에서는 다음 작업을 수행하는 방법을 설명합니다.

  • 로그 탐색기를 이용해서 로그를 쿼리하여 Log4j 2 취약점을 악용하려는 기존 시도를 확인합니다.
  • Google Cloud Armor 보안 정책 및 IAP(Identity-Aware Proxy) 액세스 제어와 같은 사용 설정된 완화 기법이 Log4j 2 악용 시도를 차단하여 올바르게 구성되고 예상대로 작동하는지 확인합니다.
  • 로그에 가능한 악용 메시지가 기록될 때 이를 알려주는 알림 정책을 만듭니다.

Google Cloud의 Log4j 2 보안 설명서에서 현재의 Google Cloud 제품 및 서비스 평가를 확인합니다. 미국 국립 표준 기술 연구소(NIST)에서 CVE-2021-44228에 대한 취약점 보고서를 읽고 노출 상태를 평가할 수 있습니다.

Cloud Logging 감지

Cloud Logging 쿼리 결과에는 로그 버킷에 이미 저장되어 있고 사용자가 지정한 보관 한도 내에 있는 로그만 포함됩니다. 대부분의 Google Cloud 서비스에는 기본적으로 로그가 사용 설정되어 있지만 사용 중지되었거나 제외된 로그는 쿼리에 포함되지 않습니다. 해당 환경에서 로그를 설정하여 해당 환경으로 가시성을 확장하는 것이 좋습니다.

HTTP(S) 부하 분산기를 사용하는 경우 Cloud Logging에서 제공되는 요청 로그에 대해 로깅을 사용 설정해야 합니다. 마찬가지로 Apache 또는 NGINX와 같은 웹 서버가 VM에서 실행되지만 작업 에이전트 또는 Logging 에이전트를 설치하지 않았으면 Cloud Logging 내에서 해당 로그에 액세스할 수 없습니다.

로그 탐색기를 사용하여 서비스에서 Log4j 2 취약점을 악용하는 잠재적 공격을 감지할 수 있습니다. Cloud Logging을 사용해서 서비스에 대한 요청을 로깅하는 경우 사용자 제작 콘텐츠가 포함된 httpRequest 필드에서 잠재적 악용 사례를 확인할 수 있습니다.

httpRequest 필드의 값에는 ${jndi:ldap://와 같은 문자열이 포함될 수 있지만, 이러한 취약점이 악용되는 많은 변형이 존재합니다. 예를 들어 감지되지 않도록 이스케이프 또는 Unicode를 사용하는 여러 방법이 있습니다. 이러한 변형 방법을 모두 보여주는 것은 아니더라도 다음 문자열은 시스템에 대한 악용 시도를 나타내는 몇 가지 일반적인 예시를 보여줍니다.

${jndi:
$%7Bjndi:
%24%7Bjndi:
${jNdI:ldAp
${jndi:${lower:l}${lower:d}${lower:a}${lower:p}:
${${lower:j}${lower:n}${lower:d}i:
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}

로그 탐색기에서 일부 가능한 악용 문자열을 스캔하는 쿼리를 만들 수 있습니다. 예를 들어 다음 쿼리는 HTTP(S) 부하 분산기 요청 로그에서 httpRequest 필드의 ${jndi: 문자열에 대해 여러 가지 난독화된 변형 형태를 찾으려고 시도합니다. 쿼리에 사용된 정규 표현식은 모든 변형 형태를 감지하지 않으며, 거짓양성으로 이어질 수도 있습니다.

resource.type="http_load_balancer"
httpRequest.requestUrl=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR
httpRequest.userAgent=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR
httpRequest.referer=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)"

이전 쿼리를 사용하여 resource.type 값을 변경하여 다른 서비스의 요청 로그를 스캔할 수 있습니다.

스캔할 로그 볼륨이 많을 때는 이전 쿼리를 완료하는 데 시간이 오래 걸릴 수 있습니다. 쿼리를 더 빠르게 실행하려면 resource.type, resource.labels, logName과 같은 색인 처리된 필드를 사용해서 특정 서비스 또는 로그 스트림 집합으로 쿼리 범위를 좁힐 수 있습니다.

일치하는 로그 항목이 발견되었더라도 손상 시도가 성공했음을 의미하지는 않습니다. 문제가 감지되면 조직의 사고 대응 프로세스를 따르는 것이 좋습니다. 일치 항목이 있다는 것은 프로젝트 또는 워크로드 내에서 누군가 취약점을 악용하기 위해 프로브하고 있음을 나타냅니다. 또는 애플리케이션이 HTTP 요청 필드에서 ${jndi:와 같은 패턴을 사용하는 경우에는 거짓양성일 수도 있습니다. 로그를 다시 검토해서 이 패턴이 정상적인 애플리케이션 동작이 아닌지 확인해야 합니다. 해당 환경에 적합하도록 쿼리를 세분화해야 합니다.

잘못된 IP 주소 검색

일치하는 결과가 발견되었고 이러한 요청을 전송하는 원격 IP 주소로 데이터를 집계하려면 로그 탐색기에서 remoteIp 필드를 로그 필드 창에 추가합니다. remoteIp 필드를 추가하려면 일치하는 로그 항목의 필드 값을 클릭하고 다음 스크린샷과 같이 로그 필드 창에 필드 추가를 선택합니다.

'로그 필드' 창에 'remoteIp' 필드를 추가하여 가장 일치하는 요청을 전송하는 IP 주소를 확인합니다.

이제 로그 필드 창에서 일치하는 요청을 전송하는 최상위 원격 IP 주소를 확인할 수 있습니다.

최상위 제거 IP 주소가 로그 탐색기에 표시됩니다.

이를 통해 이러한 Log4j 2 취약점 악용 스캔의 출처를 분석할 수 있습니다. 이 중 일부는 Web Security Scanner와 같이 구성한 애플리케이션 취약점 스캔 도구의 적법한 스캔일 수 있습니다. Security Command Center에서 Web Security Scanner를 사용하는 경우 Web Security Scanner에서 사용하는 고정 IP 주소 범위를 기록해 둡니다.

대상 애플리케이션 검색 및 완화 기술 확인

또한 대상 애플리케이션을 집계하고 악성 요청이 실제로 애플리케이션에 도달했는지 여부를 식별해야 할 수 있습니다. Google Cloud Armor의 보안 정책 또는 IAP(Identity-Aware Proxy)의 액세스 제어를 사용하여 완화 기술을 사용 설정한 경우 HTTP(S) 부하 분산기 로그에 로깅된 정보에서 예상대로 작동하는지 확인할 수도 있습니다.

먼저 로그 필드 창에 대상 애플리케이션을 추가하려면 로그 항목 결과 중 하나를 선택하고 resource.labels를 펼치고 resource.labels.backend_service_name 필드 값을 클릭합니다. 그런 다음 로그 필드 창에 필드 추가를 선택합니다.

이제 Log4j 2 악용 스캔에서 대상이 되는 상위 애플리케이션 또는 백엔드 서비스를 확인할 수 있습니다. 이러한 악용 시도가 백엔드 서비스에 도달했는지 확인하려면 HTTP(S) 부하 분산기에 의해 채워진 jsonPayload.statusDetails 필드를 사용하여 요청이 백엔드로 프록시 처리되었는지 아니면 IAP 또는 Google Cloud Armor와 같은 서비스에 의해 성공적으로 차단되었는지 확인합니다. 로그 항목 결과에서 jsonPayload.statusDetails 필드 값을 클릭하고 로그 필드 창에 필드 추가를 선택합니다.

이제 로그 필드 창에서 요청이 처리된 방식을 확인할 수 있습니다.

가장 많이 대상이 된 백엔드 서비스가 로그 탐색기에 표시됩니다.

이 예시에서 백엔드 서비스에 사용 설정된 경우 사용자 ID를 확인하고 액세스를 허용하기 전에 컨텍스트를 사용하는 IAP에서 대부분의 요청을 차단했습니다. 이러한 IAP 차단 요청은 statusDetailshandled_by_identity_aware_proxy로 설정합니다. 또한 Google Cloud Armor를 백엔드 서비스에 연결된 올바른 보안 정책과 함께 사용하면 모든 Google Cloud Armor 차단 요청은 statusDetailsdenied_by_security_policy로 설정합니다. 사전 구성된 새 cve-canary WAF 규칙을 Google Cloud Armor 보안 정책에 적용하는 방법에 대한 자세한 내용은 Apache Log4j 취약점을 완화하는 Google Cloud Armor WAF 규칙을 참조하세요.

실제로 백엔드 서비스에 도달하는 허용된 요청을 필터링하려면 로그 필드 창의 statusDetails에서 response_sent_by_backend를 선택합니다. 이러한 악용 시도를 방지하려면 이러한 백엔드 서비스에 IAP를 사용 설정하고 또는 사전 구성된 cve-canary WAF 규칙으로 Google Cloud Armor 보안 정책을 적용하는 것이 좋습니다.

로그 기반 알림 만들기

서비스에서 영향을 받는 로그를 찾는 쿼리를 설계한 다음에는 이 쿼리를 사용해서 새로운 로그 항목이 쿼리와 일치할 때 알림을 표시하는 로그 기반 알림을 만들 수 있습니다. 이 알림은 조직의 보안 운영 센터(SOC) 또는 해당 사고 대응팀으로 전달될 수 있습니다.

로그 기반 알림 만들기에 대한 자세한 내용은 로그 기반 알림 만들기(로그 탐색기)를 참조하세요. 알림을 만들 때는 예시에 지정된 쿼리 대신 악용 문자열에 대해 사용자의 쿼리를 사용해야 합니다.

로그 기반 측정항목에 대해 알림 정책 만들기

가능한 악용 시도가 로깅되는 엔드포인트 또는 서비스를 모니터링하려면 로그 기반 측정항목에서 알림 정책을 만듭니다.

  1. 로그에서 가능한 악용 문자열이 발견된 경우를 세는 로그 기반 측정항목을 만듭니다. 예를 들어 Google Cloud CLI를 사용하여 이러한 측정항목을 만들 수 있습니다.

    gcloud logging metrics create log4j_exploits \
    --description="Detect log4j exploits" \
    --log-filter='httpRequest.requestUrl=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR httpRequest.userAgent=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)" OR httpRequest.referer=~"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)"'
    

    로그 기반 측정항목 만들기에 대한 자세한 내용은 카운터 측정항목 구성을 참조하세요.

  2. 선택한 항목 개수에 도달할 때 알림을 표시하는 알림 정책을 만듭니다. 알림 정책 설정에 대한 자세한 내용은 카운터 측정항목에 대한 알림 정책 만들기를 참조하세요.

다음 단계