J'ai entendu dire qu'il y avait quelque chose qui s'appelle klee, alors j'ai essayé d'identifier le mot de passe, alors je laisse un mémorandum. Je ne comprends pas du tout les détails, alors je viens de déménager.
J'ai ciblé la fonction check_password ()
introduite dans Utilisation de l'environnement symbolique du tutoriel klee.
Cette fonction renvoie 1 lorsque le mot de passe «bonjour» est saisi, et 0 sinon.
password.c
#include <stdio.h>
int check_password(char *buf) {
if (buf[0] == 'h' && buf[1] == 'e' &&
buf[2] == 'l' && buf[3] == 'l' &&
buf[4] == 'o')
return 1;
return 0;
}
int main(int argc, char **argv) {
if (argc < 2)
return 1;
if (check_password(argv[1])) {
printf("Password found!\n");
return 0;
}
return 1;
}
Le didacticiel explique comment générer un scénario de test qui inclut des arguments de ligne de commande, mais dans cet article, nous visions à demander un mot de passe.
A partir de là, le mot de passe est en fait obtenu par exécution symbolique.
Il y a deux fonctions klee utilisées cette fois.
Dans l'exemple de code, l'argument de ligne de commande char ** argv
est pris, mais cette fois il est réécrit en char pass [6]
car il est bon que l'exécution symbolique puisse être effectuée.
password.c
#include <stdio.h>
#include "klee/klee.h"
int check_password(char *buf) {
if (buf[0] == 'h' && buf[1] == 'e' &&
buf[2] == 'l' && buf[3] == 'l' &&
buf[4] == 'o')
return 1;
return 0;
}
int main(void) {
char pass[6];
klee_make_symbolic(pass, sizeof(pass[0]) * 6, "pass");
if (check_password(pass)) {
printf("Password found!\n");
klee_assert(0);
return 0;
}
return 1;
}
Appuyez simplement sur la commande klee après avoir exécuté clang.
Dans la partie / home / klee / klee_src / include
, spécifiez le chemin de klee en fonction de votre environnement. Si vous utilisez docker, vous pouvez conserver l'exemple ci-dessous.
$ clang -I /home/klee/klee_src/include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone password.c
$ klee password.bc
Une fois exécuté, le résultat suivant sera obtenu.
À partir de ce contenu, vous pouvez voir que le résultat a été sorti dans le répertoire klee-out-0
, alors jetez un œil.
Plusieurs fichiers appelés .ktest
sont générés, mais chacun est un cas de test. Utilisez la commande ktest-tool
pour voir ce fichier .ktest
.
Dans le code exécuté cette fois, si les mots de passe correspondent, le processus est interrompu avec klee_assert
. Donc, si vous regardez le cas de test où .assert.err
existe ( test000005.ktest
), vous pouvez obtenir le mot de passe.
Quand je l'ai entendu pour la première fois, j'ai pensé que klee était un outil comme angr qui l'analyserait si je passais un binaire, mais cette méthode nécessite une procédure pour ajouter klee / klee.h
etc. au code source. Il semble. J'aimerais savoir s'il existe un moyen simple de l'utiliser même si je n'ai que le binaire.
Recommended Posts