// CyberDefenders  ·  Cloud Forensics

AbuSESer - Trufflenet

CyberDefenders Easy CloudWatch, VirusTotal
Execution, Privilege Escalation, Defense Evasion, Credential Access, Discovery, Collection, Impact

Scenario

On January 23, 2026, Maromalix’s finance department received an alarming call from TechCorp Industries, a long-standing client. TechCorp’s accounts payable team reported processing a wire transfer to what they believed was Maromalix’s bank account after receiving an invoice for services rendered — but Maromalix had not issued any such invoice.

During the week prior, Maromalix onboarded a new cloud administrator. Several IAM permission adjustments were made in response to access issues during this transition, some of which resulted in overly permissive policies. The investigation uses AWS CloudWatch Logs Insights to query CloudTrail and Lambda execution logs, reconstruct the attack timeline, and identify indicators of compromise.


Methodology

Triage — Log Groups and Schema

The first step is confirming what log sources are available. The CloudWatch log group selector reveals four groups relevant to the investigation:

  • /aws/cloudtrail/maromalix — primary CloudTrail audit log source
  • /aws/lambda/maromalix-daily-backup
  • /aws/lambda/maromalix-email-notifications
  • /aws/lambda/maromalix-health-check

Before querying blind, a limit 1 against the CloudTrail log group confirms the CloudTrail event structure — sourceIPAddress, userAgent, eventName, eventSource, userIdentity.* fields are all present:

fields @timestamp, @message
| limit 1

All queries in this investigation run in CloudWatch Logs Insights (CWLI) — a proprietary query language distinct from Kusto or Kibana KQL, using filter instead of where and stats instead of summarize.

Reconnaissance — Attacker IP and Tooling

Initial threat hunting groups activity by source IP and User-Agent to surface anomalous tooling. Filtering out AWS-internal traffic and ranking by distinct identity count exposes the attacker immediately:

fields @timestamp, sourceIPAddress, userAgent, userIdentity.userName, userIdentity.type
| filter sourceIPAddress not like "amazonaws.com"
| stats count(*) as calls, count_distinct(userIdentity.userName) as identities by sourceIPAddress, userAgent
| sort identities desc, calls desc

52.59.194.168 appears across multiple rows with multiple tools — TruffleHog (secret scanning and credential validation) and Pacu/1.5.2 (open-source AWS exploitation framework). The User-Agent field in CloudTrail is the critical signal here — legitimate AWS tooling stamps itself as Boto3, aws-cli, or Terraform; offensive tools identify themselves just as clearly if you look.

Initial Access — S3 Bucket Discovery and Credential Theft

With the attacker IP confirmed, filtering CloudTrail for S3 activity from that IP reveals the first action taken:

fields @timestamp, eventName, requestParameters.bucketName, sourceIPAddress
| filter sourceIPAddress = "52.59.194.168"
| filter eventSource = "s3.amazonaws.com"
| sort @timestamp asc

The attacker issued ListObjects against maromalix-website-assets-prod-83c9fdc8 at 12:53 UTC — a publicly accessible bucket containing exposed credentials. TruffleHog scanned the bucket contents, discovered the svc-jenkins service account keys, and automatically validated them against the AWS STS API. The GetCallerIdentity calls visible at 12:51 are TruffleHog’s validation step — confirming the keys are live before proceeding.

Enumeration — IAM Identity and Role Discovery

With validated svc-jenkins credentials, Pacu begins systematic IAM enumeration. Filtering all attacker activity in chronological order surfaces the full identity chain:

fields @timestamp, eventName, userIdentity.userName, userIdentity.type, userIdentity.arn
| filter sourceIPAddress = "52.59.194.168"
| sort @timestamp asc
| limit 20

Between 12:54 and 12:57, Pacu fires GetRole, ListUserPolicies, ListAttachedUserPolicies, ListPolicies, ListRoles, ListUsers, and ListGroups in rapid succession — the standard permission enumeration sequence to map privilege escalation paths. At 13:01, the attacker identifies an overly permissive trust policy on Maromalix-DevOps-Role and assumes it with the custom session name DevOpsing_maromalix.

