UID- und Stalker-Autorisierung auf dem MAG250

Das Thema Autorisierung von Medienkonsolen im Stalker-Portal hat mich schon lange interessiert, aber vorher nicht. Eines Tages bekam ich versehentlich das Infomir MAG250-Präfix und beschloss, dieses Problem anzugehen.

Ausbildung


Zuerst habe ich das Präfix zerlegt, das Kabel an den Stecker gelötet und an den Computer angeschlossen. Nachdem ich das Terminalprogramm gestartet hatte, war ich mit dem bekannten U-Boot zufrieden. Der Startvorgang kann auch durch Drücken einer beliebigen Taste unterbrochen werden (normalerweise deaktiviert der Hersteller solche Chips und Sie müssen viel Zeit aufwenden, um U-Boot in den gewünschten Zustand zu bringen). Der Zugriff mit Root-Rechten war auch über ssh möglich.



Die Konsole ist mit 256 MB DRAM und zwei Flash-Laufwerken ausgestattet, NOR 1 MB und NAND 256 MB. Mit NOR wird U-Boot in den Prozess geladen, der den Kernel und das Dateisystem von NAND lädt.

Getuid () Funktion


Das Präfix autorisiert sich im Stalker-Portal und sendet eine Reihe von Informationen, z. B. Typ, Firmware-Version, Hardware-Version, Seriennummer usw. Ich war jedoch speziell an dem Parameter device_id interessiert, den die Funktion gSTB.GetUID () ausgegeben hat. Auf den ersten Blick war es ein Hash wie SHA256 oder MD5. In der offiziellen Dokumentation soft.infomir.com/stbapi/JS/v343/gSTB.html#.GetUID kann die Funktion bis zu zwei Parameter annehmen, aber das erste, was mich interessierte, war die Option ohne Parameter. Durch Laden von stbapp in die IDA können wir diese Funktion leicht finden.



Wenn wir etwas weiter gehen, sehen wir einen interessanten Moment



Hier weist das Programm 0x41 Byte Speicher zu, macht es ungültig und ruft die Treiberfunktion / dev / stapi / stevt_ioctl auf, wobei es dieses Stück Speicher und den Parameter 0xC004C919 übergibt. Daher ist ein bestimmter stevt_ioctl-Treiber für die Generierung der UID verantwortlich. Um dies zu überprüfen, skizzierte ich schnell diesen Code:



Als ich ihn auf der Konsole ausführte, sah ich eine vertraute UID.

stevt_ioctl


Der nächste Schritt besteht darin, den Treiber stapi_ioctl_stripped.ko zu zerlegen, der sich in / root / modules befindet. Wir laden den Treiber in die IDA und finden den Handler 0xC004C919 ioctl (ich habe diese Funktion calcHash genannt).



Es gibt drei interessante Punkte. Zuerst werden 0x41 Bytes Speicher vom Benutzerraum in den Kernelraum kopiert (genau dies wird vom Benutzer übertragen und besteht in unserem Fall aus Nullen). Die Funktion get_mem_type wird aufgerufen(auf dem Weg in den Kernel selbst) und das Ergebnis (wieder 0x41 Bytes) wird dann in den Adressbereich des Benutzers kopiert. Um die Adresse der Funktion get_mem_type zu finden, habe ich zwei Möglichkeiten gesehen: Schauen Sie sich einfach die Datei / proc / kallsysms an, in der Hoffnung, dass der Zugriff nicht eingeschränkt wurde, oder schreiben Sie auf andere Weise eine Assembly in Assembler für den Treiber selbst, die den Wert des Registers r0 an der richtigen Stelle zurückgibt. Nachdem ich in / proc / kallsysms nachgesehen hatte, war ich angenehm überrascht und fand die Adresse der Funktion get_mem_type 0x8080E380.

Ader


Für die weitere Analyse müssen Sie den Kernel analysieren. Der Kernel selbst befindet sich in der Firmware des Herstellers. Sie können den Speicherauszug auch mit U-Boot entfernen



oder die gewünschte Partition bereitstellen.

Basierend auf den U-Boot-Informationen wird der Kernel bei 0x80800000 geladen und der Einstiegspunkt bei 0x80801000. Wir laden den Kernel in die IDA und finden die Funktion get_mem_type .

Nachdem ich den Code analysiert hatte, entdeckte ich diesen Abschnitt, der angeblich die UID zurückgab.



Die UID wird also bei 0x80D635EC gespeichert. Als nächstes suchen wir in der IDA, wo dieser Wert gebildet wird. Dies war in der Funktion init_board_extra (ich werde die vollständige Liste nicht übersetzen).



