Skip to content

Commit 9a2432f

Browse files
committed
first modifs + comments
1 parent cdc77a0 commit 9a2432f

File tree

4 files changed

+273
-25
lines changed

4 files changed

+273
-25
lines changed

HOW.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# How messages are built from seed files
2+
* `klist_t(lms)` ~= linked list
3+
* `KLIST_INIT(lms, message_t *, message_t_freer)` -> initialize datastructure (linked list) of `message_t` and utilities functions
4+
* `klist_t(lms) *construct_kl_messages(u8* fname, region_t *regions, u32 region_count)` -> build a linked list of `message_t` from a seed in the file `fname` and a *description of regions*
5+
- a region is a portion of a message correponding to one send/receive
6+
- the function `region_t* extract_requests_generic(unsigned char* buf, unsigned int buf_size, unsigned int* region_count_ref)` builds the regions from a seed (used in function `static void add_to_queue(u8* fname, u32 len, u8 passed_det)` -> in fact `extract_requests` which is equal to `extract_requests_generic`)
7+
8+
# How does the forkserver works
9+
* Instead of cloning the whole SUT for each new fork, the cloning is done within the binary of the SUT: code is injected into the fuzzed binary.
10+
* [https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html](https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html)
11+
* In `afl-fuzz.c:init_forkserver` and in `afl-as.h` and `afl-as.c` (instrumentation added in assembly language)
12+
* StateAFL has two forkservers available depending if stateAFL probes are used or if *vanilla* binary is used instead (option `-u`)
13+
14+
# The function `choose_target_state`
15+
* choose a state within all the states discovered so far
16+
* take a selection algorithm in arguments
17+
* select an id (`target_state_id`) corresponding to a state in the hash map `khms_states`
18+
* `khms_states` is a hash map of struct `state_info_t`
19+
20+
# The function `choose_seed`
21+
* produce a `queue_entry` from a state selected
22+
* take a selection algorithm in arguments
23+
* A `queue_entry` contains a seed, the regions decomposition and the state
24+
* A region contains the state sequence produced until the end of the region
25+
26+
# The function `update_scores_and_select_next_state`

TODO.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Advice from AFLNet's README
2+
- [x] Look at the function `choose_target_state`
3+
- [x] Look at the function `choose_seed`
4+
- [ ] Look at the function `update_scores_and_select_next_state`
5+
6+
# ~Remove the probes (on memory allocation and on network communication) added at compilation on memory~
7+
- [/] ~reset folder llvm\_mode as in aflnet project~
8+
9+
# Don't care about the messages sent by the SUT
10+
* In `int main(int argc, char** argv)`:
11+
- [x] remove target protocol selection (see StateAFL)
12+
13+
# Remove the state machine building process
14+
* Disable option `-E` disable the state machine building and selection of state to fuzz
15+
- [ ] follow the boolean variable `state_aware_mode`
16+
* In `int main(int argc, char** argv)`:
17+
- [/] ~remove `check_aslr()` call~
18+
* In `int setup_ipsm()`:
19+
- [x] only initialize the state hash map `khms_states`
20+
* ~In `EXP_ST void setup_shm(void)`:~
21+
- [/] ~(?) remove state related stuff: TLSH calibration, log state tracer, .. -> this is somehow related to the forkserver~
22+
* In `EXP_ST void setup_dirs_fds(void)`:
23+
- [ ] remove records of new paths
24+
* In `EXP_ST u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len)`:
25+
- [ ] remove the AFLNet update of `kl_messages` linked list
26+
- [ ] remove `update_fuzzs()` call
27+
28+
# Build a very simple state list from the seeds files
29+
* In `static void perform_dry_run(char** argv)`:
30+
- [ ] build message from *replay* format (see StateAFL)
31+
* In `void update_state_aware_variables(struct queue_entry *q, u8 dry_run)`
32+
- [ ] build a simple state list only if it is a *dry run*
33+
- [ ] otherwise do nothing
34+
* The hash map `khms_states` should be this list
35+
- [ ] initialize it in `update_state_aware_variables` in *dry run* mode
36+
- [ ] never update it after the initialisation
37+
* The type `region_t` should not contain state related stuff (in file `aflnet.h`)
38+
39+
# Select the messages to mutate directly from the seeds files
40+
* In `struct queue_entry *choose_seed(u32 target_state_id, u8 mode)`
41+
- [ ] build a `queue_entry` from the seed file corresponding to the state given as argument
42+
* In `static u8 fuzz_one(char** argv)` after the flag `AFLNET_REGIONS_SELECTION`
43+
- [ ] retrieve the M2 part of the messages from the file `length-seed.state[X]` instead of the region information
44+
45+
46+
# Select the states in a round-robin fashion (or any other "fair" selection)
47+
* In the function `choose_target_state`
48+
- [ ] add a new selection algorithm based on the simple state list
49+
50+
# Take a look at the mutation functions added in `static u8 fuzz_one(char** argv)` (in StateAFL)
51+
- [ ] `void regions_add_bytes(region_t* regions, unsigned int region_count, unsigned int position, int added_bytes)`
52+
- [ ] `int regions_remove_bytes(region_t* regions, unsigned int region_count, unsigned int position, int removed_bytes)`
53+
- [?] static variables `unsigned int mutated_region_count` and `region_t* mutated_regions`

