diff --git a/Dockerfile b/Dockerfile index ab5b80b2..e513919c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ COPY --from=builder ./scb-scanprocesses/combined-amass-nmap-process/target/combi COPY --from=builder ./scb-scanprocesses/combined-nmap-nikto-process/target/combined-nmap-nikto-process-0.0.1-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-scanprocesses/sslyze-process/target/sslyze-process-0.0.1-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-scanprocesses/arachni-process/target/arachni-process-1.0-SNAPSHOT.jar /scb-engine/lib/ +COPY --from=builder ./scb-scanprocesses/ssh-process/target/ssh-process-1.0-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-scanprocesses/amass-process/target/amass-process-1.0-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-persistenceproviders/elasticsearch-persistenceprovider/target/elasticsearch-persistenceprovider-0.0.1-SNAPSHOT-jar-with-dependencies.jar /scb-engine/lib/ diff --git a/dependency-check-suppression.xml b/dependency-check-suppression.xml index 26b693ba..55143e31 100644 --- a/dependency-check-suppression.xml +++ b/dependency-check-suppression.xml @@ -38,5 +38,12 @@ CVE-2016-5425 + + + CVE-2019-0232 + + diff --git a/pom.xml b/pom.xml index 6970ff7b..cb8ef41b 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 3.2.0 - 2.1.2.RELEASE + 2.1.4.RELEASE 2.9.0 UTF-8 diff --git a/scb-engine/pom.xml b/scb-engine/pom.xml index 152cb118..a0325da1 100644 --- a/scb-engine/pom.xml +++ b/scb-engine/pom.xml @@ -189,6 +189,12 @@ 0.0.1-SNAPSHOT runtime + + io.securecodebox.scanprocesses + ssh-process + 1.0-SNAPSHOT + runtime + io.securecodebox.persistenceproviders elasticsearch-persistenceprovider diff --git a/scb-engine/src/main/resources/application-dev.yaml b/scb-engine/src/main/resources/application-dev.yaml index 464812d0..3b2c7b5c 100644 --- a/scb-engine/src/main/resources/application-dev.yaml +++ b/scb-engine/src/main/resources/application-dev.yaml @@ -11,8 +11,4 @@ logging.level.io.securecodebox: DEBUG # - elasticsearch securecodebox.rest.user.scanner-default: user-id: defaultScanner - password: scan - -securecodebox.persistence.defectdojo.url: -securecodebox.persistence.defectdojo.auth.key: -securecodebox.persistence.defectdojo.auth.name: \ No newline at end of file + password: scan \ No newline at end of file diff --git a/scb-scanprocesses/arachni-process/src/main/resources/forms/arachni/approve-results.html b/scb-scanprocesses/arachni-process/src/main/resources/forms/arachni/approve-results.html index b982553f..38311f4c 100644 --- a/scb-scanprocesses/arachni-process/src/main/resources/forms/arachni/approve-results.html +++ b/scb-scanprocesses/arachni-process/src/main/resources/forms/arachni/approve-results.html @@ -91,7 +91,7 @@

Portscan results for "{{ target.name }}"

class="glyphicon glyphicon-education"> {{ result.severity }} - + {{ result.reference.id }} diff --git a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/configure-port-scanner-target.html b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/configure-port-scanner-target.html index c5e1ddd2..65812953 100644 --- a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/configure-port-scanner-target.html +++ b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/configure-port-scanner-target.html @@ -97,7 +97,7 @@

Portscan Target

