2 pontos por GN⁺ 2024-05-26 | 1 comentários | Compartilhar no WhatsApp
  • A Samsung WB850F foi o primeiro modelo a usar o SoC DRIMeIII junto com Wi-Fi, e o partialImage.o.map incluído no ZIP do firmware possibilitou a análise do firmware do SoC principal e o bypass da detecção de hotspot
  • WB850F_FW_210086.zip contém WB850-FW-SR-210086.bin, com 6 partições, e um dump do linker com mais de 300 mil linhas, permitindo confirmar que Main_Image era o firmware ARM real
  • Na análise com Ghidra, o ponto central foi encontrar o endereço base 0xc0004000 do Main_Image usando a diferença entre endereços de strings e importar como símbolos os nomes de funções da .text após convertê-los
  • A função de identificação de hotspot DevHTTPResponseStart determina se o AP está autenticado por um cookie de domínio Yahoo em HTTP 200 ou pela string yahoo. no início da URL de redirecionamento 301/302/307
  • Quando o Yahoo passou a redirecionar para HTTPS, a posição de yahoo. saiu do intervalo aceito pelo código; após o patch no samsung-nx-emailservice, o upload de fotos da WB850F passou a funcionar

Estrutura do ZIP de firmware da WB850F

  • A Samsung WB850F é um dos poucos modelos para os quais a Samsung ainda publica firmware e arquivos de suporte, mesmo após a descontinuação do aplicativo iLauncher
  • WB850F_FW_210086.zip contém os seguintes arquivos
    • GPS_FW/BASEBAND_FW_Flash.mbin
    • GPS_FW/BASEBAND_FW_Ram.mbin
    • GPS_FW/Config.BIN
    • GPS_FW/flashBurner.mbin
    • FWUP
    • partialImage.o.map
    • WB850-FW-SR-210086.bin
    • wb850f_adj.txt
  • FWUP contém apenas a string upgrade all, que parece ser um script para um módulo de teste/automação de firmware
  • wb850f_adj.txt é um script mais complexo que atualiza o firmware de GPS e remove arquivos relacionados
  • Os scripts relacionados a GPS e a pasta GPS_FW ficam fora do escopo desta análise

partialImage.o.map: um mapa em forma de dump do linker

  • partialImage.o.map é um arquivo de texto com mais de 300 mil linhas e contém a saída do linker para partialImage.o, além do mapa completo de memória do arquivo linkado
  • A seção .text contém nomes de funções como sysInit, archPwrDown, DevHTTPResponseStart, DevHTTPResponseData e DevHTTPResponseEnd
  • A seção .data inclui símbolos de dados como sysBus, sysCpu e sysBootLine
  • Esse arquivo é usado como um mapa de símbolos para associar o código do firmware aos nomes das funções

Cabeçalho e tabela de partições de WB850-FW-SR-210086.bin

  • Ao analisar WB850-FW-SR-210086.bin com binwalk, aparecem cabeçalhos HTML, PNG e JPEG, cabeçalhos VxWorks e vários caminhos Unix, mas nenhuma partição ou sistema de arquivos claro é revelado
  • Um dump hexadecimal do primeiro 1 KB mostra o firmware versão 210086 seguido de 0x00 0x06, e depois nomes de arquivos como FW_UP/ONBL1.bin
  • Cada registro parece ter uma estrutura de 60 bytes, composta por uma string de 32 bytes com padding de zeros, dois inteiros little-endian e um nome de partição de 20 bytes com padding de zeros
  • Os dois inteiros são interpretados, respectivamente, como tamanho e offset dentro do arquivo
  • Há 6 registros no total, então 0x00 0x06 é interpretado como o byte de término ou padding da string de versão do firmware e um contador de partições de 1 byte
  • Partições reconstruídas

    • FW_UP/ONBL1.bin
      • Tamanho: 196 bytes, offset: 0x0000800, nome da partição: ONBL1
    • FW_UP/ONBL2.bin
      • Tamanho: 46 KB, offset: 0x00008c4, nome da partição: ONBL2
    • [WB850]DSC_5KEY_WB850
      • Tamanho: 30 MB, offset: 0x000bef4, nome da partição: Main_Image
    • RomFS/SPID.Rom
      • Tamanho: 48 MB, offset: 0x1d2b32c, nome da partição: Resource
    • FW_UP/WB850.HEX
      • Tamanho: 19 KB, offset: 0x4c75f2c, nome da partição: OIS
    • FW_UP/skin.bin
      • Tamanho: 36 MB, offset: 0x4c7acb2, nome da partição: SKIN
    • Para extrair as partições, foi escrito e usado o extrator de partições de firmware DRIMeIII

