Forschen
DE EN

Netcat – Das Schweizer Taschenmesser der Netzwerk-Administration

Netcat, oder abgekürzt nc, wie auch das Shellkommando heißt, ist ein Netzwerk-Tool mit einer großen Bandbreite an Einsatzmöglichkeiten. Es kann verwendet werden, um Netzwerk-Verbindungen zu monitoren, zu testen oder auch um Daten beliebiger Natur über das Netz zu schicken. Netcat ist praktisch in jeder Distribution vorhanden. Es kommt allerdings je nach Distribution in unterschiedlichen Varianten zum Einsatz, die sich nach Umfang der unterstützenden Features unterscheiden. Beispielsweise wird bei Debian-basierten Distributionen wie Ubuntu oder auch Debian selbst das klassische (originale) netcat bereitgestellt. Bei RedHat-ähnlichen Distributionen wie RedHat, CentOS oder Fedora ist dagegen eine Variante aus dem nmap-Projekt enthalten, die ncat heißt und die aktueller ist und einen breiteren Funktionsumfang aufweist. Debian-Nutzer können sich dieses mehr an Features aber durch ein simples Nachinstallieren des nmap-Paketes verfügbar machen.


Syntax

Netcat wird üblicherweise über eine Konsole wie folgt aufgerufen:

nc [Optionen] [IP-Adresse/Hostname] [Port]

Gängige Optionen sind z. B.

-4/-6 IP-Protokollversion (IPv4 bzw. IPv6)
-l Listen-Modus für eingehende Verbindungen über den angegebenen Port
-p sport setzt einen Quell-Port für ausgehende Verbindungen
-U verwendet UNIX-domain sockets
-u verwendet das UDP Protokoll statt des Default-Protokolls TCP
-v erhöht die Debug-Ausgabe
-w timeout Timeout bei ausgehenden Verbindungsaufbauten
-z in Verbindung mit Port-Checks, ohne dass Daten gesendet werden


Einsatz-Beispiele

Im Folgenden werden einige Beispiele aufgeführt, die die vielfältigen Einsatzmöglichkeiten demonstrieren sollen.


Einfache Verbindungstests (Port-Checks)

Im einfachsten Fall kann Netcat dazu verwendet werden, die Verfügbarkeit von Ports zu testen. Im Fall von TCP-Verbindungen geschieht dies über folgenden Aufruf:

# nc -v -z Remote-Host Port
# nc -v -z 10.3.64.1 53
Connection to 10.3.64.1 53 port [tcp/domain] succeeded!

Im Fall von UDP-Diensten muss folgender Aufruf verwendet werden:

# nc -v -z -u Remote-Host Port
# nc -v -z -u 10.3.64.1 53
Connection to 10.3.64.1 53 port [udp/domain] succeeded!


In beiden Fällen signalisiert die Ausgabe (erzwungen durch die Option -v), dass der Verbindungsaufbau erfolgreich war und damit der Port grundsätzlich erreichbar ist. Alternativ kann man aber bei Verwendung dieser Aufrufe in Scripten den Return-Code auswerten (wie allgemein üblich heißt 0 erfolgreich und größer 0 nicht erfolgreich).

Portscanner

Wenn andere Mittel fehlen, kann Netcat recht einfach als Portscanner herhalten. Der Aufruf ist, ähnlich wie bei einfachen Port-Checks, auch hier recht übersichtlich:

# nc -v -n -z -w1 Remote-Host StartPort-EndPort

Beispiel: Bei Server 10.2.64.1 soll nach offenen TCP-Ports im Bereich zwischen Port 25 und 443 (einschließlich) gesucht werden.

# nc -v -n -z -w1 10.2.64.1 25-443
Connection to 10.2.64.1 25 port [tcp/] succeeded!
nc: connect to 10.2.64.1 port 26 (tcp) failed: Connection refused
nc: connect to 10.2.64.1 port 27 (tcp) failed: Connection refused
[…]
nc: connect to 10.2.64.1 port 52 (tcp) failed: Connection refused
Connection to 10.2.64.1 53 port [tcp/] succeeded!
nc: connect to 10.2.64.1 port 54 (tcp) failed: Connection refused
[…]
nc: connect to 10.2.64.1 port 79 (tcp) failed: Connection refused
Connection to 10.2.64.1 80 port [tcp/] succeeded!
nc: connect to 10.2.64.1 port 81 (tcp) failed: Connection refused
[…]
nc: connect to 10.2.64.1 port 442 (tcp) failed: Connection refused
Connection to 10.2.64.1 443 port [tcp/] succeeded!

Der Scan zeigt hier, dass neben Port 25 (SMTP) auch die Ports für DNS (53), HTTP (80) und HTTPS (443) verfügbar sind.

