Protobuf ist ein von Google entwickeltes Serialisierungsformat , das in einer zunehmenden Anzahl von Android-, Web-, Desktop- und weiteren Anwendungen verwendet wird. Es besteht aus einer Sprache zur Deklarierung von Datenstrukturen , die dann in Abhängigkeit von der Zielimplementierung mit Code oder einer anderen Art von Struktur zusammengestellt wird.
PBTK ( Protobuf Toolkit ) ist ein vollwertiger Satz von Skripten, der über eine einheitliche GUI zugänglich ist und zwei Hauptmerkmale bietet:
Extrahieren von Protobufstrukturen aus Programmen , wobei sie wieder in lesbare .
Bearbeiten, Wiederholung und Fuzzing -Daten, die an Protobuf -Netzwerkendpunkte gesendet wurden, über eine praktische grafische Schnittstelle, mit der Sie die Felder für eine Protobuf -Nachricht live bearbeiten und das Ergebnis anzeigen können.
PBTK erfordert Python ≥ 3,5, Pyqt 5, Python-Protobuf 3 und eine Handvoll ausführbarer Programme (Chromium, JAD, Dex2jar ...) zum Ausführen von Extraktorskripten.
Archlinux -Benutzer können direkt über das Paket installieren:
$ yay -S pbtk-git
$ pbtk
Bei den meisten anderen Verteilungen möchten Sie es direkt ausführen:
# 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 wird ebenfalls unterstützt (mit den gleichen erforderlichen Modulen). Sobald Sie die GUI geführt haben, sollten Sie Sie warnen, was Sie fehlen, je nachdem, was Sie versuchen.
Die GUI kann durch das Hauptskript gelangt werden:
./gui.py
Die folgenden Skripte können auch eigenständig ohne GUI verwendet werden:
./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]
Nehmen wir an, Sie sind Reverse Engineering an Android -Anwendung. Sie haben die Anwendung mit Ihrem bevorzugten Dekompiler ein wenig untersucht und festgestellt, dass sie Protobuf als Postdaten über HTTPS auf typische Weise transportiert.
Sie öffnen PBTK und werden auf sinnvolle Weise begrüßt:
Der erste Schritt besteht darin, Ihre .protos in ein Textformat zu bringen. Wenn Sie auf eine Android -App abzielen, in eine APK fallen und warten sollten, sollte die magische Arbeit erledigen! (Es sei denn, es ist eine wirklich exotische Implementierung)
In diesem Fall springen Sie zu ~/.pbtk/protos/<your APK name> (entweder über die Befehlszeile oder die Schaltfläche unten im Begrüßungsbildschirm, um Ihren Dateibrowser zu öffnen, wie Sie es bevorzugen). Alle. Protos der App sind tatsächlich hier.
Zurück in Ihrem Dekompiler sind Sie auf die Klasse gestoßen, die Daten konstruiert, die an den HTTPS -Endpunkt gesendet werden, der Sie interessiert. Es serialisiert die Protobuf -Nachricht, indem sie eine Klasse aus generiertem Code aufgerufen.
Diese letztere Klasse sollte in Ihrem .Protos -Verzeichnis perfekt übereinstimmen (dh com.foo.bar.ab passt com/foo/bar/a/b.proto ). In beiden Fällen sollte es Ihnen ermöglichen, seinen Namen zu verweisen.
Das ist großartig: Das nächste ist zu Schritt 2 , die Auswahl Ihrer gewünschten Eingabe.
Sie können auch einige Muster-Roh-Protobuf-Daten angeben, die an diesen Endpunkt gesendet wurden, der durch Mitmproxy oder Wireshark erfasst wurde und dass Sie in eine hexcodierte Form einfügen werden.
In Schritt 3 handelt es sich um den lustigen Teil des Klickens an Schaltflächen und beim Sehen, was passiert! Sie haben eine Baumansicht, die jedes Feld in der Protobufstruktur darstellt (wiederholte Felder werden von "+" satt, die erforderlichen Felder haben keine Kontrollkästchen).
Bewegen Sie einfach ein Feld, um den Fokus zu haben. Wenn das Feld ein Ganzzahltyp ist, verwenden Sie das Mausrad, um es zu erhöhen/zu verringern. Die Auslaufinformationen finden Sie auch auf Schwebeplätzen.
Hier ist es! Sie können die Bedeutung jedes Feldes damit bestimmen. Wenn Sie .Protos aus dem Minimed Code extrahiert haben, können Sie Felder nach dem, was Sie bemerken, umbenennen, indem Sie auf die Namen klicken.
Viel Spaß beim Umkehren! ? ?
PBTK -Speicher %APPDATA%pbtkprotos ~/.pbtk/protos/
Sie können Daten aus diesem Verzeichnis direkt über Ihren regulären Dateibrowser und Texteditor einziehen, ausziehen, umbenennen, umbenennen, umbenennen, umbenennen, umbenennen oder löschen.
HTTP-basierte Endpunkte werden in ~/.pbtk/endpoints/ als JSON-Objekte gespeichert. Diese Objekte sind Arrays von Anfrage-/Antwort -Informationen, die so aussehen:
[ {
"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 verwendet zwei Arten von steckbaren Modulen intern: Extraktoren und Transporte.
Extraktoren sind in extractors/*.py . Sie sind als eine Methode definiert, vor der ein Dekorateur so vorangegangen ist:
@ 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. Transporte sind in utils/transports.py definiert. Sie sind definiert als eine Klasse, der einem Dekorateur wie folgt vorangetrieben wird:
@ 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 )Das Folgende könnte für weitere Veröffentlichungen kommen:
Ich habe versucht, mein Bestes zu geben, um einen gründlich lesbaren und kommentierten Code (mit Ausnahme von Teilen, die größtenteils selbst beschreiben, z.
Da PBTK PYQT verwendet, wird es unter der GNU GPL-Lizenz (i, hiermit usw.) veröffentlicht. Ich hätte wahrscheinlich etwas öffentlich zugängliches Ähnliches gewählt.
Es gibt keine formalisierte Regel für den Brief des Projektnamens. In der Regel folgt nur Ihrem Herzen ❤