Autorização de UID e Stalker no MAG250

Há muito tempo estou interessado no tópico de autorização de consoles de mídia no portal Stalker, mas não era antes disso. Um dia, acidentalmente, recebi o prefixo Infomir MAG250 e decidi resolver esse problema.

Treinamento


Antes de tudo, desmontei o prefixo, soldei o cabo ao conector e o conectei ao computador. Após o lançamento do programa do terminal, fiquei satisfeito com o familiar U-Boot. O processo de inicialização também pode ser interrompido pressionando qualquer tecla (geralmente o fabricante desativa esses chips e você precisa gastar muito tempo para levar o U-Boot ao estado desejado). O acesso com privilégios de root também estava disponível via ssh.



O console está equipado com DRAM de 256 MB e duas unidades flash, NOR 1 MB e NAND 256 MB. Com o NOR, o U-Boot é carregado no processo, que carrega o kernel e o sistema de arquivos do NAND.

Função Getuid ()


O prefixo se autoriza no portal Stalker, enviando várias informações, como, por exemplo, tipo, versão do firmware, versão do hardware, número de série etc. Mas eu estava especificamente interessado no parâmetro device_id, emitido pela função gSTB.GetUID (). À primeira vista, era um hash como SHA256 ou MD5. Referindo-se à documentação oficial soft.infomir.com/stbapi/JS/v343/gSTB.html#.GetUID , a função pode levar até dois parâmetros, mas a primeira coisa que me interessou foi a opção sem parâmetros. Ao carregar o stbapp no ​​IDA, podemos encontrar facilmente essa função.



Indo um pouco mais adiante, vemos um momento interessante



Aqui, o programa aloca 0x41 bytes de memória, anula-o e chama a função de driver / dev / stapi / stevt_ioctl, passando para ele esta parte da memória e o parâmetro 0xC004C919. Portanto, um certo driver stevt_ioctl é responsável por gerar o UID. Para verificar isso, esbocei rapidamente este código: Ao



executá-lo no console, vi um UID familiar.

stevt_ioctl


A próxima etapa é desmontar o driver stapi_ioctl_stripped.ko, localizado em / root / modules. Carregamos o driver no IDA e encontramos o manipulador 0xC004C919 ioctl (eu chamei essa função de calcHash).



Existem três pontos interessantes. Primeiro, 0x41 bytes de memória são copiados do espaço do usuário para o espaço do kernel (é exatamente isso que é transmitido pelo usuário e, no nosso caso, consiste em zeros), a função get_mem_type é chamada(ao longo do caminho no próprio kernel) e o resultado (novamente 0x41 bytes) é copiado para a área de endereço do usuário. Para encontrar o endereço da função get_mem_type, vi duas possibilidades: basta olhar para o arquivo / proc / kallsysms, esperando que o acesso não fosse restrito, bem, ou, caso contrário, escrever um assembly no assembler para o próprio driver que retornará o valor do registro r0 no lugar certo. Tendo examinado / proc / kallsysms, fiquei agradavelmente surpreso e encontrei o endereço da função get_mem_type 0x8080E380.

Testemunho


Para uma análise mais aprofundada, você precisará analisar o kernel. O próprio kernel pode ser encontrado no firmware do fabricante ou você pode remover o despejo usando o U-Boot



ou montar a partição desejada.

Com base nas informações do U-Boot, o kernel é carregado em 0x80800000 e o ponto de entrada é em 0x80801000. Carregamos o kernel no IDA e encontramos a função get_mem_type .

Depois de analisar o código, descobri esta seção, que supostamente retornava o UID.



Portanto, o UID é armazenado em 0x80D635EC. Em seguida, procuramos na AID, onde esse valor é formado. Isso estava na função init_board_extra (não traduzirei a lista completa)



Portanto, esse é o mesmo valor desconhecido no endereço do registrador r4 a partir do qual o hash de interesse é calculado (fill_hash, a propósito, foi resolvido pelo SHA256). Eu realmente estava ansioso para descobrir o que era e rapidamente escrevi uma inserção no assembler, que, através da função printk, retornou o conteúdo da memória no endereço do registrador r2. Depois de modificar o kernel dessa maneira, criei uma nova uImage e a enviei para uma unidade USB. E no terminal U-Boot definido:

usb start
fatload usb 0:1 80000000 uImage
bootm

Mas depois da última equipe, uma tristeza estava me esperando: o



U-Boot se recusou educadamente a enviar meu novo kernel.

Editando U-Boot


Para convencer o U-Boot a inicializar meu kernel, decidi corrigi-lo na memória com o próprio comando mw . Para começar, fiz um despejo completo do flash NOR, localizado em 0xA0000000. Tendo conduzido o despejo para o IDA, descobri o endereço de memória onde o U-Boot se copiava. Era 0x8FD00000. Novamente, depois de despejar essa parte da memória e executar o IDA, encontrei facilmente uma função que verificava a assinatura. Se tudo estivesse correto, ela retornaria 0. Além disso, ela foi chamada em dois lugares diferentes.



O que exatamente essa função fez não foi interessante para mim. Ela só precisava retornar 0 assim:

mov #0x0, r0
rts
nop

O código correspondente para o U-Boot agora era assim:

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

Em seguida, o U-Boot carregou felizmente meu kernel, que emitiu

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

Análise completa


Então, em que consistia o UID? Era um número desconhecido de 8 bytes, o número de série do console, o endereço MAC, o tipo de console e um pedaço de lixo. Resta descobrir que tipo de número desconhecido era e de onde veio o lixo. Voltei à função init_board_extra novamente .

Um número desconhecido foi obtido nesta seção de código:



Aqui, usando a função __ioremap, o kernel acessou a memória física em 0x00000000 (que era o endereço NOR do flash), gravou 0x0F a 0x00000000, depois 0x98 a 0x000000AA e leu 8 bytes a partir de 0x000000C2. E o que é isso? Estes são os comandos do protocolo CFI com os quais o kernel se comunicou com o NOR. 0x0F trouxe o NOR ao seu estado original e, com o comando 0x98, o CFI modifica o comando. Neste módulo, no endereço 0x000000C2 está a área do código de segurança ou o número de dispositivo exclusivo de 64 bits. Essa. número desconhecido é um número de flash NOR exclusivo. A seguir, é apresentado um despejo de identificação de CFI.



Você pode fazer seu dump diretamente no U-Boot definindo
mw.w a0000000 f0
mw.w a00000aa 98
md.b a1000000 100

Um pedaço de lixo era apenas um conjunto de caracteres comum de 32 bytes que era costurado no próprio kernel.E



esse lixo foi processado antes de usar a função de criptografia swap_pairs , que simplesmente alterava a posição dos bytes

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


Com base nas informações recebidas, atrevo-me a supor que o banco de dados do fabricante contém informações sobre cada flash ID NOR e o número de série e endereço MAC correspondentes.
Obviamente, é impossível selecionar tudo isso, mas você pode escrever seu próprio software, que emulará totalmente o console.

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


All Articles