CloudTrail detection rules validated by live-fire adversary emulation in an isolated AWS account, alongside a Prowler HIPAA baseline with documented remediation and accepted risk.
Every rule in this repo was tested by actually running the attack it detects — detonating the technique with Stratus Red Team, capturing the real CloudTrail telemetry, writing the rule against that telemetry, and then cleaning up and independently verifying the account was returned to a clean state. The test fixtures are real events, scrubbed of account identifiers.
Anyone can write a Sigma rule that looks plausible. The question a detection has to answer is whether it fires on the real event an attacker produces, and stays quiet otherwise. This repo answers that question with evidence for six AWS techniques, and is honest about the two of them where a managed service (GuardDuty) produced no alert at all — which is the concrete argument for why custom detection is worth the effort.
rules/cloud/ 6 Sigma rules for AWS CloudTrail
tests/ a minimal Sigma evaluator + 14 tests over real fixtures
tests/fixtures/ real, scrubbed CloudTrail events from live detonations
docs/ the analysis (below)
.github/workflows/ CI running the rule tests on every push
Documentation
- Detection latency and coverage — measured detection lag per technique, and the managed-vs-custom coverage comparison.
- Prowler HIPAA remediation — the compliance baseline, what was fixed, and fourteen findings accepted with reasoning.
- Insights queries — the deployable CloudWatch form of each rule.
| Technique | Event(s) | Detected by rule | ATT&CK |
|---|---|---|---|
| Security group opened to internet (port 22) | AuthorizeSecurityGroupIngress |
yes | T1562.007 |
| CloudTrail logging stopped | StopLogging |
yes | T1562.008 |
| CloudTrail trail deleted | DeleteTrail |
yes | T1562.008 |
| Admin IAM user created | CreateUser + AttachUserPolicy + CreateAccessKey |
yes | T1098.001, T1136.003 |
| Access key backdoored onto existing user | CreateAccessKey |
yes (with a documented limit) | T1098.001 |
| S3 bucket shared to external account | PutBucketPolicy |
yes | T1537 |
- CloudTrail generates events in ~5 seconds, but they take 23–125 seconds to become searchable. Detection begins at searchability, not generation — so the latter is the misleading number to quote. See the latency doc.
- A three-call attack chain did not arrive together. The highest-signal event of the admin-user creation became queryable 73 seconds after the other two and in a different log stream — enough to defeat a naive short-window correlation rule.
- GuardDuty produced a finding for only 2 of the 6 techniques. It caught the
two CloudTrail-tampering events and missed the other four — including the
creation of an administrative IAM user with live access keys, the single most
consequential action in the run. Where it did fire, it rated audit-trail
destruction only
Low. The custom rules fired on all six.
- The rules are not deployed to a production SIEM. They are validated against real telemetry and provided in portable Sigma plus a deployable Insights form; they have not been run as live production detections.
- The backdoor-key rule is deliberately broad. Base Sigma cannot compare two
fields, so the rule fires on every
CreateAccessKey; the real signal (requestParameters.userName != userIdentity.userName) is pushed to triage or the query layer, and this is documented in the rule itself. - Single-trail environments cannot self-detect their own blinding. The
StopLogging/DeleteTraildetections worked here only because a second trail witnessed the tampering. This limitation is stated in the coverage doc. - The S3 rule depends on log representation. CloudTrail delivers bucket policies as parsed fields in CloudWatch and as an escaped string in S3; the rule matches the former and notes that the latter needs a different match.
pip install -r requirements.txt
pytest tests/ -v
The tests use a small custom Sigma evaluator (tests/sigma_eval.py) rather than
a full pySigma backend. Reason: pySigma converts a rule to a backend query
string, which tests the conversion — not whether the rule matches an event.
Evaluating rules directly against real event JSON tests the thing that actually
matters. The evaluator supports only the Sigma subset these rules use, by design.
All work was performed in a dedicated, isolated AWS account with hard billing guardrails and a region lock, using per-technique least-privilege identities whose credentials were deleted when the exercise ended. Every technique was cleaned up and independently verified as removed — not trusted to the tool's exit code. Stratus Red Team is intended for exactly this: sandbox accounts with no production workloads.