LAVA
LAVA: Large Scale Automated Vulnerability Addition
pre install
由于网络问题,可能部分操作需要进行代理。终端代理工具使用proxychains-ng
install & config
1 | git clone https://github.com/rofl0r/proxychains-ng.git |
之后,编辑vim /etc/proxychains.conf
,配置正确的代理地址。例如socks5 127.0.0.1 1080
可以配合shadowsocks
一起使用。1
2
3
4
5
6
7Usage: proxychains4 -q -f config_file program_name [arguments]
-q makes proxychains quiet - this overrides the config setting
-f allows one to manually specify a configfile to use
for example : proxychains telnet somehost.com
More help in README file
-> proxychains4 -q pip install protobuf
或者使用终端代理设置:1
2
3
4
5
6
7
8
9
10
11bash
export http_proxy="http://127.0.0.1:1080"
export https_proxy="http://127.0.0.1:1080"
git
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
git config --global --unset http.proxy
git config --global --unset https.proxy
INSTALL
1 | git clone https://github.com/panda-re/lava.git |
但是由于国内网络等问题,需要将源更换掉。在docker/Dockerfile
中,新增1
2RUN sed -i 's/httpredir.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
Run apt-get update && apt-get install -y cmake libelf-dev elfutils
同时,将docker/sources.list
中的内容替换为速度比较快的源。1
2
3
4
5
6
7
8
9
10
11deb http://mirrors.ustc.edu.cn/debian/ wheezy main contrib non-free
deb-src http://mirrors.ustc.edu.cn/debian/ wheezy main contrib non-free
deb http://mirrors.ustc.edu.cn/debian/ wheezy-updates main contrib non-free
deb-src http://mirrors.ustc.edu.cn/debian/ wheezy-updates main contrib non-free
deb http://mirrors.ustc.edu.cn/debian/ wheezy-backports main contrib non-free
deb-src http://mirrors.ustc.edu.cn/debian/ wheezy-backports main contrib non-free
deb http://mirrors.ustc.edu.cn/debian-security/ wheezy/updates main contrib non-free
deb-src http://mirrors.ustc.edu.cn/debian-security/ wheezy/updates main contrib non-free
最好放在开始的位置,在接下来的docker build过程中均可以直接使用更换后的源。
docker install
在docker的安装中,由于docker运行权限等问题,docker安装完成后,需运行sudo usermod -a -G docker username
将用户添加到docker运行组中,完成后登出再次进入,运行docker ps
1
2docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
出现该界面表示docker已经设置成功。
在安装的过程中,可能部分软件还是由于网络原因不容易安装,只好挂全局代理手动安装即可。安装部分到此即可结束。
配置
在init-project.py
文件中,包含了一个project的基本配置信息,可以根据需要进行相应的更改。
其中QCOW_URL
可以先下载下来,放到相应的位置,该文件是panda2的qemu虚拟机文件,在lava运行过程中需要使用panda2进行染色分析。
PROJ_HOME
是项目的位置,由用户指定。QCOW_FILE
是panda2虚拟机文件,用户指定。name
是项目名字,用户指定。TAR_URL
是源代码压缩包,用户指定。MAKE_CMD
源代码编译时,使用的编译命令。CMD
源文件编译成二进制文件后,二进制文件如何运行。INPUT_FILE
二进制程序运行所需要提供的输入文件。MAIN_FILE
包含main
函数的源文件。
运行python init-project.py
可以在project位置生成json文件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{
"qemu": "/home/guo/panda/build/i386-softmmu/qemu-system-i386",
"qcow": "/home/guo/buggy/wheezy_panda2.qcow2",
"snapshot": "root",
"directory": "/home/guo/buggy/readelf",
"name": "toy-readelf",
"tarfile": "/home/guo/buggy/readelf/readelf.tar.gz",
"configure": "",
"make": "make CFLAGS=-fvisibility=default CFLAGS+=-g -j 4",
"clean": "make clean",
"install": "make install",
"command": "{install_dir}/bin/readelf -hlsSe {input_file}",
"expect_prompt": "root@debian-i386:~#",
"db": "toy-readelf",
"max_liveness": 10,
"max_cardinality": 10000,
"max_tcn": 10,
"max_lval_size": 100,
"main_file": [ "readelf.c" ],
"inputs": [ "/bin/ls" ]
}
json文件包含项目所需的一般性信息。此处configure
项设置需要注意,如果源代码是需要使用configure
配置生成Makefile文件,则在此处填入./configure
,如果直接有Makefile文件则无需考虑,修改相应的代码即可。
需要修改的代码部分
1 | # file: scripts/add_queries.sh @ 84 line |
修改的目的是区分配置文件中configure
项的内容,不同的选项使用不同的命令。
1 | # file: scripts/everything.sh @ 76 line |
1 | # file: scripts/everything.sh @ 113 line |
demo
demo.c1
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73//demo.c
enum {
TYPEA = 1,
TYPEB = 2
};
typedef struct {
uint32_t magic; // Magic value
uint32_t reserved; // Reserved for future use
uint16_t num_recs; // How many entries?
uint16_t flags; // None used yet
uint32_t timestamp; // Unix Time
} file_header;
typedef struct {
char bar[16];
uint32_t type;
union {
float fdata;
uint32_t intdata;
} data;
} file_entry;
void parse_header(FILE *f, file_header *hdr) {
if (1 != fread(hdr, sizeof(file_header), 1, f))
exit(1);
if (hdr->magic != MAGIC)
exit(1);
}
file_entry * parse_record(FILE *f) {
file_entry *ret = (file_entry *) malloc(sizeof(file_entry));
if (1 != fread(ret, sizeof(file_entry), 1, f))
exit(1);
return ret;
}
void consume_record(file_entry *ent) {
printf("Entry: bar = %s, ", ent->bar);
if (ent->type == TYPEA) {
printf("fdata = %f\n", ent->data.fdata);
}
else if (ent->type == TYPEB) {
printf("intdata = %u\n", ent->data.intdata);
}
else {
printf("Unknown type %x\n", ent->type);
exit(1);
}
free(ent);
}
int main(int argc, char **argv) {
FILE *f = fopen(argv[1], "rb");
file_header head;
parse_header(f, &head);
printf("File timestamp: %u\n", head.timestamp);
unsigned i;
for (i = 0; i < head.num_recs; i++) {
file_entry *ent = parse_record(f);
consume_record(ent);
}
return 0;
}
Makefile1
2
3
4
5
6
7
8
9
10demo: demo.o
all: demo
install:
mkdir -p $(shell pwd)/lava-install/bin
cp demo $(shell pwd)/lava-install/bin
clean:
rm -f demo.o demo
输入文件binary to hex1
2
3
4
5
6
7 Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: 41 56 41 4C 00 00 00 00 03 00 00 00 99 15 80 57 AVAL...........W
00000010: 68 65 6C 6C 6F 00 00 00 00 00 00 00 00 00 00 00 hello...........
00000020: 01 00 00 00 C3 F5 48 40 67 6F 6F 64 62 79 65 00 ....CuH@goodbye.
00000030: 00 00 00 00 00 00 00 00 02 00 00 00 2A 00 00 00 ............*...
00000040: 65 75 6C 65 72 00 00 00 00 00 00 00 00 00 00 00 euler...........
00000050: 01 00 00 00 B6 F3 2D 40 ....6s-@