O Protobuf é um formato de serialização desenvolvido pelo Google e usado em um número crescente de Android, Web, desktop e mais aplicativos. Consiste em um idioma para declarar estruturas de dados , que são compiladas para codificar ou outro tipo de estrutura, dependendo da implementação de destino.
O PBTK ( Protobuf Toolkit ) é um conjunto completo de scripts, acessível através de uma GUI unificada, que fornece dois recursos principais:
Extraindo estruturas do Protobuf dos programas , convertendo -os de volta em .Proto s legíveis, apoiando várias implementações:
Dados de edição, reprodução e difusão enviados aos pontos de extremidade da rede Protobuf, através de uma interface gráfica útil que permite editar ao vivo os campos para uma mensagem do Protobuf e visualize o resultado.
O PBTK requer python ≥ 3,5, pyqt 5, python-protobuf 3 e um punhado de programas executáveis (Chromium, JAD, Dex2jar ...) para executar scripts de extrator.
Os usuários do Archlinux podem instalar diretamente através do pacote:
$ yay -S pbtk-git
$ pbtk
Na maioria das outras distribuições, você deseja executá -lo diretamente:
# For Ubuntu/Debian testing derivates:
$ sudo apt install python3-pip git openjdk-9-jre libqt5x11extras5 python3-pyqt5.qtwebengine python3-pyqt5
$ sudo pip3 install protobuf pyqt5 pyqtwebengine requests websocket-client
$ git clone https://github.com/marin-m/pbtk
$ cd pbtk
$ ./gui.pyO Windows também é suportado (com os mesmos módulos necessários). Depois de executar a GUI, ele deve avisá -lo sobre o que você está perdendo, dependendo do que você tenta fazer.
A GUI pode ser presa através do script principal:
./gui.py
Os scripts a seguir também podem ser usados independentes, sem uma GUI:
./extractors/jar_extract.py [-h] input_file [output_dir]
./extractors/from_binary.py [-h] input_file [output_dir]
./extractors/web_extract.py [-h] input_url [output_dir]
Digamos que você esteja engenharia reversa de um aplicativo Android. Você explorou um pouco o aplicativo com seu decompilador favorito e imaginou que ele transporta o Protobuf como dados postais sobre HTTPs de maneira típica.
Você abre o PBTK e é recebido de maneira significativa:
O primeiro passo é colocar seu .proto no formato de texto. Se você estiver segmentando um aplicativo Android, cair em um apk e esperar deve fazer o trabalho mágico! (a menos que seja uma implementação realmente exótica)
Isso está sendo feito, você pula para ~/.pbtk/protos/<your APK name> (seja através da linha de comando ou o botão na parte inferior da tela de boas -vindas para abrir o navegador do arquivo, da maneira que você preferir). Todos os .Protos do aplicativo estão de fato aqui.
De volta ao seu decompilador, você tropeçou na classe que constrói dados enviados ao ponto final do HTTPS que lhe interessa. Ele serializa a mensagem Protobuf chamando uma classe feita de código gerado.
Esta última aula deve ter uma combinação perfeita dentro do seu diretório .Protos (ou seja, com.foo.bar.ab corresponderá com/foo/bar/a/b.proto ). De qualquer maneira, Grepping seu nome deve permitir que você o faça referência.
Isso é ótimo: a próxima coisa será a etapa 2 , selecionando a entrada desejada .Proto e preenchendo algumas informações sobre o seu terminal.
Você também pode fornecer a alguns dados de protobuf bruto de amostra, que foram enviados para esse ponto de extremidade, capturados através do mitmproxy ou Wireshark, e que você colará em um formulário codificado por hexadecipal.
A etapa 3 é sobre a parte divertida de clicar em botões e ver o que acontece! Você tem uma visão de árvore representando todos os campos da estrutura do protobuf (os campos repetidos são sufixados por "+", os campos necessários não têm caixas de seleção).
Basta passar um campo para ter foco. Se o campo for do tipo inteiro, use a roda do mouse para incrementar/diminuir. As informações da enumeração também aparecem no Hover.
Aqui está! Você pode determinar o significado de todos os campos com isso. Se você extraiu .Protos para fora do código minificado, poderá renomear os campos de acordo com o que você percebe que eles significam clicando em seus nomes.
Feliz reversão! ? ?
Armazenamentos PBTK extrairam informações .proto em ~/.pbtk/protos/ (ou %APPDATA%pbtkprotos no Windows).
Você pode entrar, sair, renomear, editar ou apagar os dados deste diretório diretamente através do navegador de arquivos e editor de texto regular, é a maneira esperada de fazê -lo e não interferirá no PBTK.
Os pontos de extremidade baseados em HTTP são armazenados em objetos ~/.pbtk/endpoints/ AS JSON. Esses objetos são matrizes de pares de informações de solicitação/resposta, que se parecem com a seguinte:
[ {
"request" : {
"transport" : "pburl" ,
"proto" : "www.google.com/VectorTown.proto" ,
"url" : "https://www.google.com/VectorTown" ,
"pb_param" : "pb" ,
"samples" : [ {
"pb" : "!...." ,
"hl" : "fr"
} ]
} ,
"response" : {
"format" : "other"
}
} ] O PBTK usa dois tipos de módulos tragáveis internamente: extratores e transportes.
Os extratores são definidos em extractors/*.py . Eles são definidos como um método precedido por um decorador, como este:
@ register_extractor ( name = 'my_extractor' ,
desc = 'Extract Protobuf structures from Foobar code (*.foo, *.bar)' ,
depends = { 'binaries' : [ 'foobar-decompiler' ]})
def my_extractor ( path ):
# Load contents of the `path` input file and do your stuff...
# Then, yield extracted .protos using a generator:
for i in do_your_extraction_work ():
yield proto_name + '.proto' , proto_contents
# Other kinds of information can be yield, such as endpoint information or progress to display. Os transportes são definidos em utils/transports.py . Eles são definidos como uma classe precedida por um decorador, como este:
@ register_transport (
name = 'my_transport' ,
desc = 'Protobuf as raw POST data' ,
ui_data_form = 'hex strings'
)
class MyTransport ():
def __init__ ( self , pb_param , url ):
self . url = url
def serialize_sample ( self , sample ):
# We got a sample of input data from the user.
# Verify that it is valid in the form described through "ui_data_form" parameter, fail with an exception or return False otherwise.
# Optionally modify this data prior to returning it.
bytes . fromhex ( sample )
return sample
def load_sample ( self , sample , pb_msg ):
# Parse input data into the provided Protobuf object.
pb_msg . ParseFromString ( bytes . fromhex ( sample ))
def perform_request ( self , pb_data , tab_data ):
# Perform a request using the provided URL and Protobuf object, and optionally other transport-specific side data.
return post ( url , pb_data . SerializeToString (), headers = USER_AGENT )O seguinte pode estar chegando para lançamentos adicionais:
Eu tentei fazer o meu melhor para produzir código completamente legível e comentado (exceto peças que são principalmente auto-descritas, como a conexão de sinais da GUI) para a maioria dos módulos, para que você possa contribuir.
Como o PBTK usa o PYQT, ele é lançado sob a licença GNU GPL (i, por meio deste, etc.), eu provavelmente teria escolhido algo como um domínio público.
Não existe regra formalizada para o caso da letra do nome do projeto, a regra é apenas seguir seu coração ❤