Configurações de permissão para acessar a lista de IP no bucket S3 com Guard Duty
Tags: aws, devops, guardduty, security
Published: 2022-01-04 14:01:55

Amazon GuardDuty é um serviço que detecta operações suspeitas do CloudTrail, logs de fluxo VPC, logs DNS e eventos de acesso a dados S3.Como uma configuração do GuardDuty, você pode aumentar ou suprimir alertas com base em uma lista de IPs especificada pelo usuário. Esta lista de IPs deve estar no S3.

Amazon S3 é um serviço de armazenamento de objetos. Para acessar o S3, você precisa conceder direitos de acesso apropriados.Existem várias maneiras de conceder permissões, e a entrada a seguir é fácil de entender.

Desta vez, examinaremos que tipo de autoridade o GuardDuty precisa para acessar a lista de IPs colocada no S3.

O que vamos fazer hoje é preparar o ambiente e validar se esta tudo certo. Vou sintetizar abaixo: 

1. **Preparar**
    1. Crie um bucket S3 e carregue uma lista de IP
    2. Ativar GuardDuty
    3. Criar função IAM com menos privilégios
2. **Validar**
    1. Configuração da lista de IPs na função IAM (executada em outro shell)
    2. Se falhar, verifique a API que falhou no CloudTrail
    3. Adicionada permissão para APIs que falharam na função IAM
    4. Configuração da lista de IPs na função IAM novamente (executada em outro shell)
    5. Verifique o conteúdo de execução da API recém-permitida

A lista de IPs usada desta vez é uma lista de endereços IP que são considerados ameaças. Você provavelmente deve obter resultados semelhantes para endereços IP confiáveis. (Eu não tentei)

Utilize o AWS-CLI V2 e o Shell de sua preferencia. 

## Preparando:

### **Crie um bucket S3 e carregue uma lista de IP**

`ThreatIntelSet.txt`Crie uma lista de endereços IP que você considera uma ameaça .

ThreatIntelSet.txt`XXX.XXX.XXX.XXX`

Crie um depósito e carregue a lista de IPs.

```bash
$ BUCKETNAME=guard-duty-iplist-test-$(date '+%Y%m%d-%H%M%S')
$ aws s3 mb s3://$BUCKETNAME
make_bucket: guard-duty-iplist-test-20211120-141946
$ aws s3 cp ThreatIntelSet.txt s3://$BUCKETNAME/
upload: ./ThreatIntelSet.txt to s3://guard-duty-iplist-test-20211120-141946/ThreatIntelSet.txt
```

Como o nome do intervalo é usado ao trabalhar em outro shell, o nome do intervalo é enviado para um arquivo.

```bash
$ echo $BUCKETNAME > BucketName.txt
```

Não confirmo, mas neste ponto, nenhum direito de acesso ao S3 foi definido.Um usuário IAM ativo pode acessar este bucket S3 porque ele está `AdministratorAccess`conectado.

### **Habilitando GuardDuty**

Habilite GuardDuty.A propósito, GuardDuty só pode ser habilitado em no máximo um na região da conta. Irá falhar se já estiver habilitado. Se falhar, você `delete-detector`pode excluí-lo com.

```bash
$ aws guardduty create-detector --enable \
        --finding-publishing-frequency FIFTEEN_MINUTES \
        --query 'DetectorId' --output text > DetectorId.txt
```

Como o ID do GuardDuty é usado ao trabalhar em outro shell, ele é enviado para um arquivo.

### **Crie a função IAM com o menor privilégio**

Crie uma função IAM para definir a lista de IPs no GuardDuty com menos privilégios.

Usaremos dois arquivos aqui.- `assume-role-policy.json`: política de confiança ※ edição principal do rolo IAM- `policy-guardduty-ip-list.json`: política IAM que define a política in-line do rolo IAM

`assume-role-policy.json`Edite `your-account-id`, substitua pelo ID da sua conta e salve.

```json
{
    "Version": "2012-10-17",
    "Statement": {
      "Effect": "Allow",
      "Principal": {
          "AWS": "your-account-id"
      },
      "Action": "sts:AssumeRole"   
    }
}
```

