[PYTHON] Versuchen Sie, mit angr + bingraphvis einen Ausführungspfaddifferenz-Viewer zu erstellen

Übrigens war es die Zeit des Adventskalenders, also werde ich dem Drehbuch, das ich gestern geschrieben habe, einen Gedenkgottesdienst geben. Dieser Artikel ist der 13. Tagesartikel von Security Tools Adventskalender 2018.

Der Ausführungspfad-Differenz-Viewer ist ein Tool, das den Unterschied zwischen Ausführungspfaden visualisiert, wenn zwei Eingaben an dasselbe Programm übergeben werden. (Ich dachte, der Name wäre jetzt angemessen) Zum Beispiel, wenn es ein Programm gibt, das die Buchstaben "AB" wie unten gezeigt akzeptiert

test.c


#include <stdio.h>
#include <stdlib.h>

void one_match() {
        puts("One match");
}

void all_match() {
        puts("Accepted!");
}

int main(int argc, char *argv[]) {
        FILE *fp;
        char buf[32] = {0};
        if (argc < 2) { 
                fprintf(stderr, "usage: ./test <input>\n");
                exit(0);
        }
        fp = fopen(argv[1], "r");
        fread(buf, sizeof(char), 31, fp);
        if (buf[0] == 'A') {
                if (buf[1] == 'B') {
                        all_match();
                        return 0;
                } else {
                        one_match();
                }
        }
        puts("Not good");
        return 0;        
}

Angesichts der Zeichenfolge "AX", "Nicht gut" nach one_match (), Angesichts der Zeichenfolge "AB", all_match (), Ich möchte dies auf eine gute Weise visualisieren, obwohl es verschiedene Ausführungspfade durchläuft.

python


$ cat test1.in test2.in
AX
AB
$ ./test test1.in 
One match
Not good
$ ./test test2.in 
Accepted!

angr+Bingraphvis Es gibt zwei wichtige Dinge, die ich dieses Mal tun möchte.

Diesmal habe ich angr und Bingraphvis verwendet. Bingraphvis ist eine Kernbibliothek, die angr-utils zur Visualisierung von von angr generiertem CFG unterstützt. Es verarbeitet CFG-Knotenoperationen, Transformationen und Diagramme. Mit diesem und dem QEMU Runner (Tracer) von angr,

  1. Zeichnen Sie mit QEMU Runner einen Trace für zwei Eingänge auf
  2. Generieren Sie CFG nach der Hauptfunktion mit CFGEmulated
  3. Färben Sie den CFG-Knoten, der dem Trace-Unterschied zu Bingraphviz entspricht
  4. Speichern Sie CFG als PNG

Ich habe das gemacht. Der Grund, warum ich den Wrapper angr-utils nicht verwendet habe, war, dass ich eine CFG-Variante mit meinen eigenen Trace-Unterschieden definieren und verwenden wollte. Wenn Sie es mit dem zuvor erwähnten Programm ausführen, wird das folgende Bild ausgespuckt.

python


$ python3 input-tracer.py -b ./test -i test1.in,test2.in -v
[+] Opening binary ./test
[+] CFG Cache found 
CFG size = 46
[+] Tracing .... test1.in
Size: 46079
[+] Tracing .... test2.in
Size: 46033
[+] CFG processing ....
Graph len= 30
[+] Complete! Saved to outd/input_trace_test_entire.png

input_trace_test_entire.png

Der Pfad, wenn Rot test1.in und Blau test2.in ergibt. Common ist schwarz.

Zeichnen nach Funktion mit CFGFast

Wenn Sie die obigen Schritte für ein Programm wie ein UNIX-Dienstprogramm ausführen, zeichnen Sie ein großes CFG (5.000 Knoten oder mehr) und generieren ein Bild mit Zehntausenden von Pixeln. Natürlich kann der Betrachter nicht angezeigt werden und fällt, was die Bedeutung der Visualisierung beeinträchtigt. Es ist möglich, nur die Knoten mit Unterschieden anstelle der gesamten CFG anzuzeigen (ohne -v aus dem obigen Befehl), aber die Unterschiede allein können sehr groß sein. Daher haben wir auch eine Funktion zum Zeichnen von CFG hinzugefügt, indem wir das Bild für jede Funktion des Programms geteilt haben.

  1. Zeichnen Sie mit QEMU Runner einen Trace für zwei Eingänge auf
  2. Rufen Sie mit CFGFast von angr eine Liste der in der Binärdatei definierten Funktionen ab.
  3. Führen Sie für jede Funktion den gleichen Vorgang wie oben aus

