-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfuzz-cull.sh
More file actions
executable file
·245 lines (195 loc) · 8.34 KB
/
Copy pathfuzz-cull.sh
File metadata and controls
executable file
·245 lines (195 loc) · 8.34 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#!/bin/bash
# Wrapper script to run queue culling-enhanced path aware fuzzer.
export RANDOM_CULLING=0 # Set this to 1 to enable the random queue culling strategy (default: Favored seeds)
TOTAL_RUNTIME=$RUNTIME # Total runtime of the fuzzing campaign
export FUZZING_WINDOW=$FUZZING_WINDOW_ORIG # Duration of a fuzzing round
FUZZING_ROUNDS=$((TOTAL_RUNTIME / FUZZING_WINDOW))
CURR_ITER=0
echo "Going to fuzz for $FUZZING_ROUNDS rounds (=TOTAL_RUNTIME=${TOTAL_RUNTIME} - FUZZING_WINDOW=${FUZZING_WINDOW})"
# Starts the standard fuzzing round
function fuzz {
if [[ $# != 2 ]]; then
echo "Usage: $0 <in_dir> <out_dir>"
exit 3
fi
bash fuzz_enhanced.sh $1 $2
}
# This function performs the queue culling operations by feeding the current
# fuzzing round's queue to a pcguard-istrumented binary to collect the favored seeds
# and then copies them to the seeds folder for the next fuzzing round
function fuzz_cull {
if [[ $# != 2 ]]; then
echo "Usage: $0 <in_dir> <out_dir>"
exit 3
fi
idx=$(echo $2 | cut -d "_" -f 2)
tmp_dir="fuzz_tmp_out_${idx}"
d1=$(date +%s)
mv ${1}/default/queue ./test_in
d2=$(date +%s)
delta1=$((d2 - d1))
echo "Delta (mv ${1}/default/queue ./test_in): ${delta1}" >>log.txt
# Aggressive culling mode (to be used when the dry run takes several minutes or hours).
# Performs a pre-processing of the queue that removes the test cases deemed as
# redundant by the path-aware fuzzer
if [[ $AGGRESSIVE_CULLING == 1 ]]; then
echo "Removing path redudants" >>log.txt
if [[ ! -e ./test_in/.state/redundant_edges/ ]]; then
echo "redundant_edges folder does NOT exist! Will not remove path redundants" >>log.txt
elif [[ $(ls -1 ./test_in/.state/redundant_edges/ | wc -l) == 0 ]]; then
echo "redundant_edges folder is empty! Will not remove path redundants" >>log.txt
else
echo "Initial queue size: $(ls -1 ./test_in/ | wc -l) - Redundants: $(ls -1 ./test_in/.state/redundant_edges/ | wc -l)" >>log.txt
for f in test_in/.state/redundant_edges/*; do
bn=$(basename $f) && rm test_in/${bn}
done
fi
echo "New queue size: $(ls -1 ./test_in/ | wc -l)" >>log.txt
export CULL_FAST_CAL=1
fi
rm -rf test_in/.state
# Create $2 (the output directory where the non-culled seeds will be placed)
mkdir $2
if [[ $RANDOM_CULLING == 1 ]]; then # Use random culling (need to set the RANDOM_CULLING env var to 1)
echo "Culling the queue randomly" >>log.txt
d7=$(date +%s)
echo "[RANDOM_CULLING] Debug beginning" >> log.txt
python3 ${AFL_PATH}/scripts/random_culling.py test_in $2 &>> log.txt
echo "[RANDOM_CULLING] Debug end" >> log.txt
d8=$(date +%s)
delta4=$((d8 - d7))
echo "Delta (random culling): ${delta4}" >>log.txt
else # Default culling strategy (Favored seeds)
echo "Culling non-favored seeds" >>log.txt
#1) Fuzz the contents of $1/default/queue with -E 0 to perform a dry run
# This is required to instruct AFL++ to dump the favored seeds to file
export PATH_DUMP_FAVORED=1
d3=$(date +%s)
bash fuzz_enhanced.sh test_in $tmp_dir -E
d4=$(date +%s)
delta2=$((d4 - d3))
echo "Delta (afl-fuzz -E): ${delta2}" >>log.txt
unset PATH_DUMP_FAVORED
if [[ $AGGRESSIVE_CULLING == 1 ]]; then
unset CULL_FAST_CAL
fi
d5=$(date +%s)
cat seeds.favored | cut -d "/" -f 4 > seeds.favored.names
d6=$(date +%s)
delta3=$((d6 - d5))
echo "Delta (cat seeds.favored [...]): ${delta3}" >>log.txt
#3) Copy the favored test cases to $2
echo "Putting favored into $2"
d7=$(date +%s)
while read line; do cp ${tmp_dir}/default/queue/${line} $2; done < seeds.favored.names
d8=$(date +%s)
delta4=$((d8 - d7))
echo "Delta (while read [...] do cp [...] <seeds.favored): ${delta4}" >>log.txt
fi
rm -rf test_in
}
# Main fuzzing loop that interleaves the fuzzing campaign
# with the queue culling rounds
function main_loop {
remaining_fuzztime=$RUNTIME
out_dir="./out_0"
fuzz_iters=1
delta_accum=0
echo "{$(date)} [Fuzz] Start initial fuzzing run (Iteration: ${fuzz_iters}/${FUZZING_ROUNDS})" >>log.txt
d1=$(date +%s)
set -x
fuzz ./seeds/ $out_dir
set +x
remaining_fuzztime=$((remaining_fuzztime-FUZZING_WINDOW_ORIG))
d2=$(date +%s)
delta=$((d2 - d1))
echo "{$(date)} [Fuzz] End fuzzing run" >>log.txt
#echo "Delta(fuzz time): $delta" >> log.txt
tput=$(cat ${out_dir}/default/fuzzer_stats | grep execs_per_sec | cut -d ":" -f 2 | tr -d " ")
echo "Throughput: $tput" >>log.txt
cycles=$(cat ${out_dir}/default/fuzzer_stats | grep cycles_done | cut -d ":" -f 2 | tr -d " ")
echo "Cycles: $cycles" >>log.txt
export AFL_FAST_CAL=1
export AFL_CMPLOG_ONLY_NEW=1
i=0
fuzz_out=$out_dir
echo "Entering loop"
while [ 1 ]; do
i=$((i + 1))
cmin_out="in_${i}"
echo "{$(date)} [CULLING] Start" >>log.txt
corpus_before=$(cat ${fuzz_out}/default/fuzzer_stats | grep corpus_count | cut -d ":" -f 2 | tr -d " ")
echo "Corpus before: $corpus_before" >>log.txt
#d3=$(date +%s)
d3=$(date +%s)
fuzz_cull $fuzz_out $cmin_out
d4=$(date +%s)
delta2=$((d4 - d3))
echo "Delta(cull time): $delta2" >>log.txt
if [[ $REMOVE_CULLTIME == 1 ]]; then
#export FUZZING_WINDOW=$((FUZZING_WINDOW_ORIG - $delta2))
delta_accum=$((delta_accum + $delta2))
echo "Accumulated culltime: $delta_accum" >>log.txt
if [[ $fuzz_iters == $((FUZZING_ROUNDS-1)) ]]; then
export FUZZING_WINDOW=$((FUZZING_WINDOW_ORIG - delta_accum))
echo "Last round reached! Adjusted fuzzing window: $FUZZING_WINDOW" >>log.txt
if [[ $FUZZING_WINDOW -lt 2 ]]; then
export FUZZING_WINDOW=1
fi
elif [[ $delta_accum -gt $remaining_fuzztime ]]; then
echo "Accumulated culltime is greater than the remaining fuzzing time" >>log.txt
export FUZZING_WINDOW=1
fi
fi
corpus_after=$(ls -1 $cmin_out | wc -l)
echo "Corpus after: $corpus_after" >>log.txt
echo "Delta(corpus): $((corpus_before - corpus_after))" >>log.txt
echo "{$(date)} [CULLING] End" >>log.txt
fuzz_out="out_${i}"
fuzz_iters=$((fuzz_iters + 1))
echo "{$(date)} [FUZZ] Start (Iteration: ${fuzz_iters}/${FUZZING_ROUNDS})" >>log.txt
d5=$(date +%s)
set -x
fuzz $cmin_out $fuzz_out
set +x
remaining_fuzztime=$((remaining_fuzztime-FUZZING_WINDOW_ORIG))
echo "Remaining fuzztime: $remaining_fuzztime">>log.txt
d6=$(date +%s)
delta3=$((d6 - d5))
#echo "Delta(fuzz time): $delta3" >> log.txt
echo "{$(date)} [FUZZ] End" >>log.txt
tput=$(cat ${fuzz_out}/default/fuzzer_stats | grep execs_per_sec | cut -d ":" -f 2 | tr -d " ")
echo "Throughput: $tput" >>log.txt
cycles=$(cat ${out_dir}/default/fuzzer_stats | grep cycles_done | cut -d ":" -f 2 | tr -d " ")
echo "Cycles: $cycles" >>log.txt
if [ $fuzz_iters -eq $FUZZING_ROUNDS ]; then
break
fi
done
}
rm -rf out*
if [[ $RANDOM_CULLING == 1 ]]; then
echo "Culling strategy: RANDOM CULLING"
else
echo "Culling strategy: FAVORED seeds"
fi
# Aggressive culling toggle: use when the culling step takes too long
if [[ $AGGRESSIVE_CULLING == 1 ]]; then
echo "AGGRESSIVE CULLING is ENABLED!"
echo "AGGRESSIVE CULLING is ENABLED!" >>log.txt
fi
if [[ $REMOVE_CULLTIME == 1 ]]; then
echo "REMOVE CULLTIME is ENABLED, will remove the accumulated culling time deltas from the final round"
echo "REMOVE CULLTIME is ENABLED, will remove the accumulated culling time deltas from the final round" >>log.txt
fi
echo "{$(date)} *** START ***" >log.txt
main_loop
echo "{$(date)} *** END ***" >>log.txt
set +x
echo "Starting data collection"
set -x
strat="f"
rtime="6"
dirname="${strat}${rtime}_${BIND_CPU}"
mkdir $dirname && mv in_* $dirname && mv out_* $dirname && cp log.txt $dirname && zip -r -q ${dirname}.zip $dirname && mv ${dirname}.zip "afl_out_${BIND_CPU}/"
set +x