#!/bin/bash
#
# deface_demo.sh
# Teaching-lab script for Metasploitable 2 (local VM only).
# Produces a theatrical "defaced" index.php — Matrix-style rain background,
# glitch text, a fake auto-typed "exploit log", and a real phpinfo()
# dump to illustrate genuine information-disclosure risk.
#
# USAGE:
#   sudo ./deface_demo.sh /var/www/index.php
#
# It will:
#   1. Back up the original file (index.php.bak_<timestamp>)
#   2. Write the "defaced" page in its place
#   3. Restore original ownership/permissions where possible
#
# To restore: cp index.php.bak_<timestamp> index.php

set -euo pipefail

TARGET="${1:-/var/www/index.php}"

if [[ ! -f "$TARGET" ]]; then
    echo "Error: target file not found: $TARGET"
    echo "Usage: $0 /path/to/index.php"
    exit 1
fi

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP="${TARGET}.bak_${TIMESTAMP}"

ORIG_OWNER=$(stat -c '%U:%G' "$TARGET" 2>/dev/null || echo "www-data:www-data")
ORIG_PERMS=$(stat -c '%a' "$TARGET" 2>/dev/null || echo "644")

echo "[*] Backing up $TARGET -> $BACKUP"
cp -p "$TARGET" "$BACKUP"