afl-fuzz.c

+110-25
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ static u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
160160

161161
static s32 shm_id; /* ID of the SHM region */
162162

163+
//unsigned int* extract_response_codes_generic(unsigned char* buf, unsigned int buf_size, unsigned int* state_count_ref);
164+
165+
region_t* extract_requests_generic(unsigned char* buf, unsigned int buf_size, unsigned int* region_count_ref);
163166
static volatile u8 stop_soon, /* Ctrl-C pressed? */
164167
clear_screen = 1, /* Window resized? */
165168
child_timed_out; /* Traced process timed out? */
@@ -394,12 +397,12 @@ u8 state_selection_algo = ROUND_ROBIN, seed_selection_algo = RANDOM_SELECTION;
394397
u8 false_negative_reduction = 0;
395398

396399
/* Implemented state machine */
397-
Agraph_t *ipsm;
398-
static FILE* ipsm_dot_file;
400+
//Agraph_t *ipsm;
401+
//static FILE* ipsm_dot_file;
399402

400403
/* Hash table/map and list */
401404
klist_t(lms) *kl_messages;
402-
khash_t(hs32) *khs_ipsm_paths;
405+
//khash_t(hs32) *khs_ipsm_paths;
403406
khash_t(hms) *khms_states;
404407

405408
//M2_prev points to the last message of M1 (i.e., prefix)
@@ -409,18 +412,18 @@ khash_t(hms) *khms_states;
409412
kliter_t(lms) *M2_prev, *M2_next;
410413

411414
//Function pointers pointing to Protocol-specific functions
412-
unsigned int* (*extract_response_codes)(unsigned char* buf, unsigned int buf_size, unsigned int* state_count_ref) = NULL;
413-
region_t* (*extract_requests)(unsigned char* buf, unsigned int buf_size, unsigned int* region_count_ref) = NULL;
415+
//unsigned int* (*extract_response_codes)(unsigned char* buf, unsigned int buf_size, unsigned int* state_count_ref) = extract_response_codes_generic;
416+
region_t* (*extract_requests)(unsigned char* buf, unsigned int buf_size, unsigned int* region_count_ref) = extract_requests_generic;
414417

415418
/* Initialize the implemented state machine as a graphviz graph */
416419
void setup_ipsm()
417420
{
418-
ipsm = agopen("g", Agdirected, 0);
421+
//ipsm = agopen("g", Agdirected, 0);
419422

420-
agattr(ipsm, AGNODE, "color", "black"); //Default node colr is black
421-
agattr(ipsm, AGEDGE, "color", "black"); //Default edge color is black
423+
//agattr(ipsm, AGNODE, "color", "black"); //Default node colr is black
424+
//agattr(ipsm, AGEDGE, "color", "black"); //Default edge color is black
422425

423-
khs_ipsm_paths = kh_init(hs32);
426+
//khs_ipsm_paths = kh_init(hs32);
424427

425428
khms_states = kh_init(hms);
426429
}
@@ -517,21 +520,21 @@ u8 is_state_sequence_interesting(unsigned int *state_sequence, unsigned int stat
517520
}
518521

