AWS 기술 블로그
인터넷에 노출된 자격증명 탐지하기
1. 서론
이제 클라우드 서비스는 “New Normal” 이 된지 오래입니다. 클라우드라는 용어는 더 이상 생소하고 낯선 단어가 아니며 IT(Information Technology) 업계 종사자라면 누구나 알고 있고 실제 업무 환경에서 다양한 형태로 활용하고 있는 서비스입니다. 이러한 흐름에 맞춰 수 많은 기업들이 다양한 유형의 클라우드 기반 서비스를 이용하고 있으며 자사의 중요 워크로드를 확장 가능하고 안전한 클라우드 인프라상에서 서비스를 운영하기 위해 AWS 서비스를 이용하고 있습니다.
수많은 개인 및 기업이 클라우드 서비스를 이용하고 긴 시간 서비스를 구축/운용하면서 각 조직에는 클라우드를 보다 효율적이고 안전하게 운영할 수 있는 기술력이 예전에 비해 월등하게 개선되었습니다. 하지만, 많은 기업들이 클라우드 환경에서의 보안을 위해 조직의 역량을 개선하고 다양한 보안 모범사례를 적용하고 있는 것에 반해 일부 개인 및 조직에서는 여전히 기본적인 보안 모범사례를 지키지 않아 데이터 유출이나 랜섬웨어 감염 혹은 컴퓨팅 자원의 탈취와 같은 사이버 위협에 노출되어 있는 것이 현실이기도 합니다.
이러한 사이버 위협은 다양한 원인에 의해 발생될 수 있지만 가장 흔하게 발생되는 원인은 “장기보안 자격증명 사용” 을 사용한다거나 “부적절한 API 토큰 관리”, “자격증명 노출” 과 같은 관리자의 부적절한 설정관리에 있다고 볼 수 있습니다. 이 블로그에서는 클라우드 이용환경에서 발생하는 여러가지 사이버 보안 위협 중 가장 대표적이고 흔한 위협 중 하나인 “노출된 자격증명” 을 탐지하는 방안에 대해 살펴보고자 합니다.
2. 자격증명의 노출 유형
노출된 자격증명을 탐지하는 방법을 살펴보기에 앞서, 일반적으로 흔하게 발생하는 자격증명의 종류와 자격증명이 외부에 노출되는 유형을 먼저 살펴보겠습니다.
2.1 “공개” 설정된 코드저장소
가장 흔하게 발생하는 자격증명 유출 사고의 원인 중 하나로 지목되는 것이 바로 조직에서 사용하는 코드저장소의 부적절한 관리입니다. Github, Gitlab, Bitbucket, AWS CodeCommit 등의 코드저장소는 개발팀에게 편리하고 효율적인 코드 관리 기능을 제공하지만, 보안을 위해 코드저장소를 “비공개”로 운영할 것을 강력히 권장합니다. 특히 자격증명을 포함한 민감한 정보가 코드에 포함되어 있다면 더욱 그렇습니다.
하지만, 자격증명을 저장하고 있는 코드저장소가 “공개” 로 설정되어 자격증명이 유출되는 사고는 지금도 꾸준하게 발생하고 있습니다. 이러한 사고의 근본 원인은 조직마다 다를 수 있지만, 공통적으로 “적절한 이력관리 부재”와 “코드저장소에 코드를 저장하기 전에 자격증명 유무를 검증하는 절차 결여”가 주요 원인 중 하나로 볼 수 있습니다.
2.2 장기보안 자격증명의 하드코딩
어플리케이션을 개발하다보면 클라우드 기반 서비스와의 연동을 위해 API를 호출할 수 있는 자격증명을 소스코드에 반영해야 하는 경우가 있습니다. 이때 개발자는 API 호출을 위한 자격증명을 코드에 반영하기 위해 다양한 옵션을 사용할 수 있습니다. 예를 들어, AWS EC2 인스턴스에서 구동되는 환경이라면 EC2 인스턴스 프로파일, 시스템 환경변수에 저장된 자격증명 정보, 또는 Access Key와 Secret Key를 소스코드에 직접 입력하는 방법 등이 있습니다.
하지만, 보안적으로 가장 피해야할 자격증명 사용방법은 소스코드에 자격증명을 직접 입력하여(하드코딩) 사용하는 방법입니다. 이 방법은 개발 과정에서 별도로 자격증명을 갱신할 필요가 없고 어떤 환경에서도 자격증명을 사용할 수 있어 편리하다고 생각할 수 있지만, 암호화되지 않은 평문 형태의 자격증명은 다음과 같은 위험을 초래할 수 있습니다:
- 외부 공격자가 코드 저장소에 대한 접근 권한을 획득한 경우
- 코드가 저장된 코드 저장소가 “공개”로 설정된 경우
- 코드에 접근 가능한 내부 위협 행위자가 있는 경우
이러한 상황에서 위협 행위자들은 손쉽게 자격증명을 획득할 수 있으며, 자격증명에 부여된 권한으로 인해 데이터 유출이나 기타 보안 사고로 이어질 수 있습니다.
2.3 잘못된 API 키 관리
어플리케이션 개발에서 API 사용은 필수적입니다. 개발자는 API 호출을 위해 자격증명을 필요로 하며, 이를 안전하게 관리하고 사용해야할 책임이 있습니다. API 호출에 사용되는 인증 토큰과 같은 API 키(자격증명) 관리 원칙에서 가장 중요한 것은 “소스코드에 자격증명을 하드코딩하지 않는 것”입니다. 그러나 소스코드에 API 키를 하드코딩하지 않는다고 해서 안전하다고 볼 수는 없습니다. 조직에서는 협업도구(Slack, Notion, Confluence 등)를 통해 API 키나 자격증명을 편하게 저장하고 사용자들 간 공유하는 사례를 종종 접할 수 있습니다.
각 조직에서는 노출 시 보안사고의 위험이 있는 각 자격증명과 API 키는 권한을 가진 사용자(예: 개발자)가 안전한 방법을 통해 접근하고 이용하도록 해야 합니다. 하지만, 조직적으로 자격증명 보안 인식이 부족하여 내부 협업도구에 API 키가 노출되어 있다면, 해킹사고 발생 시 더욱 큰 위협으로 전파될 수 있습니다. 예를 들어, 해킹을 통해 공격자가 내부 협업도구에 존재하는 API 키를 확보하게 된다면, 공격자는 래터럴 무브먼트(Lateral Movement) 기법을 통해 공격을 손쉽게 전개할 수 있습니다.
3. 노출된 자격증명 탐지방법
이러한 자격증명 노출은 비단 클라우드 환경에서만 발생하는 것은 아닙니다. 온프레미스에도 많은 권한을 가지고 있는 중요 자격증명이나 특권권한상승 문제를 일으킬 수 있는 자격증명이 외부에 노출되는 상황이 발생할 수 있습니다. 따라서, 클라우드나 온프레미스 구분없이 중요 자격증명이 외부로 노출되지 않도록 철저하게 관리하는 것이 중요합니다. 하지만, 이미 담당자의 실수 혹은 악의적인 사용자에 의해 의도적으로 노출된 자격증명이 있다면 빠른 시간에 탐지한 후 적절한 조치를 취하는 것 또한 무엇보다 중요하다고 볼 수 있습니다.
이제 노출된 자격증명을 어떻게 탐지할 수 있는지 살펴보도록 하겠습니다.
노출된 자격증명을 탐지하는 방법은 다음과 같습니다:
- 조직 내에서 사용할 도구 자체 개발
- Git-Leaks나 TruffleHog와 같은 오픈 소스를 이용하는 방법
- 코드 저장소와 같은 서비스에서 제공하는 자격증명 노출 탐지 기능을 활용하는 방법
- Cremit과 같은 전문적인 노출된 자격증명 탐지 솔루션을 이용하는 방법
이 블로그에서는 Cremit 솔루션을 이용하여 노출된 자격증명을 탐지하는 방법을 설명하겠습니다.
3.1 Cremit 솔루션 소개
Cremit 솔루션은 SaaS와 설치형 두가지 서비스로 제공되고 있습니다. 자격증명이 노출될 수 있는 서비스들과 연동할 수 있고, 노출된 자격증명을 빠르게 알려주는 서비스를 제공하고 있습니다. 발견된 자격증명에 대해 프로토콜 또는 API를 사용하여 확인(검증)을 거쳐 False Positive가 제거된 알림을 제공합니다.
그림 1. Cremit 동작 개념도
그림 2. Cremit 동작 원리
3.2 Cremit 을 이용한 노출된 자격증명 탐지
Cremit 은 다양한 기능을 제공하고 있지만 이 블로그에서는 “코드저장소에 노출된 자격증명”과 같이 코드저장소 서비스 제공자를 통해 탐지할 수 있는 노출유형이 아닌 웹서비스 제공 환경에서 자격증명이 노출되어 있는 상태를 가정하고 어떻게 조직에서 Cremit 을 이용하여 자격증명 노출 유무를 탐지할 수 있는지 살펴보도록 하겠습니다.
Cremit 계정은 https://start.cremit.io 에서 생성할 수 있고, 코드 저장소와 연동하는 기능은 현재 무료로 사용할 수 있습니다. 아래 방법은 가입된 사용자의 이용흐름을 따라갑니다.
그림 3. 연동 가능한 서비스
Github 버튼을 눌러 앱을 Github 조직 또는 개인 계정에 Cremit Scanner 어플리케이션을 설치할 수 있습니다. 이후 자격증명을 스캔할 Repository를 선택합니다.
그러면 Cremit이 해당 Repository의 커밋 히스토리를 분석하여 AWS 자격 증명을 포함한 각종 자격증명의 노출 여부를 확인합니다. 연동 이후 Cremit은 자동으로 Repository 내의 모든 파일을 스캔하기 시작합니다. 잠시 후 스캔이 완료되면 결과 화면이 나타납니다.
그림 4. 자격증명 탐지 화면
보시는 것처럼 Cremit이 ‘AWS’의 자격증명을 포함하는 코드를 발견했습니다. 이는 AWS IAM 사용자의 액세스 키가 코드에 하드코딩되어 있음을 의미합니다. 또한 발견된 자격 증명을 바탕으로 AWS API를 호출하여 해당 자격 증명의 활성화 여부를 확인할 수 있습니다. 자격 증명 활성화 여부 확인 기능은 False positive를 줄이는 데에도 도움이 됩니다. 이미 비활성화된 자격 증명이 발견되었다면, 보안 팀은 추가적인 조사 없이도 해당 자격 증명이 더 이상 위험하지 않다고 판단할 수 있기 때문입니다.
4. 자격증명 노출 탐지 후 대응방법
보안적인 측면에서 본다면 중요한 자격증명은 유출되지 않는 것이 최선이겠지만 이미 자격증명이 유출되어 악의적인 목적으로 사용되었거나 악용된 사례는 발견되지 않았더라도 이미 노출되어 있는 것을 인지한 경우라면 노출된 자격증명에 대해 적절한 대응 조치를 취하는 것 역시 아주 중요합니다. 아무리 철저한 보안 환경을 구성하고 자격증명 관리자에게 철저한 보안 교육을 진행하더라도 자격증명의 유출 사고는 발생할 수 있기 때문에 조직에서는 반드시 사고 발생 시 대응 가능한 시나리오를 준비해야 합니다.
자격증명 노출 시 대응 절차는 다음과 같이 요약할 수 있습니다.
Step 1. 노출 경로 확인
자격증명이 노출된 경로를 파악하는 것은 사고 대응 단계에서 가장 먼저 수행되어야 하는 작업입니다. 보안관리자는 이 글에 언급된 Cremit 이나 기타 도구를 사용하여 자격증명의 노출을 탐지할 수 있어야 합니다. 다양한 도구를 통해 수동 혹은 자동으로 노출된 자격증명을 식별하였다면 식별된 경로(코드저장소, 웹 서비스, 모바일 앱 등)와 연관되어 있는 주요 담당자에게 상황을 전파해야 합니다.
Step 2. 노출된 자격증명 위험도 판별
노출된 자격증명에 대한 후속 조치의 유형과 속도 등을 결정하기 위해서는 노출된 자격증명에 대한 위험도를 판별하는 것이 필요합니다. 판별된 위험도에 따라 조치 방법이나 조치 속도 등의 차이가 있을 수 있습니다.
Step 3. 노출 경로 차단
노출된 자격증명의 위험도를 결정했다면 결정된 위험도에 따라 자격증명의 노출 경로를 차단하는 작업이 수행되어야 합니다. 코드 저장소가 “공개”로 설정되어 노출되었다면 “비공개” 로 전환하거나 부적절한 API 키 관리를 통해 유출되었다면 코드의 수정 등을 수행할 수 있습니다.
Step 4. 자격증명 격리 혹은 교체
노출된 자격증명은 조직에서 어떤 위협 징후를 감지하지 못했더라도 이미 위협 행위자에게 악의적인 목적으로 사용되고 있을 수 있습니다. 따라서, 노출이 확인된 자격증명은 가능한 즉시 비활성화하고 새로운 자격증명으로 교체되어야 합니다.
Step 5. 위협 사냥
자격증명이 노출되었다면 해당 자격증명를 위협행위자가 탈취한 상황을 가정해야 합니다. 조직에서 인지 가능한 보안사고가 발생하지 않았더라도 위협행위자는 탈취한 자격증명을 이용하여 공격을 준비하고 있을 수 있습니다. 따라서, 탈취된 자격증명을 기반으로 사용 이력 등을 추적하여 잠재적 위협을 사냥해야 합니다.
Step 6 재발 방지
노출 경로를 차단하고 잠재적 위협까지 식별하여 조치하였다면 자격증명 노출사고가 재발하지 않도록 재발방지 방안을 수립하고 수행하는 것이 필요합니다.
이제 자격증명 노출/유출에 대한 각 대응 단계에서 조직이 취할 수 있는 방법에 대해 살펴보겠습니다.
4.1 노출 경로 확인
Cremit 제품 내에서도 노출 경로를 Threat 기능을 통해 판별할 수 있습니다. 하나의 코드저장소 또는 하나의 소스코드 파일에서만 노출된 경우가 있을 수 있고, 다수의 경로나 위치에서 사용되며 노출되어 있을 수 있습니다. Cremit 제품을 통해서는 자격증명을 중심으로 노출된 것을 한눈에 확인할 수 있습니다.
그림 5. 자격증명 유출 경로 확인
위의 스크린샷을 보면, ***5JMOR
로 끝나는 AWS Access Key가 노션, 컨플루언스의 탐지 테스트 문서에 존재하고, Github의 test-keys 리포지토리에 두개가 노출되어 있는 것을 확인할 수 있습니다.
참고. Cremit 서비스에 연동 가능한 서비스는 현재 크게 5개로, Github, Gitlab, Confluence, Jira, Notion과 연동할 수 있습니다.
4.2 노출된 자격증명 위험도 판별
자격증명의 종류마다 조직별로 관리하는 위험도가 다를 수 있습니다. Cremit 제품에서는 Threat Policy 기능을 사용하여 각 Secret 종류 별로 위험도를 설정할 수 있습니다.
그림 6. 위협도 판별
본 예제에서는 소스코드 저장소인 Github와 GitLab에서 발견된 Secret 중, AWS에 접근이 되는 자격증명을 High로 설정하는 예제를 보여줍니다.
4.3 노출 경로 차단
노출 경로 차단은 자격증명이 노출된 경로에 따라 아래와 같이 다양하게 수행될 수 있습니다.
4.3.1 공개된 코드저장소를 통한 노출
대부분의 코드저장소는 저장소에 대한 “공개”, “비공개” 설정을 제공합니다. “공개” 로 설정되어 있는 코드저장소에 의해 자격증명이 포함되어 있어 노출되었다면 해당 코드저장소를 “비공개” 로 전환하거나 부득이하게 “비공개” 로 전환이 불가능한 경우 노출된 자격증명 정보를 삭제해야 합니다.
4.3.2 소스코드에 하드코딩된 자격증명
소스코드에 하드코딩어 있는 자격증명이 노출된 경우에는 어플리케이션에서 자격증명을 하드코딩하는 것이 아니라 환경변수나 임시보안 자격증명을 발급받아 사용할 수 있도록 코드를 수정해야 합니다.
4.3.3 API 키의 부적절한 관리
인가된 사용자가 발급받은 API 키의 부적절한 관리로 인해 API 키가 노출된 경우에는 API 키 발급환경을 개선하여 사용자 측에서 API 키를 추출할 수 없도록 암호화하는 등의 조치가 필요합니다. SOPS(https://github.com/getsops/sops)와 같은 도구를 이용하여 환경변수에서 사용하더라도 노출될 때 암호화 된 상태를 유지하게 사용자들에게 강제하는 환경을 제공할 수 있습니다. SOPS는 AWS KMS와 쉽게 연동할 수 있습니다.
4.4 자격증명 격리 혹은 교체
노출된 자격증명은 잠재적으로 위협행위자에게 침해된 것으로 가정하고 보안조치를 수행하는 것이 필요합니다. 따라서, 자격증명의 노출을 확인한 시점에 특정 보안 사고가 발생하지 않았더라도 노출된 자격증명은 사용할 수 없도록 조치하는 것이 필요합니다.
AWS 의 Access Key/Secret Key 가 노출된 경우라면, 아래의 절차에 따라 자격증명의 비활성화 및 신규발급을 진행하시기 바랍니다.
참고. AWS 환경에서 IAM 사용자에게 발급되는 Access Key/Secret Key 를 어플리케이션에서 사용하는 것은 권고하지 않습니다. 가능하다면 IAM 역할 기반의 자격증명을 이용하도록 어플리케이션을 재구성하는 것을 권고합니다.
4.5 위협사냥
이미 노출된 자격증명은 보안 사고 유무와 관계없이 위협 사냥이 수행되어야 합니다. 즉, 노출된 자격증명을 통해 호출된 API 등을 분석하고 각 API 등을 통해 수행된 작업 내역을 파악하여 “누가/언제/어떤 서비스를 대상으로/어떤 작업을/성공 또는 실패 하였는지” 에 대한 정보를 확인해야 합니다.
AWS 의 자격증명이 노출된 경우라면 AWS CloudTrail Log 를 분석하여 이와 같은 정보를 수집할 수 있으며 이를 통해 혹시 모를 위협행위자의 침해활동이나 잠재적인 위협을 식별하여 제거할 수 있습니다.
4.6 재발방지
마지막으로 수행되어야 할 작업은 자격증명 노출 경로에 대한 재발방지입니다. 노출된 자격증명에 대해 1차적으로 자격증명을 비활성화하고 자격증명을 안전하게 사용할 수 있는 방안을 적용하였다면 유사한 서비스 이용환경에서 동일한 노출사고가 발생하지 않도록 조직의 보안 수준을 강화하는 것이 필요합니다.
이를 위해서는 다음과 같은 방안을 수행할 수 있습니다.
방안 1. 개발자가 사용하는 IDE 에서부터 자격증명의 오용을 탐지하거나 코드 작성 시 보안 모범 사례를 안내받을 수 있도록 방안을 제공합니다. AWS 에서는 Amazon CodeWhisperer 라는 생성형 AI 기반 코딩도우미 서비스를 이용하여 소스코드의 자격증명 포함 유무를 탐지할 수 있으며 작성된 코드의 보안모범 사례 준수 유무를 탐지하는 서비스를 제공하고 있습니다.
방안 2. 조직에서는 코드저장소에 코드가 저장될 때도 자격증명 포함 유무를 탐지하고 작성된 코드의 보안 수준을 점검하는 기능을 적용해야 합니다. AWS 에서는 Amazon CodeGuru 서비스를 통해 코드저장소에 저장된 코드를 스캔하여 자격증명 포함 유무를 탐지할 수 있으며 보안 모범 사례 준수 여부도 식별 가능합니다. 또한, AWS Lambda 를 사용하는 경우 Amazon Inspector 를 통해 Lambda 코드에 포함되어 있는 자격증명이 포함되어 있는지를 확인할 수 있습니다.
방안 3. 코드저장소나 대외 서비스를 통한 자격증명 노출 여부를 탐지하여야 합니다. 조직에서는 지속적으로 새로운 서비스를 개발하고 다양한 방법으로 자격증명을 이용하는 패턴이 발생하게 됩니다. 따라서, 코드저장소나 서비스 제공환경에서 발생할 수 있는 자격증명 노출 사고 탐지활동을 자동화하여 노출사고 발생 시 짧은 시간안에 탐지하여 노출사고에 대한 대응 계획이 수행될 수 있도록 하는 것이 중요합니다.
5. 결론
AWS Access Key/Secret Key 를 포함한 다양한 자격증명 관리의 중요성은 클라우드 보안에서 다른 그 무엇보다 중요하고 가장 기본 고려사항이 되었다고 볼 수 있습니다. 자격증명은 ID/Password, Access Key/Secret Key, JWT Token 등 다양한 형태로 사용될 수 있으며 위협행위자에게는 가장 탈취하고 싶은 공격 대상이기도 합니다. 따라서, 각 조직에서는 자격증명 노출 사고를 미연에 방지하기 위하여 보안 모범 사례를 준수해야 하며 혹시라도 노출 사고가 발생하더라도 자격증명 노출로 인한 위험을 최소화할 수 있는 준비가 되어 있어야 합니다. 이를 위한 준비과정에서 각 조직은 Cremit 이 제공하는 자격증명 탐지 서비스나 AWS 가 제공하는 Amazon Inspector, AWS Codeguru, AWS CodeWhisperer 와 같은 다양한 도구들을 활용할 수 있습니다.
이러한 도구 사용 이외에도 각 조직에서는 안전한 자격증명 관리를 위한 프로세스가 수립되어 있어야하며, 사고를 미연에 발지할 수 있도록 노출된 자격증명에 대한 자동화된 처리 방법이 구현되어야 있어야 합니다.
자격증명 탐지 이외에도 이 글에서 다루지 못한 최소권한부여 원칙 준수와 자격증명 관리를 위한 다양한 모범 사례 정보는 아래의 링크들을 참고하시기 바랍니다.