`policy-guardduty-ip-list.json`As únicas APIs permitidas estão relacionadas ao GuardDuty.

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "guardduty:*ThreatIntelSet*"
            ],
            "Resource": "*"
        }
    ]
}
```

Crie uma função IAM e atribua a ela a política acima.

```bash
$ aws iam create-role --role-name role-guard-duty \
    --assume-role-policy-document file://assume-role-policy.json > /dev/null
$ aws iam put-role-policy --role-name role-guard-duty \
    --policy-name policy-guardduty-ip-list \
    --policy-document file://policy-guardduty-ip-list.json
```

Além disso, ele obtém credenciais temporárias e as envia para um arquivo para trabalhar em outro shell.
Esta credencial expira em uma hora, portanto, se expirar, tente novamente assume-rolepara obter a credencial.

```bash
$ aws sts assume-role \
    --role-session-name role-session-guardduty-test \
    --role-arn $( \
        aws iam get-role --role-name role-guard-duty \
            --query 'Role.Arn' --output text \
    ) > assume.txt
```

## **Validando:**

### **Configuração da lista de IPs na função IAM (executada em outro shell)**

Até agora, `AdministratorAccess`tenho trabalhado com o usuário anexado, maspor enquanto estarei trabalhando em um shell diferente para trabalhar com a função IAM menos privilegiada. Mantenhao `AdministratorAccess`shell antigo aberto, pois ele será usado mais tarde.

Em outro shell, defina as credenciais temporárias em uma variável de ambiente.Agora você pode trabalhar com a função IAM menos privilegiada. ( `aws sts get-caller-identity`Por favor, verifique com)

```bash
$ assume=$(cat assume.txt)
$ export \
    AWS_ACCESS_KEY_ID=$(echo $assume | jq -r '.Credentials.AccessKeyId') \
    AWS_SECRET_ACCESS_KEY=$(echo $assume | jq -r '.Credentials.SecretAccessKey') \
    AWS_SESSION_TOKEN=$(echo $assume | jq -r '.Credentials.SessionToken')
```

Agora! Agora, vamos tentar definir a lista de IPs com a função IAM menos privilegiada.A `guardduty:CreateThreatIntelSet`API usada aqui.

```bash
$ BUCKETNAME=$(cat BucketName.txt)
$ DetectorId=$(cat DetectorId.txt)
$ aws guardduty create-threat-intel-set --detector-id $DetectorId \
    --name ThreatIntelSet --activate --format TXT \
    --location s3://$BUCKETNAME/ThreatIntelSet.txt

An error occurred (BadRequestException) when calling the CreateThreatIntelSet operation: The request was rejected because you do not have the required iam:PutRolePolicy permission.
```

*Fracasso!* Gentilmente, a mensagem de erro diz que as permissões estão faltando.`iam:PutRolePolicy`Parece que a autoridade da API é insuficiente.

### **Verifique a API com falha no CloudTrail**

Uma vez de `AdministratorAccess`volta ao shell, investigue a causa da falha em detalhes.Mantenha o shell de credenciais temporário aberto, pois você o usará novamente mais tarde.

`AdministratorAccess`No shell de, eventos CloudTrail de saída.

```bash
$ aws cloudtrail lookup-events --lookup-attributes \ 
    AttributeKey=Username,AttributeValue=role-session-guardduty-test \
    > cloudtrail-events.json
```

Abra cloudtrail-events.txt e procure por eventos próximos ao tempo de execução. Houve eventos de APIcomo `iam:PutRolePolicy`este:

```json
{
            "EventId": "81f77b0d-0e9f-4ad7-ad4a-9b8d5ced458a",
            "EventName": "PutRolePolicy",
            "ReadOnly": "false",
            "AccessKeyId": "XXXXXXXXXXXXXXXX",
            "EventTime": "2021-11-20T22:34:33+09:00",
            "EventSource": "iam.amazonaws.com",
            "Username": "role-session-guardduty-test",
            "Resources": [],
            "CloudTrailEvent": "＜Event content＞"
        }
