
Pesquisa de engenharia reversa e firmware personalizado para câmeras IoT baseadas em Allwinner V3, incluindo analisadores de firmware, um cliente AVIOCTRL e uma prova de conceito CVE-2026-52656 para substituição de firmware OTA não autenticada.

Notas de engenharia reversa, ferramentas para firmware, código de prova de conceito e uma interface de firmware customizada para a versão Allwinner V3 da SJCAM SJ4000 Air.
Artigo da pesquisa
Este repositório contém o código e os artefatos produzidos durante a pesquisa. O artigo completo explica a investigação desde o primeiro dump do firmware até o firmware customizado Lelouch.
Este trabalho começou com uma pergunta simples: quanto controle eu conseguiria obter sobre uma action camera barata sem documentação, código-fonte ou suporte do fabricante?
Descobri que a câmera utiliza um SoC Allwinner V3 e um sistema Android 4.4 fortemente modificado. Sua aplicação principal, sdv, comunica-se com serviços proprietários de câmera e display por meio do Binder, renderiza a interface com MiniGUI, expõe um servidor HTTP para atualizações de firmware e comunica-se com o aplicativo SJCAM Zone por meio de um protocolo proprietário.
O repositório documenta o caminho desde a extração do firmware até uma substituição funcional para o sdv. Ele inclui ferramentas para os formatos de firmware encontrados durante a pesquisa, bancos de dados do IDA para os binários revertidos, um cliente AVIOCTRL, o código-fonte do firmware customizado Lelouch e a prova de conceito associada à CVE-2026-52656.
O código tem como alvo a placa Allwinner V3 pesquisada, com controlador de display ST7789V e sensor de imagem GC4653. Unidades SJ4000 mais antigas, baseadas no Novatek NT9665X, estão incluídas somente como parte da pesquisa anterior e utilizam um formato de firmware diferente. Apenas o nome do produto não é suficiente para determinar a compatibilidade.
Lelouch é uma interface substituta para o executável sdv original da câmera. Ele é compilado com as bibliotecas proprietárias recuperadas do firmware e utiliza as mesmas interfaces internas da aplicação original.
A implementação atual inclui:
HerbCamera e CedarDisplaywpa_supplicantLelouch não é uma distribuição completa nem um firmware genérico para todos os produtos vendidos como SJ4000. Ele depende das bibliotecas, kernel, serviços, layout de partições, controlador de display, sensor de imagem e configuração de placa utilizados na unidade Allwinner V3 pesquisada.
Alguns diretórios contêm material proprietário ou de terceiros recuperado do dispositivo. Sua presença destina-se à interoperabilidade e pesquisa de segurança e não torna esses componentes código aberto.
A compilação foi testada em Linux x86-64. Você precisa do Python 3, GNU Make, Git, um ambiente de compilação C/C++ e acesso à rede para o download inicial do toolchain.
git clone https://github.com/keowu/sjcam.git
cd sjcam/Lelouch
python3 prepare_build.py
O prepare_build.py baixa um sysroot fixado no Android API level 14 e o cross-compiler ARM arm-linux-androideabi-4.6 para Lelouch/android_compilers/. Em seguida, ele compila o wpa_supplicant estático modificado e executa o make. Os arquivos de compilador baixados e os binários gerados são ignorados pelo Git.
Os arquivos resultantes são:
Lelouch/Lelouch
Lelouch/wpa_supplicant
Para recompilar após alterar os códigos-fonte C++:
cd Lelouch
make clean
make
O binário Lelouch gerado deve substituir /bin/sdv no sistema de arquivos raiz extraído. O modo estação Wi-Fi também espera encontrar o wpa_supplicant compilado em /mnt/extsd/sta/wpa_supplicant no cartão SD da câmera.
O código experimental de detecção facial procura pelo arquivo cascade gerado em:
/mnt/extsd/frontalface.casc
O repositório inclui um cascade pré-gerado e o conversor utilizado para criá-lo:
cd Lelouch/gen_cascade
python3 gen_cascade.py haarcascade_frontalface_alt2.xml frontalface.casc
O procedimento completo de extração, substituição do sistema de arquivos raiz, reempacotamento e flash com LiveSuit está documentado no artigo da pesquisa vinculado no início desta página.
Todos os pontos de entrada dos parsers são scripts Python 3 com saída de ajuda integrada por meio de --help e não possuem dependências Python de terceiros.
Lê a imagem externa de firmware do LiveSuit, extrai seus arquivos e reconstrói uma imagem a partir de um diretório extraído.
python3 "Reversing Scripts/AllWinner IMAGEWTY - ROM Parser/main.py" info firmware.img
python3 "Reversing Scripts/AllWinner IMAGEWTY - ROM Parser/main.py" extract firmware.img -o image_dump
python3 "Reversing Scripts/AllWinner IMAGEWTY - ROM Parser/main.py" repack image_dump rebuilt.img
Inspeciona, extrai e reempacota o container full_img.fex encontrado dentro da imagem IMAGEWTY.
python3 "Reversing Scripts/AllWinner EGON - Firmware Parser/main.py" info full_img.fex
python3 "Reversing Scripts/AllWinner EGON - Firmware Parser/main.py" extract full_img.fex -o egon_dump
python3 "Reversing Scripts/AllWinner EGON - Firmware Parser/main.py" pack egon_dump \
--original full_img.fex \
-o rebuilt_full_img.fex
O packer utiliza o arquivo original como modelo para preservar o layout e os metadados originais enquanto as partições são substituídas.
Descompacta o container BCL1 utilizado por firmwares de modelos SJ4000 mais antigos baseados no Novatek e pode procurar no resultado por assets e seções de firmware incorporados.
python3 "Reversing Scripts/Novatek もな BCL1 - Firmware Parser/main.py" \
"Firmwares Files/OLD_SJCAM_Novatek_NT9665X/SJCAM001.bin" \
-o firmCode.bin \
--extract
O ウタ.py implementa o protocolo TCP proprietário utilizado pelo aplicativo móvel para controlar a câmera pela porta 6666. Ele implementa a sequência de login da câmera, mensagens de keepalive, frames IOCTRL, transferência de arquivos e solicitações do stream de vídeo utilizando somente a biblioteca padrão do Python.
Conecte seu computador à rede Wi-Fi da câmera e execute:
python3 "AVIOCTRL Script/ウタ.py"
O destino padrão é 192.168.100.1:6666. Um endereço diferente pode ser fornecido quando necessário:
python3 "AVIOCTRL Script/ウタ.py" --host 192.168.100.1 --port 6666 --debug
O cliente interativo pode ler a bateria e as configurações, inspecionar o cartão SD, tirar fotos, iniciar ou interromper gravações, listar, enviar, baixar ou excluir arquivos, solicitar thumbnails, configurar o Wi-Fi, solicitar o stream de vídeo e enviar comandos IOCTRL manualmente.
Formatar o cartão SD, excluir arquivos, alterar as configurações de Wi-Fi e executar uma restauração de fábrica modificam a câmera. Utilize esses comandos somente em hardware e dados que pertençam a você.
O firmware pesquisado expõe um endpoint HTTP sem autenticação enquanto o hotspot da câmera está ativo. Ele aceita uploads arbitrários de arquivos e os grava diretamente no cartão SD sem validar o cliente ou o conteúdo enviado. Isso permite a substituição completa do firmware, pois um atacante pode enviar uma imagem eGON customizada chamada full_img.fex; a câmera reconhece esse nome de arquivo como um pacote OTA e instala o firmware controlado pelo atacante por meio de seu fluxo normal de atualização, como se fosse uma atualização oficial.
A exploração bem-sucedida concede ao firmware enviado controle total sobre o software em execução no dispositivo. A prova de conceito incluída demonstra isso substituindo a aplicação original por um payload customizado que utiliza MiniGUI e AudioTrack para reproduzir o vídeo Bad Apple!! com frames RGB565 e áudio PCM brutos após a instalação da imagem OTA maliciosa.
O diretório POC/ contém:
run_exploit.sh, que envia o full_img.fex controlado pelo atacante para a câmerafull_img.fex, a imagem de firmware eGON modificada aceita pelo mecanismo de atualização OTA da câmeraバイバイ/, o payload MiniGUI e AudioTrack do Bad Apple!! utilizado para demonstrar execução arbitrária de código após a atualizaçãoextract_rgb_pcm_from_mp4/, um auxiliar para converter o vídeo de demonstração em dados RGB565 e PCM brutosO auxiliar de conversão de mídia requer o ffmpeg. O payload de demonstração espera encontrar os arquivos video.rgb e audio.pcm gerados na raiz do cartão SD da câmera.
A prova de conceito é destrutiva por natureza. Uma imagem malformada ou incompatível pode inutilizar permanentemente a câmera. Não a execute contra dispositivos que não pertençam a você ou sem um procedimento completo de recuperação.
O projeto foi criado para engenharia reversa, interoperabilidade, educação e pesquisa de segurança em hardware adquirido legalmente pelo autor. SJCAM, Allwinner, Novatek, Android e os nomes de seus componentes pertencem aos seus respectivos proprietários.
O repositório contém código-fonte original junto com amostras de firmware, bancos de dados de engenharia reversa, headers e bibliotecas compartilhadas originários de produtos de terceiros. Nenhuma licença é concedida para o material de terceiros. Verifique a procedência e a legislação aplicável antes de redistribuir ou utilizar esses arquivos fora de um ambiente de pesquisa.
Atualmente, não existe uma licença de código aberto aplicável a todo o repositório. O código-fonte do wpa_supplicant mantém sua própria licença upstream em Lelouch/modified_lelouch_wpa_supplicant_source/COPYING.
| Caminho | Conteúdo |
|---|
Lelouch/ | Interface do firmware customizado, ambiente de compilação, headers recuperados, bibliotecas compartilhadas proprietárias e código-fonte modificado do wpa_supplicant |
Reversing Scripts/ | Parsers e repackers para firmwares Allwinner IMAGEWTY, Allwinner eGON e Novatek BCL1 |
AVIOCTRL Script/ウタ.py | Cliente interativo para o protocolo TCP proprietário utilizado pelo SJCAM Zone |
Bin Files/ | Bancos de dados do IDA para os principais executáveis e bibliotecas compartilhadas analisados durante a pesquisa |
Firmwares Files/ | Amostras de firmware Allwinner e Novatek utilizadas durante o desenvolvimento |
POC/ | Prova de conceito da CVE-2026-52656, imagem eGON modificada e payload de demonstração para framebuffer e áudio |