diff --git a/docker-compose.yml b/docker-compose.yml index 9fc50ce4..35956c81 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: vulnado: build: . ports: - - 8080:8080 + - 8081:8080 links: - db - internal_site diff --git a/jenkins/Dockerfile b/jenkins/Dockerfile new file mode 100644 index 00000000..745253c5 --- /dev/null +++ b/jenkins/Dockerfile @@ -0,0 +1,18 @@ +FROM jenkins/jenkins:2.462.2-jdk17 +USER root +RUN apt-get update && apt-get install -y lsb-release +RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \ + https://download.docker.com/linux/debian/gpg +RUN echo "deb [arch=$(dpkg --print-architecture) \ + signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \ + https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list +RUN apt-get update && apt-get install -y docker-ce-cli +RUN apt-get install nmap +USER jenkins +RUN jenkins-plugin-cli --plugins "blueocean:1.27.14 \ +docker-workflow:580.vc0c340686b_54 \ +build-token-root:151.va_e52fe3215fc \ +file-parameters:339.v4b_cc83e11455 \ +sonar:2.17.2" + diff --git a/jenkins/Jenkinsfile b/jenkins/Jenkinsfile new file mode 100644 index 00000000..659f9a33 --- /dev/null +++ b/jenkins/Jenkinsfile @@ -0,0 +1,193 @@ +pipeline { + agent any + parameters{ + string(name: 'dockerComposePath', defaultValue: '', description: 'Path of the docker-compose.yml') + string(name: 'dockerfilePath', defaultValue: '', description: 'Path of the Dockerfile') + string(name: 'endpointsPath', defaultValue: '', description: 'Path of the endpoints to test SQLmap') + } + environment { + REPO_URL = '' + CURR_BRANCH = '' + workspace = '' + relativeWorkspacePath = '' + SNYK_TOKEN = credentials('snyk-token') + images_string = '' + } + stages { + stage ('Checkout SCM') + { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + script { + checkout scm + workspace = pwd () + } + } + } + } + stage('Setting Environment Variables') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + script { + echo "Getting git repo info" + // Get the current repository URL + REPO_URL = sh(script: 'git config --get remote.origin.url', returnStdout: true).trim() + CURR_BRANCH = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim() + } + } + } + } + + stage('TruffleHog Secret Scan') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + script { + echo "Running Trufflehog Scan" + sh 'rm -f trufflehog' + + sh """ + docker run --rm trufflesecurity/trufflehog:latest git ${REPO_URL} --since-commit HEAD --only-verified > trufflehog + """ + + def truffle = readFile "trufflehog" + + if (truffle.length() == 0) { + echo "Good to go. No secrets found" + } + else { + echo "Warning! Secrets are committed into your git repository." + error("Secrets might be committed into your git repo") + } + } + } + } + } + stage('Sonar Cube Scan') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + withSonarQubeEnv(installationName: 'sonarQube1') { + sh './mvnw clean compile' // Compile the code first + sh './mvnw org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.0.2155:sonar -Dsonar.java.binaries=target/classes' // Run the SonarQube scan + } + } + + } + } + stage('Check and build Docker Images') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + script { + def images = [] + + if (dockerComposePath?.trim()) { + // If dockerComposePath is provided, run docker-compose to build images + echo "Docker Compose file detected. Building images using docker-compose..." + sh """ + docker compose -f ${workspace}${params.dockerComposePath} build --parallel + """ + + // Get repository and tag of the images created by docker-compose + images = sh(script: """ + docker compose -f ${workspace}${params.dockerComposePath} images --format '{{.Repository}}:{{.Tag}}' + """, returnStdout: true).trim().split("\n") + + } else if (dockerfilePath?.trim()) { + // If dockerComposePath is NOT provided, build the Docker image using the Dockerfile + echo "Dockerfile detected. Building image using docker build..." + + def imageName = "my_image:latest" // You can customize the image name as needed + sh """ + docker build -t ${imageName} -f ${params.dockerfilePath} . + """ + + echo "Image built from Dockerfile: ${imageName}" + images << imageName + } else { + error "No Dockerfile or Docker Compose file provided. Please provide at least one." + } + + // Save images to an environment variable for later stages + images_string = images.join(",") + } + } + } + } + stage('Snyk Docker Image vulnerability scan') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + script { + def images = [] + if (${images_string} && ${images_string}.trim()) { + images = ${images_string}.split(",") + } + else { + error "No images to scan with Snyk" + } + + for (image in images) { + def sanitizedImageName = image.replaceAll("/", "_").replaceAll(":", "_") + + echo "Scanning image: ${image} using Snyk..." + + sh "rm -f snyk_${sanitizedImageName}" + + sh """ + docker run --rm -it --env ${SNYK_TOKEN} -v /var/run/docker.sock:/var/run/docker.sock \ + snyk/snyk:docker snyk test --docker ${image} --severity-threshold=critical --fail-on=all > snyk_${sanitizedImageName} + """ + } + } + } + } + } + + stage('Version Docker') { + steps { + sh 'docker --version' + } + } + + + stage('Run Nmap-Vuln Scan-Opened Ports-Vulnerabilites') { + steps { + script { + sh """ + docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v ${PWD}:/usr/src/myapp -w /usr/src/myapp nikolaskir2000/nmap_image_3:latest -sV --script vuln 192.168.2.11 -p 80,223,8080,8082 + + """ + } + } + } + + + + stage('SQL map endpoints scan') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh """ + docker run --rm -v ${PWD}:/usr/src/myapp -w /usr/src/myapp thanosefsta/sqlmap:latest -m ${workspace}${params.endpointsPath} --batch > sqlmap + """ + } + + } + } + stage('Run Nmap - Opened Gates') { + steps { + echo "Deliver" + } + } + } + + post { + always { + echo 'Cleaning up...' + + } + success { + echo 'Pipeline completed successfully.' + } + failure { + echo 'Pipeline failed. Please check the logs.' + } + } +} \ No newline at end of file diff --git a/jenkins/docker-compose.yml b/jenkins/docker-compose.yml new file mode 100644 index 00000000..22bbc1a9 --- /dev/null +++ b/jenkins/docker-compose.yml @@ -0,0 +1,58 @@ +services: + jenkins: + build: . # This will build the Docker image from the Dockerfile in the same directory + container_name: jenkins-blueocean + restart: on-failure + networks: + - jenkins + # environment: + # # - DOCKER_HOST=tcp://docker:2376 # Docker host for communication + # # - DOCKER_CERT_PATH=/certs/client # Path to Docker certificates + # # - DOCKER_TLS_VERIFY=1 # Enable TLS verification + volumes: + - jenkins-data:/var/jenkins_home # Persistent Jenkins data + - jenkins-docker-certs:/certs/client:ro # Mount Docker client certs for TLS connection (read-only) + - /var/run/docker.sock:/var/run/docker.sock + ports: + - "8080:8080" # Jenkins web UI + - "50000:50000" # Jenkins agent connections + sonarqube: + image: sonarqube:lts-community + depends_on: + - sonar_db + environment: + SONAR_JDBC_URL: jdbc:postgresql://sonar_db:5432/sonar + SONAR_JDBC_USERNAME: sonar + SONAR_JDBC_PASSWORD: sonar + ports: + - "9000:9000" + volumes: + - sonarqube_conf:/opt/sonarqube/conf + - sonarqube_data:/opt/sonarqube/data + - sonarqube_extensions:/opt/sonarqube/extensions + - sonarqube_logs:/opt/sonarqube/logs + - sonarqube_temp:/opt/sonarqube/temp + + sonar_db: + image: postgres:13 + environment: + POSTGRES_USER: sonar + POSTGRES_PASSWORD: sonar + POSTGRES_DB: sonar + volumes: + - sonar_db:/var/lib/postgresql + - sonar_db_data:/var/lib/postgresql/data +networks: + jenkins: + driver: bridge # Creates a custom bridge network called 'jenkins' + +volumes: + jenkins-data: # Persistent volume for Jenkins home directory + jenkins-docker-certs: # Volume for Docker TLS client certificates + sonarqube_conf: + sonarqube_data: + sonarqube_extensions: + sonarqube_logs: + sonarqube_temp: + sonar_db: + sonar_db_data: \ No newline at end of file diff --git a/jenkins/keys copy.txt b/jenkins/keys copy.txt new file mode 100644 index 00000000..98670d74 --- /dev/null +++ b/jenkins/keys copy.txt @@ -0,0 +1,44 @@ +Basic auth: +test +https://admin:admin@the-internet.herokuapp.com/basic_auth + +Private key: +-----BEGIN OPENSSH PRIVATE KEY----- +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 +Hx7UPVlTK8dyvk1Z+Yw0nrfNClI= +-----END OPENSSH PRIVATE KEY----- diff --git a/jenkins/keys.txt b/jenkins/keys.txt new file mode 100644 index 00000000..3e8e8a7e --- /dev/null +++ b/jenkins/keys.txt @@ -0,0 +1,44 @@ +Basic auth: +https://admin:admin@the-internet.herokuapp.com/basic_auth +https://admin:admin@the-internet.herokuapp.com/basic_auth + +Private key: +-----BEGIN OPENSSH PRIVATE KEY----- +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 +Hx7UPVlTK8dyvk1Z+Yw0nrfNClI= +-----END OPENSSH PRIVATE KEY----- diff --git a/jenkins/nmap/Dockerfile b/jenkins/nmap/Dockerfile new file mode 100644 index 00000000..ead7b08a --- /dev/null +++ b/jenkins/nmap/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine:latest +RUN apk update && apk add bash +RUN apk add nmap +RUN apk add nmap-scripts +ENTRYPOINT ["nmap"] \ No newline at end of file diff --git a/jenkins/sqlmap/Dockerfile b/jenkins/sqlmap/Dockerfile new file mode 100644 index 00000000..a6d38b1e --- /dev/null +++ b/jenkins/sqlmap/Dockerfile @@ -0,0 +1,11 @@ +FROM cgr.dev/chainguard/git:latest AS git-clone + +WORKDIR /sqlmap + +RUN git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git . + +FROM cgr.dev/chainguard/python:latest + +COPY --from=git-clone /sqlmap . + +ENTRYPOINT ["python3", "/sqlmap.py"] \ No newline at end of file diff --git a/jenkins/sqlmap/endpoints.txt b/jenkins/sqlmap/endpoints.txt new file mode 100644 index 00000000..7e45d0de --- /dev/null +++ b/jenkins/sqlmap/endpoints.txt @@ -0,0 +1 @@ +http://testphp.vulnweb.com/artists.php?artist=1 \ No newline at end of file diff --git a/src/main/java/com/scalesec/vulnado/Comment.java b/src/main/java/com/scalesec/vulnado/Comment.java index 4a85fc8f..c2cb480d 100644 --- a/src/main/java/com/scalesec/vulnado/Comment.java +++ b/src/main/java/com/scalesec/vulnado/Comment.java @@ -17,6 +17,100 @@ public Comment(String id, String username, String body, Timestamp created_on) { this.body = body; this.created_on = created_on; } + //Linter unusedVariable inside ! Identified by SonarQube + public void unusedVariableMethod() { + int unused = 10; + System.out.println("One useless comment!"); + } + //Linter - Incorrect method name ! Identified by SonarQube + public void FalseNameMethod() { + System.out.println("There are many comments in the DB"); + } + + + ////Linter - False name - classes ! Identified by SonarQube + class CommentImages + { + class comment_InnerClass{ + //empty class also... + } + } + + + + + //SQL INJECTION HERE ! Identified by SonarQube + public List findUserComments(String username) { + Statement statement = null; + ResultSet rs = null; + List comments = new ArrayList<>(); + Connection con = null; + + try { + con = Postgres.connection(); + statement = con.createStatement(); + + // SQL INJECTION + String query = "SELECT * FROM comments WHERE username = '" + username + "';"; + rs = statement.executeQuery(query); + + while (rs.next()) { + String id = rs.getString("id"); + String body = rs.getString("body"); + Timestamp created_on = rs.getTimestamp("created_on"); + Comment c = new Comment(id, username, body, created_on); + comments.add(c); + } + } catch (SQLException e) { //Not enough catch-Exception. Does not catch all the cases. + e.printStackTrace(); + } + return comments; + } + public void process(int value) { + if (value > 0) { + if (value < 10) { + System.out.println("Small value"); + } else { + System.out.println("Medium value"); + } + } else { + if (value == 0) { + System.out.println("Zero"); + } else { + System.out.println("Negative value"); + } + } + } + + + + //Try - Catch Should be here ! Identified by SonarQube + private Boolean commit() throws SQLException { + String sql = "INSERT INTO comments (id, username, body, created_on) VALUES (?,?,?,?)"; + Connection con = Postgres.connection(); + PreparedStatement pStatement = con.prepareStatement(sql); + pStatement.setString(1, this.id); + pStatement.setString(2, this.username); + pStatement.setString(3, this.body); + pStatement.setTimestamp(4, this.created_on); + return 1 == pStatement.executeUpdate(); + } + + + //finally must not have return ! Identified by SonarQube + public static Boolean delete(String id) { + try { + String sql = "DELETE FROM comments where id = ?"; + Connection con = Postgres.connection(); + PreparedStatement pStatement = con.prepareStatement(sql); + pStatement.setString(1, id); + return 1 == pStatement.executeUpdate(); + } catch(Exception e) { + e.printStackTrace(); + } finally { + return false; + } + } public static Comment create(String username, String body){ long time = new Date().getTime(); @@ -59,28 +153,5 @@ public static List fetch_all() { } } - public static Boolean delete(String id) { - try { - String sql = "DELETE FROM comments where id = ?"; - Connection con = Postgres.connection(); - PreparedStatement pStatement = con.prepareStatement(sql); - pStatement.setString(1, id); - return 1 == pStatement.executeUpdate(); - } catch(Exception e) { - e.printStackTrace(); - } finally { - return false; - } - } - private Boolean commit() throws SQLException { - String sql = "INSERT INTO comments (id, username, body, created_on) VALUES (?,?,?,?)"; - Connection con = Postgres.connection(); - PreparedStatement pStatement = con.prepareStatement(sql); - pStatement.setString(1, this.id); - pStatement.setString(2, this.username); - pStatement.setString(3, this.body); - pStatement.setTimestamp(4, this.created_on); - return 1 == pStatement.executeUpdate(); - } } diff --git a/src/main/java/com/scalesec/vulnado/LoginController.java b/src/main/java/com/scalesec/vulnado/LoginController.java index e0676c15..5090d441 100644 --- a/src/main/java/com/scalesec/vulnado/LoginController.java +++ b/src/main/java/com/scalesec/vulnado/LoginController.java @@ -29,6 +29,7 @@ LoginResponse login(@RequestBody LoginRequest input) { class LoginRequest implements Serializable { public String username; public String password; + } class LoginResponse implements Serializable { diff --git a/src/main/java/com/scalesec/vulnado/VulnerableServer.java b/src/main/java/com/scalesec/vulnado/VulnerableServer.java new file mode 100644 index 00000000..cf20863c --- /dev/null +++ b/src/main/java/com/scalesec/vulnado/VulnerableServer.java @@ -0,0 +1,34 @@ +package com.scalesec.vulnado; +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; + +public class VulnerableServer { + public static void main(String[] args) throws Exception { + // Open a server on port 8080 + ServerSocket serverSocket = new ServerSocket(8082); + System.out.println("Server started on port 8082"); + + while (true) { + Socket clientSocket = serverSocket.accept(); + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + + // Vulnerability 1: Command Injection + out.println("Enter a command to execute: "); + String command = in.readLine(); + + // Unsafe execution of system commands + Process process = Runtime.getRuntime().exec(command); // Command Injection vulnerability + BufferedReader processOutput = new BufferedReader(new InputStreamReader(process.getInputStream())); + + String line; + out.println("Command output:"); + while ((line = processOutput.readLine()) != null) { + out.println(line); + } + + clientSocket.close(); + } + } +}