Netcat eignet sich weiterhin auch zum sog. Banner Grabbing, d. h. zur näheren Untersuchung von entfernten Diensten. Üblicherweise (zumindest für mich :-) ) wird für eine solche Untersuchung das telnet-Kommando verwendet. Der telnet-Client ist allerdings nicht immer installiert, und es zeigt sich, dass auch Netcat diese Aufgabe durchaus genauso gut erfüllen kann.

Banner Grabbing soll hier am Beispiel des SMTP-Dienstes eines entfernten Servers gezeigt werden:

# nc 10.2.64.1 25
220 mail.example.net ESMTP Postfix (Debian/GNU)
==> ehlo test
250-mail.example.net
250-PIPELINING
250-SIZE 102400000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

(==> bedeutet hierbei die Eingabe von Befehlen oder Daten)

Hier erfahren wir, dass es sich um ein Postfix-SMTP Server handelt in der Debian-Variante.

Man könnte jetzt u. a. noch prüfen, ob es sich um einen offenenes Relay handelt, indem man noch die folgenden Eingaben tätigt:

==> mail from: user@domains.com
250 2.1.0 Ok
==> rcpt to: name@example.net
250 2.1.5 Ok
==> data
354 End data with .
==> From: user@domains.com
==> To: name@example.net
==> Subject: Testmail
==>
==> Testmail
==> .
250 2.0.0 Ok: queued as A6E02238
==> quit
221 2.0.0 Bye

Womit der SMTP-Handshake erfolgreich abgeschlossen wurde.

In Verbindung mit Webservern funktioniert dies ähnlich:

# nc -v -n 10.2.64.1 80
Connection to 10.2.64.1 80 port [tcp/*] succeeded!
GET HTTP
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sun, 16 Dec 2018 19:42:17 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

Hier sehen wir u. a., dass wir einen NGINX-Webserver getestet haben.

Datei-Übertragung

In manchen Fällen mag es erforderlich sein, ein File von einem System zu einem anderen zu transferieren, ohne die Möglichkeit zu haben, geeignete File Transfer Mechanismen wie ftp, scp, sftp o. ä. nutzen zu können. Auch hier kann Netcat ein Weg sein, mit einfachen Mitteln ans Ziel zu gelangen.

Vorgehen: Im ersten Schritt öffnen wir einen Port auf dem Zielsystem. Die Ausgabe leiten wir dabei in ein File um:

# nc -l -p 1234 >/tmp/test.txt

Auf dem Ausgangssystem haben wir die Datei test.txt, die wir auf das Zielsystem transferieren möchten. Der Inhalt der test.txt ist wie folgt:

# cat test.txt
Dies
ist
nur
ein
Test

Der Transfer kann nun mit dem folgenden Aufruf erfolgen:

# nc Remote-Host 1234 <test.txt 

Nach Ausführen des Kommandos auf dem Quell-System sollte sich der Listener-Prozess auf dem Zielsystem beendet haben und die Datei test.txt unter /tmp erzeugt haben. Sicherheitshalber sollte man sich davon überzeugen, dass Größe und Inhalt beider Dateien (Quelle und Ziel) identisch sind.

Remote-Shell (Backdoor-Shell)

Netcat kann ebenfalls verwendet werden, eine Shell auf einem entfernten System bereitzustellen. Im „normalen“ Betrieb kann man auf diesem Wege eine Absicherung einrichten, einen Shell-Zugriff zu erlauben, wenn im Zuge von Wartungsarbeiten die Gefahr besteht, sein Standbein auf diesem System, also z.B seine SSH-Verbindung, zu verlieren. Diese Form der Remote-Shell erfordert die netcat-Option -e, die aber bei der Debian/Ubuntu-Variante in der Regel fehlt.

Auf dem Zielsystem wird Netcat mit den folgenden Optionen ausgeführt:

# nc -l -p LocalPort -e /bin/bash

Beispiel:

# nc -l -p 1234 -e /bin/bash

Damit öffnen wir auf dem Zielsystem den TCP-Port 1234 und führen nach erfolgtem Verbindungsaufbau die Shell /bin/bash aus. Auf dem Client kann nun mit dem Aufruf

# nc Remote-Host Remote-Port

der Verbindungsaufbau gestartet werden:

# nc 10.2.64.1 1234

Mit Shell-befehlen können nun Operationen auf dem Zielsystem ausgeführt werden:

hostname -f
remotehost.example.net
cd /var
ls -l
drwxr-xr-x   2 root root      4096 Feb  6  2018 backups
drwxr-xr-x  26 root root      4096 Feb  5  2018 cache
drwxrwsrwt   2 root whoopsie  4096 Aug 10 07:35 crash
drwxr-xr-x   2 root root      4096 Feb  2  2018 games
drwxr-xr-x 107 root root      4096 Feb  5  2018 lib
drwxrwsr-x   3 root staff     4096 Aug  8  2013 local
lrwxrwxrwx   1 root root         9 Jun 21  2013 lock -> /run/lock


Chat

Man kann Netcat auch für die Übermittlung von Textnachrichten einsetzen. Ähnlich wie beim Write-Kommando, mit welchem man Nachrichten an einen anderen Benutzer auf dem selben System schicken kann, kann man mit Netcat Nachrichten an einen Benutzer auf einem anderen System schicken. Dazu muss man sich einerseits auf einen definierten Port einigen, und weiterhin muss dieser Port zwischen den Systemen erreichbar sein.

Auf dem empfangenden System muss man mit den Optionen

# nc -l Port

einen Port öffnen.

Auf dem sendenden System connectiert man diesen Port über den folgenden Aufruf:

# nc Remote-Host Port

Auf dem Sender wird nun eine Eingabe über STDIN beim Empfänger über STDOUT ausgegeben.
Beispiel:

+--------------------------------------------+
| Sender                   | Empfänger       |
|==========================|=================|
|                          | # nc -l 1234    |
+--------------------------------------------+
| # nc 10.2.64.1 1234      |                 |
+--------------------------------------------+
| → Hallo                  |                 |
+--------------------------------------------+
|                          | Hallo →         |
+--------------------------------------------+
|                          | → Test          |
+--------------------------------------------+
|   Test →                 |                 |
+--------------------------------------------+

(→ Text: Eingabe von Text; Text → : Ausgabe von Text) Die Verbindung ist bidirektional.,d. h. die Eingabe auf dem Sender wird auf dem Empfänger ausgegeben und eine Eingabe in derselben Session auf dem Empfänger wird auf dem Sender ebenfalls ausgegeben. Anzumerken sei, dass dies nur eine sehr einfache Art des Nachrichtenaustauschs ist und noch dazu vollkommen unverschlüsselt. Btw. neben TCP als Übertragungsprotokoll kann auch UDP verwendet werden.


ssh-ProxyCommand

Hat man Systeme zu administrieren, die nur über einen oder mehrere Jumphosts erreichbar sind, so kann man entweder den umständlichen Weg nehmen und sich Host für Host anmelden, um schließlich auf das Zielsystem zu gelangen, oder man vereinfacht sich die Arbeit und nutzt das ProxyCommand-Feature von ssh. In Verbindung mit Netcat kann man so eine Möglichkeit schaffen, mittels eines ssh-Kommando-Aufrufs quasi direkt (also über einen Hob) auf das Zielsystem zu gelangen. Dabei hat es den Anschein, als würde man die Kette von Jumphosts zwischen Quelle und Ziel einfach überspringen. An einem einfachen Beispiel will ich darstellen, wie die Konfiguration aussehen kann:

Szenario:

Quelle → Jumphost → Zielsystem

Konfigurationsbeispiel:

# cat /home/user/.ssh/config
Host [Zielsystem]
ProxyCommand ssh user@[Jumphost] nc -w2 %h 22
User user

Also konkret:

Host 172.16.1.1
ProxyCommand ssh user@10.2.64.1 nc -w2 %h 22
User user

# ssh -F /home/user/.ssh/config 172.16.1.1
user@10.2.64.1's password: 
user@172.16.1.1's password: 
user@172.16.1.1:~$ 

Die Authentifizierungsschritte auf Jumphost und Zielsystem müssen natürlich durchgeführt werden, können aber u. U. durch eine geeignete Verwendung von ssh-Keys vereinfacht werden. Netcat dient hier als Mittler, der einen entsprechenden Socket für die Verbindung zum nächsten Host ermöglicht und durchreicht.



Soweit eine Übersicht über Netcat, welches nicht umsonst das Schweizer Taschenmesser der Netzwerk-Administration bezeichnet wird. Es gibt noch eine ganze Reihe weiterer Einsatzmöglichkeiten, und durch die Universalität dieses Tools kann man mit ein wenig Fantasie noch weitere Möglichkeiten finden. Es sei aber noch darauf hingewiesen, dass so gut dieses Tool einen Administrator bei seiner Arbeit unterstützen kann, so gut kann es auch unliebsame Besucher/Eindringlinge unterstützen. Hinsichtlich der Absicherung von Systemen sollte daher durchaus abgewägt werden, inwieweit Tools wie Netcat oder ähnliche in den Installationsumfang von Systemen insb. Frontendsystemen gehört.


Frank Möller
Senior Technical Consultant


Quellen: Offizielle Seite: GNU netcat
Erweiterte Variante: nmap Variante


x

Der Job interessiert mich!

Wir haben Deine E-Mail-Adresse erhalten und melden uns kurzfristig bei Dir!