ng-minlength="2" ng-maxlength="256" ng-model="target.location" - ng-pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/" + ng-pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-\/]*[A-Za-z0-9])$/" ng-keydown="checkForEnter($event)" /> diff --git a/scb-scanprocesses/pom.xml b/scb-scanprocesses/pom.xml index 893eaf16..6079d5da 100644 --- a/scb-scanprocesses/pom.xml +++ b/scb-scanprocesses/pom.xml @@ -23,6 +23,7 @@ combined-amass-nmap-process arachni-process amass-process + ssh-process \ No newline at end of file diff --git a/scb-scanprocesses/ssh-process/pom.xml b/scb-scanprocesses/ssh-process/pom.xml new file mode 100644 index 00000000..9b1d9897 --- /dev/null +++ b/scb-scanprocesses/ssh-process/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + + io.securecodebox.scanprocesses + default-process-collection + 0.0.1-SNAPSHOT + + + io.securecodebox.scanprocesses + ssh-process + 1.0-SNAPSHOT + + + + io.securecodebox.core + sdk + ${project.parent.version} + + + + + com.h2database + h2 + + + org.camunda.bpm.springboot + camunda-bpm-spring-boot-starter-test + test + + + org.camunda.bpm.extension.mockito + camunda-bpm-mockito + test + + + org.camunda.bpm.extension + camunda-bpm-assert-scenario + test + + + org.camunda.bpm.extension + camunda-bpm-process-test-coverage + test + + + org.camunda.bpm.extension + camunda-bpm-assert + + + + diff --git a/scb-scanprocesses/ssh-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java b/scb-scanprocesses/ssh-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java new file mode 100644 index 00000000..6912cde3 --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java @@ -0,0 +1,36 @@ +/* + * + * SecureCodeBox (SCB) + * Copyright 2015-2018 iteratec GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package io.securecodebox.scanprocess; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +/** + * The secureCodeBox by default only scans for components in the package io.securecodebox.scanprocess. + *

+ * This configuration ensures that your defined package package also gets scanned, please don't move or remove this configuration. + * + * @author RĂ¼diger Heins - iteratec GmbH + * @since 09.05.18 + */ +@ComponentScan("io.securecodebox.scanprocesses") +@Configuration +public class ProcessInitConfiguration { +} diff --git a/scb-scanprocesses/ssh-process/src/main/resources/META-INF/processes.xml b/scb-scanprocesses/ssh-process/src/main/resources/META-INF/processes.xml new file mode 100644 index 00000000..e69de29b diff --git a/scb-scanprocesses/ssh-process/src/main/resources/bpmn/mozilla_ssh_process.bpmn b/scb-scanprocesses/ssh-process/src/main/resources/bpmn/mozilla_ssh_process.bpmn new file mode 100644 index 00000000..ef222bab --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/main/resources/bpmn/mozilla_ssh_process.bpmn @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + SequenceFlow_TargetConfigured + + + + SequenceFlow_SummaryCreated + + + + + + + + SequenceFlow_ManualFinish + SequenceFlow_ResultReviewed + + + SequenceFlow_ResultReviewed + SequenceFlow_ResultApproved + SequenceFlow_ResultRejected + + + + + + SequenceFlow_PortscanFinished + SequenceFlow_ManualFinish + SequenceFlow_AutomatedFinish + + + ${PROCESS_AUTOMATED == false} + + + ${PROCESS_AUTOMATED == true} + + + + SequenceFlow_TargetConfigured + SequenceFlow_PortscanFinished + + + + + SequenceFlow_ResultApproved + SequenceFlow_1i44eck + SequenceFlow_AutomatedFinish + SequenceFlow_SummaryCreated + + + + + + + + SequenceFlow_ResultRejected + SequenceFlow_1i44eck + + + + results in a generic format + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/approve-results.html b/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/approve-results.html new file mode 100644 index 00000000..051bdfd0 --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/approve-results.html @@ -0,0 +1,122 @@ + + +

+ + +
+

SSH scan results for "{{ target.name }}"

+ +
+
+
{{ scannerId }}
+
+
+
+
{{ target.location }}
+
+
+
+
{{ context }}
+
+
+
+
+ + + + + + + + + + + + + + + + + +
Host:Name:Description:Category:Severity:Reference:
{{ result.location }}{{ result.name }}{{ result.description }}{{ result.category }} +
+ + + {{ result.severity }} + + + + + {{ result.severity }} + + + + + {{ result.severity }} + + + + + {{ result.severity }} + +
+
{{ result.reference.id }}
+
+
+
+
+

Approve Result

+ +
+ +
+ + +
+
+
diff --git a/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/configure-target.html b/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/configure-target.html new file mode 100644 index 00000000..383ad225 --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/main/resources/forms/ssh/configure-target.html @@ -0,0 +1,127 @@ + + +

Please configure the SSH Scan

+ +
+ + + +
+ +
+

SSH scan Target

