lava_install

LAVA

项目地址

LAVA: Large Scale Automated Vulnerability Addition

pre install

由于网络问题,可能部分操作需要进行代理。终端代理工具使用proxychains-ng

install & config

1
2
3
4
git clone https://github.com/rofl0r/proxychains-ng.git
./configure --prefix=/usr --sysconfdir=/etc
sudo make install
sudo make install-config

之后,编辑vim /etc/proxychains.conf,配置正确的代理地址。例如socks5 127.0.0.1 1080
可以配合shadowsocks一起使用。

1
2
3
4
5
6
7
Usage:	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
11
bash
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
2
3
git clone https://github.com/panda-re/lava.git
cd lava
python setup.py

但是由于国内网络等问题,需要将源更换掉。在docker/Dockerfile中,新增

1
2
RUN 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
11
deb 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
2
docker 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
2
3
4
5
6
# file: scripts/add_queries.sh @ 84 line
if [ "$(jq -r .configure $json)" == "./configure"]; then
$(jq -r .configure $json) --prefix=$(pwd)/lava-install
elif [[ "$(jq -r .configure $json)" =~ "cmake" ]]; then
$(jq -r .configure $json)
fi

修改的目的是区分配置文件中configure项的内容,不同的选项使用不同的命令。

1
2
3
4
5
6
7
8
9
10
# file: scripts/everything.sh @ 76 line
while getopts "arcqmtb:i:n:z:kd" flag
# 新加一个参数n,插入bug的数量

# file: scripts/everything.sh @ 113 line
if [ "$flag" = "n" ]; then
inject=1
many=$OPTARG
progress "everything" 0 "Inject step will be executed: many = $many"
fi
1
2
3
4
5
6
# file: scripts/everything.sh @ 113 line
if project['configure'] == './configure':
run(shlex.split(project['configure']) + ['--prefix=' + lp.bugs_install])
elif project['configure'].find('cmake') != -1:
run(shlex.split(project['configure']))
# 不同的选项使用不同的命令

demo

demo.c

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
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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#pragma pack(1)
#define MAGIC 0x4c415641

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;
}

Makefile

1
2
3
4
5
6
7
8
9
10
demo: 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 hex

1
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-@