From f29d3627e9a97dcbab203e45e5eb2e1e46489cca Mon Sep 17 00:00:00 2001 From: Matte23 Date: Wed, 30 Apr 2025 16:44:19 +0200 Subject: [PATCH] feat(command-injection): Add command injection example --- backend/Dockerfile | 5 ++ backend/index.js | 20 ++++++++ docker-compose.yaml | 2 + frontend/src/App.jsx | 3 ++ frontend/src/pages/CommandInjection.jsx | 68 +++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 frontend/src/pages/CommandInjection.jsx diff --git a/backend/Dockerfile b/backend/Dockerfile index 42bcb6e..611900d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,10 @@ FROM node:23-slim +RUN apt update && \ + apt install -y iputils-ping \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + WORKDIR /app COPY . . RUN npm install diff --git a/backend/index.js b/backend/index.js index a82863b..fa8ca2b 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,6 +1,7 @@ const express = require('express'); const mysql = require('mysql2'); const cors = require('cors'); +const { exec } = require('child_process'); const app = express(); const db = require('./db'); @@ -35,4 +36,23 @@ app.post('/api/login', (req, res) => { }); }); +app.post('/api/ping', (req, res) => { + const { ip } = req.body; + + // 🚨 INTENTIONALLY VULNERABLE TO COMMAND INJECTION + const command = `ping -c 4 ${ip}`; + exec(command, (err, stdout, stderr) => { + if (err) { + return res.status(500).json({ + output: stderr, + command: command + }); + } + res.json({ + output: stdout, + command: command + }); + }); +}); + app.listen(5000, () => console.log('Backend running on port 5000')); diff --git a/docker-compose.yaml b/docker-compose.yaml index 9a5be31..9d57b62 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -20,6 +20,8 @@ services: restart: always ports: - "5000:5000" + cap_add: + - NET_RAW depends_on: db: condition: service_healthy diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 5dad967..4f06cc6 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,6 +1,7 @@ import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'; import SQLInjection from './pages/SQLInjection'; import { Navbar, Nav, Container } from 'react-bootstrap'; +import CommandInjection from './pages/CommandInjection'; function App() { return ( @@ -12,6 +13,7 @@ function App() { @@ -19,6 +21,7 @@ function App() {
} /> + } />
diff --git a/frontend/src/pages/CommandInjection.jsx b/frontend/src/pages/CommandInjection.jsx new file mode 100644 index 0000000..f4e3dc5 --- /dev/null +++ b/frontend/src/pages/CommandInjection.jsx @@ -0,0 +1,68 @@ +import React, { useState } from "react"; +import { Card, Container, Form, Button, Alert } from "react-bootstrap"; + +export default function CommandInjection() { + const [ipAddress, setIpAddress] = useState(""); + const [output, setOutput] = useState(""); + const [command, setCommand] = useState(""); + const [showCommand, setShowCommand] = useState(false); + const [status, setStatus] = useState(null); + + const handlePing = async () => { + const res = await fetch("http://localhost:5000/api/ping", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ ip: ipAddress }), + }); + const data = await res.json(); + setStatus(res.status); + setOutput(data.output); + setCommand(data.command); + }; + + return ( + + + + Ping Test +
+ + setIpAddress(e.target.value)} + /> + + + setShowCommand(e.target.checked)} + /> + +
+ +
+
+ {output && ( + + Output: {output} + + )} + {showCommand && command && ( + + Command: {command} + + )} +
+
+
+ ); +} \ No newline at end of file