+ + +
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+ + +
+ +
+ +
+
+ +
+
+
diff --git a/scb-scanprocesses/ssh-process/src/test/java/io/securecodebox/scanprocess/test/MozillaSshProcessTest.java b/scb-scanprocesses/ssh-process/src/test/java/io/securecodebox/scanprocess/test/MozillaSshProcessTest.java new file mode 100644 index 00000000..b95f3145 --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/test/java/io/securecodebox/scanprocess/test/MozillaSshProcessTest.java @@ -0,0 +1,231 @@ +/* + * + * SecureCodeBox (SCB) + * Copyright 2015-2018 iteratec GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package io.securecodebox.scanprocess.test; + +import io.securecodebox.constants.DefaultFields; +import io.securecodebox.scanprocess.delegate.SummaryGeneratorDelegate; +import org.camunda.bpm.engine.ExternalTaskService; +import org.camunda.bpm.engine.delegate.DelegateTask; +import org.camunda.bpm.engine.delegate.Expression; +import org.camunda.bpm.engine.delegate.TaskListener; +import org.camunda.bpm.engine.externaltask.LockedExternalTask; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.camunda.bpm.engine.test.Deployment; +import org.camunda.bpm.engine.test.ProcessEngineRule; +import org.camunda.bpm.engine.test.mock.Mocks; +import org.camunda.bpm.extension.process_test_coverage.junit.rules.TestCoverageProcessEngineRuleBuilder; +import org.camunda.bpm.scenario.ProcessScenario; +import org.camunda.bpm.scenario.Scenario; +import org.camunda.bpm.scenario.delegate.ExternalTaskDelegate; +import org.camunda.bpm.scenario.delegate.TaskDelegate; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.camunda.bpm.engine.test.assertions.ProcessEngineTests.*; +import static org.camunda.bpm.extension.mockito.CamundaMockito.autoMock; +import static org.mockito.Mockito.when; + +/** + * This class tests the process execution of the Default-Process BPMN Model + * It verifies that each process task is called when it's supposed to be and + * delegation code is executed at the right time + *

+ * The tests run in an own Camunda engine which is defined by the camunda.cfg.xml in the resources directory + *

+ * The test cases use Camunda BPM's standard framework as well as the + * Camunda BPM Assert extension (), + * camunda-bpm-mockito () + * and the Camunda BPM Assert Scenario extension () + *

+ * Furthermore this class also uses the Camunda BPM Process Test Coverage extension + * (). + * After the test is run we can examine the test coverage in the directory target/process-test-coverage + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@Deployment(resources = "bpmn/mozilla_ssh_process.bpmn") + +@Ignore("Ignored until problems with camunda testing frameworks are handled. Introduces via update to camunda 7.10") +public class MozillaSshProcessTest { + + //Define the Process Activity IDs + private static final String PROCESS_ID = "ssh-process"; + private static final String DO_SCAN_TASK_ID = "ServiceTask_DoScan"; + private static final String CREATE_REPORT_TASK_ID = "ServiceTask_CreateSummary"; + private static final String APPROVE_RESULTS_TASK_ID = "UserTask_ApproveResults"; + + private final Map defaultVariables = new HashMap<>(); + + @Rule + @ClassRule + public static ProcessEngineRule processEngineRule = TestCoverageProcessEngineRuleBuilder.create().build(); + + @Mock + private ProcessScenario process; + + @Mock + SummaryGeneratorDelegate delegate; + + /** + * Executed before every test-case + * In this method default variables for the process and a default behaviour for the mocks + * in the process are defined+ + */ + @Before + public void init() { + + MockitoAnnotations.initMocks(this); + + //Creating a map of default variables for the process + defaultVariables.put(DefaultFields.PROCESS_AUTOMATED.name(), true); + defaultVariables.put(DefaultFields.PROCESS_CONTEXT.name(), "BodgeIT"); + + /* + Mocking everything in the BPMN Model + This includes ExecutionListeners, TaskListeners, JavaDelegates, etc. + Simply stated: Everything, that's executable code + + If you need to define custom behaviour for the Mocks you can do so by + registering Mocks with Camunda's method "Mocks.register(String key, Object value)". + Here the key describes a delegateExpression (as defined in BPMN model) and the value + describes the implementation of the code which should be executed + (Hint: You can put the real implementation as well as a fake one in there) + + Note: Most of the mocking methods seem to work only in combination with delegateExpressions + but not with class definitions as delegate implementation. + + If you have the path to your executable code (the class for delegate) as delegate implementation + then this guide is helpful: + https://blog.akquinet.de/2016/11/04/camunda-bpm-test-your-processes-based-on-plain-old-java-delegates/ + */ + autoMock("bpmn/mozilla_ssh_process.bpmn"); + + /* + Here we define a default behaviour for all the tasks in the BPMN model. + This behaviour can easily be overridden in test cases. + + The code inside the "thenReturn(...)" method specifies what should happen when process execution + waits at the given task + As a default behaviour we just complete the task and move on to the next one without changing anything + + Note that we have our own mock implementation in the last two when(...) statements. + This is because these tasks are external tasks which cannot be as easily completed as + ServiceTasks. They need an external worker to do so. + */ + when(process.waitsAtUserTask(Mockito.anyString())).thenReturn(TaskDelegate::complete); + when(process.waitsAtServiceTask(Mockito.anyString())).thenReturn(ExternalTaskDelegate::complete); + when(process.waitsAtServiceTask(DO_SCAN_TASK_ID)).thenReturn(task -> startExternalMockProcess("ssh-process")); + } + + @Test + public void testAutomatedStart_shouldPass() { + + ProcessInstance processInstance = runtimeService().startProcessInstanceByKey(PROCESS_ID, defaultVariables); + + assertThat(processInstance).isStarted(); + } + + @Test + public void testManualStartWithDefaultConfiguration_shouldPass() { + ProcessInstance processInstance = runtimeService().startProcessInstanceByKey(PROCESS_ID, defaultVariables); + + assertThat(processInstance).isStarted(); + assertThat(processInstance).isWaitingAt(DO_SCAN_TASK_ID); + } + + @Test + public void testManualRunWithApprovedTestResults() { + + Map variables = new HashMap<>(defaultVariables); + changeVariable(variables, DefaultFields.PROCESS_AUTOMATED.name(), false); + + when(process.waitsAtUserTask(APPROVE_RESULTS_TASK_ID)).thenReturn(task -> { + variables.put(DefaultFields.PROCESS_RESULT_APPROVED.name(), "approved"); + task.complete(variables); + }); + + /* + Here we register a custom mock. + The BPMN model TaskListener takes an injected field variable which cannot be mocked. + Therefore we create our own TaskListener with a dummy implementation and which also + holds the variable, that should be injected. + Then we register our TaskListener with "Mocks.register(...)" and it gets executed when the delegateExpression + is called. + */ + Mocks.register("setFormUrlListener", new TaskListener() { + + @Autowired + private Expression scanner_type; + + @Override + public void notify(DelegateTask delegateTask) { + } + }); + + Scenario scenario = Scenario.run(process).startByKey(PROCESS_ID, variables).execute(); + + assertThat(scenario.instance(process)).isEnded(); + assertThat(scenario.instance(process)).hasPassed(APPROVE_RESULTS_TASK_ID); + assertThat(scenario.instance(process)).variables() + .containsEntry(DefaultFields.PROCESS_RESULT_APPROVED.name(), "approved"); + } + + /** + * Executes an external process without doing anything in the task. + * In the first step the job is executed on the Camunda engine. Therefore the token for the + * provided topic gets pushed. Then an external service is called to pull the token and execute the task + * + * @param topic the topic for the external task + */ + private void startExternalMockProcess(String topic) { + + ExternalTaskService externalTaskService = processEngine().getExternalTaskService(); + List lockedExternalTasks = externalTaskService.fetchAndLock(1, "worker") + .topic(topic, 5000L) + .execute(); + + assertThat(lockedExternalTasks.size()).isEqualTo(1); + + LockedExternalTask task = lockedExternalTasks.get(0); + externalTaskService.complete(task.getId(), "worker"); + } + + private void changeVariable(Map variables, String key, Object value) { + + if (variables.containsKey(key)) { + variables.remove(key); + } + variables.put(key, value); + } + +} diff --git a/scb-scanprocesses/ssh-process/src/test/resources/camunda.cfg.xml b/scb-scanprocesses/ssh-process/src/test/resources/camunda.cfg.xml new file mode 100644 index 00000000..d5e7d6f9 --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/test/resources/camunda.cfg.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/scb-scanprocesses/ssh-process/src/test/resources/logback-test.xml b/scb-scanprocesses/ssh-process/src/test/resources/logback-test.xml new file mode 100644 index 00000000..81dcdbcd --- /dev/null +++ b/scb-scanprocesses/ssh-process/src/test/resources/logback-test.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/scb-sdk/src/main/java/io/securecodebox/scanprocess/delegate/SummaryGeneratorDelegate.java b/scb-sdk/src/main/java/io/securecodebox/scanprocess/delegate/SummaryGeneratorDelegate.java index 2ebbecc8..a460b1b7 100644 --- a/scb-sdk/src/main/java/io/securecodebox/scanprocess/delegate/SummaryGeneratorDelegate.java +++ b/scb-sdk/src/main/java/io/securecodebox/scanprocess/delegate/SummaryGeneratorDelegate.java @@ -54,7 +54,6 @@ public class SummaryGeneratorDelegate implements JavaDelegate { @Override public void execute(DelegateExecution delegateExecution) { - List findings = new LinkedList<>(ProcessVariableHelper.readListFromValue( (String) delegateExecution.getVariable(DefaultFields.PROCESS_FINDINGS.name()), Finding.class)); removeDuplicates(findings);