ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AWS Building Block Review - DevSecOps
    Record 2023. 4. 21. 06:24

     

     

     

    시작하며


    AWS Korea에서 진행한 Building Block에 참여했습니다. 주제는 DevSecOps로, AWS를 활용한 데브옵스 환경에서의 보안이라는 내용을 다뤘습니다. 총 2일 간 진행되는 세션이었고, 1일차는 DevSecOps 환경에 대한 전반적인 설명과 도구들에  대한 이야기, 그리고 2일차는 DevSecOps 환경 구축 실습이 이뤄졌습니다. 

     

    실습 내용은 이렇습니다. 배포된 웹 응용 프로그램의 취약점에 직접 침투시키며 어떤 위험 요소가 있는지 미리 학습하고, 더 나아가 이런 문제에 대응하고, 미리 포착하기 위한 DevSecOps 환경 구축과 모니터링 방법에 대해 학습합니다.


    이번 포스트에서는 실습에 집중해서 작성하고자 합니다. 이후에 나올 글을 보면 아시게 될 테지만, 중간중간 생략된 부분이 많습니다. 내용을 따라하기 보다는, 대략적인 흐름을 파악하는데 참고하셨으면 좋겠습니다.

     

    목차

    1. 파이프라인 구성과 용어정리
    2. CDK 프로비저닝 전체 구성
    3. 소스코드
    4. 침투 시나리오
    5. 화이트박스 테스트
    6. 블랙박스 테스트
    7. 마무리

     
     
     

    파이프라인 구성과 용어정리


    Pipeline

    • 릴리스 파이프라인의 아키텍처는 상단의 이미지와 같이 구성되어 있습니다. 리소스는 모두 AWS CDK에 정의되어 있고, Cloud9 환경에서 다운로드해 진행합니다. 

     

    용어정리
    AWS CDK
    (Cloud Development Kit)
    프로그래밍 언어를 사용하여 클라우드 애플리케이션 리소스를 모델링 및 프로비저닝 해주는 도구
    AWS Cloud9 브라우저에서 동작하는 클라우드 기반 IDE
    AWS CodeCommit Private Git Repository를 호스팅하는 관리형 소스 제어 서비스
    AWS CodeBuild 웹 애플리케이션에서 컨테이너를 빌드하고 Private Container Registry에 게시하는
    통합 서비스이자 테스트가 동작되는 장소
    Amazon ECR Private Container Registry
    AWS CodePipeline 릴리스 파이프라인을 오케스트레이션 할 지속적 배포 서비스
    Amazon ECS on Fargate 웹 애플리케이션을 배포할 컴퓨팅 리소스
    SAST
    (Static Application Security Testing)
    소스 코드를 분석하여 잠재적인 보안 취약점을 찾아내는 보안 검사
    SCA
    (Software Composition Analysis)
    제 3자 소프트웨어 구성 요소를 검사하여 잠재적인 보안 취약점을 찾아내는 보안 검사
    ( SCA는 소스 코드가 아니라 바이너리 파일을 분석 )
    License Analysis
    ( 앞으로 편의상 LA로 명명 )
    라이선스의 유효성 검사 ( ex. 블랙리스트에 포함된 라이선스 체크 ) 
    DAST
    (Dynamic Application Security Testing)
    애플리케이션의 런타임 환경에서 보안 취약점을 검출하는 보안 검사 
    ( 여기서는 EC2에 zapproxy로 빌드 )
     

     
     
     
     

    CDK 프로비저닝 전체 구성


     

    AWS Cloud9

    • 첫번째로 AWS Cloud9의 화면입니다.
    • CDK가 구성된 Pipeline 파일의 설치와, Python 가상 환경이 활성화 된 상태입니다. (.venv)
    • 하단에 나올 내용들은 위에서 설치한 파일들로 구성된 세부 내역들을 설명합니다.

     
     
     

    AWS CodeCommit

    • 두번째로 AWS CodeCommit 대시보드입니다.
    • "flask-app"이라는 빈 Repository가 생성되었습니다. ( Pipeline 파일에 포함 )
    • 사진에는 보이지 않지만 CDK에서 개발자가 코드를 게시할 때마다 릴리스 파이프라인을 트리거하는
      CloudWatch Event Rule 또한 생성되었습니다.

     
     
     

    AWS CodePipeline

    • 세번째로 AWS CodePipeline에 설정된 정보입니다.
    • CheckoutSource 단계는 CodeCommit 리포지토리에 코드가 변경될 때마다 트리거됩니다.
    • ApplicationSecurityChecks 단계는 config.yaml에 설정한 SAST, SCA, LA의 검증을 진행합니다.
    • BuildImage 단계는 컨테이너 이미지를 생성하는데 사용할 아티팩트가 생성됩니다.
    • 추후 DAST 단계도 파이프라인에 포함됩니다.

     
     

    AWS CodeBuild

    • BuildImage 단계를 정의하는 CodeBuild 프로젝트입니다.
    • Buildspec 섹션에 명시된 소스코드 파일을 확인하면 세부 설정 사항을 파악할 수 있습니다.
    • ( 접은 글을 펼치면 설정 파일을 확인할 수 있습니다. )
    더보기
    // docker_buildspec.yaml
    
    version: 0.2
    
    phases:
      pre_build:
        commands:
          - echo Logging in to Amazon ECR...
          - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
      build:
        commands:
          - echo Build started on `date`
          - docker build -t $ECR_REPO_URI:latest .
          - docker tag $ECR_REPO_URI:latest $ECR_REPO_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION
      post_build:
        commands:
          - echo Build completed on `date`
          - echo Pushing the Docker images...
          - docker push $ECR_REPO_URI:latest
          - docker push $ECR_REPO_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION
          - echo Writing image definitions file...
          - printf '[{"name":"flask-app","imageUri":"%s"}]' $ECR_REPO_URI:latest > imagedefinitions.json
          - cat imagedefinitions.json
    artifacts:
      files: imagedefinitions.json

     
     
     
     

    Amazon ECR

    • BuildImage 단계에서는 컨테이너를 Amazon ECR의 Private Repository에도 게시합니다.

     
     

    VPC

    • 또한 CDK는 보안 도구와 웹 애플리케이션이 호스팅될 VPC를 프로비저닝합니다.
    • 여기서 VPC는 StagingVPC로 등록되었습니다.

     

    2 Availability Zone Topology

    • StagingVPC는 일반적인 2AZ 토폴로지를 사용합니다.

     
     

    Amazon ECS Fargate

    • CDK에서 Amazon ECS Fargate에 SonarQube Server를 배포했습니다. 이는 SAST 도구로 사용됩니다.

     

    Amazon EC2

    • 마지막으로 CDK는 Amazon EC2에 OWASP Zap Proxy(zapproxy)도 배포합니다. 이는 DAST 도구가 됩니다.

     
     
     

    소스코드


     

    • 침투당하는 웹 애플리케이션의 소스코드입니다.
    • Python/Flask 베이스로 작성되었으며 하단의 침투 테스트에 취약한 형태의 코드로 작성되었습니다.

     

    ( 소스코드 이미지 분실.. )

    CodePipeline

    • 앞으로 소스코드를 CodeCommit에 PR한다면 파이프라인이 위 이미지처럼 동작합니다.

     
     

    침투 시나리오

    OWASP Top 10

     
     
     

    WhiteBOX TEST


    SAST

    • 정적 애플리케이션 보안 테스트를 통해 소스 코드를 검토하고 취약한 소스를 식별하며 검토가 필요한 보안 핫스팟을 제공합니다. 
    • ECS Fargate에 미리 배포한 SonarQube 서버를 사용합니다.
    • 사전에 발급된 SonarQube 토큰을 Pipeline config.yaml 파일에 작성 후 deploy하여 실행된 상태입니다.
    • CodePipeline - ApplicationSecurityCheck - SAST 경로에서 접근했습니다.
    • CSRF, XSS, Insecure Configuration 등 다양한 취약점이 발견되었습니다.
    • 이제 소스코드로 돌아가 문제들을 해결할 코드를 추가하고 다시 커밋하여 에러 메세지를 없애줍니다.
    • ( 접은 글을 펼치면 설정 파일을 확인할 수 있습니다. )
    더보기
    // sast_buildspec.yaml
    
    version: 0.1
    
    phases:
      pre_build:
        commands:
          - echo Installing SAST Tool...
          - wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip
          - unzip sonar-scanner-cli-4.6.2.2472-linux.zip
          - mv sonar-scanner-4.6.2.2472-linux /opt/sonar-scanner
          - chmod -R 775 /opt/sonar-scanner
      build:
        commands:
          - echo Build started on `date`
          - /opt/sonar-scanner/bin/sonar-scanner -Dsonar.sources=. -Dproject.settings=sonar-project.properties -Dsonar.host.url=$SONARQUBE_URL -Dsonar.login=$SONARQUBE_ACCESS_TOKEN > sonarqube_scanreport.json
          - echo Build complete on `date`

     

    SCA

    • 소프트웨어 구성 분석을 통해 외부 라이브러리가 최신 상태인지, 보안 결함이 있는지 또는 라이센스가 있는지 탐색하는 테스트입니다. 여기서는 오픈소스 SCA 도구인 Safety를 사용합니다. 
    • 확인 후 빌드 로그에 작성된 보고서를 통해 종속성의 오류를 제거해줍니다. 
    • ( 접은 글을 펼치면 설정 파일을 확인할 수 있습니다. )
    더보기
    // sca_buildspec.yaml
    
    version: 0.1
    
    phases:
      pre_build:
        commands:
          - echo Installing SCA tool...
          - pip install pip-audit
      build:
        commands:
          - echo Entered the post_build phase...
          - echo Build completed on `date`
          - pip-audit -r requirements.txt

     

    License Analysis

    • 라이선스 체크는 선택사항 모듈입니다. 조직에서 개발자가 애플리케이션에 사용하는 종속성의 라이선스를 감사할 용도로 사용할 수 있습니다.
    • 이 프로젝트에서는 Python License Checker(liccheck)를 사용하여 테스트합니다.
    • 웹 애플리케이션의 requirements.txt에 wdb가 포함되어 있었습니다. 이 라이브러리는 라이선스 전략에 블랙리스트에 포함된 GPL 라이선스를 사용하고 있고, 라이선스 테스트에 감지되었습니다.
    • ( 접은 글을 펼치면 설정 파일을 확인할 수 있습니다. )
    더보기
    // license_check_buildspec.yaml
    
    version: 0.1
    
    phases:
      pre_build:
        commands:
          - echo Installing License Checker Tool...
          - pip install liccheck
          - pip install -r requirements.txt
      build:
        commands:
          - echo Entered the post_build phase...
          - echo Build completed on `date`
          - liccheck -s license_strategy.ini -r requirements.txt

     

     

    BlackBOX TEST


    DAST

    • 잠재적인 보안 취약을 식별하기 위해 웹 애플리케이션을 스캔하고 침투 테스트를 진행합니다. 
    • OWASP Zed Attack Proxy라는 무료 오픈소스 DAST 도구를 사용합니다.
    • 위의 테스트 결과에서 Click Jacking에 대한 위험성이 보고되었습니다.
    • ( 접은 글을 펼치면 설정 파일을 확인할 수 있습니다. )
    더보기
    // dast_buildspec.yaml
    
    version: 0.2
    
    phases:
      pre_build:
        commands:
          - |
            echo "Deleting Alerts from last session"
            curl -s "$ZAP_API_URL/JSON/alert/action/deleteAllAlerts/?apikey=$ZAP_API_KEY"
            echo "Starting Active Scan for: $SCAN_URL"
            curl -s "$ZAP_API_URL/JSON/core/action/accessUrl/?apikey=$ZAP_API_KEY&url=$SCAN_URL&followRedirects=false" > /dev/null
            scanId=$(curl -s "$ZAP_API_URL/JSON/ascan/action/scan/?apikey=$ZAP_API_KEY&zapapiformat=JSON&formMethod=GET&url=$SCAN_URL&recurse=&inScopeOnly=false&scanPolicyName=&method=&postData=&contextId=" | jq -r '.scan')
            echo "Waiting for results. OWASP Scan ID: $scanId"
    
            while [ "$status" != "100" ];
            do
              status=$(curl -s "$ZAP_API_URL/JSON/ascan/view/status/?apikey=$ZAP_API_KEY&scanId=$scanId" | jq -r '.status')
              echo "Scan Progress at $status%..."
              sleep 3
            done
            echo "DONE!"
      build:
        commands:
          - |
            high_alerts=$(curl -s "$ZAP_API_URL/JSON/alert/view/alertsSummary/?apikey=$ZAP_API_KEY&baseurl=$SCAN_URL" | jq -r '.alertsSummary.High')
            medium_alerts=$(curl -s "$ZAP_API_URL/JSON/alert/view/alertsSummary/?apikey=$ZAP_API_KEY&baseurl=$SCAN_URL" | jq -r '.alertsSummary.Medium')
            
            if [ $high_alerts -gt 0 ] || [ $medium_alerts -gt 0 ];
            then
              echo "There are $high_alerts High and $medium_alerts Medium Alerts. Failing Build..."
              exit 1;
            fi
      post_build:
        commands:
          - |
            echo "Generating HTML report..."
            dt=$(date +%F-%H%M%S)
            curl -s "$ZAP_API_URL/OTHER/core/other/htmlreport/?apikey=$ZAP_API_KEY" > report_$dt.html
            echo "HTML report saved: report_$dt.html"
    artifacts:
      files:
        - "*.html"

     
     

    마무리


    결론적으로 'SAST, DAST, SCA, LA'와 같은 자동화된 보안 도구는 코드베이스 내에서 보안 문제를 식별하는데 필요한 노력의 양을 크게 줄일 수 있었습니다. 또한 발표자는 현재 이러한 자동화가 이루어지지 않은 조직에게 당장 보완이 필요한 영역에 대해 이해하고, 그에 맞는 커버리티 설정을 잘 해야한다고 설명했습니다. 
    ( 발표자의 전전 회사의 경우 한 번에 수정 필요 지점이 3만개 발견됐다고 합니다.. )

    결국 도구 사용과 더불어 보안 코드 리뷰의 중요성이 매우 높다고 강조했으며, OWASP Top 10이나 Mitre Top 25는 좋은 지침이 될 수 있다고 설명합니다.

     

    지금까지 저도 나름 코드 레벨에서 최대한 보안에 신경 썼다고 생각했지만, 수동 작업에 많은 빈틈이 존재했던 것 같으며, 이번에 배운 DevSecOps 환경은 앞으로의 좋은 지침이 될 것 같습니다.  
    읽어주셔서 감사합니다.  

     

     

     

    실습에 관련된 모든 자료는 AWS Korea에서 제공한 자료를 토대로 제작되었습니다.
     
     

    댓글

Designed by Tistory.