519522
/* Update the annotations of regions (i.e., state sequence received from the server) */
520-
void update_region_annotations(struct queue_entry* q)
521-
{
522-
u32 i = 0;
523-
524-
for (i = 0; i < messages_sent; i++) {
525-
if ((response_bytes[i] == 0) || ( i > 0 && (response_bytes[i] - response_bytes[i - 1] == 0))) {
526-
q->regions[i].state_sequence = NULL;
527-
q->regions[i].state_count = 0;
528-
} else {
529-
unsigned int state_count;
530-
q->regions[i].state_sequence = (*extract_response_codes)(response_buf, response_bytes[i], &state_count);
531-
q->regions[i].state_count = state_count;
532-
}
533-
}
534-
}
523+
//void update_region_annotations(struct queue_entry* q)
524+
//{
525+
// u32 i = 0;
526+
//
527+
// for (i = 0; i < messages_sent; i++) {
528+
// if ((response_bytes[i] == 0) || ( i > 0 && (response_bytes[i] - response_bytes[i - 1] == 0))) {
529+
// q->regions[i].state_sequence = NULL;
530+
// q->regions[i].state_count = 0;
531+
// } else {
532+
// unsigned int state_count;
533+
// q->regions[i].state_sequence = (*extract_response_codes)(response_buf, response_bytes[i], &state_count);
534+
// q->regions[i].state_count = state_count;
535+
// }
536+
// }
537+
//}
535538

