
Fuzzer orientado por cobertura em processo para o daemon Bluetooth do iOS (bluetoothd) usando FRIDA, com fuzzing over-the-air para o protocolo MagicPairing e capacidades de reprodução de travamentos.

O ToothPicker é um fuzzer em processo guiado por cobertura para iOS. Foi desenvolvido para visar especificamente o daemon Bluetooth do iOS bluetoothd e para analisar vários protocolos Bluetooth no iOS. Como é construído usando FRIDA, pode ser adaptado para atingir qualquer plataforma que execute o FRIDA.
Este repositório também inclui um fuzzer over-the-air com uma implementação exemplar para fuzzear o protocolo MagicPairing da Apple usando InternalBlue. Além disso, contém o script ReplayCrashFile.py que pode ser usado para verificar crashes que o fuzzer em processo encontrou.
Este é um fuzzer muito simples que apenas inverte bits e bytes em conexões ativas. Sem orientação de cobertura, sem injeção, mas legal como demonstração e stateful. Funciona apenas com Python+Frida, nenhum módulo ou instalação necessária. Testado no iOS 13.5-14.3. Veja inplace-fuzzer.
O Fuzzer Em Processo funciona imediatamente em várias versões do iOS (13.3-13.7 testadas), mas símbolos precisam ser especificados. Outras versões do iOS exigem adaptações nos endereços das funções. Além disso, parece que o stalker do FRIDA tem alguns problemas com o iPhone 8. Em iPhones mais novos que suportam PAC, o desempenho sofre significativamente com a assinatura de ponteiros. Portanto, recomenda-se executar isso em um iPhone 7.
ToothPicker é construído na base de código do frizzer. No entanto, foi adaptado para esta aplicação específica, portanto não é mais compatível com a versão original. Existem planos para substituir isso por um componente mais dedicado no futuro.
No iPhone:
No Linux:
Para Linux baseado em Arch:
# usbmuxd typically comes with libimobiledevice
# but just to be sure, we manually install it as well
sudo pacman -S usbmuxd libimobiledevice python-virtualenv radamsa
# Connect the iPhone to the computer
# Unlock it.
# If a pairing message pops up, click "Trust"
# If no pairing message pops up:
idevicepair pair
# Now there should be the pop up, accept and then again:
idevicepair pair
# In case of connection errors:
sudo systemctl restart usbmuxd
# or pair phone and computer again
# Other useful commands
# To ssh into the iPhone:
# Checkra1n comes with an SSH server listening on Port 44
# Proxy the phone's SSH port to 4444 localport:
iproxy 4444 44
# Connect:
ssh root@localhost -p 4444
# Default password: alpine
# To fetch some device information of the phone:
ideviceinfo
Para Debian Linux:
Quase o mesmo que acima. Exceções:
radamsa precisa ser instalado a partir do repositório git porque não está empacotado.iproxy requer o pacote adicional libusbmuxd-tools.Para macOS:
Comandos ligeiramente diferentes em comparação com a configuração do Arch Linux...
brew install libimobiledevice usbmuxd radamsa npm
idevicepair pair
npm install frida-compile
pip3 install frida-tools
No macOS, o PacketLogger, que faz parte das Ferramentas Adicionais para Xcode, pode decodificar vários pacotes uma vez que o Perfil de Depuração Bluetooth esteja instalado. Além disso, se você abrir logs de crash do iOS com o Xcode, ele adicionará alguns símbolos.
Configuração:
frizzer.frizzer.projects contém um projeto exemplo para fuzzear o protocolo MagicPairing.MagicPairing em um único arquivo.harness com cd e instale o frida-compile. Note que isso precisa ser executado nessa pasta e pode ser instalado diretamente como usuário executando npm install frida-compile.frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.js. Como isso foi instalado no contexto npm, pode ser necessário executar npx frida-compile em vez disso. Cada vez que o harness mudar, você precisa reexecutar .Fuzzing:
killall -9 bluetoothd para iniciar bluetoothd novamente.cd, crie o diretório de crashlog (mkdir crashes) e execute ../../frizzer/fuzzer.py fuzz -p .Resumindo, para iniciar um novo projeto, execute:
cd harness
npx frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.js
cd ../projects/YOUR_PROJECT/
mkdir crashes
../../frizzer/fuzzer.py fuzz -p .
Você pode começar com uma semente diferente usando frizzer/fuzzer.py fuzz --seed 1234 -p ..
Adicionando novas versões do iOS:
Atualmente, diferentes versões do iOS são definidas em bluetoothd.js. Você pode encontrá-las com a ferramenta de versionamento Ghidra, dada uma versão inicial que tenha todos os símbolos necessários. Note que alguns deles não são nomeados no binário iOS original, então idealmente comece com um que já tenha sido anotado anteriormente. Cada vez que o bluetoothd.js mudar, você precisa reexecutar frida-compile.
Aumentando as capacidades do bluetoothd:
Os logs de crash do iOS são armazenados em Settings -> Privacy -> Analytics & Improvements -> Analytics Data. Se eles contiverem crashes do bluetoothd no padrão bluetoothd.cpu_resource-*.ips, isso indica que o crash foi causado por exceder recursos. Eles podem ser aumentados da seguinte forma.
Em um iPhone 7, execute:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D10.plist -o com.apple.jetsamproperties.D10.plist.txt
plistutil -i com.apple.jetsamproperties.D101.plist -o com.apple.jetsamproperties.D101.plist.txt
No iPhone SE2, estes estão em com.apple.jetsamproperties.D79.plist.:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D79.plist -o com.apple.jetsamproperties.D79.plist.txt
Pesquise por bluetoothd, atualize a prioridade para 19 (a maior prioridade válida) e defina o limite de memória para algo muito alto. Aplique as mesmas alterações a ambos os arquivos.
<dict>
<key>ActiveSoftMemoryLimit</key>
<integer>24000</integer>
<key>InactiveHardMemoryLimit</key>
<integer>24000</integer>
<key>EnablePressuredExit</key>
<false/>
<key>JetsamPriority</key>
<integer>19</integer>
</dict>
Escreva as alterações de volta e reinicie o bluetoothd.
plistutil -i com.apple.jetsamproperties.D10.plist.txt -o com.apple.jetsamproperties.D10.plist
plistutil -i com.apple.jetsamproperties.D101.plist.txt -o com.apple.jetsamproperties.D101.plist
killall -9 bluetoothd
Respectivamente no iPhone SE2:
plistutil -i com.apple.jetsamproperties.D79.plist.txt -o com.apple.jetsamproperties.D79.plist
killall -9 bluetoothd
Excluindo logs antigos:
O iOS para de salvar logs de crash para um programa depois que o limite de 25 é atingido. Se carregar um log de crash com o Xcode (via Simulators&Devices), alguns símbolos são adicionados ao stack trace. Uma vez que o limite é atingido, os logs podem ser removidos via Xcode ou diretamente no dispositivo iOS, excluindo-os na pasta /var/mobile/Library/Logs/CrashReporter/.
A12+:
A partir do iPhone XR/Xs, o PAC foi introduzido. Isso requer chamar sign() em NativeFunction no FRIDA. Embora isso seja um no-op em CPUs mais antigos, reduz tremendamente a velocidade em dispositivos mais novos, mas é necessário para fazê-los funcionar. Observamos que o ToothPicker opera com metade da velocidade ao usar um iPhone SE2 em vez de um iPhone 7.
A implementação MagicPairing do fuzzer over-the-air requer a instalação do InternalBlue e pode ser executada rodando python MagicPairingFuzzer.py TARGET_BD_ADDR.
Se você quiser reproduzir crashes, use o script ReplayCrashFile.py, que pode receber um arquivo de crash e inicia uma conexão over-the-air com um payload baseado no crash.
frida-compile