-
Notifications
You must be signed in to change notification settings - Fork 65
LAVA Wiki
The files were originally found here.
LAVA is the product of a collaboration between MIT Lincoln Laboratory, NYU, and Northeastern University, designed to provide a method for testing fuzzers and automating the creation of CTFs by injecting security vulnerabilities into source code.
Download the LAVA Debian Package here and to install the Python package, use pip install pyroclastic.
Checkmark means we know this works. To replicate the result, use the same project and check the logs for injection.
- BUG_PTR_ADD, see example with toy Looks like the implementation is somewhere here
Validating bug 23 of 50
No known solution for bug with id=942
Bug[942](type=BUG_PTR_ADD, trigger=75, atp=21)
fuzzed = [/mnt/c/Users/andre/OneDrive/Desktop/lava/target_injections/toy/generated-inputs/testsmall-fuzzed-942.bin]
Run modified program: /mnt/c/Users/andre/OneDrive/Desktop/lava/target_injections/toy/bugs/0/toy/lava-install/bin/toy /mnt/c/Users/andre/OneDrive/Desktop/lava/target_injections/toy/generated-inputs/testsmall-fuzzed-942.bin
retval = 139
:type_1 + bug.type
RV indicates memory corruption
Moving crashing input file to /mnt/c/Users/andre/OneDrive/Desktop/lava/target_injections/toy/crashes/testsmall-fuzzed-942.bin
-
[] RET_BUFFER LLVM implementation seems to be here
-
[] REL_WRITE
-
[] PRINTF_LEAK LLVM implementation seems to be here
-
MALLOC_OFF_BY_ONE LLVM implementation seems to be here
It is a bit difficult to generate an input for the specific magic value. But! To replicate this, you need to run lava -i 1 toy --bugtypes "malloc_off_by_one". Go to the bugs directory, checkout the build, and at least for toy you should see something like the snippet below.
Note: malloc() now has a way to be hardset to a value far lower, that it should crash even without ASAN on
enum {
TYPEA = 1,
TYPEB = 2
};
typedef struct {
uint32_t magic;
uint32_t reserved;
uint16_t num_recs;
uint16_t flags;
uint32_t timestamp;
} file_header;
typedef struct {
char bar[16];
uint32_t type;
union {
float fdata;
uint32_t intdata;
} data;
} file_entry;
void parse_header(int *data_flow, FILE *f, file_header *hdr) {
if (1 != fread(hdr, sizeof(file_header), 1, f))
exit(1);
if (((*f)._IO_read_base)) {
DFLOG(0, *(const unsigned int *)((*f)._IO_read_base));
}
if (hdr->magic != 0x4c415641)
exit(1);
}
file_entry * parse_record(int *data_flow, FILE *f) {
file_entry *ret = (file_entry *) malloc((0x51647761 == data_flow[0]) ? (4) : (sizeof(file_entry)));
if (1 != fread(ret, sizeof(file_entry), 1, f))
exit(1);
return ret;
}
void consume_record(int *data_flow, 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) {
int data[1] = {0};
int *data_flow= &data;
FILE *f = fopen(argv[1], "rb");
file_header head;
parse_header(data_flow, f, &head);
printf("File timestamp: %u\n", head.timestamp);
unsigned i;
for (i = 0; i < head.num_recs; i++) {
file_entry *ent = parse_record(data_flow, f);
consume_record(data_flow, ent);
}
return 0;
}Chaff Bugs Confirmation
- [] CHAFF_STACK_UNUSED
- [] CHAFF_STACK_CONST
- [] CHAFF_HEAP_CONST
- [] CHAFF_DIVZERO
Also, we highly suggest downloading the relevant PANDA QCows, as this can take some time on your first time running LAVA. The commands are provided here.
python3 -c "from pandare.qcows_internal import Qcows;Qcows.get_qcow('x86_64')"
python3 -c "from pandare.qcows_internal import Qcows;Qcows.get_qcow('i386')"
python3 -c "from pandare.qcows_internal import Qcows;Qcows.get_qcow('arm')"
python3 -c "from pandare.qcows_internal import Qcows;Qcows.get_qcow('aarch64')"