Custom session names are an attacker tell — they allow the operator to track their own sessions across API calls. In this case it also inadvertently creates a consistent filter target for defenders.

Credential Exfiltration — Secrets Manager

Filtering activity under the DevOpsing_maromalix assumed role session shows the full post-escalation enumeration sequence:

fields @timestamp, eventName, eventSource, userIdentity.arn
| filter userIdentity.arn like "DevOpsing_maromalix"
| sort @timestamp asc

KMS Decrypt calls at 13:03, DescribeInstances at 13:03, then ListSecrets against Secrets Manager at 13:04 — Pacu is methodically working through services. GetSecretValue is called multiple times at 13:07, with maromalix/automation/ssm-credentials being the first secret retrieved. SSM credentials from Secrets Manager are a high-value target — they provide direct access to EC2 instances via AWS Systems Manager without requiring network exposure.

This maps to T1555.006 — Credentials from Password Stores: Cloud Secrets Management Stores.

Privilege Escalation — Role Chaining via SSM

With the SSM credentials in hand, the attacker assumes a second role. Querying all AssumeRole events confirms the pivot:

fields @timestamp, eventName, requestParameters.roleArn, requestParameters.roleSessionName, userIdentity.arn, sourceIPAddress
| filter eventName = "AssumeRole"
| sort @timestamp asc

The Maromalix-SSM-Automation-Role is the pivot role, confirmed by the SSM activity that follows immediately after. The attacker then uses that role to execute commands remotely on an EC2 instance:

fields @timestamp, eventName, requestParameters.instanceIds.0, sourceIPAddress
| filter sourceIPAddress = "52.59.194.168"
| filter eventSource = "ssm.amazonaws.com"
| sort @timestamp asc

