UID et autorisation Stalker sur le MAG250

Je m'intéresse depuis longtemps au sujet de l'autorisation des consoles de médias dans le portail Stalker, mais ce n'était pas avant cela. Un jour, j'ai accidentellement obtenu le préfixe Infomir MAG250 et j'ai décidé de résoudre ce problème.

Entraînement


Tout d'abord, j'ai démonté le préfixe, soudé le câble au connecteur et connecté à l'ordinateur. Après avoir lancé le programme de terminal, j'ai été satisfait du U-Boot familier. Le processus de démarrage peut également être interrompu en appuyant sur n'importe quelle touche (généralement, le fabricant désactive ces puces et vous devez passer beaucoup de temps pour amener U-Boot à l'état souhaité). L'accès avec les privilèges root était également disponible via ssh.



La console est équipée de 256 Mo de DRAM et de deux lecteurs flash, NOR 1 Mo et NAND 256 Mo. Avec NOR, U-Boot est chargé dans le processus, qui charge le noyau et le système de fichiers depuis NAND.

Fonction Getuid ()


Le préfixe s'autorise dans le portail Stalker, envoyant un tas d'informations, telles que, par exemple, le type, la version du micrologiciel, la version du matériel, le numéro de série, etc. Mais je m'intéressais spécifiquement au paramètre device_id, émis par la fonction gSTB.GetUID (). À première vue, c'était un hachage comme SHA256 ou MD5. En se référant à la documentation officielle soft.infomir.com/stbapi/JS/v343/gSTB.html#.GetUID , la fonction peut prendre jusqu'à deux paramètres, mais la première chose qui m'intéressait était l'option sans paramètres. En chargeant stbapp dans l'IDA, nous pouvons facilement trouver cette fonction.



En allant un peu plus loin, nous voyons un moment intéressant



Ici, le programme alloue 0x41 octets de mémoire, l'annule et appelle la fonction de pilote / dev / stapi / stevt_ioctl, en lui passant ce morceau de mémoire et le paramètre 0xC004C919. Par conséquent, un certain pilote stevt_ioctl est responsable de la génération de l'UID. Pour vérifier cela, j'ai rapidement esquissé ce code:



En l'exécutant sur la console, j'ai vu un UID familier.

stevt_ioctl


L'étape suivante consiste à démonter le pilote stapi_ioctl_stripped.ko, qui se trouve dans / root / modules. Nous chargeons le pilote dans l'IDA et trouvons le gestionnaire 0xC004C919 ioctl (j'ai appelé cette fonction calcHash).



Il y a trois points intéressants. Tout d'abord, 0x41 octets de mémoire sont copiés de l'espace utilisateur vers l'espace noyau (c'est exactement ce qui est transmis par l'utilisateur et dans notre cas se compose de zéros), la fonction get_mem_type est appelée(en cours de route dans le noyau lui-même) et le résultat (à nouveau 0x41 octets) est ensuite copié dans la zone d'adresse de l'utilisateur. Pour trouver l'adresse de la fonction get_mem_type, j'ai vu deux possibilités: regardez simplement le fichier / proc / kallsysms, en espérant que l'accès n'était pas restreint, eh bien, ou, sinon, écrivez un assembly dans assembler pour le pilote lui-même qui retournera la valeur du registre r0 au bon endroit. Après avoir regardé dans / proc / kallsysms, j'ai été agréablement surpris et j'ai trouvé l'adresse de la fonction get_mem_type 0x8080E380.

Coeur


Pour une analyse plus approfondie, vous devrez analyser le noyau. Le noyau lui-même se trouve dans le firmware du fabricant, ou vous pouvez supprimer le vidage à l'aide de U-Boot



ou monter la partition souhaitée.

Sur la base des informations U-Boot, le noyau est chargé à 0x80800000 et le point d'entrée est à 0x80801000. Nous chargeons le noyau dans l'IDA et trouvons la fonction get_mem_type .

Après avoir analysé le code, j'ai découvert cette section, qui aurait renvoyé l'UID.



L'UID est donc stocké à 0x80D635EC. Ensuite, nous recherchons dans l'IDA, où cette valeur est formée. C'était dans la fonction init_board_extra (je ne traduirai pas la liste complète)



Il s'agit donc de la même valeur inconnue à l'adresse du registre r4 à partir de laquelle le hachage d'intérêt est calculé (fill_hash a d'ailleurs été résolu par SHA256). J'étais vraiment impatient de savoir ce que c'était et j'ai rapidement écrit un insert dans l'assembleur, qui, grâce à la fonction printk, a renvoyé le contenu de la mémoire à l'adresse du registre r2. Après avoir modifié le noyau de cette manière, j'ai créé une nouvelle uImage et l'ai téléchargée sur une clé USB. Et dans le jeu U-Boot terminal:

usb start
fatload usb 0:1 80000000 uImage
bootm

Mais après la dernière équipe, une telle tristesse m'attendait.



U-Boot a poliment refusé d'expédier mon nouveau noyau.

Modification de U-Boot


Pour convaincre U-Boot de démarrer mon noyau, j'ai décidé de le patcher en mémoire avec la commande mw elle-même . Pour commencer, j'ai fait un vidage complet du flash NOR, qui est situé à 0xA0000000. Après avoir conduit le vidage dans l'IDA, j'ai découvert l'adresse mémoire où le U-Boot s'est copié. C'était 0x8FD00000. Encore une fois, après avoir vidé cette partie de la mémoire et exécuté IDA, j'ai facilement trouvé une fonction qui vérifiait la signature. Si tout était correct, elle est revenue à 0. De plus, elle a été appelée à deux endroits différents.



Ce que faisait exactement cette fonction ne m'intéressait pas. Elle avait juste besoin de retourner 0 comme ceci:

mov #0x0, r0
rts
nop

Le code correspondant pour U-Boot était maintenant comme ceci:

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

Puis U-Boot a heureusement chargé mon noyau, qui a publié

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

Analyse complète


Alors, en quoi consistait l'UID? C'était un nombre inconnu de 8 octets, le numéro de série de la console, l'adresse MAC, le type de console et un morceau de poubelle. Reste à savoir de quel type de numéro il s'agissait et d'où venaient les ordures. Je suis retourné à nouveau à la fonction init_board_extra .

Un nombre inconnu a été tiré de cette section de code:



Ici, en utilisant la fonction __ioremap, le noyau a accédé à la mémoire physique à 0x00000000 (qui était l'adresse NOR du flash), a écrit 0x0F à 0x00000000, puis 0x98 à 0x000000AA et a lu 8 octets à partir de 0x000000C2. Et c'est quoi? Ce sont les commandes du protocole CFI avec lesquelles le noyau a communiqué avec NOR. 0x0F a ramené le NOR à son état d'origine, et avec la commande de commutation 0x98, mods CFI. Dans ce module, à l'adresse 0x000000C2 se trouve la zone de code de sécurité ou le numéro de périphérique unique 64 bits. Ceux. un nombre inconnu est un numéro de flash NOR unique. Ce qui suit est un cliché d'identification CFI.



Vous pouvez effectuer votre vidage directement dans U-Boot en définissant
mw.w a0000000 f0
mw.w a00000aa 98
md.b a1000000 100

Une poubelle était juste un jeu de caractères ordinaire de 32 octets qui était cousu dans le noyau lui-même.



Et cette poubelle a été traitée avant d'utiliser la fonction de chiffrement swap_pairs , qui a simplement changé la position des octets

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


Sur la base des informations reçues, j'ose supposer que la base de données du fabricant contient des informations sur chaque flash ID NOR et le numéro de série et l'adresse MAC correspondants.
Bien sûr, il est impossible de sélectionner tout cela, mais vous pouvez écrire votre propre logiciel, qui émulera entièrement la console.

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


All Articles