Aktiviert mit der Option -f.

$ python3 ./input-tracer.py -b mp3_player -i invalid.mp3,1.mp3 -f                              
[+] Opening binary mp3_player                                 
[+] Searching for all the functions (using CFGFast)                             
100% |#####################################| Elapsed Time: 0:00:02 Time: 0:00:02
   ==> 106 functions to process.                                                
[+] Tracing .... invalid.mp3                                                    
Size: 1305732                                                                   
[+] Tracing .... 1.mp3                                                          
Size: 6084333                                                                   
[+] CFG processing ....                                                         
[+](0/106) Computing Accurate CFG for function _init (0x8049cd8)               
[+] CFG Cache found                                                             
Graph len= 0                                                                    
[+] Complete! Saved to outd/input_trace_mpg321-0.3.0__init.png                  
[+](1/106) Computing Accurate CFG for function sub_8049d0c (0x8049d0c)         
[+] CFG Cache found  

Geben Sie dem Player eindeutig ungültige MP3-Daten und gültige MP3-Daten, zum Beispiel "ABCD". Die CFG-Differenz für jede Funktion ist in out aufgetragen. input-tracer.png

Der Unterschied zwischen den Funktionen im MP3-Player calc_length ist wie folgt.

input_trace_mpg321-0.3.0_calc_length.png

Quellcode

Der Code ist unten https://gist.github.com/RKX1209/3cb60b0fa0ba92da6575716680f32aa0

Recommended Posts

Versuchen Sie, mit angr + bingraphvis einen Ausführungspfaddifferenz-Viewer zu erstellen
Erstellen Sie mit PySimpleGUI einen Bildverarbeitungs-Viewer
Versuchen Sie, ein Bild mit Entfremdung zu erzeugen
Versuchen Sie, mit Node.js einen HTTP-Server zu erstellen
Versuchen Sie, mit Tkinter in Python dynamisch einen Checkbutton zu erstellen
Eine einfache Möglichkeit, ein Importmodul mit jupyter zu erstellen
Minimales Makefile und buildout.cfg, um eine Umgebung mit buildout zu erstellen
[Python] Ruft das Skriptausführungsverzeichnis mit einem absoluten Pfad ab
[Python Kivy] So erstellen Sie mit pyinstaller eine exe-Datei
Ich habe versucht, einen Artikel mit SQL Alchemy auf Wiki.js zu erstellen
Versuchen Sie, den Boden durch Rekursion herauszufordern
Erstellen Sie eine Umgebung mit virtualenv
Erstellen Sie eine API mit Django
Versuchen Sie Auto Encoder mit Pytorch
Erstellen Sie den Image Viewer mit Tkinter
Erstellen Sie mit der AWS-API einen Alias für Route53 zu CloudFront
Versuchen Sie, eine Python-Umgebung mit Visual Studio Code & WSL zu erstellen
Versuchen Sie, mit Python3 eine Zeichenfolge aus einem Bild zu extrahieren
Rails-Benutzer versuchen, mit Django eine einfache Blog-Engine zu erstellen
Versuchen Sie, den kürzesten Weg mit Python + NetworkX + Social Data zu lösen
Versuchen Sie, einen Artikel von Qiita mit der REST-API [Umweltvorbereitung] zu erstellen.
Versuchen Sie, Facebook mit Python zu betreiben
Versuchen Sie, sich mit ONNX Runtime zu profilieren
Erstellen Sie eine Altersgruppe mit Pandas
Versuchen Sie, Audio mit M5 STACK auszugeben
Ich habe versucht, ein Plug-In mit HULFT IoT Edge Streaming [Ausführung] (3/3) zu erstellen.
Ich möchte ein Ubuntu Chrome-Benutzerprofil nur mit Colab erstellen
(Hinweis) Eine Webanwendung, die TensorFlow verwendet, um empfohlene Songnamen abzuleiten. [Erstellen Sie eine Ausführungsumgebung mit Docker-Compose.]