```

`CloudTrailEvent`Os detalhes do evento estão escritos no item.

Conteúdo de CloudTrailEvent:

```json
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "XXXXXXXXXXXX:role-session-guardduty-test",
        "arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/role-guard-duty/role-session-guardduty-test",
        "accountId": "XXXXXXXXXXXX",
        "accessKeyId": "XXXXXXXXXXXX",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "XXXXXXXXXXXX",
                "arn": "arn:aws:iam::XXXXXXXXXXXX:role/role-guard-duty",
                "accountId": "XXXXXXXXXXXX",
                "userName": "role-guard-duty"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2021-11-20T13:27:19Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "guardduty.amazonaws.com"
    },
    "eventTime": "2021-11-20T13:34:33Z",
    "eventSource": "iam.amazonaws.com",
    "eventName": "PutRolePolicy",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "guardduty.amazonaws.com",
    "userAgent": "guardduty.amazonaws.com",
    "errorCode": "AccessDenied",
    "errorMessage": "User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/role-guard-duty/role-session-guardduty-test is not authorized to perform: iam:PutRolePolicy on resource: role AWSServiceRoleForAmazonGuardDuty",
    "requestParameters": null,
    "responseElements": null,
    "requestID": "XXXXXXXXXXXX",
    "eventID": "XXXXXXXXXXXX",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "XXXXXXXXXXXX",
    "eventCategory": "Management"
}
```

A partir daqui, torna-se o ponto de verificação.

Uma pessoa que emitiu a API, `userIdentity.invokedBy`/ `sourceIPAddress`/ `userAgent`de, você pode adivinhar o GuardDuty.A autoridade que GuardDuty assumiu é `arn:aws:sts::XXXXXXXXXXXX:assumed-role/role-guard-duty/role-session-guardduty-test`, mas essas são as credenciais temporárias para a função IAM que você criou anteriormente.

O primeiro ponto é que GuardDuty, `guardduty:CreateThreatIntelSet`portanto, assume a autoridade do usuário que emitiu a API e emite outra API ( `iam:PutRolePolicy`).Portanto, `guardduty:CreateThreatIntelSet`o usuário que emite a API também deve receber a autoridade da API que o GuardDuty deseja emitir.

Além disso, `errorMessage`diz que é diferente da saída do AWS-CLI `AWSServiceRoleForAmazonGuardDuty`.

O segundo ponto é que GuardDuty deseja `iam:PutRolePolicy`conceder algumas permissões na API para `AWSServiceRoleForAmazonGuardDuty`a função.

Bem, `AWSServiceRoleForAmazonGuardDuty`e é, o que é?

A resposta é a função de serviço do GuardDuty.Uma função de serviço é uma função IAM que um serviço AWS assume.GuardDuty usa fixo `AWSServiceRoleForAmazonGuardDuty`.

`AdministratorAccess`No shell de, você pode ver que afunção de serviço é obter os detalhes de GuardDuty `AWSServiceRoleForAmazonGuardDuty`.

```json
$ DetectorId=$(cat DetectorId.txt)
$ aws guardduty get-detector --detector-id $DetectorId
{
    "CreatedAt": "2021-11-20T14:45:09.083Z",
    "FindingPublishingFrequency": "FIFTEEN_MINUTES",
    "ServiceRole": "arn:aws:iam::XXXXXXXXXXXX:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty",
    "Status": "ENABLED",
    "UpdatedAt": "2021-11-20T14:45:09.083Z",
    "DataSources": {
        "CloudTrail": {
            "Status": "ENABLED"
        },
        "DNSLogs": {
            "Status": "ENABLED"
        },
        "FlowLogs": {
            "Status": "ENABLED"
        },
        "S3Logs": {
            "Status": "ENABLED"
        }
    },
    "Tags": {}
}
```

### **Adicionar permissão para API que falhou no papel do IAM**

`iam:PutRolePolicy`Adicione permissões de API ao seu papel IAM .

`AdministratorAccess`No shell do, `policy-guardduty-ip-list.json`edite `policy-guardduty-ip-list-v2.json`e crie.

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "guardduty:*ThreatIntelSet*"
            ],
            "Resource": "*"
+        },
+        {
+            "Effect": "Allow",
+            "Action": [
+                "iam:PutRolePolicy"
+            ],
+            "Resource": "arn:aws:iam::*:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty"
        }
    ]
}
```

Conceda a política editada à função IAM.

```bash
$ aws iam put-role-policy --role-name role-guard-duty \
    --policy-name policy-guardduty-ip-list \
    --policy-document file://policy-guardduty-ip-list-v2.json
```

### **Configuração da lista de IP novamente com papel IAM (executado em outro shell)**

Vá para o shell de credenciais temporárias e tente definir a lista de IP novamente na função IAM.`AdministratorAccess`Mantenha o invólucro aberto para uso posterior.

