Network Time Security - Absicherung von NTP gegen MITM-Angriffe

Network Time Security

Absicherung von NTP gegen MITM-Angriffe

Michael Schneider
von Michael Schneider
am 17. November 2022
Lesezeit: 10 Minuten

Keypoints

So sichern Sie das Network Time Protocol

  • NTP ist ein altes Protokoll ohne Sicherheitsfunktionen
  • Protokolle wie DNSSEC, Kerberos und TLS sind abhängig von einer korrekten Systemzeit
  • Mit MITM-Angriffen können NTP-Antworten und somit die Systemzeit manipuliert werden
  • Durch Härtungsmassnahmen kann die Systemzeit vor abrupten Zeitsprüngen geschützt werden
  • Network Time Security (NTS) bringt Authentisierung und Verschlüsselung für NTP und schützt vor MITM-Attacken

Das Network Time Protocol (NTP) ist eines der ältesten Internetprotokolle, das noch weit verbreitet genutzt wird. Das Protokoll verfügt über keine Sicherheitsmechanismen, die Kommunikation erfolgt unverschlüsselt, es gibt keine Authentisierung zwischen Client und Server und keine Vorkehrung gegen die Manipulation der Netzwerkpakete. Angriffe gegen NTP können einen grossen Einfluss haben, da weitere Protokolle wie DNSSEC, Kerberos und TLS auf die Genauigkeit der Systemzeit angewiesen sind.

Die meisten Angriffe basieren auf einer Machine-in-the-Middle-Attacke (MITM). Sobald Angreifer sich in dieser privilegierten Position befinden, können diese Antworten des Servers manipulieren und damit eine falsche Zeit vorgeben, die Antworten von Servern verzögern oder vollständig verwerfen um zu verhindern, dass der Client weiterhin seine Systemzeit mit einem oder mehreren Servern abgleichen kann. Wir demonstrieren ein solcher Angriff, zeigen mit welchen Massnahmen die Systemzeit geschützt werden kann und stellen mit dem Protokoll Network Time Security eine Erweiterung des NTP-Protokolls zum Schutz gegen solche Angriffe vor.

Angriffe gegen NTP

Für einen Angriff müssen sich Angreifer in einer Position befinden, um den Netzwerkverkehr von Client und Server mitlesen und manipulieren zu können. Dies kann in Form einer MITM-Attacke realisiert werden. Für das folgende Beispiel gibt es die Akteure:

Mallory wird einen Angriff auf Bob durchführen und versuchen dessen Systemzeit zu manipulieren. Vor dem Angriff verfügt Bob über eine synchronisierte Systemzeit und verwendet als NTP-Client die Software chrony und vier Zeitserver des NTP Pool Projekts.

[user@bob ~]$ timedatectl 
               Local time: Tue 2022-08-16 17:08:12 CEST
           Universal time: Tue 2022-08-16 15:08:12 UTC
                 RTC time: Tue 2022-08-16 15:08:12
                Time zone: Europe/Zurich (CEST, +0200)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Der Aufruf des Befehls timedatectl zeigt, dass auf dem System alles in Ordnung scheint.

Als Demonstration für einen Angriff kann das Skript von Davide Bove verwendet werden. Das Skript musste noch angepasst werden, und steht als Fork zur Verfügung. Bei der Ausführung des Skripts wird automatisch eine ARP-Spoofing-Attacke durchgeführt und danach die Systemzeit aller übermittelten NTP-Pakete manipuliert.

[user@mallory ~]$ sudo python3 ntpspoof.py 192.168.244.130 eth0
Running ARP spoofing for target: 192.168.244.130 using the router: 192.168.244.2
[*] waiting for NTP packages
Received package for: 192.168.244.130 -> Modified!
Received package for: 192.168.244.130 -> Modified!
Received package for: 192.168.244.130 -> Modified!

Das Skript wurde auf dem System Mallory gestartet und sobald eine Zeitsynchronisation durchgeführt wurde, wurden die Pakete manipuliert. Der Angriff verlieft erfolgreich, was ersichtlich ist in der Meldung von chrony, dass die Systemzeit um 486805679 Sekunden falsch läuft und korrigiert wurde.

[user@bob ~]$ sudo chronyd -q "server 0.ch.pool.ntp.org iburst"
2022-08-16T15:11:20Z chronyd version 4.2 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH +IPV6 +DEBUG)
2022-08-16T15:11:20Z Initial frequency -9.183 ppm
2022-08-16T15:11:24Z System clock wrong by 486805679.997304 seconds (step)
2038-01-18T22:59:24Z chronyd exiting

[user@bob ~]$ timedatectl 
               Local time: Mon 2038-01-18 23:59:31 CET
           Universal time: Mon 2038-01-18 22:59:31 UTC
                 RTC time: Tue 2022-08-16 15:11:31
                Time zone: Europe/Zurich (CET, +0100)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

