diff --git a/src/SUMMARY.md b/src/SUMMARY.md index df8bcfc7bf..4a2c11888a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -309,6 +309,7 @@ - [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation/README.md) - [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md) - [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation/README.md) + - [Readme](pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md) - [AWS - Privilege Escalation](pentesting-cloud/aws-security/aws-privilege-escalation/README.md) - [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc/README.md) - [AWS - AppRunner Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apprunner-privesc/README.md) diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md index 0cb9238efe..d55dd39925 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md @@ -80,6 +80,18 @@ aws sesv2 send-custom-verification-email --email-address --template-name Still to test. +## WorkMail pivot to bypass SES sandbox + +When `ses:GetAccount` shows the account is still in the SES sandbox and `ses:ListIdentities` returns no verified senders, attackers can **pivot to WorkMail** to send immediately (no sandbox and higher default quotas) by creating orgs, verifying domains, and registering mailboxes. + +{{#ref}} +../aws-workmail-post-exploitation/README.md +{{#endref}} + +## References + +- [Threat Actors Using AWS WorkMail in Phishing Campaigns](https://www.rapid7.com/blog/post/dr-threat-actors-aws-workmail-phishing-campaigns) + {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md new file mode 100644 index 0000000000..2989f4ff4e --- /dev/null +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md @@ -0,0 +1,78 @@ +# AWS - WorkMail Post Exploitation + +{{#include ../../../../banners/hacktricks-training.md}} + +## Abusing WorkMail to bypass SES sandbox + +Even if SES is stuck in the **sandbox** (verified-recipient only, ~200 msgs/24h, 1 msg/s), WorkMail has no equivalent restriction. An attacker with long-term keys can spin up disposable mail infra and start sending immediately: + +1. **Create a WorkMail org (region-scoped)** + ```bash + aws workmail create-organization --region us-east-1 --alias temp-mail --directory-id + ``` +2. **Verify attacker-controlled domains** (WorkMail invokes SES APIs as `workmail.amazonaws.com`): + ```bash + aws ses verify-domain-identity --domain attacker-domain.com + aws ses verify-domain-dkim --domain attacker-domain.com + ``` +3. **Provision mailbox users** and register them: + ```bash + aws workmail create-user --organization-id --name marketing --display-name "Marketing" + aws workmail register-to-work-mail --organization-id --entity-id --email marketing@attacker-domain.com + ``` + +Notes: +- Default **recipient cap** documented by AWS: **100,000 external recipients/day per org** (aggregated across users). +- Domain verification activity will appear in CloudTrail under SES but with **`invokedBy`: `workmail..amazonaws.com`**, so SES verification events can belong to WorkMail setup rather than SES campaigns. +- WorkMail mailbox users become **application-layer persistence** independent from IAM users. + +## Sending paths & telemetry gaps + +### Web client (WorkMail UI) +- Sends surface as **`ses:SendRawEmail`** events in CloudTrail. +- `userIdentity.type` = `AWSService`, `invokedBy/sourceIPAddress/userAgent` = `workmail..amazonaws.com`, so the **true client IP is hidden**. +- `requestParameters` still leak sender (`source`, `fromArn`, `sourceArn`, configuration set) to correlate with newly verified domains/mailboxes. + +### SMTP (stealthiest) +- Endpoint: `smtp.mail..awsapps.com:465` (SMTP over SSL) with the mailbox password. +- **No CloudTrail data events** are generated for SMTP delivery, even when SES data events are enabled. +- Ideal detection points are **org/domain/user provisioning** and SES identity ARNs referenced in subsequent web-sent `SendRawEmail` events. + +
+Example SMTP send via WorkMail + +```python +import smtplib +from email.message import EmailMessage + +SMTP_SERVER = "smtp.mail.us-east-1.awsapps.com" +SMTP_PORT = 465 +EMAIL_ADDRESS = "marketing@attacker-domain.com" +EMAIL_PASSWORD = "SuperSecretPassword!" + +target = "victim@example.com" # can be unverified/external +msg = EmailMessage() +msg["Subject"] = "WorkMail SMTP" +msg["From"] = EMAIL_ADDRESS +msg["To"] = target +msg.set_content("Delivered via WorkMail SMTP") + +with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as smtp: + smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) + smtp.send_message(msg) +``` + +
+ +## Detection considerations + +- If WorkMail is unnecessary, block it via **SCPs** (`workmail:*` deny) at the org level. +- Alert on provisioning: `workmail:CreateOrganization`, `workmail:CreateUser`, `workmail:RegisterToWorkMail`, and SES verifications with `invokedBy=workmail.amazonaws.com` (`ses:VerifyDomainIdentity`, `ses:VerifyDomainDkim`). +- Watch for anomalous **`ses:SendRawEmail`** events where the identity ARNs reference new domains and the source IP/UA equals `workmail..amazonaws.com`. + +## References + +- [Threat Actors Using AWS WorkMail in Phishing Campaigns](https://www.rapid7.com/blog/post/dr-threat-actors-aws-workmail-phishing-campaigns) +- [AWS WorkMail limits](https://docs.aws.amazon.com/workmail/latest/adminguide/limits.html) + +{{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/aws-security/aws-services/aws-iam-enum.md b/src/pentesting-cloud/aws-security/aws-services/aws-iam-enum.md index 15d98fcfca..53ab3387ff 100644 --- a/src/pentesting-cloud/aws-security/aws-services/aws-iam-enum.md +++ b/src/pentesting-cloud/aws-security/aws-services/aws-iam-enum.md @@ -90,6 +90,20 @@ aws iam list-mfa-devices aws iam list-virtual-mfa-devices ``` +### Stealth permission confirmation via intentional failures + +When `List*` or simulator APIs are blocked, you can **confirm mutating permissions without creating durable resources** by forcing predictable validation errors. AWS still evaluates IAM before returning these errors, so seeing the error proves the caller has the action: + +```bash +# Confirm iam:CreateUser without creating a new principal (fails only after authz) +aws iam create-user --user-name # -> EntityAlreadyExistsException + +# Confirm iam:CreateLoginProfile while learning password policy requirements +aws iam create-login-profile --user-name --password lower --password-reset-required # -> PasswordPolicyViolationException +``` + +These attempts still generate CloudTrail events (with `errorCode` set) but avoid leaving new IAM artifacts, making them useful for **low-noise permission validation** during interactive recon. + ### Permissions Brute Force If you are interested in your own permissions but you don't have access to query IAM you could always brute-force them.