Vamos tentar novamente!

```bash
$ aws guardduty create-threat-intel-set --detector-id $DetectorId \
    --name ThreatIntelSet --activate --format TXT \
    --location s3://$BUCKETNAME/ThreatIntelSet.txt
{
    "ThreatIntelSetId": "XXXXXXXXXXXXXXXXXXXX"
}
```

Você configurou com sucesso sua lista de IP!

### **Verifique o conteúdo de execução da API recém-permitida**

`AdministratorAccessiam:PutRolePolicy`Volte ao seu shell e veja quais políticas IAM você está concedendo com a API recém-permitida .

`AdministratorAccess`No shell de, eventos CloudTrail de saída.

```bash
$ aws cloudtrail lookup-events --lookup-attributes \ 
    AttributeKey=Username,AttributeValue=role-session-guardduty-test \
    | jq '.Events[] | select(.EventName == "PutRolePolicy")' \
    > cloudtrail-events-v2.json
```

Existem mais novos eventos.

```json
{
            "EventId": "c62d89db-46f3-4538-b345-a13c71a44893",
            "EventName": "PutRolePolicy",
            "ReadOnly": "false",
            "AccessKeyId": "XXXXXXXXXXXXXXXX",
            "EventTime": "2021-11-20T22:37:15+09:00",
            "EventSource": "iam.amazonaws.com",
            "Username": "role-session-guardduty-test",
            "Resources": [
                {
                    "ResourceType": "AWS::IAM::Policy",
                    "ResourceName": "d4be9ec85d6cd89f8b08bb31a23570c8"
                },
                {
                    "ResourceType": "AWS::IAM::Role",
                    "ResourceName": "AWSServiceRoleForAmazonGuardDuty"
                }
            ],
            "CloudTrailEvent": "＜excerpt＞"
        }
```

Conteúdo de CloudTrailEvent

```json
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROAYTUJN4U3EHCPQK73U:role-session-guardduty-test",
        "arn": "arn:aws:sts::XXXXXXXXXXXXXXXX:assumed-role/role-guard-duty/role-session-guardduty-test",
        "accountId": "XXXXXXXXXXXXXXXX",
        "accessKeyId": "XXXXXXXXXXXXXXXX",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROAYTUJN4U3EHCPQK73U",
                "arn": "arn:aws:iam::XXXXXXXXXXXXXXXX:role/role-guard-duty",
                "accountId": "XXXXXXXXXXXXXXXX",
                "userName": "role-guard-duty"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2021-11-20T10:39:14Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "guardduty.amazonaws.com"
    },
    "eventTime": "2021-11-20T11:07:33Z",
    "eventSource": "iam.amazonaws.com",
    "eventName": "PutRolePolicy",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "guardduty.amazonaws.com",
    "userAgent": "guardduty.amazonaws.com",
    "requestParameters": {
        "roleName": "AWSServiceRoleForAmazonGuardDuty",
        "policyName": "XXXXXXXXXXXXXXXXXXXX",
        "policyDocument": "{"Version":"2012-10-17","Statement":[{"Sid":"1","Effect":"Allow","Action":["s3:GetObject"],"Resource":["arn:aws:s3: : :guard-duty-iplist-test-20211120-141946/ThreatIntelSet.txt"]}]}"
    },
    "responseElements": null,
    "requestID": "36291f18-4a00-4a1b-9b15-06cc736fac3f",
    "eventID": "cc0b380b-2bdf-48b4-9974-020774ea92e9",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "XXXXXXXXXXXXXXXX",
    "eventCategory": "Management"
}
```

Os parâmetros da API são registrados em requestParameters.Expanda ainda mais o conteúdo de policyDocument nele. (Aninhamento Json é terrível ...)

Conteúdo de policyDocument

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3: : :guard-duty-iplist-test-20211120-141946/ThreatIntelSet.txt"
            ]
        }
    ]
}
```

`s3:GetObject`Permite API. Além do mais, o objetivo `ThreatIntelSet.txt`a ser alcançado é.Ao atribuir esta política à função de serviço ( `AWSServiceRoleForAmazonGuardDuty`) do GuardDuty, você pode acessar a lista de IPs no S3.

Agora você sabe como definir direitos de acesso ao balde S3 que contém a lista de IP para as configurações da lista de IP.

Vlw Flw