Dies ist also derselbe unbekannte Wert an der Adresse des r4-Registers, aus dem der interessierende Hash berechnet wird (fill_hash wurde übrigens von SHA256 aufgelöst). Ich wollte unbedingt herausfinden, was es war, und schrieb schnell eine Einfügung in Assembler, die über die Funktion printk den Speicherinhalt an die Adresse des Registers r2 zurückgab. Nachdem ich den Kernel auf diese Weise geändert hatte, erstellte ich ein neues uImage und lud es auf ein USB-Laufwerk hoch. Und im Terminal-U-Boot-Set:

usb start
fatload usb 0:1 80000000 uImage
bootm

Aber nach dem letzten Team wartete eine solche Traurigkeit auf mich.



U-Boot weigerte sich höflich, meinen neuen Kernel zu versenden.

U-Boot bearbeiten


Um U-Boot davon zu überzeugen, meinen Kernel zu booten, habe ich beschlossen, ihn mit dem Befehl mw selbst im Speicher zu patchen . Zu Beginn habe ich einen vollständigen Speicherauszug von NOR-Flash erstellt, der sich bei 0xA0000000 befindet. Nachdem ich den Dump in die IDA gefahren hatte, entdeckte ich die Speicheradresse, an die sich der U-Boot selbst kopiert hatte. Es war 0x8FD00000. Nachdem ich diesen Teil des Speichers gelöscht und IDA ausgeführt hatte, fand ich leicht eine Funktion, die die Signatur überprüfte. Wenn alles korrekt war, gab sie 0 zurück. Außerdem wurde sie an zwei verschiedenen Orten angerufen.



Was genau diese Funktion tat, war für mich nicht interessant. Sie musste nur 0 wie folgt zurückgeben:

mov #0x0, r0
rts
nop

Der entsprechende Code für U-Boot lautete jetzt wie folgt:

usb start
mw.l 8fd0ec08 000b200a;
mw.l 8fd0ec0c 00900009
fatload usb 0:1 80000000 uImage
bootm

Dann lud U-Boot glücklich meinen Kernel, der ausgegeben wurde

EF0F3A38FF7FD567012016J04501200:1a:79:23:7e:2MAG250pq8UK0DAOQD1JzpmBx1Vwdb58f9jP7SN

Vollständige Analyse


Woraus bestand die UID? Es war eine unbekannte Anzahl von 8 Bytes, die Seriennummer der Konsole, die MAC-Adresse, der Konsolentyp und ein Stück Müll. Es bleibt abzuwarten, um welche unbekannte Nummer es sich handelt und woher der Müll stammt. Ich kehrte wieder zur Funktion init_board_extra zurück .

Aus diesem Codeabschnitt wurde eine unbekannte Nummer entnommen:



Hier hat der Kernel mithilfe der __ioremap-Funktion unter 0x00000000 (der NOR-Adresse des Flashs) auf den physischen Speicher zugegriffen, 0x0F in 0x00000000 geschrieben, dann 0x98 in 0x000000AA und 8 Bytes ab 0x000000C2 gelesen. Und was ist das? Dies sind die CFI-Protokollbefehle, mit denen der Kernel mit NOR kommuniziert. 0x0F brachte das NOR in seinen ursprünglichen Zustand und mit dem 0x98-Schaltbefehl modifiziert CFI. In diesem Modul befindet sich unter der Adresse 0x000000C2 der Sicherheitscodebereich oder die eindeutige 64-Bit-Gerätenummer. Jene. Unbekannte Nummer ist eine eindeutige NOR-Flash-Nummer. Das Folgende ist ein Speicherauszug der CFI-Identifizierung.



Sie können Ihren Speicherauszug direkt in U-Boot erstellen, indem Sie die Einstellungen vornehmen
mw.w a0000000 f0
mw.w a00000aa 98
md.b a1000000 100

Ein Stück Müll war nur ein gewöhnlicher 32-Byte-Zeichensatz, der in den Kernel selbst eingenäht wurde.



Dieser Müll wurde verarbeitet, bevor die Verschlüsselungsfunktion swap_pairs verwendet wurde , die einfach die Position der Bytes änderte

[0x00000003]<->[0x0000000F]
[0x00000005]<->[0x0000001F]
[0x00000009]<->[0x00000002]
[0x0000000A]<->[0x0000001D]
[0x00000010]<->[0x00000015]
[0x00000004]<->[0x00000013]
[0x0000000D]<->[0x00000018]


Aufgrund der erhaltenen Informationen kann ich davon ausgehen, dass die Datenbank des Herstellers Informationen zu jedem ID-NOR-Flash sowie die entsprechende Seriennummer und MAC-Adresse enthält.
Natürlich ist es unmöglich, all dies auszuwählen, aber Sie können Ihre eigene Software schreiben, die die Konsole vollständig emuliert.

Source: https://habr.com/ru/post/undefined/


All Articles