Auch die Ausgabe der Systemzeit zeigt, dass der Angriff erfolgreich war und das System Bob eine neue Systemzeit in der Zukunft übernommen hatte.

Systemzeit schützen

Da die Übertragung von NTP-Paketen weder verschlüsselt noch signiert erfolgt, kann auf Protokollebene keine Mitigation gegen solche Angriffe vorgenommen werden. Es ist aber möglich in der Konfiguration von chrony die Systemzeit von zu grossen respektive abrupten Zeitsprüngen zu schützen. In der FAQ-Sektion von chrony ist beschrieben, wie die Systemzeit geschützt werden kann. Die Einstellung maxchange gibt beispielsweise vor, dass der grösstmögliche Zeitsprung nicht mehr als 100 Sekunden betragen kann, ansonsten tritt ein Fehler auf und der chrony Daemon beendet sich.

minsources 3
maxchange 100 0 0
makestep 0.001 1
maxdrift 100
maxslewrate 100
driftfile /var/lib/chrony/drift
rtcsync

Die Konfiguration von chrony wurde um die obenstehenden Einstellungen erweitert, und der Angriff nochmals durchgeführt.

systemd[1]: Started NTP client/server.
chronyd[3072]: Selected source 31.3.135.232 (1.ch.pool.ntp.org)
chronyd[3072]: Adjustment of 486753299.993 seconds exceeds the allowed maximum of 100.000 seconds (exiting)
chronyd[3072]: chronyd exiting
systemd[1]: chronyd.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: chronyd.service: Failed with result 'exit-code'.

In den Logs von chrony zeigt sich nun, dass die Abweichung mit der Zeit in den manipulierten NTP-Pakete über den erlaubten 100 Sekunden war und sich chrony daher selbst beendet hat. Die Manipulation der System war zwar nicht möglich, aber die Zeitsynchronisation ist immer noch ungeschützt. Zudem können Angreifer die Zeit weiterhin manipulieren, einfach mit kleineren Schritten.

Network Time Security

Der Mechanismus Network Time Security (NTS) wurde im RFC 8915 spezifiziert und verwendet Transport Layer Security (TLS) und Authenticated Encryption with Associated Data (AEAD) um den Client-Server-Modus von NTP abzusichern. NTS umfasst die Subprotokolle NTS Key Establishment (NTS-KE), was die initiale Authentisierung und die Einrichtung der Schlüssel über TLS handhabt, sowie NTS Extension Fields for NTPv4, welches die Verschlüsselung und Authentisierung von Erweiterungsfeldern in NTP-Paketen während der Zeitsynchronisation steuert.

Beim Initialaufbau verbindet sich der NTP-Client mit einem NTS-KE-Server über den NTS-TCP-Port, normalerweise 4460/tcp, und es wird ein TLS-Handshake durchgeführt. Über den TLS-Kanal werden dann weitere Parameter ausgehandelt und der Server sendet dem Client Cookies, dies zusammen mit dem zu verwendenden NTP-Server. Zudem wird über TLS Key Export, definiert in RFC 5705, Schlüsselmaterial ausgetauscht. Danach ist die NTS-KE-Phase abgeschlossen und der NTP-Client braucht zukünftig keine weitere Verbindung mehr mit dem NTS-KE-Server aufzubauen.

Bei der Zeitsynchronisation sendet der NTP-Client dann ein Paket, dass mehrere Erweiterungsfelder enthält, unter anderem befindet sich dabei das Cookie und ein Authentication-Tag, der aus dem Schlüsselmaterial aus dem NTS-KE-Handshake generiert wurde. Der NTP-Server verwendet das Cookie um server-seitig auf das Schlüsselmaterial zuzugreifen und sendet schlussendlich eine authentisierte Antwort zurück. Neben den Zeitangaben umfasst diese Antwort auch ein neues Cookie, das im nächsten Request des Clients verwendet wird.

Konfiguration NTP-Client

Der NTP-Client Chrony unterstützt NTS seit der Version 4. In der Konfiguration von Chrony kann bei jedem Zeitserver die Option NTS aktiviert werden – falls der Zeitserver NTS unterstützt. Zudem sollte die Option ntsdumpdir /var/lib/chrony in die Konfigurationsdatei aufgenommen werden, damit die NTS-Schlüssel und Cookies gespeichert werden und der NTS-KE-Handshake nicht nach jedem Neustart des Dienst durchgeführt werden muss. Eine Sammlung von Zeitservern mit NTS liegt im GitHub Gist Time Servers with NTS support vor.

Die Datei /etc/chrony.conf wird entsprechend um eine Liste von Servern ergänzt. Es empfiehlt sich nicht Zeitserver ohne NTS- und solche mit NTS-Unterstützung zu mischen.

server time.cloudflare.com iburst nts maxdelay 0.1
server ntp.trifence.ch iburst nts maxdelay 0.1
server ntp.zeitgitter.net iburst nts maxdelay 0.1
server ntp.3eck.net iburst nts maxdelay 0.1
server nts.netnod.se iburst nts maxdelay 0.1
server ptbtime1.ptb.de iburst nts maxdelay 0.1
server ptbtime2.ptb.de iburst nts maxdelay 0.1 
server ptbtime3.ptb.de iburst nts maxdelay 0.1