Distinção entre partições de código e dados

  • A ferramenta de extração recupera os arquivos com base no nome da partição e acrescenta .bin
  • Apenas o resultado de file tem utilidade limitada, chegando a identificar erroneamente Main_Image.bin como uma chave secreta OpenPGP
  • ONBL1 e ONBL2 parecem ser os bootloaders de primeiro e segundo estágio, considerando a string "BootLoader(ONBL1, ONBL2) Update Done" dentro de Main_Image
  • Main_Image é o firmware real, e binwalk -A reporta nesse arquivo vários prólogos de função ARM
  • Resource e SKIN são contêineres grandes, possivelmente configurações fornecidas pelo fabricante do SoC relacionadas ao skin da UI da câmera
  • OIS, apesar do nome do arquivo, não é realmente um HEX e pode ser o firmware do dispositivo dedicado de estabilização óptica de imagem
  • O centro da análise é Main_Image

Mapeando Main_Image no Ghidra

  • As três partições ONBL1, ONBL2 e Main_Image contêm código ARM real
  • Firmwares ARM comuns têm uma tabela de vetores de reset no endereço 0x0000000, mas os três binários começam com código linear, então precisam ser remapeados para um endereço ainda desconhecido
  • Para analisar o falso reconhecimento de hotspot, foram necessárias as seguintes tarefas
    • Encontrar o endereço de memória correto para mapear Main_Image
    • Carregar no Ghidra os nomes de símbolos de partialImage.o.map
    • Analisar a função que dispara incorretamente a decisão de login em hotspot
  • Ao buscar "yahoo" na aba Defined Strings do Ghidra, apareceram itens que pareciam strings de debug de DevHTTPResponseStart()
    • DevHTTPResponseStart: url=%s, handle=%x, status=%d
    • DevHTTPResponseStart: This is YAHOO check !!!
    • DevHTTPResponseStart: THIS IS GOOGLE/YAHOO/SAMSUNG PAGE!!!! 111
    • 301/302/307! cannot find yahoo!
  • Em partialImage.o.map, DevHTTPResponseStart fica em 0x321a84, e o Ghidra também encontra a função no mesmo offset
  • A diferença entre o valor do ponteiro da string de debug e o offset real da string bate com 0xc0004000, levando à conclusão de que o endereço base de Main_Image é 0xc0004000
  • Como o Ghidra não permite alterar o endereço base depois, foi necessário remover o binário do projeto e importá-lo novamente configurando o endereço base

Importação de nomes de funções e análise de DevHTTPResponseStart

  • O ImportSymbolScript.py do Ghidra consegue importar símbolos em massa a partir de uma tabela de texto
  • O script espera que cada linha contenha o nome do símbolo, o endereço em hexadecimal e f para indicar função ou l para indicar label
  • Como em partialImage.o.map só eram necessárias as funções da seção .text atual, os seguintes itens precisaram ser excluídos
    • Linhas em branco
    • Offsets de arquivos de objeto
    • Labels de seção como .text
    • Labels com prefixo L$_
    • Símbolos locais com prefixo $
  • Aos endereços foi somado 0xc0004000 para alinhá-los ao endereço base no Ghidra
  • O resultado convertido foi gerado em um formato como sysInit c0004000 f e archPwrDown c0004094 f, e carregado pelo Script Manager do Ghidra
  • Depois que os nomes de funções foram inseridos, vários campos DAT_ foram marcados como ponteiros e os nomes dos parâmetros foram alterados com base nas strings de debug, tornando legível o resultado de decompilação de DevHTTPResponseStart

Condições de detecção de hotspot

  • DevHTTPResponseStart observa o status da resposta HTTP, a URL e os cabeçalhos para decidir se o AP Wi-Fi foi autenticado
  • Em uma resposta HTTP 200 OK, é necessário haver nos cabeçalhos da resposta um cookie de domínio Yahoo para que a autenticação seja tratada como bem-sucedida
    • Os alvos da verificação são domain=.yahoo, Domain=.yahoo, domain=kr.yahoo e Domain=kr.yahoo
    • Se a condição for satisfeita, p_request_ongoing é alterado para 0 e, se o navegador estiver em estado não autenticado, safnotify_auth_ap(0) é chamado
  • Em redirecionamentos HTTP 301/302/307, a string yahoo. é verificada dentro da URL
    • Se yahoo. não existir ou estiver depois de url + 11, o código trata isso como Yahoo não encontrado
    • Se o framebuffer do navegador não estiver ligado e a autenticação também não tiver sido feita, safnotify_auth_ap(1) é chamado
    • Se yahoo. estiver no começo, a autenticação é considerada bem-sucedida com safnotify_auth_ap(0)
  • Status negativos retornam false, como em uma requisição interrompida
  • Em status positivos que não sejam 200 nem redirecionamento, o resultado varia conforme o estado do framebuffer do navegador