536539
/* Choose a region data for region-level mutations */
537540
u8* choose_source_region(u32 *out_len) {
@@ -2231,6 +2234,83 @@ EXP_ST void setup_shm(void) {
22312234
}
22322235

22332236

2237+
2238+
2239+
/********************************************************/
2240+
/* StateAFL bypasses response code extraction */
2241+
/* and build a generic request extraction */
2242+
unsigned int* extract_response_codes_generic(unsigned char* buf, unsigned int buf_size, unsigned int* state_count_ref) {
2243+
2244+
unsigned int state_tracer_count_all = state_shared_ptr->seq_len;
2245+
2246+
*state_count_ref = state_tracer_count_all;
2247+
2248+
unsigned int * state_sequence = ck_alloc( (*state_count_ref)*sizeof(int) );
2249+
memcpy(state_sequence, state_shared_ptr->seq, *state_count_ref * sizeof(unsigned int));
2250+
2251+
2252+
return state_sequence;
2253+
}
2254+
2255+
//static unsigned int mutated_region_count = 0;
2256+
//static region_t* mutated_regions = NULL;
2257+
2258+
region_t* extract_requests_generic(unsigned char* buf, unsigned int buf_size, unsigned int* region_count_ref) {
2259+
2260+
unsigned int region_count = 0;
2261+
region_t *regions = NULL;
2262+
2263+
unsigned int cur_start = 0;
2264+
2265+
//if(mutated_regions != NULL && mutated_region_count > 0) {
2266+
2267+
// *region_count_ref = mutated_region_count;
2268+
2269+
// regions = ck_alloc(mutated_region_count * sizeof(region_t));
2270+
// memcpy(regions, mutated_regions, mutated_region_count * sizeof(region_t));
2271+
2272+
// return regions;
2273+
//}
2274+
2275+
2276+
unsigned int byte_count = 0;
2277+
2278+
while(byte_count < buf_size) {
2279+
2280+
if(byte_count + 4 >= buf_size) {
2281+
PFATAL("AFLNet - Erroreous message length in input file");
2282+
}
2283+
2284+
unsigned int next_message_len = *((unsigned int *)(void *)&buf[byte_count]);
2285+
2286+
byte_count += sizeof(unsigned int);
2287+
2288+
if(byte_count + next_message_len > buf_size) {
2289+
PFATAL("AFLNet - Erroneous message length in input file (2)");
2290+
}
2291+
2292+
region_count++;
2293+
2294+
regions = (region_t *)ck_realloc(regions, region_count * sizeof(region_t));
2295+
2296+
regions[region_count - 1].start_byte = cur_start;
2297+
regions[region_count - 1].end_byte = cur_start + next_message_len - 1;
2298+
regions[region_count - 1].state_sequence = NULL;
2299+
regions[region_count - 1].state_count = 0;
2300+
2301+
cur_start += next_message_len;
2302+
byte_count += next_message_len;
2303+
2304+
}
2305+
2306+
*region_count_ref = region_count;
2307+
return regions;
2308+
2309+
}
2310+
/* End of StateAFL */
2311+
/********************************************************/
2312+
2313+
22342314
/* Load postprocessor, if available. */
22352315

22362316
static void setup_post(void) {
@@ -9074,6 +9154,11 @@ int main(int argc, char** argv) {
90749154
FATAL("%s protocol is not supported yet!", optarg);
90759155
}
90769156

9157+
9158+
// bypass the protocol selection
9159+
extract_requests = &extract_requests_generic;
9160+
extract_response_codes = &extract_response_codes_generic;
9161+
90779162
protocol_selected = 1;
90789163

90799164
break;
@@ -9132,7 +9217,7 @@ int main(int argc, char** argv) {
91329217
//AFLNet - Check for required arguments
91339218
if (!use_net) FATAL("Please specify network information of the server under test (e.g., tcp://127.0.0.1/8554)");
91349219

9135-
if (!protocol_selected) FATAL("Please specify the protocol to be tested using the -P option");
9220+
//if (!protocol_selected) FATAL("Please specify the protocol to be tested using the -P option");
91369221

91379222
if (netns_name) {
91389223
if (check_ep_capability(CAP_SYS_ADMIN, argv[0]) != 0)

stateafl-aflnet.diff.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Seulement dans aflnet: afl-clang-fast
2+
# Seulement dans aflnet: afl-clang-fast++
3+
4+
5+
# Les fichiers stateafl/afl-fuzz.c et aflnet/afl-fuzz.c sont différents
6+
Many differences ..
7+
8+
9+
# Les fichiers stateafl/aflnet-replay.c et aflnet/aflnet-replay.c sont différents
10+
```
11+
71c71
12+
< if ((!strcmp(argv[2], "DTLS12")) || (!strcmp(argv[2], "SIP"))) {
13+
---
14+
> if ((!strcmp(argv[2], "DTLS12")) || (!strcmp(argv[2], "DNS")) || (!strcmp(argv[2], "SIP"))) {
15+
96,114d95
16+
<
17+
< #ifdef LOCAL_PORT
18+
< struct sockaddr_in local_serv_addr;
19+
<
20+
< int optval = 1;
21+
< setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
22+
<
23+
< local_serv_addr.sin_family = AF_INET;
24+
< local_serv_addr.sin_addr.s_addr = INADDR_ANY;
25+
< local_serv_addr.sin_port = htons(LOCAL_PORT);
26+
<
27+
< local_serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
28+
< if (bind(sockfd, (struct sockaddr*) &local_serv_addr, sizeof(struct sockaddr_in))) {
29+
< FATAL("Unable to bind socket on local source port");
30+
< }
31+
< #endif
32+
<
33+
<
34+
<
35+
131,135d111
36+
<
37+
< #ifdef SEND_DELAY
38+
< usleep(SEND_DELAY); // send delay
39+
< #endif
40+
<
41+
```
42+
43+
44+
# Seulement dans stateafl: aflnet-to-plain.c
45+
Not used?
46+
47+
48+
# Les fichiers stateafl/afl-replay.c et aflnet/afl-replay.c sont différents
49+
```
50+
79c79
51+
< if ((!strcmp(argv[2], "DTLS12")) || (!strcmp(argv[2], "SIP"))) {
52+
---
53+
> if ((!strcmp(argv[2], "DTLS12")) || (!strcmp(argv[2], "DNS")) || (!strcmp(argv[2], "SIP"))) {
54+
```
55+
56+
57+
# Les fichiers stateafl/config.h et aflnet/config.h sont différents
58+
```
59+
331c331
60+
< #define STATE_STR_LEN 16
61+
---
62+
> #define STATE_STR_LEN 12
63+
```
64+
65+
66+
# Seulement dans stateafl: convert-pcap-replay-format.py
67+
68+
69+
# Les fichiers stateafl/Makefile et aflnet/Makefile sont différents
70+
```
71+
36c36
72+
< LDFLAGS += -ldl -lgvc -lcgraph -lm
73+
---
74+
> LDFLAGS += -ldl -lgvc -lcgraph -lm -lcap
75+
```
76+
77+
78+
# Seulement dans stateafl: README-AFLnet.md
79+
Probably an old version of the README of aflnet
80+
81+
82+
# Les fichiers stateafl/README.md et aflnet/README.md sont différents
83+
Completely different (no surprise)
84+

0 commit comments

Comments
 (0)