Danach kann mit dem Befehl chronyc -N authdata geprüft werden, ob der NTS-KE-Handshake erfolgreich war.

[user@bob ~]$ sudo chronyc -N authdata
Name/IP address             Mode KeyID Type KLen Last Atmp  NAK Cook CLen
=========================================================================
time.cloudflare.com          NTS     1   15  256 188m    0    0    8  100
ntp.trifence.ch              NTS     2   15  256 191m    0    0    8  100
ntp.zeitgitter.net           NTS     2   15  256 191m    0    0    8  100
ntp.3eck.net                 NTS     2   15  256 191m    0    0    8  100
ptbtime1.ptb.de              NTS     2   15  256 191m    0    0    8  100
ptbtime2.ptb.de              NTS     2   15  256 191m    0    0    8  100
ptbtime3.ptb.de              NTS     2   15  256 191m    0    0    8  100

Die Felder KeyID, Type, und KLen sollten nicht 0 sein. Eine mögliche Fehlerquelle wäre, dass die Firewall die ausgehende Verbindung auf den Port 4460/tcp blockt. Der Status der Zeitsynchronisation kann mittels des Befehls chronyc -N sources verifiziert werden.

[user@bob ~]$ chronyc -N sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^+ time.cloudflare.com           3  10   377   124   +532us[ +532us] +/-   18ms
^+ ntp.trifence.ch               2  10   377   828   -617us[ -437us] +/-   12ms
^+ ntp.zeitgitter.net            3  10   377   356    +81us[  +81us] +/-   11ms
^* ntp.3eck.net                  2  10   377   439   +330us[ +515us] +/- 6230us
^- ptbtime1.ptb.de               1  10   377   105   +494us[ +494us] +/-   18ms
^- ptbtime2.ptb.de               1  10   377   373   +218us[ +218us] +/-   19ms
^- ptbtime3.ptb.de               1  10   377   613   +745us[ +928us] +/-   18ms

Die Spalte Reach hat idealerweise den Wert 377. Dieser Wert gibt an, dass die letzten 8 Abfragen eine valide Antwort ergaben, inklusive der NTS-Validierung. Wenn nun der MITM-Angriff nochmals durchgeführt wird, dann verwirft chrony die Antworten und der Wert in der Spalte Reach bleibt auf 0.

[user@bob ~]$ chronyc -N sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^? time.cloudflare.com           0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ntp.trifence.ch               0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ntp.zeitgitter.net            0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ntp.3eck.net                  0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ptbtime1.ptb.de               0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ptbtime2.ptb.de               0   7     0     -     +0ns[   +0ns] +/-    0ns
^? ptbtime3.ptb.de               0   7     0     -     +0ns[   +0ns] +/-    0ns

Durch den Einsatz von NTS kann die Manipulation von NTP-Paketen durch einen MITM-Angriff verhindert werden. Angreifer haben zwar noch die Möglichkeit die Zeitsynchronisation zu beeinträchtigen, da der NTP-Client keine gültigen Antworten mehr erhält.

Fazit

Mit der Einführung von NTS können bekannte Angriffe gegen NTP abgewehrt werden. NTS wird noch nicht in allen NTP-Clients unterstützt und nicht alle Linux Distributionen verfügen über die aktualisierten Versionen von Clients, die NTS implementiert haben. Zudem existieren im August 2022 erst wenige Server mit NTS-Unterstützung. Für Windows gibt es noch keine Unterstützung von NTS. Für eine grossflächige Verbreitung von NTS braucht es also noch Zeit.

Da eine korrekte Systemzeit für viele weitere Protokolle essentiell ist, ist die Einführung einer Absicherung des NTP-Protokolls ein wichtiger und notwendiger Schritt. Der Einsatz von NTS auf den Zeitservern in der Firmeninfrastruktur sollte daher geplant und in nächster Zeit umgesetzt werden.

Über den Autor

Michael Schneider

Michael Schneider arbeitet seit dem Jahr 2000 in der IT. Im Jahr 2010 hat er sich auf die Informationssicherheit spezialisiert. Zu seinen Aufgaben gehören das Penetration Testing, Hardening und das Aufspüren von Schwachstellen in Betriebssystemen. Er ist bekannt für eine Vielzahl in PowerShell geschriebener Tools zum Finden, Ausnutzen und Beheben von Schwachstellen. (ORCID 0000-0003-0772-9761)

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Area41 2024

Area41 2024 - Ein Rückblick

Michael Schneider

Bericht und Dokumentation

Bericht und Dokumentation

Michael Schneider

Einführung von CVSS v4.0

Einführung von CVSS v4.0

Michael Schneider

Rogue Device

Rogue Device

Michael Schneider

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv