AWS Console GetSigninToken Potential Abuse


Description

Detects GetSigninToken calls from non-SSO user agents. An adversary can use tools like aws_consoler to convert compromised CLI credentials into a federated console session, bypassing MFA requirements and obscuring the original access key. The GetSigninToken API creates temporary console access from STS temporary credentials.

Query · python

from panther_aws_helpers import aws_rule_context

# User agents associated with legitimate AWS SSO portal sign-in token requests
SSO_USER_AGENTS = ["Jersey/${project.version}", "Go-http-client/2.0"]


def rule(event):
    if event.get("eventSource") != "signin.amazonaws.com":
        return False
    if event.get("eventName") != "GetSigninToken":
        return False
    # Exclude legitimate AWS SSO portal traffic
    user_agent = event.get("userAgent", "")
    for sso_ua in SSO_USER_AGENTS:
        if sso_ua in user_agent:
            return False
    return True


def title(event):
    arn = event.deep_get("userIdentity", "arn", default="<unknown>")
    ip_addr = event.get("sourceIPAddress", "<unknown>")
    user_agent = event.get("userAgent", "<unknown>")
    return (
        f"Suspicious GetSigninToken call from [{ip_addr}] "
        f"as [{arn}] with user agent [{user_agent}]"
    )


def alert_context(event):
    return aws_rule_context(event)

Analyst notes

  1. Query CloudTrail for all API calls by userIdentity:arn in the 6 hours before and after this alert, focusing on ConsoleLogin and console-based actions that may indicate the federated session was used
  2. Check if sourceIPAddress and userAgent are associated with known internal tooling or if they match patterns of attacker tools like aws_consoler
  3. Find all other alerts from this userIdentity:accessKeyId in the past 7 days to determine if the underlying credentials are compromised
Raw source AWS Console GetSigninToken Potential Abuse · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: aws_console_getsignintoken.py
RuleID: "AWS.Console.GetSigninToken.Abuse"
DisplayName: "AWS Console GetSigninToken Potential Abuse"
Enabled: true
LogTypes:
  - AWS.CloudTrail
Tags:
  - AWS
  - AWS STS
  - Lateral Movement:Remote Services
  - Defense Evasion:Use Alternate Authentication Material
Reports:
  MITRE ATT&CK:
    - TA0008:T1021.007
    - TA0005:T1550.001
Status: Experimental
Severity: Medium
Description: >
  Detects GetSigninToken calls from non-SSO user agents. An adversary can use tools
  like aws_consoler to convert compromised CLI credentials into a federated console
  session, bypassing MFA requirements and obscuring the original access key. The
  GetSigninToken API creates temporary console access from STS temporary credentials.
Runbook: |
  1. Query CloudTrail for all API calls by userIdentity:arn in the 6 hours before and after this alert, focusing on ConsoleLogin and console-based actions that may indicate the federated session was used
  2. Check if sourceIPAddress and userAgent are associated with known internal tooling or if they match patterns of attacker tools like aws_consoler
  3. Find all other alerts from this userIdentity:accessKeyId in the past 7 days to determine if the underlying credentials are compromised
Reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html
SummaryAttributes:
  - userAgent
  - sourceIpAddress
  - recipientAccountId
  - p_any_aws_arns
DedupPeriodMinutes: 60
Threshold: 1
Tests:
  - Name: Suspicious GetSigninToken
    ExpectedResult: true
    Log:
      {
        "awsRegion": "us-east-1",
        "eventName": "GetSigninToken",
        "eventSource": "signin.amazonaws.com",
        "eventTime": "2024-01-15T10:30:00Z",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "sourceIPAddress": "203.0.113.50",
        "userAgent": "python-requests/2.28.0",
        "userIdentity": {
          "accessKeyId": "ASIAIOSFODNN7EXAMPLE",
          "accountId": "123456789012",
          "arn": "arn:aws:sts::123456789012:assumed-role/MyRole/session",
          "type": "AssumedRole"
        }
      }
  - Name: Legitimate SSO Portal GetSigninToken
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-east-1",
        "eventName": "GetSigninToken",
        "eventSource": "signin.amazonaws.com",
        "eventTime": "2024-01-15T10:30:00Z",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "sourceIPAddress": "10.0.0.1",
        "userAgent": "Jersey/${project.version}",
        "userIdentity": {
          "type": "AssumedRole",
          "arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_Admin/user@example.com"
        }
      }
  - Name: Legitimate SSO Portal GetSigninToken (Go client)
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-east-1",
        "eventName": "GetSigninToken",
        "eventSource": "signin.amazonaws.com",
        "eventTime": "2024-01-15T10:30:00Z",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "sourceIPAddress": "10.0.0.1",
        "userAgent": "Go-http-client/2.0",
        "userIdentity": {
          "type": "AssumedRole",
          "arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_Admin/user@example.com"
        }
      }
  - Name: Unrelated Signin Event
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-east-1",
        "eventName": "ConsoleLogin",
        "eventSource": "signin.amazonaws.com",
        "eventTime": "2024-01-15T10:30:00Z",
        "eventType": "AwsConsoleSignIn",
        "recipientAccountId": "123456789012",
        "sourceIPAddress": "203.0.113.50",
        "userAgent": "Mozilla/5.0",
        "userIdentity": {
          "type": "IAMUser",
          "userName": "admin"
        }
      }


# ------ paired body: aws_console_getsignintoken.py ------

from panther_aws_helpers import aws_rule_context

# User agents associated with legitimate AWS SSO portal sign-in token requests
SSO_USER_AGENTS = ["Jersey/${project.version}", "Go-http-client/2.0"]


def rule(event):
    if event.get("eventSource") != "signin.amazonaws.com":
        return False
    if event.get("eventName") != "GetSigninToken":
        return False
    # Exclude legitimate AWS SSO portal traffic
    user_agent = event.get("userAgent", "")
    for sso_ua in SSO_USER_AGENTS:
        if sso_ua in user_agent:
            return False
    return True


def title(event):
    arn = event.deep_get("userIdentity", "arn", default="<unknown>")
    ip_addr = event.get("sourceIPAddress", "<unknown>")
    user_agent = event.get("userAgent", "<unknown>")
    return (
        f"Suspicious GetSigninToken call from [{ip_addr}] "
        f"as [{arn}] with user agent [{user_agent}]"
    )


def alert_context(event):
    return aws_rule_context(event)

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.