Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit be8afb3

Browse files
committed
Added a new Hook "nmap-subsequent-scans" which implements an imperative scanner combination approach
1 parent ef1f865 commit be8afb3

File tree

15 files changed

+414
-1
lines changed

15 files changed

+414
-1
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,14 @@ jobs:
214214
repository: scbexperimental/generic-webhook
215215
path: ./hooks/generic-webhook/
216216
tag_with_ref: true
217+
- uses: docker/build-push-action@v1
218+
name: "Build & Push NmapSubsequentScans Hook Image"
219+
with:
220+
username: ${{ secrets.DOCKER_USERNAME }}
221+
password: ${{ secrets.DOCKER_PASSWORD }}
222+
repository: scbexperimental/hook-nmap-subsequent-scans
223+
path: ./hooks/nmap-subsequent-scans/
224+
tag_with_ref: true
217225
scannerImages:
218226
# Note we only build images for scanner that don't provider official public container images
219227
name: "Build / Scanner"

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- [Prerequisites](#prerequisites)
2323
- [Deployment](#deployment)
2424
- [Examples](#examples)
25+
- [Access Services](#access-services)
2526
- [How does it work?](#how-does-it-work)
2627
- [Architecture](#architecture)
2728
- [License](#license)
@@ -62,7 +63,7 @@ There is a german article about [Security DevOps – Angreifern (immer) einen Sc
6263
```bash
6364
# Deploy secureCodeBox Operator
6465
kubectl create namespace securecodebox-system
65-
helm -n securecodebox-system install securecodebox-operator ./operator/
66+
helm -n securecodebox-system install securecodebox-operator ./operator/ --set image.tag=hooks
6667

6768
# Deploy definitions for the integrated scanners
6869
helm install amass ./integrations/amass/
@@ -73,13 +74,15 @@ helm install ssh-scan ./integrations/ssh_scan/
7374
helm install sslyze ./integrations/sslyze/
7475
helm install trivy ./integrations/trivy/
7576
helm install zap ./integrations/zap/
77+
helm install wpscan ./integrations/wpscan/
7678

7779
# Optional Deploy some Demo Apps for scanning
7880
helm install dummy-ssh ./demo-apps/dummy-ssh/
7981

8082
# Deploy secureCodeBox Hooks
8183
helm install add-attributes ./hooks/add-attributes/
8284
helm install generic-webhook ./hooks/generic-webhook/
85+
helm install nmap-subsequent-scans ./hooks/nmap-subsequent-scans/
8386

8487
## Persistence Provider: Elasticsearch
8588
helm install persistence-elastic ./hooks/persistence-elastic/
@@ -98,15 +101,30 @@ kubectl apply -f operator/config/samples/execution_v1_scan/trivy_mediawiki.yaml
98101
kubectl apply -f operator/config/samples/execution_v1_scan/trivy_juiceshop.yaml
99102
## Public Scan Examples
100103
# E.g. www.securecodebox.io sslyze scan
104+
kubectl apply -f operator/config/samples/execution_v1_scan/nmap_securecodebox_io.yaml
101105
kubectl apply -f operator/config/samples/execution_v1_scan/amass_securecodebox_io.yaml
102106
kubectl apply -f operator/config/samples/execution_v1_scan/sslyze_securecodebox_io.yaml
103107
kubectl apply -f operator/config/samples/execution_v1_scan/nikto_securecodebox_io.yaml
104108

105109
kubectl apply -f operator/config/samples/execution_v1_scan/ssh_iteratec_de.yaml
110+
kubectl apply -f operator/config/samples/execution_v1_scan/wpscan_nurdemteam_org.yaml
106111
# Then get the current State of the Scan by running:
107112
kubectl get scans
108113
```
109114

115+
### Access Services
116+
117+
* Minio UI
118+
* AccessKey: `kubectl get secret securecodebox-operator-minio -n securecodebox-system -o=jsonpath='{.data.accesskey}' | base64 --decode; echo`
119+
* SecretKey: `kubectl get secret securecodebox-operator-minio -n securecodebox-system -o=jsonpath='{.data.secretkey}' | base64 --decode; echo`
120+
* Port Forward Minio UI: `kubectl port-forward -n securecodebox-system service/securecodebox-operator-minio 9000:9000`
121+
* Elastic / Kibana UI
122+
* User: `elastic`
123+
* Password: `kubectl get secret scb-elasticsearch-es-elastic-user -n scb-analytics -o=jsonpath='{.data.elastic}' | base64 --decode; echo`
124+
* Port Forward Kibana: `kubectl port-forward -n default service/persistence-elastic-kibana 5601:5601`
125+
* Port Forward Elasticsearch: `kubectl port-forward -n default service/elasticsearch-master 9200:9200`
126+
127+
110128
## How does it work?
111129

112130
## Architecture
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*~
18+
# Various IDEs
19+
.project
20+
.idea/
21+
*.tmproj
22+
.vscode/
23+
# Node.js files
24+
node_modules/*
25+
package.json
26+
package-lock.json
27+
src/*
28+
config/*
29+
Dockerfile
30+
.dockerignore
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dependencies: []
2+
digest: sha256:643d5437104296e21d906ecb15b2c96ad278f20cfc4af53b12bb6069bd853726
3+
generated: "2020-05-26T16:56:03.119255+02:00"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v2
2+
name: nmap-subsequent-scans
3+
description: Starts possible subsequent security scans based on nmap findings with open ports.
4+
5+
type: application
6+
7+
version: 0.1.0
8+
9+
appVersion: latest
10+
11+
dependencies: []
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM scbexperimental/hook-sdk-nodejs:latest
2+
WORKDIR /home/app/hook-wrapper/hook/
3+
COPY --chown=app:app ./hook.js ./hook.js
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
const k8s = require('@kubernetes/client-node');
2+
3+
// configure k8s client
4+
const kc = new k8s.KubeConfig();
5+
kc.loadFromDefault();
6+
7+
const k8sApiCRD = kc.makeApiClient(k8s.CustomObjectsApi);
8+
9+
async function handle({
10+
getFindings,
11+
attributeName = process.env["ATTRIBUTE_NAME"],
12+
attributeValue = process.env["ATTRIBUTE_VALUE"],
13+
}) {
14+
15+
const findings = await getFindings();
16+
17+
console.log(findings);
18+
19+
// const sslyzeYaml = k8s.dumpYaml(sslyzeJSONString);
20+
// const sslyzeYaml = k8s.loadYaml(sslyzeScanDefinition);
21+
22+
console.log(`Found #${findings.length} findings... trying to find possible subsequent security scans.`);
23+
24+
for (const finding of findings) {
25+
if(finding.category == "Open Port") {
26+
console.log("Found open port finding for service: " + finding.attributes.port);
27+
28+
if(finding.attributes.state = "open") {
29+
30+
// search for HTTP ports and start subsequent Nikto Scan
31+
if(finding.attributes.service == "http" ) {
32+
console.log(" --> starting HTTP Service Scan: Nikto")
33+
34+
startNiktoScan(finding.attributes.hostname, finding.attributes.port);
35+
}
36+
37+
// search for HTTPS ports and start subsequent SSLyze Scan
38+
if(finding.attributes.service == "ssl" || finding.attributes.service == "https") {
39+
console.log(" --> starting HTTP(S) Service Scan: SSLyze")
40+
startSSLyzeScan(finding.attributes.hostname, finding.attributes.port);
41+
42+
console.log(" --> starting HTTP(S) Service Scan: ZAP Baseline Scan")
43+
startZAPBaselineScan(finding.attributes.hostname, finding.attributes.port);
44+
}
45+
46+
// search for HTTPS ports and start subsequent SSH Scan
47+
if(finding.attributes.service == "ssh" ) {
48+
console.log(" --> starting SSH Service Scan: SSH")
49+
50+
startSSHScan(finding.attributes.hostname, finding.attributes.port);
51+
}
52+
}
53+
}
54+
}
55+
56+
// const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
57+
58+
// console.log("list namespaced Pods")
59+
// k8sApi.listNamespacedPod('default').then((res) => {
60+
// console.log(res.body);
61+
// });
62+
63+
// const k8sApiCRD = kc.makeApiClient(k8s.CustomObjectsApi);
64+
65+
// // found at: https://github.com/kubernetes-client/javascript/issues/144
66+
// console.log("list namespaced CRDs")
67+
// k8sApiCRD.listNamespacedCustomObject(
68+
// 'execution.experimental.securecodebox.io',
69+
// 'v1',
70+
// 'default',
71+
// 'scans',
72+
// 'false'
73+
// ).then((res) => {
74+
// console.log(res.body);
75+
// });
76+
}
77+
78+
/**
79+
* Creates a new subsequent SCB ZAP Scan for the given hostname.
80+
* @param {*} hostname The hostname to start a new subsequent ZAP scan for.
81+
* @param {*} port The port to start a new subsequent ZAP scan for.
82+
*/
83+
function startZAPBaselineScan(hostname, port) {
84+
const zapScanDefinition = {
85+
apiVersion: "execution.experimental.securecodebox.io/v1",
86+
kind: "Scan",
87+
metadata: {
88+
"name": "zap-" + hostname.toLowerCase(),
89+
"labels": {
90+
"organization": "secureCodeBox"
91+
}
92+
},
93+
spec: {
94+
"scanType": "zap-baseline",
95+
"parameters": [
96+
"-t",
97+
"https://" + hostname + ":" + port
98+
]
99+
}
100+
};
101+
102+
// Starting another subsequent sslyze scan based on the nmap results
103+
// found at: https://github.com/kubernetes-client/javascript/blob/79736b9a608c18d818de61a6b44503a08ea3a78f/src/gen/api/customObjectsApi.ts#L209
104+
k8sApiCRD.createNamespacedCustomObject(
105+
'execution.experimental.securecodebox.io',
106+
'v1',
107+
'default',
108+
'scans',
109+
zapScanDefinition,
110+
'false'
111+
).then((res) => {
112+
console.log(res.body);
113+
})
114+
.catch((e) => {
115+
console.log(e);
116+
});
117+
}
118+
119+
/**
120+
* Creates a new subsequent SCB SSH Scan for the given hostname.
121+
* @param {*} hostname The hostname to start a new subsequent SSH scan for.
122+
* @param {*} port The port to start a new subsequent SSH scan for.
123+
*/
124+
function startSSHScan(hostname, port) {
125+
const sshScanDefintion = {
126+
"apiVersion": "execution.experimental.securecodebox.io/v1",
127+
"kind": "Scan",
128+
"metadata": {
129+
"name": "ssh-" + hostname.toLowerCase(),
130+
"labels": {
131+
"organization": "secureCodeBox"
132+
}
133+
},
134+
"spec": {
135+
"scanType": "ssh-scan",
136+
"parameters": [
137+
"-t",
138+
hostname
139+
]
140+
}
141+
};
142+
143+
// Starting another subsequent sslyze scan based on the nmap results
144+
// found at: https://github.com/kubernetes-client/javascript/blob/79736b9a608c18d818de61a6b44503a08ea3a78f/src/gen/api/customObjectsApi.ts#L209
145+
k8sApiCRD.createNamespacedCustomObject(
146+
'execution.experimental.securecodebox.io',
147+
'v1',
148+
'default',
149+
'scans',
150+
sshScanDefintion,
151+
'false'
152+
).then((res) => {
153+
console.log(res.body);
154+
})
155+
.catch((e) => {
156+
console.log(e);
157+
});
158+
}
159+
160+
/**
161+
* Creates a new subsequent SCB Nikto Scan for the given hostname.
162+
* @param {*} hostname The hostname to start a new subsequent Nikto scan for.
163+
* @param {*} port The port to start a new subsequent Nikto scan for.
164+
*/
165+
function startNiktoScan(hostname, port) {
166+
const niktoScanDefinition = {
167+
"apiVersion": "execution.experimental.securecodebox.io/v1",
168+
"kind": "Scan",
169+
"metadata": {
170+
"name": "nikto-" + hostname.toLowerCase(),
171+
"labels": {
172+
"organization": "secureCodeBox"
173+
}
174+
},
175+
"spec": {
176+
"scanType": "nikto",
177+
"parameters": [
178+
"-h",
179+
"https://" + hostname,
180+
"-Tuning",
181+
"1,2,3,5,7,b"
182+
]
183+
}
184+
};
185+
186+
// Starting another subsequent sslyze scan based on the nmap results
187+
// found at: https://github.com/kubernetes-client/javascript/blob/79736b9a608c18d818de61a6b44503a08ea3a78f/src/gen/api/customObjectsApi.ts#L209
188+
k8sApiCRD.createNamespacedCustomObject(
189+
'execution.experimental.securecodebox.io',
190+
'v1',
191+
'default',
192+
'scans',
193+
niktoScanDefinition,
194+
'false'
195+
).then((res) => {
196+
console.log(res.body);
197+
})
198+
.catch((e) => {
199+
console.log(e);
200+
});
201+
}
202+
203+
/**
204+
* Creates a new subsequent SCB SSLyze Scan for the given hostname.
205+
* @param {*} hostname The hostname to start a new subsequent SSLyze scan for.
206+
* @param {*} port The port to start a new subsequent SSLyze scan for.
207+
*/
208+
function startSSLyzeScan(hostname, port) {
209+
const sslyzeScanDefinition = {
210+
apiVersion: 'execution.experimental.securecodebox.io/v1',
211+
kind: 'Scan',
212+
metadata: {
213+
"name": "sslyze-" + hostname.toLowerCase(),
214+
"labels": {
215+
"organization": "secureCodeBox"
216+
}
217+
},
218+
"spec": {
219+
"scanType": "sslyze",
220+
"parameters": [
221+
"--regular",
222+
hostname
223+
]
224+
}
225+
};
226+
227+
// Starting another subsequent sslyze scan based on the nmap results
228+
// found at: https://github.com/kubernetes-client/javascript/blob/79736b9a608c18d818de61a6b44503a08ea3a78f/src/gen/api/customObjectsApi.ts#L209
229+
k8sApiCRD.createNamespacedCustomObject(
230+
'execution.experimental.securecodebox.io',
231+
'v1',
232+
'default',
233+
'scans',
234+
sslyzeScanDefinition,
235+
'false'
236+
).then((res) => {
237+
console.log(res.body);
238+
})
239+
.catch((e) => {
240+
console.log(e);
241+
});
242+
}
243+
244+
module.exports.handle = handle;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const { handle } = require("./hook");
2+

0 commit comments

Comments
 (0)