Au fait, c'était l'époque du calendrier de l'Avent, alors je vais donner un service commémoratif au scénario que j'ai écrit hier. Cet article est l'article du 13e jour de Security Tools Advent Calendar 2018.
Le visualiseur de différence de chemin d'exécution est un outil qui visualise la différence entre les chemins d'exécution lorsque deux entrées sont données au même programme. (Je pensais que le nom était approprié maintenant) Par exemple, s'il existe un programme qui accepte les lettres «AB» comme indiqué ci-dessous
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;
}
Étant donné la chaîne "AX", "Not good" après one_match (), Étant donné la chaîne "AB", all_match (), Je veux visualiser cela d'une bonne manière même si cela passe par différents chemins d'exécution.
python
$ cat test1.in test2.in
AX
AB
$ ./test test1.in
One match
Not good
$ ./test test2.in
Accepted!
angr+Bingraphvis Il y a deux choses principales que je veux faire cette fois.
Cette fois, j'ai utilisé angr et Bingraphvis. Bingraphvis est une bibliothèque de base qui prend en charge angr-utils pour visualiser CFG généré par angr. Il gère les opérations, les transformations et les tracés des nœuds CFG. En utilisant ceci et le QEMU Runner (traceur) de angr,
Je l'ai fait. La raison pour laquelle je n'ai pas utilisé le wrapper angr-utils était que je voulais définir et utiliser une variante CFG avec mes propres différences de trace. Si vous l'exécutez contre le programme mentionné précédemment, il crachera l'image ci-dessous.
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
Le chemin quand le rouge donne test1.in et le bleu donne test2.in. Le commun est noir.
Si vous faites ce qui précède pour un programme comme un utilitaire UNIX, vous tracerez un énorme CFG (5 000 nœuds ou plus) et générerez une image de dizaines de milliers de pixels. Bien sûr, le spectateur ne peut pas être affiché et tombe, ce qui altère le sens de la visualisation. Il est possible d'afficher uniquement les nœuds avec des différences au lieu de l'ensemble du CFG (sans -v de la commande ci-dessus), mais les différences seules peuvent être très importantes. Par conséquent, nous avons également ajouté une fonction pour tracer CFG en divisant l'image pour chaque fonction du programme.
Activé avec l'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
Donnez au lecteur des données mp3 clairement invalides et des données mp3 valides, par exemple "ABCD". La différence CFG pour chaque fonction est représentée dans outd.
En regardant la différence entre les fonctions du lecteur mp3 appelé calc_length, c'est comme suit.
Le code est ci-dessous https://gist.github.com/RKX1209/3cb60b0fa0ba92da6575716680f32aa0
Recommended Posts