I heard that there is something called klee, so I tried to identify the password, so I leave a memorandum. I don't understand the specifics at all, so I just moved.
I targeted the check_password ()
function introduced in the Using symbolic environment of the klee tutorial.
This function returns 1 when the password hello
is entered, and 0 otherwise.
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;
}
The tutorial explains how to generate a test case that includes command line arguments, but in this article we aimed to actually ask for a password.
From here, the password is actually obtained by symbolic execution.
There are two klee functions used this time.
In the sample code, the command line argument char ** argv
is taken, but this time it is rewritten tochar pass [6]
as long as symbolic execution can be performed.
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;
}
Just hit the klee command after running clang.
In the part of / home / klee / klee_src / include
, specify the path of klee according to your environment. If you are using docker, you can leave the example below as it is.
$ clang -I /home/klee/klee_src/include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone password.c
$ klee password.bc
When executed, the following result will be obtained.
From this content, you can see that the result was output to the directory klee-out-0
, so take a look.
Multiple files called .ktest
are output, but each is a test case. Use the ktest-tool
command to see this .ktest
file.
In the code executed this time, if the passwords match, the process is interrupted with klee_assert
. So, if you look at the test case where .assert.err
exists (test000005.ktest
), you can get the password.
When I first heard it, I thought that klee was a tool that would analyze if I passed a binary like angr, but this method requires a procedure to add klee / klee.h
etc. to the source code. It seems. I would like to find out if there is an easy way to use it even when I only have the binary.
Recommended Posts