SendCommand is issued against instance i-0afb277aeec0e6fa4 at 13:24 UTC. The command runs on the instance and curls the Instance Metadata Service endpoint (http://169.254.169.254/latest/meta-data/iam/security-credentials/) to retrieve the temporary IAM credentials attached to the instance profile. This is a well-known IMDS credential theft technique — no network exposure required, no credentials stored on disk, and the API call originates from the instance itself making attribution harder.

The stolen instance credentials belong to Maromalix-EC2-WebApp-Role.

Discovery — Lambda Function Enumeration

Operating as the EC2 WebApp role, the attacker pivots to Lambda enumeration. All Lambda API calls from the attacker IP surface the function names and the final invocation:

fields @timestamp, eventName, requestParameters.functionName, userIdentity.arn, sourceIPAddress
| filter eventSource = "lambda.amazonaws.com"
| filter sourceIPAddress = "52.59.194.168"
| sort @timestamp asc

ListFunctions at 13:04 under the DevOps role gives the attacker the full function inventory. Then under the WebApp role, GetFunction20150331v2 is called against maromalix-daily-backup first at 13:28, then maromalix-email-notifications. The attacker downloads both function configurations and code packages to inspect them — maromalix-daily-backup is discarded as unsuitable, while maromalix-email-notifications is identified as capable of sending emails via the configured SES identity. The function is then invoked twice.

Impact — Fraudulent Invoice Delivery

Pivoting to the /aws/lambda/maromalix-email-notifications log group, the invocation payloads are visible in the execution logs:

fields @timestamp, @message
| filter @message like "EMAIL_SEND_ATTEMPT"
| sort @timestamp asc

The first invocation at 13:49:46 UTC sends to the internal address billing@maromalix.cloud — placing a copy inside the victim organisation’s own email system to create a paper trail and add legitimacy. The second at 13:50 sends to billing@techcorp.live — the actual target.

The invoice body impersonates Maromalix Financial Technologies, references invoice #11000074454 for $49,900.00 in fabricated services, includes real-looking ACH banking details, and directs any queries to two attacker-controlled contact addresses: j.hepzibah@cfp-impactaction.com and ar@zoominfopay.com. Both domains are part of the TruffleNet BEC infrastructure documented by Fortinet FortiGuard Labs.

This maps to T1657 — Financial Theft.


Attack Summary

Phase Action
Reconnaissance TruffleHog scans public S3 bucket maromalix-website-assets-prod-83c9fdc8, discovers svc-jenkins credentials
Validation GetCallerIdentity confirms stolen keys are live
Enumeration Pacu/1.5.2 maps IAM roles, policies, and users from svc-jenkins context
Privilege Escalation svc-jenkins assumes Maromalix-DevOps-Role with session name DevOpsing_maromalix
Credential Exfiltration ListSecrets + GetSecretValue against Secrets Manager — maromalix/automation/ssm-credentials retrieved
Lateral Movement SSM credentials used to assume Maromalix-SSM-Automation-Role
IMDS Abuse SendCommand on i-0afb277aeec0e6fa4 curls IMDS to steal EC2 instance credentials
Discovery GetFunction on maromalix-daily-backup and maromalix-email-notifications — code inspected
Impact maromalix-email-notifications invoked twice — fraudulent $49,900 invoice sent to billing@maromalix.cloud and billing@techcorp.live

IOCs

Type Value
Attacker IP 52[.]59[.]194[.]168
Compromised S3 Bucket maromalix-website-assets-prod-83c9fdc8
Compromised IAM User svc-jenkins
Role (First Pivot) Maromalix-DevOps-Role
Session Name DevOpsing_maromalix
Role (Second Pivot) Maromalix-SSM-Automation-Role
Role (IMDS Stolen) Maromalix-EC2-WebApp-Role
EC2 Instance i-0afb277aeec0e6fa4
Secret ID maromalix/automation/ssm-credentials
Lambda (Weaponised) maromalix-email-notifications
Internal Recipient billing@maromalix[.]cloud
External Victim billing@techcorp[.]live
Attacker Domain cfp-impactaction[.]com
Attacker Domain zoominfopay[.]com
Invoice Amount $49,900.00
Invoice Number #11000074454
Campaign TruffleNet

MITRE ATT&CK

Technique ID Description
Cloud Service Discovery T1526 Pacu enumerates IAM roles, policies, Lambda functions, and Secrets Manager inventory
Data from Cloud Storage T1530 TruffleHog retrieves credential files from public S3 bucket
Valid Accounts: Cloud Accounts T1078.004 Stolen svc-jenkins keys used to authenticate to AWS
Use Alternate Authentication Material T1550.001 Temporary credentials from IMDS used to operate as EC2 instance role
Credentials from Password Stores: Cloud Secrets Management Stores T1555.006 GetSecretValue against AWS Secrets Manager to retrieve SSM credentials
Cloud Administration Command T1059.009 SSM SendCommand used to execute commands on EC2 instance
Financial Theft T1657 Fraudulent invoice sent via hijacked Lambda function to deceive TechCorp into wire transfer

Defender Takeaways

S3 buckets should never store credentials. The entire attack chain originates from a single exposed key in a public S3 bucket. Secrets belong in Secrets Manager or Parameter Store — not flat files in object storage. An S3 bucket policy blocking public access and an AWS Config rule enforcing this would have eliminated the initial access vector entirely.

IAM roles need scoped trust policies. Maromalix-DevOps-Role had a trust policy permissive enough for svc-jenkins — a CI service account — to assume it. Trust policies should explicitly enumerate which principals can assume a role, and service account permissions should be scoped to only what CI/CD pipelines require. The new administrator’s permission changes during onboarding directly created this path.

IMDS v2 should be enforced on all EC2 instances. IMDSv2 requires a session token obtained via a PUT request before credentials are accessible, which prevents the simple curl technique used here. Enforcing IMDSv2 via instance metadata options or an SCP makes IMDS credential theft significantly harder. Additionally, monitoring for GetMetadata calls in conjunction with SSM SendCommand events is a high-fidelity detection opportunity.

CloudTrail User-Agent strings are a detection primitive. TruffleHog and Pacu/1.5.2 both stamp their names in the userAgent field. An alerting rule matching known offensive tool names in CloudTrail User-Agents would have flagged the attack within minutes of the first API call. This is a low-effort, high-signal detection with minimal false positive risk.

Lambda functions that send email are high-value targets. Any function with SES permissions and the ability to accept external invocation payloads is a BEC primitive waiting to be weaponised. Lambda functions that send email should validate recipients and content server-side against an allowlist, and invocations should be logged and alerted on when the invoking identity is unexpected — particularly when an EC2 instance role invokes an email function directly.


During the initial threat hunting phase, analysis of CloudTrail logs revealed API calls from multiple source IP addresses. One IP address stood out as highly suspicious due to its association with multiple identities and offensive security tooling. What is this attacker's IP address?
Click flag to reveal 52.59.194.168
The attacker's first action was to probe for publicly accessible resources. What is the full name of the S3 bucket they discovered?
Click to reveal answer maromalix-website-assets-prod-83c9fdc8
The attacker used a tool designed to scan repositories and file systems for exposed secrets, then automatically validate any discovered credentials. What is the name of this tool?
Click flag to reveal TruffleHog
The credentials discovered by the attacker belonged to a service account. What is the name of this initially compromised user?
Click to reveal answer svc-jenkins
To systematically enumerate the AWS environment and discover potential privilege escalation paths, the attacker used an open-source cloud exploitation framework. Provide the name and version of this tool as recorded in the logs.
Click flag to reveal Pacu/1.5.2
The attacker discovered an overly permissive trust policy and escalated their privileges. What is the name of the first role the attacker successfully assumed?
Click to reveal answer Maromalix-DevOps-Role
When assuming the new role, the attacker specified a custom session name to identify their session. What was this session name?
Click flag to reveal DevOpsing_maromalix
With elevated privileges, the attacker enumerated several AWS services looking for sensitive data. Which AWS service did they successfully query to discover stored credentials and secrets?
Click to reveal answer Secrets Manager
After discovering the secrets inventory, the attacker began exfiltrating credentials. What is the ID of the first secret the attacker retrieved?
Click flag to reveal maromalix/automation/ssm-credentials
What is the MITRE ATT&CK technique ID that corresponds to this credential exfiltration behavior?
Click to reveal answer T1555.006
Using credentials obtained from the exfiltrated secrets, the attacker pivoted to a different IAM role. What is the full name of this role?
Click flag to reveal Maromalix-SSM-Automation-Role
The attacker used their new role to remotely execute commands on an EC2 instance and steal its IAM credentials via the Instance Metadata Service (IMDS). Provide the API call used to execute commands and the instance ID of the compromised machine, separated by a comma.
Click to reveal answer SendCommand, i-0afb277aeec0e6fa4
With EC2 instance credentials, the attacker enumerated Lambda functions by downloading their configurations and code. What is the name of the first Lambda function the attacker retrieved?
Click flag to reveal maromalix-daily-backup
After examining multiple functions, the attacker identified one suitable for their attack. What is the name of the Lambda function he used to send fraudulent emails?
Click to reveal answer maromalix-email-notifications
The attacker sent fraudulent emails to two recipients. Provide both email addresses separated by a comma, with the internal recipient first.
Click flag to reveal billing@maromalix.cloud, billing@techcorp.live
The fraudulent invoice included attacker-controlled contact email addresses. What are the two domains used for these contact addresses? (Provide both domains separated by a comma, in alphabetical order)
Click to reveal answer cfp-impactaction.com, zoominfopay.com
The attacker's ultimate goal was to deceive the victim into transferring funds via a fraudulent invoice. What is the MITRE ATT&CK technique ID that corresponds to this impact?
Click flag to reveal T1657
Based on the tools, TTPs, and infrastructure patterns observed in this investigation, this incident matches a known threat campaign. What is the name of this campaign?
Click to reveal answer trufflenet
🔒
// active lab
writeup locked
withheld in accordance with platform guidelines
to avoid spoiling live challenges.
password provided to recruiters on request.