Erstellung der Testmaschinen
Amazon Web Services (im folgenden nur "AWS")
AWS ist der weltweit größte Anbieter für Cloud Services. Aufgrund der hohen Nutzerzahlen war AWS unsere erste Wahl, um Tests durchzuführen. Die Nutzeroberfläche ist aktuell im Umbau auf ein neueres Interface. Im Großen und Ganzen jedoch besteht die Erstellung einer virtuellen Maschine aus sieben Schritten. Darin ist z.B. die Auswahl des Maschinentyps, des Betriebssystems und auch des Massenspeichers enthalten. Weiter können noch sehr umfangreiche Netzwerk- und Zugriffseinstellungen durchgeführt werden. Es ist hier zwingend notwendig, ein SSH-Keypair zu generieren, um auf den Server zugreifen zu können. Dieses Keypair wird dann bei AWS gespeichert und kann für beliebig viele Maschinen verwendet werden.
Die Auswahl an Betrienssystemen ist enorm, rund 80 Betriebssysteme werden offiziell von Amazon angeboten, und weitere von den Nutzern oder anderen Firmen bereitgestellt. Auch der Maschinentyp kann sehr feingranular gewählt werden, oder komplett individuell sein.
Bei dieser Menge an Images ist es sehr interessant, wie aktuell diese sind.
Google Cloud Plattform (im folgenden nur "GCP")
Durch ein Projekt im letzten Semester hatten wir bereits einen GCP-Account und erste Erfahrungen mit der Plattform. Um eine VM zu erstellen, kann man unter "Compute Engine/VM-Instanzen" eine neue VM-Instanz erstellen. Dann können Eigenschaften der VM eingestellt werden, wie z. B.: Name, Region, CPU-Kerne und Arbeitsspeicher, sowie das Bootlaufwerk mit Betriebssystem und Version. Unten, unter dem Punkt "Sicherheit", kann ein systemweiter SSH-Schlüssel gesetzt werden. Dieser gilt dann auf allen virtuellen Maschinen, egal ob sie schon erstellt wurden.
Danach kann mit der externen IP-Adresse auf die VM zugegriffen werden. Zusätzlich kann Google ein Browserfenster mit einer SSH-Sitzung öffnen.
![gcp-1](uploads/38ee4d59eb674c424082198ba54ab13b/gcp-1.png) | ![gcp-2](uploads/f100d12cbc5d56b1b93f271fca14ebf6/gcp-2.png) |
GCP Weboberfläche
GCP- und AWS-Marketplace
GCP und AWS bieten beide eine Plattform für von Nutzern erstellte Images, den sogenannten Marketplace. Dieser ist meist durch einen separaten Reiter in der Benutzeroberfläche erreichbar. Hier hat man eine Auswahl an den verschiedensten Images und Softwarepaketen. Hat man ein passendes gefunden, so können die Einstellungen gewählt und schließlich die VM gestartet werden. Die Software auf diesen Images ist speziell für den gewünschten Zweck angepasst, um optimal zu funktionieren. Beispiele hierfür wären etwa ein LAMP-Stack oder auch Wordpress.
Hetzner
Hetzner ist, im Vergleich zu GCP oder AWS, ein eher kleinerer deutscher Anbieter für Cloud Infrastruktur. Es werden neben virtuellen Maschinen auch dedizierte Server und Webspaces, sowie Speichersysteme angeboten. Hetzner wurde ausgewählt, da Privatpersonen dort deutlich einfacher und kostentransparenter Server mieten können als bei z.B. AWS. Die Server werden auf Stundenbasis bezahlt und haben ein maximales Preislimit pro Monat, was etwas unter dem Stundensatz liegt.
![hetzner-1](uploads/b2ba144a98d724da422763c78c847780/hetzner-1.png) | ![hetzner-2](uploads/775bd88672e5e60877313a9218ebeb0b/hetzner-2.png) |
Hetzner Weboberfläche
In den obigen Screenshots ist die Oberfläche zur VM Erstellung zu sehen. Es ist sehr übersichtlich gehalten. Ein Nachteil hier ist aber, dass es nur feste Maschinentypen gibt, sowie eine sehr begrenzte Anzahl an Betriebssystemen. Die Performance soll laut neuster AMD Epic Prozessoren sehr gut sein. Der Zugriff erfolgt entweder über ein automatisch erstelltes Passwort, oder einen vorher ausgewählten SSH-Key.
VMware
Unsere eigenen Maschinen haben wir mit VMware Workstation Player erstellt, da dieser kostenlos zur Verfügung steht. Die Ubuntu Server Base Images haben wir als ISO heruntergeladen und in VMware importiert. Dabei mussten wir auch die VMware Tools installieren. Diese werden der VM von der VMware Software als virtuelle CD-ROM zur Verfügung gestellt. Die CD-ROM musste zuerst per "mount" eingebunden werden. Danach konnte das enthaltene TAR Archiv entpackt, sowie die Tools installiert werden.
Auf drei von vier Base Images haben wir noch jeweils einen LAMP Stack, MEAN Stack und eine Vulnerable VM aufgesetzt. Für die Erstellung LAMP und MEAN Stack haben wir jeweils das erste Tutorial verwendet, das wir finden konnten. Die verwendeten Tutorials sind:
- LAMP Stack: https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-ubuntu-18-04-de
- MEAN Stack: https://www.vultr.com/docs/how-to-install-mean-on-ubuntu-20-04-lts
Bei der Erstellung der Vulnerable VM haben wir die vier folgenden Änderungen durchgeführt:
- Öffnen aller Ports (TCP/UDP) in "ufw" (Uncomplicated Firewall)
- Erstellen eines SETUID-Scripts, das jeden beliebigen Befehl mit Root-Berechtigungen ausführt, den es als Parameter übergeben bekommt.
- Verändern der Berechtigungen auf SSH-Keys und .ssh-Ordnern, sodass diese für alle Benutzer einsehbar sind.
- Installation verschiedenster Compiler.
Um Dateien mit der VM auszutauschen, haben wir "Shared Folders" verwendet. Diese haben wir zu Beginn aktiviert, um das Run-Script auf das Image zu laden und anschließend deaktiviert. Nach der Durchführung aller Scans haben wir den "Shared Folder" erneut aktiviert, um den entstandenen Output zu extrahieren.
Preisvergleich
Im Zuge der Anbieter ist noch kurz der teilweise sehr hohe Preisunterschied der Plattformen für ähnliche Rechenleistung zu erwähnen. AWS und GCP sind hierbei sehr ähnlich. Beide liegen für eine Basismaschine für eine Wordpress Installation etwa bei 30 USD pro Monat. Hetzner hingegen kostet für dieselbe Rechenleistung etwas weniger als die Hälfte. Es bleibt nun abzuwarten, ob der Preisunterschied sich in der Pflege und Sicherheit der Images widerspiegelt, oder es rein am Funktionsumfang liegt.
Run-Script
Die Frage nach der Notwendigkeit eines Skriptes zur Durchführung lässt sich schnell beantworten. Reproduzierbarkeit.
Da es für eine automatische Verarbeitung wichtig war, dass alle Scans gleich ausgeführt wurden, musste ein klar definierter Weg erstellt werden, wie dieses Ziel erreicht werden kann.
Zunächst musste eine optimale Sprache für das Skript gefunden werden. Zur Auswahl standen hier Python und Bash. Letztendlich wurde es dann eine Bash Implementierung. Python wurde aufgrund der hohen Abhängigkeiten nicht gewählt, denn das Python SDK (sowie auch die Runntime, da es ein Skriptspache ist) ist mit etwa 800 Megabyte sehr schwergewichtig. Weiter sind nicht auf allen Systemen die aktuellsten Pythonversionen verfügbar. Bash hingegen ist auf allen getesteten Maschinen automatisch installiert und auch der Funktionsumfang reicht für unsere Zwecke komplett aus.
Das Script ist in drei Teile unterteilt:
- Setup
- Durchführung
- Artefakte sichern
Setup
function init() {
rm -rf scans
echo "Installing prequesites..."
mkdir scans
cd scans
mkdir outputs
apt-get update
apt-get install git ... ... ...
git clone --depth 1 https://github.com/CISOfy/lynis
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
git clone --depth 1 https://github.com/trimstray/otseca
git clone --depth 1 https://github.com/Jsitech/JShielder.git
cd otseca && ./setup.sh install
echo "Setup complete!"
exit
}
Im init
-Block wird die nötige Dateistruktur angelegt und fehlende Pakete, sowie die Tools installiert. Die Tools werden immer direkt von GitHub geholt, um immer die aktuelle Version zu haben. Weiter musste für Otseca noch ein Installationsscript ausgeführt werden.
Durchführung
function run_scan() {
...
echo "Running lynis..."
cd lynis
./lynis audit system | tee "../outputs/lynis-console-$1.log"
mv /var/log/lynis.log "../outputs/lynis-log-$1.log"
mv /var/log/lynis-report.dat "../outputs/lynis-report-$1.dat"
echo "Running testssl..."
cd ../testssl.sh
./testssl.sh --logfile "../outputs/testssl-$1.log" --append --connect-timeout 10 --openssl-timeout 10 localhost
./testssl.sh --logfile "../outputs/testssl-$1.log" --append --connect-timeout 10 --openssl-timeout 10 --ssl-native localhost
...
./testssl.sh --logfile "../outputs/testssl-$1.log" --append --connect-timeout 10 --openssl-timeout 10 -t mysql localhost:3306
./testssl.sh --logfile "../outputs/testssl-$1.log" --append --connect-timeout 10 --openssl-timeout 10 --ssl-native localhost:3306
echo "testssl done!"
echo "Running otseca..."
cd ../otseca
otseca --ignore-failed --tasks system,kernel,permissions,services,network,distro,external | tee "otseca-$1.log"
mv data/output "../outputs/otseca-$1"
echo "All scans done!"
}
Bei der Durchführung wird die Funktion run_scan
ausgeführt. Diese nimmt einen Parameter an, der den aktuellen Scannamen bestimmt (der Parameter wird das Postfix des Logfiles).
Als Erstes wird Lynis via audit system
ausgeführt, von dieser Ausführung wird der Konsolenoutput, das Logfile, sowie die Lynis DAT-Datei gespeichert. Danach werden 16 TestSSL Scans ausgeführt, die die normalen Webserverports testen, sowie auch Datenbanken und Mailports. Hierbei ist zu beachten, dass TestSSL nicht zwingend für den SSL-Test benutzt wurde, sondern auch, um zu sehen, ob auf diesem Port ein Dienst ausgeführt wird. Zuletzt wird noch Otseca mit allen zur Verfügung stehenden Tasks ausgeführt. Otseca liefert statt einzelner Dateien ein ganzes Verzeichnis als Ausgabe. Dieses wird dann ebenfalls in unsere Ordnerstuktur verschoben.
Artefakte
Um nun zuletzt die Resultate archivieren zu können, bietet das Skript die Funktion tar_files
an.
function tar_files() {
if id "ftpuser" &>/dev/null
then
echo "ftpuser already exists!"
else
echo "ftpuser doesn't exist, creating it..."
adduser ftpuser
fi
cd scans
tar cfvz "scans-output-$(date +%Y%m%d-%H%M%S).tar.gz" outputs/
cp *.tar.gz /home/ftpuser
echo "Moved archived files to /home/ftpuser"
echo "To download the files use an ftp server and the ftpuser along with your password."
}
Sie legt einen FTP Benutzer an, in den dann die vorher getarten Dateien verschoben werden. Um dieses Archiv nun herunterzuladen, kann entweder eine SFTP oder SCP session gestartet werden. Manchmal ist es notwendig, für diesen Schritt die Passwordauthentifikation in den Einstellungen zu aktivieren. Dies ist aber kein Sicherheitsrisiko, da dies erst ganz am Ende geschieht, kurz bevor die Maschine sowieso gelöscht wird.
Beispielnutzung
Nachdem der Server erstellt wurde, kann dann mit folgenden Schritten ein Testlauf durchgeführt werden.
- Skript auf den Server kopieren (SCP oder C&P über Nano/Vim)
- Initialer Scan
script.sh run_scan 1
- Update
apt-get updrate && apt-get upgrade
- Zweiter Scan
script.sh run_scan 2
- JShielder ausführen (mit den vorgegebenen Tasks)
- Dritter Scan
script.sh run_scan 3
- Dateien exportieren
script.sh tar_files
- Export herunterladen
Notiz: Wenn der JShielder nicht manuell ausgeführt werden müsste, sondern CLI-Parameter unterstützen würde, wäre es möglich, ein komplettes Skript zu schreiben, das nur einmal angestoßen werden müsste und dann alle Schritte allein ausführt.
Das komplette Skript ist im Repository unter deep-thought-run.sh zu finden.