
um framework Ghidra para engenharia reversa do kernelcache do iOS
Este framework é o produto final da minha experiência em engenharia reversa de Kernelcache. Normalmente procuro por vulnerabilidades auditando manualmente o kernel e suas extensões e automatizei a maioria das coisas que realmente queria ver no Ghidra para acelerar o processo de reversão, o que se mostrou eficaz e economiza muito tempo. O framework funciona em iOS 12/13/14/15 e em macOS 11/12 (tanto kernelcache quanto KEXT único) e foi disponibilizado ao público com a intenção de ajudar pessoas a começar a pesquisar sobre o kernel iOS sem a dificuldade de preparar seu próprio ambiente. Como acredito, este framework (incluindo o conjunto de ferramentas que fornece e com algum conhecimento básico de IOKit) é suficiente para começar a hackear o Kernelcache.
O framework é inteiramente escrito em Python e pode ser estendido para construir outras ferramentas. Ele fornece algumas APIs básicas que você pode usar em quase qualquer projeto e economizar tempo de leitura do manual verboso. Sinta-se à vontade para ler as funcionalidades principais no diretório utils/.
Ghidra é bom quando se trata de analisar Kernelcaches, mas como outras ferramentas de RE, requer algum trabalho manual. ghidra_kernelcache fornece um bom ponto de entrada para corrigir coisas no início e até mesmo durante a engenharia reversa, proporcionando assim uma saída do descompilador com boa aparência.
Existe um projeto semelhante feito por @_bazad no IDAPro chamado ida_kernelcache que fornece um bom ponto de entrada para pesquisadores que desejam trabalhar com a imagem do kernel no IDA. Meu framework se parece um pouco com o trabalho de Brandon e vai além, fornecendo muito mais recursos para tornar o processo de trabalho com o kernelcache menos doloroso.
::externalMethod() e ::getTargetAndMethodForIndex().Esses recursos são feitos como ferramentas separadas que podem ser executadas por atalhos de teclado ou clicando em seus ícones na barra de ferramentas.
Clone o repositório:```sh git clone https://github.com/0x36/ghidra_kernelcache.git
**Nota importante**: O projeto foi testado no Ghidra 10.1_PUBLIC e 10.2_DEV e não é compatível com versões anteriores.
Vá para *`Windows → Script Manager`,* clique em *`script Directory`,* depois adicione *`ghidra_kernelcache`* à lista de diretórios.
Vá para *`Windows → Script Manager`,* na listagem de *scripts*, vá para a categoria *`iOS→kernel`* e marque os plug-ins vistos lá, eles aparecerão na Barra de Ferramentas do GHIDRA.
No diretório [logos/](https://github.com/0x36/ghidra_kernelcache/tree/master/logos), você pode colocar seus próprios logos para cada ferramenta.
## Simbolização do kernelcache do iOS
`ghidra_kernelcache` requer, na primeira etapa, [iometa](https://github.com/Siguza/iometa/) (feito por [@s1guza](https://twitter.com/s1guza)), uma ferramenta poderosa que fornece informações de classes C++ no binário do kernel. O ótimo é que funciona como um binário independente, então a saída pode ser importada para seu framework de RE favorito apenas analisando-a. Meu framework pega a saída do iometa e a analisa para simbolizar e corrigir tabelas virtuais.
### Uso
Após descomprimir o kernel, execute os seguintes comandos:```sh
$ iometa -n -A /tmp/kernel A10-legacy.txt > /tmp/kernel.txt
# if you want also to symbolicate using jtool2
$ jtool2 --analyze /tmp/kernel
Carregue o kernelcache no Ghidra, NÃO USE importação em lote, carregue-o como imagem Mach-O.
Após o Kernelcache ser carregado e auto-analisado, clique no ícone mostrado na barra de ferramentas ou pressione Meta-Shift-K, depois coloque o caminho completo da saída do iometa que é /tmp/kernel.txt no nosso caso.
Se quiser usar símbolos do jtool2, pode usar o jsymbol.py localizado na categoria iOS→kernel também.
Exemplos completos da API estão em ghidra_kernelcache/kc.py
→ Aqui estão alguns exemplos de manipulação de objetos de classe:```py from utils.helpers import * from utils.class import * from utils.iometa import ParseIOMeta
ff = "/Users/mg/ghidra_ios/kernel.txt" iom = ParseIOMeta(ff) Obj = iom.getObjects() kc = kernelCache(Obj)
kc.process_all_classes()
kc.process_classes_for_bundle("com.apple.iokit.IOSurface")
kc.process_classes_for_bundle("kernel")
kc.process_class("IOGraphicsAccelerator2")
kc.clear_class_structures()
kc.update_classes_vtable()
kc.explore_pac()
Como pode ver, pode simbolizar total ou parcialmente o kernelcache; se a simbolização parcial for escolhida, o `ghidra_kernelcache` construirá automaticamente todas as dependências de classe antes de prosseguir.
Se executar o script contra todo o kernelcache (simbolização completa), o `ghidra_kernelcache` levará vários minutos para analisar a imagem do kernel.
Uma vez terminado, o Ghidra fornecerá o seguinte:
→ Uma nova categoria foi adicionada no Filtro de Marcadores chamada "iOS":
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image1.png" alt="image1" width="200"/>
→ Tabelas virtuais de classes IOKit são adicionadas ao Marcador 'iOS' para uma consulta melhor e mais rápida da tabela virtual; pode procurar por uma kext ou classe fornecendo letras, palavras ou o bundle da kext na barra de busca.
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image2.png" alt="image2"/>
→ Corrigindo a tabela virtual: desmonta/compila código desconhecido, corrige namespaces, re-simboliza os métodos da classe e aplica definição de função a cada método:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image3.png" alt="image3"/>
→ Criação de namespaces de classe e coloca cada método no seu próprio namespace correspondente:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image4.png" alt="image4"/>
→ Criando estrutura de classe com respeito à hierarquia de classes:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image5.png" alt="image5"/>
→ Criando vtables de classe, e cada método tem sua própria definição de método para uma melhor saída de descompilação:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image6.png" alt="image6"/>
A implementação completa pode ser encontrada em [`utils/class.py.`](https://github.com/0x36/ghidra_kernelcache/blob/master/utils/class.py)
Aqui estão algumas capturas de tela de antes/depois da simbolização usando `ghidra_kernelcache`:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image7.png" alt="image7"/>