ProtoBuf es un formato de serialización desarrollado por Google y utilizado en un número creciente de Android, Web, Desktop y más aplicaciones. Consiste en un lenguaje para declarar estructuras de datos , que luego se compila en código u otro tipo de estructura dependiendo de la implementación de objetivos.
PBTK ( ProtoBuf Toolkit ) es un conjunto completo de scripts, accesibles a través de una GUI unificada, que proporciona dos características principales:
Extracción de estructuras de protoBuf de los programas , convirtiéndolas nuevamente en .proto s legibles, admitiendo varias implementaciones:
La edición, la reproducción y los datos confusos enviados a los puntos finales de la red ProtoBuf, a través de una práctica interfaz gráfica que le permite editar en vivo los campos para un mensaje ProtoBuf y ver el resultado.
PBTK requiere Python ≥ 3.5, Pyqt 5, Python-Protobuf 3 y un puñado de programas ejecutables (Chromium, Jad, Dex2Jar ...) para ejecutar scripts extractores.
Los usuarios de Archlinux pueden instalar directamente a través del paquete:
$ yay -S pbtk-git
$ pbtk
En la mayoría de las otras distribuciones, querrá ejecutarlo directamente:
# 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.pyWindows también es compatible (con los mismos módulos requeridos). Una vez que ejecute la GUI, debe advertirle sobre lo que se está perdiendo dependiendo de lo que intente hacer.
La GUI se puede lanchar a través del guión principal:
./gui.py
Los siguientes scripts también se pueden usar independientemente, sin una 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]
Supongamos que está Ingeniería inversa de una aplicación Android. Exploró un poco la aplicación con su descompilador favorito y pensó que transporta a ProtoBuf como datos posteriores a los HTTP de una manera típica.
Abres PBTK y te reciben de manera significativa:
El primer paso es meter sus .protas en formato de texto. Si está apuntando a una aplicación de Android, caer en un APK y esperar debería hacer el trabajo mágico. (a menos que sea una implementación realmente exótica)
Al hacer esto, salta a ~/.pbtk/protos/<your APK name> (ya sea a través de la línea de comando o el botón en la parte inferior de la pantalla de bienvenida para abrir su navegador de archivos, la forma en que prefiere). Todas las aplicaciones. Protos están aquí.
De vuelta en su descompilador, se topó con la clase que construye datos enviados al punto final HTTPS que le interesa. Serializa el mensaje ProtoBuf llamando a una clase hecha de código generado.
Esta última clase debe tener una combinación perfecta dentro de su directorio .protas (es decir, com.foo.bar.ab coincidirá com/foo/bar/a/b.proto ). De cualquier manera, Gepping su nombre debería permitirle hacer referencia a él.
Eso es genial: lo siguiente es el paso 2 , seleccionar su entrada deseada .proto y llenar información sobre su punto final.
También puede proporcionar algunos datos de protobuf sin procesar, que se enviaron a este punto final, capturado a través de MITMProxy o Wireshark, y que pegará en una forma codificada con hex.
¡ El paso 3 se trata de la parte divertida de hacer clic en los botones y ver lo que sucede! Tiene una vista de árbol que representa cada campo en la estructura de ProtoBuf (los campos repetidos están sufrojados por "+", los campos requeridos no tienen casillas de verificación).
Simplemente pasee un campo para enfocarse. Si el campo es un tipo entero, use la rueda del mouse para incrementarlo. La información de Enum también aparece en Hover.
¡Aquí lo tienes! Puede determinar el significado de cada campo con eso. Si extrajo .protas fuera del código minificado, puede cambiar el nombre de los campos de acuerdo con lo que nota, se refiere, haciendo clic en sus nombres.
¡Feliz inversión! ? ?
%APPDATA%pbtkprotos tiendas PBTK extraen ~/.pbtk/protos/
Puede moverse, moverse, cambiar el nombre, editar o borrar datos de este directorio directamente a través de su navegador de archivos regular y editor de texto, es la forma esperada de hacerlo y no interferirá con PBTK.
Los puntos finales basados en HTTP se almacenan en ~/.pbtk/endpoints/ AS JSON Objects. Estos objetos son conjuntos de pares de información de solicitud/respuesta, que se ve así:
[ {
"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"
}
} ] PBTK utiliza dos tipos de módulos conectables internamente: extractores y transportes.
Los extractores se definen en extractors/*.py . Se definen como un método precedido por un 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. Los transportes se definen en utils/transports.py . Se definen como una clase precedida por un 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 )Lo siguiente podría venir para versiones adicionales:
He tratado de hacer todo lo posible para producir un código completamente legible y comentado (a excepción de las piezas que se autodescriben en su mayoría, como conectar señales de GUI) para la mayoría de los módulos, para que pueda contribuir.
Como PBTK usa PYQT, se lanza bajo la licencia GNU GPL (I, por este, etc.), probablemente habría elegido algo de lo contrario.
No hay una regla formal para el caso de la carta del nombre del proyecto, la regla se trata solo de seguir su corazón ❤