echo "[*] Writing defacement page to $TARGET"
cat > "$TARGET" <<'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>0wn3d</title>
<style>
  * { box-sizing: border-box; }
  html, body {
    margin:0; padding:0; background:#000; overflow-x:hidden;
    font-family: "Courier New", monospace; color:#0f0;
  }
  canvas#matrix {
    position:fixed; top:0; left:0; z-index:0;
  }
  .wrap {
    position:relative; z-index:1;
    max-width: 900px; margin: 0 auto; padding: 40px 20px 80px;
    background: rgba(0,0,0,0.82);
    box-shadow: 0 0 60px 40px rgba(0,0,0,0.82);
  }
  h1.glitch {
    font-size: 3em; text-align:center; position:relative;
    color:#0f0; text-shadow: 0 0 10px #0f0;
    animation: flicker 3s infinite;
    background: rgba(0,0,0,0.6);
    padding: 10px 0;
  }
  h1.glitch::before, h1.glitch::after {
    content: attr(data-text);
    position:absolute; left:0; top:0; width:100%;
    overflow:hidden; opacity:0.8;
  }
  h1.glitch::before {
    color:#f0f; clip-path: inset(0 0 55% 0);
    animation: glitchTop 2.5s infinite linear alternate-reverse;
  }
  h1.glitch::after {
    color:#0ff; clip-path: inset(55% 0 0 0);
    animation: glitchBottom 2.5s infinite linear alternate-reverse;
  }
  @keyframes flicker {
    0%,19%,21%,23%,25%,54%,56%,100% { opacity:1; }
    20%,24%,55% { opacity:0.6; }
  }
  @keyframes glitchTop { 0%{transform:translate(0,0);} 20%{transform:translate(-3px,-2px);} 40%{transform:translate(3px,1px);} 60%{transform:translate(-2px,2px);} 80%{transform:translate(2px,-1px);} 100%{transform:translate(0,0);} }
  @keyframes glitchBottom { 0%{transform:translate(0,0);} 20%{transform:translate(3px,2px);} 40%{transform:translate(-3px,-1px);} 60%{transform:translate(2px,-2px);} 80%{transform:translate(-2px,1px);} 100%{transform:translate(0,0);} }

  .subtitle { text-align:center; color:#0f0; opacity:.95; margin-top:-10px; background: rgba(0,0,0,0.6); padding: 4px 0; }
  .badge {
    display:block; width:fit-content; margin: 18px auto; padding: 6px 14px;
    border:1px solid #0f0; border-radius:4px; font-size:.85em; letter-spacing:1px;
    background: rgba(0,20,0,0.9);
  }
  .term {
    background: rgba(0,10,0,0.96); border:1px solid #0f0; border-radius:6px;
    padding:16px 18px; margin-top:30px; min-height:180px;
    box-shadow: 0 0 20px rgba(0,255,0,0.15) inset;
    white-space: pre-wrap; font-size:.95em; line-height:1.5em;
    color:#5f5;
  }
  .term .cursor { display:inline-block; width:8px; background:#0f0; animation: blink 1s steps(1) infinite; }
  @keyframes blink { 50% { opacity:0; } }

  .panel {
    margin-top: 30px; border:1px dashed #0a0; border-radius:6px; padding:16px 18px;
    background: rgba(0,15,0,0.92);
  }
  .panel h2 { margin-top:0; color:#0f0; font-size:1.1em; border-bottom:1px solid #0a0; padding-bottom:6px;}
  .panel p, .panel li { color:#aef0ae; font-size:.9em; line-height:1.5em; }
  code { color:#0ff; }

  footer { text-align:center; margin-top:40px; color:#0a0; font-size:.8em; background: rgba(0,0,0,0.6); padding: 6px 0; }

  .infodump { margin-top:30px; }
  .infodump h2 { color:#f55; }
</style>
</head>
<body>
<canvas id="matrix"></canvas>

<div class="wrap">
  <h1 class="glitch" data-text="SYSTEM COMPROMISED">SYSTEM COMPROMISED</h1>
  <p class="subtitle">// simulated defacement — Metasploitable 2 classroom lab //</p>
  <div class="badge" id="clock">local time: --:--:--</div>

  <div class="term" id="term"></div>

  <div class="panel">
    <h2>Lesson notes</h2>
    <ul>
      <li>This page is a <strong>staged</strong> defacement, not the result of an actual exploit chain.</li>
      <li>The "exploit log" above is scripted text for atmosphere — discuss with students what a <em>real</em> compromise timeline/log would actually look like (auth logs, web server access logs, file integrity monitoring alerts).</li>
      <li>The section below runs a genuine <code>phpinfo()</code> call to demonstrate real information disclosure: PHP version, loaded modules, exposed paths, and configuration values an attacker could use for recon.</li>
      <li>Ask students: how would you detect this defacement happened? (file integrity monitoring, git diff against known-good source, checksums, IDS alerts on outbound changes, etc.)</li>
      <li>Ask students: how would you have prevented the underlying access that allowed this file to be overwritten in the first place?</li>
    </ul>
  </div>

  <div class="panel infodump">
    <h2>⚠ Live information disclosure demo (phpinfo)</h2>
    <p>In a real misconfigured server, an exposed <code>phpinfo()</code> endpoint leaks PHP version/build, loaded extensions, server document root and file paths, and sometimes environment variables — all useful recon for an attacker choosing exploits. This is exactly the kind of low-effort finding a vulnerability scan should catch.</p>
    <?php phpinfo(); ?>
  </div>

  <footer>rendered for training purposes only — restore original file when the lab is done</footer>
</div>

<script>
// Matrix rain background
const canvas = document.getElementById('matrix');
const ctx = canvas.getContext('2d');
function resize(){ canvas.width = window.innerWidth; canvas.height = window.innerHeight; }
resize();
window.addEventListener('resize', resize);
const chars = "01アイウエオカキクケコサシスセソABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const fontSize = 15;
let columns, drops;
function initDrops(){
  columns = Math.floor(canvas.width / fontSize);
  drops = Array(columns).fill(1);
}
initDrops();
window.addEventListener('resize', initDrops);
function draw(){
  ctx.fillStyle = "rgba(0,0,0,0.06)";
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.fillStyle = "#0f0";
  ctx.font = fontSize + "px monospace";
  for (let i=0;i<drops.length;i++){
    const text = chars[Math.floor(Math.random()*chars.length)];
    ctx.fillText(text, i*fontSize, drops[i]*fontSize);
    if (drops[i]*fontSize > canvas.height && Math.random() > 0.975) drops[i]=0;
    drops[i]++;
  }
}
setInterval(draw, 40);

// Fake typed "exploit log" for classroom flavor (clearly fictional/instructional)
const lines = [
  "[demo] initiating simulated recon sequence...",
  "[demo] target: 192.168.x.x (Metasploitable2 lab VM)",
  "[demo] this log is scripted for illustration -- no real exploit ran",
  "[demo] scanning services... 21/ftp 22/ssh 80/http 3306/mysql (example)",
  "[demo] identifying stack: Apache + PHP (outdated, intentionally vulnerable lab build)",
  "[demo] locating writable web root...",
  "[demo] index.php replaced with lab defacement page",
  "[demo] discussion prompt: what real steps would replace each line above?",
  "[demo] sequence complete. see lesson notes panel below."
];
const term = document.getElementById('term');
let li = 0, ci = 0;
function typeLine(){
  if (li >= lines.length){ term.innerHTML += '\n<span class="cursor">&nbsp;</span>'; return; }
  const line = lines[li];
  if (ci === 0) term.innerHTML += (li>0 ? "\n" : "") ;
  term.textContent += line[ci] || "";
  ci++;
  if (ci <= line.length){
    setTimeout(typeLine, 18 + Math.random()*25);
  } else {
    li++; ci=0;
    setTimeout(typeLine, 250);
  }
}
typeLine();

// live clock
function tick(){
  document.getElementById('clock').textContent = "local time: " + new Date().toLocaleTimeString();
}
setInterval(tick, 1000); tick();
</script>
</body>
</html>
EOF

echo "[*] Restoring ownership/permissions ($ORIG_OWNER, $ORIG_PERMS)"
chown "$ORIG_OWNER" "$TARGET" 2>/dev/null || echo "    (skipped chown — insufficient privileges)"
chmod "$ORIG_PERMS" "$TARGET" 2>/dev/null || true

echo "[+] Done. Original file saved as: $BACKUP"
echo "[+] To restore: cp \"$BACKUP\" \"$TARGET\""