Verificação do Yahoo quebrada após TLS e bypass

  • A URL consultada pela câmera é http://www.yahoo.co.kr/
  • Ao fazer uma requisição direta, o servidor redireciona com HTTP/1.1 301 Moved Permanently e Location: https://www.yahoo.com/
  • Em https://www.yahoo.com/, a substring yahoo. fica na posição 12
  • O código exige que yahoo. esteja em uma das 11 primeiras posições, então essa verificação quebrou após a migração para HTTPS
  • Para passar na verificação de hotspot, é preciso apontar o registro DNS para outro servidor, e esse servidor deve redirecionar via HTTP para um nome que se pareça mais com Yahoo ou definir um cookie de domínio Yahoo
  • Depois do patch no samsung-nx-emailservice, a câmera de fato se conecta e faz upload das fotos

Outras câmeras às quais o mesmo bypass foi aplicado

  • Esta análise conseguiu entender e contornar a detecção de hotspot da câmera Wi-Fi Samsung WB850F com base em uma única função submetida a engenharia reversa
  • O patch final era pequeno, mas a forma de detecção implementada pelos engenheiros da Samsung dificultava inferir o bypass apenas a partir do rastreamento de pacotes
  • Depois de saber o que procurar, o mesmo bypass foi aplicado também a câmeras que consultam MSN.com
  • Como resultado, EX2F, ST200F, WB3xF e WB1100F foram adicionadas à lista de câmeras compatíveis
  • Main_Image contém mais de 77 mil funções, então ainda restam muitos alvos de análise para entender melhor o funcionamento da câmera digital

1 comentários

 
GN⁺ 2024-05-26
Comentários do Hacker News
  • Gostei mais de https://op-co.de/blog/posts/samsung_nx_cryptofail/#index3h3
    É um caso realmente impressionante de falha na criptografia de firmware

  • Trabalho excelente. Fico curioso se há planos de transformar o método de engenharia reversa em um tutorial

    • Na verdade, eu esperava que este texto fornecesse informações suficientes para servir como tutorial
      Só deixei de fora as partes fáceis de encontrar no Google
  • Tudo o que eu quero é tirar fotos com uma dSLR usando o botão da câmera e, pouco depois, a imagem aparecer no Apple Photos

    • Antigamente havia cartões SD com Wi‑Fi embutido que sincronizavam fotos automaticamente, mas a Eye‑Fi, que era uma das principais empresas desse mercado, fechou, e parece que ninguém criou um produto novo que funcione com serviços de nuvem modernos
      Os smartphones praticamente acabaram com o mercado de câmeras de consumo, então parece faltar demanda. Como ideia de projeto, seria tentar encontrar uma forma de enfiar um ESP32 dentro de um cartão SD
    • Uma Canon dSLR com Wi‑Fi provavelmente consegue usar FTP
      Também dá para conectar a celulares, tablets e sites, mas é necessário um app ou serviço. Documento sobre envio por FTP diretamente da câmera: https://gdlp01.c-wss.com/gds/5/0300024975/01/eos5d-mk4-wff-i... página 113. O link é para o EOS 5D Mark IV (WG) Wi‑Fi (Wireless Communication) Function Instruction Manual
    • As Samsung NX1 e NX500 com Linux podem ser roteirizadas com bastante facilidade para enviar JPEG ou RAW a qualquer serviço online, desde que haja uma rede Wi‑Fi
      Infelizmente, são modelos de 10 anos atrás e raros até no mercado de usados
    • A série Nikon Z com SnapBridge é praticamente a melhor opção nesse sentido
      Ela pareia por Wi‑Fi ou Bluetooth e, se quiser, você pode controlar a câmera remotamente pelo iPad e também ver a tela
    • Como isso já é possível para o Google Photos, também deveria ser possível aqui: https://www.stg-uploader.xyz/