一、lief库安装
环境:python3
命令如下:
1 2
| sudo pip3 install setuptools --upgrade sudo pip3 install lief
|
二、将elf文件转成so库的使用
1、将源码crackme101.c 编译为elf文件crackme101.bin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <stdlib.h> #include <stdio.h> #include <string.h>
#define LOCAL __attribute__ ((visibility ("hidden"))) #define NOINLINE __attribute__ ((noinline))
NOINLINE LOCAL int check(char* input) { if (strcmp(input, "easy") == 0) { return 1; } return 0; }
int main(int argc, char** argv) {
if (argc != 2) { printf("Usage: %s flag\n", argv[0]); exit(-1); }
if (check(argv[1])) { printf("Well done!\n"); } else { printf("Wrong!\n"); } return 0; }
|
1
| gcc crackme101.c -O0 -fPIE -pie -Wl,-strip-all,--hash-style=sysv -o crackme101.bin
|
2、将bin文件转成so库,并将想要调用的函数地址(ida里面看)写入so库声明exported(因为elf文件不声明,库文件才声明)
1 2 3 4 5 6 7 8
| import lief app = lief.parse("./crackme101.bin") app.add_exported_function(0x830, "check") app.write("libcrackme101.so")
|
3、编译一个c语言程序调用so库里的check函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> typedef int(*check_t)(char*); int main (int argc, char** argv) {
void* handler = dlopen("./libcrackme101.so", RTLD_LAZY); check_t check_function = (check_t)dlsym(handler, "check"); char buf[100]; scanf("%s",&buf); int output = check_function(buf);
printf("Output of check('%d')",output);
return 0; }
|
这里可以看到,调用了check函数,同时输入变成了我们自己的输入,重定向了输入,这样有利于fuzz操作。
1
| gcc instrument.c -O0 -fPIE -pie -o instrument.bin -ldl
|
这样生成的instrument的elf文件就是我们勇于fuzz测试的好用程序。
三、关于格式化字符串的patch利用
1、单个格式化字符串漏洞printf
2、利用lief库进行改名
1 2 3 4 5
| import lief binary = lief.parse("./format") puts_sym = filter(lambda e: e.name == "printf", binary.dynamic_symbols)[0] puts_sym.name = "puts" binary.write("format_patch");
|
3、效果